diff --git a/.github/release-nest-v3 b/.github/release-nest-v3 index b6a7d89..98d9bcb 100644 --- a/.github/release-nest-v3 +++ b/.github/release-nest-v3 @@ -1 +1 @@ -16 +17 diff --git a/.github/workflows/release-nestv3-bak.yml b/.github/workflows/release-nestv3-bak.yml new file mode 100644 index 0000000..ed42bb7 --- /dev/null +++ b/.github/workflows/release-nestv3-bak.yml @@ -0,0 +1,40 @@ +name: PikaOS Package Build & Release (amd64-v3) + +on: + push: + branches: + - main + paths: + - '.github/release-nest-v3' + +jobs: + build: + runs-on: ubuntu-latest + container: + image: ghcr.io/pikaos-linux/pikaos-builder:nestv3 + volumes: + - /proc:/proc + options: --privileged -it + + steps: + - uses: actions/checkout@v3 + + - name: Install SSH key + uses: shimataro/ssh-key-action@v2 + with: + key: ${{ secrets.SSH_KEY }} + name: id_rsa + known_hosts: ${{ secrets.KNOWN_HOSTS }} + if_key_exists: replace + + - name: Update APT Cache + run: apt-get update -y + + - name: Set Build Config + run: cp -vf ./pika-build-config/amd64-v3.sh ./pika-build-config.sh + + - name: Build Package + run: ./main.sh + + - name: Release Package + run: ./release.sh diff --git a/.github/workflows/release-nestv3.yml b/.github/workflows/release-nestv3.yml index ed42bb7..a612f6c 100644 --- a/.github/workflows/release-nestv3.yml +++ b/.github/workflows/release-nestv3.yml @@ -11,7 +11,7 @@ jobs: build: runs-on: ubuntu-latest container: - image: ghcr.io/pikaos-linux/pikaos-builder:nestv3 + image: debian:sid volumes: - /proc:/proc options: --privileged -it @@ -28,7 +28,7 @@ jobs: if_key_exists: replace - name: Update APT Cache - run: apt-get update -y + run: apt-get update -y && sudo apt install -y git devscripts dh_make - name: Set Build Config run: cp -vf ./pika-build-config/amd64-v3.sh ./pika-build-config.sh diff --git a/main.sh b/main.sh index e87262d..d9d51a1 100755 --- a/main.sh +++ b/main.sh @@ -15,9 +15,6 @@ cd ./mutter for i in $(cat ../patches/series) ; do echo "Applying Patch: $i" && patch -Np1 -i ../patches/$i || echo "Applying Patch $i Failed!"; done -# TEMP FIX TILL FERREO CLEAN DOCKER -apt-get install -y gir1.2-gtk-4.0=4.14.4+ds-8 libgtk-4-1=4.14.4+ds-8 gir1.2-adw-1=1.5.3-1 libadwaita-1-0=1.5.3-1 --allow-downgrades - # Get build deps apt-get build-dep ./ -y diff --git a/mutter/.gitignore b/mutter/.gitignore deleted file mode 100644 index 5c45efc..0000000 --- a/mutter/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -*.swp -*~ -**/tags.* -subprojects/sysprof/ -__pycache__/ -.buildconfig -.vscode -runtime-dir -build -_build -builddir \ No newline at end of file diff --git a/mutter/.gitlab-ci.yml b/mutter/.gitlab-ci.yml deleted file mode 100644 index f08c699..0000000 --- a/mutter/.gitlab-ci.yml +++ /dev/null @@ -1,739 +0,0 @@ -include: - - remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/145b1bc7ef1702d2bd71584010d7113c6786a506/templates/fedora.yml' - - remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/34f4ade99434043f88e164933f570301fd18b125/templates/ci-fairy.yml' - - project: 'Infrastructure/openshift-images/gnome-release-service' - file: '/ci-templates/release-module.yml' - -stages: - - review - - prepare - - code-review - - build - - test - - analyze - - docs - - deploy - -variables: - FDO_UPSTREAM_REPO: GNOME/mutter - -.skip-git-clone: - variables: - GIT_STRATEGY: none - -.mutter.git-clone: - extends: - - .skip-git-clone - variables: - MUTTER_CLONE_PATH: $CI_BUILDS_DIR/$CI_PROJECT_PATH - MUTTER_CLONE_DEPTH: 1 - before_script: | - if [ -n "$MUTTER_CLONE_PATH" ]; then - set -x - uri="$CI_REPOSITORY_URL" - if [ -n "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" ]; then - uri="$CI_MERGE_REQUEST_SOURCE_PROJECT_URL.git" - branch="$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" - elif [ -n "$CI_COMMIT_TAG" ]; then - branch="$CI_COMMIT_TAG" - elif [ -n "$CI_COMMIT_BRANCH" ]; then - branch="$CI_COMMIT_BRANCH" - else - branch="$CI_DEFAULT_BRANCH" - fi - if [ ! -d "$MUTTER_CLONE_PATH" ] || [ -z "$(ls -A "$MUTTER_CLONE_PATH")" ]; then - git clone --depth $MUTTER_CLONE_DEPTH "$uri" "$MUTTER_CLONE_PATH" -b "$branch" - elif [ ! -d "$MUTTER_CLONE_PATH/.git" ]; then - git clone --bare --depth $MUTTER_CLONE_DEPTH "$uri" "$MUTTER_CLONE_PATH/.git" -b "$branch" - if git -C "$MUTTER_CLONE_PATH" config --unset core.bare; then - git -C "$MUTTER_CLONE_PATH" checkout - else - # For some weird reasons sometimes the fast-path could fail with - # "fatal: not in a git directory" error, so handle it manually - tmpdir=$(mktemp --directory --tmpdir mutter-XXXXXX) - mkdir "$tmpdir/repo" - mv "$MUTTER_CLONE_PATH/.git" "$tmpdir/repo/" - git clone "$tmpdir/repo" "$tmpdir/src" - mv "$tmpdir"/src/* "$tmpdir"/src/.* "$MUTTER_CLONE_PATH" - rm -r "$tmpdir/repo" - rm -rv "$tmpdir" - fi - fi - set +x - fi - -.mutter.skip-git-clone: - extends: - - .skip-git-clone - variables: - MUTTER_CLONE_PATH: '' - -.mutter.run-as-user: - image: - name: ${FDO_DISTRIBUTION_IMAGE} - entrypoint: - - 'runuser' - - '-u' - - !reference [.mutter.fedora@common, variables, MUTTER_USER] - - '--' - -.mutter.distribution-image: - extends: - - .fdo.distribution-image@fedora - - .mutter.run-as-user - -.mutter.fedora@common: - extends: - - .skip-git-clone - variables: - FDO_DISTRIBUTION_VERSION: 40 - BASE_TAG: '2024-04-29.0' - MUTTER_USER: 'meta-user' - FDO_DISTRIBUTION_PACKAGES: - asciidoc - clang - gcovr - gdm - gnome-shell - sassc - uncrustify - xorg-x11-server-Xvfb - mesa-dri-drivers - xorg-x11-proto-devel - qemu-system-x86-core - busybox - zenity - python3-dbusmock - "pkgconfig(libgcrypt)" - "pkgconfig(libdisplay-info)" - - FDO_DISTRIBUTION_EXEC: | - set -e - - # Create $MUTTER_USER - useradd -u 9999 -b /opt/mutter -ms /bin/bash $MUTTER_USER - - # Enable sudo for $MUTTER_USER - echo "%$MUTTER_USER ALL = (ALL) NOPASSWD: ALL" > /etc/sudoers.d/99_mutter-user - - dnf install -y 'dnf-command(builddep)' - - dnf builddep -y mutter --setopt=install_weak_deps=False - dnf builddep -y gnome-shell --setopt=install_weak_deps=False - dnf builddep -y kernel --setopt=install_weak_deps=False - dnf builddep -y gi-docgen --setopt=install_weak_deps=False - - ./.gitlab-ci/install-meson-project.sh \ - https://gitlab.gnome.org/jadahl/catch.git \ - main - - ./.gitlab-ci/install-meson-project.sh \ - https://gitlab.gnome.org/GNOME/gi-docgen.git \ - main - - rpm -e --nodeps gnome-bluetooth-libs-devel \ - mutter mutter-devel \ - gnome-shell - - # Work-around for podman-push aborting on permission issue - # https://gitlab.gnome.org/Infrastructure/Infrastructure/-/issues/1247 - rm -rf /etc/pki/pesign/ - chmod -R a+rX /opt/mutter/$MUTTER_USER - chmod -R a+rX /var/lib/gdm - - # Ensure that we mark the project clone dir as safe directory - git config --system --add safe.directory "$CI_PROJECT_DIR" - - if [[ x"$(uname -m )" = "xx86_64" ]] ; then - if [ -n "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" ]; then - git clone --depth $MUTTER_CLONE_DEPTH \ - $CI_MERGE_REQUEST_SOURCE_PROJECT_URL.git mutter-src \ - -b "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" - elif [ -n "$CI_COMMIT_BRANCH" ]; then - git clone --depth $MUTTER_CLONE_DEPTH \ - $CI_REPOSITORY_URL mutter-src -b "$CI_COMMIT_BRANCH" - else - git clone --depth $MUTTER_CLONE_DEPTH $CI_REPOSITORY_URL mutter-src - fi - meson setup build mutter-src -Dkvm_tests=true - ninja -C build src/tests/kvm/bzImage - mkdir -p /opt/mutter - cp build/src/tests/kvm/bzImage /opt/mutter/bzImage - - dnf install -y python3-argcomplete - - git clone https://github.com/arighi/virtme-ng.git - cd virtme-ng - git fetch --tags - git checkout v1.8 - ./setup.py install --prefix=/usr - cd .. - rm -rf virtme-ng - rm -rf build mutter-src - fi - retry: - max: 2 - when: - - 'always' - -default: - # Cancel jobs if newer commits are pushed to the branch - interruptible: true - # Auto-retry jobs in case of infra failures - retry: - max: 1 - when: - - 'runner_system_failure' - - 'stuck_or_timeout_failure' - - 'scheduler_failure' - - 'api_failure' - -.mutter.fedora@x86_64: - extends: - - .mutter.fedora@common - - .mutter.git-clone - variables: - FDO_DISTRIBUTION_TAG: "x86_64-${BASE_TAG}" - -.mutter.fedora@aarch64: - extends: - - .mutter.fedora@common - - .mutter.git-clone - variables: - FDO_DISTRIBUTION_TAG: "aarch64-${BASE_TAG}" - tags: - - aarch64 - -workflow: - rules: - # Allow to switch from branch pipelines to MR pipelines seamlessly - # https://docs.gitlab.com/ee/ci/jobs/job_control.html#avoid-duplicate-pipelines - - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push" - when: never - - if: $CI_PIPELINE_SOURCE == "merge_request_event" - # Don't trigger a branch pipeline if there is an open MR - - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS - when: never - - if: '$CI_COMMIT_BRANCH' - - if: '$CI_COMMIT_TAG' - -.pipeline-guard: - rules: - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - - if: '$CI_COMMIT_TAG' - - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' - - if: '$CI_COMMIT_BRANCH =~ /^gnome-[0-9-]+$/' - # Avoid catchall `when: manual` rule which might - # cause duplicate pipelines to be triggered. - # https://docs.gitlab.com/ee/ci/jobs/job_control.html#avoid-duplicate-pipelines - # - # Also make it so pipelines without MR need to be started - # manually, since their state will most likely be WIP - - if: '$CI_COMMIT_BRANCH' - when: 'manual' - -.only-merge-requests: - rules: - - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^$/' - when: never - - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME - when: on_success - -repo-sanity: - extends: - - .fdo.ci-fairy - stage: review - variables: - GIT_DEPTH: "1" - script: - - > - if [[ -z "$CI_REGISTRY_IMAGE" ]] ; - then - .gitlab-ci/simple-junit-report.sh check-junit-report.xml \ - repo-sanity "The container registry should be enabled in the project general settings panel at $CI_PROJECT_URL/edit" ; - exit 1 ; - fi - artifacts: - expire_in: 1 week - paths: - - check-junit-report.xml - reports: - junit: check-junit-report.xml - rules: - - !reference [.only-merge-requests, rules] - -check-commit-log: - extends: - - .fdo.ci-fairy - stage: review - variables: - GIT_DEPTH: "100" - script: - ci-fairy check-commits --junit-xml=commit-message-junit-report.xml - artifacts: - expire_in: 1 week - paths: - - commit-message-junit-report.xml - reports: - junit: commit-message-junit-report.xml - rules: - - !reference [.only-merge-requests, rules] - -check-merge-request: - extends: - - .fdo.ci-fairy - - .skip-git-clone - stage: review - script: - ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-merge-request-report.xml - artifacts: - expire_in: 1 week - paths: - - check-merge-request-report.xml - reports: - junit: check-merge-request-report.xml - rules: - - !reference [.only-merge-requests, rules] - -build-fedora-container@x86_64: - extends: - - .fdo.container-build@fedora@x86_64 - - .mutter.fedora@x86_64 - - .mutter.skip-git-clone - stage: prepare - rules: - - !reference [.pipeline-guard, rules] - -build-fedora-container@aarch64: - extends: - - .fdo.container-build@fedora@aarch64 - - .mutter.fedora@aarch64 - - .mutter.skip-git-clone - stage: prepare - rules: - - !reference [.pipeline-guard, rules] - when: manual - -check-code-style: - extends: - - .mutter.distribution-image - - .mutter.fedora@x86_64 - variables: - MUTTER_CLONE_DEPTH: 200 - stage: code-review - needs: - - job: build-fedora-container@x86_64 - artifacts: false - script: - git config --global --add safe.directory $CI_PROJECT_DIR ; - git remote add target $CI_MERGE_REQUEST_PROJECT_URL.git ; - git fetch target $CI_MERGE_REQUEST_TARGET_BRANCH_NAME ; - export common_parent_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "target/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME") <(git rev-list --first-parent HEAD) | head -1) ; - python3 -u ./check-style.py --dry-run --sha $common_parent_sha ; - allow_failure: true - rules: - - !reference [.only-merge-requests, rules] - -.build-mutter-base: - variables: - BASE_MESON_OPTIONS: - -Degl_device=true - -Dwayland_eglstream=true - -Dcatch=true - -Dlibdisplay_info=enabled - -.build-mutter: - extends: - - .mutter.distribution-image - - .build-mutter-base - stage: build - script: - - meson setup . build - --prefix /usr - --werror - --fatal-meson-warnings - --warnlevel 2 - -Dbuildtype=debugoptimized - -Db_coverage=true - $BASE_MESON_OPTIONS - $EXTRA_MESON_OPTIONS - - meson compile -C build - - sudo meson install --dry-run -C build - artifacts: - expire_in: 1 day - paths: - - build - -build-mutter@x86_64: - variables: - EXTRA_MESON_OPTIONS: - -Dkvm_tests=true - -Dkvm_kernel_image=/opt/mutter/bzImage - extends: - - .build-mutter - - .mutter.fedora@x86_64 - needs: - - job: build-fedora-container@x86_64 - artifacts: false - -build-mutter@aarch64: - extends: - - .build-mutter - - .mutter.fedora@aarch64 - needs: - - job: build-fedora-container@aarch64 - artifacts: false - when: manual - -build-without-opengl-and-glx@x86_64: - extends: - - .mutter.distribution-image - - .mutter.fedora@x86_64 - stage: build - needs: - - job: build-fedora-container@x86_64 - artifacts: false - script: - - meson setup . build --werror --prefix /usr - -Dbuildtype=debugoptimized - -Dopengl=false - -Dglx=false - -Degl_device=true - -Dwayland_eglstream=true - -Dintrospection=false - - meson compile -C build - - sudo meson install --no-rebuild -C build - artifacts: - paths: - - build/meson-logs - -build-without-native-backend-and-wayland@x86_64: - extends: - - .mutter.distribution-image - - .mutter.fedora@x86_64 - stage: build - needs: - - job: build-fedora-container@x86_64 - artifacts: false - script: - - meson setup . build --werror --prefix /usr - -Dbuildtype=debugoptimized - -Dnative_backend=false - -Dudev=false - -Dwayland=false - -Dxwayland=false - -Dcore_tests=false - -Dnative_tests=false - -Dintrospection=false - - meson compile -C build - - sudo meson install --no-rebuild -C build - artifacts: - paths: - - build/meson-logs - -build-wayland-only@x86_64: - extends: - - .mutter.distribution-image - - .mutter.fedora@x86_64 - stage: build - needs: - - job: build-fedora-container@x86_64 - artifacts: false - script: - - meson setup . build --werror --prefix /usr - -Dbuildtype=debugoptimized - -Dwayland=true - -Dxwayland=false - -Dcore_tests=false - -Dnative_tests=false - -Dintrospection=false - - meson compile -C build - - sudo meson install --no-rebuild -C build - artifacts: - paths: - - build/meson-logs - -.test-setup: - variables: - XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir" - GSETTINGS_SCHEMA_DIR: "$CI_PROJECT_DIR/build/data" - MUTTER_DEBUG_DUMMY_MODE_SPECS: "800x600@10.0" - PIPEWIRE_DEBUG: 2 - PIPEWIRE_LOG: "$CI_PROJECT_DIR/build/meson-logs/pipewire.log" - XVFB_SERVER_ARGS: "+iglx -noreset" - G_SLICE: "always-malloc" - MALLOC_CHECK_: "3" - NO_AT_BRIDGE: "1" - GTK_A11Y: "none" - before_script: - - !reference [.mutter.git-clone, before_script] - # Disable e.g. audio support to not dead lock screen cast tests - - mkdir -m 700 $XDG_RUNTIME_DIR - - pipewire & sleep 2 - -.test-mutter-base: - extends: - - .mutter.distribution-image - - .test-setup - stage: test - after_script: - - pushd build - - gcovr --root=.. - --filter='\.\./src/' - --filter='\.\./clutter/' - --filter='\.\./cogl/' - --filter='\.\./mtk/' - --exclude='\.\./build/.*\.[ch]$' --exclude='.*/tests/.*\.[ch]$' - --json --output=../coverage-${CI_JOB_NAME}.json - - popd - artifacts: - expire_in: 1 day - name: "mutter-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}" - when: always - paths: - - build - - coverage-*.json - -.test-mutter: - extends: - - .mutter.distribution-image - - .test-mutter-base - script: - - glib-compile-schemas $GSETTINGS_SCHEMA_DIR - - xvfb-run -a -s "$XVFB_SERVER_ARGS" - ./src/tests/meta-dbus-runner.py - --launch=wireplumber - meson test - -C build - --setup plain - --no-suite 'mutter/kvm' - --no-rebuild - --timeout-multiplier 10 - --print-errorlogs - artifacts: - reports: - junit: "build/meson-logs/testlog-plain.junit.xml" - -test-mutter@x86_64: - extends: - - .mutter.fedora@x86_64 - - .test-mutter - tags: - - asan - needs: - - build-mutter@x86_64 - -test-mutter-kvm@x86_64: - extends: - - .mutter.fedora@x86_64 - - .test-mutter-base - tags: - - kvm - script: - - meson test -C build - --no-rebuild - --timeout-multiplier 10 - --setup plain - --suite 'mutter/kvm' - --print-errorlogs - needs: - - build-mutter@x86_64 - artifacts: - reports: - junit: "build/meson-logs/testlog-plain.junit.xml" - -test-mutter@aarch64: - extends: - - .mutter.fedora@aarch64 - - .test-mutter - tags: - - asan-aarch64 - needs: - - build-mutter@aarch64 - when: manual - -coverage: - extends: - - .mutter.distribution-image - - .mutter.fedora@x86_64 - stage: analyze - script: - - mkdir coveragereport - - gcovr --add-tracefile 'coverage-*.json' - --html-details --print-summary --output coveragereport/index.html - - gcovr --add-tracefile 'coverage-*.json' - --xml --output coveragereport/coverage.xml - artifacts: - expose_as: 'Coverage Report' - paths: - - coveragereport - - coveragereport/index.html - reports: - coverage_report: - coverage_format: cobertura - # TODO: we may need to split this file once it will reach the - # gitlab limit size of 10M, or it will stop working: - # https://gitlab.com/gitlab-org/gitlab/-/issues/328772 - path: coveragereport/coverage.xml - coverage: '/^lines: (\d+\.\d+\%)/' - needs: - - test-mutter@x86_64 -# - test-mutter@aarch64 - - test-mutter-kvm@x86_64 - -can-run-gnome-shell@x86_64: - extends: - - .mutter.distribution-image - - .mutter.fedora@x86_64 - - .test-setup - stage: test - needs: - - build-mutter@x86_64 - before_script: - - !reference [.mutter.fedora@x86_64, before_script] - - sudo meson install --no-rebuild -C build - script: - - .gitlab-ci/checkout-gnome-shell.sh - - meson setup gnome-shell gnome-shell/build --prefix /usr -Dbuildtype=debugoptimized -Dman=false --werror --fatal-meson-warnings - - sudo meson install -C gnome-shell/build - - dbus-run-session -- xvfb-run meson test -C gnome-shell/build --no-rebuild --timeout-multiplier 5 - -test-mutter-coverity: - rules: - - if: '$CI_PIPELINE_SOURCE == "schedule" && $MUTTER_SCHEDULED_JOB == "coverity"' - when: on_success - - if: '$CI_COMMIT_BRANCH' - when: 'manual' - extends: - - .mutter.distribution-image - - .mutter.fedora@x86_64 - needs: - - job: build-fedora-container@x86_64 - artifacts: false - stage: analyze - allow_failure: true - script: - - .gitlab-ci/download-coverity-tarball.sh - - CC=clang meson setup coverity-build -Dprofiler=false - - ./coverity/cov-analysis-linux64-*/bin/cov-build --dir cov-int meson compile -C coverity-build - - tar czf cov-int.tar.gz cov-int - - curl https://scan.coverity.com/builds?project=mutter - --form token=$COVERITY_TOKEN --form email=carlosg@gnome.org - --form file=@cov-int.tar.gz --form version="`git describe --tags`" - --form description="GitLab CI build" - cache: - key: coverity-tarball - paths: - - coverity - -distinfo: - extends: - - .fdo.distribution-image@fedora - - .mutter.fedora@x86_64 - - .build-mutter-base - - .test-setup - stage: deploy - needs: - - job: build-fedora-container@x86_64 - artifacts: false - script: - - meson setup . build - - .gitlab-ci/export-artifact-path build > dist.env - artifacts: - reports: - dotenv: dist.env - paths: - - dist.env - rules: - - if: '$CI_COMMIT_TAG' - -dist-mutter: - extends: - - .fdo.distribution-image@fedora - - .mutter.fedora@x86_64 - - .build-mutter-base - - .test-setup - stage: deploy - needs: - - job: build-fedora-container@x86_64 - artifacts: false - script: - - meson setup . build --werror --prefix /usr - -Dbuildtype=debugoptimized - - glib-compile-schemas $GSETTINGS_SCHEMA_DIR - - xvfb-run -a -s "$XVFB_SERVER_ARGS" - ./src/tests/meta-dbus-runner.py - --launch=wireplumber - meson dist -C build - artifacts: - expire_in: 7 day - name: "mutter-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}" - when: always - paths: - - build/meson-private/dist-build/meson-logs - rules: - - if: '$CI_PIPELINE_SOURCE != "merge_request_event"' - when: manual - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - changes: - - "**/meson.build" - - meson/* - when: on_success - - if: '$GITLAB_USER_LOGIN == "marge-bot"' - when: on_success - - if: '$CI_MERGE_REQUEST_ASSIGNEES == "marge-bot"' - when: on_success - -dist-mutter-tarball: - extends: dist-mutter - needs: - - distinfo - artifacts: - expose_as: 'Get tarball here' - paths: - - $TARBALL_ARTIFACT_PATH - reports: - dotenv: dist.env - rules: - - if: '$CI_COMMIT_TAG' - -release-module: - stage: deploy - needs: - - dist-mutter-tarball - extends: .release-module - rules: - - if: '$CI_COMMIT_TAG' - -reference: - extends: - - .mutter.distribution-image - - .mutter.fedora@x86_64 - stage: docs - needs: - - job: build-fedora-container@x86_64 - artifacts: false - script: - - meson setup . build --werror -Ddocs=true -Dtests=false - - ninja -C build - - mkdir references - - cp -r doc/website/* ./references - - mv build/doc/reference/{cally/cally,clutter/clutter,cogl/cogl,cogl-pango/cogl-pango,meta/meta,mtk/mtk} references/ - artifacts: - expire_in: 1 week - expose_as: 'Documentation' - paths: - - references/ - -pages: - stage: deploy - needs: ['reference'] - extends: - - .skip-git-clone - script: - - mv references public/ - artifacts: - paths: - - public - rules: - - if: ($CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH && $CI_PROJECT_NAMESPACE == "GNOME") diff --git a/mutter/.gitlab-ci/checkout-gnome-shell.sh b/mutter/.gitlab-ci/checkout-gnome-shell.sh deleted file mode 100755 index f8e3ecd..0000000 --- a/mutter/.gitlab-ci/checkout-gnome-shell.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/bash - -fetch() { - local remote=$1 - local ref=$2 - - git fetch --quiet --depth=1 $remote $ref 2>/dev/null -} - -gnome_shell_target= - -echo -n Cloning into gnome-shell ... -if git clone --quiet --depth=1 https://gitlab.gnome.org/GNOME/gnome-shell.git; then - echo \ done -else - echo \ failed - exit 1 -fi - -cd gnome-shell - -if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then - merge_request_remote=${CI_MERGE_REQUEST_SOURCE_PROJECT_URL//mutter/gnome-shell} - merge_request_branch=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME - - echo -n Looking for $merge_request_branch on remote ... - if fetch $merge_request_remote $merge_request_branch; then - echo \ found - gnome_shell_target=FETCH_HEAD - else - echo \ not found - - echo -n Looking for $CI_MERGE_REQUEST_TARGET_BRANCH_NAME instead ... - if fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME; then - echo \ found - gnome_shell_target=FETCH_HEAD - else - echo \ not found - fi - fi -fi - -if [ -z "$gnome_shell_target" ]; then - ref_remote=${CI_PROJECT_URL//mutter/gnome-shell} - echo -n Looking for $CI_COMMIT_REF_NAME on remote ... - if fetch $ref_remote $CI_COMMIT_REF_NAME; then - echo \ found - gnome_shell_target=FETCH_HEAD - else - echo \ not found - gnome_shell_target=HEAD - echo Using $gnome_shell_target instead - fi -fi - -git checkout -q $gnome_shell_target diff --git a/mutter/.gitlab-ci/commit-rules.yml b/mutter/.gitlab-ci/commit-rules.yml deleted file mode 100644 index 1ae4337..0000000 --- a/mutter/.gitlab-ci/commit-rules.yml +++ /dev/null @@ -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 diff --git a/mutter/.gitlab-ci/download-coverity-tarball.sh b/mutter/.gitlab-ci/download-coverity-tarball.sh deleted file mode 100755 index 182363c..0000000 --- a/mutter/.gitlab-ci/download-coverity-tarball.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/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 diff --git a/mutter/.gitlab-ci/export-artifact-path b/mutter/.gitlab-ci/export-artifact-path deleted file mode 100755 index f9a7534..0000000 --- a/mutter/.gitlab-ci/export-artifact-path +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/gjs -m -// SPDX-FileCopyrightText: 2024 Florian Müllner -// -// SPDX-License-Identifier: GPL-2.0-or-later - -import Gio from 'gi://Gio'; -import {programArgs, programInvocationName, exit} from 'system'; - -const [buildDir] = programArgs; -if (!buildDir) { - printerr(`usage: ${programInvocationName} `); - exit(1); -} - -const subprocess = Gio.Subprocess.new( - ['meson', 'introspect', '--projectinfo', buildDir], - Gio.SubprocessFlags.STDOUT_PIPE); -const [, out] = subprocess.communicate_utf8(null, null); - -const {descriptive_name, version} = JSON.parse(out); -print(`TARBALL_ARTIFACT_PATH=${buildDir}/meson-dist/${descriptive_name}-${version}.tar.xz`); diff --git a/mutter/.gitlab-ci/install-meson-project.sh b/mutter/.gitlab-ci/install-meson-project.sh deleted file mode 100755 index 8ecf8a3..0000000 --- a/mutter/.gitlab-ci/install-meson-project.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/bash - -set -e - -usage() { - cat <<-EOF - Usage: $(basename $0) [OPTION…] REPO_URL COMMIT - - Check out and install a meson project - - Options: - -Dkey=val Option to pass on to meson - --subdir Build subdirectory instead of whole project - --prepare Script to run before build - - -h, --help Display this help - - EOF -} - -TEMP=$(getopt \ - --name=$(basename $0) \ - --options='D:h' \ - --longoptions='subdir:' \ - --longoptions='prepare:' \ - --longoptions='help' \ - -- "$@") - -eval set -- "$TEMP" -unset TEMP - -MESON_OPTIONS=() -SUBDIR=. -PREPARE=: - -while true; do - case "$1" in - -D) - MESON_OPTIONS+=( -D$2 ) - shift 2 - ;; - - --subdir) - SUBDIR=$2 - shift 2 - ;; - - --prepare) - PREPARE=$2 - shift 2 - ;; - - -h|--help) - usage - exit 0 - ;; - - --) - shift - break - ;; - esac -done - -if [[ $# -lt 2 ]]; then - usage - exit 1 -fi - -REPO_URL="$1" -COMMIT="$2" - -CHECKOUT_DIR=$(mktemp --directory) -trap "rm -rf $CHECKOUT_DIR" EXIT - -git clone --depth 1 "$REPO_URL" -b "$COMMIT" "$CHECKOUT_DIR" - -pushd "$CHECKOUT_DIR/$SUBDIR" -sh -c "$PREPARE" -meson setup --prefix=/usr _build "${MESON_OPTIONS[@]}" -meson install -C _build -popd diff --git a/mutter/.gitlab-ci/simple-junit-report.sh b/mutter/.gitlab-ci/simple-junit-report.sh deleted file mode 100755 index 3a60324..0000000 --- a/mutter/.gitlab-ci/simple-junit-report.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -OUTFILE=$1 -NAME=$2 -MESSAGE=$3 - -cat >$OUTFILE < - - - - - - - -EOF - -# Also echo the message in stdout for good measure -echo $MESSAGE diff --git a/mutter/.gitlab/issue_templates/Bug.md b/mutter/.gitlab/issue_templates/Bug.md deleted file mode 100644 index 11cc9a1..0000000 --- a/mutter/.gitlab/issue_templates/Bug.md +++ /dev/null @@ -1,55 +0,0 @@ - - -### Affected version - - - -### Bug summary - - - -### Steps to reproduce - - - -### What happened - - - -### What did you expect to happen - - - -### Relevant logs, screenshots, screencasts etc. - - - - - -/label ~"1. Bug" diff --git a/mutter/.gitlab/issue_templates/Feature.md b/mutter/.gitlab/issue_templates/Feature.md deleted file mode 100644 index 17d498e..0000000 --- a/mutter/.gitlab/issue_templates/Feature.md +++ /dev/null @@ -1,30 +0,0 @@ - - -### Feature summary - - - -### How would you like it to work - - - -### Relevant links, screenshots, screencasts etc. - - - - - -/label ~"1. Feature" diff --git a/mutter/COPYING b/mutter/COPYING deleted file mode 100644 index d159169..0000000 --- a/mutter/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/mutter/NEWS b/mutter/NEWS deleted file mode 100644 index 06e4095..0000000 --- a/mutter/NEWS +++ /dev/null @@ -1,7476 +0,0 @@ -46.4 -==== -* Fix nested popovers on wayland [Carlos; !3874] -* Misc. bug fixes and cleanups [Robert, Jonas; !3906, !3329] - -Contributors: - Jonas Ådahl, Carlos Garnacho, Robert Mader - -Translators: - Jürgen Benvenuti [de], Chao-Hsiung Liao [zh_TW] - -46.3.1 -====== -* Fix visibility of Xwayland windows [Michel; !3862] -* Misc. bug fixes [Marco; !2959] - -Contributors: - Michel Dänzer, Marco Trevisan (Treviño) - -46.3 -==== -* Fix performance issues with second virtual monitor [Jonas; !3803] -* Fix missing unmap animation of some windows [Michel; !3840] -* Fix placement/resizing regression [Jonas; #2616] -* Fix possible out of sync primary selections and clipboard [Carlos; !3789] -* Fix ibus support in popups [Sebastian K.; !3787] -* Fix hardware accelerated rendering when headless [Jonas; !3805] -* Add back support for legacy X11 cursor themes [Daniel; !3718] -* Fix preedit offsets [Orko; !3845] -* Use character offsets to specify surrounding text [Shiki; !3719] -* Don't force titlebar on screen on all interactive resizes [Jeffrey; !3764] -* Fixed crashes [Carlos, Sebastian W., Michel; !3729, !3783, !3849] -* Misc. bug fixes and cleanups [Daniel, Philip, Marco, José, Jonas, Pascal, - Corentin; #3368, !3770, !3788, !3791, !3809, !3811, !3827, !3790] - -Contributors: - Jonas Ådahl, Michel Dänzer, José Expósito, Orko Garai, Carlos Garnacho, - Sebastian Keller, Jeffrey Knockel, Corentin Noël, Pascal Nowack, - Shiki Okasaka, Marco Trevisan (Treviño), Daniel van Vugt, Sebastian Wick, - Philip Withnall - -Translators: - Scrambled 777 [hi], Jose Riha [sk], Pawan Chitrakar [ne], Милош Поповић [sr] - -46.2 -==== -* Fix hardware cursor with non-atomic KMS drivers [Daniel; !3676] -* Fix night light state getting stuck on monitor changes [Michel; !3742] -* Fix sending preferred buffer transform [Robert; !3717] -* Fix key press events with immediate release being ignored [Carlos; !3721] -* Fix unsetting clipboard on screen lock [Florian; !3752] -* Fix wrong input region of undecorated X11 windows [Sebastian K.; !3720] -* Fix windows potentially shrinking unexpectedly on configure [Jonas Å.; !3755] -* Fix popup menus sometimes closing immediately [Jonas D.; !3631] -* Fixed crashes [Michel, Carlos, Keyu, Jonas Å., Sebastian K.; !3725, !3763, - !3715, !3711, !3758, !3749] -* Misc. bug fixes and cleanups [Florian, Echo, Michel, Jonas Å., Sebastian W., - Corentin, Bilal; !3723, !3744, !3737, !3743, !3735, !3731, !3700, !3750, - !3757, !3754, !3748, !3730, !3775] - -Contributors: - Jonas Ådahl, Michel Dänzer, Jonas Dreßler, Bilal Elmoussaoui, Carlos Garnacho, - Echo J, Sebastian Keller, Robert Mader, Florian Müllner, Corentin Noël, - Keyu Tao, Marco Trevisan (Treviño), Daniel van Vugt, Sebastian Wick - -Translators: - Hugo Carvalho [pt], Leônidas Araújo [pt_BR] - -46.1 -==== -* Implement linux-drm-syncobj-v1 [Austin; !3300] -* Fix input lag on X11 nvidia [Daniel; !3685] -* Fix scanout on secondary GPUs [Michel; !3674] -* Don't apply max-render-time to secondary GPUs [Michel; !3689] -* Fix reusing single-pixel buffers [Jonas Å.; !3702] -* Improve scanout candidate check [Robert; !3699] -* Always use logical pixels for bounds [Sophie; !3698] -* Fix modifiers getting stuck during grabs [Carlos; !3704] -* Fix night-light on displays without EDID [Sebastian W.; !3673] -* Fix secondary GPU acceleration with nvidia driver [Jonas Å., Daniel; !3304] -* Fix some XWayland clients being partially click-through [Sebastian K.; !3697] -* Fix initial suspended state [Jonas Å.; !3475] -* Fixed crashes [Bilal, Jonas Å., Sebastian W., Daniel; - !3683, !3666, !3691, !3708, !3678] -* Misc. bug fixes and cleanups [Ray, Carlos, Bilal, Ivan, Barnabás, Jonas Å., - Jonas D., Michel; !3672, !3681, !3686, !3687, !3671, !3679, !3690, !3703, - !3695, !2946, !3696, !3710, !3644, !3707] - -Contributors: - Jonas Ådahl, Michel Dänzer, Jonas Dreßler, Bilal Elmoussaoui, Carlos Garnacho, - Sophie Herold, Sebastian Keller, Robert Mader, Athmane MOKRAOUI, - Ivan Molodetskikh, Barnabás Pőcze, Austin Shafer, Ray Strode, Daniel van Vugt, - Sebastian Wick - -Translators: - A S Alam [pa], Athmane MOKRAOUI [kab], Rachida SACI [kab], - Nathan Follens [nl], Gwan-gyeong Mun [ko], Fabio Tomat [fur] - -46.0 -==== -* Fix duplicate scroll events over libei [Peter; !3637] -* Fix window menu with mouse button modifier [Jonas; !3623] -* Fix caret offset in accessible event [Carlos; !3643] -* Fix handling of scroll events for mice [Carlos; !3642] -* Use timerfd for clock timing [Christian; !3636] -* Advertise support for BGRA for all screencast types [Robert; !3617] -* Add support for preferred_buffer_scale/transform [Robert; !3580] -* Use memfd to store selection data [Yotam; !3551] -* Fix globally active input focus [Sebastian K.; !3651] -* Call malloc_trim() after loading background image [Sebastian K.; !3653] -* Fix dynamic max render time sometimes getting stuck on constant framerate - [Robert; !3655] -* Introduce base of new gesture framework [Jonas; !2389] -* Work around windows missing work area changes [Balló; !3601] -* Fix black screen with some drivers [Sebastian W.; !3646] -* Improve login screen <-> session transition [Jocelyn; !3659] -* Fixed crashes [Bilal, Carlos; !3656, !3660] -* Misc. bug fixes and cleanups [Philip, Peter, Sebastian W., Zander, Petr, - Sebastian K., Robert, Bilal, Jonas; !3640, !3647, !3648, !3654, !3658, !3622, - !1918, !3067, !3661, !3662, !3652, !3645] - -Contributors: - Yotam Bar-On, Zander Brown, Jonas Dreßler, Bilal Elmoussaoui, Jocelyn Falempe, - Carlos Garnacho, Balló György, Christian Hergert, Petr Hodina, Peter Hutterer, - Sebastian Keller, Robert Mader, Sebastian Wick, Philip Withnall - -Translators: - Sabri Ünal [tr], Aurimas Černius [lt], Jordi Mas i Hernandez [ca], - Asier Sarasua Garmendia [eu], Matej Urbančič [sl], Anders Jonsson [sv], - Bruce Cowan [en_GB], Guillaume Bernard [fr], Kukuh Syafaat [id], - Milo Casagrande [it], Rūdolfs Mazurs [lv], Fran Dieguez [gl], - Ask Hjorth Larsen [da] - -46.rc -===== -* screencast: Renegotiate when DMABUF allocation fails [columbarius; !2557] -* Unify wayland pointer- and keyboard grab mechanisms [Carlos; !3420] -* Add modifier-aware screencasting support [Doğukan; !3537] -* Fix synchronization issue on Xorg [Daniel; !3590] -* Send fractional_scale event immediately on window creation [Jonas; !3598] -* wayland/client: Add make_dock() method [Leonhard; !3612] -* Fix gray area on top of some X11 fullscreen windows [Sebastian K.; !3608] -* Stick dragged windows to the right anchor point [Carlos; !3546] -* cally/text: Fix emission of `text_caret_moved` signal [Florian; !3621] -* clutter/text: Fix minimum height calculation [Julian; !3610] -* Add experimental support for variable refresh rate [Dor; !1154] -* Expose the minimum refresh rate of monitors through D-Bus [Dor; !3576] -* Use "default" cursor for moving windows [Sebastian K.; !3634] -* Fixed crashes [Carlos, Michel; !3618, !3632] -* Misc. bug fixes and cleanups [Robert, Bilal, Dor, Florian, Sebastian W., - Daniel, msizanoen, Corentin, Agustín, Sebastian K., Marco, Doğukan, Carlos, - Jonas, Barnabás; !3217, !3581, !3582, !3583, !3586, !3574, !3587, !3585, - !3584, !3588, !3553, !3589, !3593, !3595, !3597, !3599, !3327, !3603, !3606, - !3594, !3611, !3613, !3552, !3620, !3592, !3614, !3619, !3625, !3628, !3627, - !3624, !3629, !3630, !3633, !3027] - -Contributors: - Dor Askayo, columbarius, Agustín Dall'Alba, Michel Dänzer, Jonas Dreßler, - Bilal Elmoussaoui, Carlos Garnacho, Sebastian Keller, Doğukan Korkmaztürk, - Leonhard, Robert Mader, msizanoen, Florian Müllner, Corentin Noël, - Barnabás Pőcze, Julian Sparber, Marco Trevisan (Treviño), Daniel van Vugt, - Sebastian Wick - -Translators: - Ekaterine Papava [ka], Danial Behzadi [fa], Aurimas Černius [lt], - Yuri Chornoivan [uk], Yaron Shahrabani [he], Nathan Follens [nl], - Matej Urbančič [sl], Jordi Mas i Hernandez [ca], Kukuh Syafaat [id], - Luming Zh [zh_CN], Andi Chandler [en_GB], Asier Sarasua Garmendia [eu], - Quentin PAGÈS [oc], Rūdolfs Mazurs [lv], Irénée THIRION [fr], - Daniel Mustieles [es], Daniel Rusek [cs], Piotr Drąg [pl], Balázs Úr [hu], - Artur S0 [ru] - -46.beta -======= -* Implement mouse cursor hotspots for KMS atomic [Albert, Zack; !3337, !3503] -* Improve project and development documentation - [Bilal, Sebastian W.; !3489, !3505, !3519] -* Add a documentation website [Bilal; !3490] -* Refactor wayland focus management [Carlos; !3511] -* Remove experimental rt-scheduler feature [Dallas; !3296] -* Remove ClutterCanvas [Shmuel; !3470] -* Consider reduced blanking with lower pixelclock [Kai-Heng; !3449] -* Fix centering non-modal transients over parent [Florian; !3533] -* Allow XKB model to be configured [Leorize; !2760] -* Enable KMS deadline timer after a VT switch if it was inhibited [Dor; !3534] -* Prepare for variable refresh rate support [Dor; !3521, !3560, !3561] -* Restore IM state flushing before handling key events [Carlos; !3536] -* Swap stylus buttons to match traditional order [Peter; !3541] -* Fix handling of pad ring wrap arounds [Peter; !3545] -* Support Broadcast RGB/RGB range KMS property [Sebastian W.; !3535] -* Ensure all planes support EGL config format [Sebastian W.; !3512] -* Handle Alt modifier in pad actions [Peter; !3522] -* Store eraser and stylus tools separately [Peter; !3542] -* Disambiguate output mapped to tablet with connector name [Carlos; !3556] -* Fix lost keyboard focus after dismissing popups [Carlos; !3568] -* Implement direct scanout for cropped and scaled surfaces - [Robert; !3559, !3177] -* Fixed crashes [Peter, Carlos, Sebastian W., Simon, Olivier, Daniel; !3383, - !3517, !3518, !2774, !3446, !3539, !3562, !3565] -* Misc. bug fixes and cleanups [Bilal, Daniel, Sebastian W., Robert, Zander, - Florian, Carlos, Corentin, Shmuel, Dor, Sebastian K., Jonas; !3498, !3418, - !3500, !3492, !3484, !3504, !3499, !3333, !3351, !3501, !3211, !3506, !3387, - !3509, !3510, !3483, !3467, !3514, !3515, !3516, !3520, !3513, !3507, !3526, - !3527, !3528, !3450, !3531, !3549, !3532, !3543, !3529, !3530, !3550, !3554, - !3540, !3569, !3563, !3570, !3555, !3572, !3571, !3538, !3573, !3575] - -Contributors: - Dor Askayo, Zander Brown, Jonas Dreßler, Bilal Elmoussaoui, Albert Esteve, - Kai-Heng Feng, Olivier Fourdan, Carlos Garnacho, Peter Hutterer, - Sebastian Keller, Leorize, Robert Mader, Simon McVittie, Shmuel Melamud, - Florian Müllner, Corentin Noël, Zack Rusin, Dallas Strouse, Daniel van Vugt, - Sebastian Wick - -Translators: - Ekaterine Papava [ka], Efstathios Iosifidis [el], Artur S0 [ru], - Daniel Rusek [cs], Fran Dieguez [gl], Sabri Ünal [tr] - -46.alpha -======== -* Fix filtering keybinding events in presence of grabs [Sebastian K.; !3054] -* Fix direct scanout support when using integer scaling [Daniel; !3290] -* Fix capitalization of some keys when caps lock is on [Carlos; !3306] -* Fix vsync regression [Robert; !3286] -* Fix visibility of software cursors when using direct scanout [Robert; !3302] -* Fix artifacts at the bottom of some surfaces [Robert; !3310] -* Discard monitor configs with fractional scale when unusable [Jonas Å.; !3299] -* Apply track point settings [Rohan; !3089] -* xwayland: Enable XDG portal only when not nested [Olivier; !3303] -* Inhibit real-time scheduling when mode setting [Ray; !3324] -* Don't delay frame updates after idle period [Michel; !3174] -* Fix running Xwayland in headless setup with nvidia driver [Olivier; !3320] -* wayland: Send keyboard modifiers after the enter event [Alexandros; !3341] -* wayland/client: Add make_desktop() method [Florian; !3305] -* Add a target workspace to raise_and_make_recent() [Sebastian W.; !3315] -* clutter: Drop cairo helpers [Bilal; !3086] -* cogl: Port away from CoglObject [Bilal; !3193] -* mtk: Add a Region type [Bilal; !3292] -* Propagate focus appearance to all ancestors [Sebastian W.; !3356] -* Ignore locked modifiers in keybinding machinery [Carlos; !3369] -* Fix disabling check-alive timeout [Sebastian K.; !3367] -* Drop ClutterContainer interface [Zander; !3377, !3384] -* Improve sloppy and mouse focus modes [Sebastian W.; !3258] -* Sync geometry only when window is mapped [Sebastian W.; !3401, !3404] -* Improve repick due to transform changes [Carlos; !3385] -* Fix tablets on X11 having the wrong device [Carlos; !3393] -* Disable HW cursor when inhibited by backend [Robert; !3412] -* screencast: Bring back blitting [Georges; !3406] -* backends/native: Try 10 bpc formats [Michel; !3139] -* Fix forcing EGLStream with NVIDIA proprietary driver [Daniel; !2905] -* screencast: Add ability to stop streams [Jonas Å., Pascal; !3307] -* Use standard cursor names from CSS specification [Carlos; !3295] -* Avoids over-synchronization due to client reads [Michel; !3389, !3408] -* Add more profiling instrumentation [Ivan; !3417] -* Allow specifyig the layout manager for an actor type [Florian; !3445] -* Fix handling of relative mode for tablets [Peter; !3410] -* Dynamically assign hardware planes during configuration [Jonas Å.; !3428] -* Simplify X11 focus management [Carlos; !3269] -* background: Fix background color around image [Sebastian W.; !3459] -* text-input: Use correct offsets in delete_surrounding_text [Alynx; !2712] -* Add wayland shm YCbCr support [Sebastian W.; !3371] -* Set a minimum guessed scale [Joan; !3464] -* Fix building without native backend [Bilal; !3480] -* Fix occasional artifacts at top of X11 fullscreen windows [Carlos; !3476] -* Add documentation for building, running and debugging - [Sebastian W.; !3465, !3485] -* Improve tablet pressure curve calculation [Peter; !3399] -* Fixed crashes [Carlos, Jonas D., Robert, Sebastian W., Jonas Å., Sebastian K.; - !3287, !3283, !3311, !3322, !3318, !3370, !3392, !3335, !3422, !3376, !3453] -* Plugged leaks [Sebastian K.; !3411, !3442] -* Misc. bug fixes and cleanups [Daniel, Corentin, Carlos, Jonas Å., Ivan, - Michel, Sebastian W., Robert, Barnabás, Peter, Bilal, Sebastian K., Zander, - Florian, Mike, Qiu, Olivier, Christopher, Mart; !3212, !3298, !3267, !3297, - !3313, !3316, !3317, !3323, !3325, !3326, !3328, !3330, !3332, !3319, !3097, - !3288, !3347, !3178, !3240, !3338, !3352, !3321, !2618, !3309, !3353, !3348, - !3349, !3358, !3361, !3362, !3276, !3340, !3365, !3366, !3364, !3363, !3375, - !3181, !3374, !3379, !3382, !3388, !3354, !3386, !3398, !3395, !3397, !3368, - !3400, !3396, !3405, !3403, !3409, !3413, !3402, !3280, !3394, !3421, !3423, - !3431, !3432, !3425, !3438, !3440, !3430, !3429, !2016, !3443, !3444, !3441, - !3451, !3350, !3434, !3437, !3447, !1908, !3456, !3452, !3454, !3455, !2620, - !3463, !3466, !3458, !3468, !3469, !3474, !3473, !3471, !3479, !3482, !3487, - !3486, !3478, !3488, !3357, !3491] - -Contributors: - Jonas Ådahl, Zander Brown, Michel Dänzer, Jonas Dreßler, Bilal Elmoussaoui, - Christopher Fore, Olivier Fourdan, Alexandros Frantzis, Carlos Garnacho, - Mike Gorse, Peter Hutterer, Rohan Hendrik Jotz-Lean, Sebastian Keller, - Robert Mader, Ivan Molodetskikh, Florian Müllner, - Georges Basile Stavracas Neto, Corentin Noël, Pascal Nowack, Barnabás Pőcze, - Mart Raudsepp, Ray Strode, Joan Torres, Daniel van Vugt, Qiu Wenbo, - Sebastian Wick, Alynx Zhou - -Translators: - Kristjan SCHMIDT [eo], Rafael Fontenelle [pt_BR], Guillaume Bernard [fr], - Jordi Mas i Hernandez [ca], Florentina Mușat [ro], Ngọc Quân Trần [vi], - Artur S0 [ru] - -45.0 -==== -* Fix focus-follows-mouse mode [Carlos; !3256] -* Optimize applying relative transformation matrix [Robert; !3259] -* Add support for P010 YCbCr format [Robert; !3244] -* Fix hardware cursor stuttering on Raspberry Pi [Daniel; !3279] -* Fix input in multi-monitor remote desktop sessions with libei [Pascal; !3273] -* Fixed crashes [Carlos, Daniel, Sebastian W.; !3252, !3253, !3255, !3160, - !3268, !3262, !3277] -* Misc. bug fixes and cleanups [Florian, Joan, Jonas, Carlos, Sebastian W., - Pascal; !3248, !3249, !3263, !3261, !3116, !3251, !3032, !3275, !3278] - -Contributors: - Jonas Ådahl, Carlos Garnacho, Sebastian Keller, Andre Klapper, Robert Mader, - Florian Müllner, Pascal Nowack, Joan Torres, Daniel van Vugt, Sebastian Wick - -Translators: - Sabri Ünal [tr], Quentin PAGÈS [oc], Anders Jonsson [sv], - Christian Kirbach [de], Ask Hjorth Larsen [da] - -45.rc -===== -* Fix possible redraw freeze in fullscreen windows [msizanoen; !3127] -* Fix restoring focus when leaving the overview [Jonas Å., Carlos; !3185] -* Support alpha-composited window screencasts [Georges; !3175] -* Fix some XWayland windows not getting mapped [Sebastian; !3194] -* Fix cursor movement on rotated screens [Daniel; !3180] -* Avoid global lock in stage signals [Christian; !3204] -* Implemented suspended xdg_toplevel state [Jonas Å.; !3019, !3213] -* Support idle_inhibit protocol [Charbel; !3145] -* Do not trigger repick during relayout [Carlos; !3220] -* Fix redraw issue when buffer age is unavailable [Carlos; !3221] -* Add Meta Toolkit (MTK) library [Bilal; !3128] -* Fix possible window freeze during resize operations [Carlos; !3189] -* Fixes to tablet cursor visibility on Wayland [Carlos; !3218] -* Improve support for input capture and emulated input [Jonas Å.; !3228] -* Use headless mode when seat ID is unset [Joan; !3093] -* Fix unresponsive touchscreen after titlebar drag [Carlos; !3059] -* Fix absolute pointer events on virtual monitor streams [Jonas Å.; !3241] -* Fix disabling CRTCs in disable-only mode updates [Jonas Å.; !3073] -* Cache multi-texture shader snippets [Daniel; !3224] -* Fixed crashes [Carlos, Jonas Å., Jonas D., Barnabás, Jeremy; !3183, !3219, - !3234, !3216, !3202, !3229, !3246] -* Plugged leaks [Sebastian, Niels; !3188, !3203] -* Misc. bug fixes and cleanups [Bilal, Michel, Jonas Å., Florian, Carlos, - Sebastian, Sandro, Daniel, Pascal, Georges, Jonas D., Uzair; !3087, !3154, - !3169, !3124, !3173, !3190, !3197, !3198, !3215, !3209, !3155, !3225, !3226, - !3223, !3231, !3187, !3230, !3210, !3227, !3233, !3235, !3237, !3238, !3236, - !3239, !3243, !3199, !3247, !3242] - -Contributors: - Jonas Ådahl, Uzair Ahmad, Charbel Assaad, Sandro Bonazzola, Jeremy Cline, - Michel Dänzer, Jonas Dreßler, Bilal Elmoussaoui, Carlos Garnacho, - Niels De Graef, Christian Hergert, Sebastian Keller, msizanoen, - Florian Müllner, Georges Basile Stavracas Neto, Pascal Nowack, Barnabás Pőcze, - Joan Torres, Daniel van Vugt - -Translators: - Kukuh Syafaat [id], Sabri Ünal [tr], Jiri Grönroos [fi], - Baurzhan Muftakhidinov [kk], Vasil Pupkin [be], Jordi Mas [ca], - Aurimas Černius [lt], A S Alam [pa], Nathan Follens [nl], Philipp Kiemle [de], - Milo Casagrande [it], Yaron Shahrabani [he], Gwan-gyeong Mun [ko], - Bruce Cowan [en_GB] - -45.beta.1 -========= -* Fix blitting from premultiplied to opaque formats [Jonas; !3159] -* Fix Super key not going to overview in GNOME Shell [Carlos; 3162] -* Use ClutterEvent in ClutterActor class event vmethod signatures - [Carlos; 3163] -* Misc. bug fixes and cleanups [Carlos, !3167, !3168] - -Contributors: - Jonas Ådahl, Carlos Garnacho - -Translators: - Piotr Drąg [pl], Daniel Mustieles [es] - -45.beta -======= -* Support input capture and emulated input with libei - [Jonas, Peter, Olivier; !2628] -* Add KMS thread [Jonas; !2777] -* Fix touch move operations on subsurfaces [Gergo; !3125] -* Fix unexpected cursor changes over non-resizable windows [Michel; !3096] -* Improve render time estimates [Michel; !3090] -* Fix flickering when DRI driver isn't available [Daniel; !3117] -* Fix restoring maximized state of SSD windows [Sebastian K.; !3035] -* Add support for YUV formats [Niels, Robert; !2191] -* Fix xwayland-allow-byte-swapped-clients setting [Olivier; !3156] -* Misc. bug fixes and cleanups [Jonas, Florian, Bilal, Daniel, Robert, - Sebastian W., Michel, Carlos; !3111, !3100, !3112, !3065, !3101, !3129, - !3118, !3131, !3123, !3135, !3134, !3130, !3141, !3140, !3144, !3148, !3138, - !3150, !3005, !3103, !3126, !3147, !3157, !3153] - -Contributors: - Jonas Ådahl, Michel Dänzer, Bilal Elmoussaoui, Olivier Fourdan, - Carlos Garnacho, Niels De Graef, Peter Hutterer, Sebastian Keller, - Gergo Koteles, Robert Mader, Florian Müllner, Daniel van Vugt, Sebastian Wick - -Translators: - Yosef Or Boczko [he], Fabio Tomat [fur], Balázs Úr [hu], - Ekaterine Papava [ka], Yuri Chornoivan [uk], Artur So [ru], - Matej Urbančič [sl], Asier Sarasua Garmendia [eu], Danial Behzadi [fa], - Luming Zh [zh_CN], Hugo Carvalho [pt], Daniel Rusek [cs], Fran Dieguez [gl], - Daniel Mustieles [es] - -45.alpha -======== -* Fix DND in some server-side decorated windows [Sebastian; !2978] -* Optionally use libdisplay-info for EDID parsing [adarshgm; !2642] -* Optimize partial surface updates [msizanoen1; !2965] -* Fix redrawing regression in non-DMA remote sessions [Jonas Å.; !2987] -* Avoid race condition in xwayland-on-demand [Marco; !2970] -* Do not unminimize windows with initial IconicState [Carlos; !3001] -* Implement physical pixel rounding of wayland surfaces [msizanoen1; !2726] -* Fix mispositioning of some X11 fullscreen windows [Carlos; !2996] -* Fix legacy fullscreen windows appearing on all monitors [Carlos; !2999] -* Improve support for display-attached tablets [Carlos; !3012] -* Fix stuck cursor in some clients [Carlos; !3025] -* Avoid unexpected orientation changes around suspend/resume [Carlos; !3021] -* Fix oversized input region around Xwayland windows [Jonas Å.; !3022] -* Re-enable client modifiers with amdgpu driver [Robert; !3030] -* Fix sysprof tracing in non-main threads [Jonas Å.; !2998] -* Fix X11 client input region issues [Sebastian, Jonas Å.; !3031, !3045] -* Optimize finish-layout step during stage updating [Robert, Jonas D.; !2679] -* Fix profiling repeatedly [Jonas Å.; !3068] -* Ensure preferred monitor mode is always included [Timotej; !3061] -* Fully initialize input device state during init [Jonas Å.; !3070, !3071] -* Forward modifiers to IM alongside regular key events [Carlos; !3044] -* Fix window focus unexpectedly moving to secondary monitor when changing - workspaces [Sebastian W.; !2909] -* Avoid rapidly toggling dynamic max render time [Daniel; !3074] -* Fix dynamic max render time blocking with direct scanout [Dor; !3080] -* Mirror window placement in RTL locales [Shmuel; !3009] -* Fix screencast with fractionally scaled surfaces [msizanoen; !3053] -* Reipmlement strict focus mode policy [Brendan; !3063] -* Fixed crashes [Jonas Å., Barnabás, Carlos, Robert, Dor; !2992, !2995, - !3002, !3004, !3037, !3076, !3077, !3095, !3104] -* Plugged leaks [Jonas Å., Dor; !2991, !3078] -* Misc. bug fixes and cleanups [Marco, Andy, Sebastian K., Jonas Å., Robert, - Alexandre, Bilal, Georges, Florian, Dmitry, Michel, Pascal, Olivier, Carlos, - Daniel, Sebastian W., Corentin, Barnabás, Dor; !2903, !2983, !2986, !2985, - !2990, !2982, !3000, !2938, !2445, !3006, !3010, !2913, !2893, !2939, !3011, - !3007, !3018, !3016, !3024, !3020, !3029, !3034, !3036, !3040, !3046, !3051, - !3047, !3055, !3058, !3075, !3081] !3082, !3079, !2911, !3084, !3088, !3085, - !3052, !3094, !3083, !3092, !3008, !3098, !3091, !3062, !3108] - -Contributors: - Jonas Ådahl, adarshgm, Dor Askayo, Michel Dänzer, Jonas Dreßler, - Bilal Elmoussaoui, Olivier Fourdan, Alexandre Franke, Carlos Garnacho, - Andy Holmes, Sebastian Keller, Dmitry V. Levin, Robert Mader, Shmuel Melamud, - msizanoen, msizanoen1, Florian Müllner, Georges Basile Stavracas Neto, - Corentin Noël, Pascal Nowack, Barnabás Pőcze, Timotej Šulík, - Marco Trevisan (Treviño), Daniel van Vugt, Sebastian Wick, Brendan William - -Translators: - Danial Behzadi [fa], Simon Elst [fr], Rafael Fontenelle [pt_BR], - Sergej A [ru], Bruce Cowan [en_GB], Alexandre Franke [fr] - -44.1 -==== -* Fall back to the default, not the unknown color space [Sebastian W.; !2915] -* Fix resizing windows via keyboard [Florian; !2908] -* Fix possible screen freeze after resume with multiple monitors [Daniel; !2933] -* Fix anchor position when dragging window [Carlos; !2942] -* Fix applying XSettings to decorations on X11 [Marco; !2948] -* Allow clipped redraws for headless backend [Salman; !2775] -* Improve screencast support [Georges; !2804] -* Fix focus-on-click for server-side decorated windows [Carlos; !2954] -* Fix initial fullscreen state of server-side decorated windows [Carlos; !2961] -* Fix feedback loop triggering bursts of excessive CPU load [Robert; !2823] -* Enable modifiers by default on non-native backend [Robert; !2972] -* Check EDID for supported sink Colorimetry [Sebastian W.; !2919] -* Fix artifacts in titlebars on some hardware [Carlos; !2976] -* Fix map transitions for X11 windows on wayland [Carlos; !2975] -* Fixed crashes [Jonas Å., Sebastian K., Carlos, Michel, Daniel, Robert; - !2932, !2930, !2945, !2956, !2962, !2968, !2967, !2960, !2963] -* Plugged leaks [Sebastian K., Jonas Å.; !2922, !2926, !2957] -* Misc. bug fixes and cleanups [Daniel, Ivan, Emmanuele, Simon, Jonas D., - Jonas Å., Chris, Florian, Corentin, msizanoen1, Sebastian K.; !2918, !2904, - !2928, !2929, !2900, !2856, !2944, !2935, !2947, !2949, !2951, !2940, !2953, - !2964, !2934, !2902, !2971] - -Contributors: - Jonas Ådahl, Emmanuele Bassi, Michel Dänzer, Jonas Dreßler, Carlos Garnacho, - Sebastian Keller, Robert Mader, Chris Mayo, Simon McVittie, Ivan Molodetskikh, - msizanoen1, Florian Müllner, Georges Basile Stavracas Neto, Corentin Noël, - Salman, Marco Trevisan (Treviño), Daniel van Vugt, Sebastian Wick - -Translators: - Boyuan Yang [zh_CN], Ngọc Quân Trần [vi], Nathan Follens [nl] - -44.0 -==== -* Fix state confusion and delay on startup [Carlos; !2906] -* Fix night light regression [Sebastian; !2916] -* Fix fullscreen regression with many SDL apps [Jonas; !2921] -* Fixed crashes [Jonas; !2901, !2912] - -Contributors: - Jonas Ådahl, Carlos Garnacho, Sebastian Wick - -Translators: - Ask Hjorth Larsen [da], Piotr Drąg [pl], Marek Černocký [cs], - Gwan-gyeong Mun [ko] - -44.rc -===== -* Do not overwrite previously set offsets on attach [Matthias; !2843] -* Fix Xwayland focus regressions [Carlos; !2841, !2878] -* Stop parsing unused EDID parameters [adarshgm; !2825] -* Fix partial updates on offscreen rotated screens [Robert; !2860] -* Improve Xwayland RandR emulation compatibility [msizanoen1; !2725] -* Fix touch window dragging on rotated monitors [Jonas D.; !2859] -* Remove legacy OpenGL driver support [Jonas Å.; !2672] -* Improve default scale factor selection [Adrian, Jonas Å.; !2653, !2880] -* Handle all X11 window title fallbacks [Carlos; !2872] -* Fix handling of keyboard-driven window resize [Carlos; !2871] -* Fix recording windows on non-active workspaces [Robert; !2789] -* Manage KMS updates more asynchronously [Jonas Å.; !2854, !2855] -* Fix headless startup [Jonas Å.; !2821] -* Remove support for window shading [Robert; !2884] -* Move away from GTK3 [Carlos; !2864] -* Restore zero-copy fast path for Xwayland fullscreen windows [Carlos; !2797] -* Prevent clients from locking the compositor with cursor updates - [Olivier; !2849] -* Add experimental development tool for HDR modes [Sebastian; !2879] -* Account for linear sampling when calculating actor damage [msizanoen1; !2771] -* wayland: Implement fractional_scale protocol [Robert; !2394] -* Fixed crashes [Jonas D., Jonas Å., Robert; !2858, !2863, !2869, !2885, !2887] -* Memory handling fixes - [Jonas Å., Carlos, Simon, Michel; !2853, !2868, !2877, !2886] -* Misc. bug fixes and cleanups [Jonas Å., Florian, Robert, Carlos, Sebastian, - Jonas D.; !2846, !2840, !2850, !2829, !2862, !2779, !2861, !2713, !2865, - !2866, !2867, !2874, !2875, !2873, !2881, !2847, !2889, !2890, !2891, !2892, - !2894, !2895, !2899] - -Contributors: - Dor Askayo, Matthias Clasen, Jonas Dreßler, Michel Dänzer, Olivier Fourdan, - Carlos Garnacho, Robert Mader, Simon McVittie, Florian Müllner, Adrian Vovk, - Sebastian Wick, adarshgm, msizanoen1, Jonas Ådahl - -Translators: - Марко Костић [sr], Daniel [es], Fabio Tomat [fur], Matej Urbančič [sl], - Jiri Grönroos [fi], Balázs Úr [hu], Anders Jonsson [sv], Marek Černocký [cs], - Jürgen Benvenuti [de], Alexander Shopov [bg] - -44.beta -======= -* Don't disable KMS modifiers on newer i915 systems [Sameer; !2641] -* Set LOD bias for sharper mipmaps [Daniel; !2644] -* Fix edge resistance and window snapping regression [John; !2687] -* Avoid high-level udev queries for input caps and properties [Carlos; !2617] -* Implement wl_output v3 and v4 [Robert; !2692] -* Fix recalculating viewport after window resize [Sebastian Kr.; !2689] -* Fix opaque cursors and LoDPI cursor on HiDPI screens [Jonas Å.; !2698] -* Process device removing events immediately [Jonas D.; !2696] -* Handle stage view updates without allocation more gracefully [Jonas D.; !2694] -* Fix window screenshots being cut off at the bottom right [Sebastian K.; !2720] -* wayland/subsurface: Avoid using buffers with unfinished client work - [Michel; !1880] -* Move X11 window decorations to a separate client - [Carlos; !2175, !2735, !2756, !2791, !2796, !2758] -* Fix cursor position in window screencasts [Georges; !2737] -* Skip resize effects for tiled windows during user grabs [Michael; !2579] -* Fix pointer constrains with subsurfaces [Robert; !2717] -* Disable direct scanout during drag-n-drop operations [Robert; !2677] -* Ignore unmapped subsurfaces in direct scanout check [Robert; !2755] -* Fix cursor disappearing over windows during grabs [Carlos; !2754] -* Make wl_output mode independent of the orientation [Sebastian W.; !2723] -* Improve focus handling on workspace switches [Sebastian W.; !2747] -* Fix initialization of keyboard accessibility [Carlos; !2750, !2778] -* Refactor API to use well-defined ownership instead of singletons - [Jonas Å.; !2718] -* Add support for xdg-foreign-v2 [Jason, Jonas Å.; !2770] -* Add higher bit depth offscreen framebuffers support [Jonas Å., Naveen; !2461] -* Overhaul dynamic max render time calculation [Michel; !2500] -* Do not require a physical device to update pointer visibility [Carlos; !2766] -* Allow building without xwayland support [Bilal; !2407, !2399] -* Add Xwayland byte-swapped clients support [Olivier; !2785] -* Fix freeze when crossing monitors under some conditions [Carlos; !2803] -* Don't allow window activation to break global grabs - [Florian, Carlos; !2776, !2832] -* Integrate window grab operations with new ClutterGrab API [Carlos; !2683] -* Support selecting an acceleration profile for touchpad devices [Evan; !2426] -* Enforce compliant surface buffer sizes [Robert; !2815] -* Keep proportional position when moving window between rects [Sebastian; !2591] -* Introduce implicit grabbing in Clutter [Jonas D.; !2342] -* Fix unexpected window focus changes after global grabs [Sebastian W.; !2742] -* Fix sloppy/mouse focus mode on wayland [Carlos; !2828] -* Add service channel Wayland clients [Jonas Å.; !2810] -* Fixed crashes [Sebastian W., Jonas Å., Bilal, Jonas D., msizanoen1, Georges, - Carlos, Daniel, Keyu; !2695, !2704, !2706, !2711, !2691, !2709, !2690, !2736, - !2745, !2674, !2793, !2794, !2827, !2831, !2834] -* Plugged leaks [Niels; !2799, !2817] -* Misc. bug fixes and cleanups [Jonas D., Jonas Å., Bilal, Florian, Corentin, - Bram, Georges, Hunor, Carlos, Robert, Michel, Christian, Olivier, Daniel, - Corey, Sebastian K., Jan, Anders, Simon, Sebastian W., Jake, Erico; !1492, - !2508, !2645, !2699, !2418, !2701, !2702, !2703, !2708, !2697, !2710, !2714, - !2715, !2716, !2719, 2724, 2739, 2740, 2733, 2753, 2741, !2680, !2727, !2757, - !2762, !2671, !2765, !2767, !2707, !2768, !2428, !2467, !2772, !2769, !2781, - !2784, !2786, !2780, !2788, !2792, !2783, !2798, !2795, !2800, !2805, !2790, - !2809, !2572, !2811, !2812, !2813, !2807, !2773, !2806, !2816, !2818, !2814, - !2819, !2782, !2822, !2087, !2824, !2826, !2621, !2748, !2091, !2833, !2808, - !2836] - -Contributors: - Corey Berla, Hunor Csomortáni, Jake Dane, Jonas Dreßler, Michel Dänzer, - Bilal Elmoussaoui, Olivier Fourdan, Jason Francis, Carlos Garnacho, - Evan Goode, Niels De Graef, Christian Hergert, Peter Hutterer, Anders Jonsson, - Sebastian Keller, Sebastian Krzyszkowiak, Naveen Kumar, Sameer Lattannavar, - Robert Mader, Simon McVittie, Florian Müllner, Georges Basile Stavracas Neto, - Corentin Noël, Erico Nunes, Bram Stolk, Keyu Tao, Jan Tojnar, Daniel van Vugt, - Michael Webster, Sebastian Wick, John Wudrick, msizanoen1, Jonas Ådahl - -Translators: - Dušan Kazik [sk], Aleksandr Melman [ru], Yuri Chornoivan [uk], - Hugo Carvalho [pt], Emin Tufan Çetin [tr], Kukuh Syafaat [id], - Fran Dieguez [gl], Yosef Or Boczko [he], Asier Sarasua Garmendia [eu], - Quentin PAGÈS [oc], Aurimas Černius [lt] - -43.1 -==== -* Add quirk to work around issue with Mali GPUs [Daniel; !2614] -* Notify changes to night-light support over D-Bus [Sebastian W.; !2623] -* Fix always-on-top windows unexpectedly taking focus [Sebastian W.; !2489] -* Fix accidental direct scanout [Jonas Å.; !2624] -* Disable client modifiers with amdgpu driver [Michel; !2637] -* Cancel pointer gesture on wl_pointer.leave [Carlos; !2640] -* Add black padding to fixed-size wayland fullscreen windows - [Jonas Å., Sebastian W.; !2338] -* Stop sending frame callbacks to minimized clients [Robert; !2662] -* Fix scrolling in clients with no hi-res scroll support in RDP [José; !2664] -* Fix skipped low-res scroll events with some high-res mice [José; !2668] -* Throttle interactive move and resize updates [Jonas Å.; !2652] -* wayland-keyboard: Send pressed keys on enter [Jonas Å.; !2657] -* Fix some X11 windows getting unredirected erroneously [Sebastian K.; !2651] -* Fix Flatpak applications bypassing X11 permission [msizanoen1; !2633] -* Fix always visible cursor in virtual streams [Salman; !2629] -* Fixed crashes [Jonas Å., Sebastian W., Max, Carlos, Łukasz; !2616, !2627, - !2646, !2661, !2655, !2669, !2676] -* Misc. bug fixes and cleanups [Daniel, Jonas Å., Sebastian W., Ivan, Marco, - Florian, Carlos, Jonas D.; !2615, !2619, !2590, !2630, !2515, !2656, - !2659, !2670, !2667, !2678] - -Contributors: - Marco Trevisan (Treviño), Jonas Dreßler, Michel Dänzer, José Expósito, - Carlos Garnacho, Sebastian Keller, Robert Mader, Salman Malik, - Ivan Molodetskikh, Florian Müllner, Łukasz Spintzyk, Daniel van Vugt, - Sebastian Wick, Max Zhao, msizanoen1, Jonas Ådahl - -Translators: - Baurzhan Muftakhidinov [kk], Sabri Ünal [tr], Pawan Chitrakar [ne], - Jürgen Benvenuti [de], Nart Tlisha [ab], Fabio Tomat [fur], - Quentin PAGÈS [oc], Freddy Cheng [zh_TW], Мирослав Николић [sr], - Nathan Follens [nl] - -43.0 -==== -* Fix stuttering in Xorg session [Daniel; !2625] -* Make MetaBarrier type derivable again [Jonas; !2626] -* Fixes crash [Jonas; !2622] - -Contributors: - Daniel van Vugt, Jonas Ådahl - -Translators: - Aleksandr Melman [ru], Fran Dieguez [gl], Daniel Mustieles [es], - Aurimas Černius [lt], Matej Urbančič [sl], Leônidas Araújo [pt_BR], - Kukuh Syafaat [id], Sveinn í Felli [is], Zurab Kargareteli [ka], - Rūdolfs Mazurs [lv], Yosef Or Boczko [he], Alexander Shopov [bg], - Alan Mortensen [da] - -43.rc -===== -* Remember monitor scale when switching configurations [Jonas Å.; !2479] -* Embed wayland output name into screencast streams [Salman; !2540] -* Limit precision of stored refresh rates [Daniel; !2465, !2602] -* Add support for the "max bpc" connector property [Daniel; !2412] -* Fix focus-tracking corner case [Jonas D.; !2329] -* Add detail to ::event signal [Jonas D.; !2431] -* Improve heuristics for adding fallback monitor modes [Mario; !2586] -* Take over color management from gnome-settings-daemon - [Jonas Å.; !2141, !2164, !2165, !2166, !2568] -* Allow scanout for offscreen rotated views [Robert; !2468] -* Fix hot corner regression on X11 [Jonas Å.; !2604] -* Fix losing IM focus in some circumstances [Carlos; !2585] -* Avoid swapping redundant portions of buffers onscreen [Erico; !2241] -* Animate windows moving between monitors [Alessandro; !2558] -* Make NVIDIA + gbm use atomic mode setting [Jonas Å.; !2578] -* Fixed crashes [Jonas Å., Steev, Carlos, Simon; !2554, !2577, !2592, !2182, - !2609, !2612] -* Plugged memory leak [Alessandro; !2608] -* Misc. bug fixes and cleanups [Florian, Carlos, Jordan, Simon, Jonas Å., - Jonas D., Daniel, Sebastian K., Alberts, Bilal, Dor, Sebastian W.; !2566, - !2573, !2576, !2534, !2581, !2430, !2561, !2584, !2588, !2551, !2552, !2594, - !2596, !2598, !2601, !2603, !2589, !2587, !2375, !2486, !2606, !1354, !2605, - !2611] - -Contributors: - Dor Askayo, Alessandro Bono, Jonas Dreßler, Bilal Elmoussaoui, - Carlos Garnacho, Sebastian Keller, Steev Klimaszewski, Mario Limonciello, - Robert Mader, Salman Malik, Simon McVittie, Alberts Muktupāvels, - Florian Müllner, Erico Nunes, Jordan Petridis, Daniel van Vugt, - Sebastian Wick, Jonas Ådahl - -Translators: - Nart Tlisha [ab], Jiri Grönroos [fi], Goran Vidović [hr], - Yuri Chornoivan [uk], Jordi Mas [ca], Marek Černocký [cs], Balázs Úr [hu], - Emin Tufan Çetin [tr], Danial Behzadi [fa], Piotr Drąg [pl], - Rūdolfs Mazurs [lv], Hugo Carvalho [pt], Anders Jonsson [sv], - Boyuan Yang [zh_CN], Asier Sarasua Garmendia [eu] - -43.beta -======= -* Fix glitches in apps using subsurfaces [Robert; !2501, !2530] -* Reduce client work when entering overview [Robert; !2502] -* Support direct scanout on GPUs without modifiers support [Dor; !2510] -* screencast: Set correct stride when using dmabufs [Pascal; !2513] -* High-resolution scroll wheel support [José, Carlos; !1962] -* screencast: Use flag to signal failed recording [columbarius; !2516] -* Fix cursor visibility on X11 with only tablets as input [Carlos; !2518] -* Notify about privacy screen changes via predictions [Jonas Å.; !2340, !2531] -* Highlight actors becoming reactive under the pointer [Carlos; !2532] -* Replace MetaTextureTower with native GL mipmapping [Daniel, Neil; !2506] -* Add tool to pretty print display configuration [Jonas Å., Marco; !2448] -* Remove mipmap framerate limiting [Daniel; !2538] -* Fall back to ARGB if XRGB is not supported [Daniel; !2519] -* Add basic color-scheme support for server-side decorations [Florian; !2541] -* Don't skip frames after skipped KMS updates [Michel; !2498] -* Add support for multi-monitor direct scanout [Dor; !2526] -* Continue gi-docgen migration [Bilal; !2441] -* Always send modifiers to clients if supported [Jonas Å.; !2546] -* Defer and accumulate redraw-clip on scanout [Robert; !2480] -* Add single pixel buffer support [Robert, Jonas Å.; !2246] -* Report actual monitor transform [Robert; !344] -* Better integrate cogl tests with existing infrastructure [Jonas Å.; !2555] -* Fix registering as X11 window manager if GDK_BACKEND is set [Michel; !2496] -* Don't skip vblank sync on missing presentation timestamp [Dor; !2481] -* Fix cursor showing on Xilinx [Daniel; !2520] -* Plugged leaks [Michel, Daniel; !2527, !2562] -* Fixed crashes [Robert, Jonas Å.; !2459, !2553] -* Misc. bug fixes and cleanups [columbarius, Daniel, Carlos, Michel, Jonas Å., - Florian, Jonas D., Julia, Corentin; !2323, !2074, !2517, !2525, !2524, !2442, - !2523, !2535, !2348, !2537, !2456, !2542, !2547, !2556, !2559, !2564, !2511] - -Contributors: - Marco Trevisan (Treviño), Dor Askayo, Jonas Dreßler, Michel Dänzer, - Bilal Elmoussaoui, José Expósito, Carlos Garnacho, Julia Johannesen, - Robert Mader, Neil Moore, Florian Müllner, Pascal Nowack, Corentin Noël, - Nart Tlisha, Daniel van Vugt, columbarius, Jonas Ådahl - -Translators: - Nart Tlisha [ab] - -43.alpha -======== -* Drop zenity dependency [Bilal; !2370] -* Fix initialization of privacy mode in displays that support it [Marco; !2372] -* Add NightLightSupported property to DisplayConfig [Jonas; !2310] -* Don't use direct scanout for transparent windows [Sebastian K.; !2409] -* Improve picking a window for direct scanout [Sebastian K.; !2413] -* Drop support for obsolete wayland protocols [Fernando; !2207, !2184] -* Fix --replace again [Jonas; !2432] -* Do not allow windows to steal focus when the shell has a grab [Carlos; !2433] -* Fix night light without GAMM_LUT property [Jonas; !2435] -* Expose Cogl's Snippet API to introspection [Simon; !2422] -* wayland: Fix rotation transform [Robert; !1055] -* Build and deploy API documentation [Bilal; !2427] -* Attach color state information to actors [Naveen; !2443] -* Fix pointer confinement on HiDPI setups [Jonas; !2460] -* Fix dma-bufu screencast regression [Jonas; !2462] -* Fix monitor mirroring in some cases [Jonas; !2492] -* Parse HDR and Colorimetry CTA-861 EDID extension blocks [Sebastian W.; !2351] -* Fix cursor tracking during screencasts on X11 [George; !2474] -* Fixed crashes [Jonas, Florian; !2415, !2364, !2491] -* Plugged leaks [Michel, Sebastian K.; !2469, !2497] -* Misc. bug fixes and cleanups [Kazuki, Dor, Jonas, Bilal, Sebastian K., - Christian, Florian, Georges,, Sebastian W., Olivier; !2405, !2406, !2403, - !2416, !2398, !2414, !2425, !2354, !2436, !2447, !2446, !2355, !2429, !2417, - !2434, !2439, !2015, !2444, !2458, !2379, !2455, !2463, !2484, !2485, !2488, - !2499] - -Contributors: - Marco Trevisan (Treviño), Dor Askayo, George Barrett, Michel Dänzer, - Bilal Elmoussaoui, Olivier Fourdan, Carlos Garnacho, Kazuki Hashimoto, - Sebastian Keller, Naveen Kumar, Robert Mader, Fernando Monteiro, - Florian Müllner, Georges Basile Stavracas Neto, Christian Rauch, - Simon Schneegans, Sebastian Wick, Jonas Ådahl - -Translators: - Zurab Kargareteli [ka], Pawan Chitrakar [ne] - -42.1 -==== -* Send correct LEAVE events when entering windows [Jonas D.; !2321] -* Be more forgiving with wrongly sized clients [Robert; !2335] -* Add ClutterInputCapabilities enum and device property [Carlos; !2331] -* Fall back if COPY_MODE_SECONDARY_GPU fails to init [Daniel; !2341] -* Fix missing root window properties after XWayland start [Olivier; !2336] -* wayland/shm: Add support for ABGR8888 and XBGR8888 formats [Jonas Å.; !2352] -* Keep actors dirty if a redraw was queued up during paint() [Carlos; !2353] -* Fix overview painting of shaped texture with layer snippets [Jonas Å.; !2278] -* Survive missing GAMMA_LUT KMS property [Daniel; !2360] -* Record current event when going through event filters [Jonas D.; !2327] -* Pass events to pointer a11y before going through filters [Jonas D.; !2332] -* Update cursor when scaled or transformed [Sebastian W.; !2363] -* Fix screen cast when DMA buffer fails or can't be used [Jonas Å.; !2383] -* Repick when pointer actor goes unmapped [Jonas D.; !2333] -* Improve IM support [Carlos; !2365, !2384] -* Allow using dumb buffers for cursor sprites [Jonas Å.; !2275] -* wayland/dma-buf: Only advertise supported formats [Robert; !2386] -* Fix screen cast cursor metadata with unthrottled input [Jonas Å.; !2393] -* Fixed crashes [Olivier Daniel, Łukasz, Jonas D.; !2339, !2359, !2347, !2299] -* Plugged memory leak [Sebastian K.; !2345] -* Misc. bug fixes and cleanups [Christian, Jonas Å., Bartłomiej, Carlos, Daniel, - Sebastian W., Corentin, Jonas D., Sebastian K.; !2316, !2152, !2334, !2349, - !2325, !2357, !2362, !2373, !2374, !2361, !2366, !2350, !2377, !2382, !2391, - !2395, !2387, !2400, !2397, !2378] - -Contributors: - Jonas Dreßler, Bilal Elmoussaoui, Olivier Fourdan, Carlos Garnacho, - Christian Hergert, Sebastian Keller, Robert Mader, Florian Müllner, - Corentin Noël, Bartłomiej Piotrowski, Łukasz Spintzyk, Daniel van Vugt, - Sebastian Wick, Jonas Ådahl - -Translators: - Balázs Úr [hu], Charles Monzat [fr], Milo Casagrande [it], Марко Костић [sr], - Nathan Follens [nl], Jordi Mas [ca], Ngọc Quân Trần [vi] - -42.0 -==== - -Translators: - Fabio Tomat [fur], Alexander Shopov [bg] - -42.rc -===== -* Fix X11 → wayland drops ending up in the wrong wayland client [Olivier; !2305] -* Make xdg-activation interoperate with other startup sequences [Carlos; !2314] -* Fix stuck grab feedback actor during compositor grabs [Jonas D.; !2308] -* Make gnome-desktop dependency optional [Bilal; !2317] -* Provide better profiling information [Ivan; !1928] -* Drop ClutterEvent "source" field [Carlos; !2311] -* Add support for xdg_toplevel.configure_bounds() [Jonas Å.; !2167] -* Add support for wl_surface.offset [Jonas Å.; !1905] -* Fix resizing of virtual monitors [Jonas Å.; !2270] -* Include size in configure events of maximized clients [Sebastian K.; !2238] -* Only allow direct scanouts for surfaces that aren't cropped, scaled or rotated - [Robert; !2276] -* Fix pipewire screencasts [Ivan; !2322] -* Plugged memory leak [Robert; !2297] -* Fixed crash [Jonas; !2318] -* Misc. bug fixes and cleanups [Bilal, Jonas Å., Florian, Dor, Alfonso, - Sebastian W., Carlos, Jonas D.; !2306, !2300, !2301, !2303, !2307, !2315, - !2319, !2298, !2320, !2324] - -Contributors: - Dor Askayo, Jonas Dreßler, Bilal Elmoussaoui, Olivier Fourdan, - Carlos Garnacho, Sebastian Keller, Robert Mader, Ivan Molodetskikh, - Florian Müllner, Alfonso Sánchez-Beato, Sebastian Wick, Jonas Ådahl - -Translators: - Emin Tufan Çetin [tr], Yosef Or Boczko [he], Quentin PAGÈS [oc], - Christian Kirbach [de], Aurimas Černius [lt], Danial Behzadi [fa], - Daniel Mustieles [es], Alan Mortensen [da], Goran Vidović [hr], - Tim Sabsch [de], Anders Jonsson [sv], Gwan-gyeong Mun [ko], - Daniel Șerbănescu [ro], Piotr Drąg [pl] - -42.beta -======= -* Implement a new Clutter grab API [Carlos; !2068, !2099, !2100] -* Support KMS testing via QEMU [Jonas Å.; !2151] -* Generate API references with gi-docgen [Andy; !2248] -* Improve support for running from toolbx [Sebastian; !2254, !2261] -* Add support for privacy screen [Marco; !1952] -* Allow changing monitor configuration policy [Jonas Å.; !2030] -* Add support for XFixes ClientDisconnectMode [Olivier; !1794] -* Fix possible missed clicks on menus [Carlos; !2257] -* Place popups on the same monitor as the anchor rect [Jonas Å.; !2252] -* Announce DMA-BUF support via pipewire [columbarius; !1939] -* Raise the file descriptor limit of the wayland compositor [Olivier; !2235] -* Fix resetting idle time on lid open [Carlos; !2272] -* Don't limit DMA buffer screen casting only to Intel [Jonas Å.; !2086] -* Keep a single cursor sprite visible with tablets [Carlos; !285] -* Sync keyboard LEDs after layout changes [Konstantin; !2279] -* Honor window input area in picking [Carlos; !2283] -* Handle mixture of keycombo/no action in pad rings/strips [Carlos; !2001] -* Fixed crashes [Carlos, Jonas Å., Daniel; !2237, !2280, !2282, !2251] -* Misc. bug fixes and cleanups [Björn, Jonas Å., Daniel, Michel, Robert, - Pascal, Florian, Olivier, Pabel, Carlos, Jonas D.; !2236, !2014, !2240, - !2230, !2232, !2255, !2245, !2242, !2159, !2253, !2258, !2263, !2266, - !2271, !2256, !2264, !2262, !2281, !2287, !2284] - -Contributors: - Marco Trevisan (Treviño), Björn Daase, Jonas Dreßler, Michel Dänzer, - Olivier Fourdan, Carlos Garnacho, Pablo Correa Gómez, Andy Holmes, - Konstantin Kharlamov, Robert Mader, Florian Müllner, Pascal Nowack, - Daniel van Vugt, Sebastian Wick, columbarius, Jonas Ådahl - -Translators: - Yaron Shahrabani [he], Boyuan Yang [zh_CN], Marek Černocký [cs], - Aurimas Černius [lt], Kukuh Syafaat [id], Daniel Mustieles [es], - Yuri Chornoivan [uk], Hugo Carvalho [pt], Yosef Or Boczko [he], - Fran Dieguez [gl], Matheus Barbosa [pt_BR], Aleksandr Melman [ru], - sicklylife [ja], Luming Zh [zh_CN], Matej Urbančič [sl], - Leônidas Araújo [pt_BR], Asier Sarasua Garmendia [eu], - Jordi Mas i Hernandez [ca] - -42.alpha -======== -* Fix monitor screencast scanouts [Michel; !1914] -* dma-buf: Use alpha-less pixel formats where appropriate [Robert; !1810] -* wayland: Allow clients to maximize windows regardless of constraints - [Christian; !1997] -* Handle hotplug events without relevant changes more effectively [Marco; !1964] -* Improve error reporting when startup fails [Jonas; !1994] -* dma-buf: Add support for ABGR and XBGR formats [Erfan; !1999] -* Fix X11 middle button emulation setting [José; !2000] -* Include server-side shadows in window screenshots [Robert; !1996] -* Don't change workspaces of unmanaged windows [Sebastian; !2003] -* Reset idletime when unplugging the power cable [Bastien; !2029] -* xwayland: Avoid unnecessary _NET_WM_STATE events [Dor; !2032] -* Fix videos in Firefox stuttering in overview [Robert; !2034] -* Don't use atomic mode setting for virtio_gpu driver [Jonas; !2040] -* Improve on-screen keyboard on X11 [Sebastian, Ray; !1955, !2039] -* Fix text glitches after size changes [Sebastian; !2006] -* Fix reporting output rotation to xwayland [Olivier; !2050] -* wayland: Accept final preference of drop destination [Robert; !2043] -* Only add paint volumes of mapped actors to stage clip [Robert; !2035] -* Fix negative paint volume offscreen effect [Sebastian; !2031] -* Introduce MetaRenderDevice [Jonas; !1854] -* Prefer GBM over EGLStream where possible [Jonas; !2051, !2052] -* Fix erratic scrolling in GTK apps [Carlos; !2059] -* Use rtkit to get realtime priority [Carlos; !2060] -* Turn experimental features into flags [Robert; !1961] -* Add support for EGL_KHR_partial_update [Erico; !2023] -* Use b/w unicode for tablet mode OSD [Carlos; !2064] -* Fix tilt direction of pen/tablet inputs [Quytelda; !2065] -* Sanitize event handling at gestures [Carlos; !2024] -* Fix mapping tablet input to correct monitor [Jason; !1934] -* Optionally run (and exit) with a command [Mark; !1982] -* Fix key repeat of on-screen keyboard for 2nd-level keysyms [Ray; !2045] -* Copy damage rectangles to secondary GPU [Piotr; !2033] -* Fix window size after returning from fullscreen [Sebastian, Jonas; !2066] -* Fix blank screen when unplugging docking station [Jonas; !2097] -* Ensure constraints after client resize [Sebastian; !2103] -* Improve anti-aliasing of background corners [Daniel; !2102] -* Fix unredirected Xwayland windows not getting updated [Michel; !2112] -* Fix DND between X11 and wayland clients [Carlos; !2124] -* Add hold gestures [José; !1830] -* Always snoop key events for a11y [Carlos; !1328] -* Improve Wacom tablet mapping [Carlos; !2107] -* Allow adding more streams to a screen cast session [Jonas; !2131] -* Do not throttle input in wayland event delivery [Carlos; !1915] -* Allow forcing EGLStream backend [Jonas; !2132] -* Check keyboard serials for activation [Carlos; !2148] -* Rebind the EGL image when handling damage [Neil; !2062] -* Do not pass events to windows with modal transients [Florian; !2123] -* Fix mixed up refresh rates in multi-monitor setups [Robert; !2169] -* Fix orientation changes on devices with 90° [Hans, Marco; !2090] -* Allow disabling HW cursors [Olivier; !2150] -* Improve damage handling [Robert; !2168] -* Consider xrandr flags for advertised modes [Robert; !2190] -* Improve KMS fallback modes [Robert; !2189] -* window-group: Disable culling when rendinging clone to offscreen buffer - [Sebastian; !2080] -* Support DMA buffer feedback [Jonas, Robert; !2202, !1959] -* Advance timelines according to presentation time [Daniel; !2161] -* Drop deprecated wl-shell and text-input-v3 support [Fernando; !2183, !2185] -* Fix workspace switch animation in default plugin [Mark, Erik; !2076, !2120] -* Fix unfullscreening of window that were mapped fullscreen [Jonas; !2210] -* Consider wayland subsurfaces for scanout [Robert; !2211] -* Fix DMA-BUF screencasts with unredirected fullscreen windows [Georges; !2186] -* Fixed crashes [Carlos, Jonas, Daniel; !2063, !2025, !2081, !2104, !1991, - !2111, !2127, !2147, !2181, !2216] -* Plugged leaks [Sebastian, Jonas; !2193, !2192, !2225] -* Misc. bug fixes and cleanups [Daniel, Jonas, Corentin, Robert, Georges, - Sebastian, Simon, Carlos, Pascal, Fernando, Joan, José, Florian, Alexander, - Ievgen; !1992, !2007, !2008, !2026, !2044, !2057, !2002, !2028, !2049, !2061, - !1796, !2079, !2084, !2088, !2093, !2009, !2094, !2108, !2125, !2133, !2128, - !2138, !2058, !2130, !2140, !2122, !2095, !2126, !2139, !2145, !2149, !2157, - !1966, !2163, !2158, !2134, !1993, !2142, !2162, !2173, !2187, !2199, !2203, - !2204, !2205, !2146, !1812, !2214, !2215, !2188, !2206] - -Contributors: - Marco Trevisan (Treviño), Erfan Abdi, Dor Askayo, Michel Dänzer, - José Expósito, Olivier Fourdan, Carlos Garnacho, Jason Gerecke, Hans de Goede, - JoseExposito, Quytelda Kahja, Sebastian Keller, Robert Mader, Mark, - Erik Massop, Simon McVittie, Alexander Mikhaylenko, Fernando Monteiro, - Florian Müllner, Georges Basile Stavracas Neto, Bastien Nocera, Pascal Nowack, - Corentin Noël, Erico Nunes, Ievgen Popovych, Christian Rauch, Neil Roberts, - Ray Strode, Joan Torres, Daniel van Vugt, Jonas Ådahl, Piotr Łopatka - -Translators: - eshagh shahidani [fa], Danial Behzadi [fa], Марко Костић [sr], - Zander Brown [en_GB], Ngọc Quân Trần [vi], Rūdolfs Mazurs [lv], - Yuri Chornoivan [uk], Fabio Tomat [fur], Hugo Carvalho [pt], - Milo Casagrande [it], Quentin PAGÈS [oc], Goran Vidović [hr], - Yaron Shahrabani [he], Daniel Mustieles [es], Aleksandr Melman [ru], - Aurimas Černius [lt], Sveinn í Felli [is], Kukuh Syafaat [id], - Asier Sarasua Garmendia [eu] - -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 committing 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 ClutterAlignConstraint:pivot-point property [Jonas D.; !737] -* Fix crash on area screenshots with fractional scaling [Sebastian; !1320] -* Do not paint textures of fully obscured windows [Robert; !1326] -* Use a more appropriate combine function on opaque areas [Daniel; !1331] -* Fix remote desktop being broken without screencast session [Olivier; #1307] -* Remove more long-deprecated Clutter APIs [Adam, Georges; !1194, !1332] -* Drive each monitor by its own frame clock [Jonas Å.; !1285] -* Fix copy/paste failures on X11 [Carlos; !1350] -* Mipmap background texture rendering [Daniel; !1347] -* Plugged memory leaks [Sebastian, Jonas D.; !1293, !1281, !1304] -* Misc. bug fixes and cleanups [Jonas Å., Jonas D., Daniel, Corentin, Carlos, - Sebastian, Michel, Robert, Florian; !1288, !1289, !1291, !1296, !1292, !1298, - !1300, !1303, !1290, !1287, !1306, !1305, !1308, !1313, !1250, !1314, !1267, - !1275, !1317, !1270, !1322, !1181, !1282, !1325, !1323, !1240, !1295, !1329, - !1333, !1334, !1336, !1341, #1312, !1345, !1349, !1356, #873, !1310, !1357] - -Contributors: - Jonas Dreßler, Michel Dänzer, Olivier Fourdan, Carlos Garnacho, - Peter Hutterer, Adam Jackson, Sebastian Keller, Robert Mader, Florian Müllner, - Georges Basile Stavracas Neto, Corentin Noël, Daniel van Vugt, Jonas Ådahl - -3.37.2 -====== -* Fix move-to-center keybinding with multiple monitors [Sergey; #1073] -* Fix stuck buttons when a virtual device is destroyed [Carlos; !1239] -* Use workarea when centering new windows [Akatsuki; #964] -* Limit mipmap levels when rendering background [Daniel; !1003] -* Broadcast clipboard/primary offers [Carlos; !1253] -* Support primary-selection protocol from wayland-protocols [Carlos; !1255] -* Fix monitor screen cast on X11 [Jonas Å.; !1251] -* Support a "blank" cursor type [Florian; !1244] -* Improve stage view damage tracking [Jonas Å.; !1237] -* Implement touch-mode detecation for the X11 backend [Carlos; !1278] -* Drop external keyboard detection from touch-mode heuristics [Carlos; !1277] -* Optimize actor allocations [Jonas D.; !1247] -* Fixed crashes [Daniel, Carlos, Jonas Å., Jonas D.; !1256, !1258, !1217, !1280] -* Misc. bug fixes and cleanups [Christian, Jonas D., Olivier, Ting-Wei, - Jonas Å., Marco, Corentin, Daniel, Robert, Niels, Florian, Simon; !1231, - !1228, !1238, !1229, !1192, !1236, !1171, !1134, #1126, !1234, !1230, !1210, - !1242, !1243, !1252, !1113, !1232, !1259, !1245, !1265, !1180, !1261, !788, - !1264, !1235, !1218, !1150, !1274, !1271, !1279, !1283, !1272] - -Contributors: - Marco Trevisan (Treviño), Akatsuki, Jonas Dreßler, Olivier Fourdan, - Carlos Garnacho, Niels De Graef, Ting-Wei Lan, Robert Mader, Simon McVittie, - Florian Müllner, Corentin Noël, Christian Rauch, Daniel van Vugt, - Sergey Zigachev, Jonas Ådahl - -3.37.1 -====== -* Fix screencasting non-maximized windows [Jonas Å.; !1174] -* Make window-aliveness checks less aggressive [Jonas Å.; !1182] -* Fix stylus coordinates when using screen rotation [Jonas T.; #1118] -* Preserve keyboard state on VT switch [Olivier; !1185] -* Remove Clutter's drag and drop actions [Jonas D.; !789] -* Cancel clicks/gestures actions on disable [Georges; !1188] -* Fix various clipboard issues [Carlos; !1186, !1198, !1203, !1204, !1206] -* Fix trackball button scrolling [Phillip; #1120] -* Fix tiled monitor support [Jonas; !1199] -* Support unredirecting fullscreen wayland surfaces [Jonas Å.; !798] -* Support area screencasts [Jonas Å.; !1207] -* Synchronize shadows to server-side decorations [Olivier; !1214] -* Allow inhibiting remote access [Jonas Å.; !1212] -* Fix overview key on X11 when using multiple keyboard layouts [Olivier; !1219] -* Fixed crashes [Jonas, D., Carlos; !1173, !1183, !1012] -* Misc. bug fixes and cleanups [Andre, Georges, Christian, Jonas Å., Andre, - Simon, Florian, Carlos, Adam, Marco, Thomas, Elias, Pekka, Jonas D., - Laurent; !1169, !1168, !1166, !1170, !1167, !1172, !1175, !1176, !1184, - !1126, !1187, !1191, !1195, !1179, !1200, !1193, !1209, !1213, !1208, - #1074, !1223] - -Contributors: - Marco Trevisan (Treviño), Elias Aebi, Thomas Hindoe Paaboel Andersen, - Laurent Bigonville, Jonas Dreßler, Olivier Fourdan, Carlos Garnacho, - Adam Jackson, Andre Moreira Magalhaes, Simon McVittie, Florian Müllner, - Georges Basile Stavracas Neto, Pekka Paalanen, Christian Rauch, Jonas Troeger, - Phillip Wood, Jonas Ådahl - -Translators: - Dušan Kazik [sk], Christian Kirbach [de] - -3.36.0 -====== -* Fix placement of popup windows in multi-monitor setups [Jonas; !1110] -* Fix invisible mouse cursor on some hardware [Jonas; !1079] - -Contributors: - Jonas Ådahl - -Translators: - Aurimas Černius [lt], Goran Vidović [hr], Anders Jonsson [sv], - Guillaume Bernard [fr], Milo Casagrande [it], Daniel Korostil [uk], - Andre Klapper [cy], Aman Alam [pa], Nathan Follens [nl] - -3.35.92 -======= -* Fix visibility of initially hidden windows [Jonas Å.; !1066] -* Avoid flicker when (un)redirecting windows [Sebastian; #997] -* Let BindConstraints update the preferred size [Emmanuele; !1070] -* Learn about GLES3 [Adam; !882] -* Ping windows on every window focus [Jonas D.; !891] -* Remove overhead from hot code paths [Christian; - #1056, !1081, !1083, !1071, !1087] -* Allow remote desktop services to inhibit animations [Jonas Å.; !838] -* Update screen-cast code to PipeWire 0.3 API [Wim; !1062] -* Make check-alive timeouts configurable [Jonas Å.; !1080] -* Make each stage view correspond to a single CRTC [Jonas Å.; !1042] -* Implement scaled/transformed hardware cursors [Robert; !526] -* Use DMA buffers for screencasting if possible [Georges; !1086] -* Make Xwayland startup asynchronous [Carlos; !944] -* Fix clipping glitches in long text entries [Jonas D.; !1096] -* Add side channel for starting required X11 services [Carlos; !945] -* Support synchronized wayland popup moving [Jonas Å.; !705] -* Fixed crashes [Olivier, Jonas Å.; !1073, !1093] -* Plugged memory leaks [Sebastian, Jonas Å.; !1089, !1095] -* Misc. bug fixes and cleanups [Jonas Å, Olivier, Florian, Daniel, Jonas D., - Robert, Sebastian, Christian, Arun, Carlos, worldofpeace; !1061, #1043, - !1067, !1068, !1065, !835, !1058, !1069, !1075, #1060, !1077, !423, !1090, - !1088, !1094, #1067, !1064, !1099, !957, !1000, !1082] - -Contributors: - Emmanuele Bassi, Jonas Dreßler, Olivier Fourdan, Carlos Garnacho, - Christian Hergert, Adam Jackson, Sebastian Keller, Robert Mader, - Florian Müllner, Georges Basile Stavracas Neto, Arun Raghavan, Wim Taymans, - Daniel van Vugt, worldofpeace, Jonas Ådahl - -Translators: - Yi-Jyun Pan [zh_TW], Asier Sarasua Garmendia [eu], Rafael Fontenelle [pt_BR], - Emin Tufan Çetin [tr], Daniel Mustieles [es], Balázs Úr [hu], - Gwan-gyeong Mun [ko], Marek Černocký [cs], Fran Dieguez [gl], - Kukuh Syafaat [id], Alan Mortensen [da], Piotr Drąg [pl], sicklylife [ja], - Matej Urbančič [sl] - -3.35.91 -======= -* Honor accelerometer orientation on monitor config changes [Hans; !959] -* Enable culling for integer-scaled actors [Robert; !1036] -* Add ClutterSeat::touch-mode property [Carlos; !1044] -* Fix mis-scaling when streaming windows [Olivier; !1022] -* Make the cursor renderer use the transactional KMS API [Jonas; !930] -* Advertise MetaMonitor as wl_output [Olivier; !994] -* Fix culling of XWayland windows [Robert; !1049] -* Only consider enabled effects when disabling culling [Robert; !1052] -* Misc. bug fixes and cleanups [Olivier, Sergio, Adam, Carlos, Björn; !1040, - #985, !1024, !1039, !1051] - -Contributors: - Sergio Costas, Björn Daase, Olivier Fourdan, Carlos Garnacho, Hans de Goede, - Adam Jackson, Robert Mader, Jonas Ådahl - -Translators: - sicklylife [ja] - -3.35.90 -======= -* Cull out clip region [Robert; !985] -* Always enable tap-to-click/drag on opaque Wacom tablets [Carlos; !968] -* Fix visual glitches with offscreen effects applied [Georges; !992] -* Fix "sticky corner" in multi-head setups [Jonas D.; #774] -* Fix black shadows around XWayland windows during resizes [Ray, Olivier; #858] -* Zero-copy path for GPU-less secondary GPUs [Pekka; !810] -* Cancel DND on Esc [Carlos; #1020] -* Sync XWayland window shadows to frame during resizes [Olivier; !1009] -* Add support for per-monitor workareas [Alberts; !370] -* Ensure newly mapped wayland windows receive ENTER event [Olivier; !1026] -* Add ClutterSeat object [Carlos; !852] -* Honour CLUTTER_ACTOR_NO_LAYOUT flag more efficiently [Daniel; !575] -* Fix interoperation with wl_data_device_manager v1 [Carlos; #965] -* Favor text over images in clipboard manager [Carlos; #919] -* Apply monitor scale after background texture creation [Daniel; !1004] -* Plugged memory leaks [Sebastian, Adam; !991, #1000, !1011, !1020, !1030, - !1001, !1033] -* Fixed crashes [Jonas Å., Florian, Olivier; !961, #1029, !1037] -* Misc. bug fixes and cleanups [Björn, Jonas Å., Adam, Sebastian, Jonas D., - Daniel, Carlos, Corentin, Sebastian, Robert, Daniel; #385, !998, !1007, !995, - !1016, !1018, !1017, !1005, !1019, !1025, !1028, !1029, !1031, !1015, !1032, - !1034, #1025] - -Contributors: - Björn Daase, Jonas Dreßler, Olivier Fourdan, Carlos Garnacho, Adam Jackson, - Sebastian Keller, Robert Mader, Alberts Muktupāvels, Florian Müllner, - Georges Basile Stavracas Neto, Corentin Noël, Pekka Paalanen, Ray Strode, - Daniel van Vugt, Jonas Ådahl - -Translators: - sicklylife [ja], Umarzuki Bin Mochlis Moktar [ms] - -3.35.3 -====== -* backends/native: Correct dy value in pinch gesture event [Yariv; !974] -* Upload clipping rectangles in parallel [Daniel; !969] -* More cogl API cleanups [Adam; !978, !977, !973] -* Fix window recording on HiDPI [Pascal; !976] -* Fix top-left pixel being insensitive to clicks [Sebastian; #893] -* Misc. bug fixes and cleanups [Daniel, Adam; !979, !980] - -Contributors: - Yariv Barkan, Adam Jackson, Sebastian Keller, Pascal Nowack, Daniel van Vugt - -Translators: - Fran Dieguez [gl], Dz Chen [zh_CN] - -3.35.2 -====== -* Don't emit focus event after destruction [Marco; gnome-shell#1704, !860] -* Add a notion of pixel format planes [Niels; !858] -* Replace various Cogl/Clutter types with Graphene [Georges; !458] -* Improve CoglJournal [Georges, Jasper; !402] -* Split pick and paint [Georges; !865] -* Remove deprecated/unused cogl/clutter APIs [Adam; !866, !878, !879, !880, - !885, !900, !902, !904, !896, !913, !922, !883, !903, !921, !933, !819] -* Fix hang when opening not-responding dialog on Xorg [Carlos; !876] -* Allow changing Clutter debug flags at runtime [Georges; !862] -* Fix frozen grabs on Xorg after weeks of inactivity [Jonas; !886] -* Fix triggering popups from stylus devices o wayland [Carlos; #886] -* Fix fallback to GLES2 [Adam; #635] -* Fix buffer age checks on multiple monitors [Carlos; !906] -* Adjust to Sysprof API change [Christian; !908] -* Improve support for (X11) fullscreen games under wayland [Hans; !739] -* Support shadow framebuffers for offscreen rendering [Olivier; !877] -* Fix hang after interacting with desktop icons on X11 [Marco; !909] -* Don't double scale when getting absolute surface coordinates [Xiang; !915] -* Respect NET_WM_TRANSIENT_FOR for override-redirect windows [Marco; !920] -* Kill window effects on destroy [Robert; !924] -* Remove deprecated ClutterTexture [Jonas; !932] -* Use regions instead of bounding box for clipping and culling [Carlos; !867] -* Use partial damage for dma-buf and EGLImage buffers on wayland [Robert; #947] -* Do not stack transients underneath their always-on-top parent [Florian; #587] -* Add explicit paint/pick contexts [Jonas; !935] -* Fix KMS freeze after pageflip fallback [Pekka; !953] -* Fixed crashes [Robert, Carlos, Jonas, Marco, Hans, Tim; !856, !869, !912, - !895, !928, #591, !823, !960] -* Plugged memory leaks [Niels, Robert, Carlos, Marco; !847, !868, !873, #908] -* Misc. bug fixes and cleanups [Niels, Robert, Jonas, Marco, Carlos, Daniel, - Jan, Adam, Cosimo, Florian, Thomas, Georges, Hans, Corentin, Christian, - Benjamin; !853, !822, !451, !854, !816, !857, !859, !734, !844, !851, #876, - !874, !673, !692, !888, !889, !894, !901, !905, !872, !898, !911, !918, !863, - #878, !811, !893, !925, !926, !890, !931, !927, !934, !938, !940, !947, !941, - !929, !949, !952, !871, !955, !956, !958, !907, !965, !964, !966] - -Contributors: - Marco Trevisan (Treviño), Jan Alexander Steffens (heftig), - Thomas Hindoe Paaboel Andersen, Benjamin Berg, Cosimo Cecchi, Tim Crawford, - Piotr Drąg, Xiang Fan, Olivier Fourdan, Carlos Garnacho, Hans de Goede, - Niels De Graef, Christian Hergert, Adam Jackson, Robert Mader, - Florian Müllner, Georges Basile Stavracas Neto, Bastien Nocera, Corentin Noël, - Pekka Paalanen, Jasper St. Pierre, Christian Rauch, Daniel van Vugt, - Jonas Ådahl - -Translators: - Bruce Cowan [en_GB] - -3.35.1 -====== -* Fix immediate screen blank after releaseing inhibitor [Tim; #573] -* Respond to frame callbacks regardless of damage [Jonas; !839] -* selection [Carlos; !842] -* Fix Night Light on wayland [Jonas; !840] -* Fix various copy+paste/DND regressions [Carlos; !848, #789, #842, - #793, #845, #854] -* Misc. bug fixes and cleanups [Daniel, Marco, Jonas, Georges; - !841, !764, !837, !846] - -Contributors: - Marco Trevisan (Treviño), Carlos Garnacho, Tim Klocke, - Georges Basile Stavracas Neto, Daniel van Vugt, Jonas Ådahl - -3.34.1 -====== -* Fix startup of X11 session services on wayland [Carlos; #771] -* Fix _NET_ACTIVE_WINDOW emission [Carlos; #751] -* Fix initial view perspective [Marco; !803] -* Fix screenshots and window animations when scaled [Robert; !758] -* Re-enable coredumps when capabilities are set [Jonas; !811] -* Fix scaling of DND surface actors [Robert; !780] -* Optimize blitting of untransformed offscreen stage views [Olivier; !809, !820] -* Fix freeze of pointer event delivery on X11 [Olivier; !821] -* Fix scaling of stylus input coordinates with HiDPI [Dorian; !830] -* Fix memory leak when using implicit animations [Jonas; !828] -* Fix numlock state for native backend [Carlos; #769] -* Fixed crashes [Marco, Olivier, Jonas Å.; !805, #823, !808, !825, - #844, !826, #779] -* Misc. bug fixes and cleanups [Jonas Å., Georges, Jonas D., Michal, Daniel, - Iain, Adam, Marco, Carlos, Ting-Wei, Hans, Robert; !787, !795, !791, !797, - !772, !775, !799, !778, !785, !782, !796, #819, !814, !769, !817, !783, !786, - !829, !774, #822] - -Contributors: - Marco Trevisan (Treviño), Jonas Dreßler, Olivier Fourdan, Carlos Garnacho, - Hans de Goede, Adam Jackson, Ting-Wei Lan, Iain Lane, Michal Lazo, - Robert Mader, Georges Basile Stavracas Neto, Dorian Stoll, Daniel van Vugt, - Jonas Ådahl - -Translators: - Milo Casagrande [it], Nathan Follens [nl], Matej Urbančič [sl], - Ask Hjorth Larsen [da], Alan Mortensen [da], Jordi Mas [ca] - -3.34.0 -====== -* Fix xdg-output v3 support [Olivier; !771] -* Fix crash when changing decoration state [Jonas; !773] -* Add and remove connectors on hot-plug [Jonas; !743] - -Contributors: - Olivier Fourdan, Jonas Ådahl - -Translators: - Rafael Fontenelle [pt_BR], Gwan-gyeong Mun [ko], Christian Kirbach [de], - Claude Paroz [fr], Milo Casagrande [it], Emin Tufan Çetin [tr], - Ryuta Fujii [ja] - -3.33.92 -======= -* Turn MetaShapedTexture into a ClutterContent implementation [Georges; !409] -* Restore inhibit shortcut for overlay key [Olivier; #734] -* Misc. pointer a11y improvements [Jonas D., Olivier; !746, !747, !745, !761] -* Fix position of drag surfaces [Robert; !684] -* Implement subsurface.place_below() for parents [Robert; !664] -* Add meta_window_actor_get_image() [Jonas Å.; !752] -* Revert faulty optimization from !719 [Jonas Å.; #735] -* Add additional sysprof trace points [Jonas Å.; !757, !765] -* Remove GLX "threaded swap wait" used on Nvidia [Daniel; !602] -* Implement geometric picking [Daniel; !189] -* Fix lost keyboard focus after DND [Olivier; #747] -* Misc. bug fixes and cleanups [Florian, Carlos, Piotr, Hans, Georges, Robert, - Ray, Mart, Rémi; !740, !672, !749, !751, !753, !730, !755, !756, !750, !715, - #738944, !657, !768] - -Contributors: - Jonas Ådahl, Rémi Bernon, Piotr Drąg, Jonas Dreßler, Olivier Fourdan, - Carlos Garnacho, Hans de Goede, Robert Mader, Florian Müllner, - Georges Basile Stavracas Neto, Mart Raudsepp, Ray Strode, Daniel van Vugt - -Translators: - Piotr Drąg [pl], Марко Костић [sr], Rūdolfs Mazurs [lv], Matej Urbančič [sl], - Balázs Úr [hu], Fran Dieguez [gl], Jordi Mas [ca], Anders Jonsson [sv], - Trần Ngọc Quân [vi], Tim Sabsch [de], Fabio Tomat [fur], Goran Vidović [hr], - Marek Černocký [cs] - -3.33.91 -======= -* Fix primary selection copy and paste between X11 and wayland [Hans; #702] -* Improve monitor hotplug support [Hans; !713] -* Remove a source of frame skips [Daniel; !719] -* Fix windows being lowered after unmaximizing with double click [Olivier; #88] -* Remove Clutter API for global grabs [Jonas D.; !536] -* Improve processing of incompressible events [Daniel; !711] -* Add xdg-output v3 support [Olivier; !704] -* Misc. bug fixes and cleanups [Jonas Å., Marco, Carlos, Adam, Albert, Niels, - Olivier, Florian; !722, !385, !728, !726, !500, !731, !727, !700, !735, !738] - -Contributors: - Jonas Ådahl, Albert Vaca Cintora, Jonas Dreßler, Olivier Fourdan, - Carlos Garnacho, Hans de Goede, Niels De Graef, Adam Jackson, Florian Müllner, - Marco Trevisan (Treviño), Daniel van Vugt - -Translators: - Asier Sarasua Garmendia [eu], Kukuh Syafaat [id], Florentina Mușat [ro], - Aurimas Černius [lt], Daniel Mustieles [es] - -3.33.90 -======= -* Fix visibility of clones with hidden source [Florian; #683] -* Reduce freezes when opening some popup windows [Carlos; #556] -* Be more thorough when excluding obscured areas from painting [Carlos; !698] -* Make it possible to start Xwayland on demand [Carlos; !709] -* clutter: Expose layout_manager to transitions [Florian; !716] -* Misc. bug fixes and cleanups [Mark, Florian, Iain, Niels, Carlos, Ray; !671, - !691, !694, !696, !703, !707, !697, !710, !708, !714, #719, !721] - -Contributors: - Mark Blakeney, Carlos Garnacho, Niels De Graef, Iain Lane, Florian Müllner, - Ray Strode - -Translators: - Asier Sarasua Garmendia [eu], Rafael Fontenelle [pt_BR], Fabio Tomat [fur], - Florentina Mușat [ro] - -3.33.4 -====== -* Discard page flip retries on hotplug [Jonas; !630] -* Add xdg-output v2 support [Olivier; #645] -* Restore DRM format fallbacks [Jonas; !662] -* Don't emit ::size-changed when only position changed [Daniel; !568] -* Expose workspace layout properties [Florian; !618] -* Don't use grab modifiers when shortcuts are inhibited [Olivier; #642] -* Fix stuttering due to unchanged power save mode notifications [Georges; !674] -* Add API to reorder workspaces [Adam; !670] -* Make picking a new focus window more reliable [Marco; !669] -* Defer actor allocation till shown [Carlos; !677] -* Try to use primary GPU for copy instead of glReadPixels [Pekka; !615] -* Unset pointer focus when the cursor is hidden [Jonas D.; !448] -* Fix modifier-drag on wayland subsurfaces [Robert; !604] -* Fix background corruption on Nvidia after resuming from suspend [Daniel; !600] -* Only grab the locate-pointer key when necessary [Olivier; !685, #647] -* Misc. bug fixes and cleanups [Florian, Jonas, Daniel, Robert, Olivier, - Georges, Marco, Carlos, Emmanuele; !648, !650, !647, !656, !658, !637, - !663, !660, !659, !665, !666, !668, !667, #667, !676, !678, #672, !680, - !683, !688, !689, !687] - -Contributors: - Jonas Ådahl, Emmanuele Bassi, Adam Bieńkowski, Piotr Drąg, Jonas Dreßler, - Olivier Fourdan, Carlos Garnacho, Robert Mader, Florian Müllner, - Georges Basile Stavracas Neto, Pekka Paalanen, Marco Trevisan (Treviño), - Daniel van Vugt - -Translators: - Fabio Tomat [fur], Kukuh Syafaat [id] - -3.33.3 -====== -* Prepare for running Xwayland on demand [Carlos; !420] -* Fix text selection color rendering [Florian; #494] -* Fix black shadows when using fractional scaling [Robert; #609] -* Honor startup sequence workspace on wayland [Carlos; gnome-shell#674] -* Only emit 'grab-op-end` signal after dropping grabs [Marco; !596] -* Add a Sysprof-based profiler [Jonas, Georges; !197, !603] -* Relax "xwayland-allow-grabs" setting [Olivier; #597] -* Implement locate-pointer accessibility feature [Olivier; !453] -* Implement mouse accessibility [Olivier; !512] -* Consolidate frame throttling [Daniel, Georges; !363] -* Fix setting blank cursor under wayland [Jonas; #630] -* Pixel-align OpenGL cursors [Jonas; !610] -* Handle returning from fullscreen/maximization better [Jonas; !621] -* Improve screencast support on multi-monitor systems [Georges; !623] -* Fix running X11 applications with sudo under wayland [Hans; #643] -* Implement toggle-keys notification [Olivier; #637] -* Add initial KMS transactional support [Jonas; !525] -* Improve finding new focus window when the old one is closed [Marco; #308] -* Misc. bug fixes and cleanups [Jonas, Carlos, Marco, Florian, Pekka, Robert, - Douglas, Georges, Daniel, Emil, Niels, Hans, Olivier, Ting-Wei, Corentin; - !591, #398, !592, !581, !597, !598, !593, !497, #591, !545, gtk#1675, !601, - #568, !564, !605, !609, !115, !214, !611, !617, !616, !619, !624, !622, !627, - !628, !629, !632, !633, !631, !636, !639, !638, !634, !640, !529, !644, !590] - -Contributors: - Jonas Ådahl, Piotr Drąg, Olivier Fourdan, Carlos Garnacho, Hans de Goede, - Niels De Graef, Ting-Wei Lan, Robert Mader, Florian Müllner, - Georges Basile Stavracas Neto, Corentin Noël, Pekka Paalanen, Douglas R. Reno, - Marco Trevisan (Treviño), Emil Velikov, Daniel van Vugt - -Translators: - Balázs Úr [hu], Daniel Mustieles [es], Nathan Follens [nl], Goran Vidović [hr] - -3.33.2 -====== -* Fix rendering lag on Xorg [Daniel; !520, !281] -* Misc. bug fixes and cleanups [Carlos, Marco, Jonas D., Florian, Niels, - Daniel, Benjamin, Jonas Å., Ignacio, Vasilis; #598, !576, !547, !578, - !583, !582, !469, !524, !119, !571, !584, !585, !586, #425] - -Contributors: - Jonas Ådahl, Benjamin Berg, Jonas Dreßler, Carlos Garnacho, Niels De Graef, - Vasilis Liaskovitis, Florian Müllner, Ignacio Casal Quinteiro, - Marco Trevisan (Treviño), Daniel van Vugt - -Translators: - Daniel Mustieles [es] - -3.33.1 -====== -* Remove unused APIs and outdated driver support - [Adam; !481, !468, !489, !487, !546] -* Enable EGL_IMG_context_priority [Adam; !454] -* Disable mouse keys with Numlock on [Olivier; #530] -* Fix crash when restarting on X11 [Marco; #576] -* Implement clipboard manager [Carlos; !320] -* Fix spurious idle signals that prevent session unblank [Jonas Å.; !543] -* Fix mapping of touchscreens that don't report dimensions [Carlos; #581] -* Fix propagating fractional scaling factor [Robert; !537] -* Add experimental RT scheduling support [Carlos; !460] -* Misc. bug fixes and cleanups [Robert, Carlos, Olivier, Ray, Marco, Jonas D., - Georges, Daniel V., Daniel M; !467, !504, !551, !552, #575, #556, !557, !442, - !562, !535, !548, #586, !567, !396, !422, !507] - -Contributors: - Jonas Ådahl, Piotr Drąg, Jonas Dreßler, Olivier Fourdan, Carlos Garnacho, - Adam Jackson, Robert Mader, Daniel García Moreno, Florian Müllner, - Georges Basile Stavracas Neto, Ray Strode, Marco Trevisan (Treviño), - Daniel van Vugt - -Translators: - Daniel Mustieles [es], Fabio Tomat [fur], Kukuh Syafaat [id] - -3.32.1 -====== -* Fix fallback app menu on wayland [Florian; #493] -* Fix elogind support [Tom; !491] -* Fix startup notifications not timing out [Carlos; #501] -* Fix keyboard accessibility toggle from keys - [Olivier, Carlos; !501, #529, !531] -* Fix touchscreen input on rotated displays [Carlos; #514] -* Work around hangul text input bug [Carlos; #1365] -* Fix blurry wallpaper scaling [Daniel; !505] -* Fix placement of window menu when using fractional scaling [Jan; #527] -* Fix repaint issues of offscreen effects on secondary monitors [Daniel; !511] -* Fix windows not getting focus after launch [Daniel; #505] -* Properly advertise support for 'underscan' property [Jonas; !507] -* Improve power-saving handling [Jonas; !506] -* Fix moving windows by super+touch [Jonas D.; !495] -* Misc. bug fixes and cleanups [Benjamin, Florian, Adam, Marco, Pablo, - Erik, Jonas, Heiher, Pekka, Daniel, Olivier, Carlos; !478, !475, !480, - !482, #490, !488, #491, #480, !477, !496, !492, !485, !515, !519, !521, - !216, !538, #541, #523] - -Contributors: - Jonas Ådahl, Pablo Barciela, Benjamin Berg, Tom Briden, Jonas Dreßler, - Olivier Fourdan, Carlos Garnacho, Jan Alexander Steffens (heftig), Heiher, - Adam Jackson, Erik Kurzinger, Florian Müllner, Pekka Paalanen, - Marco Trevisan (Treviño), Daniel van Vugt - -Translators: - Khaled Hosny [ar], Goran Vidović [hr], Daniel Mustieles [es] - -3.32.0 -====== -* Fix deadlock when cancelling a theme sound [Andrea; !474] -* Stop swizzling BGRA buffers (bye-bye inverted colors in screenshots - and animations) [Carlos; !486] - -Contributors: - Andrea Azzarone, Carlos Garnacho, Robert Mader - -3.31.92 -======= -* Fix flicker of apps that use multiple SHM buffers [Jonas Å.; #199] -* Don't disable page flips after temporary failures [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] -* Add fractional scaling support [Marco, Jonas Å.; !3] -* Consider remapped keys when guessing keycode from keysym [Andrea; #443] -* Stop turning on-screen-keyboard off on focus changes [Carlos; !432] -* Fix crashes [Robert, Carlos, Jonas D., Florian; !447, #361, !426, #479] -* Misc. bug fixes and cleanups [Benjamin, Adam, Olivier, Niels, Piotr; !457, - !452, !459, !380, !361, !461, !464, !471, !473, !463] - -Contributors: - Jonas Ådahl, Andrea Azzarone, Benjamin Berg, Piotr Drąg, Jonas Dreßler, - Olivier Fourdan, Carlos Garnacho, Niels De Graef, Adam Jackson, Robert Mader, - Florian Müllner, Marco Trevisan (Treviño) - -Translators: - Milo Casagrande [it], Tim Sabsch [de], Trần Ngọc Quân [vi], - Gwan-gyeong Mun [ko], Марко Костић [sr], Daniel Mustieles [es], - Rūdolfs Mazurs [lv], Nathan Follens [nl] - -3.31.91 -======= -* Fix infinite loop in EDID matching [Marco; #459] -* wayland: Don't resetin text-input state prematurely [Carlos; !410] -* wayland: Don't maximize windows if minimum size is too big [Olivier; #463] -* Fix crash when using "restore shortcuts" without focus window [Olivier; #464] -* Add flag parameter to grab accelerator API [Andrea; !169] -* Reuse old CRTC if possible to avoid flicker on hotplug [Pekka, Emilio; #373] -* Misc. bug fixes and cleanups [Marco, Jonas, Niels, Adam, Olivier; !436, - !421, #462, !439, !440, !444, !321, !445, !456] - -Contributors: - Jonas Ådahl, Andrea Azzarone, Olivier Fourdan, Carlos Garnacho, - Niels De Graef, Adam Jackson, Emilio Pozuelo Monfort, Pekka Paalanen, - Marco Trevisan (Treviño) - -Translators: - Jiri Grönroos [fi], Charles Monzat [fr], Claude Paroz [fr], Fran Dieguez [gl], - Emin Tufan Çetin [tr], Aurimas Černius [lt], Anders Jonsson [sv], - Matej Urbančič [sl], Marek Cernocky [cs], Daniel Șerbănescu [ro], - Alan Mortensen [da], Baurzhan Muftakhidinov [kk], Yi-Jyun Pan [zh_TW], - Daniel Mustieles [es], Rafael Fontenelle [pt_BR] - -3.31.90 -======= -* Fix support of extended characters in on-screen keyboard [Andrea; #109] -* Improve selection of the primary GPU [Pekka, Emilio; !271] -* Screen-cast cursor updates as PipeWire stream metadata [Jonas; !357] -* Fix rendering glitches in magnifier [Daniel; gnome-shell#387] -* Fix monitor recording on HiDPI [Jonas; !415] -* Honour secondary GPU supported pixel formats [Pekka; !341] -* Fall back to CPU copy path when using a software renderer [Emilio; !325] -* Remove fallback app menu [Florian; gnome-shell#624] -* wayland: Add support for viewporter protocol [Robert; !323] -* Misc. bug fixes and cleanups [Florian, Carlos, Olivier, Marco, Robert, - Daniel, Pekka, Jonas, Ole, Georges; !391, #335, #442, !406, !395, #447, - !375, gnome-shell#349, #451, !416, #784199, !408, !181, !405] - -Contributors: - Jonas Ådahl, Andrea Azzarone, Ole Jørgen Brønner, Piotr Drąg, Olivier Fourdan, - Dariusz Gadomski, Carlos Garnacho, Antoine Jacoutot, Iain Lane, Robert Mader, - Emilio Pozuelo Monfort, Florian Müllner, Georges Basile Stavracas Neto, - Pekka Paalanen, Marco Trevisan (Treviño), Josh Triplett, Daniel van Vugt - -Translators: - Fabio Tomat [fur], Balázs Úr [hu], Daniel Mustieles [es], Kukuh Syafaat [id], - Jordi Mas [ca], Piotr Drąg [pl] - -3.31.4 -====== -* keybindings: Limit corner move to current monitor [Jānis; #320] -* xdg-output: Report rotated physical dimensions [Olivier; #369] -* Add continuous integration pipeline [Jonas; #193] -* Improve performance on secondary GPUs [Pekka; #323, !313] -* Use the actual hardware refresh rate [Daniel; #781296] -* Remove hide-titlebar-when-maximized support [Florian; !221] -* wayland: Implement buffer transforms [Robert; !322] -* Remove ability to externally set sync-to-vblank [Georges; !191] -* Turn off touchscreens together with DPMS [Carlos; gnome-settings-daemon#29] -* Mipmap the wallpaper when shrinking [Daniel; gnome-shell#254] -* Implement RecordWindow method for screen-casts [Olivier; !306] -* Fix EGLStream texture downloading [Jonas; !362] -* Split out display-server-specific code from MetaWindowActor [Georges; !368] -* Improve render performance on some KMS devices with software GL [Jonas; #106] -* Fix damage area of transformed surfaces [Robert; !366] -* Remove autotools support [George] -* Misc. bug fixes and cleanups [Jonas, Alan, Olivier, Carlos, Javier, Peter, - Daniel, Robert, Florian; !309, #790207, #272, #393, #276, #404, #104, !343, - #765011, #786663, #342, !356, #414, #782344, #781034, #423, !374, !382, !383] - -Contributors: - Jonas Ådahl, Nikita Churaev, Alan Coopersmith, Jānis Džeriņš, Olivier Fourdan, - Carlos Garnacho, Niels De Graef, Peter Hutterer, Javier Jardón, - Abderrahim Kitouni, Andre Klapper, Ting-Wei Lan, Robert Mader, - Emilio Pozuelo Monfort, Florian Müllner, Georges Basile Stavracas Neto, - Pekka Paalanen, Daniel Stone, Marco Trevisan (Treviño), Daniel van Vugt - -3.31.2 -====== -* Fix handling of non-UTF8 encodings [Florian; !227] -* Fix memory leaks introduced in 3.30.1 [Jonas; #653] -* Fix regression when overriding workspace layout [Ron; #270] -* Fix crash when restarting window manager [Andrea; gnome-shell#595] -* Add meson build support [Jonas; !167] -* Freeze clock when headless [Jonas; !170] -* Fix crash on monitor hotplug [Olivier; #189] -* Misc. bug fixes [Jonas; #353, !132, #382] - -Contributors: - Jonas Ådahl, Andrea Azzarone, Olivier Fourdan, Niels De Graef, - Alexander Mikhaylenko, Florian Müllner, Akira Nakajima, - Georges Basile Stavracas Neto, Pekka Paalanen, Peter Uithoven, - Daniel van Vugt, Ron Yorston - -3.30.1 -====== -* Improve trackball detection [Tony; #258] -* Fix clipping of scaled surfaces [Jonas; #300] -* Improve tracking of monitor switch configuration [Daniel; !213] -* Fix parent-relative positioning of constrained windows [Jonas; #332] -* Add clutter_input_method_forward_key() method [Carlos; gnome-shell#531] -* Various crash fixes [Olivier, Jonas; #194, #336] -* Misc. bug fixes [Carlos, Florian, Olivier, Jonas; gnome-shell#540, #294, - #221, !229, #30, #331] - -Contributors: - Jonas Ådahl, Daniel Drake, Olivier Fourdan, Carlos Garnacho, Peter Hutterer, - Ting-Wei Lan, Florian Müllner, Tony Novak, Pekka Paalanen, Sam Spilsbury - -Translators: - Yuras Shumovich [be], Марко Костић [sr], Marek Cernocky [cs] - -3.30.0 -====== - -Translators: - Fran Dieguez [gl], Balázs Meskó [hu], Rūdolfs Mazurs [lv], - Trần Ngọc Quân [vi], Ask Hjorth Larsen [da], gogo [hr] - -3.29.92 -======= -* Avoid crash when a cursor is not found [Sebastian; #254] -* Fix screen rotation regression [Jonas; #216] -* Handle requests to unmanaged windows gracefully [Jonas; #240] -* Move popups together with their parent [Jonas; #274] -* Fix non-lowercase letters on virtual key devices [Carlos; gnome-shell#135] -* Misc. bug fixes [Iain, Jonas; #223, #192, #279] - -Contributors: - Jonas Ådahl, Carlos Garnacho, Sebastian Keller, Iain Lane, Robert Mader, - Daniel van Vugt - -Translators: - Gwan-gyeong Mun [ko], Kukuh Syafaat [id], Milo Casagrande [it], - Anders Jonsson [sv], Rafael Fontenelle [pt_BR], Marek Cernocky [cs] - -3.29.91 -======= -* Various crash fixes [Olivier, Iain; #255, #223] -* Fix lock up with some DRI drivers [Alex; #127] -* Send correct button codes from virtual evdev devices [Jonas; !190] -* Improve grab-device clock updates on X11 [Jeff; !174] -* Fix popups closing immediately on key down [Jonas; !180] -* Prevent clients from modifying the shared keymap [Jonas; #784206] - -Contributors: - Jonas Ådahl, Andrea Azzarone, Piotr Drąg, Olivier Fourdan, Carlos Garnacho, - Jan Grulich, Iain Lane, Alex Villacís Lasso, Jeff Smith, Daniel van Vugt - -Translators: - Matej Urbančič [sl], Mario Blättermann [de], Piotr Drąg [pl], - Aurimas Černius [lt], Yi-Jyun Pan [zh_TW], Emin Tufan Çetin [tr], - Fabio Tomat [fur], Bruce Cowan [en_GB] - -3.29.90 -======= -* Various crash fixes [Olivier, Jonas, Florian; #189, #70, #194, #15, #130] -* Don't expose resolutions that are below the minimum [Andrea; #793223] -* Remove support for preference overrides [Florian; #786496] -* Misc. bug fixes and cleanups [Daniel, Jonas, Florian; #131, #245, !176] - -Contributors: - Jonas Ådahl, Andrea Azzarone, Olivier Fourdan, Florian Müllner, Kevin Tamool, - Daniel van Vugt - -Translators: - Daniel Mustieles [es], Claude Paroz [fr] - -3.29.4 -====== -* Fix crash with parent-less modal dialogs [Olivier; #174] -* Preserve paint volumes where possible to optimize CPU usage [Carlos; #782344] - -Contributors: - Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Iain Lane, Bastien Nocera - -Translators: - Daniel Șerbănescu [ro] - -3.29.3 -====== -* Fix Korean Hangul support on wayland [Changwoo; #152] -* Improve support for proprietary Nvidia driver [Jonas; #790316] -* Only upload HW cursor sprite to the GPU that will display them [Jonas; #77] -* Improve EGLstream support [Miguel; #2, #782575] -* Remove MetaScreen to prepare for non-mandatary X11 dependency - [Armin, Jonas; #759538] -* Misc. bug fixes [Olivier, Jonas, Sam; #160, !130, #786929, #788834] - -Contributors: - Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Armin Krezović, Corentin Noël, - Changwoo Ryu, Sam Spilsbury, Daniel Stone, Marco Trevisan (Treviño), - Miguel A. Vico, Daniel van Vugt - -Translators: - Yi-Jyun Pan [zh_TW], Jordi Mas [ca], Daniel Șerbănescu [ro], Fabio Tomat [fur] - -3.29.2 -====== -* Fix size change animations on wayland [Georges; #780292] -* Handle touch events on server-side titlebars [Carlos; #770185] -* Misc. bug fixes [Florian, Olivier, Jonas, Georges; #134, #124, !96, #138, - !102, #781471, #150] - -Contributors: - Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Florian Müllner, - Georges Basile Stavracas Neto, Marco Trevisan (Treviño), Daniel van Vugt - -Translators: - Daniel Șerbănescu [ro], Marcos Lans [gl], Dz Chen [zh_CN] - -3.29.1 -====== -* Fix various input-method regressions [Carlos, Olivier; #65, #74, #66, #112] -* Fix wayland build on FreeBSD [Ting-Wei; #792280, #792717] -* Fix swapped colors in screenshots (again) [Carlos; #72] -* Allow building with elogind [Rasmus; !46] -* Consider display rotation for cursor [Olivier; #85] -* Fall back to non-modifier GBM surfaces [Daniel; #84] -* Take inhibitors into account for monitoring idle [Bastien; #705942] -* Misc. bug fixes [handsome-feng, Olivier, Mario, Jonas; !45, #83, #104, - gnome-shell#157, #130, #21] - -Contributors: - Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, handsome-feng, Yussuf Khalil, - Ting-Wei Lan, Aleksandr Mezin, Alberts Muktupāvels, - Georges Basile Stavracas Neto, Bastien Nocera, Benjamin Otte, - Mario Sanchez Prada, Daniel Stone, Ray Strode, Rasmus Thomsen, - Marco Trevisan (Treviño), Daniel van Vugt - -Translators: - Emin Tufan Çetin [tr], Dušan Kazik [sk], Matej Urbančič [sl] - -3.28.0 -====== -* Fix xdg-foreign regression [Carlos; #63] - -Contributors: - Carlos Garnacho, Georges Basile Stavracas Neto - -Translators: - Marek Cernocky [cs], Ask Hjorth Larsen [da], Chao-Hsiung Liao [zh_TW], - Anders Jonsson [sv], Mart Raudsepp [et] - -3.27.92 -======= -* Fix use of modifiers with multi-GPU systems [Louis-Francis; #18] -* Add xdg-shell stable support [Jonas; #791938] -* Fix scaling of icons in titlebar buttons [Egmont; #23] -* Implement missing wacom functionality on X11 [Carlos; #48] -* Force 8-bit RGB config [Jonas; #2] -* Misc. bug fixes [Jonas, Olivier, Robert; #6, #27, #792203] - -Contributors: - Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Egmont Koblinger, Robert Mader, - Bastien Nocera, Louis-Francis Ratté-Boulianne - -Translators: - Daniel Mustieles [es], Марко Костић [sr], Милош Поповић [sr@latin], - Fran Dieguez [gl], Balázs Úr [hu], Gwan-gyeong Mun [ko], Rūdolfs Mazurs [lv], - Milo Casagrande [it], Mario Blättermann [de], GNOME Translation Robot [gd, - nl], Claude Paroz [fr], Aurimas Černius [lt] - -3.27.91 -======= -* Fix handling of trackball settings on wayland [Carlos; #787804] -* Apply font settings on wayland [Daniel; #645433] -* Fix keybindings getting mixed up with some layouts [Jonas; #789300] -* Fix bluetooth mouse cursor disappearing after idle [Benoit; #761067] -* Support platforms that export EGL_KHR_platform_gbm [memeka; #780668] -* Add keyboard accessibility support on wayland [Olivier; #788564] -* Fix missing cursor when using screen magnifier [Carlos; #754806] -* Fix external monitor shutting off on wayland when lid closes [Jonas; #788915] -* Add xdg-output support [Olivier; #787363] -* Add Xwayland grab keyboard support [Olivier; #783342] -* Allow shortcut inhibition of the super key [Olivier; #790627] -* Take "panel orientation" drm_connector property into account [Hans; #782294] -* Fix focus window ending up below other windows on wayland [Olivier; #780820] -* Fix maximized windows restoring to a tiny size on wayland [Olivier; #783901] -* Fix tap-and-drag setting on X11 [Jonas; #775755] -* Fix handling of single-touch devices on wayland [Carlos; #792005] -* Support tiled/compressed buffers [Daniel; #785779] -* Port screencast support to pipewire 0.1.8 [Jonas; #792854] -* Add support for third stylus button on newer tablets [Jason; #790033] -* Fix background corruption regression on nvidia [Jonas; #739178] -* Misc. bug fixes [Jonas, Rui, Michael, Marco, Carlos, Olivier, Philip, Piotr, - Ting-Wei, Daniel, Jeremy, Hans, Florian, Ray, Jeff, George, Gwan-gyeong; - #789153, #788493, #784314, #789227, #789223, #789277, #782344, #789552, - #789553, #788695, #789984, #788764, #789386, #784545, #790336, #790358, - #791022, #791006, #789070, #772218, #791383, #791809, #776220, #791916, - #792281, #790309, #791371, #792527, #792599, #788834, #792765, #792062, - #645460, #792853, !2, #792818, #8, #12, #789501, #10, #789961, #13, !15, #1, - #26, #28, #35, #36, #38] - -Contributors: - Jonas Ådahl, Jeremy Bicha, Michael Catanzaro, Piotr Drąg, Olivier Fourdan, - Carlos Garnacho, Jason Gerecke, Hans de Goede, Benoit Gschwind, - Peter Hutterer, George Kiagiadakis, Ting-Wei Lan, Rui Matos, memeka, - Florian Müllner, Gwan-gyeong Mun, Jeremy Nickurak, Marc-Antoine Perennou, - Jeff Smith, Daniel Stone, Ray Strode, Marco Trevisan (Treviño), - Daniel van Vugt, Philip Withnall - -Translators: - Khaled Hosny [ar], Kjartan Maraas [nb], Piotr Drąg [pl], - Rafael Fontenelle [pt_BR], Christian Kirbach [de], Anders Jonsson [sv], - Charles Monzat [fr], Marek Cernocky [cs], Muhammet Kara [tr], - Milo Casagrande [it], Pawan Chitrakar [ne], Yosef Or Boczko [he], - Kukuh Syafaat [id], Daniel Mustieles [es], Fabio Tomat [fur], - Kristjan SCHMIDT [eo], Balázs Úr [hu], Andika Triwidada [id], - Fran Dieguez [gl], gogo [hr] - -3.27.1 -====== -* Work with clients that require older linux_dmabuf protocol [Daniel; #788558] -* Support hybrid GPU systems [Jonas; #785381] -* Prevent crash when closing maximized windows [Jonni; #788666] -* Use the correct monitor for HiDPI scaling of shell chrome [Jonas; #788820] -* Fix unredirection of fullscreen windows [Rui, Jonas; #788493] -* Fix list of supported monitor scales on X11 [Jonas; #788901] -* Misc. bug fixes [Florian, Jonas, Marco; #788572, #788569, #788607, #788860, - #788921] - -Contributors: - Jonas Ådahl, Carlos Garnacho, Rui Matos, Florian Müllner, Daniel Stone, - Marco Trevisan, Jonni Westphalen - -Translations: - Xavi Ivars [ca@valencia] - -3.26.1 -====== -* Fix crash when respawning shortcut inhibitor dialog [Olivier; #787568] -* Fix crash during monitor configuration migration [Carlos, Jonas; #787668] -* Fix multihead regressions in X11 session [Jonas; #787477] -* Fix screen rotation regressions [Hans; #787836] -* Fix keybindings not being resolved with non-latin layouts [Jonas; #787016] -* Support snap packages for sandboxed app IDs [Marco; #788217] -* Fix crash when reconnecting tablet device [Jason; #787649] -* Support running headless [Jonas; #730551, #787637] -* Support _NET_RESTACK_WINDOW and ConfigureRequest siblings [Vasilis; #786365] -* Fix monitor layout not being remembered across sessions [Jonas; #787629] -* Make sure to export _NET_NUMBER_OF_DESKTOPS [Florian; #760651] -* Allow resizing of tiled windows [Georges, Florian; #645153] -* Export tiling information to clients [Georges; #751857] -* Misc. bug fixes [Jonas, Florian, Jeremy, Rico; #787570, #787715, #787953, - #788049, #788199, #788292, #788197] - -Contributors: - Jonas Ådahl, Andrea Azzarone, Georges Basile Stavracas Neto, Hans de Goede, - Olivier Fourdan, Carlos Garnacho, Jason Gerecke, Vasilis Liaskovitis, - Rui Matos, Florian Müllner, Jeremy Soller, Marco Trevisan, Rico Tzschichholz - -Translations: - Matej Urbančič [sl], gogo [hr], Cheng-Chia Tseng [zh_TW] - -3.26.0 -====== -Contributors: - Florian Müllner - -Translations: - Trần Ngọc Quân [vi], Inaki Larranaga Murgoitio [eu], Jordi Mas [ca], - Anders Jonsson [sv], Alexander Shopov [bg], Ask Hjorth Larsen [da], - Jean-Baptiste Holcroft [fr], A S Alam [pa] - -3.25.92 -======= -* Add screencast and remote desktop support [Jonas; #784199] -* Support running with no attached monitors [Jonas; #730551] -* Add a vertical gradient effect to background actor [Alessandro; #786618] -* Misc. bug fixes [Mario, Daniel, Piotr, Jonas, Bastien; #786619, #786677, - #772218, #786918, #760670] - -Contributors: - Jonas Ådahl, Alessandro Bono, Piotr Drąg, Bastien Nocera, - Mario Sanchez Prada, Daniel Stone - -Translations: - Marek Cernocky [cs], Aurimas Černius [lt], Piotr Drąg [pl], - Fran Dieguez [gl], gogo [hr], Dušan Kazik [sk], Milo Casagrande [it], - Jordi Mas [ca], Cheng-Chia Tseng [zh_TW], Марко Костић [sr], - Милош Поповић [sr@latin], Rūdolfs Mazurs [lv], Matej Urbančič [sl], - Ask Hjorth Larsen [da], Piotr Drąg [it, lt], Jiri Grönroos [fi], - Emin Tufan Çetin [tr], Wolfgang Stöggl [de], Kukuh Syafaat [id], - Yuras Shumovich [be], Changwoo Ryu [ko], Alexander Shopov [bg], - Rafael Fontenelle [pt_BR], Balázs Úr [hu] - -3.25.91 -======= -* Reduce memory use of suspended instances [Jonas; #786299] -* Make supported scales determination saner [Rui; #786474] -* Fix crash on inhibit-shortcuts dialog response [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] -* Avoid unnecessary work during background painting [Alessandro; #783512] -* Misc. bug fixes [Alberts, Jonas, Mario; #691611, #786300, #777732, #786568] - -Contributors: - freeroot, Jonas Ådahl, Alessandro Bono, Carlos Garnacho, Rui Matos, - Alberts Muktupāvels, Mario Sanchez Prada - -Translations: - Muhammet Kara [tr], Claude Paroz [fr], Мирослав Николић [sr, sr@latin], - Pawan Chitrakar [ne], Kukuh Syafaat [id] - -3.25.90 -======= -* Add zwp_linux_dmabuf_v1 support [Daniel; #785262] -* Add (x)wayland shortcut inhibitor support [Olivier; #783342] -* Misc. bug fixes [Daniel, Carlos, Cosimo; #785263, #785347, #767805] - -Contributors: - Jonas Ådahl, Cosimo Cecchi, Olivier Fourdan, Carlos Garnacho, Daniel Stone - -Translations: - Fabio Tomat [fur], Kukuh Syafaat [id], Aurimas Černius [lt], - Daniel Mustieles [es], Baurzhan Muftakhidinov [kk], Jordi Mas [ca], - Matej Urbančič [sl], Marek Cernocky [cs], gogo [hr], Fran Dieguez [gl], - Balázs Meskó [hu] - -3.25.4 -====== -* Do not throttle motion events on tablet tools [Carlos; #783535] -* Handle left-handed mode on pen/eraser devices [Carlos; #782027] -* Add wl_surface.damage_buffer() support [Jonas; #784080] -* Fix crash when moving across on-adjacent monitors [Jonas; #783630] -* Fix window moving/resizing via tablet tools [Jason; #777333] -* Support fractional monitor scaling [Jonas, Marco; #765011] -* Keep override-redirect windows stacked on top [Rui; #780485] -* Implement tablet rings/strips configuration [Carlos; #782033] -* Support tablet wheel events on wayland [Jason; #783716] -* Move g-s-d xrandr functionality into mutter [Rui; #781906] -* Misc. bug fixes [Florian, Jason, Miguel, Carlos, Jonas; #783502, #784009, - #784223, #784272, #784402, #784881, #762083, #784867, #781723] - -Contributors: - Jonas Ådahl, Miguel A. Vico, Emmanuele Bassi, Carlos Garnacho, Jason Gerecke, - Rui Matos, Florian Müllner, Marco Trevisan (Treviño) - -3.25.3 -====== -* Ignore hotplug-mode-update value on startup [Marco; #783073] -* Implement configurable monitor scales on X11 [Jonas; #777732] -* Fix handling of tiled monitors [Jonas; #781723] -* Handle multiple keycodes for keysym [Christian; #781223] -* Consider subsurfaces when grabbing [mindtree; #781811] -* Fix logic for HiPDPI scaling of TV outputs [Christian; #777347] -* Fix handling of left-handed mode on pen/eraser devices [Carlos; #782027] -* Fix output cycling in non-display-attached tablets [Carlos; #782032] -* Fix wacom cursor offset on wayland [Jason; #784009] -* Handle EXIF orientation of backgrounds [Silvère; #783125] -* Misc. bug fixes [Piotr, Tim, Bastien, Jonas, Florian, Benoit, Carlos; #772218, - #783161, #780407, #783113, #783293, #783505, #781703] - -Contributors: - mitchmindtree, Jonas Ådahl, Ikey Doherty, Piotr Drąg, Carlos Garnacho, - Jason Gerecke, Benoit Gschwind, Christian Kellner, Silvère Latchurié, - Tim Lunn, Florian Müllner, Bastien Nocera, Marco Trevisan (Treviño) - -Translations: - Fabio Tomat [fur], Kukuh Syafaat [id], Khaled Hosny [ar], - Daniel Mustieles [es] - -3.25.2 -====== -* Fix frame updates on hide-titlebar-when-maximized changes [Florian; #781862] -* Fix accessible screen coordinates on X11 [Florian; #781902] -* Use less CPU when rendering fast-updating windows [Carlos, Emmanuele; #782344] -* Compute geometry of clients that don't set one explicitly [Olivier; #782213] -* Fix copy+paste of UTF8 strings between X11 and wayland [Carlos; #782472] -* Fix non-wayland builds [Chris; #780533] -* Add plugin vfunc to implement a custom force-quit dialog [Carlos; #711619] -* Fix swapped red and blue channels in CoglTexture data [Carlos; #779234 -* Fix build where libtool's link_all_deplibs defaults to 'no' [Marco; #782821] -* Fix glitches when opening a window maximized [Olivier; #781353, #782183] -* Fix wrong cursor after window underneath the pointer changed [Carlos; #755164] -* Implement support for disable-while-typing option [Evan; #764852] -* Emit size-change signal when tiling [Alessandro; #782968] -* Misc. bug fixes [Nigel, Matthias, Jonas; #759085, #780215, #782156, #782152] - -Contributors: - Jonas Ådahl, Emmanuele Bassi, Alessandro Bono, Olivier Fourdan, - Carlos Garnacho, Matthias Liertzer, Florian Müllner, Nigel Taylor, - Marco Trevisan (Treviño), Chris Vine, Evan Welsh - -Translations: - Fabio Tomat [fur], Jordi Mas [ca], Mario Blättermann [de], - Emin Tufan Çetin [tr], Balázs Úr [hu] - -3.25.1 -====== -* Always sync window geometry on state changes [Jonas; #780292] -* Use EGL instead of GLX when drawing using GLES [Jonas; #771636] -* Fix HiDPI detection on vertical monitor layouts [Carlos; #777687] -* Get double-click timing from desktop mouse settings [Armin; #771576] -* Scale relative motion deltas with monitor scale [Jonas, Carlos; #778119] -* Use texture fallback when setting hardware cursor fails [Jente; #770020] -* Fix lock-up when using additional theme variants [Shantanu; #780254] -* Rework low-level monitor configuration [Jonas; #777732] -* Fix building with GLES2 instead of GL [Mario; #781398] -* Misc. bug fixes [Jonas, Piotr, Philip; #780304, #772218, #781242, #781391] - -Contributors: - Jonas Ådahl, Philip Chimento, Piotr Drąg, Carlos Garnacho, Shantanu Goel, - Jente Hidskes, Armin Krezović, Rui Matos, Florian Müllner, Mario Sanchez Prada - -Translations: - Yuras Shumovich [be], Yosef Or Boczko [he], Tom Tryfonidis [el], - Fabio Tomat [fur], Kukuh Syafaat [id] - -3.24.0 -====== - -Translations: - Yuri Myasoedov [ru], Rūdolfs Mazurs [lv], Jordi Mas [ca] - -3.23.92 -======= -* Properly handle EGLOutput acquire errors [Jonas, Miguel; #779112] -* Fix crash when a window closes during Alt+Tab [Rui; #779483] -* Implement DnD handling code in wayland [Hyungwon; #765003] -* Fix fallout from pixel conversion optimization in 3.23.91 [Carlos; #779234] -* Fix mouse input stopping to work in applications [Carlos; #763246] -* Fix DnD between QT5 and GTK3 applications on wayland [Carlos; #779757] -* Make EDID reading less fragile [Jonas; #779837] -* Add support for tablet grouping [Carlos; #779986] -* Misc. bug fixes and cleanups [Rui, Jonas; #779436, #779001, #779745] - -Contributors: - Jonas Ådahl, Miguel A. Vico, Olivier Fourdan, Carlos Garnacho, - Hyungwon Hwang, Rui Matos - -Translations: - Chao-Hsiung Liao [zh_TW], Sveinn í Felli [is], Ask Hjorth Larsen [da], - Changwoo Ryu [ko], Aurimas Černius [lt], GNOME Translation Robot [gd], - Marek Černocký [cs], Fran Dieguez [gl], Dušan Kazik [sk] - -3.23.91 -======= -* Give libinput read-only access to /sys [Carlos; #778472] -* Allow edge-scrolling without 2-finger-scroll capable devices [Rui; #778554] -* Fullscreen windows on the requested monitor on wayland [Rui; #772525] -* Implement threaded swap_event fallback for NVIDIA driver [Owen; #779039] -* Avoid pixel conversions when storing textures from cairo [Carlos; #779234] -* Misc. bug fixes [Piotr, Rui, Florian; #772218, #776919, #778831, #642652] - -Contributors: - Piotr Drąg, Carlos Garnacho, Rui Matos, Florian Müllner, Owen W. Taylor - -Translations: - Inaki Larranaga Murgoitio [eu], Daniel Mustieles [es], Claude Paroz [fr], - Mario Blättermann [de], Kjartan Maraas [nb], Piotr Drąg [pl], - Andika Triwidada [id], Anders Jonsson [sv], Milo Casagrande [it], - Fabio Tomat [fur], Rafael Fontenelle [pt_BR], - Мирослав Николић [sr, sr@latin], Balázs Meskó [hu], Chao-Hsiung Liao [zh_TW] - -3.23.90 -======= -* Fix window menu placement with HiDPI [Jonas; #776055] -* Improve EGLStream support [Jonas; #773629] -* Start moving low-level monitor configuration into mutter [Jonas; #777732] -* Fix erroneous key event repeats [Rui; #774989] -* Don't hardcode seat ID in ClutterDeviceManager [Carlos; #778092] -* Fix "ghost" cursors in multi-monitor setups [Jonas; #771056] -* Use eglGetPlatformDisplay [Adam; #772422] -* Fix erratic raise_or_lower behavior [Jose; #705200] -* Fix coordinate mapping of absolute devices [Carlos; #774115] -* Show OSD on tablet mode switches [Carlos; #771098] -* Make mutter libs parallel installable [Jonas; #777317] -* Only apply keymap when not running nested [Jonas; #777800] -* Set right scale for tablet tool cursors on HiDPI [Carlos; #778474] -* Adjust server-side shadows to match Adwaita [Juraj; #744667] -* Misc. bug fixes [Jonas, Bastien, Carlos, Peter, Lionel, Jeremy, Florian; - #774891, #777389, #777691, #778262, #776543, #778684, #778699, #744667] - -Contributors: - Jonas Ådahl, Jeremy Bicha, Piotr Drąg, Juraj Fiala, Carlos Garnacho, - Peter Hutterer, Adam Jackson, Lionel Landwerlin, Jose Marino, Rui Matos, - Florian Müllner, Bastien Nocera - -Translations: - Kjartan Maraas [nb], Mandy Wang [zh_CN], Marek Černocký [cs], - Anders Jonsson [sv], Dušan Kazik [sk], Piotr Drąg [pl], Matej Urbančič [sl] - -3.23.3 -====== -* Fix frequent freezes in multihead setups on wayland [Rui; #774557] -* Preserve root window mask on XSelectionRequest [Olivier; #776128] -* Misc. bug fixes [Carlos, Florian, Rui, Olivier; #775478, #774891, #775986, - #776036] - -Contributors: - Olivier Fourdan, Carlos Garnacho, Rui Matos, Florian Müllner - -3.23.2 -====== -* Stack docks below other windows on fullscreen monitors [Rui; #772937] -* Fix popup grabs blocking screen lock on wayland [Rui; #771235] -* Handle touchpad pinch gestures with more than two fingers [Carlos; #765937] -* Implement drawing tablet support on X11 [Carlos; #773779] -* Fix some Wine games starting minimized [Carlos; #774333] -* Fix switching between two finger- and edge scrolling on wayland [Rui; #771744] -* Implement support for EGLStream/EGLDevice [Jonas; #773629] -* Add size_changed vfunc to handle async client size changes [Rui; #770345] -* Change focus window on clicks with any modifiers [Rui; #746642] -* Misc. bug fixes and cleanups [Carlos, Daniel, Jonas, Rui; #771067, #774330, #774613, - #771297, #774135, #774827, #774923] - -Contributors: - Jonas Ådahl, Carlos Garnacho, Rui Matos, Florian Müllner, Daniel Stone - -Translations: - Kjartan Maraas [nb] - -3.23.1 -====== -* Fix handling of Escape shortcut in force-quit dialog [Landry; #737109] -* Improve pointer constraints support [Jonas; #771859] -* Really fix framebuffer capture origin offset [Rui; #771502] -* Fix session going into idle mode immediately on startup [Rui; #772839] -* Fix mirror mode with stage views [Rui; #773115] -* Fall back to X with connectors spread across multiple GPUs [Ray; #771442] -* Fix various crashes on wayland [Jonas, Carlos; #771646, #771858, #772929] -* Fix various placement issues on wayland [Olivier, Jonas, Sjoerd; #772729, - #768039, #771841, #771841, #773141] -* Misc. bug fixes [Rui, Jonas, Olivier; #771019, #773116, #772914, #773210] - -Contributors: - Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Rui Matos, Landry MINOZA, - Sjoerd Simons, Ray Strode - -Translations: - Theppitak Karoonboonyanan [th], Kjartan Maraas [nb], Hannie Dumoleyn [nl], - liushuyu [zh_CN] - -3.22.1 -====== -* Fix feedback loop between StClipboard and X11 bridge [Carlos; #760745] -* Fall back gracefully if DRM plane rotation fails [Carlos; #772512] -* Approximate native monitor backend behavior to X [Rui; #772176] -* Fix crash on VT switch on wayland [Jonas; #771646] -* Expose Flatpak ID for application matching [Florian; #772613, #772614] - -Contributors: - Jonas Ådahl, Carlos Garnacho, Rui Matos, Florian Müllner, Olav Vitters - -Translations: - Inaki Larranaga Murgoitio [eu], Milo Casagrande [it] - -3.22.0 -====== -* Fix wayland crashes [Jonas; #771305, #771345, #770940, #771495] -* Fix display rotation on wayland [Jonas; #770672] -* Fix framebuffer capture origin offset [Rui; #771502] -* Misc. bug fixes [Jonas, Florian, Carlos; #770937, #771536, #771628, #771549] - -Contributors: - Jonas Ådahl, Carlos Garnacho, Rui Matos, Florian Müllner - -Translations: - Ask Hjorth Larsen [da], Charles Monzat [fr], Stas Solovey [ru], - Tom Tryfonidis [el], David King [en_GB] - -3.21.92 -======= -* Fix absolute pointer motion events on wayland [Jonas; #770557] -* Default to using stage views [Jonas; #770366] -* Fix animated cursors on wayland [Rui; #749913] -* Fix various crashes on wayland [Jonas; #757568, #770727, #770992] -* Fix screen capture for stage views not at (0, 0) [Jonas; #770127] -* Compress motion events instead of discarding them [Jonas; #771049] -* Fix XWayland pointer warp emulation [Jonas; #771050] -* Add common monitor modes in KMS backend [Rui; #744544] -* Temporarily use g-s-d schemas for tablet configuration [Carlos; #771315] -* Misc. bug fixes [Jonas, Carlos; #770402, #770647, #770991, #770994, #770929] - -Contributors: - Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Rui Matos, Florian Müllner - -Translations: - Changwoo Ryu [ko], Baurzhan Muftakhidinov [kk], Anders Jonsson [sv], - Tiago Santos [pt], Rafael Fontenelle [pt_BR], Mario Blättermann [de], - Alexander Shopov [bg], Rūdolfs Mazurs [lv], Fran Dieguez [gl], - Trần Ngọc Quân [vi], Piotr Drąg [pl], Мирослав Николић [sr, sr@latin] - -3.21.91 -======= -* Add support for xdg-foreign protocol [Jonas; #769786] -* Support monitor rotation on wayland [Carlos; #745079] -* Port xdg-shell implementation to unstable v6 [Jonas; #769936] -* Handle unsupported buffer sizes more gracefully [Olivier; #770387] -* Use the same output naming logic as the X server on wayland [Rui; #770338] -* Fix replies in gnome-shell's chat notifications on wayland [Florian; #758167] -* Misc. bug fixes and cleanups [Bastien, Sjoerd, Jonas; #769276, #769636, - #770131, #770324, #769731] - -Contributors: - Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Rui Matos, Florian Müllner, - Bastien Nocera, Sjoerd Simons - -Translations: - Piotr Drąg [pl], Mario Blättermann [de], Andika Triwidada [id], - Enrico Nicoletto [pt_BR], Мирослав Николић [sr, sr@latin] - -3.21.90 -======= -* 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] -* 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; - #769014, #769024, #769054, #769070, #769036, #769305, #769578, #769800, - #769073] - -Contributors: - Jonas Ådahl, Carlos Garnacho, Thomas Hindoe Paaboel Andersen, Simon McVittie, - Alberts Muktupāvels, Florian Müllner, Bastien Nocera, Jouke Witteveen - -Translations: - Daniel Mustieles [es], Aurimas Černius [lt], Dušan Kazik [sk], - Fabio Tomat [fur], Balázs Úr [hu], Yosef Or Boczko [he], Marek Černocký [cs], - Matej Urbančič [sl] - -3.21.4 -====== -* Fix missing frame border around GTK+ dialogs [Florian; #745060] -* Improve X11 <-> wayland copy and paste interaction [Carlos; #768007] -* Add support for NV_robustness_video_memory_purge extension [Rui; #739178] -* Fix restoring the old focused window on restart [Owen; #766243] -* Fix fullscreen windows on other monitors stealing focus after closing - a window [Rui; #768221] -* Draw monitor content to individual framebuffer [Jonas; #768976] -* Provide screen capture API [Jonas; #768978] -* Misc. bug fixes and cleanups [Rui, Owen, Luca, Olivier, Jonas, Carlos; - #767969, #768243, #762407, #767997, #768039, #768977, #768977] - -Contributors: - Jonas Ådahl, Luca Bruno, Olivier Fourdan, Carlos Garnacho, Rui Matos, - Florian Müllner, Owen W. Taylor - -Translations: - Andika Triwidada [id] - -3.21.3 -====== -* Don't create invalid UTF-8 window description strings [Rui; #765535] -* Convert window titles and wm_class to UTF-8 [Rui; #752788] -* Communicate tiled state to GTK+ on wayland [Olivier; #766860] -* Use kill() to force-quit unresponsive wayland clients [Olivier; #767464] -* Fix window position when unmaximizing via DND on wayland [Olivier; #764180] -* Avoid full window redraws when using extended frame sync [Florian; #767798] - -Contributors: - Olivier Fourdan, Rui Matos, Florian Müllner - -Translations: - Cédric Valmary [oc] - -3.21.2 -====== -* Clean up surface <-> shell interaction [Jonas; #763431] -* Fix grabbing random keys for disabled shortcuts [Rui; #766270] -* Fix stacking of hidden windows on wayland [Rui; #764844] -* Misc. bug fixes [Victor, Florian, Marek, Rui; #766306, #766326, #751847, - #763832, #766528] - -Contributors: - Jonas Ådahl, Emmanuele Bassi, Marek Chalupa, Matthias Clasen, - Carlos Garnacho, Rui Matos, Florian Müllner, Victor Toso - -Translations: - Tiago Santos [pt], Cédric Valmary [oc], Muhammet Kara [tr] - -3.21.1 -====== -* Notify clients of pending modifier state changes [Rui; #748526] -* Add get_is_builtin_display_on() method [Florian; #765267] -* Fix 2-finger titlebar taps on wayland [Carlos; #764519] -* Merge clutter and cogl forks into mutter [Rui; #760439] -* Misc. bug fixes [Florian, Victor, Jonas; #765058, #765252, #765062] - -Contributors: - Jonas Ådahl, Emmanuele Bassi, Olivier Fourdan, Carlos Garnacho, Rui Matos, - Florian Müllner, Victor Toso, Rico Tzschichholz - -Translations: - GNOME Translation Robot [ja, gd] - -3.20.1 -====== -* Constrain window move/resizes on wayland as on X11 [Rui; #748819] -* Don't crash with invalid previous monitor configurations [Rui; #764286] -* Misc. bug fixes and cleanups [Jonas, Cosimo; #762828, #764807] - -Contributors: - Jonas Ådahl, Cosimo Cecchi, Rui Matos, Jasper St. Pierre - -Translations: - Inaki Larranaga Murgoitio [eu], Reinout van Schouwen [nl], Fabio Tomat [fur], - Trần Ngọc Quân [vi] - -3.20.0 -====== -* Fix crash when using visual bell [Jonas; #763858] - -Contributors: - Jonas Ådahl, Jasper St. Pierre - -Translations: - Milo Casagrande [it], Ask Hjorth Larsen [da] - -3.19.92 -======= -* Add system bell support on wayland [Jonas; #763284] -* Add gtk_surface.present to gtk-shell [Jonas; #763295] -* Handle DND drops on the root window [Carlos; #762104] -* Misc. bug fixes [Jonas, Carlos, Rui; #762828, #760745, #763125, #762763, - #762661, #762639, #763159] - -Contributors: - Jonas Ådahl, Carlos Garnacho, Rui Matos, Florian Müllner - -Translations: - Rūdolfs Mazurs [lv], Balázs Úr [hu], Claude Paroz [fr], Matej Urbančič [sl], - Мирослав Николић [sr, sr@latin], Sebastian Rasmussen [sv], Changwoo Ryu [ko], - Gil Forcada [ca], Tom Tryfonidis [el] - -3.19.91 -======= -* Add --nested CLI argument to fix nested wayland session [Jonas; #758658] -* Fix stack - scene graph stacking synchronization issues [Jonas; #755605] -* Rate-limit last-device changes to fix freezes [Carlos; #753527] -* Implement primary selection protocol [Carlos; #762560] -* Misc. bug fixes [Carlos, Jonas; #762878, #762716] - -Contributors: - Jonas Ådahl, Carlos Garnacho, Tim Lunn - -Translations: - Piotr Drąg [pl], Artur de Aquino Morais [pt_BR], Marek Černocký [cs], - Cédric Valmary [oc], Mario Blättermann [de], Dušan Kazik [sk], - Fran Dieguez [gl], Aurimas Černius [lt], Daniel Mustieles [es], - Stas Solovey [ru], Yosef Or Boczko [he] - -3.19.90 -======= -* Release buffer after processing commit [Ray; #761312, #761613] -* Implement pointer motion, locks and confinement on wayland [Jonas; #744104] -* Add basic startup notification support on wayland [Carlos; #762268] -* Misc. bug fixes [Rui, Alberts, Florian; #760670, #761543, #752794, #761557] - -Contributors: - Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Rui Matos, - Alberts Muktupāvels, Florian Müllner, Jasper St. Pierre, Ray Strode - -3.19.4 -====== -* Fix updating stacking order when setting transient_for [Jonas; #755606] -* Support screen rotation when supported by the driver [Carlos; #745079] -* Protect against broken WM_CLASS property implementations [Sebastian; #759658] -* Handle wl_pointer v5 events on wayland [Carlos; #760637] -* Implement DND actions on wayland [Carlos; #760805] -* Misc. bug fixes [Jonas, Rui, Ray, Marek; #754711, #756789, #759297, #758613, - #760330, #760476, #759222, #760670] - -Contributors: - Jonas Ådahl, Marek Chalupa, Carlos Garnacho, Sebastian Keller, Rui Matos, - Florian Müllner, Jasper St. Pierre, Ray Strode - -Translations: - Aurimas Černius [lt] - -3.19.3 -====== -* Correct refresh rate units on KMS/Wayland [Daniel; #758653] -* Fix crash when initial cursor position is not on a monitor [Marek; #756698] -* Fix crash when more CRTs are enabled than outputs connected [Rui; #751638] -* Fix touch pointer emulation on wayland [Carlos; #756754] -* Allow minimizing windows that don't advertise supporting it [Jasper; #758186] -* Force 2-finger scroll by default if available [Bastien; #759304] -* Fix crash during XWayland initialization [Marek; #751845] -* Ensure to send a ConfigureNotify to just mapped windows [Rui; #759492] -* Misc. bug fixes and cleanups [Carlos, Jonas, Lionel; #758239, #758633, - #755503, #759374] - -Contributors: - Jonas Ådahl, Marek Chalupa, Carlos Garnacho, Lionel Landwerlin, Rui Matos, - Bastien Nocera, Daniel Stone, Jasper St. Pierre - -3.19.2 -====== -* Fix crash on monitor unplug [Rui; #756796] -* Exit cleanly on initialization errors [Owen; #757311] -* Allow to determine backend setting from session type [Ray; #741666] -* Fix DRM device detection for non-PCI devices [Alban; #754911] -* Don't force placement of windows without buffer on wayland [Marek; #751887] -* Fix initialization of bypass compositor hint [Rui; #758544] - -Contributors: - Alban Browaeys, Marek Chalupa, Rui Matos, Florian Müllner, Ray Strode, - Owen W. Taylor - -3.19.1 -====== -* wayland: Allow to trigger popups through keyboard/touch [Carlos; #756296] -* Fix modifiers-only input source switching on Ubuntu [Alberts; #756543] -* Misc. bug fixes [Jonas, Rui, Giovanni, Florian; #756675, #756660, #746420, - #756548, #756796, #757101, #757148] - -Contributors: - Jonas Ådahl, Giovanni Campagna, Carlos Garnacho, Rui Matos, - Alberts Muktupāvels, Florian Müllner - -Translations: - Daniel Șerbănescu [ro] - -3.18.1 -====== -* Misc. crash fixes [Jonas, Rui, Carlos, Owen, Florian; #755096, #754979, - #755490, #754357, #745785, #756642] -* Improve HiDPI support on wayland [Jonas; #755097] -* Fix doubly-scaled cursor on XWayland HiDPI [Jonas; #755099] -* Stop hiding titlebar buttons in dialogs [Florian; #641630] -* Add support for fullscreen/unfullscreen animations [Cosimo; #707248] -* Misc. bug fixes [Rui, Colin, Florian; #743339, #752047, #756074, #756649] - -Contributors: - Jonas Ådahl, Cosimo Cecchi, Carlos Garnacho, Rui Matos, Florian Müllner, - Jasper St. Pierre, Colin Walters, Owen W. Taylor - -3.18.0 -====== -* Misc. fixes [Florian, Jonas; #753434] - -Contributors: - Jonas Ådahl, Florian Müllner - -Translations: - Rūdolfs Mazurs [lv] - -3.17.92 -======= -* Don't omit the background color for backgrounds that don't fill the screen - [Ray; #754476] -* Fix up key state on FocusIn when running nested [Owen; #753948] -* Find the right DRM device instead of hardcoding card0 [Marek; #753434] -* Scale cursor on HiDPI screens [Jonas; #744932] -* Misc. fixes and cleanups [Lan, Jonas, Javier, Olivier; #754545, #754215, - #754621, #754715] - -Contributors: - Jonas Ådahl, Marek Chalupa, Olivier Fourdan, Javier Jardón, Ting-Wei Lan, - Ray Strode, Owen W. Taylor - -3.17.91 -======= -* Send error on pointer-gesture protocol version mismatch [Jonas; #753855] -* Misc. cleanups [Jonas; #744932] - -Contributors: - Jonas Ådahl - -Translations: - Chao-Hsiung Liao [zh_TW], Piotr Drąg [pl] - -3.17.90 -======= -* Fix glitch with some fullscreen apps [Rui; #753020] -* Fix screen update issue with NVidia driver [Aaron, Rui; #728464] -* Only call frame callbacks for surfaces that get drawn [Adel; #739163] -* Misc. bug fixes and cleanups [Jonas, Rui, Ting-Wei; #753222, #752753, #753237, - #753380, #744104, #744932] - -Contributors: - Jonas Ådahl, Adel Gadllah, Carlos Garnacho, Ting-Wei Lan, Rui Matos, - Florian Müllner, Aaron Plattner, Jasper St. Pierre - -Translations: - Akom Chotiphantawanon [th] - -3.17.4 -====== -* nested: Allow basic configuration of dummy outputs [Jonas; #747089] -* Send wl_surface.enter and wl_surface.leave on output changes [Jonas; #744453] -* Improve HiDPI handling on wayland [Jonas; #745655, #744934] -* Implement compositor-side animated cursors [Carlos; #752342] -* Misc. bug fixes [Peter, Marek, Carlos, Matthias, Rui; #750816, #751884, - #752248, #752551, #752552, #752673, #752674] - -Contributors: - Jonas Ådahl, Marek Chalupa, Matthias Clasen, Carlos Garnacho, Peter Hutterer, - Rui Matos, Florian Müllner, Jasper St. Pierre - -3.17.3 -====== -* Add X11/wayland clipboard interaction [Carlos; #738312] -* Support VM monitor layout hints on wayland [Thomas; #750363] -* Misc. bug fixes [Rui, Jonas, Olivier, Carlos, Ting-Wei, Peter, Florian; - #749994, #750256, #749716, #748705, #750552, #751036, #750007, #751136, - #750552, #751471, #751715, #750680] - -Contributors: - Jonas Ådahl, Dave Airlie, Cosimo Cecchi, Olivier Fourdan, Carlos Garnacho, - Thomas Hellstrom, Peter Hutterer, Ting-Wei Lan, Jasper Lievisse Adriaanse, - Rui Matos, Florian Müllner, Jasper St. Pierre - -Translations: - Marek Černocký [cs], Christian Kirbach [de], Pedro Albuquerque [pt] - -3.17.2 -====== -* Honor default value for click method setting [Rui; #746290] -* Add X11/wayland clipboard interoperation [Carlos; #738312] -* Misc. bug fixes [Rui; #749076, #749711] - -Contributors: - Carlos Garnacho, Rui Matos, Jasper St. Pierre - -3.17.1 -====== -* Add public method to get neighboring monitor [Florian; #633994] -* Apply the right settings to the right input devices [Carlos; #747886] -* Fix scroll button setting [Ondrej; #747967] -* Add support for modal hint on wayland [Jonas; #745720] -* Don't reset idle time for non-hardware events [Rui; #748541] -* Misc. bug fixes [Ray, Rui; #748380, #748478] - -Contributors: - Jonas Ådahl, Carlos Garnacho, Ondrej Holy, Rui Matos, Florian Müllner, - Jasper St. Pierre, Ray Strode, Tomeu Vizoso - -3.16.1 -====== -* Add function to refresh all background instances [Rui; #739178] -* Fix swapped scroll methods on wayland [Ondrej; #746870] -* Manually activate stage to fix accessibility on wayland [Ray, Rui; #746670] -* Center pointer on primary monitor on startup [Carlos; #746896] -* wayland: Reword synchronized state application semantics [Jonas; #743617] -* Ensure input settings are applied on startup [Rui; #747434] -* Misc. bug fixes [Jonas, Giovanni, Calvin, Ray, Rui; #744932, #746509, #746692, - #746510, #746545, #747263] - -Contributors: - Jonas Ådahl, Giovanni Campagna, Carlos Garnacho, Ondrej Holy, Rui Matos, - Jasper St. Pierre, Ray Strode, Calvin Walton - -Translations: - Khaled Hosny [ar], Marek Černocký [cs] - -3.16.0 -====== -* wayland: Don't skip notifying about initial maximized state [Jonas; #745303] - -Contributors: - Jonas Ådahl - -Translations: - Kjartan Maraas [nb], Jiri Grönroos [fi], Andika Triwidada [id], - Inaki Larranaga Murgoitio [eu], Ask H. Larsen [da], Muhammet Kara [tr] - -3.15.92 -======= -* Ensure pointer visibility on monitor changes [Rui, Marek; #745121, #745752] -* Fix geometry of shaded windows [Florian; #746145] -* Take over cursor visibility handling from gsd [Carlos; #712775] -* Fix touch interaction on window decorations [Carlos; #745335] -* Add options for libinput_config_click_method [Carlos; #746290] -* Scale window decorations on HiDPI displays [Florian; #744354] -* Misc. bug fixes [Carlos, Ray, Rui; #745163, #746295, #746098, #745734] - -Contributors: - Marek Chalupa, Carlos Garnacho, Rui Matos, Florian Müllner, - Jasper St. Pierre, Ray Strode - -Translations: - Piotr Drąg [pl], Milo Casagrande [it], Changwoo Ryu [ko], - Daniel Korostil [uk], Baurzhan Muftakhidinov [kk], Trần Ngọc Quân [vi], - Alexander Shopov [bg], Jordi Mas [ca], Samir Ribic [bs], A S Alam [pa], - Matej Urbančič [sl] - -3.15.91 -======= -* wayland: Fix nested compositor mode [Jonas; #745401] -* wayland: Fix pointer constraining [Marek; #727337] -* wayland: Fix input region on HiDPI [Jonas; #744933] -* Allow themes to style buttons differently based on function [Horst; #745108] -* Misc. bug fixes and cleanups [Ray, Rui, Alban; #745141, #745118, #745476, - #745442] - -Contributors: - Jonas Ådahl, Alban Browaeys, Marek Chalupa, Horst, Rui Matos, - Jasper St. Pierre, Ray Strode - -Translations: - Chao-Hsiung Liao [zh_TW], Efstathios Iosifidis [el], Dušan Kazik [sk], - Balázs Úr [hu], Daniel Mustieles [es], Claude Paroz [fr], Stas Solovey [ru], - Yosef Or Boczko [he], Rafael Ferreira [pt_BR], Aurimas Černius [lt], - Fran Dieguez [gl], Anders Jonsson [sv], Мирослав Николић [sr, sr@latin] - -3.15.90 -======= -* Initialize MetaOutput even when we can't get the EDID [Rui; #743412] -* Expose MetaMonitorManager to introspection [Rui; #743745] -* Fix flash on unredirection [Chris; #743858] -* Update xdg-shell implementation to v5 [Jonas; #744452] -* Do not try to use seat devices that aren't (yet) present [Ray; #744640] -* Add keybindings for switching to VT8-VT12 [Ray; #744800] -* Misc bug fixes [Jonas, Cosimo; #743678, #744500] - -Contributors: - Jonas Ådahl, Cosimo Cecchi, Carlos Garnacho, Rui Matos, Jasper St. Pierre, - Ray Strode, Chris Wilson - -Translations: - Yosef Or Boczko [he], Yuri Myasoedov [ru], Kristjan SCHMIDT [eo], - Matej Urbančič [sl], Dušan Kazik [sk] - -3.15.4 -====== -* Use GTK+ theme for window decorations instead of metacity [Florian; #741917] -* Export the same EDID information on X11 and wayland [Carlos; #742882] -* Apply input device configuration on wayland [Carlos; #739397] -* Implement pointer barriers on wayland [Jonas; #706655] -* Misc. bug fixes (Ting-Wei, Rui, Ikey, Florian, Marek, Jonas; #741829, - #738630, #737463, #698995, #727893, #742825, #742824, #742841, #743173, - #743189, #743217, #743254] - -Contributors: - Jonas Ådahl, Giovanni Campagna, Marek Chalupa, Ikey Doherty, Adel Gadllah, - Carlos Garnacho, Ting-Wei Lan, Rui Matos, Florian Müllner, Jasper St. Pierre, - Rico Tzschichholz - -Translations: - Matej Urbančič [sl], Balázs Úr [hu], Marek Černocký [cs], - Inaki Larranaga Murgoitio [eu], Rafael Ferreira [pt_BR], - Daniel Mustieles [es], Fran Dieguez [gl] - -3.15.3 -====== -* Don't leave left-over frames queued [Owen; #738686] -* Set CRTC configuration even if it might be redundant [Rui; #740838] - -Contributors: - Rui Matos, Jasper St. Pierre, Rico Tzschichholz, Owen W. Taylor - -Translations: - Trần Ngọc Quân [vi], Muhammet Kara [tr] - -3.15.2 -====== -* Don't enable hiDPI on monitors with broken EDID [Bastien; #734839] -* Prevent crash applying monitor config for a closed lid [Rui; #739450] -* Fix "flicker" during startup transition [Ray; #740377] -* Misc. bug fixes [Lan, Florian, Carlos; #731521, #740133, #738890] - -Contributors: - Emmanuele Bassi, Carlos Garnacho, Jonathon Jongsma, Ting-Wei Lan, Rui Matos, - Florian Müllner, Bastien Nocera, Jasper St. Pierre, Ray Strode - -Translations: - Kjartan Maraas [nb] - -3.15.1 -====== -* Use GResources for theme loading [Cosimo; #736936] -* Fix headerbar drag getting stuck on xwayland [Carlos; #738411] -* Fix wayland hiDPI regressions [Adel; #739161] -* Misc bug fixes and cleanups [Jasper, Rui, Carlos; #662962, #738630, #738888, - #738890] - -Contributors: - Cosimo Cecchi, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner, - Jasper St. Pierre - -3.14.1 -====== -* Fix move-titlebar-onscreen function [Florian; #736915] -* Fix stacking of the guard window [Owen; #737233] -* Fix keycode lookup for non-default layouts [Rui; #737134] -* Fix workspaces-only-on-primary handling [Florian; #737178] -* Don't unstick sticky windows on workspace removal [Florian; #737625] -* Do not auto-minimize fullscreen windows [Jasper; #705177] -* Upload keymap to newly added keyboard devices [Rui; #737673] -* Apply keyboard repeat settings [Rui; #728055] -* Don't send pressed keys on enter [Rui; #727178] -* Fix build without wayland/native [Rico; #738225] -* Send modifiers after the key event [Rui; #738238] -* Fix unredirect heuristic [Adel; #738271] -* Do not show system chrome over fullscreen windows [Florian; #693991] -* Misc. bug fixes [Florian, Adel, Tom; #737135, #737581, #738146, #738384] - -Contributors: - Tom Beckmann, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner, - Jasper St. Pierre, Rico Tzschichholz, Owen W. Taylor - -Translations: - Krishnababu Krothapalli [te], Мирослав Николић [sr, sr@latin], - Alexander Shopov [bg], Saibal Ray [bn_IN], Milo Casagrande [it], - Rūdolfs Mazurs [lv] - -3.14.0 -====== -* Fix placement of popup windows on wayland [Jasper; #736812] -* Only increment serial once per event [Jasper; #736840] -* Fix window positioning regression with non-GTK+ toolkits [Owen; #736719] - -Contributors: - Jasper St. Pierre, Owen W. Taylor - -Translations: - Saibal Ray [bn_IN], Dušan Kazik [sk], Manoj Kumar Giri [or], - Christian Kirbach [de], Ask H. Larsen [da], YunQiang Su [zh_CN], - Bernd Homuth [de], Shankar Prasad [kn], Petr Kovar [cs], Rajesh Ranjan [hi] - -3.13.92 -======= -* Rewrite background code [Owen; #735637, #736568] -* Fix size in nested mode [Owen; #736279] -* Fix destroy animation of background windows [Florian; #735927] -* Wire keymap changes up to the wayland frontend [Rui; #736433] -* Add a test framework and stacking tests [Owen; #736505] -* Simplify handling of the merged X and wayland stack [Owen; #736559] -* Fix cursor size on HiDPI [Adel; #729337] -* Misc. bug fixes [Owen; #735632, #736589, #736694] - -Contributors: - Adel Gadllah, Rui Matos, Florian Müllner, Jasper St. Pierre, Owen W. Taylor - -Translations: - Andika Triwidada [id], Piotr Drąg [pl], Changwoo Ryu [ko], - Kjartan Maraas [nb], Ville-Pekka Vainio [fi], Yuri Myasoedov [ru], - Aurimas Černius [lt], Balázs Úr [hu], Sweta Kothari [gu], A S Alam [pa], - Sandeep Sheshrao Shedmake [mr], Shantha kumar [ta], Gil Forcada [ca], - Carles Ferrando [ca@valencia], Mattias Eriksson [sv] - -3.13.91 -======= -* Misc. bug fixes [Carlos; #735452] - -Contributors: - Adel Gadllah, Carlos Garnacho, Rui Matos, Jasper St. Pierre, - Rico Tzschichholz - -Translations: - Chao-Hsiung Liao po/zh_HK, zh_TW.po, Enrico Nicoletto [pt_BR], - Kjartan Maraas [nb], Fran Diéguez [gl], Yosef Or Boczko [he], - Maria Mavridou [el], Claude Paroz [fr] - -3.13.90 -======= -* Only call XSync() once per frame [Rui; #728464] -* Update capabilities on device list changes [Carlos; #733563] -* Make use of GLSL optional [Adel; #733623] -* Handle gestures and touch events on wayland [Carlos; #733631] -* Add support for unminimize compositor effects [Cosimo; #733789] -* Always set the frame background to None [Giovanni; #734054] -* Add backend methods to handle keymaps [Rui; #734301] -* Actually mark revalidated MetaTextureTower levels as valid [Owen; #734400] -* Rely on explicit -backward switcher keybindings instead of -magic - [Christophe; #732295, #732385] -* Misc. bug fixes and cleanups [Rui, Adel, Christophe; #727178, #734852, - #734960] - -Contributors: - Emmanuele Bassi, Giovanni Campagna, Cosimo Cecchi, Piotr Drąg, - Christophe Fergeau, Adel Gadllah, Carlos Garnacho, Rui Matos, - Florian Müllner, Jasper St. Pierre, Rico Tzschichholz, Olav Vitters, - Owen W. Taylor - -Translations: - Kjartan Maraas [nb], Inaki Larranaga Murgoitio [eu], Lasse Liehu [fi], - ngoswami [as], Daniel Mustieles [es] - -3.13.4 -====== -* Fix move/resize operations for wayland clients [Marek; #731237] -* Add ::first-frame signal to MetaWindowActor [Owen; #732343] -* Handle keysyms without the XF86 prefix [Owen; #727993] -* Add touch gesture support [Carlos] -* Fix a deadlock when exiting [Owen; #733068] -* Add framework for restarting the compositor with nice visuals - [Owen; #733026] -* Toggle seat capabilities on VT switch [Carlos; #733563] -* Misc bug fixes [Florian, Owen; #732695, #732350] - -Contributors: - Tom Beckmann, Giovanni Campagna, Marek Chalupa, Adel Gadllah, - Carlos Garnacho, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz, - Owen W. Taylor - -Translations: - Yuri Myasoedov [ru], Fran Diéguez [gl], Aurimas Černius [lt], MarMav [el], - Enrico Nicoletto [pt_BR] - -3.13.3 -====== -* Improve behavior of window buttons with compositor menus [Florian; #731058] -* Implement touch support on wayland [Carlos; #724442] -* Update window shadows [Nikita; #731866] -* Keep windows on the preferred output [Florian; #731760] -* Misc bug fixes [Jonas, Florian, Jasper; #729601, #730681, #731353, #731332, - #730527, #662962] - -Contributors: - Jonas Ådahl, Nikita Churaev, Carlos Garnacho, Florian Müllner, - Jasper St. Pierre, Rico Tzschichholz - -3.13.2 -====== -* Add basic HiDPI support on wayland [Adel; #728902] -* Fix crash when monitors change during suspend [Giovanni; #725637] -* Replace mutter-launch with logind integration [Jasper; #724604] -* Move window menu into the compositor [Jasper; #726352] -* Fix delayed focus-follows-mouse support [Florian; #730541] -* Support fallback app menu in window decorations [Florian; #730752] -* Misc. bug fixes and cleanups [Giovanni, Jonas, Jasper; #729732, #729602, - #726714] - -Contributors: - Jonas Ådahl, Giovanni Campagna, Adel Gadllah, Florian Müllner, - Jasper St. Pierre, Rico Tzschichholz - -Translations: - Pau Iranzo [ca], Daniel Mustieles [es] - -3.13.1 -====== -* Fix opacity values from _NET_WM_WINDOW_OPACITY [Nirbheek; #727874] -* Merge wayland branch [Jasper, Giovanni, Robert B., Neil, Adel, Rui, Jonas, - Lionel, Tim, Owen, Florian, Colin W., Cosimo, Ray, Kalev, Pavel, Robert A., - Magdalen, Marek, Matthias, Alban, Seán, Daniel, Stefano, Carlos, Colin G., - Andreas, Alexander, Ryan, Marc-André, Asad, Alberto, Bastien, Hans, - Debarshi, Sindhu, Andika, Rico, Olav] -* Don't prevent workspace switches for present_with_time() [Florian; #728018] -* Add shortcuts for switching to the last workspace [Elad; #659288] -* Make move/resize menu items behave like the keybindings [Jasper; #728617] -* Misc. bug fixes and cleanups [Jasper, Bastien, Florian, Adel; #720631, - #727979, #728423, #728395, #729044] - -Contributors: - Jonas Ådahl, Elad Alfassa, Robert Ancell, Magdalen Berns, Robert Bragg, - Giovanni Campagna, Cosimo Cecchi, Marek Chalupa, Nirbheek Chauhan, - Matthias Clasen, Alban Crequy, Seán de Búrca, Daniel Drake, Jason Ekstrand, - Stefano Facchini, Adel Gadllah, Carlos Garnacho, Colin Guthrie, - Andreas Heider, Lionel Landwerlin, Alexander Larsson, Kalev Lember, - Ryan Lortie, Tim Lunn, Marc-André Lureau, Rui Matos, Asad Mehmood, - Alberto Milone, Florian Müllner, Bastien Nocera, Hans Petter Jansson, - Debarshi Ray, Neil Roberts, Sindhu S, Jasper St. Pierre, Ray Strode, - Andika Triwidada, Rico Tzschichholz, Pavel Vasin, Olav Vitters, - Colin Walters, A. Walton, Owen W. Taylor - -Translations: - Inaki Larranaga Murgoitio [eu], marablack3 [el], Daniel Mustieles [es], - Fran Diéguez [gl], Yosef Or Boczko [he], Dirgita [id] - -3.12.0 -====== -* Fix grab issue with SSD xwayland windows [Rui; #726123] -* Misc. bug fixes [Jasper, Ray, Rui, Florian; #727011] - -Contributors: - Rui Matos, Florian Müllner, Jasper St. Pierre, Ray Strode - -3.11.92 -======= -* Fix identification of CSD windows [Owen; #723029] -* Update keyboard state unconditionally [Rui; #722847] -* Misc bug fixes and cleanups [Owen, Rui, Giovanni, Matthias, Adel, Ryan, - Jasper, Marek, Florian; #723580, #726123, #726683] - -Contributors: - Giovanni Campagna, Marek Chalupa, Matthias Clasen, Adel Gadllah, Ryan Lortie, - Rui Matos, Florian Müllner, Jasper St. Pierre, Owen W. Taylor - -3.11.91 -======= -* Don't use keysym to match keybindings [Rui; #678001] -* Fix message tray icons showing up blank (again) [Adel; #725180] -* Improve keybinding lookups [Rui; #725588] -* Fix dynamic updates of titlebar style properties [Owen; #725751] -* Fix positioning of manually positioned windows [Owen; #724049] -* Misc bug fixes and cleanups [Jasper, Carlos, Adel, Giovanni, Florian; #720631, - #724969, #725216, #724402, #722266, #725338, #725525] - -Contributors: - Giovanni Campagna, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner, - Jasper St. Pierre, Owen W. Taylor - -3.11.90 -======= -* Fix double-scaling on high DPI resolutions [Adel; #723931] -* Make tile previews a compositor effect [Stefano, Florian; #665758] -* Misc. bug fixes and cleanups [Ryan, Giovanni, Jasper, Adel; #722530, #724257, - #724258, #720631, #724364, #724472] - -Contributors: - Giovanni Campagna, Marek Chalupa, Stefano Facchini, Adel Gadllah, - Ryan Lortie, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz - -3.11.5 -====== -* Fix CSD titlebars being placed off-screen [Jasper; #719772] -* Add support for subsurfaces [Jonas; #705502] -* Expose MetaWindow:skip-taskbar property [Florian; #723307] -* Fix legacy tray icons showing up blank [Adel; #721596] -* Fix configuration of cloned monitors [Adel; #710610] -* Misc bug fixes and cleanups [Jasper, Adel, Marek, Jonas; #720631, #723468, - #720818, #723563, #723564] - -Contributors: - Jonas Ådahl, Marek Ch, Adel Gadllah, Florian Müllner, Jasper St. Pierre - -3.11.4 -====== -* Don't leave focus on windows that are being unmanaged [Owen; #711618] -* Reduce server grabs [Daniel Drake; #721345, #721709] -* Improve heuristic to determine display output name [Cosimo Cecchi; #721674] -* Atomically unmaximize both directions [Jasper; #722108] -* Misc bug fixes [Debarshi, Andika, Florian; #721517, #721674, #722347] - -Contributors: - Cosimo Cecchi, Daniel Drake, Florian Müllner, Debarshi Ray, Jasper St. Pierre, - Andika Triwidada, Owen W. Taylor - -3.11.3 -====== -* Fix focus issues with external OSKs[Jasper; #715030] -* Add a MetaCullable interface [Jasper; #714706] -* Fix window keybindings [Rui; #719724] -* Fix settings keyboard/pointer focus for new clients [Rui; #719725] -* Fix window group paint volume [Owen; #719669] -* Fix frame extents problems [Owen; #714707] -* Add shortcut to move windows between monitors [Florian; #671054] -* Fix problems with focus tracking [Owen; #720558] -* Misc. bug fixes and cleanups: [Rui, Colin, Lionel, Jasper, Owen; #712833, - #719557, #719695, #719833, #678989, #720417, #720630] - -Contributors: - Lionel Landwerlin, Rui Matos, Alberto Milone, Florian Müllner, - Jasper St. Pierre, Rico Tzschichholz, Owen W. Taylor, Colin Walters - -3.11.2 -====== -* Support setting a NULL opaque region [Andreas; #711518] -* Sync keymap from X to wayland [Giovanni; #707446] -* Implement support for subsurfaces [Jonas; #705502] -* Don't focus the no-focus-window for globally active windows [Jasper; #710296] -* Support "hotplug_mode_update" property [Marc-André; #711216] -* Fix resize operations using mouse-button-modifier [Lionel; #710251] -* Fix position of attached modals for CSD windows [Giovanni, Owen; #707194] -* Misc. bug fixes [Rui, Jasper, Neil, Florian; #712247, #711731] - -Contributors: - Giovanni Campagna, Andreas Heider, Lionel Landwerlin, Marc-André Lureau, - Rui Matos, Florian Müllner, Neil Roberts, Sindhu S, Jasper St. Pierre, - Rico Tzschichholz, Owen W. Taylor, Jonas Ådahl - -3.11.1 -====== -* Fix tile previews getting stuck on right click during drags [Lionel; #704759] -* Use new UPower API [Bastien] -* Set hot spot when cursor set from wl_buffer [Jonas; #709593] -* Expose min-backlight-step [Asad; #710380] -* Misc. bug fixes and cleanups [Jasper, Olav, Magdalen; #709776] - -Contributors: - Magdalen Berns, Lionel Landwerlin, Asad Mehmood, Bastien Nocera, - Jasper St. Pierre, Olav Vitters, Jonas Ådahl - -3.10.1 -====== -* Don't apply fullscreen workarounds to CSD windows [Giovanni; #708718] -* Fix hangs during DND operations [Adel; #709340] -* Misc bug fixes [Dan, Giovanni, Jasper; #708813, #708420] - -Contributors: - Giovanni Campagna, Adel Gadllah, Dan Horák, Hans Petter Jansson, - Jasper St. Pierre - -3.10.0.1 -======== -* Fix bug when a window changed size twice in a single frame - this - can happen with GTK+ client-side decorations [Giovanni, Owen; #708367] - -Contributors: - Giovanni Campagna, Owen Taylor - -3.10.0 -====== -* Update dependencies [Giovanni; #708210] - -3.9.92 -====== -* Constrain the pointer position onto visible monitors [Giovanni; #706655] -* Fix keyboard state handling in face of event compression [Giovanni; #706963] -* Extend the MetaCursorTracker API with query pointer and cursor visibility [Giovanni; #707474] -* Be stricter in checking and exposing the wayland protocol version [#707851] -* Don't require plugins to pass event to Clutter [Giovanni; #707482] -* Move the --wayland option from the binary to the library [Giovanni; #707897] -* Implement running from gnome-session (environment variable setting, process group - handling, Clutter backend variables) [Giovanni; #706421] -* Add support for more cursor types [Giovanni; #707919] -* Drop man pages for removed utilities [Kalev; #706579] -* Implement monitor configuration on KMS [Giovanni; #706308] -* Implement HW cursors [Giovanni; #707573] -* Implement minimal support for resizing and maximizing wayland clients [Giovanni; #707401] -* Implement transient hints for wayland clients [Giovanni; #707401] -* Implement popup menu surfaces and grabs [Giovanni; #707863] -* Immediately fire idle watches that are already expired [Giovanni; #707302] -* Remove holes generated by disabling the laptop lid [Giovanni; #707473] -* Misc bug fixes [Giovanni, Pavel, Adel; #707649, #706124, #707584, #707851, #707929, - #708070] - -Contributors: - Adel Gadllah, Giovanni Campagna, Kalev Lember, Pavel Vasin - -Translations: - Мирослав Николић po/sr, sr@latin.po, Мирослав Николић [sr, sr@latin], - Chao-Hsiung Liao [zh_HK, zh_TW], Yuri Myasoedov [ru], - Ville-Pekka Vainio [fi], Changwoo Ryu [ko], A S Alam [pa], - Mattias Põldaru [et], Rūdolfs Mazurs [lv], Ihar Hrachyshka [be], - Nilamdyuti Goswami [as], Andika Triwidada [id], Baurzhan Muftakhidinov [kk], - Benjamin Steinwender [de] - -3.9.91 -====== -* Drop man pages for removed utilities [Kalev; #706579] -* Add support for idle tracking [Giovanni, Cosimo; #706005, #707250] -* Skip CRTC reconfigurations that have no effect [Giovanni; #706672] -* 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] -* 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] -* Install an X IO error handler for XWayland [Giovanni; #706962] -* Use the clutter xkbcommon integration for the wayland keyboard [Giovanni; #705862] -* Add a setuid helper for running on KMS+evdev [Giovanni, Colin; #705861] -* Add keybindings for switching VT [Giovanni; #705861] -* Implement plugin modality when running as a wayland compositor [Giovanni; #705917] -* Add support for the application menu for wayland clients [Giovanni; #707128] -* Several Coverity spotted fixes [Jasper] -* Don't create a dummy texture for the texture template [Neil; #707458] -* Use a more conservative paint volume for obscured windows [Adel] -* Misc bug fixes [Giovanni, Colin, Seán, Jasper, Cosimo; #706582, #706598, - #706787, #706729, #706825, #707081, #707090, #707267, #706982, #706289] - -Contributors: - Giovanni Campagna, Cosimo Cecchi, Adel Gadllah, Colin Guthrie, Kalev Lember, - Tim Lunn, Jasper St. Pierre, Neil Roberts, Rico Tzschichholz, Seán de Búrca - -Translations: - Piotr Drąg [pl], Alexandre Franke [fr], Kjartan Maraas [nb], - Milo Casagrande [it], Balázs Úr [hu], Seán de Búrca [ga], Fran Diéguez [gl], - Daniel Mustieles [es], Aurimas Černius [lt], Gil Forcada [ca] - -3.9.90 -====== -* First release from the wayland branch, includes basic support for running - as a wayland compositor [Robert, Neil, Giovanni] -* Add support for _GTK_FRAME_EXTENTS [Jasper; #705766] -* Fix quick consecutive presses breaking keyboard input [Alban; #666101] -* Work towards running as wayland compositor [Giovanni] - - Add DBus API for display configuration - [#705670, #706231, #706233, #706322, #706382] - - Add abstraction layer for cursor tracking [#705911] - - Add support for plugin modality under wayland [#705917] -* Disable GTK+ scaling [Alexander; #706388] -* Disable blending while updating tower [Robert] -* Misc bug fixes and cleanups [Adel, Jasper, Giovanni, Colin, Rico, Florian; - #703332, #704437, #706207] - -Contributors: - Robert Bragg, Giovanni Campagna, Alban Crequy, Adel Gadllah, - Alexander Larsson, Florian Müllner, Jasper St. Pierre, Neil Roberts, - Rico Tzschichholz, Colin Walters - -Translations: - Jiro Matsuzawa [ja], Kjartan Maraas [nb], Matej Urbančič [sl], - Marek Černocký [cs], Daniel Mustieles [es], Rafael Ferreira [pt_BR], - Yaron Shahrabani [he], Ján Kyselica [sk] - -3.9.5 -===== -* Don't select for touch events on the stage [Jasper; #697192] -* Don't queue redraws for obscured regions [Adel; #703332] -* Export timestamp of global keybinding events [Bastien; #704858] -* Misc bug fixes and cleanups [Jasper, Rico; #703970] - -Contributors: - Adel Gadllah, Bastien Nocera, Jasper St. Pierre, Rico Tzschichholz - -3.9.4 -===== -* Tweak window shadows [Allan; #702141] -* Ignore our own focus events for focus prediction [Jasper; #701017] -* Add API to query if the stage is focused [Jasper; #700735] -* Add API to query the monitor for a given position [Adel] -* Don't force attached dialogs to be border-only [Florian; #702764] -* Allow slicing of backgrounds to avoid texture size limits [Ray; #702283] -* Miscellaneous bug fixes and cleanups [Adel; #701224, #702564] - -Contributors: - Allan Day, Adel Gadllah, Florian Müllner, Jasper St. Pierre, Ray Strode - -3.9.3 -===== -* Ensure events are always reported to the grab window [Rui; #701219] -* Use new clutter_stage_set_paint_callback() function to prevent dropping - frames with frame synced toolkits [Owen; #698794] - -Contributors: - Rui Matos, Owen W. Taylor - -3.9.2 -===== -* Add meta_window_can_close() function [Jasper; #699269] -* Add support for string-array preferences [Florian; #700223] -* Fix a potential race condition with _NET_WM_MOVERESIZE [Jasper; #699777] -* Fix shade window action [Stef; #693714] -* Remove overlay_group [Giovanni; #700735] -* Improve tracking of the focus window [Dan, Jasper; #647706] -* Add API to freeze/unfreeze the keyboard [Rui; #697001] -* Grab and emit a signal when XK_ISO_Next_Group is pressed [Rui; #697002] -* Misc bug fixes and cleanups [Dieter, Jasper, Rui; #699636, #700735, #697000] - -Contributors: - Giovanni Campagna, Rui Matos, Florian Müllner, Jasper St. Pierre, - Dieter Verfaillie, Stef Walter, Dan Winship - -Translations: - Kjartan Maraas [nb], Ján Kyselica [sk] - -3.9.1 -===== -* Fix miscellaneous memory leaks [Pavel; #698710] -* Misc fixes and cleanups [Stef, Simon; #698179, #697758] - -Contributors: - Simon McVittie, Pavel Vasin, Stef Walter - -3.8.1 -===== -* Fix crash when getting default font [Bastien; #696814] -* Fix ungrabbing of keybindings [Rui; #697003] -* Misc fixes and cleanups [Jasper, Simon; #697758] - -Contributors: - Jasper Lievisse Adriaanse, Rui Matos, Simon McVittie, Bastien Nocera - -Translations: - Guillaume Desmottes [fr], Shankar Prasad [kn], Bruce Cowan [en_GB], - Andika Triwidada [id], Yaron Shahrabani [he], Kjartan Maraas [nb], - Gheyret Kenji [ug] - -3.8.0 -===== -* Address major memory leak when changing backgrounds [Ray; #696157] - -Contributors: - Ray Strode - -Translations: - Sandeep Sheshrao Shedmake [mr], Victor Ibragimov [tg], Gabor Kelemen [hu], - Ville-Pekka Vainio [fi], Rajesh Ranjan [hi], Dr.T.Vasudevan [ta], - ManojKumar Giri [or], Yuri Myasoedov [ru], Petr Kovar [cs], - Jiro Matsuzawa [ja], Krishnababu Krothapalli [te], Ani Peter [ml], - Inaki Larranaga Murgoitio [eu] - -3.7.92 -====== -* Build and improve reference docs [Tomeu; #676856, #695641, #695935] -* Add tracking of whether there are fullscreen windows [Owen; 649748] -* Misc bug fixes and cleanups [Adel, Giovanni, Owen, Jasper, Florian; #695269, - #695711, #694046, #695813, #695881, #676856, #696053, #682779, #696089, - #696091, #696087] - -Contributors: - Giovanni Campagna, Adel Gadllah, Florian Müllner, Jasper St. Pierre, - Tomeu Vizoso, Owen W. Taylor - -Translations: - Chao-Hsiung Liao [zh_HK, zh_TW], Rafael Ferreira [pt_BR], - Ihar Hrachyshka [be], Nilamdyuti Goswami [as], Matej Urbančič [sl], - Dimitris Spingos [el], Jan Kyselica [sk], Khaled Hosny [ar], - Мирослав Николић [sr, sr@latin], Duarte Loreto [pt], Sweta Kothari [gu], - Milo Casagrande [it], Changwoo Ryu [ko], Gil Forcada [ca], - Carles Ferrando [ca@valencia], Mattias Põldaru [et], Alexandre Franke [fr], - Ask H. Larsen [da], Rūdolfs Mazurs [lv], Nguyễn Thái Ngọc Duy [vi] - -3.7.91 -====== -* Fix windows being treated as remote after hostname changes [Ray; #688716] -* Add meta_window_get_all_monitors() method [Adel; #646861] -* Add grab API for externally defined accelerators [Florian; #643111] -* Make session registration an explicit step [Ray; #694876] -* Avoid unnecessary stage redraws [Adel; #694988, #695006] -* Misc fixes [Giovanni, Ray, Jasper, Rui, Pavel, Owen; #694801, #694725, - #694641, #694393, #678917, #695093, #694837, #695135, #694771, #694321] - -Contributors: - Giovanni Campagna, Adel Gadllah, Rui Matos, Florian Müllner, - Jasper St. Pierre, Ray Strode, Owen Taylor, Pavel Vasin - -Translations: - Daniel Mustieles [es], Yaron Shahrabani [he], A S Alam [pa], Piotr Drąg [pl], - Gheyret Kenji [ug], Alexandre Franke [fr], Milo Casagrande [it], - Fran Diéguez [gl], Dimitris Spingos [el], Мирослав Николић [sr, sr@latin], - Chao-Hsiung Liao [zh_HK, zh_TW], Nguyễn Thái Ngọc Duy [vi], - Aurimas Černius [lt], Mario Blättermann [de], Kjartan Maraas [nb] - -3.7.90 -====== -* Support _NET_WM_OPAQUE_REGION [Jasper, Adel; #679901] -* Add wrapper for XI2.3 pointer barriers [Jasper; #677215] -* Update style of resize popups [Cosimo; #692741] -* Implement compositor <-> application frame synchronization [Owen; #685463] -* Handle animated backgrounds [Ray; #682427] -* Add a new window group for override-redirect windows [Gayan; #633620] -* Pass on pointer events on guard window to Clutter [Jasper; #681540] -* Show correct shortcut in window menus [Giovanni; #694045] -* Don't put minimized windows at the back of alt-tab [Jasper; #693991] -* Misc bug fixes and cleanups [Jasper, Rico, Adel, Florian, Rui, Giovanni, - Owen; #692679, #693354, #690581, #693439, #692718, #693475, #693482, #693540, - #690580, #680990, #693833, #693922, #693854, #694224] - -Contributors: - Giovanni Campagna, Cosimo Cecchi, Adel Gadllah, Rui Matos, Florian Müllner, - Gayan Perera, Jasper St. Pierre, Ray Strode, Owen Taylor, Rico Tzschichholz - -Translations: - Fran Diéguez [gl], A S Alam [pa], Alexandre Franke [fr], Aurimas Černius [lt], - Мирослав Николић [sr, sr@latin], Fran Diéguez [gl], Piotr Drąg [pl], - Luca Ferretti [it], Daniel Mustieles [es] - -3.7.5 -===== -* Don't allow multiline window titles [Jon; #683056] -* Make meta_window_located_on_workspace() public [Jasper; #691744] -* Request XI2.3 [Colin; #692877] -* Add meta_window_set_icon_geometry() method [Florian; #692997] -* Require XFixes 5.0 [Jasper; #677215] -* Change unredirection hints to match spec changes [Adel; #693064] -* Improve unredict heuristicts [Adel; #683786] -* Misc bug fixes and cleanups [Florian, Jasper, Adel; #691874, #679901, - #692952, #693042] - -Contributors: - Adel Gadllah, William Jon McCann, Florian Müllner, Jasper St. Pierre, - Colin Walters - -Translations: - Daniel Mustieles [es], Ihar Hrachyshka [be], Nilamdyuti Goswami [as], - Gheyret Kenji [ug], Kjartan Maraas [nb], Yaron Shahrabani [he], - Piotr Drąg [pl], Chao-Hsiung Liao [zh_HK,zh_TW], Milo Casagrande [it] - -3.7.4 -===== -* Add support for bypass compositor hints [Adel; #683020] -* Make automaximization optional [Adel; #680990] -* Add method for checking if the application is responding [Giovanni; #684340] -* Expose the xinput opcode [Jasper; #690590] -* Rebrand "minimize" as "hide" [Florian; #682887] -* Misc bug fixes and cleanups [Giovanni, Ray, Jasper, Matthias, Debarshi, - Florian, Rui; #690454, #690573, #690593, #690956, #691363, #690609, #690317, - #689263] - -Contributors: - Giovanni Campagna, Matthias Clasen, Adel Gadllah, Rui Matos, Florian Müllner, - Debarshi Ray, Jasper St. Pierre, Ray Strode - -Translations: - Mattias Põldaru [et], Yaron Shahrabani [he], Daniel Mustieles [es], - Khaled Hosny [ar], Fran Diéguez [gl], A S Alam [pa], Piotr Drąg [pl], - Rafael Ferreira [pt_BR], Nilamdyuti Goswami [as], Alexander Shopov [bg], - Matej Urbančič [sl] - -3.7.3 -===== -* Fix maximized windows jumping to other monitors [Alban; #556696] -* Add 'switch-applications' keybinding [Florian; #688913] -* Add a convenience method to focus the default window [Jasper; #689652] -* Increase typical icon size to 96 [Jasper; #689651] -* Port to XInput2 [Jasper; #688779] -* Give dynamic keybindings a keybinding action [Florian; #682315] -* Misc. fixes and cleanups [Jasper, Rui; #688777] - -Contributors: - Alban Crequy, Rui Matos, Florian Müllner, Jasper St. Pierre - -Translations: - Nilamdyuti Goswami [as], Piotr Drąg [pl], Yaron Shahrabani [he], - Dr.T.Vasudevan [ta], ManojKumar Giri [or], Shankar Prasad [kn] - -3.7.2 -===== -* Fix spurious focus changes when showing desktop [Florian; #686928] -* MetaPluginManager: don't send events to Clutter twice [Owen; #686406] -* Add the ability to add shader hooks to MetaBackgroundActor [Giovanni; #669798] -* Only process keyboard mapping events for the core X keyboard [Rui; #674859] -* Import keybinding files from Metacity [Florian; #687672] -* Add compositor hook to process keybindings selectively [Florian; #688202] -* MetaBackgroundActor: add a setter for GLSL uniforms [Giovanni; #682536] -* Misc. fixes and cleanups [Jasper, Rui, Florian, Rico; #688182] - -Contributors: - Giovanni Campagna, Rui Matos, Florian Müllner, Jasper St. Pierre, - Owen Taylor, Rico Tzschichholz - -Translations: - Rafael Ferreira [pt_BR], Tobias Endrigkeit [de], Yaron Shahrabani [he] - -3.7.1 -===== -* screen: Ignore num-workspaces when using dynamic workspaces [Florian; #685439] - -Contributors: - Florian Müllner - -Translations: - Mattias Põldaru [et], Kjartan Maraas [nb], Мирослав Николић [sr, sr@latin], - Marek Černocký [cs], Andika Triwidada [id], Daniel Mustieles [es], - Fran Diéguez [gl], Matej Urbančič [sl] - -3.6.1 -===== -* Fix crash when opening large popup menus [Jasper; #681676] -* window: Don't move the desktop window after monitor hotplug [Jasper; #681159] -* Expose MetaPlugin to introspection [Evan; #671098] -* Optionally delay focus changes in focus-follows-mouse mode [Florian; #678169] -* Resize the guard window when the X screen is resized [Benjamin; #670396] -* display: Only manage the default X screen [Jürg; #648156] -* Misc cleanups: [Owen; #587255] - -Contributors: - Benjamin Berg, Jürg Billeter, Evan Broder, Florian Müllner, Jasper St. Pierre, - Owen Taylor - -Translations: - Alexandre Franke [fr], Theppitak Karoonboonyanan [th], Sayak Sarkar [bn_IN], - Sandeep Sheshrao Shedmake [mr], Ask H. Larsen [da], Shankar Prasad [kn], - Alexander Shopov [bg], Aurimas Černius [lt], Ihar Hrachyshka [be], - Kjartan Maraas [nb], Daniel Mustieles [es], Changwoo Ryu [ko], - Yuri Myasoedov [ru], Tom Tryfonidis [el], Rūdolfs Mazurs [lv], - Chris Leonard [en_GB], Piotr Drąg [pl], Fran Diéguez [gl], Gil Forcada [ca], - Matej Urbančič [sl], Andika Triwidada [id], Carles Ferrando [ca] - -3.6.0 -===== - -Translations: - Alexander Shopov [bg], Daniel Korostil [uk], Rajesh Ranjan [hi], - Krishnababu Krothapalli [te], Ani Peter [ml], Rūdolfs Mazurs [lv], - Sweta Kothari [gu], Ihar Hrachyshka [be], Noriko Mizumoto [ja], - Timo Jyrinki [fi], Mattias Põldaru [et] - -3.5.92 -====== -* screen: Allow NULL out arguments in meta_screen_get_size [Tomeu] -* display: Add API to set wm_name / wm_keybindings [Florian; #671010] -* Improve the not responding dialog [Jon, Florian; #684306] -* Misc. bugfixes [Jasper] - -Contributors: - William Jon McCann, Florian Müllner, Jasper St. Pierre, Tomeu Vizoso - -Translations: - Gabor Kelemen [hu], Piotr Drąg [pl], Dr.T.Vasudevan [ta], Bruce Cowan [en_GB], - Alexandre Franke [fr], Theppitak Karoonboonyanan [th], Gil Forcada [ca], - Carles Ferrando [ca@valencia], Tobias Endrigkeit [de], Tom Tryfonidis [el], - Nguyễn Thái Ngọc Duy [vi], Changwoo Ryu [ko], Ask H. Larsen [da], - Rafael Ferreira [pt_BR], Marek Černocký [cs] - -3.5.91 -====== -* Do not include markup in app not responding dialog [Alex] -* Fix subtracting unredirected windows from visible region [Jasper; #677116] -* Minor improvements and bugfixes [Jasper, Florian; #682648, #682993] - -Contributors: - Alexander Larsson, Florian Müllner, Jasper St. Pierre - -Translations: - Dirgita [id], Piotr Drąg [pl], A S Alam [pa], Yuri Myasoedov [ru], - Milo Casagrande [it], Nilamdyuti Goswami [as], Tom Tryfonidis [el], - Duarte Loreto [pt], Fran Diéguez [gl], Nguyễn Thái Ngọc Duy [vi], - Aurimas Černius [lt], Daniel Nylander [sv] - -3.5.90 -====== -* Fix logic for handling translations of the windows group [Owen; #681221] -* Handle painting inside a Clutter clone [Owen; #681953] -* Update overlay-key on settings changes [Florian; #681906] -* Add keybinding for overlay-key [Florian; #665547] -* Minor fixes and improvements [Javier, Florian] - -Contributors: - Javier Jardón, Florian Müllner, Owen Taylor - -Translations: - Sweta Kothari [gu], Muhammet Kara [tr], Khaled Hosny [ar], - Sandeep Sheshrao Shedmake [mr] - -3.5.5 -===== -* Fix flickering around windows when using window group [Tom; #681221] - -Contributor(s): - Tom Beckmann - -Translations: - Chao-Hsiung Liao [zh_HK, zh_TW], Matej Urbančič [sl], Fran Diéguez [gl], - Мирослав Николић [sr, sr@latin], Yaron Shahrabani [he], Kjartan Maraas [nb] - -3.5.4 -===== -* Make it possible to reimplement move-to-workspace keybindings from plugins - [Giovanni; #674104] -* Add a preference to ignore hide-titlebar-when-maximized hint [Rico; #678947] -* window: Also use hide-titlebar-when-maximized when tiled [Florian; #679290] -* Center modal dialogs on their parent instead [Florian; #674499] -* Reduce amount of markup in translated messages [Matthias; #679660] -* Fix focus problem after closing a window with focus-follows-mouse - [Jasper; #675982] -* Handle changes of the attach-modal-dialogs preference [Florian; #679904] -* Do not restore tiling on unmaximize [Florian; #677565] -* Misc. fixes and cleanups [Jasper Adriaanse, Jasper, Debarshi, Pavel; - #679153, 673824] - -Contributors: - Jasper Lievisse Adriaanse, Giovanni Campagna, Matthias Clasen, Florian Müllner, - Debarshi Ray, Jasper St. Pierre, Rico Tzschichholz, Pavel Vasin - -Translations: - Alexander Shopov [bg], Kjartan Maraas [nb], Yaron Shahrabani [he], - Nilamdyuti Goswami [as], Ihar Hrachyshka [be], Daniel Mustieles [es] - -3.5.3 -===== -* Simplify plugin system [Jasper; #676855] -* meta-window-actor: Don't unredirect shaped windows [Jasper; #677657] -* screen: Add new public meta_screen_get_current_monitor API [Tim; #642591] -* frames: Increase the size of resize corners [Jasper; #677669] -* window: Make some window methods public [Jasper; #678126] -* Fix crash when running mutter stand-alone [Jasper; #678238] -* meta-window-actor: Fix potential crash in shaping code [Jasper; #677977] -* Misc. fixes [Jasper, Marc-Antoine, Rico] - -Contributors: - Tim L, Marc-Antoine Perennou, Jasper St. Pierre, Rico Tzschichholz - -Translations: - - Daniel Mustieles [es], Matej Urbančič [sl], Khaled Hosny [ar], - Bruno Brouard [fr], Fran Diéguez [gl] - -3.5.2 -===== -* keybindings: Remove 'toggle-recording' binding [Florian; #674376] -* Switch to gtk-doc syntax [Jasper; #673752] -* shaped-texture: never slice shape mask texture [Robert; #674731] -* Make Mutter stop relying on Cogl including a GL header [Neil; #672711] -* Make support for "XFree86" Xinerama mandatory [Owen; #674727] -* meta_window_move_frame(): fix crash when frame is NULL [Owen; #675254] -* Fix memory leaks [Pavel; #672640] -* Code cleanups [Jasper; #671104 #674876 #676052] -* Look for themes in XDG user data dir [Jasper; #675316] -* Remove frame pixel caching [Jasper; #675111] -* stack: Ignore keep-on-top property on maximized windows [Florian; #673581] -* Misc. fixes [Javier, Jasper, Owen, Rico] - -Contributors: - Robert Bragg, Javier Járdon, Florian Müllner, Neil Roberts, Jasper St. Pierre, - Owen Taylor, Rico Tzschichholz, Pavel Vasin - -Translations: - Praveen Illa [te], Luca Ferretti [it], Daniel Mustieles [es] - -3.4.1 -===== -* API change: the meta_display_add_keybinding() function added in 3.4 - wasn't usable from a GNOME Shell extension, so has been changed to take - a GSettings object rather than the name of a schema [Jasper; #673014] -* Don't try to auto-maximize not-maximizable windows; this fixes the problem - with the Nautilus desktop window being mispositioned when enabled - [Owen; #673566] -* Fix a crash in the default plugin (not used in GNOME) [Giovanni; #673809] -* Make the key work when set as the mouse button modifier - [Florian; #662476] - -Contributors: - Giovanni Campagna, Florian Muellner, Jasper St. Pierre, Owen Taylor - -Translations: - Khaled Hosny [ar], Jordi Serratosa [ca], Carles Ferrando [ca@valencia], - Christian Kirbach [de], Kristjan Schmidt [eo], Arash Mousavi [fa], - Jiro Matsuzawa [ja], Shankar Prasad [kn], Aurimas Černius [lt], - Yinghua Wang [zh_CN] - -3.4.0 -===== -* Fix crash when a full-screen window is opened [Jasper; #672797] -* Fix memory leaks [Pavel; #672640] - -Contributors: - Jasper St. Pierre, Pavel Vasin - -Translations: - Marek Černocký, Petr Kovar [cz], Bruno Brouard [fr], Sweta Kothari [gu], - Yaron Shahrabani [he], Changwoo Ryu [kr], Enrico Nicoletto [pt_BR], - Yuri Myasoedov [ru], Muhammet Kara [tr], Nguyễn Thái Ngọc Duy [vi] - -3.3.92 -====== -* Automaximize large windows on map [Adel; #671677] -* When unmaximizing windows, make sure the unminimized size - is significantly 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 - when closing a window [Jasper; #620744] -* Avoid drawing shadows when two windows are tiled together [Rui; #643075] -* Remove tooltips for window decorations [Florian; #645101] -* Add org.gnome.mutter.dynamic-workspaces GSetting - when this is set - to true, workspace counts are never saved to GSettings, avoiding - pointless disk traffic for GNOME dynamic workspaces [Florian; #671568] -* Add ::grab-op-begin, ::grab-op-end signals to MetaDisplay [Jasper; #670658] -* Add meta_display_get_ignored_modifier_mask() [Florian; #665215] -* Remove pointless wrapper methods on MetaPlugin [Jasper; #671103] -* Fix frame drawing with 3.3.x GTK+ releases [Florian; #671796] -* Build fixes [Jasper, Rico, Rui] -* Misc bug fixes [Damien, Jasper, Lionel, Marius, Owen, Rui; - #661256, #667437, #671601, #671087, #672374] - -Contributors: - Stefano Facchini, Adel Gadllah, Lionel Landwerlin, Mariusz Libera, - Rui Matos, Florian Müllner, Jasper St. Pierre, Damien Radtke, Owen Taylor, - Rico Tzschichholz - -Translations: - Nilamdyuti Goswami [as], Ihar Hrachyshka [be], Alexander Shopov [bg], - David Planella [ca], Carles Ferrando [ca@valencia], Kenneth Nielsen [dk], - Bruce Cowan [en_GB], Daniel Mustieles [es], Mattias Põldaru [et], - Inaki Larranaga Murgoitio [eu], Timo Jyrinki [fi], Fran Diéguez [gl], - Gabor Kelemen [hu], Changwoo Ryu [ko], Anita Reitere [lv], - Kjartan Maraas [nb], Wouter Bolsterlee [nl], A S Alam [pa], Piotr Drąg [pl], - Duarte Loreto [pt], Yuri Myasoedov [ru], Daniel Nylander [se], - Matej Urbančič [sl], Miroslav Nikolić [sr], Tirumurti Vasudevan [ta], - Sasi Bhushan [te], Daniel Korostil [uk], Nguyễn Thái Ngọc Duy [vi], - YunQiang Su [zh_CN], Chao-Hsiung Liao [zh_HK, zh_TW] - -3.3.90 -====== -* Update for Cogl API changes [Robert] -* Bug fixes [Adel, Jasper; #659643] -* Build fixes [Jasper, Owen] - -Contributors: - Robert Bragg, Adel Gadllah, Jasper St. Pierre, Owen Taylor - -Translations: - Ask H. Larsen [dk], Miroslav Nikolić [sr] - -3.3.5 -===== -* MetaShapedTexture no longer is a ClutterTexture subclass [Jasper; #660941] -* Add meta_shaped_texture_get_image() [Jasper; #660941] -* Cleanups [Rui, Jasper; #657639] -* Depend on GTK+ 3.3.7 [Rico] - -Contributors: - Rui Matos, Jasper St. Pierre, Rico Tzschichholz - -Translations: - Kjartan Maraas [nb], Chao-Hsiung Liao [zh_HK, zh_TW] - -3.3.4 -===== -* Adapt to changes in GtkStateFlags [Owen] -* Redo properties for applications menu corresponding to GTK+ changes - - they are now _GTK_* not DBUS_*. [Ryan] -* Fix crash on gnome-shell restart when a modal dialog is open [Owen; #668299] -* Code cleanup [Florian; #666039] - -Contributors: - Ryan Lortie, Florian Müllner, Owen Taylor - -Translations: - Alexander Shopov [bg], Fran Diéguez [gl] - -3.3.3 -===== -* Add keybindings for tiling to left or right [Florian; #648700] -* Support GTK+'s hide-titlebar-when-maximized hint [Florian; #665617] -* Load _DBUS_APPLICATION_ID, _DBUS_UNIQUE_NAME, _DBUS_OBJECT_PATH - property [Colin, Ryan; #664851] -* Handle changes to workspaces-only-on-primary GSetting [Florian; #664853] -* Don't use the Clutter default stage [Jasper; #664028] -* Fix compilation with --disable-introspection [Lionel; #661871] -* Fix problem where stage could end up missized on startup with - multiple monitors [Lionel] -* Misc bug fixes [Adel, Lionel, Jasper; #666015] - -Contributors: - Adel Gadllah, Lionel Landwerlin, Florian Müllner, Jasper St. Pierre - -Translations: - Daniel Mustieles [es], Yaron Shahrabani [he], Kjartan Maraas [nb], - Matej Urbančič [sk], Muhammet Kara [tr] - -3.3.2 -===== - -* 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 - to allow applications to draw unfocused windows differently - [Rui; #661427] -* Add meta_window_move_resize_frame() to allow specifying the - size and position of a window via the outside dimensions of the - window frame. -* Don't activate window tiling when moving in snap mode - [Rui; #662270] -* Remove the ability to resize a window from the inner edge of - the titlebar [Jasper; #660129] -* Fix for deprecations in GTK+ [Jasper, Rico; #662574, #662895] -* Misc bug fixes [Jasper, Rico, Rui; #662895, #642652, #660941, #662225] - -Contributors: - Tim Cuthbertson, Rui Matos, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz - -Translations: - Jorge González (es), Kjartan Maraas (nb), Krishnababu Krothapalli (te), Nguyễn Thái Ngọc Duy (vi) - -3.2.1 -===== -* Allow keyboard window switching (alt-Tab) during drag-and-drop - [Matthias, #660457] -* Don't add invisible resize borders to fullscreen windows - [Jasper, Owen; #659854] -* Fix crash when toplevel windows were set to unexpected window types - [Owen; #599988] -* Correct problems with windows moving when restarting or switching - window managers [Jasper; #660848] -* Fix interaction of tiled windows with multiple monitors - [Rui; #642580, #657519] -* Make meta_display_unmanage_screen() public [Jasper; #660848] -* Fix problem with turning off window decorations on the fly [Rui; #660773] -* Fix spurious assertion failures with themes such as Nodoka [Sandro; #661286] -* Misc bug fixes [Adel, Jasper, Rui; #660464, #660854, #662053] - -Contributors: - Matthias Clasen, Sandro Mani, Rui Matos, Jasper St. Pierre, Owen Taylor - -Translations: - Tommi Vainikainen [fi], Miroslav Nikolić [sr, sr@latin], Muhammet Kara [tr] - -3.2.0 -===== -* Fix _NET_WM_FRAME_EXTENTS not to include invisible borders [Jasper; #659848] -* Fix application-specified window placement (-geometry) for - invisible borders [Jasper; #659848] - -Contributors: - Jasper St. Pierre - -Translations: - Nilamdyuti Goswami [as], Carles Ferrando [ca@valencia], Petr Kovar [cz], - Mario Blättermann [de], Inaki Larranaga [eu], Gabor Kelemen [hu], - Takayoshi Okano [ja], Changwoo Ryu [ko], Djavan Fagundes [pt_BR] - -3.1.92 -====== -* Fix bug with unredirecting full-screen windows on multi-monitor - - notably affected gnome-screensaver [Adel; #657869] -* Disable top resizing of attached dialogs [Jasper; #657795] -* Code cleanup [Jasper, Rui] -* Misc bug fixes [Adel, Florian, Jasper, Rui; - #658069, #659266, #659523, #659477] - -Contributors: - Adel Gadllah, Rui Matos, Florian Müllner, Jasper St. Pierre - -Translations: - Joan Duran [ca], Joe Hansen [dk], Jiro Matsuzawa [ja], Daniel Korostil [uk] - -3.1.91.1 -======== -* Fix problem where certain application updates would get lost [#657071, Owen] -* Fix a problem where after resuming from the screensaver, things got - slow [#658228, Jasper, Adel] -* When a monitor is plugged or unplugged, keep existing windows on their - current monitor [#645408, Alex] -* Remove 'Mutter' title from alerts such as - "The widow '%s' is not responding" [Matthias] -* Remove pointless warning: - Received a _NET_WM_MOVERESIZE message for %s; these - messages lack timestamps and therefore suck. - [Rui] -* Misc bug fixes [Jasper] -* Build fixes [Javier] - -Contributors: - Matthias Clasen, Adel Gadllah, Javier Jardón, Alex Larsson, Rui Matos, - Jasper St. Pierre, Owen Taylor - -Translations: - Ihar Hrachyshka [be], Bruce Cowan [en_FB], Daniel Mustieles [es], - Claude Paroz [fr], Andika Triwidada [id], Luca Ferretti [it], - Rudolfs Mazurs [lt], Piotr Drąg [pl], Duarte Loreto [pt], - Matej Urbančič [sl], Tirumurti Vasudevan [ta], Chao-Hsiung Liao [zh_KH, TW] - -3.1.90.1 -======== -* Fix crash when no windows are open [Adel; #657692] -* Fix annotations for new strictness in gobject-introspection [Jasper, Owen] -* Fix some errors with rounded frame drawing [Jasper; #657661] - -Contributors: - Adel Gadllah, Jasper St. Pierre, Owen Taylor - -3.1.90 -====== -* Extend the draggable portion of window borders outside the visible frame - 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] -* 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] -* Add MUTTER_DISABLE_FALLBACK_COLOR environment variable to allow visualizing - places where a color is missing for gtk:custom() colors [Florian; #656112] -* Don't attach modal dialogs to special windows like the desktop; - add meta_window_is_attached_dialog() [Dan, #646761] -* Make MetaBackgroundActor public, allow creating multiple instances - (sharing a common texture), and add a :dim-factor property - [Rui, Owen; #656433] -* Fix attached dialogs to not be resizable from the top and to be - position correctly [Jasper; #656619] -* Misc bug fixes [Jasper, Rui; #656335, #657583] - -Contributors: - Tim Cuthbertson, Adel Gadllah, Rui Matos, Florian Müllner, Jasper St. Pierre, - Owen Taylor, Dan Winship - -Translations: - Alexander Shopov [bg], Jorge González [es], Fran Dieguez [gl], - Yaron Shahrabani [he], Takeshi Aihana [ja], Aurimas Černius [lt], - Kjartan Maraas [nb], A S Alam [pa], Yuri Kozlov [ru], Daniel Nylander [se], - Theppitak Karoonboonyanan [th], Abduxukur Abdurixit [ug], Aron Xu [zh_CN] - -3.1.4 -===== -* Use better, much more subtle shadow definitions [Jakub; #649374] -* Add the ability to use named GTK+ colors in theme files as - gtk:custom(name,fallback) [Florian; #648709] -* Port from GdkColor to GdkRGBA and from GtkStyle to GtkStyleContext - [Florian; #650586] -* Try to fix window bindings using the Super key [Owen; #624869] -* Update to using more modern Cogl and Clutter APIs - [Adel, Emmanuele, Neil; #654551 #654729 #654730 #655064] -* Fix for srcdir != builddir builds [Thierry; #624910] -* Make handling of focus appearance for attached dialogs more robust - [Dan; #647712] -* Misc bug fixes - [Dan, Florian, Jasper, Owen, Rui; #642957 #649374 #650661 #654489 #654539] - -Contributors: - Emmanuele Bassi, Adel Gadllah, Rui Matos, Florian Müllner, Neil Roberts, - Jasper St. Pierre, Jakub Steiner, Owen Taylor - -Translations: - Ihar Hrachyshka [be], Jorge González, Daniel Mustieles [es], - Fran Dieguez [gl], Yaron Shahrabani [he], Takeshi Aihana [ja], - Kjartan Maraas [nb], Rudolfs Mazurs [lv], Matej Urbančič [sl], - Abduxukur Abdurixit [ug], Nguyễn Thái Ngọc Duy [vi] - -3.1.3.1 -======= -* Back API version down to "3.0" - the change to Meta-3.1.gir - was unintentional [Owen] - -Translations: - Yaron Shahrabani [he], Kjartan Maraas [nb], Muhammet Kara [tr] - -3.1.3 -===== -* Support dark window theme variants for windows with a dark - widget theme; this is selected by the _GTK_THEME_VARIANT - property [Florian, #645355] -* Don't draw a shadow under windows with an alpha-channel - this - fixes transparency for GNOME Terminal [Owen, Jasper; #635268] -* Add a MetaWindow:wm-class property for notification [Jasper; #649315] -* Add a MetaWindow:minimized property for notification [Florian] -* Fix handing of unusual window shapes that Wine was setting - causing some applications to draw wrong [Jasper; #627880] -* Improve replacing another compositor and being replaced: - release compositor selection in the right order and wait for - compositors that get it wrong. [Colin, Owen; #653121] -* Remove behavior where left clicking on a window border with - the titlebar offscreen gave the window menu [Florian; #652369] -* Don't set the global default textdomain, since Mutter is - a library as well as an application [Dan; #649202] -* Exit with the right (success or failure) exit status [Dan] -* Code cleanup [Florian] -* Miscellaneous bug fixes [Owen; #649114, #652507] - -Contributors: - Florian Müllner, Jasper St. Pierre, Owen Taylor, Colin Walters, Dan Winship - -Translations: - Ihar Hrachyshka [be], Daniel Mustieles [es], Yaron Shahrabani [he], - Carles Ferrando [ca@valencia], Takeshi Aihana [ja], Fran Diéguez [gl], - Matej Urbančič [sl], Miroslav Nikolic [sr], Muhammet Kara [tr], - Daniel Korostil [uk] - -3.0.2.1 -======= -* When saving the session, use the "program name" rather than - hardcoding mutter, fixing session saving for gnome-shell [Matthias] - https://bugzilla.gnome.org/show_bug.cgi?id=648828 - -Contributors: - Matthias Clasen - -3.0.2 -===== - -* Fix a crash when running without XKB support [Adam] - https://bugzilla.gnome.org/show_bug.cgi?id=647777 -* Fix smallish memory leaks [Colin] - https://bugzilla.gnome.org/show_bug.cgi?id=649500 - https://bugzilla.gnome.org/show_bug.cgi?id=649504 -* Ignore mirrored monitors when listing monitors, fixing - drag-and-drop problems in GNOME Shell [Owen] - https://bugzilla.gnome.org/show_bug.cgi?id=649299 -* Don't allow side-by-side tiling of non-maximizable windows - like dialogs and utility windows [Dan] -* Fix interaction of _NET_WM_WINDOW_OPACITY with window effects, - making it work again with GNOME Shell - https://bugzilla.gnome.org/show_bug.cgi?id=648613 - -Contributors: - Adam Jackson, Colin Walters, Dan Winship - -Translations: - Abduxukur Abdurixit [ug] - -3.0.1 -===== - -* If WM_CLIENT_MACHINE isn't set, don't assume a window is remote; - fixes behavior of Fox toolkit applications under GNOME Shell. - https://bugzilla.gnome.org/show_bug.cgi?id=647662 [Colin] -* Fix cases where windows could get stuck drawing as focused after - an attached modal dialog was closed. [Dan] - https://bugzilla.gnome.org/show_bug.cgi?id=647613 -* Fix a bug where a window that is too big to be tiled side-by-side - would behave strangely when using the gesture of dragging to - the top to maximize. [Florian] - -Contributors: - Florian Müllner, Colin Walters, Dan Winship - -Translations: - Amitakhya Phukan [as], Kristjan Schmidt [eo], Muhammet Kara [tr] - -3.0.0 -===== - -* Avoid crashing when you have a single window and try to move it between - workspaces. [Dan] - https://bugzilla.gnome.org/show_bug.cgi?id=642957 - -Contributors: - Dan Winship - -Translations: - Jordi Serratosa [ca], Petr Kovar [cz], Ask H. Larsen [da], Bruce Cowan [en_GB], - Inaki Larranaga Murgoitio [eu], Gabor Kelemen [hu], Dirgita [id], Shankar Prasad [kn], - Changwoo Ryu [ko], Wouter Bolsterlee [nl], Duarte Loreto [pt], - Antonio Fernandes C. Neto, Rodrigo Padula de Oliveira [pt_BR], T. Vasudevan [ta], - Nguyễn Thái Ngọc Duy [vi], Chao-Hsiung Liao [zh_HK, zh_TW] - -2.91.93 -======= - -* Fix bug where, when a monitor was hot-plugged, all workspaces - would collapse to a single workspace. (There are still issues - when a secondary monitor is hot-plugged to the left of the - primary monitor.) [Alex] - https://bugzilla.gnome.org/show_bug.cgi?id=645408) - -* Fix a crash for the cycle_group action [Jasper] - https://bugzilla.gnome.org/show_bug.cgi?id=645843 - -* Fix misdrawing of window shadows on some focus changes [Dan] - https://bugzilla.gnome.org/show_bug.cgi?id=636904 - -* Export meta_get_replace_current_wm() to allow fixing a - GNOME Shell bug with --replace [Colin] - https://bugzilla.gnome.org/show_bug.cgi?id=645590 - -Contributors: - Alexander Larsson, Jasper St. Pierre, Colin Walters, Dan Winship - -Translations: - Alexander Shopov [bg], Christian Kirbach [de], Yaron Shahrabani [he], - Rudolfs Mazurs [lv], A S Alam [pa], Yuri Myasoedov [ru], Daniel Nylander [se], - Abduxukur Abdurixit [ug], Daniel Korostil [uj], Aron Xu [zh_CN] - -2.91.92 -======= - - * Add a workspaces_only_on_primary preferences. When set, this makes - workspaces switching only apply to windows on the primary monitor, - while windows on other monitors are unaffected. - * Export API for monitor handling [Alex] - MetaScreen::monitors-changed signal - meta_screen_get_primary_monitor() - meta_window_is_on_primary_monitor() - meta_window_get_monitor() - MetaWindow::window-entered-monitor, Above_Tab from being a cycle_group binding to - a switch_group binding [Rui] - * Make plugin-loading failure fatal [Colin] - * Add 'position-changed' signal to MetaWindowActor [Owen] - * When 'live_hidden_previews' is enabled, position hidden windows - to allow the creation of workspace previews [Owen] - * Fix bug with opacity of MetaBackgroundActor - -Contributors: - Rui Matos, Owen Taylor, Colin Walters - -Translations: - Jorge González [es], Mattias Põldaru [et], Sweta Kothari [gu], Luca Ferretti [it], - Changwoo Ryu [ko], Nguyễn Thái Ngọc Duy [vi] - -Bugs fixed: - 641309 When live_hidden_previews is set, force placement for hidden windows - 641310 MetaWindowActor: Add a 'positioned-changed' signal - 641979 Visual glitch on workspace selector closing overview mode - 641384 Make plugin loading failure fatal - 642426 Don't pass handled key events to GTK+ - -2.91.6 -====== - - * Add meta_screen_override_window_layout() to let a plugin set the workspace - layout [Owen] - * Add a 'size-changed' signal to MetaWindowActor [Florian] - * Add meta_window_actor_is_destroyed() [Adel] - * Fix problems with window tile previews when cancelling a move [Florian] - * Port theme elements that use GTK+ drawing to use GtkStyleContext instead - of the deprecated GtkStyle. [Florian] - * Fix compiler warnings that were causing compilation failures [Jasper, Owen] - * Misc bug fixes [Gabor, Jasper, Owen, Rui] - -Contributors: - Adel Gadllah, Gabor Kelemen, Rui Matos, Florian Müllner, Jasper St. Pierre, - Owen Taylor - -Translations: - Khaled Hosny [ar], Alexander Shopov [bg], Petr Kovar [cz], Fran Diéguez [gl], - Marios Zindilis [gr], Gabor Kelemen [hu], Kjartan Maraas [nb], A S Alam [pa], - Daniel Nylander [se], Chao-Hsiung Liao [zh_HK, zh_TW] - -2.91.5 -====== - -* Add a Above_Tab key symbol that can be used in key bindings to mean - the key above the Tab key. This is now the default binding for - cycle_group in both Mutter and Metacity. [Owen] -* Add new frame states for tiled-on-the-left and tiled-on-the-right [Florian] -* Add new background drawing functions that can be defined in a theme - for single buttons. [Florian] -* Draw the right button backgrounds for all custom button layouts [Florian] -* Remove vestigal --composite/--no-composite command line options [Nickolas] -* Fix building on GLES [Andreas] -* Code cleanups [Adel, Owen] - -Contributors: - Adel Gadllah, Nickolas Lloyd, Andreas Mueller, Florian Müllner, Owen Taylor - -Translations: - Mattias Põldaru, Ivar Smolin [et], Gheyret T. Kenji [ug] - -Bugs fixed: - 613124 Invalid visibility-related asserts in MutterWindow - 626875 Fix handling of --composite and --no-composite command line options - 629282 [PATCH] Fix errors building for gles-systems (clutter-eglx) - 635569 Add an "Above_Tab" pseudo-keysym - 635683 add specific button background for single button (per side) case - 635686 button backgrounds broken with rtl locales - 637330 [PATCH] theme: Add tiled_left/tiled_right frame states - -2.91.4 -====== - -* Update for GTK+ 3 changes [Benjamin, Colin, Emmanuele, Florian] -* Support maximizing a window by dragging to the top of the screen - in the same way you can tile by dragging to the edge of the screen. - [Ray, Florian] -* Misc bug fixes [Milan, Owen] - -Contributors: - Emmanuele Bassi, Milan Bouchet-Valat, Florian Müllner, Benjamin Otte, - Ray Strode, Owen Taylor, Colin Walters - -Translations: - Matej Urbančič [sl], Nguyễn Thái Ngọc Duy [vi] - -Bugs fixed: - 630548 gnome-shell could auto-maximize windows when dragged to top edge of screen - 636083 workspace: Consider text direction when switching - 636301 Port testgradient example to GTK3 - 636302 Replace some GDK X11 calls with future-proof ones - 636491 valgrind: meta_window_shape_new (meta-window-shape.c:79) - 637802 ui: Adapt to GDK API changes - -2.91.3 -====== - -* Better shadows: [Owen] - - Shadows can be different for different window types and focus states - - Shadows are larger by default, especially for the currently active - window - - Shadows for attached modal dialogs and menus are drawn not to - overlap the attachment point. - - Shadows follow the shape of shaped windows - * Optimization: [Owen] - - Avoid repainting in situations when windows are potentially restacked - but aren't actually restacked. - - Pay attention to partial stage repaints in obscured window calculations - - Better optimization of painting obscured shadows; turn off shadows - for maximized windows. - - Move background repainting into Mutter; doing it here rather than - in plugins allows not painting obscured parts of the background. - * A new frame type 'attached' is added for attached modal dialogs - and can be referenced in theme files with a theme version of 3.2. - * Fix updating key bindings when the keyboard layout changes - [Derek, Owen, Thomas] - * Bug fixes [Adel, Florian] - * Build fixes [Dan Williams, Diego, Javier, Owen] - -Contributors: - Adel Gadllah, Javier Jardón, Florian Müllner, Derek Poon, Owen Taylor, - Thomas Thurman, Diego Escalante Urrelo, Dan Williams - -Translations: - Khaled Hosny [ar], Jorge González [es], Fran Diéguez [gl], - Yaron Shahrabani [he], Kjartan Maraas [nb], Gheyret T. Kenji [ug] - -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 - 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 - 635493 configure.in: it's git, not Subversion - 635528 configure.ac: move call to AM_GNU_GLIB_GETTEXT above cflags modification - 635575 meta-window-actor: remove unused meta_window_actor_get_shadow_bounds - 636083 workspace: Consider text direction when switching - -2.91.2 -====== - -* Remove support for GTK+ 2 [Florian] -* Adapt to deprecation of size_request deprecation in GTK+ [Matthias] -* Include change from Metacity to fix confusion of mouse - tracking when double-clicking on title bar [Owen] -* Fix bug with the the window menu getting stuck when you alt-Tab [Owen] - -Contributors: - Matthias Clasen, Florian Müllner, Owen Taylor - -Translations: - Petr Kovar [cz] - -Bugs fixed: - 633133 Remove compatibility for GTK+-2.0 - 633352 prepare for the demise of size_request - 633398 Fix check for events on UI widgets - 633401 Fix warning from synthesized events with GdkDevice - -2.91.1 -====== - -* Default build is now GTK+ 3 build -* Mutter namespace prefix is removed, in favor of consistent - meta_ namespace prefixing [Owen]. Naming changes: - MutterWindow => MetaWindowActor - mutter_get_windows => meta_get_window_actors - mutter_plugin_get_windows => meta_plugin_get_window_actors -* Add missing values in MetaKeyBindingAction - this fixes a problem where - key binding lookup wasn't working properly for some key bindings. [Dan] -* Remove keysym parameter to meta_display_get_keybinding_action() - the - function expected the default keysym for the keycode to always be passed [Dan] -* Clean up installed header files - in particular, theme-parser.h is merged - into a new public-only theme.h and private internals are moved to - theme-private.h. -* Fix problems with antialiased rendering of themes [Brandon, Owen, Nickolas] -* Fix problem with parsing color constants in themes [Jon, Owen] -* Build fixes [Colin] -* Miscellaneous bug fixes [Giovanni, Rico] - -Contributors: - Giovanni Campagna, Nickolas Lloyd, William Jon McCann, Owen Taylor, - Rico Tzschichholz, Colin Walters, Dan Winship, Brandon Wright - -Translations: - Fran Diéguez [gl], Yinghua Wang [zh_CN] - -Fixed bugs: - 628401 tint and line draw ops rendering issues - 628520 unfortunate namespacing - 631487 Fix drawing of theme elements - 632116 don't clobber gerrors - 632149 Fill in missing MetaKeyBindingAction values - 632155 meta_display_get_keybinding_action: remove keysym parameter - 632474 Remove MetaRegion - 632494 introspection: remove --allow-unprefixed - -2.91.0 -====== - - * Enable side-by-side tiling via a gesture of dragging to the left or right - edge of the screen. (enabled with an off-by-default GConf key) [Florian] - * Allow breaking out of maximization/tiling using a alt-middle-button window - resize [Owen, Florian] - * Add the ability to have modal dialogs attached to their parent window - (enabled with an off-by-default GConf key) [Maxim] - * Draw with Cairo rather than GDK [Florian, Benjamin] - * Add compatibility for changes in GTK+ 3 - [Benjamin, Alban, Florian, Jasper, Matthias, Owen, Thierry] - - libmutter-private is now only installed for GTK+ 3 builds - - Theme parts of libmutter-private API are changed to take cairo_t - rather than GdkDrawable - * Update introspection build and annotations for new behavior of - g-ir-scanner [Colin] - * Fix bug that caused window menu options not to work [Owen] - * Fix misbehavior of Wine windows [Owen, Alban] - * Fix crashes from missing error traps [Adel] - * Build fixes [Colin, Florian, Owen, Rob, Tomas] - * Misc bug fixes [Adel, Jon, Owen, Nickolas, Tomas] - * Cleanups [Adel, Benjamin, Florian] - -Contributors: - Alban Browaeys, Matthias Clasen, Maxim Ermilov, Tomas Frydrych, Adel Gadllah, - Nickolas Lloyd, William Jon McCann, Florian Muellner, Benjamin Otte, - Thierry Reding, Rob Staudinger, Jasper St. Pierre, Owen Taylor, Colin Walters - -Translations: - Alexander Shopov [bg], Mario Blättermann [de], Ask H. Larsen [dk], - Michael Kotsarinis [el], Philip Withnall [en_UK], Jorge González [es], - Fran Diéguez [gl], Bruno Brouard, Claude Paroz [fr], Yaron Shahrabani [he], - Gabor Kelemen [hu], Luca Ferretti [it], Nils-Christoph Fiedler [nds], - Kjartan Maraas [nb], A S Alam [pa], Piotr Drąg [pl], Duarte Loreto [pt], - Antonio Fernandes C. Neto [pt_BR], Matej Urbančič [sl], - Miloš Popović [sr, sr@latin], Tirumurti Vasudevan [ta], Aron Xu [zh_CN], - Chao-Hsiung Liao [zh_HK, zh_TW] - -Fixed Bugs: - 597763 With >2 workspaces, Window menu "Move to Another Workspace" menu doesn't work - 598603 displays window size when moving terminal window - 606158 "Always on top" triggers Window manager warning: - Log level 8: meta_window_set_user_time: assertion `!window->override_redirect' failed - 610575 make meta_screen_set_cursor public - 613126 Do not cancel Alt+Tab grab due to Shift key events - 623235 BadDamage error from XSubtractDamage - 624757 Check for TFP usage after actually setting the pixmap - 625712 [mutter-shaped-texture] Remove material_workaround - 626583 Replace Gdk drawing API with cairo - 627087 Mipmap emulation not working - 627210 Crash with X error - 628544 introspection: Build with --warn-fatal, drop fix-meta-rectangle.py hack - 629127 build problem with recent gtk3 - 629232 Multiple syntax errors in file mutter-message.c when building Mutter for - GNOME Shell dependencies - 629350 [mutter-shaped-texture] Use a base material for all instances - 629931 Allow breaking out from maximization/tiling during a mouse resize - 630195 Use GDK error trapping straight-up - 630203 Prepare mutter code for GTK3 rendering-cleanup - 630671 prepare mutter for the demise of GtkObject - 630843 gtk_window_set_visual was replaced by gtk_widget_set_visua - 631147 Adapt to GTK API changes - 631175 Mutter error compiling Gnome Shell - -2.31.5 -====== - -* Support building with GTK+ 3.0 [Florian] -* Remove deprecated usages for compatibility with GTK+ 3.0 - [Claudio, Florian, Nickolas] -* Export a boxed type for MetaRectangle [Owen] -* Allow disabling -Werror with --enable-compile-warnings=yes [Nickolas] -* Build fixes [Andreas, Florian, Owen] - -Contributors: - Nickolas Lloyd, Andreas Mueller, Florian Müllner, Claudio Saavedra, - Owen Taylor - -Translations: - Petr Kovar [cz], Jorge González [es], Fran Diéguez [gl], - Yaron Shahrabani [he], Matej Urbančič [sl] - -Fixed Bugs: - 587991 - Remove deprecated GTK+ symbols - 616275 - -Werror should not be enabled by default (or should be possible to disable) - 622303 - Allow building with Gtk+-3.0 - 622800 - Make mutter more gtk+ 3.0 friendly - 623335 - Make MetaRectangle a boxed type - 623639 - Work around g-ir-scanner problem with Gdk.Rectangle - 624166 - src/core/util.c: Fix warning in case WITH_VERBOSE_MODE is not set - -2.31.4 -====== - -* Clean up MutterPlugin effect interface [Maxim] -* Track damage as the bounding box, a significant optimizations - for rapidly drawing clients [Robert] -* Add meta_window_is_remote() [Colin] -* Add meta_add_debug_topic() for turning on logging of - specific topics [Colin] -* Fix bug with window unmaximization [Owen] - -Contributors: - Robert Bragg, Maxim Ermilov, Owen Taylor, Colin Walters - -Translations: - Yaron Shahrabani (he), Fran Diéguez (gl), Kjartan Maraas (nb), A S Alam (pa) - -Fixed Bugs: - 611838 - expose sub-stage redraws by streaming raw updates to ClutterX11TexturePixmap - 620585 - Add meta_window_is_remote - 620860 - function ‘meta_display_open’ - 621082 - MutterPluginManager should call plugin->switch_workspace, - when screen doesn't have any window. Or function should be renamed. - 621413 - Maximize/Unmaximize not behaving properly for some non-gnome based programs - -2.31.2 -====== - -* Theme enhancements [Owen] - - Add a flexible version mechanism for themes - - metacity-theme-3.xml is now supported, and can include - version="> 3.2" type attributes on the root element or - any subelement. - - Add frame_x_center/frame_y_center variables - - 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] - - 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 - plugin-specific location. [Owen] -* Support a _MUTTER_HINTS window property; this is a string - property holding key-value pairs with plugin-specific - interpretation [Tomas] -* Build with GSEAL_ENABLE [Florian, Javier] -* Add meta_display_get_leader_window() [Tomas] -* Add meta_display_sort_windows_by_stacking [Colin] -* Export - meta_display_get_last_user_time() - meta_display_xserver_time_is_before() - meta_window_foreach_ancestor(), - meta_window_foreach_transient() - meta_window_lower() - meta_window_raise() - meta_window_set_demands_attention() - meta_window_unset_demands_attention() [Colin] -* Bug fixes [Dan, Edward, Owen, Tomas] -* Build fixes [Owen, Dominique, Vincent] - -Contributors: - Robert Bragg, Adel Gadllah, Tomas Frydrych, Javier Jardón, - Dominique Leuenberger, Florian Müllner, Edward Sheldrake, - Owen Taylor, Vincent Untz, Colin Walters, Dan Winship - -Translations: - Xandru Armesto Fernandez (ast), Khaled Hosny (ar), Petr Kovar (cz), - Mario Blättermann, (de), Jorge González (es), - Inaki Larranaga Murgoitio [eu), Claude Paroz (fr), Luca Ferretti (it), - Gintautas Miliauskas (lt), Pavol Šimo (sk), Matej Urbančič (sl) - -Fixed Bugs: - 591842 - ellipsize titles when oversize - 592503 - Add a flexible version mechanism - 595496 - Use accessor functions instead direct access (use GSEAL GnomeGoal) - 596659 - Fix handling of grabbed key events - 613123 - Framework for plugin-specific per-window hint - 613125 - Add meta_display_get_leader_window() - 613127 - Keep num_workspaces key in sync with the actual workspace number - 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 - strict-aliasing rules - 616050 - alt-tab infrastructure patches - 616274 - mutter from git fails with gcc 4.5 (on new warning) - 616546 - On dual screen maximized windows dragged to the second screen no - longer update their contents - 618138 - Work around COGL bug causing flash for new windows - 618613 - Fix crash with --sync option - -2.29.1 -====== - -* Support and require Clutter 1.2 (Owen) -* Add meta_display_get_keybinding_action() (Colin, Dan) -* Add meta_window_get_wm_class_instance() (Tomas) -* Remove workaround for bug fixed in intel driver Q2/2009 release (Robert) -* Build fixes (Owen, Brian, Nguyễn Thái Ngọc Duy) - -Contributors: - Robert Bragg, Brian Cameron, Tomas Frydrych, Nguyễn Thái Ngọc Duy, - Owen Taylor, Colin Walters, Dan Winship - -Translations: - Alexander Shopov (bg), Mario Blättermann (de), Bruno Brouard (fr), - Nils-Christoph Fiedler (nds), Piotr Drąg (pl), Aron Xu (zh_CN) - -Fixed Bugs: - - 610862 Support and require Clutter 1.1 - 612506 mutter 2.29.0 fails to compile on Solaris - 613100 [MetaDisplay] Expose meta_display_get_keybinding_action - 613121 Remove workaround for multitexturing with old intel drivers - 613128 [MetaWindow] Accessor for the instance part of WM_CLASS property - 613278 meta_display_get_keybinding_action: strip out uninteresting modifiers - -2.29.0 -====== - -* Improve appearance of scaled down windows using mipmap emulation (Owen) -* Added signals: MetaDisplay::window-created, MetaDisplay::window-marked-urgent, - MetaDisplay::window-demands-attention, MetaWindow::unmanaged (Colin, Tomas) -* Added properties: MetaWindow:demands-attention, MetaWindow:urgent, - MetaWindow:maximized-horizontally, MetaWindow:maximized-vertically (Florian, Tomas) -* Fix nasty crash when workspace "struts" changed during a window move (Jon, Owen) -* Bug fixes (Dan, Maxim, Neil, Owen, Tomas) -* Build fixes (Colin, Emmanuele, Nickolas, Owen, Richard) -* Merge Metacity changes since 2.26. Includes themable sound support - via libcanberra (Owen) - -Contributors - Emmanuele Bassi, Maxim Ermilov, Tomas Frydrych, Richard Hughes, Nickolas Lloyd, - Florian Müllner, Jon Nettleton, Neil Roberts, Owen Taylor, Colin Walters, - Dan Winship - -Additional Metacity contributors: - Thomas Hindoe Paaboel Andersen, Peter Bloomfield, Matthias Clasen, - Matt Kraai, Claude Paroz, Lennart Poettering, Ray Strode, Thomas Thurman, - Vincent Untz, Tomislav Vujec, Tomeu Vizoso, Travis Watkins, 'alexisdm59' - -Translations: - Khaled Hosny (ar), Petr Kovar (cz), Kjartan Maraas (nb), Djavan Fagundes (pt_BR), - Nils-Christoph Fiedler (nds), Matej Urbančič (sl), Vincent Untz - -Fixed Bugs: - - 588065 Adds demands-attention signal to the window class - 591913 Fails to skip current window on alt+tab when another window is asking for attention - 592567 Dereferencing NULL in mutter_window_get_workspace() - 597052 Add signal to MetaDisplay so we know when a window has demanded-attention - 598289 Add "window-created" signal to MetaDisplay, "unmanaged" signal for MetaWindow - 598473 "XXX specified twice for this theme" messages not in sync with metacity. - 598600 "Visual Bell" option in Metacity causes Mutter to crash - 600068 notifications for window urgency hint - 601228 rdesktop does not get keypress signals - 602349 [PATCH] trivial - fix compilation warning in mutter - 602740 Remove XOR gc only used in removed reduced-resources mode - 602870 Fix compilation with older libGL - 604200 Compile issue: Use of deprecated clutter functions - 606388 mutter fails to build when using ld with --no-add-needed - 607125 Fails to build with latest introspection data - 607398 Do not use CGL_* symbols - 607746 reduce gconf roundtrips at startup - 608800 alt-dragging gimp windows crashes gnome-shell - 609350 Mutter does not support the COGL_DEBUG environment variable - 609546 meta_workspace_set_builtin_struts(): optimize out non-changes - 609585 Merge libcanberra usage from Metacity - 609657 Use cogl multitexture API when drawing MutterShapedTexture - 609665 Bug fixes from Fedora RPM - 609710 screencast recording broke - 610391 Fix crash on startup with list bindings - -2.28.0 -====== - -* New exported API: - meta_window_get_stable_sequence() [Colin] - meta_window_get_transient_for_as_xid() [Tomas] - MutterScreen::workareas-changed signal [Tomas] -* Fix a problem where changes processed from a Clutter event - callback wouldn't get handled before the screen was next - repainted, causing flashing [Owen] -* Remove MetaAltTabHandler as no longer needed [Dan] -* Bug fixes [Colin, Owen] - -Contributors: - Tomas Frydrych, Owen Taylor, Colin Walters, Dan Winship - -Translations: - Christian Kirbach (de), Claude Paroz (fr) - -2.27.5 -====== - - * Fix bug in GConf schemas where the overview activation key was specified as - '' not 'Super_L'. - -Contributors: - - Colin Walters - -Translation: - - Denis Arnaud (br) - -2.27.4 -====== - -* Big code cleanup: when talking about multiple monitors, call them - "monitors", not "xineramas". [Dan] - -* Accessors added or made public: - - meta_screen_get_n_monitors(), meta_screen_get_monitor_geometry() - meta_window_get_user_time() and MetaWindow:user-time property. - - [Colin, Dan] - -* Set _GNOME_WM_KEYBINDINGS=Metacity,Mutter on the _NET_SUPPORTING_WM_CHECK - window so that gnome-keybinding-properties can figure out to show the - Metacity keybindings when Mutter is running. [Owen] - -* Bug and build fixes [Colin, Owen] - -Contributors: - - Owen Taylor, Colin Walters, Dan Winship - -Translation: - - Jorge González (es), Inaki Larranaga Murgoitio (eu), Gabor Kelemen (hu) - -Bugs fixed: - - 592393 - Clicking on a minimized window in the overview doesn't focus the window - 593399 - Add meta_display_get_grab_op() - 593404 - Make MUTTER_DEBUG_XINERAMA override active Xinerama - 593407 - Add 'skip-taskbar' accessor to MetaWindow. - 593686 - Add meta_screen_get_monitors() - 594067 - Export a _GNOME_WM_KEYBINDINGS property - -2.27.3 -====== - -* Key handling improvements: - - - enforce that every key is handled no more than once. - - mutter_plugin_begin_modal() and mutter_plugin_begin_modal() allow - putting a plugin into a "modal" state where it has exclusive access - to key and pointer events. - - Add "tab_popup_select", "tab_pop_cancel" pseudo-keypress-handlers - that plugins can use to get notification when Alt-Tab ends - - [Owen] - -* Accessors added or made public: - - meta_window_is_override_redirect(), meta_window_is_mapped(), - meta_display_xwindow_is_a_no_focus_window(), - meta_display_get_grab_op(), meta_window_is_skip_taskbar(), - meta_window_is_modal(), all of errors.h - - [Colin, Owen, Michael, Steve, Tomas] - -* Fix for various GTK+ deprecations [Javier] -* Bug fixes [Colin, Frédéric, Owen, Thomas, Tomas, Volker] - -Contributors: - - Javier Jardón, Steve Frécinaux, Tomas Frydrych, Michael Meeks, - Frédéric Péters, Volker Sobek, Owen Taylor, Thomas Thurman, - Colin Walters - -Translation: - - Fran Dieguez (gl), Gabor Kelemen (hu), Daniel Nylander (se) - -Bugs fixed: - - 589457 - Fix up window property notification for "title" - 590911 - Do not run plugin effects on WM startup - 590978 - API to query whether window is in modal state - 591367 - Be silent by default - 591566 - install errors.h header ... - 591788 - Add meta_window_is_override_redirect - 591836 - mutter mishandles opacity - 591913 - Fails to skip current window on alt+tab when another window is asking for attention - 592393 - Clicking on a minimized window in the overview doesn't focus the window - 592699 - Remove deprecated Encoding key from desktop files - 592742 - Avoid accessing freed memory when being replaced - 593399 - Add meta_display_get_grab_op() - 593404 - Make MUTTER_DEBUG_XINERAMA override active Xinerama - 593407 - Add 'skip-taskbar' accessor to MetaWindow. - ------------------------------ Older Metacity News ----------------------------- - -2.26.0 -====== - -Thanks to Luca Ferretti, Matt Kraai, and Neil Jagdish Patel for -improvements in this version. - - - queue frame resize on window undecorate (Neil) - - fix description of desktop background (Luca) (#569649) - - wrap g_error calls in braces (Matt) - -Translations - Amitakhya Phukan (as), Mikel González (ast), Ihar Hrachyshka (be@latin), Runa - Bhattacharjee (bn_IN), David Planella (ca), Petr Kovar (cs), Ask Hjorth - Larsen (da), Christian Kirbach (de), Jennie Petoumenou (el), David Lodge (en_GB), - Jorge González (es), Mattias Põldaru (et), Iñaki Larrañaga Murgoitio (eu), - Ilkka Tuohela (fi), Claude Paroz (fr), Ankit Patel (gu), Mark Krapivner (he), - Rajesh Ranjan (hi), Gabor Kelemen (hu), Luca Ferretti (it), Takeshi AIHANA (ja), - Changwoo Ryu (ko), Gintautas Miliauskas (lt), Sangeeta Kumari (mai), Sandeep - Shedmake (mr), Wouter Bolsterlee (nl), Manoj Kumar Giri (or), Duarte Loreto (pt), - Leonardo Ferreira Fontenelle (pt_BR), Adi Roiban (ro), Yuriy Penkin (ru), Daniel - Nylander (sv), I. Felix (ta), Krishna Babu K (te), Theppitak Karoonboonyanan (th), - Clytie Siddall (vi), Chao-Hsiung Liao (zh_HK), Chao-Hsiung Liao (zh_TW) - -2.25.144 -======== - -Thanks to Matthias Claesen, Matt Kraai, Elijah Newren, Owen Taylor, and Thomas -Thurman for improvements in this version. - - - Optimise window property lookup (Thomas) (#549886) - - Fix slip in the above (Matt) - - Several memory leaks fixed (Matthias) (#552303, #552973, #552307) - - Fix longstanding crasher about colourmaps (Owen) (#568365) - - Alt+middle/right buttons can be switched (Thomas) (#437910) - - Support _NET_WM_MOVERESIZE_CANCEL (Elijah) - - minor fix paving the way for a theme editor (Thomas) - -Translations - David Planella (ca), Jorge González (es), Mattias Põldaru (et), saudat - mohammed (ha), Yuval Tanny\n (he), Gabor Kelemen (hu), Onye, Sylvester (ig), - Changwoo Ryu (ko), Raivis Dejus (lv), Kjartan Maraas (nb), Daniel Nylander (sv), - Fajuyitan, Sunday Ayo (yo), 甘露 (Gan Lu) (zh_CN) - -2.25.89 -======= - -Thanks to Yanko Kaneti, Frederic Peters, Thomas Thurman, and Colin Walters for -improvements in this version. - - - The maximisation key is a toggle. (Thomas) (#343824) - - "Unmaximise" is now called "restore". (Thomas) (#343824) - - New thread handling call for gconf (Frederic) (#565517) - - Add screenshot commands back which had been removed (Yanko) (#565343) - - move_to_corner_se keybinding fixed (Thomas) - - Windows on other workspaces which attempt to present themselves - are marked as needing attention (Colin) (#482354) - - End the grab op when the user clicks the titlebar (Thomas) (#401028) - -Translations - Jorge González (es) - -2.25.55 -======= - -Thanks to Erwann Chenede for improvements in this version. - - - Fix build on Solaris (Erwann) (#564123) - -Translations - Mattias Põldaru (et), Luca Ferretti (it) - -2.25.34 -======= - -Thanks to Matt Kraai for improvements in this version. - - - Fixes to Thomas's earlier fixes (Matt) (#562939) - -Translations - None - -2.25.21 -======= - -Thanks to Thomas Thurman for improvements in this version. - - - Fixes to allow building without compositor again (Thomas) - - Fixes for -Wall problems (Thomas) - - Various tool updates (Thomas) - -Translations: none - - -2.25.13 -======= - -Thanks to Thomas Thurman for improvements in this version. - - - Add casts to fix failure to build from source on 64bit hosts (Thomas) (#562106) - - Added script to produce announcements (Thomas) - -Translations - Jorge González (es) - -2.25.8 -====== - -Thanks to Brian Cameron, Maxim Ermilov, Daniel Macks, Elijah Newren, Frederic -Peters, Thomas Thurman, David Trowbridge, and Olav Vitters for improvements in -this version. - - - Reorder compiler flags (Daniel) (#562033) - - Fix compositor switch (Daniel) (#560990) - - Remove spurious warnings about operations on window "none" (Thomas) - - Fix _POSIX_C_SOURCE which was breaking OS X builds (Thomas) (#561962) - - -Werror -Wall and -ansi are now standard compile flags (Thomas) - - Merge screen and window keybindings files; fix minor alt-tab bug - in the process (Thomas) (#528337) - - Support _NET_WM_FULLSCREEN_MONITORS (David) - - Remove some deprecated calls (Thomas) (#560445) - - Clean up #includes (Maxim) (#560449) - - Update description of raise_on_click (Elijah) - - First dialogue delegated to zenity (Thomas) - - fix theme-parser typo (Olav) - - double-quote variable names in messages (Thomas) (#558309) - - fix accidental renaming of run_command_terminal (Thomas) (#557943) - - some null checks; problems exposed by new GDM (Brian) (#558058) - - ignore mouse button modifier if it's missing (Thomas) (Launchpad 258054, Launchpad 266929) - - fix docbook markup (Frederic) - -Translations - Astur (ast), Jorge González (es), Thomas Thurman (la), Leonardo Ferreira - Fontenelle (pt_BR), Daniel Nylander (sv) - -2.25.5 -====== - -Thanks to Thomas Thurman for improvements in this version. - - - Allow third-party apps to decide whether a window appears - on all workspaces (Thomas) (#557536) - - Fixed keybindings script (again) (Thomas) - -Translations - David Planella (ca), Robert Millan (ca@valencia) - -2.25.3 -====== - -Brown paper bag release which fixes numerous build problems from last night's -release of 2.25.2. Apologies. - -Thanks to Murray Cumming, Thomas Thurman, and Götz Waschk for improvements -in this version. - - - Fix distcheck (Thomas) (#557356) - - add libm reference (Götz) (#557357) - - fix docbook tags (Murray) (#557337) - -Translations - Yavor Doganov (bg), David Planella (ca), Robert Millan (ca@valencia), Kenneth - Nielsen (da), Hendrik Richter (de), Ivar Smolin (et), Claude Paroz (fr), Seán de - Búrca (ga), Launchpad Translations Administrators (hr), Gabor Kelemen (hu), - Thomas Thurman (la), Žygimantas Beručka (lt), Kjartan Maraas (nb), Duarte - Loreto (pt), Djavan Fagundes (pt_BR), Mugurel Tudor (ro), Pavol Šimo (sk), - Laurent Dhima (sq), Горан Ракић (sr), Theppitak Karoonboonyanan (th), - Funda Wang (zh_CN) - -2.25.2 -====== - -Thanks to Joe Marcus Clarke, Murray Cumming, Tomas Frydrych, William Lachance, -Matthew Martin, Christian Persch, Thomas Thurman, and Vincent Untz for -improvements in this version. - - - Add handler for SIGTERM (Joe) (#553980) - - Minimised windows are necessarily obscured (Matthew) (#528927) - - Build fixes with the above (Christian, Tomas, Thomas) (#557335) - (#557201) (#469361) - - Changed keybindings to be in a single place (Thomas) (#469361) - - Add new document about themes (Murray) - - Remove obsolete support for fallback icons (Thomas) - - Pass modified mouse events to panels (William) (#554428) - - Change where desktop files should go (Vincent) (#549479) - -Translations - Yavor Doganov (bg), David Planella (ca), Kenneth Nielsen (da), Hendrik - Richter (de), Ivar Smolin (et), Claude Paroz (fr), Seán de Búrca (ga), Launchpad - Translations Administrators (hr), Gabor Kelemen (hu), Thomas Thurman (la), - Žygimantas Beručka (lt), Kjartan Maraas (nb), Duarte Loreto (pt), Djavan - Fagundes (pt_BR), Mugurel Tudor (ro), Pavol Šimo (sk), Laurent Dhima (sq), - Горан Ракић (sr), Theppitak Karoonboonyanan (th), Funda Wang (zh_CN) -2.25.1 -====== - -Thanks to Thomas Thurman for improvements in this version. - - - Fix small memory leak, found by Matthias Clasen (Thomas) (#549952) - - Added move_to_center keybinding suggested by - Khanh-Dang Nguyen Thu Lam (Thomas) (#549979) - - Compositor can be turned on and off from the command line - (#545323) (Thomas) - -Translations - Khaled Hosny (ar), Petr Kovar (cs), Iñaki Larrañaga Murgoitio (eu), Ilkka - Tuohela (fi), Žygimantas Beručka (lt), Duarte Loreto (pt), Djavan - Fagundes (pt_BR), Laurent Dhima (sq) - -2.25.0 -====== - -Thanks to Patrick Niklaus, Ted Percival, Eric Piel, Akira TAGOH, and Thomas -Thurman for improvements in this version. - - - Fix memory allocation problem in struts (Eric) (probably #468075) - - Ensure windows which start maximised know where to jump back - to, so they don't warp to other screens (Ted) (#504692) - - Added header comments to some files (Thomas) - - Icons for windows which are uncooperative enough not to provide - an icon are taken from the theme, not built in (Patrick) (#524343) - - Added manual page for metacity-message (Akira, from Debian downstream) - -Translations - Khaled Hosny (ar), Petr Kovar (cs), Ilkka Tuohela (fi), Duarte Loreto (pt), Djavan - Fagundes (pt_BR) - -2.23.89 -======= - -Thanks to Thomas Thurman for improvements in this version. - - - Added DOAP file. (Thomas) - -Translations - Khaled Hosny (ar), Luca Ferretti (it), Takeshi AIHANA (ja), Wouter - Bolsterlee (nl), Vladimir Melo (pt_BR), Daniel Nylander (sv) - -2.23.55 -======= - -Thanks to Elijah Newren and Thomas Thurman for improvements in this version. - -Contrary to rumour, this release does not add tabbing to everything. - - - Display theme name in title bar of theme viewer (Thomas) (#430198) - - Allow toggling of non-compositor effects (Thomas) (#92867) - - Add some extra null checks (Thomas) (#422242) - - Check for double-freeing at the time of workspace freeing (Elijah) (#361804) - - Don't generate log messages unless we're logging (Thomas) - - Two windows which don't belong to any application can't be considered to - belong to the same application (Thomas) - - Various tidyings (Thomas) - -Translations - Yavor Doganov (bg), Gabor Kelemen (hu), Kjartan Maraas (nb), Matej - Urbančič (sl), Daniel Nylander (sv), Theppitak Karoonboonyanan (th) - - -2.23.34 -======= - -Thanks to Thomas Thurman for improvements in this version. - - - Commenting and tidying (Thomas) - - Fix possible compositor crash (Thomas) (#530702) - -Translations - Khaled Hosny (ar), Yavor Doganov (bg), Jorge González (es), Kjartan Maraas (nb), - Yannig Marchegay (Kokoyaya) (oc), Theppitak Karoonboonyanan (th), Clytie - Siddall (vi) - -2.23.34 -======= - -Thanks to Thomas Thurman for improvements in this version. - - - Commenting and tidying (Thomas) - - Fix possible compositor crash (Thomas) (#530702) - -Translations - Khaled Hosny (ar), Yavor Doganov (bg), Jorge González (es), Kjartan Maraas (nb), - Yannig Marchegay (Kokoyaya) (oc), Theppitak Karoonboonyanan (th), Clytie - Siddall (vi) - -2.23.34 -======= - -Thanks to Thomas Thurman for improvements in this version. - - - Various commenting (Thomas) - - Ensure you can turn off compositor with "configure" (Thomas) - - Ensure you can turn off gconf with "configure" (Thomas) (#530870) - -Translations - Clytie Siddall (vi) - -2.23.21 -======= - -Thanks to Robert Escriva, Iain Holmes, Matt Krai, Thomas Thurman, -and Chris Wang for improvements in this version. - - - Add shadow ability for menus and tooltips (Iain) (#517442) (#517524) - - Fix possible crashes in compositor (Iain) (#534569) (#528787) - - Major reorganisation of compositor code (Iain) - - Initial version of XRender backend for the compositor (Iain) - - New basic public API for compositor (Iain) - - Window decoration updates colour when GTK theme changes (Robert) (#511826) - - Minor code cleanup for pedantic compilers (Thomas) - - Further code cleanup for pedantic compilers (Matt) (#526049) - - The atom list appears only once in the code (Thomas) (#530843) - - Don't attempt to read attributes of invalid windows (Chris) (#530485) - -Translations - Khaled Hosny (ar), Gabor Kelemen (hu), Kjartan Maraas (nb), Tino Meinen (nl), - Theppitak Karoonboonyanan (th) -2.23.13 -======= - -Thanks to Erwann Chenede and Carlos Garnacho for improvements -in this version. - - - Re-enable cascading (Erwann) (#529925) - - Propagate opacity to frame windows (spec compliance!) (Carlos) - -Translations - - None this time! - -2.23.8 -====== - -Thanks to Lucas Rocha, Iain Holmes, and Jens Granseuer for improvements -in this version. - - * No need to symlink to .desktop files (Lucas) - * Fixes to compositor's dealings with overlay windows (Iain) - * C89 fixes (Jens) - -Translators: -Khaled Hosny (ar), Amitakhya Phukan (as), Ihar Hrachyshka (be@latin), -Petr Kovar (cs), Rhys Jones (cy), Kenneth Nielsen (da), Andre Klapper (de), -Jorge González (es), Iñaki Larrañaga Murgoitio (eu), Ilkka Tuohela (fi), -Claude Paroz (fr), Seán de Búrca (ga), Ignacio Casal Quinteiro (gl), -Yuval Tanny (he), Gabor Kelemen (hu), Luca Ferretti (it), Takeshi AIHANA (ja), -Shankar Prasad (kn), Changwoo Ryu (ko), Arangel Angov (mk), sandeep shedmake (mr), -Kjartan Maraas (nb), Nabin Gautam (ne), Wouter Bolsterlee (nl), -Eskild Hustvedt (nn), Yannig Marchegay (Kokoyaya) (oc), Tomasz Dominikowski (pl), -Duarte Loreto (pt), Vasiliy Faronov (ru), Daniel Nylander (sv), -Theppitak Karoonboonyanan (th), Baris Cicek (tr), Maxim Dziumanenko (uk), -Clytie Siddall (vi), Woodman Tuen (zh_HK), Woodman Tuen (zh_TW) -2.23.5 -====== - -Thanks to Lucas Rocha, Owen Taylor, and Thomas Thurman for improvements in this -version. - - - Updates of useless preferences don't crash (Thomas) (#526016) - - Compliance with new gnome-session (Lucas) (#525051) - - Preview widget doesn't crash on broken themes (Thomas) (Launchpad 199402) - - Initially iconic windows don't unminimise (Owen) (#491090) - - Move ~/.metacity to ~/.config/metacity (Thomas) (#518596) - - Metacity doesn't stay around when replaced (Thomas) - - Extra check for null return in a function (Thomas) - - Displays are singletons, simplifying code (Thomas) (#499301) - -Translations - Jorge González (es), Eskild Hustvedt (nn), Baris Cicek (tr), Clytie Siddall (vi) - -2.23.3 -====== - -Thanks to Marco Pesenti Gritti, Iain Holmes, Josh Lee, Thomas Thurman, and -Matthew Wilson for improvements in this version. - - - Workspaces whose name is the same as the standard name, plus some string, - are not cut off. (Thomas) (#453678) - - Improve compositor performance (Iain) (#522166) - - Draw wallpaper correctly when we start up with compositor - (Iain) (#522599) - - Several other smaller compositor fixes (Iain) - - Don't draw shadows on shaped windows unless they have frames - (Iain) (#505333) - - Newly-created keep-above windows get focus (Marco) (#519188) - - Allow moving workspace when dragging with modifier key (Matthew) - (#474195) - -Translations - Kenneth Nielsen (da), Gabor Kelemen (hu), Vasiliy Faronov (ru), Daniel - Nylander (sv), Maxim Dziumanenko (uk), Woodman Tuen (zh_HK) - -2.23.2 -====== - -Removed some debug statements introduced in 2.23.1. Brown paper bag release. - - -2.23.1 -====== - -Thanks to Cosimo Cecchi, Jens Granseuer, Jim Huang, Andrea Del Signore, and -Thomas Thurman for improvements in this version. - -(Cosimo's patch was very similar to another received from Jason Ribero.) - - - Allow horizontal and vertical maximisation using the mouse (Cosimo/Jason) - (#358674) - - Allow "spacer" as a value for buttons, for blank space (Andrea) (#509165) - - Remove unused code (Jim) - - refactor preferences handling (Thomas) - - make sure we're valid C89 (Jens) (#518917) - - some messing with tool scripts (Thomas) - -Translations - Jorge González (es), Claude Paroz (fr), Woodman Tuen (zh_HK), Woodman - Tuen (zh_TW) - -2.23.0 -====== - -Thanks to Matthias Clasen, Mikkel Kamstrup Erlandsen, Jim Huang, Thomas Thurman, -and Thomas Wood for improvements in this version. - - - the preview widget can draw shaped windows properly! (Thomas W, #460018) - - refactored handling of boolean and enumerated gconf preferences; - refactoring of string and integer preferences will follow shortly (Thomas T) - - Applications asking to move and resize windows at the same time have - both their requests granted (Mikkel) (#448183) - - Windows marked "skip taskbar" don't appear in the ctrl-alt-tab list - (Matthias) (#106249) - - fix session management detection (Thomas T) (#328210) - - when resizing with the keyboard, the cursor stays on a window edge if - you escape, whichever direction you were going (Thomas T) (#436257) - - fix major breakage when gconf was turned off in configure (Jim) (#515019) - - fix major breakage when verbose was turned off in configure (Jim) (#515152) - - fix name of verbose option in help (Thomas T) - - various bits of messing around with release scripts (Thomas T) - -Translations - Ihar Hrachyshka (be@latin), Ilkka Tuohela (fi), Ignacio Casal Quinteiro (gl), - Shankar Prasad (kn), Changwoo Ryu (ko), Nabin Gautam (ne), Wouter Bolsterlee (nl) - -2.21.13 -======= - -Thanks to Michael Meeks and Thomas Thurman for improvements in this version. - - - Only use compositor version if we have a compositor (Thomas) (#514453) - - Remove workaround for a problem in an ancient GTK version (Thomas) (#513737) - - Compositor efficiency fixes (Michael) - - Various tools added (Thomas) - -Translations - Amitakhya Phukan (as), Rhys Jones (cy), Andre Klapper (de), Takeshi AIHANA (ja), - Arangel Angov (mk), Tomasz Dominikowski (pl), Duarte Loreto (pt) - -2.21.8 -====== - -Thanks to Paolo Borelli, Iain Holmes, Havoc Pennington, Christian Persch, Thomas -Thurman, and Alex R.M. Turner for improvements in this version. - - - Windows on other workspaces which need attention appear in the alt-tab - list too (Alex) (#333548) - - Remove deprecated function call (Christian) (#512561) - - New release script (Thomas) - - Made a start at improving the general number of comments (Thomas) - - Updated copyright year to 2008, and some other tiny fixes (Thomas) - - Don't do anything unusual when the compositor frees a window (Iain) - - Mapping windows doesn't mark them as damaged (Iain) - - Compositor uses the overlay window and not the root window (Iain) - - Fixed several list leaks (Paolo) - - Fixed warnings about printf formats (Havoc) - - Move source files into subdirectories of the src directory (Havoc) - -Translations - Khaled Hosny (ar), Ihar Hrachyshka (be@latin), Petr Kovar (cs), Andre - Klapper (de), Jorge González (es), Iñaki Larrañaga Murgoitio (eu), Seán de - Búrca (ga), Yuval Tanny (he), Luca Ferretti (it), Takeshi AIHANA (ja), Arangel - Angov (mk), sandeep shedmake (mr), Kjartan Maraas (nb), Yannig - Marchegay (Kokoyaya) (oc), Daniel Nylander (sv), Theppitak Karoonboonyanan (th), - Baris Cicek (tr), Clytie Siddall (vi) -2.21.5 -====== - -Thanks to Iain Holmes and Thomas Thurman for improvements in this version. -This contains the new compositor; downstream maintainers should note that -its GConf key is initially turned off in src/metacity.schemas.in and consider -whether to turn it on by default in their packages. - - - merge compositor branch! (Iain) (499081) - - print "Subversion" and not "CVS" when building (Thomas) - -Translations - Jorge González (es), Kjartan Maraas (nb), Daniel Nylander (sv) - -2.21.3 -====== - -Thanks to Matthias Clasen, Martin Meyer, Kjartan Maraas, Thomas Thurman, -and Lucas Rocha for improvements in this version. - - - remove dead code (pointed out by Kjartan) (501365) - - rewrote long key binding description for the sake of - the translators (Thomas) (474889) - - check for null before adding menu (Matthias) (496054) - - let keys which end a grab also begin a grab (Thomas) (112560) - - check the right variable in theme sanity check (Martin) (501362) - - get session ID from environment if it's not passed in on the command - line (Lucas) (498033) - -Translations - Ihar Hrachyshka (be@latin), Petr Kovar (cs), Jorge González (es), - Ignacio Casal Quinteiro (gl), Rodrigo Flores (pt_BR), Pavol Šimo (sk), - Matej Urbančič (sl) - -2.21.2 -====== - -Thanks to Benjamin Gramlich, Thomas Thurman, and Peter Bloomfield -for improvements in this release. - - - Theme parser is compliant to XDG Base Directory Specification - in searching for theme files. (Benjamin) (#480026) - - Some source files which didn't get used were removed (Thomas) - (#496947) - - Fullscreen and maximise windows don't try to save their position - (Peter) (#461927) - -Translations - Matej Urbančič (sl) - -2.21.1 -====== - -Thanks to Elijah Newren, Alex R.M. Turner, Peter Bloomfield, Iain Holmes, -Jans Granseuer, Federico Mena Quintero and Thomas Thurman for improvements -in this release. - - - Add --sync option, like all other GTK apps (Iain) - - Don't save window's position if it's maximised (Peter) (#461927) - - Memory leak fix in preview (Jans) (#469682) - - Truncate tab popup string correctly, and refactor function (Alex) - - Windows which pop up under always-on-top windows don't get the - focus, but do get the "needs attention" hint (Thomas) (#486445) - - Fix error in function call which caused focus problems (Federico) - (partial fix of #488468) - -Translations - Djihed Afifi (ar), Metin Amiroff (az), Alexander Shopov (bg), - Jordi Mallach (ca), David Lodge (en_GB), Jorge González (es), - Iñaki Larrañaga Murgoitio (eu), Vincent Untz (fr), Alastair McKinstry (ga), - Ankit Patel (gu), Rajesh Ranjan (hi), auto (hr), Changwoo Ryu (ko), - Raivis Dejus (lv), Wouter Bolsterlee (nl), Gora Mohanty (or), - ASB (pa), wadim dziedzic (pl), Duarte Loreto (pt), - Og Maciel (pt_BR), Peter Tuhársky (sk), Matej Urbančič (sl), - Daniel Nylander (sv), Maxim Dziumanenko (uk), Funda Wang (zh_CN) - -2.20.0 -====== - -Thanks to Alexey Rusakov for the fix in this release. - - - prevent a crash on logout with metacity subsequently not being - restored in future sessions (Alexey) [#433253] - -Translations - Khaled Hosny (ar), Ihar Hrachyshka (be@latin), Ask Hjorth Larsen (da), - Adam Weinberger (en_CA), Iñaki Larrañaga Murgoitio (eu), Ilkka - Tuohela (fi), Vincent Untz (fr), Ankit Patel (gu), Gabor Kelemen (hu), - Luca Ferretti (it), Takeshi AIHANA (ja), Žygimantas Beručka (lt), Jovan - Naumovski (mk), Ani Peter (ml), Og Maciel (pt_BR), Duarte Loreto (pt), - Mugurel Tudor (ro), Nickolay V. Shmyrev (ru), Peter Tuhársky (sk), Горан - Ракић (sr), Daniel Nylander (sv), Dr.T.Vasudevan (ta), Maxim - Dziumanenko (uk), Clytie Siddall (vi) - -2.19.55 -======= - -Thanks to Frederic Crozat, Matthias Clasen, and Thomas Thurman for improvements -in this release. - - - Noninteger auto-raise delay is not assumed to be zero (Thomas) (#377491) - - Fix mangled window title in "Force Quit" (Frederic) (#462734) - - "Close" can appear at any point in the window menu, and now appears - at the bottom (Thomas) (#104026) - - Windows which are always on top have "stick" insensitive (Thomas) (#460997) - - All bitfields in window structure are together for optimisation (Thomas) - (#450271) - - Use the correct directory when installing keybindings (Matthias) (#454055) - -Translations - Alexander Shopov (bg), Jorge González (es), Iñaki Larrañaga Murgoitio (eu), - Ilkka Tuohela (fi), Theppitak Karoonboonyanan (th) - -2.19.34 -======= - -Thanks to Rob Bradford, Cosimo Cecchi, Yair Hershkovitz and Thomas Thurman -for improvements in this release. - - - Fix a bug where the window can be focused without being raised - if the maximize is aborted. (Rob) [#459027] - - Unset fullscreen is an allowed action where relevant. (Cosimo) [#449427] - - Reverse window buttons and align them to the left for RTL locales. - (Yair) [#92212] - - Put all bitfields in window data together to help with optimisation. - (Thomas) [#450271] - -Translations - Jorge Gonzalez (es), Ilkka Tyohela (fi), Gabor Kelemen (hu), - Takeshi AIHANA (ja), Kjartan Maraas (nb), Vincent van Adrighem (nl), - Daniel Nylander (sv), Theppitak Karoonbooyana (th), - Nguyễn Thái Ngọc Duy (vi) - -2.19.21 -======= - -Thanks to Damien Carbery and Thomas Thurman for improvements in -this release. - - - Fixed build on Solaris (Damien) [#397296, #446535] - - Only activate windows which change their startup ID if the - new ID differs from the old. (This fixes the bug where KDE - apps gained the attention hint when switching workspaces.) - (Thomas) [#400167] - - Open new windows on the current xinerama. (Thomas) [#145503]. - -Translations - Tshewang Norbu (dz), Jorge González (es), Funda Wang (zh_CN) - -2.19.13 -======= - -Thanks to Elijah Newren and Thomas Thurman for improvements in -this release. - - - Updated the description of raise_on_click (Elijah) [#445447, - #389923] - - Refactor queueing code in window.c (Thomas) [#376760] - - Added switch_group to the keybindings file (Thomas) [#444879] - - New window information accessor function (Thomas) [#377495] - -2.19.8 -====== - -Thanks to Linus Torvalds, Yair Hershkovitz and Thomas Thurman for -improvements in this release. - - - Lots of fixups for various alignments in RTL locales (Yair) - [#387893] - - Add code to configure what happens on right or middle click - of titlebar (Linus) [#408904] - - Fix layout for titlebars with mixed LTR/RTL scripts (Thomas) - [#433400] - - Fix window menu layout for RTL scripts (Thomas) [#433400] - -Translations - Khaled Hosny (ar), Ihar Hrachyshka (be@latin), Jovan Naumovski (mk), - Theppitak Karoonboonyanan (th) - - [ Apologies to these translators who didn't get credited in the - version of 2.19.8 that shipped. ] - -2.19.5 -====== - - - Prevent metacity from "forgetting" which machine a window is on - (Elijah) [#418552] - - Prevent nasty flickering an placement problem introduced in - metacity 2.19.2 (Elijah) [fix side-effect of change in #426519] - - Fix some uninitialized memory usage errors (Elijah) [#427385] - -Translations - David Lodge (en_GB), Jorge González (es), Ignacio Casal Quinteiro (gl), - Daniel Nylander (sv) - -2.19.3 -====== - -Thanks to Magnus Therning, Elijah Newren, Thomas Thurman, and Bruno -Boaventura for improvements in this release. - - - Add support for _NET_MOVERESIZE_WINDOW (Magnus, Elijah) [#344521] - - EWMH compliance: set _NET_WM_ALLOWED_ACTIONS so that pagers know - which actions we support (Elijah) [#115247] - - Fix crash with apps trying to open an insanely huge window - (Thomas) [#399529] - - Fix temporary hang/pause with libXt by making sure apps get a - ConfigureNotify on unmap (Elijah) [#399552] - - do not auto-maximize windows larger than the workarea in only a - single direction (Elijah) [#419810] - - Don't show the current workspace as a possible workspace to switch - to (Bruno) [#426791] - - Preserve stacking order across restarts (Elijah) - -Translations - Khaled Hosny (ar), Kjartan Maraas (nb) - -2.19.2 -====== - -Thanks to Bastien Nocera, Thomas Thurman, and Elijah Newren for -improvements in this release. - - - Add new control-center key bindings definitions (Bastien) [#420145] - - Prevent metacity from crashing when trying to use invalid themes - (Thomas) [#423855] - - Fix invalid free causing crash on metacity close introduced in - 2.19.1 (Elijah) [#427385] - - Add special keybinding just for debugging spew marks, unbound and - not even listed in schemas (Elijah) - - Fix move/resize events in relation to combinations of - ConfigureRequest and WM_NORMAL_HINTS change notifications (Elijah) - [#426519] - - Remove what we believe to be an ancient attempt at working around - sloppy/mouse focus bugs that we believe have since been correctly - fixed. May fix some ugly race conditions. May also cause nasty - bugs in sloppy/mouse focus modes. Only one way to find - out... (Elijah) [#304430] - -Translations - Raivis Dejus (lv) - -2.19.1 -====== - -Thanks to Jaap Haitsma, Linus Torvalds, Charlie Brej, Kjartan Maraas, -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 - related code (Linus) [#408899, #408902, others] - - add schemeas for middle and right click titlebar actions (Charlie) - [#408903] - - remove pango/pangox.h include since it's not needed and not - installed anymore (Kjartan) - - adjust rounded corners so that they fit nicely with the arcs - around them (Arthur) [#399373] - - fix session hang when metacity .sm file is missing (Josselin) - [#407981] - - add support for _NET_WM_USER_TIME_WINDOW in order to cut down on - context switches (Elijah, Havoc) [#354213] - - prevent nasty metacity/gdk interactions causing hangs with gtk - trunk (Elijah) [offshoots of #354213] - - fix button middle fallback and the prelight state (Benjamin) [#419043] - - Lots of code cleanup for the strut lists (Elijah) - - fix handling of unidirectional maximization and partial struts + - some miscellaneous cleanups (Carlo) [#358311] - - avoid some crashes when dragging windows partially offscreen - (Elijah) [#353513] - - avoid mousenav vs. keynav focus problems with the run application - dialog in mouse/sloppy focus modes (Elijah) [#374752] - - _NET_ACTIVE_WINDOW property on the root window should be a single - xwindow id, not two (Elijah) - - Fix unidirection unmaximization causing jumps (Elijah) [#355497] - - fix unfullscreening and unmaximizing with size increment/size - constraint windows (such as gnome-terminal) possibly not returning - to their "original position" (Elijah) [#329152] - - fix some issues with min/max and size increment constraints - (Elijah) [#418395] - - send synthetic configure notify events in response to appropriate - MapRequest events too (Elijah) [#322840] - -Translations - Ihar Hrachyshka (be@latin), Jordi Mallach (ca), Jakub Friedl (cs), - norbu (dz), David Lodge (en_GB), Ivar Smolin (et), Gabor Kelemen (hu), - Luca Ferretti (it), Takeshi AIHANA (ja), Erdal Ronahi (ku), Gintautas - Miliauskas (lt), Jovan Naumovski (mk), Kjartan Maraas (nb), Reinout van - Schouwen (nl), wadim dziedzic (pl), raulpereira (pt_BR), Nickolay V. - Shmyrev (ru), Горан Ракић (sr), Woodman Tuen (zh_HK), Woodman Tuen (zh_TW) - -2.17.5 -====== - -Thanks to Bruno Boaventura, Mad Alex, and Thomas Thurman for -improvements in this release. - - - make window menu arrangement more sensible. (Bruno) [#382962] - - unmaximise button keeps pressed appearance when moved off and - back. (Alex) [#395560] - - fix a couple of compositor crashes (Thomas) [#387761] - - new environment variables checked if the compositor is enabled; - see the new file doc/compositor-control.txt for details. (Thomas) - -Translations - Djihed Afifi (ar), Ales Nyakhaychyk (be), Jordi Mallach (ca), - Jakub Friedl (cs), David Lodge (en_GB), Raivis Dejus (lv), - Kjartan Maraas (nb), Mugurel Tudor (ro), Daniel Nylander (sv), - Theppitak Karoonboonyanan (th) - -2.17.3 -====== - -Thanks to Christof Krüger, Federico Mena Quintero, Bruno Boaventura, -and Björn Lindqvist for improvements in this release. - - - fix longstanding problem about windows flickering in and out of - maximised state when dragging between xineramas (Christof) [#358715] - - grab server when switching workspaces (Federico) [#381127] - - replace changing text on window menu with pairs of radio buttons - and checkboxes (Bruno, Björn) [#343108] - -Translations - Kjartan Maraas (nb), Jakub Friedl (cs), Yuval Tanny (he), Ivar Smolin (et), - Duarte Loreto (pt), Francisco Javier F. Serrador (es) - -2.17.2 -====== - -Thanks to Priit Laes, Bruno Boaventura, Kjartan Maraas, Justin Mason, -Elijah Newren and Dan Mick for improvements in this release. - - - implement handle_move_to_{side|corner}_* to allow the user to flip a - window to the side or corner of the screen. (Justin) [#317884] - - fix strict focus mode by picking up on res_class (Dan) [#361054] - - remove deprecated gtk stuff (Priit, Bruno) - - string fixes (Kjartan) [#363354, #363355] - -Translations - Jakub Friedl (cs), Francisco Javier F. Serrador (es), Ilkka Tuohela (fi), - Christophe Merlet (RedFox) (fr), Kjartan Maraas (nb) - -2.17.1 -====== - -Thanks to Bruno Boaventura and Carlo Wood for improvements in this -release. - - - sync metacity workspace previous with libwnck (Bruno) [#341893] - - fix cases when titlebar is allowed offscreen and shouldn't be, and - vice-versa (Carlo) [#333995] - -Translations - Ilkka Tuohela (fi) - -2.17.0 -====== - -Thanks to Elijah Newren, Jens Granseuer, Bruno Boaventura, Carlo Wood, -and Thomas Thurman for changes in this release. - - - version 2 of theme format: stick, shade and above buttons on titlebar, - variable rounding on corners, variable transparency on window - backgrounds, stock icons in themes, can remove all titlebar buttons - from certain classes of window, and more (Thomas) [#102547 and - dependencies] - - improve "Force Quit" dialog (Bruno) [#121936] - - ignore edge resistance when resizing with keyboard (Elijah) [#346782] - - maintain window size and placement across restarts (Carlo) [#358042] - - prevent crash when closing certain remote apps (Elijah) [#358514] - - longstanding mouse-focus bug fixed which affected firefox's - autocompletion (Elijah) [#357695] - - ignore maximum size constraints when maximising (Elijah) [#327543] - - warn translators to keep translations in sync with libwnck (Bruno) - [#355620] - - fixes for compilation warnings, etc (Elijah, Jens) [#348067, #356631] - -Translators - Ivar Smolin (et), Gabor Kelemen (hu), Luca Ferretti (it), - Runa Bhattacharjee (bn_IN) - -2.16.2 -====== - -Thanks to Eljah Newren, Maik Beckmann, Christian Hamar, Thomas Andersen, -and Bruno Boaventura de Oliveira for changes in this release. - - - partial audit to fix timestamp usage (Elijah) [part of #355180] - - remove compilation warnings (Maik) [#355876]; (Bruno) [#355490, - #355489] - - automatic detection of stable/unstable in configure script - (Christian/Elijah) [#356122] - - make windows be stacked correctly before showing them (Thomas) - [#332385] - - use guint32 for timestamps (Elijah) [#348305] - -Translators - Wouter Bolsterlee (nl), Matic Žgur (sl), Francisco Javier F. Serrador (es), - Vladimir Petkov (bg), Jordi Mallach (ca), Ilkka Tuohela (fi), - Rajesh Ranjan (hi), Woodman Tuen (zh_HK, zh_TW), Ani Peter (ml), - Felix (ta), Ankit Patel (gu), Mohammad DAMT (id) - -2.16.1 -====== - -Thanks to Elijah Newren, Colin Watson, and Bruno Boaventura de Oliveira -Lacerda for changes in this release. - - - fix stuck grab, letting focus be transferred between windows (Elijah) - [#354422 partial] - - windows returning from fullscreen are constrained to be onscreen - (Elijah) [#353699] - - Clear the transient_for flag of a window after emitting a warning - (Colin) - - Replace copy_of_gdk_x11_window_set_user_time() with the real thing - (Bruno) [#352293] - -Translators - David Lodge (en_GB), Ivar Smolin (et), Matic Žgur (sl), - Vasiliy Faronov (ru) - -2.16.0 -== - -Thanks to Jens Granseuer for changes in this release. - - - Fix the build with c89/gcc 2.95. - -Translators - Rahul Bhalerao (mr), Runa Bhattacharjee (bn_IN), Woodman Tuen - (zh_HK, zh_TW), Kostas Papadimas (el), Ani Peter (ml), - Jonathan Ernst (fr), Горан Ракић (sr, Gabor Kelemen (hu), - Maxim Dziumanenko (uk), Duarte Loreto (pt), Jordi Mallach (ca), - Gintautas Miliauskas (lt) - -2.15.34 -== - -Thanks to Stéphane Rosi, Vytautus Liuolia, Will Walker, Baptiste -Mille-Mathias, Elijah Newren, Ed Catmur, and Thomas Andersen for fixes -in this release. - - - allow moving maximized windows between xineramas again (Stéphane) - [#338660] - - fix an uninitialized-usage bug with net_wm_user_time that breaks - focus with new windows (Vytautus) - - re-fix accessibility events for the alt-tab popup (Will) [#350624] - - update the close pixmap to fit better with the other pixmaps of the - menu (Baptiste) [#345498] - - fix several fullscreen handling bugs I introduced, causing - fullscreen windows to not actually be shown fullscreen (Elijah) - [#343115] - - fix keybindings with hex-values, coming from special extended - keyboard keys (Ed) [#140448] - - fix metacity-dialog handling of arguments (Thomas) [#340690] - -Translators - Vladimir Petkov (bg), Jordi Mallach (ca), Gabor Kelemen (hu), - Mohammad DAMT (id), Wouter Bolsterlee (nl), Daniel Nylander (sv), - Funda Wang (zh_CN) - -2.15.21 -== - -Thanks to Vincent Untz, Jens Granseuer, Björn Lindqvist, Dmitry -Timoshkov, Thomas Thurman, Vytautas Liuolia, Thomas Andersen, Chris -Ball, and Elijah Newren for fixes in this release. - - - kill usage of libegg (Vincent) [#348633] - - fix another C89 vs. C99 issue (Jens) [#347621] - - make it so maximized windows do not have rounded corners (Björn) - [#336850] - - fix the heuristic for determining if windows can be made - fullscreen, needed for WINE and possible also some legacy - applications (Dmitry) [#346927] - - make sure window features get recalculated when the screen is - resized via XRandR (Dmitry) [#346927] - - fitts' law fixes for titlebar buttons on maximized windows (Thomas - Thurman) [#97703] - - react to _NET_STARTUP_ID changes, as proposed for the new - startup-notification/EWMH spec (Vytautas) [#347515] - - return the window to maximized state if the window was "shaken - loose" from maximized state during a resize but the resize is later - aborted (Thomas Andersen) [#346719] - - fix button lighting with dragged clicks (Björn) [#321474] - - don't minimize in response to double clicks on the titlebar when - minimiziation should not be allowed (Chris) [#347377] - - fix some titlebar-not-on-screen constraint issues (Elijah) - [#333328, #345522] - -Translators - Mahay Alam Khan (bn_IN), Jakub Friedl (cs), Iñaki Larrañaga - Murgoitio (eu), Yuval Tanny (he), Rajesh Ranjan (hi), Jovan - Naumovski (mk) Kjartan Maraas (nb), Leonid Kanter (ru) - -2.15.13 -== - -Thanks to Björn Lindqvist and Thomas Thurman for improvements in this -release. - - - grab alt+shift+button1 when trying to snap-move windows (Björn) - - avoid a case where memory is written after it's freed (Thomas) - -Translators - Hendrik Richter (de), Kostas Papadimas (el), Jonathan Ernst (fr), - Satoru SATOH (ja) - -2.15.8 -== - -Known as the "Elijah sucks for not reviewing a couple dozen patches" -release. And for not getting on IRC soon enough to catch Marnanel and -show him how to do the release. So, just translations this time. - -Translations - - Mahay Alam Khan (bn_IN), Rhys Jones (cy), Francisco Javier - F. Serrador (es), Ilkka Tuohela (fi), Rajesh Ranjan (hi), Changwoo - Ryu (ko), Fano Rajaonarisoa (mg), Sanlig Badral (mn), Слободан Д. - Средојевић (sr), Funda Wang (zh_CN) - -2.15.5 -== - -Thanks to Björn Lindqvist, Søren Sandmann, Adam Jackson, Elijah -Newren, and Aidan Delaney for improvements in this release. - - - code cleanup in resizepopup.c (Björn) [#341648] - - fix a logic bug so that the whole titlebar becomes sensitive to - mouse clicks (Björn) [#336320] - - make mouse cursor when moving windows become a hand (Björn) [#337376] - - lots and lots of compositor improvements -- beginning of a new - layer to abstract transition effects, shrinking and minimizing and - exploding effects, fading in and out, unminimize animation that - reverses minimize one, translucent menus, bounce on window focus, - and all kinds of stuff I don't understand and can't summarize well - (Søren, Adam) - - Fix a crash on exit/logout from assuming a compositor would always - exist (Elijah) [#342166] - - code cleanup in tabpopup.c (Aidan Delaney) [#166890] - -Translations - Pema Geyleg (dz), Iñaki Larrañaga Murgoitio (eu), Theppitak - Karoonboonyanan (th), Clytie Siddall (vi) - -2.15.3 -== - -Thanks to Søren Sandmann, Elijah Newren, Paolo Borelli, Björn -Lindqvist, jylefort at FreeBSD org, - - - various code cleanups (Søren) - - prevent long titles from "sticking" in the tasklist (Elijah) [#330671] - - handle sync counter notifications in the compositor (Søren) - - notes/documentation updates (Elijah) - - plug a small leak (Paolo) - - remove a lot of dead code obsoleted by the new edge-resistance - stuff (Björn) [#341561] - - prevent a crash when changing resolution (jylefort) [#340847] - - revert an accessibility module loading workaround from Gnome 2.6 - that has long since been fixed for us in gtk+ (Elijah) [#123372] - -Translations - Francisco Javier F. Serrador (es), Ignacio Casal Quinteiro (gl), - Raivis Dejus (lv), Kjartan Maraas (nb), Funda Wang (zh_CN), Woodman - Tuen (zh_HK), Woodman Tuen (zh_TW) - -2.15.2 -== - -Here's hoping that "third time's a charm." ;-) This release just -fixes the translations-not-included issue. See -http://mail.gnome.org/archives/desktop-devel-list/2006-April/msg00483.html -for more details. - - - Use gnome-autogen.sh like most other modules (Rodney) - -2.15.1 -== - -This release just fixes the control-center build (which depends upon -libmetacity-private). Thanks to Vincent for catching the problem. - - - Include boxes.h in the includes dir (Elijah) [#339708] - -2.15.0 -== - -Thanks to Thomas Thurman, Elijah Newren, Havoc Pennington, Björn -Lindqvist, Gora Mohanty, Alejandro Andres, Andy Morum, Dan Sanders, -Thomas Andersen, Brian Pepple, and Søren Sandmann for improvements in -this release. (Note that "Thomas" below refers to Thomas Thurman if -last name isn't specified) - - - An endless array of compositor updates, not all of which are well - explained in the ChangeLog. ;-) Includes an ability to enable and - disable the compositor at runtime, fixed up wobbling effect and new - explosion effect, special magnification handling, different opacity - for different window types like menus, a way of scaling windows, - handling of foreign displays, improved handling of window - moving/resizing, various code restructuring, special runtime checks - for correct extensions and other compositors, lots of bug fixes, - and possibly other stuff I'm missing or not understanding (Søren) - - Removed "move to another workspace" menu when there are exactly two - workspaces (Thomas) [#151183] - - fix type for compositing_manager schema entry (Elijah) [#335901] - - Port more properties to our async system for code cleanliness and - speed improvements (Havoc, Thomas) - - Lots of code cleanup, even more code cleanup, wow our code was - messy (Björn) [#335177, #337507, #336890, #338359] - - Abstract out the functions for setting/unsetting demands attention - hint and avoid doing it when the window isn't obscured (Thomas) - [#305882] - - Change strings to make them more readable, and more - translatable (Gora) [#335720] - - Reduce compiling warnings -- add a number of casts and change - signedness on a number of variables (Björn) [#336032] - - Fixed broken links in README (Alejandro) [#333303] - - Add a tabbing function, bound to alt-f6 by default, to cycle - through the windows of the current application (Thomas) [#94682] - - Fix the build with --disable-xsync (Andy) [#336605] - - Raise windows on maximize/unmaximize (Dan) [#335076] - - Don't have confirmation windows make applications appear to be - locked when closing via the window list (Dan) [#334899] - - Allow any keybinding pref to be specified either with , a - string, or _list, a list of strings, or both (Thomas) - [#164831] - - warn and ignore if transient_for is set to a non-top-level window - (Thomas Andersen) [#335524] - - Use po/LINGUAS for listing supported languages (Brian) [#337951] - -Translations - Vladimir Petkov (bg), Jordi Mallach (ca), Miloslav Trmac (cs), Rhys - Jones (cy), Lasse Bang Mikkelsen (da), Frank Arnold (de), Kostas - Papadimas (el), Francisco Javier F. Serrador (es), Ivar Smolin (et), Iñaki - Larrañaga (eu), Farzaneh Sarafraz (fa), Ilkka Tuohela (fi), Ignacio Casal - Quinteiro (gl), Ankit Patel (gu), Rajesh Ranjan (hi), Gabor Kelemen (hu), - Satoru SATOH (ja), Alexander Didebulidze (ka), Žygimantas Beručka (lt), - Kjartan Maraas (nb), Michiel Sikkes (nl), Åsmund Skjæveland (nn), Gora - Mohanty (or), Raphael Higino (pt_BR), Duarte Loreto (pt), Mugurel Tudor (ro), - Leonid Kanter (ru), Steve Murphy (rw), Laurent Dhima (sq), Слободан Д. - Средојевић (sr), Daniel Nylander (sv), Theppitak Karoonboonyanan (th), Maxim - Dziumanenko (uk), Clytie Siddall (vi), Funda Wang (zh_CN) - -2.14.3 -== - -This release just reverts the widely hated new focus behavior of Metacity -2.14.x to the behavior found in 2.12.x. Patch came from Ron Yorston. -See http://blogs.gnome.org/view/newren/2006/04/13/0 and -http://mail.gnome.org/archives/release-team/2006-April/msg00025.html for -more details. - - - Add a focus_new_windows gconf key, change the default to 'smart' (2.12 - behavior) and add a 'strict' option to get 2.14 behavior. (Ron) - [#326159] - -Translations - Vladimir Petkov (bg), Miloslav Trmac (cs), Frank Arnold (de), Francisco - Javier F. Serrador (es), Ilkka Tuohela (fi), Tino Meinen (nl), Åsmund - Skjæveland (nn), Raphael Higino (pt_BR), Daniel Nylander (sv) - -2.14.2 -== - -Thanks to Thomas Thurman, Paolo Borelli, Björn Lindqvist, and -Elijah Newren for fixes in this release. - - - Fix constraints bug causing negative width windows and crashes - (Elijah) [#336651] - - Fix window grouping with parent/child windows (Björn) [#336184] - - use g_str_has_prefix instead of a local copy of the function - (Paolo) [#334643] - - Make sure pager can refresh when window is minimized on a different - workspace (Thomas) [#315142] - - Add debugging information for edge resistance (Elijah) - -Translations - - Vladimir Petkov (bg), tangi.bzh (br), Jordi Mallach (ca), Miloslav - Trmac (cs), Rhys Jones (cy), Lasse Bang Mikkelsen (da), Frank - Arnold (de), Mindu Dorji (dz), Kostas Papadimas (el), Francisco - Javier F. Serrador (es), Ivar Smolin (et), Iñaki Larrañaga - Murgoitio (eu), Elnaz Sarbar (fa), Ilkka Tuohela (fi), - Ignacio Casal Quinteiro (gl), Ankit Patel (gu), Rajesh Ranjan (hi) - Gabor Kelemen (hu), Luca Ferretti (it), Satoru SATOH (ja), Vladimer - Sichinava (ka), Žygimantas Beručka (lt), Kjartan Maraas (nb), - Tino Meinen (nl), Kjartan Maraas (no), Gora Mohanty (or), Gnome PL - Team (pl), Evandro Fernandes Giovanini (pt_BR), Duarte Loreto (pt), - Mugurel Tudor (ro), Leonid Kanter (ru), Laurent Dhima (sq), - Слободан Д. Средојевић (sr), Daniel Nylander (sv), Theppitak - Karoonboonyanan (th), Maxim Dziumanenko (uk), Clytie Siddall (vi), - Funda Wang (zh_CN) - -2.14.1 -== - -The only change since 2.14.0 is to remove the "This is the UNSTABLE -branch" warning from configure for those compiling Metacity from -source. - -2.14.0 -== - -Thanks to Ryan Lortie and Thomas Thurman for fixes in this release. - - - Mark the app-running-remotely-window-title string for translation - (Thomas) [#334332] - - Only unmaximise window before freeing if the window is actually - maximised (Ryan) [#333563] - -Translations - Jordi Mallach (ca), Frank Arnold (de), Luca Ferretti (it), Evandro - Fernandes Giovanini (pt_BR), Theppitak Karoonboonyanan (th) - -2.13.144 -== - -Thanks to Jens Granseuer, Kristian, Søren Sandmann, Sylvain -Bertrand, and Thomas Thurman for improvements in this release. - - - Fix build with gcc 2.95 (Jens) [#331166] - - Compositor improvements [remember, still off by default]: add - unused wobbly (un)minimize animation (Kristian), add support for - turning updates on and off (Søren), use sync counter to make - composited resizing tear free (Søren), add ability to unmanage - the screen (Søren), - - Fix build issue with library search order (Sylvain) [#330695] - - Work around buggy application grouping with transient windows - (Thomas) [#328211] - - Prevent setting cycle_windows to keybindings that won't work. - (Thomas) [#329676] - -2.13.89 -== - -Thanks to Søren Sandmann, Thomas Thurman, Thom May, Akira Tagoh, -Luke Morton, and Philip O'Brien for improvements in this release. - - - Compositor improvements [remember that the compositor is still - disabled by default]: New fancy minimize animation that fades in - and out, new debug stuff, various bug fixes (Søren) - - When buggy apps create synthetic button or keypresses without a - timestamp, produce a warning instead of failing an assertion - (Thomas) [#313490] - - Avoid a memory leak when checking which workspace(s) a window is - on (Thomas) [#322059] - - Add a man page for metacity (Thom, Akira, Luke, Philip) [#321279] - - Disable alt-f7 if a window can't be moved, and alt-f8 if it can't - be resized (Thomas) [#328920] - - Allow alt-escape to cancel alt-tabbing, and vice versa (Thomas) - [#141425] - -Translations - Miloslav Trmac (cs), Kjartan Maraas (nb), Tino Meinen (nl), - Kjartan Maraas (no), Слободан Д. Средојевић (sr), Funda Wang (zh_CN) - -2.13.55 -== - -Thanks to Dick Marinus, Christian Kirbach, and Elijah Newren for -improvements in this release. - - - Add a minimize and none double-click-titlebar-action (Dick) - [#300210] - - Prevent a critical warning crasher when switching themes - (Christian) [#327847] - - Fix some uninitialized value problems (Elijah) - - If the mouse enters a window on a different screen, activate the - default window on the new screen (Elijah) [#319348] - -Translations - Jordi Mallach (ca), Adam Weinberger (en_CA), Francisco Javier - F. Serrador (es), Ilkka Tuohela (fi), Ignacio Casal Quinteiro (gl), - Ankit Patel (gu), Kjartan Maraas (nb), Kjartan Maraas (no), Evandro - Fernandes Giovanini (pt_BR), Theppitak Karoonboonyanan (th), Clytie - Siddall (vi), Funda Wang (zh_CN) - -2.13.34 -== - -Thanks to Damien Carbery, Havoc Pennington, Søren Sandmann, -Björn Lindqvist, Kjartan Maraas, Elijah Newren for improvements in -this release. - - - manually define HOST_NAME_MAX if not already defined to fix Solaris - compilation issue (Damien, Havoc) [#326745] - - compositor improvements: port to changes in libcm, do it again, fix - unrefing, make minimize animation update again (all done by Søren) - - make sure an outline border is shown even if a window decoration's - width is 0 (Björn) [#98340] - - correctly handle window alt-tab outlines in showing desktop mode - (Björn) [#98340] - - fix lots of tiny issues spotted by the intel compiler (Kjartan) - [#321439] - - prevent rapidly repeated visual bells from hanging metacity - (Elijah) [#322032] - - more careful error handling of values returned by GConf (Elijah) - [#326615] - - fix various initialization and default issues, especially for - 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 - (Søren) [#327572] - - avoid flashing original-sized window when closing a maximized - window (Elijah) [#317254] - - prevent windows from sometimes getting shoved and smashed by - sliding (and possibly auto-hiding) panels (Elijah) [#327822] - -Translations - Ilkka Tuohela (fi), Ignacio Casal Quinteiro (gl), Tino Meinen (nl), - Funda Wang (zh_CN) - -2.13.21 -== - -Thanks to Damien Carbery, Ray Strode, Søren Sandmann, Elijah -Newren, Jens Granseuer, and Kyle Ambroff for improvements in this -release. - - - Fix Solaris compilation issues (Ray, Damien) [#326281, #326746] - - Merge compositor work from branches to get the beginnings of an openGL - based compositor. Still not ready and thus disabled by default. - (Søren) - - Composite fixes: Only update composite on damage events (Søren), get - non-composite compilation working again (Elijah), Really turn off - draw-in-a-loop (Søren) - - Don't dereference a NULL string (Elijah) [#327013] - - GCC 2.95 fix; remove more C99 style variable initiailizations (Jens) - [#327050] - - Fix accidental overzealous focus holding by the terminal (introduced in - last release) so that windows launched from panel icons, the panel - menu, or global keybindings should get focus now. (Elijah) [#326159] - - If no valid window is found in the MRU list, then set focus to the - desktop window. (Kyle) [#317405] - -Translations - Adam Weinberger (en_CA), Francisco Javier F. Serrador (es), Ankit - Patel (gu), Takeshi AIHANA (ja), Theppitak Karoonboonyanan (th), - Clytie Siddall (vi) - -2.13.13 -== - -Thanks to Jens Granseuer, Björn Lindqvist, and Elijah Newren for -improvements in this release. - - - Remove C99 style variable initiailization (Jens) [#322622] - - Fix a logic error (Björn) [#322149] - - Plug a few leaks (Elijah) [#309178] - - Allow edge resistance at both sides of a window and also when edges - don't overlap but are a single pixel away from doing so (Elijah) - [part of #321905] - - Remove the timeout resistance at screen/xinerama edges (Elijah) - [part of #321905] - - Revert to the old edge resistance behavior for keyboard - movement/resizing based resistance (Elijah) [part of #321905] - - Remove the "pull-away" edge resistance (Elijah) [part of #321905] - - Avoid crashing when visual bell is in use and focus window is - closed (Elijah) [#322031] - - Be more strict about what is considered a valid region with partial - struts (Elijah) [#322070] - - Fix reduced resources resize handling for windows with sizing or - resizing constraints (Elijah) [#325774] - - Fix window outline for minimized windows when using alt-esc - (Elijah) [#325092] - - Make the taskbar less flash happy and fix up some related stacking - issues (Elijah) [#326035] - - More thorough handling of source indication (Elijah) [part of #326041] - - Don't "steal" focus from terminal windows for new window mappings - as the difference in usage between terminals and other apps seems - to suggest this difference in treatment. See bug #326159 for - details, feedback welcome (Elijah) [#326159] - - Add a raise on click option, basically only because all the major - distros are patching it in anyway (though each and every one of - them has bugs in their implementations). (Elijah) [#326156] - -Translations - Kjartan Maraas (nb), Kjartan Maraas (no) - -2.13.8 -== - -Thanks to Kang Jeong-Hee and Elijah Newren for improvements in this -release. - - - Fix some compilation warnings and issues (Kang) - - Escape the title since it is going to be treated as Markup (Elijah) - [#324846] - - Make the workspace switcher work with dual-head (non-xinerama) - setups (Elijah) [#319423] - -Translations - Ilkka Tuohela (fi), Ankit Patel (gu), Kang Joeng-Hee (ko) - -2.13.5 -== - -Thanks to Davyd Madeley, Kjartan Maraas, and Björn Lindqvist for -improvements in this release. - - - Make a debugging message actually correspond to the code (Björn) - [#322051] - - Make the wireframe a bit slimmer (Kjartan) [#320051] - - Display hostname in titlebar for remote X clients (Davyd) [#322202] - -Translations - Miloslav Trmac (cs), Adam Weinberger (en_CA), Ankit Patel (gu), - Kjartan Maraas (nb), Kjartan Maraas (no), Marcel Telka (sk) - -2.13.3 -== - -This is a special edition release just for gicmo, code-named 'elijah, -please do a release so magic seb can bring it to me'. It fixes a -number of issues due to the major constraints changes found since the -last release. - -Thanks to Davyd Madeley and Elijah Newren for improvements in this release. - - - Differentiate between movement towards an edge and movement away from - one for edge-resistance. Pick smaller constants for movement away from - an edge (Elijah) - - Use GPOINTER_TO_INT() macro instead of cast to allow compilation on - 64-bit architectures without warning (Davyd) - - compute the frame geometry due to maximization only after actually - maximizing (Elijah) [#321902] - - add some developer documentation on updating struts, workareas, regions, - and edges (Elijah) - - When updating the xinerama due to placement, update which - maximal/spanning rect set to use as well (Elijah) [#322068] - - Relax the partially onscreen constraint to allow the titlebar to touch - the bottom panel in order to make the new constraints code function the - same as the old version (Elijah) [#322071] - - Don't allow removing a window from maximized or fullscreened state to - place the titlebar under the top panel (Elijah) [#322075] - -Translations - Vladimir Petkov (bg), Francisco Javier F. Serrador (es), Ignacio Casal - Quinteiro (gl), Takeshi AIHANA (ja), Theppitak Karoonboonyanan (th) - -2.13.2 -== - -This release just contains a merge of all the changes on the -constraints_experiments branch. - -Thanks to Havoc Pennington for reviewing the gargantuan patch and -suggesting lots of little fixes for making it better, to Rob Adams and -Soeren Sandmann for grilling me on how some of the difficult internals work --- allowing me to improve the documentation, to Olav Vitters for finding an -easy-to-fix crasher bug in early testing and for repeatedly extending my -deadline for switching from working on Metacity to Bugzilla, to Ray Strode -for finding two crashers and fixing one of them in early testing, to Bryan -Clark for usability advice, to Davyd Madeley and Christian Kellner for -testing Xinerama stuff, to Sebastien Bacher for packaging an early version -and finding some obscure bugs (that I unfortunately still can't duplicate -and will probably still need to fix once I can), - -Bugs fixed: - unfiled - constraints.c is overly complicated[1] - unfiled - constraints.c is not robust when all constraints cannot - simultaneously be met (constraints need to be prioritized) - unfiled - keep-titlebar-onscreen constraint is decoration unaware (since - get_outermost_onscreen_positions() forgets to include - decorations) - unfiled - keyboard snap-moving and snap-resizing snap to hidden edges - 86644 - resize should have a shift option like move does - 109553 - gravity w/ simultaneous move & resize doesn't work - 113601 - maximize vertical and horizontal should toggle and be - constrained - 122196 - windows show up under vertical panels - 122670 - jerky/random resizing of window via keyboard[2] - 124582 - keyboard and mouse snap-resizing and snap-moving erroneously - moves the window multidimensionally - 136307 - don't allow apps to resize themselves off the screen (*cough* - filechooser *cough*) - 142016, 143784 - windows should not span multiple xineramas unless - placed there by the user - 143145 - clamp new windows to screensize and force them onscreen, if - they'll fit - 144126 - Handle pathological strut lists sanely[3] - 149867 - fixed aspect ratio windows are difficult to resize[4] - 152898 - make screen edges consistent; allow easy slamming of windows - into the left, right, and bottom edges of the screen too. - 154706 - bouncing weirdness at screen edge with keyboard moving or - resizing - 156699 - avoid struts when placing windows, if possible (nasty a11y - blocker) - 302456 - dragging offscreen too restrictive - 304857 - wireframe moving off the top of the screen is misleading - 308521 - make uni-directional resizing easier with alt-middle-drag and - prevent the occasional super annoying resize-the-wrong-side(s) - behavior - 312007 - snap-resize moves windows with a minimum size constraint - 312104 - resizing the top of a window can cause the bottom to grow - 319351 - don't instantly snap on mouse-move-snapping, remove - braindeadedness of having order of releasing shift and - releasing button press matter so much - - [1] fixed in my opinion, anyway. - [2] Actually, it's not totally fixed--it's just annoying - instead of almost completely unusable. Matthias had a - suggestion that may fix the remainder of the problems (see - http://tinyurl.com/bwzuu). - [3] This bug was originally about not-quite-so-pathological - cases but was left open for the worse cases. The code from - the branch handles the remainder of the cases mentioned in - this bug. - [4] Actually, although it's far better there's still some minor - issues left: a slight drift that's only noticeable after - lots of resizing, and potential problems with partially - onscreen constraints due to not clearing any - fixed_directions flags (aspect ratio windows get resized in - both directions and thus aren't fixed in one of them) - -New feature: - 81704 - edge resistance for user move and resize operations; in - particular 3 different kinds of resistance are implemented: - Pixel-Distance: window movement is resisted when it aligns with an - edge unless the movement is greater than a threshold number of - pixels - Timeout: window movement past an edge is prevented until a certain - amount of time has elapsed during the operation since the first - request to move it past that edge - Keyboard-Buildup: when moving or resizing with the keyboard, once a - window is aligned with a certain edge it cannot move past until the - correct direction has been pressed enough times (e.g. 2 or 3 times) - -Major code changes: - - constraints.c has been rewritten; very few lines of code from the old - version remain. There is a comment near the top of the function - explaining the basics of how the new framework works. A more detailed - explanation can be found in doc/how-constraints-works.txt - - edge-resistance.[ch] are new files implementing edge-resistance. - - boxes.[ch] are new files containing low-level error-prone functions - used heavily in constraints.c and edge-resistance.c, among various - places throughout the code. testboxes.c contains a thorough testsuite - for the boxes.[ch] functions compiled into a program, testboxes. - - meta_window_move_resize_internal() *must* be told the gravity of the - associated operation (if it's just a move operation, the gravity will - be ignored, but for resize and move+resize the correct value is needed) - - the craziness of different values that - meta_window_move_resize_internal() accepts has been documented in a - large comment at the beginning of the function. It may be possible to - clean this up some, but until then things will remain as they were - before--caller beware. - - screen and xinerama usable areas (i.e. places not covered by - e.g. panels) are cached in the workspace now, as are the screen and - xinerama edges. These get updated with the workarea in - src/workspace.c:ensure_work_areas_validated() - -Translation - Michiel Sikkes (nl) - -2.13.1 -== - -Thanks to Philip O'Brien, Kjartan Maraas, and Aidan Delaney for -improvements in this release. - - - add handling for META_PREF_CURSOR_THEME and META_PREF_CURSOR_SIZE - for more complete debug info (Philip) [#318976] - - Remove possible g_source leak in #ifdef'd out code, in case anyone uses - it in the future (Kjartan) [#320050] - - Changed the 'minimized' field of the MetaTabEntry struct to 'hidden' - (Aidan) [#168455] - -Translations - Miloslav Trmac (cs), Francisco Javier F. Serrador (es), Takeshi AIHANA (ja), - Erdal Ronahi (ku), Theppitak Karoonboonyanan (th) - -2.13.0 -== - -Thanks to Björn Lindqvist, Kjartan Maraas, Søren Sandmann, -Elijah Newren, Ross Cohen, and Muktha for improvements in this release -since 2.12.1. - - - Mave ancestors come along with the transient when moving the window from - one workspace to another (Björn) [#314977] - - Fix the workspace switcher tabpopup to display the right windows and to - fix the pick-a-new-window-to-focus algorithm in order to not select - windows that aren't showing (Björn) [#170475] - - Fix a couple memory leaks (Kjartan, Søren, Elijah) [#313030] - - Make alt-esc (the "switch between windows immediately" keybinding) - actually show minimized windows too (Ross) [#107072] - - Make alt-esc consistent with alt-tab by leaving stacking of unselected - windows unchanged (Ross) [#314285] - - Clarify the meaning of the auto_raise preference (Elijah) [#312421] - - Fix a crash that occurs when removing some virtual desktops and windows - happen to be on those desktops (Elijah) [#318306] - - Make the unfocussed Simple window border visible with high contrast - inverse theme (Muktha) [#121361] - - Fix edge snapping for multi-screen (non-xinerama) setups (Elijah) - [#319425] - -Translations - Vladimir Petkov (bg), Kostas Papadimas (el), Adam Weinberger (en_CA), - Ivar Smolin (et), Michiel Sikkes (nl), Marcel Telka (sk), Funda - Wang (zh_CN) - -2.12.1 -== - -Thanks to Ray Strode, Havoc Pennington, and Elijah Newren for -improvements in this release. - - - Truncate ridiculously long titles to avoid crashing or letting the - pager crash (Ray, Havoc, Elijah) [#315070] - - Get the tabbing window outline to work with gtk+ 2.8.4 again - (Elijah) [#317528] - -Translations - Mahay Alam Khan (bn), Francisco Javier F. Serrador (es), Ivar Smolin (et), - Iñaki Larrañaga Murgoitio (eu), Luca Ferretti (it), Christian Rose (sv), - Clytie Siddall (vi), Funda Wang (zh_CN) - -2.12.0 -== - -Thanks to Brent Smith for finding the crasher in the release candidate! - - - Fix an uninitialized variable problem causing crashes (Brent) [#315000] - -Translations - Bryn Salisbury (cy), Hendrik Richter (de), Christophe Merlet (RedFox) (fr), - Ignacio Casal Quinteiro (gl), Norayr Chilingaryan (hy), Young-Ho Cha (ko), - Žygimantas Berucka (lt), Michiel Sikkes (nl), Leonid Kanter (ru), Danilo - Šegan (sr), Baris Cicek (tr) - -2.11.3 -== - -Thanks to Björn Lindqvist and Elijah Newren for improvements in -this release. - - - Check for the right versions of glib and gtk+ (Björn) [#314116] - - Avoid obscuring centered-on-desktop windows which are denied focus - (Elijah) [#313234] - -Translations - Vladimir Petkov (bg), Jordi Mallach (ca), Kostas Papadimas (el), - Ivar Smolin (et), Gabor Kelemen (hu), Mohammad DAMT (id), Duarte - Loreto (pt), Mugurel Tudor (ro), Laurent Dhima (sq), Maxim - Dziumanenko (uk) - -2.11.2 -== - -Thanks to Elijah Newren, Jaap Haitsma, Ray Strode, and Brent Smith for -improvements in this release. - - - Fix an easy to trigger crasher in 2.11.1 caused by unneeded - debugging spew (Elijah) [#311819] - - Make sure that Metacity dialogs have icons (Jaap) [#309876] - - Fix an infinite restacking flicker loop in sloppy and mouse focus - with fullscreen windows (Elijah) [#311400] - - Change default theme from Simple to Clearlooks (Elijah) - - Vastly improve the behavior of keyboard move/resize and edge - snapping (Ray) [#310888] - - Remove a duplicate string (Brent) [#309774] - -Translations - Yuval Tanny (he), Gnome PL Team (pl), Raphael Higino (pt_BR), - Chao-Hsiung Liao (zh_TW) - -2.11.1 -== - -Thanks to Elijah Newren, Ken Harris, Matthias Clasen, Christian -Persch, and Billy Biggs for improvements in this release. - - - Fix a miscoloring of parts of the titlebar introduced in the last - unstable release (Elijah) [follow-up to #169982] - - Provide a more lenient threshold for drawing rounded corners (Ken) - [#122065] - - Make the Xcursor changes in the last unstable release effective - (Matthias) [follow-up to #308106] - - Revert the _NET_ACTIVE_WINDOW behavior change made in the 2.9.x - unstable series; activation includes changing a window to the - current workspace again (Elijah) [reversion of #128380] - - Restore original window size if the window was maximized upon - withdrawing it (Elijah, Christian) [#137185] - - Fix a raising bug with a window that has more than one child window - (Elijah, Billy) [part of #307875] - - Try to place windows denied focus near the focus window and fix a - xinerama bug with the placement (Elijah) [part of #307875] - - Avoid modal dialogs being obscured in somewhat pathologically - strange circumstances that Eclipse seems to be good at triggering - (Elijah) [part of #307875] - -Translations - Miloslav Trmac (cs), Kostas Papadimas (el), Adam Weinberger (en_CA), - Francisco Javier F. Serrador (es), Ilkka Tuohela (fi), Christophe - Merlet (RedFox) (fr), Ignacio Casal Quinteiro (gl), Ankit - Patel (gu), Yair Hershkovitz (he), Takeshi AIHANA (ja), Kjartan - Maraas (nb), Kjartan Maraas (no), Marcel Telka (sk), Theppitak - Karoonboonyanan (th), Clytie Siddall (vi), Funda Wang (zh_CN) - -2.11.0 -== - -This release contains all fixes up to Metacity 2.10.2 plus some new goodies. - -Thanks to Matthias Clasen, Aivars Kalvans, Björn Lindqvist, and -Andrew Johnson for improvements in this release. - - - React to cursor theme changes (Matthias) [#308106] - - Plug a small leak with xinerama information (Aivars) [#307884] - - Split up main() into more manageable chunks and make use of GOpt - (Björn) [#305331] - - Speed up vertical gradients (Andrew) [#169982] - -Translations - Hendrik Richter (de), Ivar Smolin (et), Ignacio Casal - Quinteiro (gl), Clytie Siddall (vi) - -2.10.2 -== - -Thanks to Billy Biggs, Greg Hudson, Elijah Newren, Ray Strode, Ryan -Lortie, and Soeren Sandmann for improvements in this release. - - - Makes metacity a bit faster when dragging windows around (Soeren) [#141813] - - Fix simple memory error, using the address of a local variable as a - hash key (Ryan) [#307209] - - Fix a small leak in the case of a SYNC_COUNTER property value and - HAVE_XSYNC not defined (Ryan) [#307214] - - Cleanup font data when done with it (Ray) [#306720] - - If the window has a modal transient which is being unmanaged, don't - focus it (Elijah) [#305362] - - Make sure window position is calculated correctly for reconfigure - requests when part of the XWindowChanges structure is uninitialized - (Greg) [#305257] - - Add a resize popup when resizing constrained windows (Ray) [#305564] - - Don't accidentally treat maximize vertically as maximize in both - directions (Elijah) [#302204] - - Put all transients of the new window, if any exist, in the - calc_showing queue (Elijah, Billy) [#303284] - -Translations - Kostas Papadimas (el), Priit Laes (et), Pauli Virtanen (fi), Ignacio - Casal Quinteiro (gl), Theppitak Karoonboonyanan (th), Canonical - Ltd (xh), Woodman Tuen (zh_TW) - -2.10.1 -== - -This is a stable release to coincide with the release of Gnome 2.10.0. - -Thanks to Dan Winship and Lex Hider for fixes in this release. - - - Make sure the "Close" button has the focus in the - buggy-session-management-applications-warning dialog instead of the - table (Dan) [#172703] - - add doc/code-overview.txt and doc/how-to-get-focus-right.txt to the - distributed files (Lex) [#170519] - -Translations - Adam Weinberger (en_CA), Christopher Orr (en_GB), Elnaz Sarbar (fa), - Gabor Kelemen (hu), Jyotsna Shrestha (ne), Steve Murphy (rw), - Baris Cicek (tr), Canonical Ltd (xh) - -2.10.0 -== - -This is a stable release to coincide with the release of Gnome 2.10.0. -The only difference between this version and 2.9.34 is some -translation updates. - -Translations - Vladimir Petkov (bg), Gabor Kelemen (hu), Žygimantas Berucka (lt), - Reinout van Schouwen (nl), Mugurel Tudor (ro), Danilo Šegan (sr), - Woodman Tuen (zh_TW) - -2.9.34 -== - -This is an unstable release to coincide with the release of Gnome -2.10.0 release candidate 1 (2.9.92). - -Thanks to Aidan Delaney, Elijah Newren, and Joe Marcus Clarke for -fixes in this release. - - - Fix crash that occurs when stupid apps claim that a window is its - own parent (Elijah, Joe) [#168207] - - Prevent the visual bell from changing the focus window (Elijah) - [#123366] - - Make sure that icons in the alt-tab popup are dimmed for all hidden - windows, not just minimized ones (Aidan) [#168455] - -Translations - Elnaz Sarbar (fa), Ankit Patel (gu), Luca Ferretti (it), - Reinout van Schouwen (nl), Gnome PL Team (pl), - Alexandre Folle de Menezes (pt_BR) - -2.9.21 -== - -This is an unstable release heading towards Gnome 2.10. Since there -have been an awful lot of fixes since Gnome 2.10 Beta 2, we are hoping -to get an extra week of wider testing of all these changes before hard -code freeze. - -Thanks to Aidan Delaney, Crispin Flowerday, Elijah Newren, and Joe -Marcus Clarke for fixes in this release. - - - Make sure we get a valid timestamp if one doesn't come with the - _NET_ACTIVE_WINDOW message (Elijah, Crispin) [#166728] - - Avoid sending CurrentTime to our XSetInputFocus wrappers, but - handle it better in case we miss any cases (Elijah) [#166732] - - Remove useless function call (Aidan) [#166730] - - Avoid new windows being obscured by the focus window and thus - possibly lost (Elijah) [#166524] - - Don't unconditionally place not-to-be-focused windows, such as - splashscreens, below the focus window (Elijah) [#167042] - - Raise the ancestor of a window instead of the window itself - (Elijah) [#166894] - - Cover half a dozen issues needed to fix a variety of rare timestamp - bugs (Elijah) [#167358] - - Fix a possible crash on logout (Joe) [#167935] - - Fix an obscure xinerama placement bug with windows that are too - large to fit in the workarea in both dimensions (Elijah) [#166757] - - Ignore all focus and focus-stealing-prevention code in - meta_window_show when not showing the window for the first time - (Elijah) [#167199] - - when receiving a _NET_ACTIVE_WINDOW message, switch to the desktop - where the window is located before activating instead of moving the - window to the current desktop (Elijah) [#128380] - - Handle _NET_CURRENT_DESKTOP messages that come with timestamps - (Elijah) [#161361] - - Handle keynav vs. mousenav in mouse and sloppy focus modes (Elijah) - [#167545] - -Translations - Jordi Mallach (ca), Martin Willemoes Hansen (da), - Kostas Papadimas (el), David Lodge (en_GB), - Francisco Javier F. Serrador (es), Tõivo Leedjärv (et), - Christophe Merlet (RedFox) (fr), Takeshi AIHANA (ja), - Young-Ho, Cha (ko), Kjartan Maraas (nb), Michiel Sikkes (nl), - Kjartan Maraas (no), Duarte Loreto (pt), Leonid Kanter (ru), - Marcel Telka (sk), Laurent Dhima (sq), Maxim Dziumanenko (uk) - -2.9.13 -== - -This is an unstable release to coincide with the release of Gnome -2.10.0 Beta 2 (2.9.91). - -Thanks to Elijah Newren, Balamurali Viswanathan, Stephane Loeuillet, -Benjamin Kahn, Garrett (LeSage?), Jose Moya, Dave Ahlswede, Arvind -Samptur, John Paul Wallington, Tim Herold, Muktha Narayan, Sinisa -Segvic, Owen Taylor, Crispin Flowerday, "RHEL-3", KWin, and Google for -improvements in this release. - - - Refuse to focus a window with a modal transient, and focus the - transient instead (Elijah) [#164716] - - Make sure we get gconf notifications about the terminal command - changing (Balamurali) [#160934] - - Specify encoding of src/metacity.desktop.in (Stephane) [#151850] - - New 48x48 default icon (Benjamin, Garrett) [#160660] - - Add man pages for metacity-window-demo and metacity-theme-viewer - (Jose, Dave) [#143513] - - Fix minimized window display in workspace switcher after relogin - with a saved session (Elijah) [#164677] - - Ignore sticky windows for non-active workspaces (Elijah) [#165259] - - Don't wireframe when accessibility is on, it apparently causes a - desktop wide freeze. (Arvind) [#159538] - - Keep tooltip on screen horizontally for xinerama (John) [#165261] - - Stick and unstick transients with their parent automatically - (Elijah) [#152283] - - Shaded windows should not show up in pagers (Elijah) [#165377] - - Treat splashscreens same as other windows for stacking (Elijah) - [#165243] - - Plug a pair of leaks (Elijah) [#165378] - - Take into account the appropriate list of windows when placing a - new one (Elijah) [#165381] - - Correct misleading and inaccurate wording (Elijah) [#165380] - - Handle xcomposite pkgconfig version regression (Tim) [#149368] - - Make the warn-about-buggy-session-management-apps dialog be sticky - (Elijah) [#164745] - - Fix the problem with fullscreen windows on a different xinerama - monitor not staying on top ("RHEL-3") [#156511] - - Make the unfocussed title bar distinguishable in cases where it - otherwise isn't for the Atlanta, Simple, and Bright themes (Muktha) - [#125291] - - Correct the stacking when returning from fullscreen mode (Elijah) - [#165718] - - Focus parents of dismissed transient windows in preference to the - window that most recently had keyboard focus (Elijah) [#157360] - - Make sure window->border_only is initialized so we don't get random - windows without decorations (Elijah, Sinisa, Owen) [#145131] - - Add period to the end of reduced_resources' description (Dave) - [#165780] - - If activation requests are too old, set the demands_attention hint - instead of actually activating (Elijah, Crispin) [#166395] - - Ignore xconfigurerequest events for stacking when it should be safe - to do so (Elijah, Crispin, KWin, Google) [#166395] - - Set a _METACITY_VERSION property (a utf8 string) on the WM check - window (Elijah) [#165350] - -Translations - Vladimir Petkov (bg), Miloslav Trmac (cs), Frank Arnold (de), - Adam Weinberger (en_CA), David Lodge (en_GB), - Francisco Javier F. Serrador (es), Pauli Virtanen (fi), - Young-Ho, Changwoo Ryu (ko), Žygimantas Berucka (lt), - Kjartan Maraas (nb), Kjartan Maraas (no), Duarte Loreto (pt), - Marcel Telka (sk), Christian Rose (sv), - Theppitak Karoonboonyanan (th) - -2.9.8 -== - -This is a brown paper bag release to cover up the crash I introduced -in version 2.9.5. Thanks to Sebastien Bacher and the bleeding edge -Ubuntu users for quickly catching the occasional crash that my fix in -#123576 could cause, and for verifying that the patch I made fixed -this issue (I couldn't duplicate). - - - Don't forget to initialize display->grab_old_window_stacking - [#165093] - -2.9.5 -== - -This is an unstable release to coincide with the release of Gnome -2.10.0 Beta 1 (2.9.90). - -Thanks to Vincent Noel, Elijah Newren, and John Paul Wallington for -fixes in this release. - - - Restore original stacking when aborting an alt-esc window switch - operation (Elijah) [#123576] - - Fix vertical maximization for second screen (John) [#163420] - - Show labels in bold for windows that demand attention (Vincent) - [#164590] - - In the tab task switcher popup, dim the window icon and put its - name between brackets when the window is minimized (Vincent) - [#136666] - - Correct highlighting of windows in workspace switcher popup - (Elijah) [#163450] - -Translations - zh_CN (Funda Wang), nb (Kjartan Maraas), nn (Kjartan Maraas), de - (Frank Arnold) - -2.9.3 -== - -This is an unstable release to coincide with the release of Gnome 2.9.4. - -Thanks to Leena Gunda, Thomas Fitzsimmons, and mild7 users sourceforge -net, and Elijah Newren for fixes in this release. - - - Don't focus the panel on click (Elijah) [#160470, and others] - - Make sure the save session dialog appears focused (Elijah) [#162983] - - Correctly restore size of window when double clicking the titlebar - to unmaximize (Leena) [#161236] - - Install schema data from builddir not srcdir (Thomas) [#161417] - - Provide more documentation to make it easier for people to - contribute to Metacity (Elijah) [#162646] - - Allow users to move the window around immediately after - double-clicking to shade (Elijah) [#90290] - - Focus windows that manually position themselves too (Elijah) [#107347] - - Don't show window menu if all options are invalid (Elijah) [#148915] - - Exclude windows with skip_taskbar hint set from the alt-tab list; - they'll appear in the ctrl-alt-tab list instead. (mild7 users - sourceforge net) [#106249] - - Wrap XSetInputFocus to make display->expected_focus_window more - reliable (Elijah) [#154598] - - Remove conflict between windows on multiple workspaces and hidden - being a global quantity (Elijah) [#156182] - -Translations - es (Francisco Javier F. Serrador), sv (Christian Rose), cs (Miloslav - Trmac), ja (Takeshi AIHANA) - -2.9.2 -== - -This is an unstable release to coincide with the release of Gnome 2.9.3. - -Thanks to Alex Duggan, ash AT contact bg, Elijah Newren, and Baptiste -Mille-Mathias for fixes in this release. - - - Add a missing period at the end of a sentence (Baptiste) [#158210] - - When snap-moving don't snap to hidden windows, such as transients - of minimized windows (Elijah) [#157180] - - Focus the desktop when showing it (Elijah) [#159257] - - Remove deprecated capplet (Alex, ash) [#160753] - -Translations - da (Martin Willemoes Hansen), bg (Alexander Shopov), en_CA (Adam - Weinberger) - -2.9.1 -== - -This is an unstable release heading towards Gnome 2.10, released a -little late for Gnome 2.9.2 but there weren't many changes anyway this -time... - -Thanks to Benjamin Kahn, Marco Pesenti Gritti, James Henstridge, and -Vincent Untz for fixes/features in this release. - - - gnome-panel-screenshot was renamed to gnome-screenshot (Vincent) [#157529] - - Update build stuff (use newer automake, etc.) (James) - - Fix build out of src directory (Marco) [#158325] - - Use a better default application icon (Benjamin) [#160373] - -Translations - da (Martin Willemoes Hansen), fr(Christophe Merlet, Baptiste - Mille-Mathias), lt(Žygimantas Berucka), ja(Takeshi AIHANA) - -2.9.0 -== - -This is an unstable release heading towards Gnome 2.10. - -Thanks to Rob Adams, Anders Carlsson, Elijah Newren, Soeren Sandmann, -and Vincent Untz for fixes and features in this release. - - - Add a keybinding to launch a terminal (Vincent) [#154232] - - Correct the requested number of keycodes (Rob) [#155247] - - Add tracker bugs to rationales.txt file - - Make the "showing desktop" mode be per-workspace instead of - per-screen. (Elijah) [#142198] - - Don't try to use an ARGB visual at all if the depth isn't - 32-bit. This caused major slowdowns with Composite - enabled. (Anders) - - Fix the modifier key breakage introduced by an Xorg - change. (Soeren) [#151554] - - Update _NET_WM_STATE_HIDDEN so the pager on the panel will know - whether to display windows as visible or hidden (Elijah) [#105665] - - Fix the alt-tab order--if the most recently used window is not - focused, start alt tabbing with that window instead of the one - after it (Elijah) [#156251] - - Don't lower newly mapped windows when they're denied focus if they - are transients of the focused window. Instead, defocus the - currently focused window (Elijah) [#151996] - - Re-enable focus stealing prevention (Elijah) - -Translations - es(Francisco Javier F. Serrador), sq(Laurent Dhima), sr(Danilo Šegan), - cs(Miloslav Trmac), en_CA(Adam Weinberger), en_GB(David Lodge) - -2.8.6 -== - -This is a stable release for Gnome 2.8.1. - -Thanks to the Ken Harris, Kjartan Maraas, and the tireless efforts of -Elijah Newren for fixes in this release. - -Fixes - * Ensure the correct window is focused when minimizing (Elijah) - * Fix keynav with mouse focus (Elijah) - * Fix several race conditions in window focusing (Elijah) - * Focus the top window when lowering by frame click (Ken) - * Fix some compiler warnings (Kjartan) - * Fix some valgrind-reported errors (Elijah) - * Fix some potential issues with autoraising windows (Elijah) - -Translations - * en_CA(Adam Weinberger), it(Luca Ferretti) - -2.8.5 -== - -This is a stable release for Gnome 2.8. Only translations and some -new developer documentation were added since the last unstable release. -This release boasts improved standards-compliance and a number of -bug fixes since the last stable release. - -Translations - - * ar(Abdulaziz Al-Arfaj), cs(Miloslav Trmac), cy(Dafydd Harries), - en_GB(David Lodge), fr(Christophe Merlet (RedFox)), - nn(Åsmund Skjæveland), or(Gora Mohanty), - pr_BR(Gustavo Noronha Silva), ro(Mugurel Tudor), - th(Paisa Seeluangsawat), tr(Baris Cicek), zh_TW(Woodman Tuen) - -2.8.4 -== - -This release features a number of bug fixes, and also the disabling of -the focus-stealing-prevention code (we're entering hard code freeze in -Gnome so it's too late to fix the remaining issues, especially since -it requires several patches to modules other than Metacity). - -Thanks to Havoc Pennington, Soeren Sandmann, Elijah Newren, and Rich -Wareham for fixes in this release - -Fixes - * track the last_xor_rect, for wireframe painting (Havoc) - * Move wireframe code before grab is released to prevent endless - loops with fullscreen windows. (Soeren) - * Make dialogs that Metacity shows follow focus-stealing-prevention - conventions. (Elijah; part of #149028) - * add render extension check to the display, don't build the - compositing manager by default, use an ARGB visual when available - for the window frame (Rich Wareham; various tweaks added later by - Havoc) - * move the have_xrender variable initialization up in the file since - it can be set as part of composite check (Havoc) - * make argb stuff compile, add some code from xcompmgr (Havoc) - * fix an assertion failure that would occur after increasing the - number of workspaces; fix stacking order when a window is denied - focus (Elijah; #150615) - * disable some compositor code that wasn't working, don't grab the - server during repaint, various set_background fixes and - refactoring (Havoc) - -Translations - * az(Metin Amiroff), bs(Kemal Sanjta), ca(Jordi Mallach), - el(Kostas Papadimas), es(Francisco Javier F. Serrador), - eu(Iñaki Larrañaga Murgoitio), fi(Pauli Virtanen), - nb(Kjartan Maraas), sq(Laurent Dhima), uk(Maxim Dziumanenko) - - -2.8.3 -== - -Some important bug fixes in this release, including somy a11y bugs, -and a compile issue on Solaris. - -Thanks to Rob Adams, Bill Haneman, Peter O'Shea, Mike Castle, Soeren -Sandman, Elijah Newren, and Havoc Pennington for fixes in this -release. - -Fixes - * Adjust the MRU list when preventing focus stealing (Elijah) - * Ensure that we maintain a focus window when switching workspaces - in mouse focus mode (Elijah) - * Some improvements in the showing desktop mode, and window - activation (Elijah) - * Make sure cursors changes are handled correctly (Havoc, Soeren) - * Some fixes to the window menu (Rob) - * Fix a compile issue on Solaris (Peter, Mike) - * Allow struts to go past the middle of the screen, provided there's - a gap between them, fixing an issue with gnome magnifier (Bill) - -Translations - * fi (Pauli Virtanen), ja (Takeshi AIHANA), ko (Young-Ho, Cha), - pl (Gnome PL Team), ru (Dmitry G. Mastrukov), sr (Danilo Šegan), - tk (Gurban M. Tewekgeli), zh_CN (Funda Wang) - -2.8.2 -=== - -Many bugfixes and better support for the freedesktop.org EWMH spec. - -Thanks to Rob Adams, Anders Carlsson, Elijah Newren, Soeren Sandmann, -Emil Soleyman-Zomalan, Michael Terry, and Jeff Waugh for fixes in this -release. - - - set titlebar_uses_system_font = false (it was ugly) - - make naming for "move a window"/"move the window"/"move window" - more consistent (fixes #142235) - - Add trailing quotes to keybinding explanation text. - - support for EWMH update counter spec & add compensation events - when events are ignored. (fixes #143333 and #109362) - - Fix focus bugs: remove race condition on window close/minimize - (#131582), make focus choice consistent for each focus mode - (#135810), choose correct focus window when "un-showing the - desktop (#144900), make sure correct window is focused when using - the workspace switcher (#120100). - - Use meta_topic instead of meta_warning when failing to connect to - a session manager; reduces metacity verbosity. (fixes #136218) - - Make meta_window_delete take a timestamp, and be sure to pass it - one. - - Add support for EWMH _NET_WM_USER_TIME spec. This enables part of - preventing focus stealing. (bug #118372) Also fix bug with - windows not being focused on unminimizing caused by original - patch. (also bug #118372) - - Fix some support for EWMH hints, and fix USER_TIME support to - include the DEMANDS_ATTENTION hint. Also includes some code for - implementing _NET_RESTACK_WINDOW and _NET_MOVERESIZE_WINDOW, but - this is disabled pending feature thaw. - -2.8.1 -=== - -Thanks to Olivier Crete, Jarrod Johnson, Neil Muller, Elijah Newren, -Mark McLoughlin, Rob Adams, and foser AT gentoo.org for fixes in this -release. - - - make the --enable-xinerama switch work properly - - prevent unwanted grab op from occurring - - don't down-size nitems from a gulong to an int - - add a value type check for the visual/audible bell gconf settings - - make the no sm support warning resizable - - more translations - -2.8.0 -=== - -No code changes in this release, but some new translations. - -2.7.1 -=== - -Thanks to Rob Adams for fixes in this release. - - - bug #122016 - fix a focus race - - Change move_to_workspace_left/right/up/down keybindings to - arrow to avoid conflicting with new - keybindings in spacial nautilus. - - fix dialog stacking order issues so e.g. panel properties - dialog is above the panel - -2.7.0 -=== - -First unstable release tarball for GNOME 2.6. - -Thanks to Anders Carlsson, Elijah Newren, Rob Adams, James Cape, -Thomas Fitzimmons, Calum Benson for fixes in this release. - -2.6.2 -=== - -Thanks to Yukihiro Nakai, Rached Ben Mustapha, Gwenole Beauchesne, -Padraig O'Briain, Laurent Vivier, Rob Adams for contributions to this -release. - - - fix to repaint after resize always, so on maximize - and theme changes we get things drawn properly - - fix a compile issue on HPUX - - fix translations of metacity-message output - - fix to update window icons when they change - - put a limit on number of characters displayed in - window titles during Alt+tab - - fix configure check for Xrandr - - fix 64-bit bug in property reading that broke - things badly on 64-bit - - don't move focus when clicking close button on a window - - fix a crash in getting pixmap icons - - spawn dialogs and child processes on the proper - screen in multihead situations - - if the focus gets set to None, set it back to - something sane - - load accessibility modules and set accessibility roles - - fix hang after displaying warning dialogs - - fix a memory corruption when sticking/unsticking windows - that lead to a frequent crash and windows appearing - in Alt+tab improperly - - fix some handling of partial-width panel struts - - more translations - -2.6.1 -=== - - - rebuild with fixed glib-gettext.m4 - -2.6.0 -=== - - - some additional translations - -2.5.5 -=== - - Thanks to Rob Adams, Arvind Samptur, Andreas Volz, Ray Strode, John - Paul Wallington, Soeren Sandmann for contributions to this release. - And as always thanks to the translators. - - - fix aspect ratio handling - - fix "shake loose" functionality for maximized windows - - handle Xrandr size changes properly again - - fix fullscreen window detection - - fix workspace name handling - - don't steal button press events on root window - - nuke metacity.spec due to nonmaintenance - - allow too-large-for-screen windows to move their titlebar offscreen - - keep an MRU list of windows per-workspace and use it to focus - the next window when the focused window disappears - - fix cursor when moving - - improve appearance of opaque resize - - make BELOW window state work - - fix a crash when gdk_pixmap_foreign_new() returned NULL - -2.5.3 -=== - - Thanks to Jordi Mallach, Padraig O'Briain, Rob Adams, Julio Merino, - Ben Jansens, Jurg Billeter, Ray Strode, marcus@freebsd.org, James - Laska, for contributions to this release. Thanks also to - all the tireless translators. - - - fixups to .desktop file - - activate window prior to grab end, avoiding - extra focus events - - add support for partial-width panels (fixes corner panel - and xinerama window position constraints) - - added keybinding to toggle window as "always on top" - - support --disable-schemas-install option to configure - - destroy support for legacy GNOME 1.x hints; metacity - no longer works with GNOME 1.x - - disable raise-on-click for mouse focus modes - - fix bug that broke many Javascript popup menus with mozilla - - allow "shaking loose" maximized windows, to move them - between Xinerama heads or whatever - - honor desktop-wide double click timeout - - handle window placement properly for windows that - start out maximized - - integrate Ximian patch to go ahead and log out after 4 minutes - even if a dialog is open - - fix a segfault - - fix bug where window groups weren't always kept up to date - - fix bug where focus got confused when switching workspaces - with mouse focus mode - - fix 64-bit crash on s390x - - chdir to user's homedir on startup - - keep window in fullscreen layer when its transients are focused - - fix keybindings bug when you had ScrollLock enabled - - many translation updates - -2.5.2 -=== - - Thanks to David Santiago, Julien Olivier, Anders Carlsson, Rob Adams - for fixes in this release. - - - improved wording/UI for some dialogs - - while clicking a window button, if you move the mouse outside - the button such that releasing the mouse button won't activate - the window button, visually indicate by "popping out" the button. - - fix some valgrind errors - - change "show desktop mode" to convert to "everything is minimized - mode" if you open a new window while showing desktop, rather - than previous behavior of simply leaving show desktop mode. - - fix a trivial memory leak - - change "move to workspace N" so it doesn't switch workspaces, - just moves the window. - - translation updates - -2.5.1 -=== - - Thanks to Rob Adams, Peter O'Shea, Dafydd Harries, Masahiro Sakai, - Soeren Sandmann for fixes in this release. - - - fix bug where fullscreen windows were below top panels - - build fix for Solaris - - support diagonal window movement with numeric keypad - - multihead fix - - build fix for Cygwin - - place on xinerama containing the pointer - - fix totally hosed window placement/movement for frameless - windows - - improvement to smoothness of window move/resize - -2.5.0 -=== - - Thanks to Rob Adams, Owen Taylor, Frederic Crozat, Arvind Samptur, - Bill Haneman, Akira Tagoh for help with fixes in this release. - - - many new translations - - fix an infinite loop while holding a server grab triggered by - some recent Qt versions doing weird stuff - - fix bug where Alt+rightclick repeatedly on titlebar resulted - in zillions of menus - - fix Alt+Tab to *actually* put minimized windows at the end, - though this was always intended - - rewrite size/positions constraint code (currently known - to be quite buggy, e.g. xmms is hosed) - - enforce size of at least 1x1 on windows - - reduce latency of managing new windows still further - by using async properties code in more places - - don't grab keybindings on docks, so gnome-panel - can handle them - - suck in the panel's screenshot and run dialog global - bindings - - lots of improvements to window placement - - sync max number of workspaces with pager applet - - fix to keep focus when inside window frame in - strict mouse focus mode - - make it possible to start a reverse tab with - shift+alt+tab (vs. alt+tab then shift) - - fix a multihead issue with constraints between two - windows on different heads - - require GTK+ 2.2.0 and fontconfig - - default theme is now Simple - - add visual bell feature - - incorporate many fixes from 2.4.34 - - other stuff - -2.4.13 -=== - - - we were making all dialogs skip the taskbar, even non-transient - ones, though this was supposedly fixed a while ago. Now really - fixed. - - change back to Alt+click by default for the window drag feature. - - assign Alt+F12 to shade window - - fix not deleting enough workspaces when the number - was reduced via the pager config dialog (readams@hmc.edu) - - don't allow windows under the top panel ever, even if they - are tall windows (Arvind) - - fix up the window layout for directional workspace nav, - so you always stop at the edges and always end up - where you expect (hp, with tweaks from readams@hmc.edu) - - focus new windows in mouse focus mode (readams@hmc.edu) - - support xeyes, oclock, etc. by applying shape mask - to the window manager frame (yeah it resizes slow, deal) - - fix vertical/horizontal maximize - - handle crossing events resizing for more opaque resize goodness - (Soeren) - - add wacky _METACITY_UPDATE_COUNTER experimental extension - to do nice opaque resizing (does nothing without a GTK patch) - - fix a crash setting workspace names - - fix internationalized WM_NAME reading - diff --git a/mutter/README.md b/mutter/README.md deleted file mode 100644 index 0e58440..0000000 --- a/mutter/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# Mutter - -Mutter is a Wayland display server and X11 window manager and compositor library. - -When used as a Wayland display server, it runs on top of KMS and libinput. It -implements the compositor side of the Wayland core protocol as well as various -protocol extensions. It also has functionality related to running X11 -applications using Xwayland. - -When used on top of Xorg it acts as a X11 window manager and compositing manager. - -It contains functionality related to, among other things, window management, -window compositing, focus tracking, workspace management, keybindings and -monitor configuration. - -Internally it uses a fork of Cogl, a hardware acceleration abstraction library -used to simplify usage of OpenGL pipelines, as well as a fork of Clutter, a -scene graph and user interface toolkit. - -Mutter is used by, for example, GNOME Shell, the GNOME core user interface, and -by Gala, elementary OS's window manager. It can also be run standalone, using -the command "mutter", but just running plain mutter is only intended for -debugging purposes. - -## Contributing - -To contribute, open merge requests at https://gitlab.gnome.org/GNOME/mutter. - -It can be useful to first look at the -[GNOME Handbook](https://handbook.gnome.org/development.html) and the -documentation and API references below first. - -## Documentation - -- [Coding style and conventions](doc/coding-style.md) -- [Git conventions](doc/git-conventions.md) -- [Code overview](doc/code-overview.md) -- [Building and Running](doc/building-and-running.md) -- [Debugging](doc/debugging.md) -- [Monitor configuration](doc/monitor-configuration.md) - -## API Reference - -- Meta: -- Clutter: -- Cally: -- Cogl: -- CoglPango: -- Mtk: - -## License - -Mutter is distributed under the terms of the GNU General Public License, -version 2 or later. See the [COPYING][license] file for detalis. - -[bug-tracker]: https://gitlab.gnome.org/GNOME/mutter/issues -[license]: COPYING diff --git a/mutter/check-style.py b/mutter/check-style.py deleted file mode 100755 index 5862e9b..0000000 --- a/mutter/check-style.py +++ /dev/null @@ -1,164 +0,0 @@ -#!/bin/env python3 - -import argparse -import os -import re -import subprocess -import sys -import tempfile - -# Path relative to this script -uncrustify_cfg = 'tools/uncrustify.cfg' - -def run_diff(sha): - proc = subprocess.run( - ["git", "diff", "-U0", "--function-context", "--default-prefix", sha, "HEAD"], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - encoding="utf-8", - ) - return proc.stdout.strip().splitlines() - -def find_chunks(diff): - file_entry_re = re.compile(r'^\+\+\+ b/(.*)$') - diff_chunk_re = re.compile(r'^@@ -\d+,\d+ \+(\d+),(\d+)') - file = None - chunks = [] - - for line in diff: - match = file_entry_re.match(line) - if match: - file = match.group(1) - - match = diff_chunk_re.match(line) - if match: - start = int(match.group(1)) - len = int(match.group(2)) - end = start + len - - if len > 0 and (file.endswith('.c') or file.endswith('.h') or file.endswith('.vala')): - chunks.append({ 'file': file, 'start': start, 'end': end }) - - return chunks - -def reformat_chunks(chunks, rewrite): - # Creates temp file with INDENT-ON/OFF comments - def create_temp_file(file, start, end): - with open(file) as f: - tmp = tempfile.NamedTemporaryFile() - if start > 1: - tmp.write(b'/** *INDENT-OFF* **/\n') - for i, line in enumerate(f, start=1): - if i == start - 1: - tmp.write(b'/** *INDENT-ON* **/\n') - - tmp.write(bytes(line, 'utf-8')) - - if i == end - 1: - tmp.write(b'/** *INDENT-OFF* **/\n') - - tmp.seek(0) - - return tmp - - # Removes uncrustify INDENT-ON/OFF helper comments - def remove_indent_comments(output): - tmp = tempfile.NamedTemporaryFile() - - for line in output: - if line != b'/** *INDENT-OFF* **/\n' and line != b'/** *INDENT-ON* **/\n': - tmp.write(line) - - tmp.seek(0) - - return tmp - - changed = None - - for chunk in chunks: - # Add INDENT-ON/OFF comments - tmp = create_temp_file(chunk['file'], chunk['start'], chunk['end']) - - # uncrustify chunk - proc = subprocess.run( - ["uncrustify", "-c", uncrustify_cfg, "-f", tmp.name], - stdout=subprocess.PIPE, - ) - reindented = proc.stdout.splitlines(keepends=True) - if proc.returncode != 0: - continue - - tmp.close() - - # Remove INDENT-ON/OFF comments - formatted = remove_indent_comments(reindented) - - if dry_run is True: - # Show changes - proc = subprocess.run( - ["diff", "-up", "--color=always", chunk['file'], formatted.name], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - encoding="utf-8", - ) - diff = proc.stdout - if diff != '': - output = re.sub('\t', '↦\t', diff) - print(output) - changed = True - else: - # Apply changes - diff = subprocess.run( - ["diff", "-up", chunk['file'], formatted.name], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - ) - patch = subprocess.run(["patch", chunk['file']], input=diff.stdout) - - formatted.close() - - return changed - - -parser = argparse.ArgumentParser(description='Check code style. Needs uncrustify installed.') -parser.add_argument('--sha', metavar='SHA', type=str, - help='SHA for the commit to compare HEAD with') -parser.add_argument('--dry-run', '-d', type=bool, - action=argparse.BooleanOptionalAction, - help='Only print changes to stdout, do not change code') -parser.add_argument('--rewrite', '-r', type=bool, - action=argparse.BooleanOptionalAction, - help='Whether to amend the result to the last commit (e.g. \'git rebase --exec "%(prog)s -r"\')') - -# Change CWD to script location, necessary for always locating the configuration file -os.chdir(os.path.dirname(os.path.abspath(sys.argv[0]))) - -args = parser.parse_args() -sha = args.sha or 'HEAD^' -rewrite = args.rewrite -dry_run = args.dry_run - -diff = run_diff(sha) -chunks = find_chunks(diff) -changed = reformat_chunks(chunks, rewrite) - -if dry_run is not True and rewrite is True: - proc = subprocess.run(["git", "add", "-p"]) - if proc.returncode == 0: - # Commit the added changes as a squash commit - subprocess.run( - ["git", "commit", "--squash", "HEAD", "-C", "HEAD"], - stdout=subprocess.DEVNULL) - # Delete the unapplied changes - subprocess.run(["git", "reset", "--hard"], stdout=subprocess.DEVNULL) - os._exit(0) -elif dry_run is True and changed is True: - print(f""" -Issue the following commands in your local tree to apply the suggested changes: - - $ git rebase {sha} --exec "./check-style.py -r" - $ git rebase --autosquash {sha} -""") - os._exit(-1) - -os._exit(0) diff --git a/mutter/clutter/clutter/cally/ChangeLog.pre-cally-merge b/mutter/clutter/clutter/cally/ChangeLog.pre-cally-merge deleted file mode 100644 index 89e2de9..0000000 --- a/mutter/clutter/clutter/cally/ChangeLog.pre-cally-merge +++ /dev/null @@ -1,986 +0,0 @@ -# DO NOT MODIFY THIS FILE -# -# Clutter uses the Git commit log to generate the ChangeLog files when -# creating the tarball for releases and snapshots. This file is maintained -# only for historical reasons. - -2010-07-05 Alejandro Pieiro - -Cleaning ClutterText - - * Removing superfluous g_return_if_fail - * Removing unused ClutterText::text-changed callback - -2010-07-05 Alejandro Pieiro - -Refactoring "window:create" and "window:destroy" emission code - -Previously "window:create" and "window:destroy" were emitted on -CallyUtil. Although it works, and CallyUtil already have callbacks to -stage_added/removed signals, I think that it is more tidy/clear to do -that on CallyRoot: - - * CallyRoot already has code to manage ClutterStage addition/removal - - * In fact, we can see CallyRoot as the object exposing the a11y - information from ClutterStageManager, so it fits better here. - - * CallyUtil callbacks these signals are related to key event - listeners (key snooper simulation). One of the main CallyUtil - responsibilities is managing event (connecting, emitting), so I - would prefer to not start to add/mix more functionalities here. - -Ideally it would be better to emit all CallyStage methods from -CallyStage, but it is clear that "create" and "destroy" are more easy -to emit from a external object. - -2010-06-25 Alejandro Pieiro - -Cleaning clutter-actor - -Some cleaning changes: - * Using CallyActionFunc instead of ACTION_FUNC - * Removing a extra * on cally-actor-private macro documentation, to - avoid gtk-doc warnings - * Using g_strcmp0 instead of strcmp - -Changes to be applied on clutter (see CB#2097 and CB#2098), applied -also here to maintain the sync. My intention is keep this developing line -until the real integration, in order to make a final independent cally -release. - -2010-06-14 Alejandro Pieiro - -Adding -Wshadow option and solving warnings related - - -2010-06-14 Alejandro Pieiro - -Added dummy padding for future vt expansion - -Added dummy padding on the different classes structures, to allow -future expansion of virtual methods. - -I decided to add this on all the classes, although it would be -really unlikely in some cases (ie, CallyGroup) - -2010-06-10 Alejandro Pieiro - -Adding and emitting "window:xxx" methods on CallyStage - -Added some window related signals on CallyStage: - - * window:activate and window:deactivate emitted from CallyStage - * window:create and window:destroy emitted from CallyUtil - -ClutterStage doesn't fulfill 100% the window concept, but some of -these signals are important in order to identify the object which -could emit global/key events. - -The current implementation is equivalent to GailWindow one, supposing -CallyStage as the only window related window. This likely would change -in any clutter-based toolkit implement a real Window object, so a more -flexible procedure would be required. But we would solve problems step -by step. - -BTW: as I explain here [1] I really think that the current way to -implement "window:xxx" signals (not defined in ATK but expected from -the a11y implementation toolkit) somewhat hacky and undocumented (you -need to check at-spi2 idls to know that you require to emit this -events) - -Related to bug CB#2147 (Orca doesn't speech out properly non -printable chars on some environments), as solves this problem -in a specific case. - -[1] https://bugzilla.gnome.org/show_bug.cgi?id=620977#c1 - -2010-06-04 Alejandro Pieiro - -Avoiding clutter_stage_get_key_focus warning - -For any reason, in some cases, a clutter actor doesn't have a stage -associated. We use the default one as fallback. - -2010-06-02 Alejandro Pieiro - -Added a defunct check on cally_group_get_n_children - -Some warnings appeared when we tried to get the number -of children of a defunct object. - -2010-06-02 Alejandro Pieiro - -Update TODO file - -Use Bugzilla to setting missing features. - -2010-06-01 Alejandro Pieiro - -Removing heuristics to decide CallyRectable/CallyTexture role - -Previously CallyRectangle and CallyTexture used some heuristics in -order to decide the default role: ATK_ROLE_IMAGE or -ATK_PUSH_BUTTON, as in practice most applications using these -objects as buttons were not applying the proper role. - -As this is a hack, and a application responsibility, finally we -have decided to remove this, so the default role is ATK_ROLE_IMAGE. - -Fixes CB#1732 (CallyTexture and CallyRectangle uses some heuristics to -decide the role) - -2010-05-28 Alejandro Pieiro - -Post-release version bump, after release 1.2.0 - -I wrongly added the last commit on the 1.1 branch, when in fact it -requires clutter 1.3.3, and on the README it is explained that -cally versioning is tied to clutter versioning. In order to solve -that a clutter-1.2 release branch is created, and bumped the version. - -This versioning tyding will be obsolete when the integration with -clutter become a reality, but in the same way, this is the way to -tidy this thinking in this integration. - -2010-04-13 Alejandro Pieiro - -Use clutter_actor_get_accessible - -The method clutter_actor_get_accessible was added due work on -bug 2070, and should be used to get the accessibility object, -instead of atk_gobject_accessible_for_object - -This would allow to implement a11y support directly on -any clutter based toolkit object (ie StLabel). - -2010-05-13 Alejandro Pieiro - -Added CallyClone example - - -2010-05-13 Alejandro Pieiro - -Added a11y support for ClutterClone - -Resolved in the most simplified way, just as a image and a -default description to identify cloned objects. - -More information: -http://lists.o-hand.com/clutter/3797.html - -2010-04-14 Alejandro Pieiro - -Remove gail dependency - -Removed to avoid gdk/gtk dependency on cally. - -Part of bug CB#2072 solution - -2010-04-14 Alejandro Pieiro - -Avoid gdk functions filling AtkKeyEventStruct - -Now when AtkKeyEventStruct is filled in order to emit any key event -signal, it is not used any gdk function on the keyval or the -string fields. - -event_string is filled with the printable character if possible, if -not (Ctrl, Alt, etc) it is set as NULL. - -Now the AT should take care of that, at least until we define atk key -event struct in a more agnostic way (not tied to gdk/gtk). See orca -bug bgo#616206 as a example. - -Part of bug CB#2072 solution. - -2010-04-15 Alejandro Pieiro - -Added gail_misc_layout_get_run_attributes implementation - -Part of bug CB#2072 solution - -2010-04-14 Alejandro Pieiro - -Remove gailutil/gailmisc functions calls - -This is because gailutil/gailmisc added a gdk/gtk dependency, and -this dependency is being removed. New cally-specific implementation -are required. - -Related to bug CB#1733 - -Part of bug CB#2072 solution - -2010-04-13 Alejandro Pieiro - -Fixing the libdir directory in some examples - - -2010-03-26 Alejandro Pieiro - -Previous cally.pc.in update was incomplete - -The previous commit was not tested properly, and it was missing one -detail. Sorry for the noise. - -2010-03-26 Alejandro Pieiro - -Update cally.pc.in after module relocation - -Previous commit places cally module in a different directory. -It also corrects where the include directory is placed. - -2010-03-15 Alejandro Pieiro - -Use a proper clutter module directory - -Use a proper clutter module directory, instead of keep being -installed on a gtk directory. - -Improve the cally-examples-util, in order to keep using -hardcoded values. - -Fixes CB#1737 (Wrong cally module directory) - -2010-03-15 Alejandro Pieiro - -Proper UTF-8 headers - - -2010-02-25 Alejandro Pieiro - -Change "--with-dbus" option for "atk-bridge-dir" on examples - -The atk-adaptor in the dbus at-spi was renamed to atk-bridge due -some apps hardcoding the name. So right now the only difference -is the final directory. - -So the option was removed, and atk-bridge-dir added. This also allows -to use the system atk-bridge or the compiled in any developing environment, -so it is really more flexible. - -See the README (updated with this commit) for more information. - -2010-02-19 Alejandro Pieiro - -Added .gitignore file - - -2010-02-19 Alejandro Pieiro - -Release 1.1.1 - - -2010-02-19 Alejandro Pieiro - -Using clutter_threads_idle_add instead of the gdk one - -The idea is being as less gdk dependent as possible. Right now -it is inviable to remove the dependency (gailutil and so on) but -hypothetically, the ideal is remove this dependency in the future, -and being "clutter pure". - -2010-02-15 Alejandro Pieiro - -Check if the state is defunct on cally_text_get_name - -Check if the state is defunct on cally_text_get_name, in order -to avoid warnings cally clutter_text_get_text when the clutter -object is NULL - -2010-01-26 Alejandro Pieiro - -Update on configure.ac after autoupdate call - - -2010-02-02 Alejandro Pieiro - -Try to apply the key modifiers to event->keyval like GDK does - -ClutterKeyEvent defines the keyval without taking into account the -modifiers. GDK defines this keyval taking into account the modifiers. - -AtkKeyEventStruct expects the keyval in a GDK fashion, so a -translation is required. - -This patch tries to do that using using -gdk_keymap_translate_keyboard_state. - -This functions only works correctly if gtk has been initialized, so -the fallback is create the AtkKeyEventStruct with the keyval -provided by Clutter. - -More information: -http://library.gnome.org/devel/atk/stable/AtkUtil.html#AtkKeyEventStruct -http://bugzilla.openedhand.com/show_bug.cgi?id=1961 - -2010-02-02 Alejandro Pieiro - -Filling AtkKeyEventStruct->string used on the atk key event listeners - -Finally we use directly gdk_keyval_name. Not the ideal solution, but works, -and more important, it avoids to reimplement this issue on clutter or cally. - -More information on Bug 1952 - -Fixes http://bugzilla.openedhand.com/show_bug.cgi?id=1952 - -2010-01-22 Alejandro Pieiro - -Added AM_PROG_CC_C_O option to avoid a warning running configure - - -2010-01-22 Alejandro Pieiro - -Fix clutter version required on the pc files - - -2010-01-22 Alejandro Pieiro - -Check on configure time if any x11 clutter backend is in use - -It uses AC_CHECK_LIB in order to check if x11 backend is in use. -It also modifies cally-actor in order to use the information -retrieved. - -So now cally has a minimum multi-backend support. It only manages -a x11 (glx or eglx) backend, but at least, it checks it, so you -can compile cally without this backend. It probably will not work -properly, but at least you can compile and execute it. - -Solves http://bugzilla.openedhand.com/show_bug.cgi?id=1736 - -2010-01-21 Alejandro Pieiro - -Fix the perspective problems computing the on-screen extensions - -Use clutter_actor_get_abs_allocation_vertices and -clutter_actor_get_transformed_size to get the real on-screen -position and size, instead of compute that using the geometry -and the anchor point. - -It also update cally-atkcomponent-example, adding a actor inside -a nested ClutterGroup hierarchy. - -Fixes: http://bugzilla.openedhand.com/show_bug.cgi?id=1731 - -2010-01-13 Alejandro Pieiro - -Added extra button on cally-atkeditabletext-example - -Added a button to print the current cursor position, and also -extend the size of the buttons - -2010-01-12 Alejandro Pieiro - -Remove superfluous g_print on CallyStage - - -2009-12-03 Alejandro Pieiro - -Use clutter_stage_manager_peek_stages to avoid a leak - - -2009-12-03 Alejandro Pieiro - -Added ATK_STATE_SELECTABLE_TEXT management - - -2009-11-26 Alejandro Pieiro - -Manage properly ATK_STATE_ACTIVE on CallyStage - -* cally/cally-stage.c -Added private struct -(cally_stage_class_init),(cally_stage_init),(cally_stage_real_initialize): -Initialization stuff -(cally_stage_activate_cb) -(cally_stage_deactivate_cb): new ClutterStage signal callbacks, change -the internal value of active, and notify the atk state change -(cally_stage_ref_state_set): manage ATK_STATE_ACTIVATE -* examples/cally-atktext-example2.c -If possible, creates two stage, in order to test ATK_STATE_ACTIVATE - -2009-11-24 Alejandro Pieiro - -Focused state change and focused object notification - -* cally/cally-actor.h -(focus_clutter): added virtual method for the focus management -* cally/cally-actor.c -(cally_actor_component_interface_init) -(cally_actor_add_focus_handler) -(cally_actor_remove_focus_handler): -Implementation of the AtkComponent methods add_focus_handler and -remove_focus_handler -(cally_actor_focus_event): CallyActor specific focus handler, notify -the state focused change -(cally_actor_focus_clutter) -(cally_actor_real_focus_clutter): -Handlers for the ClutterActor "key-focus-in" and "key-focus-out" -signals. Emit the signal AtkObject "focus_event" and set the focus -object with atk_focus_tracker_notify. -(cally_actor_initialize): -Connect to the signals "key-focus-in" and "key-focus-out", use -atk_component_add_focus_handler to add cally_actor_focus_event - -Note: The focus management is more simplified that the gail one. The -main reason is that the focus management in GTK is really more complex -that the Clutter one. - -2009-11-24 Alejandro Pieiro - -Modify cally-atkeditabletext-example.c to manage "activatable" status - - -2009-11-24 Alejandro Pieiro - -Added "activate" action in ClutterText - -* cally/cally-actor.h -* cally/cally-actor.c -cally_actor_add_action now returns the action id added. Documentation -added in order to explain the return values and others. - -* cally/cally-text.c -Added action "activate". This action is only available if the ClutterText is -activatable, so the "activatable" property is tracked in the notify - -2009-11-20 Alejandro Pieiro - -Signal event emission - -Emits the signals "text_selection_changed", "text_caret_moved", -"text_changed::insert", "text_changed::delete", and notify the -ATK_STATE_EDITABLE state change. - -It also adds the ATK_STATE_EDITABLE in the ref_state_set, includes a -finalize to clean the new private data used, and move part of the -initialization from the _init to the _real_initialization. - -2009-12-03 Alejandro Pieiro - -Remove the ATK_STATE_DEFUNCT emission - -Remove the ATK_STATE_DEFUNCT emission, as this is already made by -AtkGObjectAccessible. - -It also removes the clutter actor from the private structure, as we -can use the AtkGObjectAccessible API to obtain it. This makes the code -more coherent, with respect of the rest of the Cally classes -implementation. - -2009-11-26 Alejandro Pieiro - -Remove ; from the CALLY_GET_CLUTTER_ACTOR macro - - -2009-11-25 Alejandro Pieiro - -TODO cleanup and more implementation notes - -* TODO: removed the data that we have in the bugzilla or in the implementation - notes on the cally source -* cally/cally-actor.c: complete implementations notes -* cally/Makefile.am: add a comment related to the public headers, and include - Makefile.in in the MAINTAINERCLEANFILES - -2009-11-13 Alejandro Pieiro - -Adding new tips on CODING_STYLE - - -2009-11-09 Alejandro Pieiro - -AtkEditableText implementation on CallyText - -* examples/Makefile.am -* examples/cally-atkeditabletext-example.c: New example added -* cally/cally-text.c - -Interface AtkEditableText implemented, except some methods: - * Missing ClipBoard feature on Clutter: - paste_text - copy_text - cut_text - * Missing a equivalent GtkTextTag on Clutter (so the possibility to - set run attributes in a range): - set_run_attributes - -Fixes bug CB#1734 - -2009-11-03 Alejandro Pieiro - -Removed DG_DISABLE_CHECKS and DG_DISABLE_CAST_CHECKS from CFLAGS - -* configure.ac: Removed DG_DISABLE_CHECKS and DG_DISABLE_CAST_CHECKS - from the common CFLAGS options -* cally/cally-actor.c: fixed cast errors on some return values, not - detected previously because of the use of relaxed compilation - options - -Problem detected by Mario Sánchez Prada - -2009-10-28 Alejandro Pieiro - -Support for multiple stages - -* cally-root.c -* cally-stage.c -* cally-util.c -Implemented the support for multiple stages, by tracking the signals -stage-added and stage-removed of the ClutterStageManager. - -In the same way CallyRoot has implement properly the atk_object_initialize, -and in general now is more tied to ClutterStageManager (CallyRoot is now -the a11y object of ClutterStageManager), but factory not required anyway, -as it is instanced on the CallyUtil atk_get_root - -Fixes: CB#1754 (Missing multi-stage support) - -2009-10-27 Alejandro Pieiro - -Implemented atk_[add/remove]_key_event_listener on CallyUtil - -* cally/cally-util.c: - Implemented atk_[add/remove]_key_event_listener -* examples/cally-atktext-example2.c: - Modified in order to install and remove key event listeners, - for testing purposes - -Fixes CB#1852 (AtkUtil implementation misses -atk_[add/remove]_key_event_listener) - -2009-10-21 Alejandro Pieiro - -Implemented atk-[add/remove]-global-event-listener on CallyUtil - - * cally/cally-util.c: - Implemented atk-[add/remove]-global-event-listener on CallyUtil - * examples/Makefile.am - * examples/cally-atktext-example2.c - New example in order to test easier the event emission on focus - change (not working right now) - -2009-10-12 Alejandro Pieiro - -Add --with-dbus option executing the examples - -The replacement for atk-bridge on at-spi-dbus has a different name -(atk-adaptor), and it has not defined the method gnome_accessibility_init. -The --with-dbus option allow to load the correct library and use the -correct hook method if you are using at-spi-dbus. - -Anyway, take into account that this is just an example, and in a final -environment, this should be made in a more general way. - -More information: CB#1738, CB#1737 - -2009-09-25 Alejandro Pieiro - -Symplifying shave support. - - -2009-09-25 Alejandro Pieiro - -Cleanup on the compilation and installation process - -* cally/Makefile.am: - Added libcallydir and libcally_HEADERS in order to publish all cally - headers, as the current policy is use the cally headers as public. -* configure.ac: - Change API_VERSION_MAJOR for CALLY_API_VERSION, as was the real - meaning, and define CALLY_VERSION. - Change CALLY_OBJ_CFLAGS and CALLY_OBJ_LIBS, used to compile the - tests, as was not required to compile against the cally module (the - example only required to compile against Clutter, as the cally - module was just a module loaded by GModule). - Support for Shave. - -2009-07-31 Alejandro Pieiro - -Be able to run the examples without installing Cally - -Before that, the examples searched the cally module from the final installed -directory. This means that you should install the library to use the examples. -On development this is not desirable. Now it is loaded from ../cally/.libs - -This is a little hackish, but more useful, and in the end, it is just a example. -Probably a best option could be configure that on the command line. - $ ./example --cally-dir="mydir" - -But just a nitpick. - -2009-07-29 Alejandro Pieiro - -Upgrade to cally-1.0, using clutter-1.0 - -* NEWS -* TODO: removed several items, waiting to be moved to the bugzilla -* configure.ac -* examples/cally-examples-util.c - -2009-07-27 Alejandro Pieiro - -Fixed return value of cally_actor_get_index_in_parent - -Bug and solutiond pointed by Gerd Kohlberger - -2009-06-30 Alejandro Pieiro - -Added the implementation of most AtkText methods for CluttetText (CallyText) - -It remains some methods: - get_default_attributes - get_character_extents - get_offset_at_point - -The current gail implementation delegate on gailmisc, but this is tied to -GtkWidget so an equivalent functionality would be implemented (something like -callymisc), and in the case of get_character_extents, not sure about the layout -position (see gtk_entry_get_layout_offsets). - -I think that worth manage this in a different commit. - -In the same way is still missing AtkEditableText support. - -2009-07-07 Alejandro Pieiro - -Added CALLY_GET_CLUTTER_ACTOR macro - -This macro was created to simplify how do you get the clutter actor object -related to the cally object. On CallyActor a private attributte maintains it -(for convenience, as it is heavily used) but outside, atkgobject methods can -be used. Note that there is a possibility on the future to change it. Two -options: - * Add a public method to get the clutter object - * Use this method on CallyActor too - -This macro simplifies this: - -CLUTTER_ACTOR (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (cally_object))) - -2009-06-24 Alejandro Pieiro - -Renamed examples/cally-util.[ch] to examples/cally-examples-util.[ch] - -Renamed examples/cally-util.[ch] to examples/cally-examples-util.[ch] to avoid -confusion with cally/cally-util.[ch], implementation of the AtkUtil interface - -2009-06-23 Alejandro Pieiro - -Adding examples directory - -* NEWS: Updates -* configure.ac -* Makefile.am -* cally/Makefile.am -* examples/Makefile.am: New -* examples/cally-util.[ch]: New -* examples/example1.c: New -Added a directory in order to put examples. In this way we don't require any -external clutter app to make the basic a11y functionality checks. At this -moment only an example was added, but all the compiling structure is working. -By default the examples are not compiled, use "--enable-examples" on configure -time in order to enable their compilation. - -This basic example basically shows several objects, with different depth, in -order to check that AtkComponent returns the correct screen position. - -Other minor changes done on the building infrastructure. - -2009-06-23 Alejandro Pieiro - -Fix clutter version required - - -2009-06-23 Alejandro Pieiro - -Solve a problem calling clutter_actor_get_anchor_point - -* cally/cally-actor.c: -(_get_actor_extents): use gfloat instead of gint, as now this clutter_actor_get_anchor_point -use floats - -2009-06-11 Alejandro Pieiro - -Minor fixes - - * Update TODO - * Fix .pc files, to use clutter-0.9 version - -2009-05-20 Alejandro Pieiro - -Library renamed from cail to cally - - -2009-05-08 Alejandro Pieiro - -Removed cail-clone-texture.h from cail.h - -* cail/cail.h: Removed reference to cail-clone-texture.h - -2009-05-08 Alejandro Pieiro - -Upgrade to cail-0.9, using clutter-0.9, first compilable version - -* NEWS: new file with the information of the releases -* TODO: updated -* configure.ac: updated clutter version to compile against -* cail/cail-clone-texture.[ch]: Removed as ClutterCloneTexture was removed on Clutter 0.9.0 -* cail/cail-label.[ch]: Removed as ClutterLabel was removed on Clutter 0.9.0 -* cail/Makefile.am: updated due the source files removed -* cail/cail-actor.c: removed include to -* cail/cail.c: removed the factories for CailLabel and CailCloneTexture - -2009-05-07 Alejandro Pieiro - -Reflect change on the version number policy - -* README: correct some typos and explain that the cail version number -is tied to the clutter version number and how -* configure.ac -Set the version number to 0.8.0 - -2009-05-07 Alejandro Pieiro - -Edit the ChangeLog file, to show that now we are using git - -* ChangeLog.SVN: new file, with the ChangeLog used while cail was -using a Subversion repository -* ChangeLog: now is empty, and only maintains a reference to use git log - -2009-04-29 Alejandro Pieiro - -Coding style review - -* CODING_STYLE -* cail/Makefile.am -* cail/cail-actor-private.[ch] -* cail/cail-actor.h -* cail/cail-clone-texture.[ch] -* cail/cail-group.[ch] -* cail/cail-label.[ch] -* cail/cail-rectangle.[ch] -* cail/cail-root.[ch] -* cail/cail-stage.[ch] -* cail/cail-texture.[ch] -* cail/cail-util.[ch] -* cail/cail.c - -2009-04-28 Alejandro Pieiro - -Coding style review: cail-actor.c - - -2009-04-21 Alejandro Pieiro - -2009-04-21 Alejandro Pinheiro - - * TODO: updated TODO file - -2009-04-21 Alejandro Pieiro - -2009-03-06 Alejandro Pinheiro - - * AUTHORS: update authors file to public release - -2009-03-06 Alejandro Pieiro - -2009-03-06 Alejandro Pinheiro - - * debian/control - Added cdbs dependency, renamed debugging package - * debian/libcail-common-dbg.dirs: new file - * debian/libcail-common.dirs - * debian/libcail-common.install - Minor changes - -2009-03-05 Alejandro Pieiro - -2009-03-05 Alejandro Pinheiro - - * TODO - Added TODO file, in order to list the remaining tasks. - -2009-03-05 Alejandro Pieiro - -2009-03-05 Alejandro Pinheiro - - * configure.ac - * cail/cail.c - * cail/cail-util.c - * Makefile.am - Removed all the missing gtk related stuff - -2009-03-05 Alejandro Pieiro - -2009-03-05 Alejandro Pinheiro - - * cail/cail-actor.c - (_get_actor_extents): managing too the anchor point to compute the position - (_get_top_level_origin): reimplemented using x11 functions, removed - gtk/gdk related functions, and taking into account the relative position - inside the parent (previous position calculation was wrong if a child - was not a direct stage child) - * cail/clutter-gtk/cail-clutter-embed.[ch] - * cail/clutter-gtk/cail-gtk-factory.h - Removed, in order to remove any gtk dependency - * cail/debian/control: removed gtk dependency - -2009-03-03 Alejandro Pieiro - -2009-03-03 Alejandro Pinheiro - - * cail/cail-actor-private.[ch]: new files to private utility functions - (_cail_actor_pushable): new function, that checks if a cail actor is - pushable by checking if the clutter actor related has a handler for - a release event - * cail/cail-texture.c - * cail/cail-clone-texture.c - * cail/cail-rectangle.c - Use of new function _cail_actor_pushable - * cail-actor.c: Added some documentation related to current implementation - * cail-util.c: Code style review - -2009-03-02 Alejandro Pieiro - -2009-03-02 Alejandro Pinheiro - - * cail/cail-label.[ch]: new - * cail/cail.[ch] - (cail_accessibility_module_init) - * cail/Makefile.am - Added CailLabel, a11y object for ClutterLabel - -2009-02-27 Alejandro Pieiro - -2009-02-27 Alejandro Pinheiro - - * cail/cail-actor.c - (cail_actor_real_remove_actor) - Fixed a typo that causes a crash while removing the actor from a - container - -2009-02-26 Alejandro Pieiro - -2009-02-26 Alejandro Pinheiro - - * cail/cail-actor.c - (cail_actor_remove_actor) - (cail_actor_add_actor) - Fixed a typo calling klass->add_actor and klass->remove_actor that causes - a crash in some (container,actor) combinations - - (cail_actor_real_add_actor) - Additional parameter check - -2009-02-25 Alejandro Pieiro - -Missing cail-rectangle.[ch] files, according 2009-02-23 entry at Changelog - - -2009-02-23 Alejandro Pieiro - -2009-02-23 Alejandro Pinheiro - - * cail/cail-rectangle.[ch] - * cail/cail.[ch] - * cail/Makefile.am - - Added CailRectangle, a11y object for ClutterRectangle - - * cail/cail-group.c - * cail/cail-texture.c - * cail/cail-stage.c - - Avoid to add a empty private structure, to avoid the glib warning. Anyway - the pointer to the private structure is still on the .h, to allow future - add-on. - -2009-02-20 Alejandro Pieiro - -2009-02-20 Alejandro Pinheiro - - * cail-actor.[ch] - * cail-group.[ch] - - Moved most of the ClutterContainer a11y support from cail-group to - cail-actor, in order to generalize this support. - - * cail-stage.[ch] - * cail-util.[ch] - Normalize the private structure to avoid future problems with missing - gaps - -2009-02-20 Alejandro Pieiro - -2009-02-20 Alejandro Pinheiro - - * cail/cail-actor.c - (cail_actor_connect_actor_destroyed): connects to the clutter actor - destroy signal - (cail_actor_clutter_actor_destroyed): handler to the clutter actor - destroy signal, update the priv->actor pointer and notify a state change - - This change allows to be sure about the priv->actor correct value, so we - can use directly priv->actor instead of atk_gobject_accessible_get_object - in the next functions: - (cail_actor_get_parent) - (cail_actor_get_index_in_parent) - (cail_actor_ref_state_set) - (cail_actor_get_extents) - -2009-02-19 Alejandro Pieiro - -2009-02-19 Alejandro Pinheiro - - * cail/cail-texture.[ch] - * cail/cail-clone-texture.[ch] - * cail/cail.[ch] - * cail/Makefile.am - - Added CailTexture and CailCloneTexture a11y objects for ClutterTexture - and ClutterCloneTexture - - * cail/cail-util.c - - Added private structure - -2009-02-18 Alejandro Pieiro - -2009-02-18 Alejandro Pinheiro - - * cail/cail-actor.c: - (cail_actor_get_parent) - Return the accessible object of the clutter actor if accessible_parent - is not available. Previously it only took into account the these object - as a possible parent to return (you can set it with atk_object_set_parent) - -2009-02-18 Alejandro Pieiro - -2009-02-18 Alejandro Pinheiro - - * cail/cail-group.[ch]: code style review - * cail/cail-actor.[ch]: implemented basic support for ClutterContainer - -2009-02-18 Alejandro Pieiro - -2009-02-18 Alejandro Pinheiro - - * debian/control: updating dependencies - -2009-02-18 Alejandro Pieiro - -2009-02-18 Alejandro Pinheiro - - * configure.ac: added additional compile flags - * cail/cail-actor.[ch]: Reimplemented support for AtkAction interface - * cail/cail-root.[ch]: code style review - -2009-02-16 Alejandro Pieiro - -2009-02-16 Alejandro Pinheiro - - * First release. diff --git a/mutter/clutter/clutter/cally/cally-actor-private.h b/mutter/clutter/clutter/cally/cally-actor-private.h deleted file mode 100644 index 0de920e..0000000 --- a/mutter/clutter/clutter/cally/cally-actor-private.h +++ /dev/null @@ -1,35 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2008 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * Some parts are based on GailWidget from GAIL - * GAIL - The GNOME Accessibility Implementation Library - * Copyright 2001, 2002, 2003 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#include "cally/cally-actor.h" - -/* - * Auxiliary define, in order to get the clutter actor from the AtkObject using - * AtkGObject methods - * - */ -#define CALLY_GET_CLUTTER_ACTOR(cally_object) \ - (CLUTTER_ACTOR (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (cally_object)))) diff --git a/mutter/clutter/clutter/cally/cally-actor.c b/mutter/clutter/clutter/cally/cally-actor.c deleted file mode 100644 index 1d53542..0000000 --- a/mutter/clutter/clutter/cally/cally-actor.c +++ /dev/null @@ -1,1146 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2008 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * Some parts are based on GailWidget from GAIL - * GAIL - The GNOME Accessibility Implementation Library - * Copyright 2001, 2002, 2003 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/** - * CallyActor: - * - * Implementation of the ATK interfaces for [class@Clutter.Actor] - * - * #CallyActor implements the required ATK interfaces of [class@Clutter.Actor] - * exposing the common elements on each actor (position, extents, etc). - */ - -/* - * - * IMPLEMENTATION NOTES: - * - * #### - * - * Focus: clutter hasn't got the focus concept in the same way that GTK, but it - * has a key focus managed by the stage. Basically any actor can be focused using - * clutter_stage_set_key_focus. So, we will use this approach: all actors are - * focusable, and we get the currently focused using clutter_stage_get_key_focus - * This affects focus related stateset and some atk_component focus methods (like - * grab focus). - * - * In the same way, we will manage the focus state change management - * on the cally-stage object. The reason is avoid missing a focus - * state change event if the object is focused just before the - * accessibility object being created. - * - * #AtkAction implementation: on previous releases ClutterActor added - * the actions "press", "release" and "click", as at that time some - * general-purpose actors like textures were directly used as buttons. - * - * But now, new toolkits appeared, providing high-level widgets, like - * buttons. So in this environment, it doesn't make sense to keep - * adding them as default. - * - * Anyway, current implementation of AtkAction is done at CallyActor - * providing methods to add and remove actions. This is based on the - * one used at gailcell, and proposed as a change on #AtkAction - * interface: - * - * https://bugzilla.gnome.org/show_bug.cgi?id=649804 - * - */ - -#include "config.h" - -#include - -#include "clutter/clutter.h" -#include "clutter/clutter-actor-private.h" - -#include - -#include "cally/cally-actor.h" -#include "cally/cally-actor-private.h" - -typedef struct _CallyActorActionInfo CallyActorActionInfo; - -/*< private > - * CallyActorActionInfo: - * @name: name of the action - * @description: description of the action - * @keybinding: keybinding related to the action - * @do_action_func: callback - * @user_data: data to be passed to @do_action_func - * @notify: function to be called when removing the action - * - * Utility structure to maintain the different actions added to the - * #CallyActor - */ -struct _CallyActorActionInfo -{ - gchar *name; - gchar *description; - gchar *keybinding; - - CallyActionCallback do_action_func; - gpointer user_data; - GDestroyNotify notify; -}; - -static void cally_actor_initialize (AtkObject *obj, - gpointer data); -static void cally_actor_finalize (GObject *obj); - -/* AtkObject.h */ -static AtkObject* cally_actor_get_parent (AtkObject *obj); -static gint cally_actor_get_index_in_parent (AtkObject *obj); -static AtkStateSet* cally_actor_ref_state_set (AtkObject *obj); -static gint cally_actor_get_n_children (AtkObject *obj); -static AtkObject* cally_actor_ref_child (AtkObject *obj, - gint i); -static AtkAttributeSet * cally_actor_get_attributes (AtkObject *obj); - -/* ClutterContainer */ -static gint cally_actor_add_actor (ClutterActor *container, - ClutterActor *actor, - gpointer data); -static gint cally_actor_remove_actor (ClutterActor *container, - ClutterActor *actor, - gpointer data); -static gint cally_actor_real_add_actor (ClutterActor *container, - ClutterActor *actor, - gpointer data); -static gint cally_actor_real_remove_actor (ClutterActor *container, - ClutterActor *actor, - gpointer data); - -/* AtkComponent.h */ -static void cally_actor_component_interface_init (AtkComponentIface *iface); -static void cally_actor_get_extents (AtkComponent *component, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coord_type); -static gint cally_actor_get_mdi_zorder (AtkComponent *component); -static gboolean cally_actor_grab_focus (AtkComponent *component); - -/* AtkAction.h */ -static void cally_actor_action_interface_init (AtkActionIface *iface); -static gboolean cally_actor_action_do_action (AtkAction *action, - gint i); -static gboolean idle_do_action (gpointer data); -static gint cally_actor_action_get_n_actions (AtkAction *action); -static const gchar* cally_actor_action_get_description (AtkAction *action, - gint i); -static const gchar* cally_actor_action_get_keybinding (AtkAction *action, - gint i); -static const gchar* cally_actor_action_get_name (AtkAction *action, - gint i); -static gboolean cally_actor_action_set_description (AtkAction *action, - gint i, - const gchar *desc); -static void _cally_actor_destroy_action_info (gpointer action_info, - gpointer user_data); -static void _cally_actor_clean_action_list (CallyActor *cally_actor); - -static CallyActorActionInfo* _cally_actor_get_action_info (CallyActor *cally_actor, - gint index); -/* Misc functions */ -static void cally_actor_notify_clutter (GObject *obj, - GParamSpec *pspec); -static void cally_actor_real_notify_clutter (GObject *obj, - GParamSpec *pspec); - -struct _CallyActorPrivate -{ - GQueue *action_queue; - guint action_idle_handler; - GList *action_list; - - GList *children; -}; - -G_DEFINE_TYPE_WITH_CODE (CallyActor, - cally_actor, - ATK_TYPE_GOBJECT_ACCESSIBLE, - G_ADD_PRIVATE (CallyActor) - G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, - cally_actor_component_interface_init) - G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, - cally_actor_action_interface_init)); - -/** - * cally_actor_new: - * @actor: a #ClutterActor - * - * Creates a new #CallyActor for the given @actor - * - * Return value: the newly created #AtkObject - */ -AtkObject * -cally_actor_new (ClutterActor *actor) -{ - gpointer object; - AtkObject *atk_object; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); - - object = g_object_new (CALLY_TYPE_ACTOR, NULL); - - atk_object = ATK_OBJECT (object); - atk_object_initialize (atk_object, actor); - - return atk_object; -} - -static void -cally_actor_initialize (AtkObject *obj, - gpointer data) -{ - CallyActor *self = NULL; - CallyActorPrivate *priv = NULL; - ClutterActor *actor = NULL; - guint handler_id; - - ATK_OBJECT_CLASS (cally_actor_parent_class)->initialize (obj, data); - - self = CALLY_ACTOR(obj); - priv = cally_actor_get_instance_private (self); - actor = CLUTTER_ACTOR (data); - - g_signal_connect (actor, - "notify", - G_CALLBACK (cally_actor_notify_clutter), - NULL); - - g_object_set_data (G_OBJECT (obj), "atk-component-layer", - GINT_TO_POINTER (ATK_LAYER_MDI)); - - priv->children = clutter_actor_get_children (actor); - - /* - * We store the handler ids for these signals in case some objects - * need to remove these handlers. - */ - handler_id = g_signal_connect (actor, - "child-added", - G_CALLBACK (cally_actor_add_actor), - obj); - g_object_set_data (G_OBJECT (obj), "cally-add-handler-id", - GUINT_TO_POINTER (handler_id)); - handler_id = g_signal_connect (actor, - "child-removed", - G_CALLBACK (cally_actor_remove_actor), - obj); - g_object_set_data (G_OBJECT (obj), "cally-remove-handler-id", - GUINT_TO_POINTER (handler_id)); - - obj->role = ATK_ROLE_PANEL; /* typically objects implementing ClutterContainer - interface would be a panel */ -} - -static void -cally_actor_class_init (CallyActorClass *klass) -{ - AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - klass->notify_clutter = cally_actor_real_notify_clutter; - klass->add_actor = cally_actor_real_add_actor; - klass->remove_actor = cally_actor_real_remove_actor; - - /* GObject */ - gobject_class->finalize = cally_actor_finalize; - - /* AtkObject */ - class->get_parent = cally_actor_get_parent; - class->get_index_in_parent = cally_actor_get_index_in_parent; - class->ref_state_set = cally_actor_ref_state_set; - class->initialize = cally_actor_initialize; - class->get_n_children = cally_actor_get_n_children; - class->ref_child = cally_actor_ref_child; - class->get_attributes = cally_actor_get_attributes; -} - -static void -cally_actor_init (CallyActor *cally_actor) -{ - CallyActorPrivate *priv = cally_actor_get_instance_private (cally_actor); - - priv->action_queue = NULL; - priv->action_idle_handler = 0; - - priv->action_list = NULL; - - priv->children = NULL; -} - -static void -cally_actor_finalize (GObject *obj) -{ - CallyActor *cally_actor = NULL; - CallyActorPrivate *priv = NULL; - - cally_actor = CALLY_ACTOR (obj); - priv = cally_actor_get_instance_private (cally_actor); - - _cally_actor_clean_action_list (cally_actor); - - g_clear_handle_id (&priv->action_idle_handler, g_source_remove); - - if (priv->action_queue) - { - g_queue_free (priv->action_queue); - } - - if (priv->children) - { - g_list_free (priv->children); - priv->children = NULL; - } - - G_OBJECT_CLASS (cally_actor_parent_class)->finalize (obj); -} - -/* AtkObject */ - -static AtkObject * -cally_actor_get_parent (AtkObject *obj) -{ - ClutterActor *parent_actor = NULL; - AtkObject *parent = NULL; - ClutterActor *actor = NULL; - CallyActor *cally_actor = NULL; - - g_return_val_if_fail (CALLY_IS_ACTOR (obj), NULL); - - /* Check if we have and assigned parent */ - if (obj->accessible_parent) - return obj->accessible_parent; - - /* Try to get it from the clutter parent */ - cally_actor = CALLY_ACTOR (obj); - actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); - if (actor == NULL) /* Object is defunct */ - return NULL; - - parent_actor = clutter_actor_get_parent (actor); - if (parent_actor == NULL) - return NULL; - - parent = clutter_actor_get_accessible (parent_actor); - - /* FIXME: I need to review the clutter-embed, to check if in this case I - * should get the widget accessible - */ - - return parent; -} - -static gint -cally_actor_get_index_in_parent (AtkObject *obj) -{ - CallyActor *cally_actor = NULL; - ClutterActor *actor = NULL; - ClutterActor *parent_actor = NULL; - ClutterActor *iter; - gint index = -1; - - g_return_val_if_fail (CALLY_IS_ACTOR (obj), -1); - - if (obj->accessible_parent) - { - gint n_children, i; - gboolean found = FALSE; - - n_children = atk_object_get_n_accessible_children (obj->accessible_parent); - for (i = 0; i < n_children; i++) - { - AtkObject *child; - - child = atk_object_ref_accessible_child (obj->accessible_parent, i); - if (child == obj) - found = TRUE; - - g_object_unref (child); - if (found) - return i; - } - return -1; - } - - cally_actor = CALLY_ACTOR (obj); - actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); - if (actor == NULL) /* Object is defunct */ - return -1; - - index = 0; - parent_actor = clutter_actor_get_parent (actor); - if (parent_actor == NULL) - return -1; - - for (iter = clutter_actor_get_first_child (parent_actor); - iter != NULL && iter != actor; - iter = clutter_actor_get_next_sibling (iter)) - { - index += 1; - } - - return index; -} - -static AtkStateSet* -cally_actor_ref_state_set (AtkObject *obj) -{ - ClutterActor *actor = NULL; - AtkStateSet *state_set = NULL; - ClutterStage *stage = NULL; - ClutterActor *focus_actor = NULL; - CallyActor *cally_actor = NULL; - - g_return_val_if_fail (CALLY_IS_ACTOR (obj), NULL); - cally_actor = CALLY_ACTOR (obj); - - state_set = ATK_OBJECT_CLASS (cally_actor_parent_class)->ref_state_set (obj); - - actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); - - if (actor == NULL) /* Object is defunct */ - { - atk_state_set_add_state (state_set, ATK_STATE_DEFUNCT); - } - else - { - if (clutter_actor_get_reactive (actor)) - { - atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE); - atk_state_set_add_state (state_set, ATK_STATE_ENABLED); - } - - if (clutter_actor_is_visible (actor)) - { - atk_state_set_add_state (state_set, ATK_STATE_VISIBLE); - - /* It would be good to also check if the actor is on screen, - like the old and removed clutter_actor_is_on_stage*/ - if (clutter_actor_get_paint_visibility (actor)) - atk_state_set_add_state (state_set, ATK_STATE_SHOWING); - - } - - /* See focus section on implementation notes */ - atk_state_set_add_state (state_set, ATK_STATE_FOCUSABLE); - - stage = CLUTTER_STAGE (clutter_actor_get_stage (actor)); - if (stage != NULL) - { - focus_actor = clutter_stage_get_key_focus (stage); - if (focus_actor == actor) - atk_state_set_add_state (state_set, ATK_STATE_FOCUSED); - } - } - - return state_set; -} - -static gint -cally_actor_get_n_children (AtkObject *obj) -{ - ClutterActor *actor = NULL; - - g_return_val_if_fail (CALLY_IS_ACTOR (obj), 0); - - actor = CALLY_GET_CLUTTER_ACTOR (obj); - - if (actor == NULL) /* State is defunct */ - return 0; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0); - - return clutter_actor_get_n_children (actor); -} - -static AtkObject* -cally_actor_ref_child (AtkObject *obj, - gint i) -{ - ClutterActor *actor = NULL; - ClutterActor *child = NULL; - - g_return_val_if_fail (CALLY_IS_ACTOR (obj), NULL); - - actor = CALLY_GET_CLUTTER_ACTOR (obj); - if (actor == NULL) /* State is defunct */ - return NULL; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); - - if (i >= clutter_actor_get_n_children (actor)) - return NULL; - - child = clutter_actor_get_child_at_index (actor, i); - if (child == NULL) - return NULL; - - return g_object_ref (clutter_actor_get_accessible (child)); -} - -static AtkAttributeSet * -cally_actor_get_attributes (AtkObject *obj) -{ - AtkAttributeSet *attributes; - AtkAttribute *toolkit; - - toolkit = g_new (AtkAttribute, 1); - toolkit->name = g_strdup ("toolkit"); - toolkit->value = g_strdup ("clutter"); - - attributes = g_slist_append (NULL, toolkit); - - return attributes; -} - -/* ClutterContainer */ -static gint -cally_actor_add_actor (ClutterActor *container, - ClutterActor *actor, - gpointer data) -{ - CallyActor *cally_actor = CALLY_ACTOR (data); - CallyActorClass *klass = NULL; - - klass = CALLY_ACTOR_GET_CLASS (cally_actor); - - if (klass->add_actor) - return klass->add_actor (container, actor, data); - else - return 1; -} - -static gint -cally_actor_remove_actor (ClutterActor *container, - ClutterActor *actor, - gpointer data) -{ - CallyActor *cally_actor = CALLY_ACTOR (data); - CallyActorClass *klass = NULL; - - klass = CALLY_ACTOR_GET_CLASS (cally_actor); - - if (klass->remove_actor) - return klass->remove_actor (container, actor, data); - else - return 1; -} - - -static gint -cally_actor_real_add_actor (ClutterActor *container, - ClutterActor *actor, - gpointer data) -{ - AtkObject *atk_parent = ATK_OBJECT (data); - AtkObject *atk_child = clutter_actor_get_accessible (actor); - CallyActor *cally_actor = CALLY_ACTOR (atk_parent); - CallyActorPrivate *priv = cally_actor_get_instance_private (cally_actor); - gint index; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (container), 0); - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0); - - g_object_notify (G_OBJECT (atk_child), "accessible_parent"); - - g_list_free (priv->children); - - priv->children = clutter_actor_get_children (CLUTTER_ACTOR (container)); - - index = g_list_index (priv->children, actor); - g_signal_emit_by_name (atk_parent, "children_changed::add", - index, atk_child, NULL); - - return 1; -} - -static gint -cally_actor_real_remove_actor (ClutterActor *container, - ClutterActor *actor, - gpointer data) -{ - AtkPropertyValues values = { NULL }; - AtkObject* atk_parent = NULL; - AtkObject *atk_child = NULL; - CallyActorPrivate *priv = NULL; - gint index; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (container), 0); - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0); - - atk_parent = ATK_OBJECT (data); - - if (clutter_actor_has_accessible (actor)) - { - atk_child = clutter_actor_get_accessible (actor); - - g_value_init (&values.old_value, G_TYPE_POINTER); - g_value_set_pointer (&values.old_value, atk_parent); - - values.property_name = "accessible-parent"; - - g_object_ref (atk_child); - g_signal_emit_by_name (atk_child, - "property_change::accessible-parent", &values, NULL); - g_object_unref (atk_child); - } - - priv = cally_actor_get_instance_private (CALLY_ACTOR (atk_parent)); - index = g_list_index (priv->children, actor); - g_list_free (priv->children); - - priv->children = clutter_actor_get_children (CLUTTER_ACTOR (container)); - - if (index >= 0 && index <= g_list_length (priv->children)) - g_signal_emit_by_name (atk_parent, "children_changed::remove", - index, atk_child, NULL); - - return 1; -} - -/* AtkComponent implementation */ -static void -cally_actor_component_interface_init (AtkComponentIface *iface) -{ - g_return_if_fail (iface != NULL); - - iface->get_extents = cally_actor_get_extents; - iface->get_mdi_zorder = cally_actor_get_mdi_zorder; - - /* focus management */ - iface->grab_focus = cally_actor_grab_focus; -} - -static void -cally_actor_get_extents (AtkComponent *component, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coord_type) -{ - CallyActor *cally_actor = NULL; - ClutterActor *actor = NULL; - gfloat f_width, f_height; - graphene_point3d_t verts[4]; - ClutterActor *stage = NULL; - - g_return_if_fail (CALLY_IS_ACTOR (component)); - - cally_actor = CALLY_ACTOR (component); - actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); - - if (actor == NULL) /* actor is defunct */ - return; - - /* If the actor is not placed in any stage, we can't compute the - * extents */ - stage = clutter_actor_get_stage (actor); - if (stage == NULL) - return; - - clutter_actor_get_abs_allocation_vertices (actor, verts); - clutter_actor_get_transformed_size (actor, &f_width, &f_height); - - *x = verts[0].x; - *y = verts[0].y; - *width = ceilf (f_width); - *height = ceilf (f_height); -} - -static gint -cally_actor_get_mdi_zorder (AtkComponent *component) -{ - CallyActor *cally_actor = NULL; - ClutterActor *actor = NULL; - - g_return_val_if_fail (CALLY_IS_ACTOR (component), G_MININT); - - cally_actor = CALLY_ACTOR(component); - actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); - - return clutter_actor_get_z_position (actor); -} - -static gboolean -cally_actor_grab_focus (AtkComponent *component) -{ - ClutterActor *actor = NULL; - ClutterActor *stage = NULL; - CallyActor *cally_actor = NULL; - - g_return_val_if_fail (CALLY_IS_ACTOR (component), FALSE); - - /* See focus section on implementation notes */ - cally_actor = CALLY_ACTOR(component); - actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); - stage = clutter_actor_get_stage (actor); - - clutter_stage_set_key_focus (CLUTTER_STAGE (stage), - actor); - - return TRUE; -} - -/* AtkAction implementation */ -static void -cally_actor_action_interface_init (AtkActionIface *iface) -{ - g_return_if_fail (iface != NULL); - - iface->do_action = cally_actor_action_do_action; - iface->get_n_actions = cally_actor_action_get_n_actions; - iface->get_description = cally_actor_action_get_description; - iface->get_keybinding = cally_actor_action_get_keybinding; - iface->get_name = cally_actor_action_get_name; - iface->set_description = cally_actor_action_set_description; -} - -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; - - cally_actor = CALLY_ACTOR (action); - priv = cally_actor_get_instance_private (cally_actor); - - set = atk_object_ref_state_set (ATK_OBJECT (cally_actor)); - - if (atk_state_set_contains_state (set, ATK_STATE_DEFUNCT)) - goto out; - - if (!atk_state_set_contains_state (set, ATK_STATE_SENSITIVE) || - !atk_state_set_contains_state (set, ATK_STATE_SHOWING)) - goto out; - - info = _cally_actor_get_action_info (cally_actor, index); - - if (info == NULL) - goto out; - - if (info->do_action_func == NULL) - goto out; - - if (!priv->action_queue) - priv->action_queue = g_queue_new (); - - g_queue_push_head (priv->action_queue, info); - - 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; -} - -static gboolean -idle_do_action (gpointer data) -{ - CallyActor *cally_actor = NULL; - CallyActorPrivate *priv = NULL; - ClutterActor *actor = NULL; - - cally_actor = CALLY_ACTOR (data); - priv = cally_actor_get_instance_private (cally_actor); - actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); - priv->action_idle_handler = 0; - - if (actor == NULL) /* state is defunct*/ - return FALSE; - - while (!g_queue_is_empty (priv->action_queue)) - { - CallyActorActionInfo *info = NULL; - - info = (CallyActorActionInfo *) g_queue_pop_head (priv->action_queue); - - info->do_action_func (cally_actor, info->user_data); - } - - return FALSE; -} - -static gint -cally_actor_action_get_n_actions (AtkAction *action) -{ - CallyActor *cally_actor = NULL; - CallyActorPrivate *priv = NULL; - - g_return_val_if_fail (CALLY_IS_ACTOR (action), 0); - - cally_actor = CALLY_ACTOR (action); - priv = cally_actor_get_instance_private (cally_actor); - - return g_list_length (priv->action_list); -} - -static const gchar* -cally_actor_action_get_name (AtkAction *action, - gint i) -{ - CallyActor *cally_actor = NULL; - CallyActorActionInfo *info = NULL; - - g_return_val_if_fail (CALLY_IS_ACTOR (action), NULL); - cally_actor = CALLY_ACTOR (action); - info = _cally_actor_get_action_info (cally_actor, i); - - if (info == NULL) - return NULL; - - return info->name; -} - -static const gchar* -cally_actor_action_get_description (AtkAction *action, - gint i) -{ - CallyActor *cally_actor = NULL; - CallyActorActionInfo *info = NULL; - - g_return_val_if_fail (CALLY_IS_ACTOR (action), NULL); - cally_actor = CALLY_ACTOR (action); - info = _cally_actor_get_action_info (cally_actor, i); - - if (info == NULL) - return NULL; - - return info->description; -} - -static gboolean -cally_actor_action_set_description (AtkAction *action, - gint i, - const gchar *desc) -{ - CallyActor *cally_actor = NULL; - CallyActorActionInfo *info = NULL; - - g_return_val_if_fail (CALLY_IS_ACTOR (action), FALSE); - cally_actor = CALLY_ACTOR (action); - info = _cally_actor_get_action_info (cally_actor, i); - - if (info == NULL) - return FALSE; - - g_free (info->description); - info->description = g_strdup (desc); - - return TRUE; -} - -static const gchar* -cally_actor_action_get_keybinding (AtkAction *action, - gint i) -{ - CallyActor *cally_actor = NULL; - CallyActorActionInfo *info = NULL; - - g_return_val_if_fail (CALLY_IS_ACTOR (action), NULL); - cally_actor = CALLY_ACTOR (action); - info = _cally_actor_get_action_info (cally_actor, i); - - if (info == NULL) - return NULL; - - return info->keybinding; -} - -/* Misc functions */ - -/* - * This function is a signal handler for notify signal which gets emitted - * when a property changes value on the ClutterActor associated with the object. - * - * It calls a function for the CallyActor type - */ -static void -cally_actor_notify_clutter (GObject *obj, - GParamSpec *pspec) -{ - CallyActor *cally_actor = NULL; - CallyActorClass *klass = NULL; - - cally_actor = CALLY_ACTOR (clutter_actor_get_accessible (CLUTTER_ACTOR (obj))); - klass = CALLY_ACTOR_GET_CLASS (cally_actor); - - if (klass->notify_clutter) - klass->notify_clutter (obj, pspec); -} - -/* - * This function is a signal handler for notify signal which gets emitted - * when a property changes value on the ClutterActor associated with a CallyActor - * - * It constructs an AtkPropertyValues structure and emits a "property_changed" - * signal which causes the user specified AtkPropertyChangeHandler - * to be called. - */ -static void -cally_actor_real_notify_clutter (GObject *obj, - GParamSpec *pspec) -{ - ClutterActor* actor = CLUTTER_ACTOR (obj); - AtkObject* atk_obj = clutter_actor_get_accessible (CLUTTER_ACTOR(obj)); - AtkState state; - gboolean value; - - if (g_strcmp0 (pspec->name, "visible") == 0) - { - state = ATK_STATE_VISIBLE; - value = clutter_actor_is_visible (actor); - } - else if (g_strcmp0 (pspec->name, "mapped") == 0) - { - /* Clones may temporarily map an actor in order to - * paint it; we don't want this to generate an ATK - * state change - */ - if (clutter_actor_is_painting_unmapped (actor)) - return; - - state = ATK_STATE_SHOWING; - value = clutter_actor_is_mapped (actor); - } - else if (g_strcmp0 (pspec->name, "reactive") == 0) - { - state = ATK_STATE_SENSITIVE; - value = clutter_actor_get_reactive (actor); - } - else - return; - - atk_object_notify_state_change (atk_obj, state, value); -} - -static void -_cally_actor_clean_action_list (CallyActor *cally_actor) -{ - CallyActorPrivate *priv = NULL; - - priv = cally_actor_get_instance_private (cally_actor); - - if (priv->action_list) - { - g_list_free_full (priv->action_list, - (GDestroyNotify) _cally_actor_destroy_action_info); - priv->action_list = NULL; - } -} - -static CallyActorActionInfo * -_cally_actor_get_action_info (CallyActor *cally_actor, - gint index) -{ - CallyActorPrivate *priv = NULL; - GList *node = NULL; - - g_return_val_if_fail (CALLY_IS_ACTOR (cally_actor), NULL); - - priv = cally_actor_get_instance_private (cally_actor); - - if (priv->action_list == NULL) - return NULL; - - node = g_list_nth (priv->action_list, index); - - if (node == NULL) - return NULL; - - return (CallyActorActionInfo *)(node->data); -} - -/** - * cally_actor_add_action: (skip) - * @cally_actor: a #CallyActor - * @action_name: the action name - * @action_description: the action description - * @action_keybinding: the action keybinding - * @action_func: the callback of the action, to be executed with do_action - * - * Adds a new action to be accessed with the #AtkAction interface. - * - * Return value: added action id, or -1 if failure - */ -guint -cally_actor_add_action (CallyActor *cally_actor, - const gchar *action_name, - const gchar *action_description, - const gchar *action_keybinding, - CallyActionFunc action_func) -{ - return cally_actor_add_action_full (cally_actor, - action_name, - action_description, - action_keybinding, - (CallyActionCallback) action_func, - NULL, NULL); -} - -/** - * cally_actor_add_action_full: (rename-to cally_actor_add_action) - * @cally_actor: a #CallyActor - * @action_name: the action name - * @action_description: the action description - * @action_keybinding: the action keybinding - * @callback: (scope notified): the callback of the action - * @user_data: (closure): data to be passed to @callback - * @notify: function to be called when removing the action - * - * Adds a new action to be accessed with the #AtkAction interface. - * - * Return value: added action id, or -1 if failure - */ -guint -cally_actor_add_action_full (CallyActor *cally_actor, - const gchar *action_name, - const gchar *action_description, - const gchar *action_keybinding, - CallyActionCallback callback, - gpointer user_data, - GDestroyNotify notify) -{ - CallyActorActionInfo *info = NULL; - CallyActorPrivate *priv = NULL; - - g_return_val_if_fail (CALLY_IS_ACTOR (cally_actor), -1); - g_return_val_if_fail (callback != NULL, -1); - - priv = cally_actor_get_instance_private (cally_actor); - - info = g_new0 (CallyActorActionInfo, 1); - info->name = g_strdup (action_name); - info->description = g_strdup (action_description); - info->keybinding = g_strdup (action_keybinding); - info->do_action_func = callback; - info->user_data = user_data; - info->notify = notify; - - priv->action_list = g_list_append (priv->action_list, info); - - return g_list_length (priv->action_list); -} - -/** - * cally_actor_remove_action: - * @cally_actor: a #CallyActor - * @action_id: the action id - * - * Removes a action, using the @action_id returned by [method@Actor.add_action] - * - * Return value: %TRUE if the operation was successful, %FALSE otherwise - */ -gboolean -cally_actor_remove_action (CallyActor *cally_actor, - gint action_id) -{ - GList *list_node = NULL; - CallyActorPrivate *priv = NULL; - - g_return_val_if_fail (CALLY_IS_ACTOR (cally_actor), FALSE); - priv = cally_actor_get_instance_private (cally_actor); - - list_node = g_list_nth (priv->action_list, action_id - 1); - - if (!list_node) - return FALSE; - - _cally_actor_destroy_action_info (list_node->data, NULL); - - priv->action_list = g_list_remove_link (priv->action_list, list_node); - - return TRUE; -} - -/** - * cally_actor_remove_action_by_name: - * @cally_actor: a #CallyActor - * @action_name: the name of the action to remove - * - * Removes an action, using the @action_name used when the action was added - * with [method@Actor.add_action] - * - * Return value: %TRUE if the operation was successful, %FALSE otherwise - */ -gboolean -cally_actor_remove_action_by_name (CallyActor *cally_actor, - const gchar *action_name) -{ - GList *node = NULL; - gboolean action_found = FALSE; - CallyActorPrivate *priv = NULL; - - g_return_val_if_fail (CALLY_IS_ACTOR (cally_actor), FALSE); - priv = cally_actor_get_instance_private (cally_actor); - - for (node = priv->action_list; node && !action_found; - node = node->next) - { - CallyActorActionInfo *ainfo = node->data; - - if (!g_ascii_strcasecmp (ainfo->name, action_name)) - { - action_found = TRUE; - break; - } - } - if (!action_found) - return FALSE; - - _cally_actor_destroy_action_info (node->data, NULL); - priv->action_list = g_list_remove_link (priv->action_list, node); - - return TRUE; -} - - -static void -_cally_actor_destroy_action_info (gpointer action_info, - gpointer user_data) -{ - CallyActorActionInfo *info = action_info; - - g_assert (info != NULL); - - g_free (info->name); - g_free (info->description); - g_free (info->keybinding); - - if (info->notify) - info->notify (info->user_data); - - g_free (info); -} diff --git a/mutter/clutter/clutter/cally/cally-actor.h b/mutter/clutter/clutter/cally/cally-actor.h deleted file mode 100644 index 433048c..0000000 --- a/mutter/clutter/clutter/cally/cally-actor.h +++ /dev/null @@ -1,123 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2008 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * Some parts are based on GailWidget from GAIL - * GAIL - The GNOME Accessibility Implementation Library - * Copyright 2001, 2002, 2003 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -#include "clutter/clutter.h" - -G_BEGIN_DECLS - -#define CALLY_TYPE_ACTOR (cally_actor_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (CallyActor, - cally_actor, - CALLY, - ACTOR, - AtkGObjectAccessible) - -typedef struct _CallyActor CallyActor; -typedef struct _CallyActorClass CallyActorClass; -typedef struct _CallyActorPrivate CallyActorPrivate; - -/** - * CallyActionFunc: - * @cally_actor: a #CallyActor - * - * Action function, to be used on #AtkAction implementations as a individual - * action - */ -typedef void (* CallyActionFunc) (CallyActor *cally_actor); - -/** - * CallyActionCallback: - * @cally_actor: a #CallyActor - * @user_data: user data passed to the function - * - * Action function, to be used on #AtkAction implementations as - * an individual action. - * - * Unlike #CallyActionFunc, this function uses the @user_data - * argument passed to [method@Actor.add_action_full]. - */ -typedef void (* CallyActionCallback) (CallyActor *cally_actor, - gpointer user_data); - -/** - * CallyActorClass: - * @notify_clutter: Signal handler for notify signal on Clutter actor - * @add_actor: Signal handler for child-added signal on Clutter actor - * @remove_actor: Signal handler for child-removed signal on Clutter actor - */ -struct _CallyActorClass -{ - /*< private >*/ - AtkGObjectAccessibleClass parent_class; - - /*< public >*/ - void (*notify_clutter) (GObject *object, - GParamSpec *pspec); - - gint (*add_actor) (ClutterActor *container, - ClutterActor *actor, - gpointer data); - - gint (*remove_actor) (ClutterActor *container, - ClutterActor *actor, - gpointer data); -}; - -CLUTTER_EXPORT -AtkObject* cally_actor_new (ClutterActor *actor); - -CLUTTER_EXPORT -guint cally_actor_add_action (CallyActor *cally_actor, - const gchar *action_name, - const gchar *action_description, - const gchar *action_keybinding, - CallyActionFunc action_func); -CLUTTER_EXPORT -guint cally_actor_add_action_full (CallyActor *cally_actor, - const gchar *action_name, - const gchar *action_description, - const gchar *action_keybinding, - CallyActionCallback callback, - gpointer user_data, - GDestroyNotify notify); - -CLUTTER_EXPORT -gboolean cally_actor_remove_action (CallyActor *cally_actor, - gint action_id); - -CLUTTER_EXPORT -gboolean cally_actor_remove_action_by_name (CallyActor *cally_actor, - const gchar *action_name); - -G_END_DECLS diff --git a/mutter/clutter/clutter/cally/cally-clone.c b/mutter/clutter/clutter/cally/cally-clone.c deleted file mode 100644 index 382b99c..0000000 --- a/mutter/clutter/clutter/cally/cally-clone.c +++ /dev/null @@ -1,127 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2010 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * 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 . - */ - -/** - * CallyClone: - * - * Implementation of the ATK interfaces for a #ClutterClone - * - * #CallyClone implements the required ATK interfaces of [class@Clutter.Clone] - * - * In particular it sets a proper role for the clone, as just a image, - * as it is the sanest and simplest approach. - */ - -/* Design rationale for CallyClone: - * - * In the old times, it was just ClutterCloneTexture. So, from a a11y POV - * CallyCloneTexture was just another image, like ClutterTexture, and if - * it was a clone was irrelevant. So on cally-0.8, CallyCloneTexture - * expose a object with role ATK_ROLE_IMAGE. But now, ClutterClone is more - * general. You can clone any object, including groups, and made things - * like have one text entry, and a clone with different properties in the - * same window, updated both at once. - * - * The question is if the idea is have a ClutterClone as a "first-class" - * citizen inside the stage hierarchy (full clone), or it is just supposed - * to be a mirror image of the original object. - * - * In the case of the a11y POV this would mean that if the text changes on - * the source, the clone should emit as well the text-changing signals. - * - * As ClutterClone smartly just paint the same object with different - * parameters, this would mean that it should be the cally object the one - * that should replicate the source clutter hierarchy to do that, - * something that just sound crazy. - * - * Taking into account that: - * - * - ClutterClone doesn't re-emit mirrored signals from the source - * I think that likely the answer would be "yes, it is just a - * mirrored image, not a real full clone". - * - * - You can't interact directly with the clone (ie: focus, and so on). - * Its basic usage (right now) is clone textures. - * - * Any other solution could be overwhelming. - * - * I think that the final solution would be that ClutterClone from the - * a11y POV should still be managed as a image (with the proper properties, - * position, size, etc.). - */ -#include "config.h" - -#include "cally/cally-clone.h" -#include "cally/cally-actor-private.h" - -/* AtkObject */ -static void cally_clone_real_initialize (AtkObject *obj, - gpointer data); - -G_DEFINE_TYPE (CallyClone, cally_clone, CALLY_TYPE_ACTOR) - -static void -cally_clone_class_init (CallyCloneClass *klass) -{ -/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */ - AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - - class->initialize = cally_clone_real_initialize; -} - -static void -cally_clone_init (CallyClone *clone) -{ - /* nothing to do yet */ -} - -/** - * cally_clone_new: - * @actor: a #ClutterActor - * - * Creates a new #CallyClone for the given @actor. @actor must be a - * [class@Clutter.Clone]. - * - * Return value: the newly created #AtkObject - */ -AtkObject* -cally_clone_new (ClutterActor *actor) -{ - GObject *object = NULL; - AtkObject *accessible = NULL; - - g_return_val_if_fail (CLUTTER_IS_CLONE (actor), NULL); - - object = g_object_new (CALLY_TYPE_CLONE, NULL); - - accessible = ATK_OBJECT (object); - atk_object_initialize (accessible, actor); - - return accessible; -} - -static void -cally_clone_real_initialize (AtkObject *obj, - gpointer data) -{ - ATK_OBJECT_CLASS (cally_clone_parent_class)->initialize (obj, data); - - obj->role = ATK_ROLE_IMAGE; -} diff --git a/mutter/clutter/clutter/cally/cally-clone.h b/mutter/clutter/clutter/cally/cally-clone.h deleted file mode 100644 index 26c32fb..0000000 --- a/mutter/clutter/clutter/cally/cally-clone.h +++ /dev/null @@ -1,53 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2010 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * 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 . - */ - -#pragma once - -#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter.h" -#include "cally/cally-actor.h" - -G_BEGIN_DECLS - -#define CALLY_TYPE_CLONE (cally_clone_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (CallyClone, - cally_clone, - CALLY, - CLONE, - CallyActor) - -typedef struct _CallyClone CallyClone; -typedef struct _CallyCloneClass CallyCloneClass; - -struct _CallyCloneClass -{ - /*< private >*/ - CallyActorClass parent_class; -}; - -CLUTTER_EXPORT -AtkObject *cally_clone_new (ClutterActor *actor); - -G_END_DECLS diff --git a/mutter/clutter/clutter/cally/cally-factory.h b/mutter/clutter/clutter/cally/cally-factory.h deleted file mode 100644 index 2007bdb..0000000 --- a/mutter/clutter/clutter/cally/cally-factory.h +++ /dev/null @@ -1,108 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2008 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * Based on gailfactory.h from GAIL - * Copyright 2001, 2002, 2003 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -#pragma once - -#include -#include - -/** - * CALLY_ACCESSIBLE_FACTORY: - * @type: GType of the accessible which is created by the factory - * @type_as_function: prefix of the accessible object methods - * @opt_create_accessible: method to instantiate the accessibility object - * - * Defines a new #AtkObjectFactory factory to create accessible - * objects of a specific GType. It defines the factory GType and also - * overrides the proper #AtkObjectFactory methods. - * - * It assumes that the accessibility object provides a - * @opt_create_accessible method in order to create the accessibility - * object. It returns a @type GType object. - */ -#define CALLY_ACCESSIBLE_FACTORY(type, type_as_function, opt_create_accessible) \ - \ -static GType \ -type_as_function ## _factory_get_accessible_type (void) \ -{ \ - return type; \ -} \ - \ -static AtkObject* \ -type_as_function ## _factory_create_accessible (GObject *obj) \ -{ \ - ClutterActor *actor; \ - AtkObject *accessible; \ - \ - g_return_val_if_fail (CLUTTER_ACTOR (obj), NULL); \ - \ - actor = CLUTTER_ACTOR (obj); \ - \ - accessible = opt_create_accessible (actor); \ - \ - return accessible; \ -} \ - \ -static void \ -type_as_function ## _factory_class_init (AtkObjectFactoryClass *klass) \ -{ \ - klass->create_accessible = type_as_function ## _factory_create_accessible; \ - klass->get_accessible_type = type_as_function ## _factory_get_accessible_type;\ -} \ - \ -static GType \ -type_as_function ## _factory_get_type (void) \ -{ \ - static GType t = 0; \ - \ - if (!t) \ - { \ - char *name; \ - static const GTypeInfo tinfo = \ - { \ - sizeof (AtkObjectFactoryClass), \ - NULL, NULL, (GClassInitFunc) type_as_function ## _factory_class_init, \ - NULL, NULL, sizeof (AtkObjectFactory), 0, NULL, NULL \ - }; \ - \ - name = g_strconcat (g_type_name (type), "Factory", NULL); \ - t = g_type_register_static ( \ - ATK_TYPE_OBJECT_FACTORY, name, &tinfo, 0); \ - g_free (name); \ - } \ - \ - return t; \ -} - -/** - * CALLY_ACTOR_SET_FACTORY: - * @widget_type: GType of the clutter actor - * @type_as_function: prefix of the accessible object methods - * - * Sets the #AtkObjectFactory to be used in order to instantiate - * accessibility objects for the actor which GType is @widget_type. - */ -#define CALLY_ACTOR_SET_FACTORY(widget_type, type_as_function) \ - atk_registry_set_factory_type (atk_get_default_registry (), \ - widget_type, \ - type_as_function ## _factory_get_type ()) diff --git a/mutter/clutter/clutter/cally/cally-main.h b/mutter/clutter/clutter/cally/cally-main.h deleted file mode 100644 index ce50513..0000000 --- a/mutter/clutter/clutter/cally/cally-main.h +++ /dev/null @@ -1,41 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2008 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * Some parts are based on GailWidget from GAIL - * GAIL - The GNOME Accessibility Implementation Library - * Copyright 2001, 2002, 2003 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include -#include - -G_BEGIN_DECLS - -CLUTTER_EXPORT -gboolean cally_get_cally_initialized (void); -CLUTTER_EXPORT -gboolean cally_accessibility_init (void); - -G_END_DECLS diff --git a/mutter/clutter/clutter/cally/cally-root.c b/mutter/clutter/clutter/cally/cally-root.c deleted file mode 100644 index 53312f9..0000000 --- a/mutter/clutter/clutter/cally/cally-root.c +++ /dev/null @@ -1,294 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2008 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * 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 . - */ - -/** - * CallyRoot: - * - * Root object for the Cally toolkit - * - * #CallyRoot is the root object of the accessibility tree-like - * hierarchy, exposing the application level. - * - * Somewhat equivalent to #GailTopLevel. We consider that this class - * expose the a11y information of the [class@Clutter.StageManager], as the - * children of this object are the different [class@Clutter.Stage] managed (so - * the [class@GObject.Object] used in the [method@Atk.Object.initialize] is the - * [class@Clutter.StageManager]). - */ - -#include "config.h" - -#include "cally/cally-root.h" - -#include "clutter/clutter-actor.h" -#include "clutter/clutter-stage-private.h" -#include "clutter/clutter-stage-manager.h" - - -/* GObject */ -static void cally_root_finalize (GObject *object); - -/* AtkObject.h */ -static void cally_root_initialize (AtkObject *accessible, - gpointer data); -static gint cally_root_get_n_children (AtkObject *obj); -static AtkObject * cally_root_ref_child (AtkObject *obj, - gint i); -static AtkObject * cally_root_get_parent (AtkObject *obj); -static const char * cally_root_get_name (AtkObject *obj); - -/* Private */ -static void cally_util_stage_added_cb (ClutterStageManager *stage_manager, - ClutterStage *stage, - gpointer data); -static void cally_util_stage_removed_cb (ClutterStageManager *stage_manager, - ClutterStage *stage, - gpointer data); - -typedef struct _CallyRootPrivate -{ -/* We save the CallyStage objects. Other option could save the stage - * list, and then just get the a11y object on the ref_child, etc. But - * the ref_child is more common that the init and the stage-add, - * stage-remove, so we avoid getting the accessible object - * constantly - */ - GSList *stage_list; - - /* signals id */ - gulong stage_added_id; - gulong stage_removed_id; -} CallyRootPrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (CallyRoot, cally_root, ATK_TYPE_GOBJECT_ACCESSIBLE) - -static void -cally_root_class_init (CallyRootClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - - gobject_class->finalize = cally_root_finalize; - - /* AtkObject */ - class->get_n_children = cally_root_get_n_children; - class->ref_child = cally_root_ref_child; - class->get_parent = cally_root_get_parent; - class->initialize = cally_root_initialize; - class->get_name = cally_root_get_name; -} - -static void -cally_root_init (CallyRoot *root) -{ - CallyRootPrivate *priv = cally_root_get_instance_private (root); - - priv->stage_list = NULL; - priv->stage_added_id = 0; - priv->stage_removed_id = 0; -} - -/** - * cally_root_new: - * - * Creates a new #CallyRoot object. - * - * Return value: the newly created #AtkObject - */ -AtkObject* -cally_root_new (void) -{ - GObject *object = NULL; - AtkObject *accessible = NULL; - ClutterStageManager *stage_manager = NULL; - - object = g_object_new (CALLY_TYPE_ROOT, NULL); - - accessible = ATK_OBJECT (object); - stage_manager = clutter_stage_manager_get_default (); - - atk_object_initialize (accessible, stage_manager); - - return accessible; -} - -static void -cally_root_finalize (GObject *object) -{ - CallyRoot *root = CALLY_ROOT (object); - GObject *stage_manager = NULL; - CallyRootPrivate *priv; - - g_return_if_fail (CALLY_IS_ROOT (object)); - - priv = cally_root_get_instance_private (root); - if (priv->stage_list) - { - g_slist_free (priv->stage_list); - priv->stage_list = NULL; - } - - stage_manager = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (root)); - - g_clear_signal_handler (&priv->stage_added_id, stage_manager); - - g_clear_signal_handler (&priv->stage_removed_id, stage_manager); - - G_OBJECT_CLASS (cally_root_parent_class)->finalize (object); -} - -/* AtkObject.h */ -static void -cally_root_initialize (AtkObject *accessible, - gpointer data) -{ - ClutterStageManager *stage_manager = NULL; - const GSList *iter = NULL; - const GSList *stage_list = NULL; - ClutterStage *clutter_stage = NULL; - AtkObject *cally_stage = NULL; - CallyRoot *root = CALLY_ROOT (accessible); - CallyRootPrivate *priv = cally_root_get_instance_private (root); - - - accessible->role = ATK_ROLE_APPLICATION; - accessible->accessible_parent = NULL; - - /* children initialization */ - stage_manager = CLUTTER_STAGE_MANAGER (data); - stage_list = clutter_stage_manager_peek_stages (stage_manager); - - for (iter = stage_list; iter != NULL; iter = g_slist_next (iter)) - { - clutter_stage = CLUTTER_STAGE (iter->data); - cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (clutter_stage)); - - atk_object_set_parent (cally_stage, ATK_OBJECT (root)); - - priv->stage_list = g_slist_append (priv->stage_list, cally_stage); - } - - priv->stage_added_id = - g_signal_connect (G_OBJECT (stage_manager), "stage-added", - G_CALLBACK (cally_util_stage_added_cb), root); - - priv->stage_removed_id = - g_signal_connect (G_OBJECT (stage_manager), "stage-removed", - G_CALLBACK (cally_util_stage_removed_cb), root); - - ATK_OBJECT_CLASS (cally_root_parent_class)->initialize (accessible, data); -} - - -static gint -cally_root_get_n_children (AtkObject *obj) -{ - CallyRoot *root = CALLY_ROOT (obj); - CallyRootPrivate *priv = cally_root_get_instance_private (root); - - return g_slist_length (priv->stage_list); -} - -static AtkObject* -cally_root_ref_child (AtkObject *obj, - gint i) -{ - CallyRoot *cally_root = CALLY_ROOT (obj); - CallyRootPrivate *priv = cally_root_get_instance_private (cally_root); - GSList *stage_list = NULL; - gint num = 0; - AtkObject *item = NULL; - - stage_list = priv->stage_list; - num = g_slist_length (stage_list); - - g_return_val_if_fail ((i < num)&&(i >= 0), NULL); - - item = g_slist_nth_data (stage_list, i); - if (!item) - { - return NULL; - } - - g_object_ref (item); - - return item; -} - -static AtkObject* -cally_root_get_parent (AtkObject *obj) -{ - return NULL; -} - -static const char * -cally_root_get_name (AtkObject *obj) -{ - return g_get_prgname (); -} - -/* -------------------------------- PRIVATE --------------------------------- */ - -static void -cally_util_stage_added_cb (ClutterStageManager *stage_manager, - ClutterStage *stage, - gpointer data) -{ - CallyRoot *root = CALLY_ROOT (data); - AtkObject *cally_stage = NULL; - CallyRootPrivate *priv = cally_root_get_instance_private (root); - - gint index = -1; - - cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); - - atk_object_set_parent (cally_stage, ATK_OBJECT (root)); - - priv->stage_list = g_slist_append (priv->stage_list, cally_stage); - - index = g_slist_index (priv->stage_list, cally_stage); - g_signal_emit_by_name (root, "children_changed::add", - index, cally_stage, NULL); - g_signal_emit_by_name (cally_stage, "create", 0); -} - -static void -cally_util_stage_removed_cb (ClutterStageManager *stage_manager, - ClutterStage *stage, - gpointer data) -{ - CallyRoot *root = CALLY_ROOT (data); - AtkObject *cally_stage = NULL; - CallyRootPrivate *priv - = cally_root_get_instance_private (root); - gint index = -1; - - cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); - - index = g_slist_index (priv->stage_list, cally_stage); - - priv->stage_list = g_slist_remove (priv->stage_list, - cally_stage); - - index = g_slist_index (priv->stage_list, cally_stage); - g_signal_emit_by_name (root, "children_changed::remove", - index, cally_stage, NULL); - g_signal_emit_by_name (cally_stage, "destroy", 0); -} diff --git a/mutter/clutter/clutter/cally/cally-root.h b/mutter/clutter/clutter/cally/cally-root.h deleted file mode 100644 index d4efb93..0000000 --- a/mutter/clutter/clutter/cally/cally-root.h +++ /dev/null @@ -1,54 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2009 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * 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 . - */ - -#pragma once - -#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -#include "clutter/clutter.h" - -G_BEGIN_DECLS - -#define CALLY_TYPE_ROOT (cally_root_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (CallyRoot, - cally_root, - CALLY, - ROOT, - AtkGObjectAccessible) - -typedef struct _CallyRoot CallyRoot; -typedef struct _CallyRootClass CallyRootClass; - -struct _CallyRootClass -{ - /*< private >*/ - AtkGObjectAccessibleClass parent_class; -}; - -CLUTTER_EXPORT -AtkObject *cally_root_new (void); - -G_END_DECLS diff --git a/mutter/clutter/clutter/cally/cally-stage.c b/mutter/clutter/clutter/cally/cally-stage.c deleted file mode 100644 index 6526a87..0000000 --- a/mutter/clutter/clutter/cally/cally-stage.c +++ /dev/null @@ -1,266 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2008 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * 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 . - */ - -/** - * CallyStage: - * - * Implementation of the ATK interfaces for a #ClutterStage - * - * #CallyStage implements the required ATK interfaces for [class@Clutter.Stage] - * - * Some implementation details: at this moment #CallyStage is used as - * the most similar Window object in this toolkit (ie: emitting window - * related signals), although the real purpose of [class@Clutter.Stage] is - * being a canvas. Anyway, this is required for applications using - * just clutter, or directly [class@Clutter.Stage] - */ -#include "config.h" - -#include "cally/cally-stage.h" -#include "cally/cally-actor-private.h" - -/* AtkObject.h */ -static void cally_stage_real_initialize (AtkObject *obj, - gpointer data); -static AtkStateSet* cally_stage_ref_state_set (AtkObject *obj); - -/* AtkWindow */ -static void cally_stage_window_interface_init (AtkWindowIface *iface); - -/* Auxiliary */ -static void cally_stage_activate_cb (ClutterStage *stage, - gpointer data); -static void cally_stage_deactivate_cb (ClutterStage *stage, - gpointer data); - -typedef struct _CallyStagePrivate -{ - /* NULL means that the stage will receive the focus */ - ClutterActor *key_focus; - - gboolean active; -} CallyStagePrivate; - -G_DEFINE_TYPE_WITH_CODE (CallyStage, - cally_stage, - CALLY_TYPE_ACTOR, - G_ADD_PRIVATE (CallyStage) - G_IMPLEMENT_INTERFACE (ATK_TYPE_WINDOW, - cally_stage_window_interface_init)); - -static void -cally_stage_class_init (CallyStageClass *klass) -{ - AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - - /* AtkObject */ - class->initialize = cally_stage_real_initialize; - class->ref_state_set = cally_stage_ref_state_set; -} - -static void -cally_stage_init (CallyStage *cally_stage) -{ - CallyStagePrivate *priv = cally_stage_get_instance_private (cally_stage); - - priv->active = FALSE; -} - -/** - * cally_stage_new: - * @actor: a #ClutterActor - * - * Creates a new #CallyStage for the given @actor. @actor should be a - * [class@Clutter.Stage]. - * - * Return value: the newly created #AtkObject - */ -AtkObject* -cally_stage_new (ClutterActor *actor) -{ - GObject *object = NULL; - AtkObject *accessible = NULL; - - g_return_val_if_fail (CLUTTER_IS_STAGE (actor), NULL); - - object = g_object_new (CALLY_TYPE_STAGE, NULL); - - accessible = ATK_OBJECT (object); - atk_object_initialize (accessible, actor); - - return accessible; -} - -static void -cally_stage_notify_key_focus_cb (ClutterStage *stage, - GParamSpec *pspec, - CallyStage *self) -{ - ClutterActor *key_focus = NULL; - AtkObject *new = NULL; - CallyStagePrivate *priv = cally_stage_get_instance_private (self); - - if (priv->active == FALSE) - return; - - key_focus = clutter_stage_get_key_focus (stage); - - if (key_focus != priv->key_focus) - { - AtkObject *old = NULL; - - if (priv->key_focus != NULL) - { - if (priv->key_focus != CLUTTER_ACTOR (stage)) - { - g_object_remove_weak_pointer (G_OBJECT (priv->key_focus), - (gpointer *) &priv->key_focus); - } - old = clutter_actor_get_accessible (priv->key_focus); - } - else - old = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); - - atk_object_notify_state_change (old, - ATK_STATE_FOCUSED, - FALSE); - } - - /* we keep notifying the focus gain without checking previous - * key-focus to avoid some missing events due timing - */ - priv->key_focus = key_focus; - - if (key_focus != NULL) - { - /* ensure that if the key focus goes away, the field inside - * CallyStage is reset. see bug: - * - * https://bugzilla.gnome.org/show_bug.cgi?id=692706 - * - * we remove the weak pointer above. - */ - if (key_focus != CLUTTER_ACTOR (stage)) - { - g_object_add_weak_pointer (G_OBJECT (priv->key_focus), - (gpointer *) &priv->key_focus); - } - - new = clutter_actor_get_accessible (key_focus); - } - else - new = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); - - atk_object_notify_state_change (new, - ATK_STATE_FOCUSED, - TRUE); -} - -static void -cally_stage_real_initialize (AtkObject *obj, - gpointer data) -{ - ClutterStage *stage = NULL; - - g_return_if_fail (CALLY_IS_STAGE (obj)); - - ATK_OBJECT_CLASS (cally_stage_parent_class)->initialize (obj, data); - - stage = CLUTTER_STAGE (CALLY_GET_CLUTTER_ACTOR (obj)); - - g_signal_connect (stage, "activate", G_CALLBACK (cally_stage_activate_cb), obj); - g_signal_connect (stage, "deactivate", G_CALLBACK (cally_stage_deactivate_cb), obj); - g_signal_connect (stage, "notify::key-focus", - G_CALLBACK (cally_stage_notify_key_focus_cb), obj); - - atk_object_set_role (obj, ATK_ROLE_WINDOW); -} - -static AtkStateSet* -cally_stage_ref_state_set (AtkObject *obj) -{ - CallyStage *cally_stage = NULL; - AtkStateSet *state_set = NULL; - ClutterStage *stage = NULL; - CallyStagePrivate *priv; - - g_return_val_if_fail (CALLY_IS_STAGE (obj), NULL); - cally_stage = CALLY_STAGE (obj); - priv = cally_stage_get_instance_private (cally_stage); - - state_set = ATK_OBJECT_CLASS (cally_stage_parent_class)->ref_state_set (obj); - stage = CLUTTER_STAGE (CALLY_GET_CLUTTER_ACTOR (cally_stage)); - - if (stage == NULL) - return state_set; - - if (priv->active) - atk_state_set_add_state (state_set, ATK_STATE_ACTIVE); - - return state_set; -} - -/* AtkWindow */ -static void -cally_stage_window_interface_init (AtkWindowIface *iface) -{ - /* At this moment AtkWindow is just about signals */ -} - -/* Auxiliary */ -static void -cally_stage_activate_cb (ClutterStage *stage, - gpointer data) -{ - CallyStage *cally_stage = NULL; - CallyStagePrivate *priv; - - g_return_if_fail (CALLY_IS_STAGE (data)); - - cally_stage = CALLY_STAGE (data); - priv = cally_stage_get_instance_private (cally_stage); - - priv->active = TRUE; - - atk_object_notify_state_change (ATK_OBJECT (cally_stage), - ATK_STATE_ACTIVE, TRUE); - - g_signal_emit_by_name (cally_stage, "activate", 0); -} - -static void -cally_stage_deactivate_cb (ClutterStage *stage, - gpointer data) -{ - CallyStage *cally_stage = NULL; - CallyStagePrivate *priv; - - g_return_if_fail (CALLY_IS_STAGE (data)); - - cally_stage = CALLY_STAGE (data); - priv = cally_stage_get_instance_private (cally_stage); - - priv->active = FALSE; - - atk_object_notify_state_change (ATK_OBJECT (cally_stage), - ATK_STATE_ACTIVE, FALSE); - - g_signal_emit_by_name (cally_stage, "deactivate", 0); -} diff --git a/mutter/clutter/clutter/cally/cally-stage.h b/mutter/clutter/clutter/cally/cally-stage.h deleted file mode 100644 index c452882..0000000 --- a/mutter/clutter/clutter/cally/cally-stage.h +++ /dev/null @@ -1,53 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2008 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * 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 . - */ - -#pragma once - -#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cally/cally-actor.h" -#include "clutter/clutter.h" - -G_BEGIN_DECLS - -#define CALLY_TYPE_STAGE (cally_stage_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (CallyStage, - cally_stage, - CALLY, - STAGE, - CallyActor) - -typedef struct _CallyStage CallyStage; -typedef struct _CallyStageClass CallyStageClass; - -struct _CallyStageClass -{ - /*< private >*/ - CallyActorClass parent_class; -}; - -CLUTTER_EXPORT -AtkObject *cally_stage_new (ClutterActor *actor); - -G_END_DECLS diff --git a/mutter/clutter/clutter/cally/cally-text.c b/mutter/clutter/clutter/cally/cally-text.c deleted file mode 100644 index 625d0a1..0000000 --- a/mutter/clutter/clutter/cally/cally-text.c +++ /dev/null @@ -1,2329 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2009 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * Some parts are based on GailLabel, GailEntry, GailTextView from GAIL - * GAIL - The GNOME Accessibility Implementation Library - * Copyright 2001, 2002, 2003 Sun Microsystems Inc. - * - * Implementation of atk_text_get_text_[before/at/after]_offset - * copied from gtkpango.c, part of GTK+ project - * Copyright (c) 2010 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 . - */ - -/** - * CallyText: - * - * Implementation of the ATK interfaces for a [class@Clutter.Text] - * - * #CallyText implements the required ATK interfaces of - * [class@Clutter.Text], #AtkText and #AtkEditableText - */ - -#include "config.h" - -#include "cally/cally-text.h" -#include "cally/cally-actor-private.h" - -#include "clutter/clutter-color.h" -#include "clutter/clutter-main.h" -#include "clutter/clutter-text.h" - -static void cally_text_finalize (GObject *obj); - -/* AtkObject */ -static void cally_text_real_initialize (AtkObject *obj, - gpointer data); -static AtkStateSet* cally_text_ref_state_set (AtkObject *obj); - -/* atkaction */ - -static void _cally_text_activate_action (CallyActor *cally_actor); -static void _check_activate_action (CallyText *cally_text, - ClutterText *clutter_text); - -/* AtkText */ -static void cally_text_text_interface_init (AtkTextIface *iface); -static gchar* cally_text_get_text (AtkText *text, - gint start_offset, - gint end_offset); -static gunichar cally_text_get_character_at_offset (AtkText *text, - gint offset); -static gchar* cally_text_get_text_before_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset); -static gchar* cally_text_get_text_at_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset); -static gchar* cally_text_get_text_after_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset); -static gint cally_text_get_caret_offset (AtkText *text); -static gboolean cally_text_set_caret_offset (AtkText *text, - gint offset); -static gint cally_text_get_character_count (AtkText *text); -static gint cally_text_get_n_selections (AtkText *text); -static gchar* cally_text_get_selection (AtkText *text, - gint selection_num, - gint *start_offset, - gint *end_offset); -static gboolean cally_text_add_selection (AtkText *text, - gint start_offset, - gint end_offset); -static gboolean cally_text_remove_selection (AtkText *text, - gint selection_num); -static gboolean cally_text_set_selection (AtkText *text, - gint selection_num, - gint start_offset, - gint end_offset); -static AtkAttributeSet* cally_text_get_run_attributes (AtkText *text, - gint offset, - gint *start_offset, - gint *end_offset); -static AtkAttributeSet* cally_text_get_default_attributes (AtkText *text); -static void cally_text_get_character_extents (AtkText *text, - gint offset, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coords); -static gint cally_text_get_offset_at_point (AtkText *text, - gint x, - gint y, - AtkCoordType coords); - -static void _cally_text_get_selection_bounds (ClutterText *clutter_text, - gint *start_offset, - gint *end_offset); -static void _cally_text_insert_text_cb (ClutterText *clutter_text, - gchar *new_text, - gint new_text_length, - gint *position, - gpointer data); -static void _cally_text_delete_text_cb (ClutterText *clutter_text, - gint start_pos, - gint end_pos, - gpointer data); -static gboolean _idle_notify_insert (gpointer data); -static void _notify_insert (CallyText *cally_text); -static void _notify_delete (CallyText *cally_text); - -/* AtkEditableText */ -static void cally_text_editable_text_interface_init (AtkEditableTextIface *iface); -static void cally_text_set_text_contents (AtkEditableText *text, - const gchar *string); -static void cally_text_insert_text (AtkEditableText *text, - const gchar *string, - gint length, - gint *position); -static void cally_text_delete_text (AtkEditableText *text, - gint start_pos, - gint end_pos); - -/* CallyActor */ -static void cally_text_notify_clutter (GObject *obj, - GParamSpec *pspec); - -static gboolean _check_for_selection_change (CallyText *cally_text, - ClutterText *clutter_text); - -/* Misc functions */ -static AtkAttributeSet* _cally_misc_add_attribute (AtkAttributeSet *attrib_set, - AtkTextAttribute attr, - gchar *value); - -static AtkAttributeSet* _cally_misc_layout_get_run_attributes (AtkAttributeSet *attrib_set, - ClutterText *clutter_text, - gint offset, - gint *start_offset, - gint *end_offset); - -static AtkAttributeSet* _cally_misc_layout_get_default_attributes (AtkAttributeSet *attrib_set, - ClutterText *text); - -static int _cally_misc_get_index_at_point (ClutterText *clutter_text, - gint x, - gint y, - AtkCoordType coords); - -typedef struct _CallyTextPrivate -{ - /* Cached ClutterText values*/ - gint cursor_position; - gint selection_bound; - - /* text_changed::insert stuff */ - const gchar *signal_name_insert; - gint position_insert; - gint length_insert; - guint insert_idle_handler; - - /* text_changed::delete stuff */ - const gchar *signal_name_delete; - gint position_delete; - gint length_delete; - - /* action */ - guint activate_action_id; -} CallyTextPrivate; - -G_DEFINE_TYPE_WITH_CODE (CallyText, - cally_text, - CALLY_TYPE_ACTOR, - G_ADD_PRIVATE (CallyText) - G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, - cally_text_text_interface_init) - G_IMPLEMENT_INTERFACE (ATK_TYPE_EDITABLE_TEXT, - cally_text_editable_text_interface_init)); - -static void -cally_text_class_init (CallyTextClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - CallyActorClass *cally_class = CALLY_ACTOR_CLASS (klass); - - gobject_class->finalize = cally_text_finalize; - - class->initialize = cally_text_real_initialize; - class->ref_state_set = cally_text_ref_state_set; - - cally_class->notify_clutter = cally_text_notify_clutter; -} - -static void -cally_text_init (CallyText *cally_text) -{ - CallyTextPrivate *priv = cally_text_get_instance_private (cally_text); - - priv->cursor_position = 0; - priv->selection_bound = 0; - - priv->signal_name_insert = NULL; - priv->position_insert = -1; - priv->length_insert = -1; - priv->insert_idle_handler = 0; - - priv->signal_name_delete = NULL; - priv->position_delete = -1; - priv->length_delete = -1; - - priv->activate_action_id = 0; -} - -static void -cally_text_finalize (GObject *obj) -{ - CallyText *cally_text = CALLY_TEXT (obj); - CallyTextPrivate *priv = - cally_text_get_instance_private (cally_text); - -/* g_object_unref (priv->textutil); */ -/* priv->textutil = NULL; */ - - g_clear_handle_id (&priv->insert_idle_handler, g_source_remove); - - G_OBJECT_CLASS (cally_text_parent_class)->finalize (obj); -} - -/** - * cally_text_new: - * @actor: a #ClutterActor - * - * Creates a new #CallyText for the given @actor. @actor must be a - * [class@Clutter.Text]. - * - * Return value: the newly created #AtkObject - */ -AtkObject* -cally_text_new (ClutterActor *actor) -{ - GObject *object = NULL; - AtkObject *accessible = NULL; - - g_return_val_if_fail (CLUTTER_IS_TEXT (actor), NULL); - - object = g_object_new (CALLY_TYPE_TEXT, NULL); - - accessible = ATK_OBJECT (object); - atk_object_initialize (accessible, actor); - - return accessible; -} - -/* atkobject.h */ - -static void -cally_text_real_initialize(AtkObject *obj, - gpointer data) -{ - ClutterText *clutter_text = NULL; - CallyText *cally_text = NULL; - CallyTextPrivate *priv; - - ATK_OBJECT_CLASS (cally_text_parent_class)->initialize (obj, data); - - g_return_if_fail (CLUTTER_TEXT (data)); - - cally_text = CALLY_TEXT (obj); - priv = cally_text_get_instance_private (cally_text); - clutter_text = CLUTTER_TEXT (data); - - priv->cursor_position = clutter_text_get_cursor_position (clutter_text); - priv->selection_bound = clutter_text_get_selection_bound (clutter_text); - - g_signal_connect (clutter_text, "insert-text", - G_CALLBACK (_cally_text_insert_text_cb), - cally_text); - g_signal_connect (clutter_text, "delete-text", - G_CALLBACK (_cally_text_delete_text_cb), - cally_text); - - _check_activate_action (cally_text, clutter_text); - - if (clutter_text_get_password_char (clutter_text) != 0) - atk_object_set_role (obj, ATK_ROLE_PASSWORD_TEXT); - else - atk_object_set_role (obj, ATK_ROLE_TEXT); -} - -static AtkStateSet* -cally_text_ref_state_set (AtkObject *obj) -{ - AtkStateSet *result = NULL; - ClutterActor *actor = NULL; - - result = ATK_OBJECT_CLASS (cally_text_parent_class)->ref_state_set (obj); - - actor = CALLY_GET_CLUTTER_ACTOR (obj); - - if (actor == NULL) - return result; - - if (clutter_text_get_editable (CLUTTER_TEXT (actor))) - atk_state_set_add_state (result, ATK_STATE_EDITABLE); - - if (clutter_text_get_selectable (CLUTTER_TEXT (actor))) - atk_state_set_add_state (result, ATK_STATE_SELECTABLE_TEXT); - - return result; -} - -/***** pango stuff **** - * - * FIXME: all this pango related code used to implement - * atk_text_get_text_[before/at/after]_offset was copied from GTK, and - * should be on a common library (like pango itself). - * - *********************/ - -/* - * _gtk_pango_move_chars: - * @layout: a #PangoLayout - * @offset: a character offset in @layout - * @count: the number of characters to move from @offset - * - * Returns the position that is @count characters from the - * given @offset. @count may be positive or negative. - * - * For the purpose of this function, characters are defined - * by what Pango considers cursor positions. - * - * Returns: the new position - */ -static gint -_gtk_pango_move_chars (PangoLayout *layout, - gint offset, - gint count) -{ - const PangoLogAttr *attrs; - gint n_attrs; - - attrs = pango_layout_get_log_attrs_readonly (layout, &n_attrs); - - while (count > 0 && offset < n_attrs - 1) - { - do - offset++; - while (offset < n_attrs - 1 && !attrs[offset].is_cursor_position); - - count--; - } - while (count < 0 && offset > 0) - { - do - offset--; - while (offset > 0 && !attrs[offset].is_cursor_position); - - count++; - } - - return offset; -} - -/* - * _gtk_pango_move_words: - * @layout: a #PangoLayout - * @offset: a character offset in @layout - * @count: the number of words to move from @offset - * - * Returns the position that is @count words from the - * given @offset. @count may be positive or negative. - * - * If @count is positive, the returned position will - * be a word end, otherwise it will be a word start. - * See the Pango documentation for details on how - * word starts and ends are defined. - * - * Returns: the new position - */ -static gint -_gtk_pango_move_words (PangoLayout *layout, - gint offset, - gint count) -{ - const PangoLogAttr *attrs; - gint n_attrs; - - attrs = pango_layout_get_log_attrs_readonly (layout, &n_attrs); - - while (count > 0 && offset < n_attrs - 1) - { - do - offset++; - while (offset < n_attrs - 1 && !attrs[offset].is_word_end); - - count--; - } - while (count < 0 && offset > 0) - { - do - offset--; - while (offset > 0 && !attrs[offset].is_word_start); - - count++; - } - - return offset; -} - -/* - * _gtk_pango_move_sentences: - * @layout: a #PangoLayout - * @offset: a character offset in @layout - * @count: the number of sentences to move from @offset - * - * Returns the position that is @count sentences from the - * given @offset. @count may be positive or negative. - * - * If @count is positive, the returned position will - * be a sentence end, otherwise it will be a sentence start. - * See the Pango documentation for details on how - * sentence starts and ends are defined. - * - * Returns: the new position - */ -static gint -_gtk_pango_move_sentences (PangoLayout *layout, - gint offset, - gint count) -{ - const PangoLogAttr *attrs; - gint n_attrs; - - attrs = pango_layout_get_log_attrs_readonly (layout, &n_attrs); - - while (count > 0 && offset < n_attrs - 1) - { - do - offset++; - while (offset < n_attrs - 1 && !attrs[offset].is_sentence_end); - - count--; - } - while (count < 0 && offset > 0) - { - do - offset--; - while (offset > 0 && !attrs[offset].is_sentence_start); - - count++; - } - - return offset; -} - -/* - * _gtk_pango_is_inside_word: - * @layout: a #PangoLayout - * @offset: a character offset in @layout - * - * Returns whether the given position is inside - * a word. - * - * Returns: %TRUE if @offset is inside a word - */ -static gboolean -_gtk_pango_is_inside_word (PangoLayout *layout, - gint offset) -{ - const PangoLogAttr *attrs; - gint n_attrs; - - attrs = pango_layout_get_log_attrs_readonly (layout, &n_attrs); - - while (offset >= 0 && - !(attrs[offset].is_word_start || attrs[offset].is_word_end)) - offset--; - - if (offset >= 0) - return attrs[offset].is_word_start; - - return FALSE; -} - -/* - * _gtk_pango_is_inside_sentence: - * @layout: a #PangoLayout - * @offset: a character offset in @layout - * - * Returns whether the given position is inside - * a sentence. - * - * Returns: %TRUE if @offset is inside a sentence - */ -static gboolean -_gtk_pango_is_inside_sentence (PangoLayout *layout, - gint offset) -{ - const PangoLogAttr *attrs; - gint n_attrs; - - attrs = pango_layout_get_log_attrs_readonly (layout, &n_attrs); - - while (offset >= 0 && - !(attrs[offset].is_sentence_start || attrs[offset].is_sentence_end)) - offset--; - - if (offset >= 0) - return attrs[offset].is_sentence_start; - - return FALSE; -} - -static void -pango_layout_get_line_before (PangoLayout *layout, - AtkTextBoundary boundary_type, - gint offset, - gint *start_offset, - gint *end_offset) -{ - PangoLayoutIter *iter; - PangoLayoutLine *line, *prev_line = NULL, *prev_prev_line = NULL; - gint index, start_index, end_index; - const gchar *text; - gboolean found = FALSE; - - text = pango_layout_get_text (layout); - index = g_utf8_offset_to_pointer (text, offset) - text; - iter = pango_layout_get_iter (layout); - do - { - line = pango_layout_iter_get_line (iter); - start_index = line->start_index; - end_index = start_index + line->length; - - if (index >= start_index && index <= end_index) - { - /* Found line for offset */ - if (prev_line) - { - switch (boundary_type) - { - case ATK_TEXT_BOUNDARY_LINE_START: - end_index = start_index; - start_index = prev_line->start_index; - break; - case ATK_TEXT_BOUNDARY_LINE_END: - if (prev_prev_line) - start_index = prev_prev_line->start_index + prev_prev_line->length; - else - start_index = 0; - end_index = prev_line->start_index + prev_line->length; - break; - default: - g_assert_not_reached(); - } - } - else - start_index = end_index = 0; - - found = TRUE; - break; - } - - prev_prev_line = prev_line; - prev_line = line; - } - while (pango_layout_iter_next_line (iter)); - - if (!found) - { - start_index = prev_line->start_index + prev_line->length; - end_index = start_index; - } - pango_layout_iter_free (iter); - - *start_offset = g_utf8_pointer_to_offset (text, text + start_index); - *end_offset = g_utf8_pointer_to_offset (text, text + end_index); -} - -static void -pango_layout_get_line_at (PangoLayout *layout, - AtkTextBoundary boundary_type, - gint offset, - gint *start_offset, - gint *end_offset) -{ - PangoLayoutIter *iter; - PangoLayoutLine *line, *prev_line = NULL; - gint index, start_index, end_index; - const gchar *text; - gboolean found = FALSE; - - text = pango_layout_get_text (layout); - index = g_utf8_offset_to_pointer (text, offset) - text; - iter = pango_layout_get_iter (layout); - do - { - line = pango_layout_iter_get_line (iter); - start_index = line->start_index; - end_index = start_index + line->length; - - if (index >= start_index && index <= end_index) - { - /* Found line for offset */ - switch (boundary_type) - { - case ATK_TEXT_BOUNDARY_LINE_START: - if (pango_layout_iter_next_line (iter)) - end_index = pango_layout_iter_get_line (iter)->start_index; - break; - case ATK_TEXT_BOUNDARY_LINE_END: - if (prev_line) - start_index = prev_line->start_index + prev_line->length; - break; - default: - g_assert_not_reached(); - } - - found = TRUE; - break; - } - - prev_line = line; - } - while (pango_layout_iter_next_line (iter)); - - if (!found) - { - start_index = prev_line->start_index + prev_line->length; - end_index = start_index; - } - pango_layout_iter_free (iter); - - *start_offset = g_utf8_pointer_to_offset (text, text + start_index); - *end_offset = g_utf8_pointer_to_offset (text, text + end_index); -} - -static void -pango_layout_get_line_after (PangoLayout *layout, - AtkTextBoundary boundary_type, - gint offset, - gint *start_offset, - gint *end_offset) -{ - PangoLayoutIter *iter; - PangoLayoutLine *line, *prev_line = NULL; - gint index, start_index, end_index; - const gchar *text; - gboolean found = FALSE; - - text = pango_layout_get_text (layout); - index = g_utf8_offset_to_pointer (text, offset) - text; - iter = pango_layout_get_iter (layout); - do - { - line = pango_layout_iter_get_line (iter); - start_index = line->start_index; - end_index = start_index + line->length; - - if (index >= start_index && index <= end_index) - { - /* Found line for offset */ - if (pango_layout_iter_next_line (iter)) - { - line = pango_layout_iter_get_line (iter); - switch (boundary_type) - { - case ATK_TEXT_BOUNDARY_LINE_START: - start_index = line->start_index; - if (pango_layout_iter_next_line (iter)) - end_index = pango_layout_iter_get_line (iter)->start_index; - else - end_index = start_index + line->length; - break; - case ATK_TEXT_BOUNDARY_LINE_END: - start_index = end_index; - end_index = line->start_index + line->length; - break; - default: - g_assert_not_reached(); - } - } - else - start_index = end_index; - - found = TRUE; - break; - } - - prev_line = line; - } - while (pango_layout_iter_next_line (iter)); - - if (!found) - { - start_index = prev_line->start_index + prev_line->length; - end_index = start_index; - } - pango_layout_iter_free (iter); - - *start_offset = g_utf8_pointer_to_offset (text, text + start_index); - *end_offset = g_utf8_pointer_to_offset (text, text + end_index); -} - -/* - * _gtk_pango_get_text_at: - * @layout: a #PangoLayout - * @boundary_type: a #AtkTextBoundary - * @offset: a character offset in @layout - * @start_offset: return location for the start of the returned text - * @end_offset: return location for the end of the return text - * - * Gets a slice of the text from @layout at @offset. - * - * The @boundary_type determines the size of the returned slice of - * text. For the exact semantics of this function, see - * [method@Atk.Text.get_text_after_offset]. - * - * Returns: a newly allocated string containing a slice of text - * from layout. Free with g_free(). - */ -static gchar * -_gtk_pango_get_text_at (PangoLayout *layout, - AtkTextBoundary boundary_type, - gint offset, - gint *start_offset, - gint *end_offset) -{ - const gchar *text; - gint start, end; - const PangoLogAttr *attrs; - gint n_attrs; - - text = pango_layout_get_text (layout); - - if (text[0] == 0) - { - *start_offset = 0; - *end_offset = 0; - return g_strdup (""); - } - - attrs = pango_layout_get_log_attrs_readonly (layout, &n_attrs); - - start = offset; - end = start; - - switch (boundary_type) - { - case ATK_TEXT_BOUNDARY_CHAR: - end = _gtk_pango_move_chars (layout, end, 1); - break; - - case ATK_TEXT_BOUNDARY_WORD_START: - if (!attrs[start].is_word_start) - start = _gtk_pango_move_words (layout, start, -1); - if (_gtk_pango_is_inside_word (layout, end)) - end = _gtk_pango_move_words (layout, end, 1); - while (!attrs[end].is_word_start && end < n_attrs - 1) - end = _gtk_pango_move_chars (layout, end, 1); - break; - - case ATK_TEXT_BOUNDARY_WORD_END: - if (_gtk_pango_is_inside_word (layout, start) && - !attrs[start].is_word_start) - start = _gtk_pango_move_words (layout, start, -1); - while (!attrs[start].is_word_end && start > 0) - start = _gtk_pango_move_chars (layout, start, -1); - end = _gtk_pango_move_words (layout, end, 1); - break; - - case ATK_TEXT_BOUNDARY_SENTENCE_START: - if (!attrs[start].is_sentence_start) - start = _gtk_pango_move_sentences (layout, start, -1); - if (_gtk_pango_is_inside_sentence (layout, end)) - end = _gtk_pango_move_sentences (layout, end, 1); - while (!attrs[end].is_sentence_start && end < n_attrs - 1) - end = _gtk_pango_move_chars (layout, end, 1); - break; - - case ATK_TEXT_BOUNDARY_SENTENCE_END: - if (_gtk_pango_is_inside_sentence (layout, start) && - !attrs[start].is_sentence_start) - start = _gtk_pango_move_sentences (layout, start, -1); - while (!attrs[start].is_sentence_end && start > 0) - start = _gtk_pango_move_chars (layout, start, -1); - end = _gtk_pango_move_sentences (layout, end, 1); - break; - - case ATK_TEXT_BOUNDARY_LINE_START: - case ATK_TEXT_BOUNDARY_LINE_END: - pango_layout_get_line_at (layout, boundary_type, offset, &start, &end); - break; - } - - *start_offset = start; - *end_offset = end; - - g_assert (start <= end); - - return g_utf8_substring (text, start, end); -} - -/* - * _gtk_pango_get_text_before: - * @layout: a #PangoLayout - * @boundary_type: a #AtkTextBoundary - * @offset: a character offset in @layout - * @start_offset: return location for the start of the returned text - * @end_offset: return location for the end of the return text - * - * Gets a slice of the text from @layout before @offset. - * - * The @boundary_type determines the size of the returned slice of - * text. For the exact semantics of this function, see - * [method@Atk.Text.get_text_before_offset]. - * - * Returns: a newly allocated string containing a slice of text - * from layout. Free with g_free(). - */ -static gchar * -_gtk_pango_get_text_before (PangoLayout *layout, - AtkTextBoundary boundary_type, - gint offset, - gint *start_offset, - gint *end_offset) -{ - const gchar *text; - gint start, end; - const PangoLogAttr *attrs; - gint n_attrs; - - text = pango_layout_get_text (layout); - - if (text[0] == 0) - { - *start_offset = 0; - *end_offset = 0; - return g_strdup (""); - } - - attrs = pango_layout_get_log_attrs_readonly (layout, &n_attrs); - - start = offset; - end = start; - - switch (boundary_type) - { - case ATK_TEXT_BOUNDARY_CHAR: - start = _gtk_pango_move_chars (layout, start, -1); - break; - - case ATK_TEXT_BOUNDARY_WORD_START: - if (!attrs[start].is_word_start) - start = _gtk_pango_move_words (layout, start, -1); - end = start; - start = _gtk_pango_move_words (layout, start, -1); - break; - - case ATK_TEXT_BOUNDARY_WORD_END: - if (_gtk_pango_is_inside_word (layout, start) && - !attrs[start].is_word_start) - start = _gtk_pango_move_words (layout, start, -1); - while (!attrs[start].is_word_end && start > 0) - start = _gtk_pango_move_chars (layout, start, -1); - end = start; - start = _gtk_pango_move_words (layout, start, -1); - while (!attrs[start].is_word_end && start > 0) - start = _gtk_pango_move_chars (layout, start, -1); - break; - - case ATK_TEXT_BOUNDARY_SENTENCE_START: - if (!attrs[start].is_sentence_start) - start = _gtk_pango_move_sentences (layout, start, -1); - end = start; - start = _gtk_pango_move_sentences (layout, start, -1); - break; - - case ATK_TEXT_BOUNDARY_SENTENCE_END: - if (_gtk_pango_is_inside_sentence (layout, start) && - !attrs[start].is_sentence_start) - start = _gtk_pango_move_sentences (layout, start, -1); - while (!attrs[start].is_sentence_end && start > 0) - start = _gtk_pango_move_chars (layout, start, -1); - end = start; - start = _gtk_pango_move_sentences (layout, start, -1); - while (!attrs[start].is_sentence_end && start > 0) - start = _gtk_pango_move_chars (layout, start, -1); - break; - - case ATK_TEXT_BOUNDARY_LINE_START: - case ATK_TEXT_BOUNDARY_LINE_END: - pango_layout_get_line_before (layout, boundary_type, offset, &start, &end); - break; - } - - *start_offset = start; - *end_offset = end; - - g_assert (start <= end); - - return g_utf8_substring (text, start, end); -} - -/* - * _gtk_pango_get_text_after: - * @layout: a #PangoLayout - * @boundary_type: a #AtkTextBoundary - * @offset: a character offset in @layout - * @start_offset: return location for the start of the returned text - * @end_offset: return location for the end of the return text - * - * Gets a slice of the text from @layout after @offset. - * - * The @boundary_type determines the size of the returned slice of - * text. For the exact semantics of this function, see - * [method@Atk.Text.get_text_after_offset]. - * - * Returns: a newly allocated string containing a slice of text - * from layout. Free with g_free(). - */ -static gchar * -_gtk_pango_get_text_after (PangoLayout *layout, - AtkTextBoundary boundary_type, - gint offset, - gint *start_offset, - gint *end_offset) -{ - const gchar *text; - gint start, end; - const PangoLogAttr *attrs; - gint n_attrs; - - text = pango_layout_get_text (layout); - - if (text[0] == 0) - { - *start_offset = 0; - *end_offset = 0; - return g_strdup (""); - } - - attrs = pango_layout_get_log_attrs_readonly (layout, &n_attrs); - - start = offset; - end = start; - - switch (boundary_type) - { - case ATK_TEXT_BOUNDARY_CHAR: - start = _gtk_pango_move_chars (layout, start, 1); - end = start; - end = _gtk_pango_move_chars (layout, end, 1); - break; - - case ATK_TEXT_BOUNDARY_WORD_START: - if (_gtk_pango_is_inside_word (layout, end)) - end = _gtk_pango_move_words (layout, end, 1); - while (!attrs[end].is_word_start && end < n_attrs - 1) - end = _gtk_pango_move_chars (layout, end, 1); - start = end; - if (end < n_attrs - 1) - { - end = _gtk_pango_move_words (layout, end, 1); - while (!attrs[end].is_word_start && end < n_attrs - 1) - end = _gtk_pango_move_chars (layout, end, 1); - } - break; - - case ATK_TEXT_BOUNDARY_WORD_END: - end = _gtk_pango_move_words (layout, end, 1); - start = end; - if (end < n_attrs - 1) - end = _gtk_pango_move_words (layout, end, 1); - break; - - case ATK_TEXT_BOUNDARY_SENTENCE_START: - if (_gtk_pango_is_inside_sentence (layout, end)) - end = _gtk_pango_move_sentences (layout, end, 1); - while (!attrs[end].is_sentence_start && end < n_attrs - 1) - end = _gtk_pango_move_chars (layout, end, 1); - start = end; - if (end < n_attrs - 1) - { - end = _gtk_pango_move_sentences (layout, end, 1); - while (!attrs[end].is_sentence_start && end < n_attrs - 1) - end = _gtk_pango_move_chars (layout, end, 1); - } - break; - - case ATK_TEXT_BOUNDARY_SENTENCE_END: - end = _gtk_pango_move_sentences (layout, end, 1); - start = end; - if (end < n_attrs - 1) - end = _gtk_pango_move_sentences (layout, end, 1); - break; - - case ATK_TEXT_BOUNDARY_LINE_START: - case ATK_TEXT_BOUNDARY_LINE_END: - pango_layout_get_line_after (layout, boundary_type, offset, &start, &end); - break; - } - - *start_offset = start; - *end_offset = end; - - g_assert (start <= end); - - return g_utf8_substring (text, start, end); -} - -/***** atktext.h ******/ - -static void -cally_text_text_interface_init (AtkTextIface *iface) -{ - g_return_if_fail (iface != NULL); - - iface->get_text = cally_text_get_text; - iface->get_character_at_offset = cally_text_get_character_at_offset; - iface->get_text_before_offset = cally_text_get_text_before_offset; - iface->get_text_at_offset = cally_text_get_text_at_offset; - iface->get_text_after_offset = cally_text_get_text_after_offset; - iface->get_character_count = cally_text_get_character_count; - iface->get_caret_offset = cally_text_get_caret_offset; - iface->set_caret_offset = cally_text_set_caret_offset; - iface->get_n_selections = cally_text_get_n_selections; - iface->get_selection = cally_text_get_selection; - iface->add_selection = cally_text_add_selection; - iface->remove_selection = cally_text_remove_selection; - iface->set_selection = cally_text_set_selection; - iface->get_run_attributes = cally_text_get_run_attributes; - iface->get_default_attributes = cally_text_get_default_attributes; - iface->get_character_extents = cally_text_get_character_extents; - iface->get_offset_at_point = cally_text_get_offset_at_point; - -} - -static gchar* -cally_text_get_text (AtkText *text, - gint start_offset, - gint end_offset) -{ - ClutterActor *actor = NULL; - PangoLayout *layout = NULL; - const gchar *string = NULL; - gint character_count = 0; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* Object is defunct */ - return NULL; - - /* we use the pango layout instead of clutter_text_get_chars because - it take into account password-char */ - - layout = clutter_text_get_layout (CLUTTER_TEXT (actor)); - string = pango_layout_get_text (layout); - character_count = pango_layout_get_character_count (layout); - - if (end_offset == -1 || end_offset > character_count) - end_offset = character_count; - - if (string[0] == 0) - return g_strdup(""); - else - return g_utf8_substring (string, start_offset, end_offset); -} - -static gunichar -cally_text_get_character_at_offset (AtkText *text, - gint offset) -{ - ClutterActor *actor = NULL; - const gchar *string = NULL; - gchar *index = NULL; - gunichar unichar; - PangoLayout *layout = NULL; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* State is defunct */ - return '\0'; - - /* we use the pango layout instead of clutter_text_get_chars because - it take into account password-char */ - - layout = clutter_text_get_layout (CLUTTER_TEXT (actor)); - string = pango_layout_get_text (layout); - - if (offset >= g_utf8_strlen (string, -1)) - { - unichar = '\0'; - } - else - { - index = g_utf8_offset_to_pointer (string, offset); - - unichar = g_utf8_get_char (index); - } - - return unichar; -} - -static gchar* -cally_text_get_text_before_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset) -{ - ClutterActor *actor = NULL; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* State is defunct */ - return NULL; - - return _gtk_pango_get_text_before (clutter_text_get_layout (CLUTTER_TEXT (actor)), - boundary_type, offset, - start_offset, end_offset); -} - -static gchar* -cally_text_get_text_at_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset) -{ - ClutterActor *actor = NULL; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* State is defunct */ - return NULL; - - return _gtk_pango_get_text_at (clutter_text_get_layout (CLUTTER_TEXT (actor)), - boundary_type, offset, - start_offset, end_offset); -} - -static gchar* -cally_text_get_text_after_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset) -{ - ClutterActor *actor = NULL; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* State is defunct */ - return NULL; - - return _gtk_pango_get_text_after (clutter_text_get_layout (CLUTTER_TEXT (actor)), - boundary_type, offset, - start_offset, end_offset); -} - -static gint -cally_text_get_caret_offset (AtkText *text) -{ - ClutterActor *actor = NULL; - ClutterTextBuffer *buffer; - int cursor_pos; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* State is defunct */ - return -1; - - cursor_pos = clutter_text_get_cursor_position (CLUTTER_TEXT (actor)); - if (cursor_pos >= 0) - return cursor_pos; - - /* Cursor is at end */ - buffer = clutter_text_get_buffer (CLUTTER_TEXT (actor)); - return clutter_text_buffer_get_length (buffer); -} - -static gboolean -cally_text_set_caret_offset (AtkText *text, - gint offset) -{ - ClutterActor *actor = NULL; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* State is defunct */ - return FALSE; - - clutter_text_set_cursor_position (CLUTTER_TEXT (actor), offset); - - /* like in gailentry, we suppose that this always works, as clutter text - doesn't return anything */ - return TRUE; -} - -static gint -cally_text_get_character_count (AtkText *text) -{ - ClutterActor *actor = NULL; - ClutterText *clutter_text = NULL; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* State is defunct */ - return 0; - - clutter_text = CLUTTER_TEXT (actor); - return g_utf8_strlen (clutter_text_get_text (clutter_text), -1); -} - -static gint -cally_text_get_n_selections (AtkText *text) -{ - ClutterActor *actor = NULL; - gint selection_bound = -1; - gint cursor_position = -1; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* State is defunct */ - return 0; - - if (!clutter_text_get_selectable (CLUTTER_TEXT (actor))) - return 0; - - selection_bound = clutter_text_get_selection_bound (CLUTTER_TEXT (actor)); - cursor_position = clutter_text_get_cursor_position (CLUTTER_TEXT (actor)); - - if (selection_bound == cursor_position) - return 0; - else - return 1; -} - -static gchar* -cally_text_get_selection (AtkText *text, - gint selection_num, - gint *start_offset, - gint *end_offset) -{ - ClutterActor *actor = NULL; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* State is defunct */ - return NULL; - - /* As in gailentry, only let the user get the selection if one is set, and if - * the selection_num is 0. - */ - if (selection_num != 0) - return NULL; - - _cally_text_get_selection_bounds (CLUTTER_TEXT (actor), start_offset, end_offset); - - if (*start_offset != *end_offset) - return clutter_text_get_selection (CLUTTER_TEXT (actor)); - else - return NULL; -} - -/* ClutterText only allows one selection. So this method will set the selection - if no selection exists, but as in gailentry, it will not change the current - selection */ -static gboolean -cally_text_add_selection (AtkText *text, - gint start_offset, - gint end_offset) -{ - ClutterActor *actor; - gint select_start, select_end; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* State is defunct */ - return FALSE; - - _cally_text_get_selection_bounds (CLUTTER_TEXT (actor), - &select_start, &select_end); - - /* Like in gailentry, if there is already a selection, then don't allow another - * to be added, since ClutterText only supports one selected region. - */ - if (select_start == select_end) - { - clutter_text_set_selection (CLUTTER_TEXT (actor), - start_offset, end_offset); - - return TRUE; - } - else - return FALSE; -} - - -static gboolean -cally_text_remove_selection (AtkText *text, - gint selection_num) -{ - ClutterActor *actor = NULL; - gint caret_pos = -1; - gint select_start = -1; - gint select_end = -1; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* State is defunct */ - return FALSE; - - /* only one selection is allowed */ - if (selection_num != 0) - return FALSE; - - _cally_text_get_selection_bounds (CLUTTER_TEXT (actor), - &select_start, &select_end); - - if (select_start != select_end) - { - /* Setting the start & end of the selected region to the caret position - * turns off the selection. - */ - caret_pos = clutter_text_get_cursor_position (CLUTTER_TEXT (actor)); - clutter_text_set_selection (CLUTTER_TEXT (actor), - caret_pos, caret_pos); - return TRUE; - } - else - return FALSE; -} - -static gboolean -cally_text_set_selection (AtkText *text, - gint selection_num, - gint start_offset, - gint end_offset) -{ - ClutterActor *actor = NULL; - gint select_start = -1; - gint select_end = -1; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* State is defunct */ - return FALSE; - - /* Like in gailentry, only let the user move the selection if one is set, - * and if the selection_num is 0 - */ - if (selection_num != 0) - return FALSE; - - _cally_text_get_selection_bounds (CLUTTER_TEXT (actor), - &select_start, &select_end); - - if (select_start != select_end) - { - clutter_text_set_selection (CLUTTER_TEXT (actor), - start_offset, end_offset); - return TRUE; - } - else - return FALSE; -} - -static AtkAttributeSet* -cally_text_get_run_attributes (AtkText *text, - gint offset, - gint *start_offset, - gint *end_offset) -{ - ClutterActor *actor = NULL; - ClutterText *clutter_text = NULL; - AtkAttributeSet *at_set = NULL; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* State is defunct */ - return NULL; - - /* Clutter don't have any reference to the direction*/ - - clutter_text = CLUTTER_TEXT (actor); - - at_set = _cally_misc_layout_get_run_attributes (at_set, - clutter_text, - offset, - start_offset, - end_offset); - - return at_set; -} - -static AtkAttributeSet* -cally_text_get_default_attributes (AtkText *text) -{ - ClutterActor *actor = NULL; - ClutterText *clutter_text = NULL; - AtkAttributeSet *at_set = NULL; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* State is defunct */ - return NULL; - - clutter_text = CLUTTER_TEXT (actor); - - at_set = _cally_misc_layout_get_default_attributes (at_set, clutter_text); - - return at_set; -} - -static void cally_text_get_character_extents (AtkText *text, - gint offset, - gint *xp, - gint *yp, - gint *widthp, - gint *heightp, - AtkCoordType coords) -{ - ClutterActor *actor = NULL; - ClutterText *clutter_text = NULL; - gint x = 0, y = 0, width = 0, height = 0; - gint index, x_window, y_window; - gint x_layout, y_layout; - PangoLayout *layout; - PangoRectangle extents; - const gchar *text_value; - graphene_point3d_t verts[4]; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* State is defunct */ - goto done; - - clutter_text = CLUTTER_TEXT (actor); - - text_value = clutter_text_get_text (clutter_text); - index = g_utf8_offset_to_pointer (text_value, offset) - text_value; - - layout = clutter_text_get_layout (clutter_text); - pango_layout_index_to_pos (layout, index, &extents); - - /* handle RTL text layout */ - if (extents.width < 0) - { - extents.x += extents.width; - extents.width = -extents.width; - } - - clutter_actor_get_abs_allocation_vertices (actor, verts); - x_window = verts[0].x; - y_window = verts[0].y; - - clutter_text_get_layout_offsets (clutter_text, &x_layout, &y_layout); - - x = (extents.x / PANGO_SCALE) + x_layout + x_window; - y = (extents.y / PANGO_SCALE) + y_layout + y_window; - width = extents.width / PANGO_SCALE; - height = extents.height / PANGO_SCALE; - -done: - if (widthp) - *widthp = width; - - if (heightp) - *heightp = height; - - if (xp) - *xp = x; - - if (yp) - *yp = y; -} - -static gint -cally_text_get_offset_at_point (AtkText *text, - gint x, - gint y, - AtkCoordType coords) -{ - ClutterActor *actor = NULL; - ClutterText *clutter_text = NULL; - const gchar *text_value; - gint index; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) /* State is defunct */ - return -1; - - clutter_text = CLUTTER_TEXT (actor); - - index = _cally_misc_get_index_at_point (clutter_text, x, y, coords); - text_value = clutter_text_get_text (clutter_text); - if (index == -1) - return g_utf8_strlen (text_value, -1); - else - return g_utf8_pointer_to_offset (text_value, text_value + index); -} - - -/******** Auxiliary 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 - the start and end positions in a proper order (so start<=end). This is - similar to the function gtk_editable_get_selection_bounds */ -static void -_cally_text_get_selection_bounds (ClutterText *clutter_text, - gint *start_offset, - gint *end_offset) -{ - gint pos = -1; - gint selection_bound = -1; - - pos = clutter_text_get_cursor_position (clutter_text); - selection_bound = clutter_text_get_selection_bound (clutter_text); - - if (pos < selection_bound) - { - *start_offset = pos; - *end_offset = selection_bound; - } - else - { - *start_offset = selection_bound; - *end_offset = pos; - } -} - -static void -_cally_text_delete_text_cb (ClutterText *clutter_text, - gint start_pos, - gint end_pos, - gpointer data) -{ - CallyText *cally_text = NULL; - CallyTextPrivate *priv; - - g_return_if_fail (CALLY_IS_TEXT (data)); - - /* Ignore zero length deletions */ - if (end_pos - start_pos == 0) - return; - - cally_text = CALLY_TEXT (data); - priv = cally_text_get_instance_private (cally_text); - - if (!priv->signal_name_delete) - { - priv->signal_name_delete = "text_changed::delete"; - priv->position_delete = start_pos; - priv->length_delete = end_pos - start_pos; - } - - _notify_delete (cally_text); -} - -static void -_cally_text_insert_text_cb (ClutterText *clutter_text, - gchar *new_text, - gint new_text_length, - gint *position, - gpointer data) -{ - CallyText *cally_text = NULL; - CallyTextPrivate *priv; - - g_return_if_fail (CALLY_IS_TEXT (data)); - - cally_text = CALLY_TEXT (data); - priv = cally_text_get_instance_private (cally_text); - - if (!priv->signal_name_insert) - { - priv->signal_name_insert = "text_changed::insert"; - priv->position_insert = *position; - priv->length_insert = g_utf8_strlen (new_text, new_text_length); - } - - /* - * The signal will be emitted when the cursor position is updated, - * or in an idle handler if it not updated. - */ - if (priv->insert_idle_handler == 0) - priv->insert_idle_handler = clutter_threads_add_idle (_idle_notify_insert, - cally_text); -} - -/***** atkeditabletext.h ******/ - -static void -cally_text_editable_text_interface_init (AtkEditableTextIface *iface) -{ - g_return_if_fail (iface != NULL); - - iface->set_text_contents = cally_text_set_text_contents; - iface->insert_text = cally_text_insert_text; - iface->delete_text = cally_text_delete_text; - - iface->set_run_attributes = NULL; - iface->copy_text = NULL; - iface->cut_text = NULL; - iface->paste_text = NULL; -} - -static void -cally_text_set_text_contents (AtkEditableText *text, - const gchar *string) -{ - ClutterActor *actor = NULL; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) - return; - - if (!clutter_text_get_editable (CLUTTER_TEXT (actor))) - return; - - clutter_text_set_text (CLUTTER_TEXT (actor), - string); -} - - -static void -cally_text_insert_text (AtkEditableText *text, - const gchar *string, - gint length, - gint *position) -{ - ClutterActor *actor = NULL; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) - return; - - if (!clutter_text_get_editable (CLUTTER_TEXT (actor))) - return; - - if (length < 0) - length = g_utf8_strlen (string, -1); - - clutter_text_insert_text (CLUTTER_TEXT (actor), - string, *position); - - /* we suppose that the text insertion will be successful, - clutter-text doesn't warn about it. A option would be search for - the text, but it seems not really required */ - *position += length; -} - -static void cally_text_delete_text (AtkEditableText *text, - gint start_pos, - gint end_pos) -{ - ClutterActor *actor = NULL; - - actor = CALLY_GET_CLUTTER_ACTOR (text); - if (actor == NULL) - return; - - if (!clutter_text_get_editable (CLUTTER_TEXT (actor))) - return; - - clutter_text_delete_text (CLUTTER_TEXT (actor), - start_pos, end_pos); -} - -/* CallyActor */ -static void -cally_text_notify_clutter (GObject *obj, - GParamSpec *pspec) -{ - ClutterText *clutter_text = NULL; - CallyText *cally_text = NULL; - AtkObject *atk_obj = NULL; - - clutter_text = CLUTTER_TEXT (obj); - atk_obj = clutter_actor_get_accessible (CLUTTER_ACTOR (obj)); - cally_text = CALLY_TEXT (atk_obj); - - if (g_strcmp0 (pspec->name, "cursor-position") == 0) - { - /* the selection can change also for the cursor position */ - if (_check_for_selection_change (cally_text, clutter_text)) - g_signal_emit_by_name (atk_obj, "text_selection_changed"); - - g_signal_emit_by_name (atk_obj, "text_caret_moved", - clutter_text_get_cursor_position (clutter_text)); - } - else if (g_strcmp0 (pspec->name, "selection-bound") == 0) - { - if (_check_for_selection_change (cally_text, clutter_text)) - g_signal_emit_by_name (atk_obj, "text_selection_changed"); - } - else if (g_strcmp0 (pspec->name, "editable") == 0) - { - atk_object_notify_state_change (atk_obj, ATK_STATE_EDITABLE, - clutter_text_get_editable (clutter_text)); - } - else if (g_strcmp0 (pspec->name, "activatable") == 0) - { - _check_activate_action (cally_text, clutter_text); - } - else if (g_strcmp0 (pspec->name, "password-char") == 0) - { - if (clutter_text_get_password_char (clutter_text) != 0) - atk_object_set_role (atk_obj, ATK_ROLE_PASSWORD_TEXT); - else - atk_object_set_role (atk_obj, ATK_ROLE_TEXT); - } - else - { - CALLY_ACTOR_CLASS (cally_text_parent_class)->notify_clutter (obj, pspec); - } -} - -static gboolean -_check_for_selection_change (CallyText *cally_text, - ClutterText *clutter_text) -{ - gboolean ret_val = FALSE; - gint clutter_pos = -1; - gint clutter_bound = -1; - CallyTextPrivate *priv = - cally_text_get_instance_private (cally_text); - - clutter_pos = clutter_text_get_cursor_position (clutter_text); - clutter_bound = clutter_text_get_selection_bound (clutter_text); - - if (clutter_pos != clutter_bound) - { - if (clutter_pos != priv->cursor_position || - clutter_bound != priv->selection_bound) - /* - * This check is here as this function can be called for - * notification of selection_bound and current_pos. The - * values of current_pos and selection_bound may be the same - * for both notifications and we only want to generate one - * text_selection_changed signal. - */ - ret_val = TRUE; - } - else - { - /* We had a selection */ - ret_val = (priv->cursor_position != priv->selection_bound); - } - - priv->cursor_position = clutter_pos; - priv->selection_bound = clutter_bound; - - return ret_val; -} - -static gboolean -_idle_notify_insert (gpointer data) -{ - CallyText *cally_text = CALLY_TEXT (data); - CallyTextPrivate *priv = - cally_text_get_instance_private (cally_text); - - priv->insert_idle_handler = 0; - - _notify_insert (cally_text); - - return FALSE; -} - -static void -_notify_insert (CallyText *cally_text) -{ - CallyTextPrivate *priv = - cally_text_get_instance_private (cally_text); - if (priv->signal_name_insert) - { - g_signal_emit_by_name (cally_text, - priv->signal_name_insert, - priv->position_insert, - priv->length_insert); - priv->signal_name_insert = NULL; - } -} - -static void -_notify_delete (CallyText *cally_text) -{ - CallyTextPrivate *priv = - cally_text_get_instance_private (cally_text); - if (priv->signal_name_delete) - { - g_signal_emit_by_name (cally_text, - priv->signal_name_delete, - priv->position_delete, - priv->length_delete); - priv->signal_name_delete = NULL; - } -} -/* atkaction */ - -static void -_cally_text_activate_action (CallyActor *cally_actor) -{ - ClutterActor *actor = NULL; - - actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); - - clutter_text_activate (CLUTTER_TEXT (actor)); -} - -static void -_check_activate_action (CallyText *cally_text, - ClutterText *clutter_text) -{ - CallyTextPrivate *priv = - cally_text_get_instance_private (cally_text); - if (clutter_text_get_activatable (clutter_text)) - { - if (priv->activate_action_id != 0) - return; - - priv->activate_action_id = cally_actor_add_action (CALLY_ACTOR (cally_text), - "activate", NULL, NULL, - _cally_text_activate_action); - } - else - { - if (priv->activate_action_id == 0) - return; - - if (cally_actor_remove_action (CALLY_ACTOR (cally_text), - priv->activate_action_id)) - { - priv->activate_action_id = 0; - } - } -} - -/* GailTextUtil/GailMisc reimplementation methods */ - -/** - * _cally_misc_add_attribute: - * - * Reimplementation of gail_misc_layout_get_run_attributes (check this - * function for more documentation). - * - * Returns: A pointer to the new #AtkAttributeSet. - **/ -static AtkAttributeSet* -_cally_misc_add_attribute (AtkAttributeSet *attrib_set, - AtkTextAttribute attr, - gchar *value) -{ - AtkAttributeSet *return_set; - AtkAttribute *at = g_malloc (sizeof (AtkAttribute)); - at->name = g_strdup (atk_text_attribute_get_name (attr)); - at->value = value; - return_set = g_slist_prepend(attrib_set, at); - return return_set; -} - - -static gint -_cally_atk_attribute_lookup_func (gconstpointer data, - gconstpointer user_data) -{ - AtkTextAttribute attr = (AtkTextAttribute) GPOINTER_TO_INT (user_data); - AtkAttribute *at = (AtkAttribute *) data; - if (!g_strcmp0 (at->name, atk_text_attribute_get_name (attr))) - return 0; - return -1; -} - -static gboolean -_cally_misc_find_atk_attribute (AtkAttributeSet *attrib_set, - AtkTextAttribute attr) -{ - GSList* result = g_slist_find_custom ((GSList*) attrib_set, - (gconstpointer) attr, - _cally_atk_attribute_lookup_func); - return (result != NULL); -} - -/** - * _cally_misc_layout_atk_attributes_from_pango: - * - * Store the pango attributes as their ATK equivalent in an existing - * #AtkAttributeSet. - * - * Returns: A pointer to the updated #AtkAttributeSet. - **/ -static AtkAttributeSet* -_cally_misc_layout_atk_attributes_from_pango (AtkAttributeSet *attrib_set, - PangoAttrIterator *iter) -{ - PangoAttrString *pango_string; - PangoAttrInt *pango_int; - PangoAttrColor *pango_color; - PangoAttrLanguage *pango_lang; - PangoAttrFloat *pango_float; - gchar *value = NULL; - - if ((pango_string = (PangoAttrString*) pango_attr_iterator_get (iter, - PANGO_ATTR_FAMILY)) != NULL) - { - value = g_strdup_printf("%s", pango_string->value); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_FAMILY_NAME, - value); - } - if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, - PANGO_ATTR_STYLE)) != NULL) - { - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_STYLE, - g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, pango_int->value))); - } - if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, - PANGO_ATTR_WEIGHT)) != NULL) - { - value = g_strdup_printf("%i", pango_int->value); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_WEIGHT, - value); - } - if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, - PANGO_ATTR_VARIANT)) != NULL) - { - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_VARIANT, - g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, pango_int->value))); - } - if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, - PANGO_ATTR_STRETCH)) != NULL) - { - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_STRETCH, - g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, pango_int->value))); - } - if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, - PANGO_ATTR_SIZE)) != NULL) - { - value = g_strdup_printf("%i", pango_int->value / PANGO_SCALE); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_SIZE, - value); - } - if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, - PANGO_ATTR_UNDERLINE)) != NULL) - { - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_UNDERLINE, - g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, pango_int->value))); - } - if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, - PANGO_ATTR_STRIKETHROUGH)) != NULL) - { - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_STRIKETHROUGH, - g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, pango_int->value))); - } - if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, - PANGO_ATTR_RISE)) != NULL) - { - value = g_strdup_printf("%i", pango_int->value); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_RISE, - value); - } - if ((pango_lang = (PangoAttrLanguage*) pango_attr_iterator_get (iter, - PANGO_ATTR_LANGUAGE)) != NULL) - { - value = g_strdup( pango_language_to_string( pango_lang->value)); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_LANGUAGE, - value); - } - if ((pango_float = (PangoAttrFloat*) pango_attr_iterator_get (iter, - PANGO_ATTR_SCALE)) != NULL) - { - value = g_strdup_printf("%g", pango_float->value); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_SCALE, - value); - } - if ((pango_color = (PangoAttrColor*) pango_attr_iterator_get (iter, - PANGO_ATTR_FOREGROUND)) != NULL) - { - value = g_strdup_printf ("%u,%u,%u", - pango_color->color.red, - pango_color->color.green, - pango_color->color.blue); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_FG_COLOR, - value); - } - if ((pango_color = (PangoAttrColor*) pango_attr_iterator_get (iter, - PANGO_ATTR_BACKGROUND)) != NULL) - { - value = g_strdup_printf ("%u,%u,%u", - pango_color->color.red, - pango_color->color.green, - pango_color->color.blue); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_BG_COLOR, - value); - } - - return attrib_set; -} - -static AtkAttributeSet* -_cally_misc_add_actor_color_to_attribute_set (AtkAttributeSet *attrib_set, - ClutterText *clutter_text) -{ - ClutterColor color; - gchar *value; - - clutter_text_get_color (clutter_text, &color); - value = g_strdup_printf ("%u,%u,%u", - (guint) (color.red * 65535 / 255), - (guint) (color.green * 65535 / 255), - (guint) (color.blue * 65535 / 255)); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_FG_COLOR, - value); - return attrib_set; -} - - -/** - * _cally_misc_layout_get_run_attributes: - * - * Reimplementation of gail_misc_layout_get_run_attributes (check this - * function for more documentation). - * - * Returns: A pointer to the #AtkAttributeSet. - **/ -static AtkAttributeSet* -_cally_misc_layout_get_run_attributes (AtkAttributeSet *attrib_set, - ClutterText *clutter_text, - gint offset, - gint *start_offset, - gint *end_offset) -{ - PangoAttrIterator *iter; - PangoAttrList *attr; - gint index, start_index, end_index; - gboolean is_next = TRUE; - glong len; - PangoLayout *layout = clutter_text_get_layout (clutter_text); - gchar *text = (gchar*) clutter_text_get_text (clutter_text); - - len = g_utf8_strlen (text, -1); - /* Grab the attributes of the PangoLayout, if any */ - if ((attr = pango_layout_get_attributes (layout)) == NULL) - { - *start_offset = 0; - *end_offset = len; - _cally_misc_add_actor_color_to_attribute_set (attrib_set, clutter_text); - } - else - { - iter = pango_attr_list_get_iterator (attr); - /* Get invariant range offsets */ - /* If offset out of range, set offset in range */ - if (offset > len) - offset = len; - else if (offset < 0) - offset = 0; - - index = g_utf8_offset_to_pointer (text, offset) - text; - pango_attr_iterator_range (iter, &start_index, &end_index); - while (is_next) - { - if (index >= start_index && index < end_index) - { - *start_offset = g_utf8_pointer_to_offset (text, - text + start_index); - if (end_index == G_MAXINT) - /* Last iterator */ - end_index = len; - - *end_offset = g_utf8_pointer_to_offset (text, - text + end_index); - break; - } - is_next = pango_attr_iterator_next (iter); - pango_attr_iterator_range (iter, &start_index, &end_index); - } - - /* Get attributes */ - attrib_set = _cally_misc_layout_atk_attributes_from_pango (attrib_set, iter); - pango_attr_iterator_destroy (iter); - } - - if (!_cally_misc_find_atk_attribute (attrib_set, ATK_TEXT_ATTR_FG_COLOR)) - attrib_set = _cally_misc_add_actor_color_to_attribute_set (attrib_set, clutter_text); - - return attrib_set; -} - - -/** - * _cally_misc_layout_get_default_attributes: - * - * Reimplementation of gail_misc_layout_get_default_attributes (check this - * function for more documentation). - * - * Returns: A pointer to the #AtkAttributeSet. - **/ -static AtkAttributeSet* -_cally_misc_layout_get_default_attributes (AtkAttributeSet *attrib_set, - ClutterText *clutter_text) -{ - PangoLayout *layout; - PangoContext *context; - PangoLanguage* language; - PangoFontDescription* font; - PangoWrapMode mode; - gchar *value = NULL; - gint int_value; - ClutterTextDirection text_direction; - PangoAttrIterator *iter; - PangoAttrList *attr; - - text_direction = clutter_actor_get_text_direction (CLUTTER_ACTOR (clutter_text)); - switch (text_direction) - { - case CLUTTER_TEXT_DIRECTION_DEFAULT: - value = g_strdup ("none"); - break; - - case CLUTTER_TEXT_DIRECTION_LTR: - value = g_strdup ("ltr"); - break; - - case CLUTTER_TEXT_DIRECTION_RTL: - value = g_strdup ("rtl"); - break; - - default: - value = g_strdup ("none"); - break; - } - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_DIRECTION, - value); - - layout = clutter_text_get_layout (clutter_text); - context = pango_layout_get_context (layout); - if (context) - { - if ((language = pango_context_get_language (context))) - { - value = g_strdup (pango_language_to_string (language)); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_LANGUAGE, value); - } - - if ((font = pango_context_get_font_description (context))) - { - value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, - pango_font_description_get_style (font))); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_STYLE, - value); - - value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, - pango_font_description_get_variant (font))); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_VARIANT, value); - - value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, - pango_font_description_get_stretch (font))); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_STRETCH, value); - - value = g_strdup (pango_font_description_get_family (font)); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_FAMILY_NAME, value); - value = g_strdup_printf ("%d", pango_font_description_get_weight (font)); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_WEIGHT, value); - - value = g_strdup_printf ("%i", pango_font_description_get_size (font) / PANGO_SCALE); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_SIZE, value); - - } - - } - - if (pango_layout_get_justify (layout)) - int_value = 3; - else - { - PangoAlignment align; - - align = pango_layout_get_alignment (layout); - if (align == PANGO_ALIGN_LEFT) - int_value = 0; - else if (align == PANGO_ALIGN_CENTER) - int_value = 2; - else /* if (align == PANGO_ALIGN_RIGHT) */ - int_value = 1; - } - value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, - int_value)); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_JUSTIFICATION, - value); - - mode = pango_layout_get_wrap (layout); - if (mode == PANGO_WRAP_WORD) - int_value = 2; - else /* if (mode == PANGO_WRAP_CHAR) */ - int_value = 1; - value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_WRAP_MODE, - int_value)); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_WRAP_MODE, value); - - if ((attr = clutter_text_get_attributes (clutter_text))) - { - iter = pango_attr_list_get_iterator (attr); - /* Get attributes */ - attrib_set = _cally_misc_layout_atk_attributes_from_pango (attrib_set, iter); - pango_attr_iterator_destroy (iter); - } - - - if (!_cally_misc_find_atk_attribute (attrib_set, ATK_TEXT_ATTR_FG_COLOR)) - attrib_set = _cally_misc_add_actor_color_to_attribute_set (attrib_set, - clutter_text); - - value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_FG_STIPPLE, 0)); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_FG_STIPPLE, - value); - - value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_BG_STIPPLE, 0)); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_BG_STIPPLE, - value); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_BG_FULL_HEIGHT, - g_strdup_printf ("%i", 0)); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, - g_strdup_printf ("%i", 0)); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_PIXELS_BELOW_LINES, - g_strdup_printf ("%i", 0)); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, - g_strdup_printf ("%i", 0)); - value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, - clutter_text_get_editable (clutter_text))); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_EDITABLE, - value); - - value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_INVISIBLE, - !clutter_actor_is_visible (CLUTTER_ACTOR (clutter_text)))); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_INVISIBLE, value); - - value = g_strdup_printf ("%i", pango_layout_get_indent (layout)); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_INDENT, value); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_RIGHT_MARGIN, - g_strdup_printf ("%i", 0)); - attrib_set = _cally_misc_add_attribute (attrib_set, - ATK_TEXT_ATTR_LEFT_MARGIN, - g_strdup_printf ("%i", 0)); - - return attrib_set; -} - -static int -_cally_misc_get_index_at_point (ClutterText *clutter_text, - gint x, - gint y, - AtkCoordType coords) -{ - gint index, x_window, y_window; - gint x_temp, y_temp; - gboolean ret; - graphene_point3d_t verts[4]; - PangoLayout *layout; - gint x_layout, y_layout; - - clutter_text_get_layout_offsets (clutter_text, &x_layout, &y_layout); - - clutter_actor_get_abs_allocation_vertices (CLUTTER_ACTOR (clutter_text), verts); - x_window = verts[0].x; - y_window = verts[0].y; - - x_temp = x - x_layout - x_window; - y_temp = y - y_layout - y_window; - - layout = clutter_text_get_layout (clutter_text); - ret = pango_layout_xy_to_index (layout, - x_temp * PANGO_SCALE, - y_temp * PANGO_SCALE, - &index, NULL); - - if (!ret) - { - if (x_temp < 0 || y_temp < 0) - index = 0; - else - index = -1; - } - return index; -} diff --git a/mutter/clutter/clutter/cally/cally-text.h b/mutter/clutter/clutter/cally/cally-text.h deleted file mode 100644 index 47c108e..0000000 --- a/mutter/clutter/clutter/cally/cally-text.h +++ /dev/null @@ -1,53 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2009 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * 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 . - */ - -#pragma once - -#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter.h" -#include "cally/cally-actor.h" - -G_BEGIN_DECLS - -#define CALLY_TYPE_TEXT (cally_text_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (CallyText, - cally_text, - CALLY, - TEXT, - CallyActor) - -typedef struct _CallyText CallyText; -typedef struct _CallyTextClass CallyTextClass; - -struct _CallyTextClass -{ - /*< private >*/ - CallyActorClass parent_class; -}; - -CLUTTER_EXPORT -AtkObject* cally_text_new (ClutterActor *actor); - -G_END_DECLS diff --git a/mutter/clutter/clutter/cally/cally-util.c b/mutter/clutter/clutter/cally/cally-util.c deleted file mode 100644 index 13ded78..0000000 --- a/mutter/clutter/clutter/cally/cally-util.c +++ /dev/null @@ -1,351 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2008 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * Based on GailUtil from GAIL - * Copyright 2001, 2002, 2003 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -/** - * CallyUtil: - * - * #AtkUtil implementation - * - * #CallyUtil implements #AtkUtil abstract methods. Although it - * includes the name "Util" it is in fact one of the most important - * interfaces to be implemented in any ATK toolkit implementation. - - * For instance, it defines [func@Atk.get_root], the method that returns - * the root object in the hierarchy. Without it, you don't have - * available any accessible object. - */ - -#include "config.h" - -#include -#include - -#include "cally/cally-util.h" -#include "cally/cally-root.h" -#include "cally/cally-stage.h" -#include "clutter/clutter.h" - -#define DEFAULT_PASSWORD_CHAR '*' - -/* atkutil.h */ - -static guint cally_util_add_key_event_listener (AtkKeySnoopFunc listener, - gpointer data); -static void cally_util_remove_key_event_listener (guint remove_listener); -static AtkObject* cally_util_get_root (void); -static const gchar * cally_util_get_toolkit_name (void); -static const gchar * cally_util_get_toolkit_version (void); - -/* private */ -static gboolean notify_hf (gpointer key, - gpointer value, - gpointer data); -static void insert_hf (gpointer key, - gpointer value, - gpointer data); - -/* This is just a copy of the Gail one, a shared library or place to - define it could be a good idea. */ -typedef struct _CallyKeyEventInfo CallyKeyEventInfo; - -struct _CallyKeyEventInfo -{ - AtkKeySnoopFunc listener; - gpointer func_data; -}; - -static AtkObject* root = NULL; -static GHashTable *key_listener_list = NULL; - - -G_DEFINE_TYPE (CallyUtil, cally_util, ATK_TYPE_UTIL); - -static void -cally_util_class_init (CallyUtilClass *klass) -{ - AtkUtilClass *atk_class; - gpointer data; - - data = g_type_class_peek (ATK_TYPE_UTIL); - atk_class = ATK_UTIL_CLASS (data); - - atk_class->add_key_event_listener = cally_util_add_key_event_listener; - atk_class->remove_key_event_listener = cally_util_remove_key_event_listener; - atk_class->get_root = cally_util_get_root; - atk_class->get_toolkit_name = cally_util_get_toolkit_name; - atk_class->get_toolkit_version = cally_util_get_toolkit_version; - - /* FIXME: Instead of create this on the class, I think that would - worth to implement CallyUtil as a singleton instance, so the - class methods will access this instance. This will be a good - future enhancement, meanwhile, just using the same *working* - implementation used on GailUtil */ -} - -static void -cally_util_init (CallyUtil *cally_util) -{ - /* instance init: usually not required */ -} - -/* ------------------------------ ATK UTIL METHODS -------------------------- */ - -static AtkObject* -cally_util_get_root (void) -{ - if (!root) - root = cally_root_new (); - - return root; -} - -static const gchar * -cally_util_get_toolkit_name (void) -{ - return "clutter"; -} - -static const gchar * -cally_util_get_toolkit_version (void) -{ - return VERSION; -} - -static guint -cally_util_add_key_event_listener (AtkKeySnoopFunc listener, - gpointer data) -{ - static guint key = 1; - CallyKeyEventInfo *event_info = NULL; - - if (!key_listener_list) - key_listener_list = g_hash_table_new_full (NULL, NULL, NULL, g_free); - - event_info = g_new (CallyKeyEventInfo, 1); - event_info->listener = listener; - event_info->func_data = data; - - g_hash_table_insert (key_listener_list, GUINT_TO_POINTER (key++), event_info); - /* XXX: we don't check to see if n_listeners > MAXUINT */ - return key - 1; -} - -static void -cally_util_remove_key_event_listener (guint remove_listener) -{ - if (!g_hash_table_remove (key_listener_list, GUINT_TO_POINTER (remove_listener))) { - g_warning ("Not able to remove listener with id %i", remove_listener); - } - - if (g_hash_table_size (key_listener_list) == 0) - { - g_hash_table_destroy (key_listener_list); - key_listener_list = NULL; - } -} - -/* ------------------------------ PRIVATE FUNCTIONS ------------------------- */ - -static AtkKeyEventStruct * -atk_key_event_from_clutter_event_key (ClutterKeyEvent *clutter_event, - gunichar password_char) -{ - AtkKeyEventStruct *atk_event = g_new0 (AtkKeyEventStruct, 1); - gunichar key_unichar; - - switch (clutter_event_type ((ClutterEvent *) clutter_event)) - { - case CLUTTER_KEY_PRESS: - atk_event->type = ATK_KEY_EVENT_PRESS; - break; - case CLUTTER_KEY_RELEASE: - atk_event->type = ATK_KEY_EVENT_RELEASE; - break; - default: - g_assert_not_reached (); - return NULL; - } - - if (password_char) - atk_event->state = 0; - else - atk_event->state = clutter_event_get_state ((ClutterEvent *) clutter_event); - - /* We emit the clutter keyval. This is not exactly the one expected - by AtkKeyEventStruct, as it expects a Gdk-like event, with the - modifiers applied. But to avoid a dependency to gdk, we delegate - that on the AT application. - More information: Bug 1952 and bug 2072 - */ - if (password_char) - atk_event->keyval = clutter_unicode_to_keysym (password_char); - else - atk_event->keyval = clutter_event_get_key_symbol ((ClutterEvent *) clutter_event); - - /* It is expected to store a key defining string here (ie "Space" in - case you press a space). Anyway, there are no function on clutter - to obtain that, and we want to avoid a gdk dependency here, so we - delegate on the AT application to obtain that string using the - rest of the data on the ATK event struct. - - More information: Bug 1952 and 2072 - */ - - if (password_char) - key_unichar = password_char; - else - key_unichar = clutter_event_get_key_unicode ((ClutterEvent *) clutter_event); - - if (g_unichar_validate (key_unichar) && !g_unichar_iscntrl (key_unichar)) - { - GString *new = NULL; - - new = g_string_new (""); - new = g_string_insert_unichar (new, 0, key_unichar); - atk_event->string = g_string_free (new, FALSE); - } - else - atk_event->string = NULL; - - atk_event->length = 0; - - /* Computing the hardware keycode from the password-char is - difficult. But we are in a password situation. We are already a - unichar that it is not the original one. Providing a "almost - real" keycode is irrelevant */ - if (password_char) - atk_event->keycode = 0; - else - atk_event->keycode = clutter_event_get_key_code ((ClutterEvent *) clutter_event); - - atk_event->timestamp = clutter_event_get_time ((ClutterEvent *) clutter_event); - -#ifdef CALLY_DEBUG - - g_debug ("CallyKeyEvent:\tsym 0x%x\n\t\tmods %x\n\t\tcode %u\n\t\ttime %lx \n\t\tstring %s\n", - (unsigned int) atk_event->keyval, - (unsigned int) atk_event->state, - (unsigned int) atk_event->keycode, - (unsigned long int) atk_event->timestamp, - atk_event->string); -#endif - - return atk_event; -} - - -static gboolean -notify_hf (gpointer key, gpointer value, gpointer data) -{ - CallyKeyEventInfo *info = (CallyKeyEventInfo *) value; - AtkKeyEventStruct *key_event = (AtkKeyEventStruct *)data; - - return (*(AtkKeySnoopFunc) info->listener) (key_event, info->func_data) ? TRUE : FALSE; -} - -static void -insert_hf (gpointer key, gpointer value, gpointer data) -{ - GHashTable *new_table = (GHashTable *) data; - g_hash_table_insert (new_table, key, value); -} - - -/* - * 0 if the key of that event is visible, in other case the password - * char - */ -static gunichar -check_key_visibility (ClutterStage *stage) -{ - AtkObject *accessible; - ClutterActor *focus; - - focus = clutter_stage_get_key_focus (stage); - accessible = clutter_actor_get_accessible (focus); - - g_return_val_if_fail (accessible != NULL, 0); - - if (atk_object_get_role (accessible) != ATK_ROLE_PASSWORD_TEXT) - return 0; - - /* If it is a clutter text, we use his password char. Note that - although at Clutter toolkit itself, only ClutterText exposes a - password role, nothing prevents on any derived toolkit (like st) - to create a new actor that can behave like a password entry. And - the key event will still be emitted here. Although in that case - we would lose any password char from the derived toolkit, it is - still better fill this with a default unichar that the original - one */ - - if (CLUTTER_IS_TEXT (focus)) - return clutter_text_get_password_char (CLUTTER_TEXT (focus)); - else - return DEFAULT_PASSWORD_CHAR; -} - -gboolean -cally_snoop_key_event (ClutterStage *stage, - ClutterKeyEvent *key) -{ - ClutterEvent *event = (ClutterEvent *) key; - AtkKeyEventStruct *key_event = NULL; - ClutterEventType event_type; - gboolean consumed = FALSE; - gunichar password_char = 0; - - event_type = clutter_event_type (event); - - /* filter key events */ - if ((event_type != CLUTTER_KEY_PRESS) && (event_type != CLUTTER_KEY_RELEASE)) - return FALSE; - - if (key_listener_list) - { - GHashTable *new_hash = g_hash_table_new (NULL, NULL); - - g_hash_table_foreach (key_listener_list, insert_hf, new_hash); - password_char = check_key_visibility (stage); - key_event = atk_key_event_from_clutter_event_key (key, password_char); - /* func data is inside the hash table */ - consumed = g_hash_table_foreach_steal (new_hash, notify_hf, key_event) > 0; - g_hash_table_destroy (new_hash); - - g_free (key_event->string); - g_free (key_event); - } - - return consumed; -} - -void -_cally_util_override_atk_util (void) -{ - AtkUtilClass *atk_class = ATK_UTIL_CLASS (g_type_class_ref (ATK_TYPE_UTIL)); - - atk_class->add_key_event_listener = cally_util_add_key_event_listener; - atk_class->remove_key_event_listener = cally_util_remove_key_event_listener; - atk_class->get_root = cally_util_get_root; - atk_class->get_toolkit_name = cally_util_get_toolkit_name; - atk_class->get_toolkit_version = cally_util_get_toolkit_version; -} diff --git a/mutter/clutter/clutter/cally/cally-util.h b/mutter/clutter/clutter/cally/cally-util.h deleted file mode 100644 index 41cbc26..0000000 --- a/mutter/clutter/clutter/cally/cally-util.h +++ /dev/null @@ -1,55 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2008 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * 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 . - */ - -#pragma once - -#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter.h" -#include - -G_BEGIN_DECLS - -#define CALLY_TYPE_UTIL (cally_util_get_type ()) - -typedef struct _CallyUtil CallyUtil; -typedef struct _CallyUtilClass CallyUtilClass; - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (CallyUtil, - cally_util, - CALLY, - UTIL, - AtkUtil) - -struct _CallyUtilClass -{ - /*< private >*/ - AtkUtilClass parent_class; -}; - -void _cally_util_override_atk_util (void); - -gboolean cally_snoop_key_event (ClutterStage *stage, - ClutterKeyEvent *key); - -G_END_DECLS diff --git a/mutter/clutter/clutter/cally/cally.c b/mutter/clutter/clutter/cally/cally.c deleted file mode 100644 index 4b61949..0000000 --- a/mutter/clutter/clutter/cally/cally.c +++ /dev/null @@ -1,79 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2008 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * 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 . - */ -#include "config.h" - -#include "cally/cally.h" - -#include "cally/cally-actor.h" -#include "cally/cally-stage.h" -#include "cally/cally-text.h" -#include "cally/cally-clone.h" - -#include "cally/cally-factory.h" -#include "cally/cally-util.h" - -#include "clutter/clutter.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-private.h" - -/* factories initialization*/ -CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_ACTOR, cally_actor, cally_actor_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_CLONE, cally_clone, cally_clone_new) - -/** - * cally_accessibility_init: - * - * Initializes the accessibility support. - * - * Return value: %TRUE if accessibility support has been correctly - * initialized. - */ -gboolean -cally_accessibility_init (void) -{ - /* setting the factories */ - CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_ACTOR, cally_actor); - CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_STAGE, cally_stage); - CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXT, cally_text); - CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_CLONE, cally_clone); - - /* Initialize the CallyUtility class */ - _cally_util_override_atk_util (); - - CLUTTER_NOTE (MISC, "Clutter Accessibility initialized"); - - return TRUE; -} - -/** - * cally_get_cally_initialized: - * - * Returns if the accessibility support using cally is enabled. - * - * Return value: %TRUE if accessibility support has been correctly - * initialized. - */ -gboolean cally_get_cally_initialized (void) -{ - return !g_strcmp0 (atk_get_toolkit_name (), "clutter"); -} diff --git a/mutter/clutter/clutter/cally/cally.h b/mutter/clutter/clutter/cally/cally.h deleted file mode 100644 index e12c966..0000000 --- a/mutter/clutter/clutter/cally/cally.h +++ /dev/null @@ -1,34 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2008 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * 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 . - */ - -#pragma once - -#define __CALLY_H_INSIDE__ - -#include "cally/cally-actor.h" -#include "cally/cally-clone.h" -#include "cally/cally-factory.h" -#include "cally/cally-main.h" -#include "cally/cally-root.h" -#include "cally/cally-stage.h" -#include "cally/cally-text.h" -#include "cally/cally-util.h" - -#undef __CALLY_H_INSIDE__ diff --git a/mutter/clutter/clutter/clutter-action-private.h b/mutter/clutter/clutter/clutter-action-private.h deleted file mode 100644 index bcb969e..0000000 --- a/mutter/clutter/clutter/clutter-action-private.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2021 Red Hat Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Carlos Garnacho - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-action.h" - -G_BEGIN_DECLS - -void clutter_action_set_phase (ClutterAction *action, - ClutterEventPhase phase); - -gboolean clutter_action_handle_event (ClutterAction *action, - const ClutterEvent *event); - -void clutter_action_sequence_cancelled (ClutterAction *action, - ClutterInputDevice *device, - ClutterEventSequence *sequence); - -gboolean clutter_action_register_sequence (ClutterAction *self, - const ClutterEvent *event); - -int clutter_action_setup_sequence_relationship (ClutterAction *action_1, - ClutterAction *action_2, - ClutterInputDevice *device, - ClutterEventSequence *sequence); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-action.c b/mutter/clutter/clutter/clutter-action.c deleted file mode 100644 index 62148de..0000000 --- a/mutter/clutter/clutter/clutter-action.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterAction: - * - * Abstract class for event-related logic - * - * #ClutterAction is an abstract base class for event-related actions that - * modify the user interaction of a [class@Actor], just like - * [class@Constraint] is an abstract class for modifiers of an actor's - * position or size. - * - * Implementations of #ClutterAction are associated to an actor and can - * provide behavioral changes when dealing with user input - for instance - * drag and drop capabilities, or scrolling, or panning - by using the - * various event-related signals provided by [class@Actor] itself. - */ - -#include "config.h" - -#include "clutter/clutter-action.h" -#include "clutter/clutter-action-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-private.h" - -typedef struct _ClutterActionPrivate ClutterActionPrivate; - -struct _ClutterActionPrivate -{ - ClutterEventPhase phase; -}; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterAction, clutter_action, - CLUTTER_TYPE_ACTOR_META) - -static gboolean -clutter_action_handle_event_default (ClutterAction *action, - const ClutterEvent *event) -{ - return FALSE; -} - -static void -clutter_action_class_init (ClutterActionClass *klass) -{ - klass->handle_event = clutter_action_handle_event_default; -} - -static void -clutter_action_init (ClutterAction *self) -{ -} - -void -clutter_action_set_phase (ClutterAction *action, - ClutterEventPhase phase) -{ - ClutterActionPrivate *priv; - - priv = clutter_action_get_instance_private (action); - priv->phase = phase; -} - -ClutterEventPhase -clutter_action_get_phase (ClutterAction *action) -{ - ClutterActionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ACTION (action), CLUTTER_PHASE_CAPTURE); - - priv = clutter_action_get_instance_private (action); - - return priv->phase; -} - -gboolean -clutter_action_handle_event (ClutterAction *action, - const ClutterEvent *event) -{ - gboolean retval; - - g_object_ref (action); - retval = CLUTTER_ACTION_GET_CLASS (action)->handle_event (action, event); - g_object_unref (action); - - return retval; -} - -void -clutter_action_sequence_cancelled (ClutterAction *action, - ClutterInputDevice *device, - ClutterEventSequence *sequence) -{ - ClutterActionClass *action_class = CLUTTER_ACTION_GET_CLASS (action); - - if (action_class->sequence_cancelled) - action_class->sequence_cancelled (action, device, sequence); -} - -gboolean -clutter_action_register_sequence (ClutterAction *self, - const ClutterEvent *event) -{ - ClutterActionClass *action_class = CLUTTER_ACTION_GET_CLASS (self); - - if (action_class->register_sequence) - return action_class->register_sequence (self, event); - - return TRUE; -} - -int -clutter_action_setup_sequence_relationship (ClutterAction *action_1, - ClutterAction *action_2, - ClutterInputDevice *device, - ClutterEventSequence *sequence) -{ - ClutterActionClass *action_class = CLUTTER_ACTION_GET_CLASS (action_1); - - if (action_class->setup_sequence_relationship) - return action_class->setup_sequence_relationship (action_1, action_2, device, sequence); - - return 0; -} diff --git a/mutter/clutter/clutter/clutter-action.h b/mutter/clutter/clutter/clutter-action.h deleted file mode 100644 index dd5d590..0000000 --- a/mutter/clutter/clutter/clutter-action.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-actor-meta.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_ACTION (clutter_action_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterAction, clutter_action, - CLUTTER, ACTION, ClutterActorMeta); - -/** - * ClutterActionClass: - * - * The ClutterActionClass structure contains only private data - */ -struct _ClutterActionClass -{ - /*< private >*/ - ClutterActorMetaClass parent_class; - - gboolean (* handle_event) (ClutterAction *action, - const ClutterEvent *event); - - void (* sequence_cancelled) (ClutterAction *action, - ClutterInputDevice *device, - ClutterEventSequence *sequence); - - gboolean (* register_sequence) (ClutterAction *self, - const ClutterEvent *event); - - int (* setup_sequence_relationship) (ClutterAction *action_1, - ClutterAction *action_2, - ClutterInputDevice *device, - ClutterEventSequence *sequence); -}; - -/* ClutterActor API */ -CLUTTER_EXPORT -void clutter_actor_add_action (ClutterActor *self, - ClutterAction *action); -CLUTTER_EXPORT -void clutter_actor_add_action_with_name (ClutterActor *self, - const gchar *name, - ClutterAction *action); -CLUTTER_EXPORT -void clutter_actor_add_action_full (ClutterActor *self, - const char *name, - ClutterEventPhase phase, - ClutterAction *action); -CLUTTER_EXPORT -void clutter_actor_remove_action (ClutterActor *self, - ClutterAction *action); -CLUTTER_EXPORT -void clutter_actor_remove_action_by_name (ClutterActor *self, - const gchar *name); -CLUTTER_EXPORT -ClutterAction *clutter_actor_get_action (ClutterActor *self, - const gchar *name); -CLUTTER_EXPORT -GList * clutter_actor_get_actions (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_clear_actions (ClutterActor *self); - -CLUTTER_EXPORT -gboolean clutter_actor_has_actions (ClutterActor *self); - -ClutterEventPhase clutter_action_get_phase (ClutterAction *action); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-actor-box-private.h b/mutter/clutter/clutter/clutter-actor-box-private.h deleted file mode 100644 index 5093c34..0000000 --- a/mutter/clutter/clutter/clutter-actor-box-private.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -void _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-actor-box.c b/mutter/clutter/clutter/clutter-actor-box.c deleted file mode 100644 index 33dcd04..0000000 --- a/mutter/clutter/clutter/clutter-actor-box.c +++ /dev/null @@ -1,606 +0,0 @@ -#include "config.h" - -#include - -#include "clutter/clutter-types.h" -#include "clutter/clutter-interval.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-actor-box-private.h" - -/** - * clutter_actor_box_new: - * @x_1: X coordinate of the top left point - * @y_1: Y coordinate of the top left point - * @x_2: X coordinate of the bottom right point - * @y_2: Y coordinate of the bottom right point - * - * Allocates a new [struct@ActorBox] using the passed coordinates - * for the top left and bottom right points. - * - * This function is the logical equivalent of: - * - * ```c - * clutter_actor_box_init (clutter_actor_box_alloc (), - * x_1, y_1, - * x_2, y_2); - * ``` - * - * Return value: (transfer full): the newly allocated #ClutterActorBox. - * Use [method@ActorBox.free] to free the resources - */ -ClutterActorBox * -clutter_actor_box_new (gfloat x_1, - gfloat y_1, - gfloat x_2, - gfloat y_2) -{ - return clutter_actor_box_init (clutter_actor_box_alloc (), - x_1, y_1, - x_2, y_2); -} - -/** - * clutter_actor_box_alloc: - * - * Allocates a new [struct@ActorBox]. - * - * Return value: (transfer full): the newly allocated #ClutterActorBox. - * Use [method@ActorBox.free] to free its resources - */ -ClutterActorBox * -clutter_actor_box_alloc (void) -{ - return g_new0 (ClutterActorBox, 1); -} - -/** - * clutter_actor_box_init: - * @box: a #ClutterActorBox - * @x_1: X coordinate of the top left point - * @y_1: Y coordinate of the top left point - * @x_2: X coordinate of the bottom right point - * @y_2: Y coordinate of the bottom right point - * - * Initializes @box with the given coordinates. - * - * Return value: (transfer none): the initialized #ClutterActorBox - */ -ClutterActorBox * -clutter_actor_box_init (ClutterActorBox *box, - gfloat x_1, - gfloat y_1, - gfloat x_2, - gfloat y_2) -{ - g_return_val_if_fail (box != NULL, NULL); - - box->x1 = x_1; - box->y1 = y_1; - box->x2 = x_2; - box->y2 = y_2; - - return box; -} - -/** - * clutter_actor_box_init_rect: - * @box: a #ClutterActorBox - * @x: X coordinate of the origin - * @y: Y coordinate of the origin - * @width: width of the box - * @height: height of the box - * - * Initializes @box with the given origin and size. - */ -void -clutter_actor_box_init_rect (ClutterActorBox *box, - gfloat x, - gfloat y, - gfloat width, - gfloat height) -{ - g_return_if_fail (box != NULL); - - box->x1 = x; - box->y1 = y; - box->x2 = box->x1 + width; - box->y2 = box->y1 + height; -} - -/** - * clutter_actor_box_copy: - * @box: a #ClutterActorBox - * - * Copies @box - * - * Return value: a newly allocated copy of #ClutterActorBox. Use - * [method@ActorBox.free] to free the allocated resources - */ -ClutterActorBox * -clutter_actor_box_copy (const ClutterActorBox *box) -{ - if (G_LIKELY (box != NULL)) - return g_memdup2 (box, sizeof (ClutterActorBox)); - - return NULL; -} - -/** - * clutter_actor_box_free: - * @box: a #ClutterActorBox - * - * Frees a #ClutterActorBox allocated using [ctor@ActorBox.new] - * or [method@ActorBox.copy]. - */ -void -clutter_actor_box_free (ClutterActorBox *box) -{ - if (G_LIKELY (box != NULL)) - g_free (box); -} - -/** - * clutter_actor_box_equal: - * @box_a: a #ClutterActorBox - * @box_b: a #ClutterActorBox - * - * Checks @box_a and @box_b for equality - * - * Return value: %TRUE if the passed #ClutterActorBox are equal - */ -gboolean -clutter_actor_box_equal (const ClutterActorBox *box_a, - const ClutterActorBox *box_b) -{ - g_return_val_if_fail (box_a != NULL && box_b != NULL, FALSE); - - if (box_a == box_b) - return TRUE; - - return box_a->x1 == box_b->x1 && box_a->y1 == box_b->y1 && - box_a->x2 == box_b->x2 && box_a->y2 == box_b->y2; -} - -/** - * clutter_actor_box_get_x: - * @box: a #ClutterActorBox - * - * Retrieves the X coordinate of the origin of @box - * - * Return value: the X coordinate of the origin - */ -gfloat -clutter_actor_box_get_x (const ClutterActorBox *box) -{ - g_return_val_if_fail (box != NULL, 0.); - - return box->x1; -} - -/** - * clutter_actor_box_get_y: - * @box: a #ClutterActorBox - * - * Retrieves the Y coordinate of the origin of @box - * - * Return value: the Y coordinate of the origin - */ -gfloat -clutter_actor_box_get_y (const ClutterActorBox *box) -{ - g_return_val_if_fail (box != NULL, 0.); - - return box->y1; -} - -/** - * clutter_actor_box_get_width: - * @box: a #ClutterActorBox - * - * Retrieves the width of the @box - * - * Return value: the width of the box - */ -gfloat -clutter_actor_box_get_width (const ClutterActorBox *box) -{ - g_return_val_if_fail (box != NULL, 0.); - - return box->x2 - box->x1; -} - -/** - * clutter_actor_box_get_height: - * @box: a #ClutterActorBox - * - * Retrieves the height of the @box - * - * Return value: the height of the box - */ -gfloat -clutter_actor_box_get_height (const ClutterActorBox *box) -{ - g_return_val_if_fail (box != NULL, 0.); - - return box->y2 - box->y1; -} - -/** - * clutter_actor_box_get_origin: - * @box: a #ClutterActorBox - * @x: (out) (allow-none): return location for the X coordinate, or %NULL - * @y: (out) (allow-none): return location for the Y coordinate, or %NULL - * - * Retrieves the origin of @box - */ -void -clutter_actor_box_get_origin (const ClutterActorBox *box, - gfloat *x, - gfloat *y) -{ - g_return_if_fail (box != NULL); - - if (x) - *x = box->x1; - - if (y) - *y = box->y1; -} - -/** - * clutter_actor_box_get_size: - * @box: a #ClutterActorBox - * @width: (out) (allow-none): return location for the width, or %NULL - * @height: (out) (allow-none): return location for the height, or %NULL - * - * Retrieves the size of @box - */ -void -clutter_actor_box_get_size (const ClutterActorBox *box, - gfloat *width, - gfloat *height) -{ - g_return_if_fail (box != NULL); - - if (width) - *width = box->x2 - box->x1; - - if (height) - *height = box->y2 - box->y1; -} - -/** - * clutter_actor_box_get_area: - * @box: a #ClutterActorBox - * - * Retrieves the area of @box - * - * Return value: the area of a #ClutterActorBox, in pixels - */ -gfloat -clutter_actor_box_get_area (const ClutterActorBox *box) -{ - g_return_val_if_fail (box != NULL, 0.); - - return (box->x2 - box->x1) * (box->y2 - box->y1); -} - -/** - * clutter_actor_box_contains: - * @box: a #ClutterActorBox - * @x: X coordinate of the point - * @y: Y coordinate of the point - * - * Checks whether a point with @x, @y coordinates is contained - * within @box - * - * Return value: %TRUE if the point is contained by the #ClutterActorBox - */ -gboolean -clutter_actor_box_contains (const ClutterActorBox *box, - gfloat x, - gfloat y) -{ - g_return_val_if_fail (box != NULL, FALSE); - - return (x > box->x1 && x < box->x2) && - (y > box->y1 && y < box->y2); -} - -/** - * clutter_actor_box_from_vertices: - * @box: a #ClutterActorBox - * @verts: (array fixed-size=4): array of four #graphene_point3d_t - * - * Calculates the bounding box represented by the four vertices; for details - * of the vertex array see [method@Actor.get_abs_allocation_vertices]. - */ -void -clutter_actor_box_from_vertices (ClutterActorBox *box, - const graphene_point3d_t verts[]) -{ - gfloat x_1, x_2, y_1, y_2; - - g_return_if_fail (box != NULL); - g_return_if_fail (verts != NULL); - - /* 4-way min/max */ - x_1 = verts[0].x; - y_1 = verts[0].y; - - if (verts[1].x < x_1) - x_1 = verts[1].x; - - if (verts[2].x < x_1) - x_1 = verts[2].x; - - if (verts[3].x < x_1) - x_1 = verts[3].x; - - if (verts[1].y < y_1) - y_1 = verts[1].y; - - if (verts[2].y < y_1) - y_1 = verts[2].y; - - if (verts[3].y < y_1) - y_1 = verts[3].y; - - x_2 = verts[0].x; - y_2 = verts[0].y; - - if (verts[1].x > x_2) - x_2 = verts[1].x; - - if (verts[2].x > x_2) - x_2 = verts[2].x; - - if (verts[3].x > x_2) - x_2 = verts[3].x; - - if (verts[1].y > y_2) - y_2 = verts[1].y; - - if (verts[2].y > y_2) - y_2 = verts[2].y; - - if (verts[3].y > y_2) - y_2 = verts[3].y; - - box->x1 = x_1; - box->x2 = x_2; - box->y1 = y_1; - box->y2 = y_2; -} - -/** - * clutter_actor_box_interpolate: - * @initial: the initial #ClutterActorBox - * @final: the final #ClutterActorBox - * @progress: the interpolation progress - * @result: (out): return location for the interpolation - * - * Interpolates between @initial and @final `ClutterActorBox`es - * using @progress - */ -void -clutter_actor_box_interpolate (const ClutterActorBox *initial, - const ClutterActorBox *final, - gdouble progress, - ClutterActorBox *result) -{ - g_return_if_fail (initial != NULL); - g_return_if_fail (final != NULL); - g_return_if_fail (result != NULL); - - result->x1 = initial->x1 + (final->x1 - initial->x1) * progress; - result->y1 = initial->y1 + (final->y1 - initial->y1) * progress; - result->x2 = initial->x2 + (final->x2 - initial->x2) * progress; - result->y2 = initial->y2 + (final->y2 - initial->y2) * progress; -} - -/** - * clutter_actor_box_clamp_to_pixel: - * @box: (inout): the #ClutterActorBox to clamp - * - * Clamps the components of @box to the nearest integer - */ -void -clutter_actor_box_clamp_to_pixel (ClutterActorBox *box) -{ - g_return_if_fail (box != NULL); - - box->x1 = floorf (box->x1); - box->y1 = floorf (box->y1); - box->x2 = ceilf (box->x2); - box->y2 = ceilf (box->y2); -} - -/** - * clutter_actor_box_union: - * @a: (in): the first #ClutterActorBox - * @b: (in): the second #ClutterActorBox - * @result: (out): the #ClutterActorBox representing a union - * of @a and @b - * - * Unions the two boxes @a and @b and stores the result in @result. - */ -void -clutter_actor_box_union (const ClutterActorBox *a, - const ClutterActorBox *b, - ClutterActorBox *result) -{ - g_return_if_fail (a != NULL); - g_return_if_fail (b != NULL); - g_return_if_fail (result != NULL); - - result->x1 = MIN (a->x1, b->x1); - result->y1 = MIN (a->y1, b->y1); - - result->x2 = MAX (a->x2, b->x2); - result->y2 = MAX (a->y2, b->y2); -} - -static gboolean -clutter_actor_box_progress (const GValue *a, - const GValue *b, - gdouble factor, - GValue *retval) -{ - ClutterActorBox res = { 0, }; - - clutter_actor_box_interpolate (g_value_get_boxed (a), - g_value_get_boxed (b), - factor, - &res); - - g_value_set_boxed (retval, &res); - - return TRUE; -} - -/** - * clutter_actor_box_set_origin: - * @box: a #ClutterActorBox - * @x: the X coordinate of the new origin - * @y: the Y coordinate of the new origin - * - * Changes the origin of @box, maintaining the size of the #ClutterActorBox. - */ -void -clutter_actor_box_set_origin (ClutterActorBox *box, - gfloat x, - gfloat y) -{ - gfloat width, height; - - g_return_if_fail (box != NULL); - - width = box->x2 - box->x1; - height = box->y2 - box->y1; - - clutter_actor_box_init_rect (box, x, y, width, height); -} - -/** - * clutter_actor_box_set_size: - * @box: a #ClutterActorBox - * @width: the new width - * @height: the new height - * - * Sets the size of @box, maintaining the origin of the #ClutterActorBox. - */ -void -clutter_actor_box_set_size (ClutterActorBox *box, - gfloat width, - gfloat height) -{ - g_return_if_fail (box != NULL); - - box->x2 = box->x1 + width; - box->y2 = box->y1 + height; -} - -void -_clutter_actor_box_enlarge_for_effects (ClutterActorBox *box) -{ - float width, height; - - if (clutter_actor_box_get_area (box) == 0.0) - return; - - /* The aim here is that for a given rectangle defined with floating point - * coordinates we want to determine a stable quantized size in pixels - * that doesn't vary due to the original box's sub-pixel position. - * - * The reason this is important is because effects will use this - * API to determine the size of offscreen framebuffers and so for - * a fixed-size object that may be animated across the screen we - * want to make sure that the stage paint-box has an equally stable - * size so that effects aren't made to continuously re-allocate - * a corresponding fbo. - * - * The other thing we consider is that the calculation of this box is - * subject to floating point precision issues that might be slightly - * different to the precision issues involved with actually painting the - * actor, which might result in painting slightly leaking outside the - * user's calculated paint-volume. For this we simply aim to pad out the - * paint-volume by at least half a pixel all the way around. - */ - width = box->x2 - box->x1; - height = box->y2 - box->y1; - width = CLUTTER_NEARBYINT (width); - height = CLUTTER_NEARBYINT (height); - /* XXX: NB the width/height may now be up to 0.5px too small so we - * must also pad by 0.25px all around to account for this. In total we - * must padd by at least 0.75px around all sides. */ - - /* XXX: The furthest that we can overshoot the bottom right corner by - * here is 1.75px in total if you consider that the 0.75 padding could - * just cross an integer boundary and so ceil will effectively add 1. - */ - box->x2 = ceilf (box->x2 + 0.75); - box->y2 = ceilf (box->y2 + 0.75); - - /* Now we redefine the top-left relative to the bottom right based on the - * rounded width/height determined above + a constant so that the overall - * size of the box will be stable and not dependent on the box's - * position. - * - * Adding 3px to the width/height will ensure we cover the maximum of - * 1.75px padding on the bottom/right and still ensure we have > 0.75px - * padding on the top/left. - */ - box->x1 = box->x2 - width - 3; - box->y1 = box->y2 - height - 3; -} - -/** - * clutter_actor_box_scale: - * @box: a #ClutterActorBox - * @scale: scale factor for resizing this box - * - * Rescale the @box by provided @scale factor. - */ -void -clutter_actor_box_scale (ClutterActorBox *box, - gfloat scale) -{ - g_return_if_fail (box != NULL); - - box->x1 *= scale; - box->x2 *= scale; - box->y1 *= scale; - box->y2 *= scale; -} - -/** - * clutter_actor_box_is_initialized: - * @box: a #ClutterActorBox - * - * Checks if @box has been initialized, a #ClutterActorBox is uninitialized - * if it has a size of -1 at an origin of 0, 0. - * - * Returns: %TRUE if the box is uninitialized, %FALSE if it isn't - */ -gboolean -clutter_actor_box_is_initialized (ClutterActorBox *box) -{ - gboolean x1_uninitialized, x2_uninitialized; - gboolean y1_uninitialized, y2_uninitialized; - - g_return_val_if_fail (box != NULL, TRUE); - - x1_uninitialized = isinf (box->x1); - x2_uninitialized = isinf (box->x2) && signbit (box->x2); - y1_uninitialized = isinf (box->y1); - y2_uninitialized = isinf (box->y2) && signbit (box->y2); - - return !x1_uninitialized || !x2_uninitialized || - !y1_uninitialized || !y2_uninitialized; -} - -G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterActorBox, clutter_actor_box, - clutter_actor_box_copy, - clutter_actor_box_free, - CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_actor_box_progress)); diff --git a/mutter/clutter/clutter/clutter-actor-meta-private.h b/mutter/clutter/clutter/clutter-actor-meta-private.h deleted file mode 100644 index 477dd46..0000000 --- a/mutter/clutter/clutter/clutter-actor-meta-private.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#include "clutter/clutter-actor-meta.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_META_GROUP (_clutter_meta_group_get_type ()) - - -struct _ClutterMetaGroup -{ - GObject parent_instance; - - ClutterActor *actor; - - GList *meta; -}; - -G_DECLARE_FINAL_TYPE (ClutterMetaGroup, - _clutter_meta_group, - CLUTTER, META_GROUP, - GObject) - -/* Each actor meta has a priority with zero as a default. A higher - number means higher priority. Higher priority metas stay at the - beginning of the list. The priority can be negative to give lower - priority than the default. */ - -#define CLUTTER_ACTOR_META_PRIORITY_DEFAULT 0 - -/* Any value greater than this is considered an 'internal' priority - and if we expose the priority property publicly then an application - would not be able to use these values. */ - -#define CLUTTER_ACTOR_META_PRIORITY_INTERNAL_HIGH (G_MAXINT / 2) -#define CLUTTER_ACTOR_META_PRIORITY_INTERNAL_LOW (G_MININT / 2) - -void _clutter_meta_group_add_meta (ClutterMetaGroup *group, - ClutterActorMeta *meta); -void _clutter_meta_group_remove_meta (ClutterMetaGroup *group, - ClutterActorMeta *meta); -const GList * _clutter_meta_group_peek_metas (ClutterMetaGroup *group); -void _clutter_meta_group_clear_metas (ClutterMetaGroup *group); -ClutterActorMeta * _clutter_meta_group_get_meta (ClutterMetaGroup *group, - const gchar *name); - -gboolean _clutter_meta_group_has_metas_no_internal (ClutterMetaGroup *group); - -GList * _clutter_meta_group_get_metas_no_internal (ClutterMetaGroup *group); -void _clutter_meta_group_clear_metas_no_internal (ClutterMetaGroup *group); - -/* ActorMeta */ -const gchar * _clutter_actor_meta_get_debug_name (ClutterActorMeta *meta); - -void _clutter_actor_meta_set_priority (ClutterActorMeta *meta, - gint priority); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-actor-meta.c b/mutter/clutter/clutter/clutter-actor-meta.c deleted file mode 100644 index f342928..0000000 --- a/mutter/clutter/clutter/clutter-actor-meta.c +++ /dev/null @@ -1,702 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterActorMeta: - * - * Base class of actor modifiers - * - * #ClutterActorMeta is an abstract class providing a common API for - * modifiers of [class@Actor] behaviour, appearance or layout. - * - * A #ClutterActorMeta can only be owned by a single [class@Actor] at - * any time. - * - * Every sub-class of #ClutterActorMeta should check if the - * [property@ActorMeta:enabled] property is set to %TRUE before applying - * any kind of modification. - */ - -#include "config.h" - -#include "clutter/clutter-actor-meta-private.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-private.h" - -struct _ClutterActorMetaPrivate -{ - ClutterActor *actor; - gulong destroy_id; - - gchar *name; - - guint is_enabled : 1; - - gint priority; -}; - -enum -{ - PROP_0, - - PROP_ACTOR, - PROP_NAME, - PROP_ENABLED, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterActorMeta, - clutter_actor_meta, - G_TYPE_INITIALLY_UNOWNED) - -static void -on_actor_destroy (ClutterActor *actor, - ClutterActorMeta *meta) -{ - ClutterActorMetaPrivate *priv = - clutter_actor_meta_get_instance_private (meta); - - priv->actor = NULL; -} - -static void -clutter_actor_meta_real_set_actor (ClutterActorMeta *meta, - ClutterActor *actor) -{ - ClutterActorMetaPrivate *priv = - clutter_actor_meta_get_instance_private (meta); - - g_warn_if_fail (!priv->actor || - !CLUTTER_ACTOR_IN_PAINT (priv->actor)); - g_warn_if_fail (!actor || !CLUTTER_ACTOR_IN_PAINT (actor)); - - if (priv->actor == actor) - return; - - g_clear_signal_handler (&priv->destroy_id, priv->actor); - - priv->actor = actor; - - if (priv->actor != NULL) - priv->destroy_id = g_signal_connect (priv->actor, "destroy", - G_CALLBACK (on_actor_destroy), - meta); - - g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ACTOR]); -} - -static void -clutter_actor_meta_real_set_enabled (ClutterActorMeta *meta, - gboolean is_enabled) -{ - ClutterActorMetaPrivate *priv = - clutter_actor_meta_get_instance_private (meta); - - g_warn_if_fail (!priv->actor || - !CLUTTER_ACTOR_IN_PAINT (priv->actor)); - - priv->is_enabled = is_enabled; - - g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ENABLED]); -} - -static void -clutter_actor_meta_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject); - - switch (prop_id) - { - case PROP_NAME: - clutter_actor_meta_set_name (meta, g_value_get_string (value)); - break; - - case PROP_ENABLED: - clutter_actor_meta_set_enabled (meta, g_value_get_boolean (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_actor_meta_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterActorMetaPrivate *priv = - clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject)); - - switch (prop_id) - { - case PROP_ACTOR: - g_value_set_object (value, priv->actor); - break; - - case PROP_NAME: - g_value_set_string (value, priv->name); - break; - - case PROP_ENABLED: - g_value_set_boolean (value, priv->is_enabled); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_actor_meta_finalize (GObject *gobject) -{ - ClutterActorMetaPrivate *priv = - clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject)); - - if (priv->actor != NULL) - g_clear_signal_handler (&priv->destroy_id, priv->actor); - - g_free (priv->name); - - G_OBJECT_CLASS (clutter_actor_meta_parent_class)->finalize (gobject); -} - -void -clutter_actor_meta_class_init (ClutterActorMetaClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - klass->set_actor = clutter_actor_meta_real_set_actor; - klass->set_enabled = clutter_actor_meta_real_set_enabled; - - /** - * ClutterActorMeta:actor: - * - * The #ClutterActor attached to the #ClutterActorMeta instance - */ - obj_props[PROP_ACTOR] = - g_param_spec_object ("actor", NULL, NULL, - CLUTTER_TYPE_ACTOR, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActorMeta:name: - * - * The unique name to access the #ClutterActorMeta - */ - obj_props[PROP_NAME] = - g_param_spec_string ("name", NULL, NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterActorMeta:enabled: - * - * Whether or not the #ClutterActorMeta is enabled - */ - obj_props[PROP_ENABLED] = - g_param_spec_boolean ("enabled", NULL, NULL, - TRUE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - gobject_class->finalize = clutter_actor_meta_finalize; - gobject_class->set_property = clutter_actor_meta_set_property; - gobject_class->get_property = clutter_actor_meta_get_property; - g_object_class_install_properties (gobject_class, - PROP_LAST, - obj_props); -} - -void -clutter_actor_meta_init (ClutterActorMeta *self) -{ - ClutterActorMetaPrivate *priv = - clutter_actor_meta_get_instance_private (self); - - priv->is_enabled = TRUE; - priv->priority = CLUTTER_ACTOR_META_PRIORITY_DEFAULT; -} - -/** - * clutter_actor_meta_set_name: - * @meta: a #ClutterActorMeta - * @name: the name of @meta - * - * Sets the name of @meta - * - * The name can be used to identify the #ClutterActorMeta instance - */ -void -clutter_actor_meta_set_name (ClutterActorMeta *meta, - const gchar *name) -{ - ClutterActorMetaPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR_META (meta)); - - priv = clutter_actor_meta_get_instance_private (meta); - - if (g_strcmp0 (priv->name, name) == 0) - return; - - g_free (priv->name); - priv->name = g_strdup (name); - - g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_NAME]); -} - -/** - * clutter_actor_meta_get_name: - * @meta: a #ClutterActorMeta - * - * Retrieves the name set using [method@ActorMeta.set_name] - * - * Return value: (transfer none): the name of the #ClutterActorMeta - * instance, or %NULL if none was set. The returned string is owned - * by the #ClutterActorMeta instance and it should not be modified - * or freed - */ -const gchar * -clutter_actor_meta_get_name (ClutterActorMeta *meta) -{ - ClutterActorMetaPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL); - - priv = clutter_actor_meta_get_instance_private (meta); - - return priv->name; -} - -/** - * clutter_actor_meta_set_enabled: - * @meta: a #ClutterActorMeta - * @is_enabled: whether @meta is enabled - * - * Sets whether @meta should be enabled or not - */ -void -clutter_actor_meta_set_enabled (ClutterActorMeta *meta, - gboolean is_enabled) -{ - ClutterActorMetaPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR_META (meta)); - - priv = clutter_actor_meta_get_instance_private (meta); - is_enabled = !!is_enabled; - - if (priv->is_enabled == is_enabled) - return; - - CLUTTER_ACTOR_META_GET_CLASS (meta)->set_enabled (meta, is_enabled); -} - -/** - * clutter_actor_meta_get_enabled: - * @meta: a #ClutterActorMeta - * - * Retrieves whether @meta is enabled - * - * Return value: %TRUE if the #ClutterActorMeta instance is enabled - */ -gboolean -clutter_actor_meta_get_enabled (ClutterActorMeta *meta) -{ - ClutterActorMetaPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), FALSE); - - priv = clutter_actor_meta_get_instance_private (meta); - - return priv->is_enabled; -} - -/* - * _clutter_actor_meta_set_actor - * @meta: a #ClutterActorMeta - * @actor: a #ClutterActor or %NULL - * - * Sets or unsets a back pointer to the #ClutterActor that owns - * the @meta - */ -static void -_clutter_actor_meta_set_actor (ClutterActorMeta *meta, - ClutterActor *actor) -{ - g_return_if_fail (CLUTTER_IS_ACTOR_META (meta)); - g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor)); - - CLUTTER_ACTOR_META_GET_CLASS (meta)->set_actor (meta, actor); -} - -/** - * clutter_actor_meta_get_actor: - * @meta: a #ClutterActorMeta - * - * Retrieves a pointer to the [class@Actor] that owns @meta - * - * Return value: (transfer none): a pointer to a #ClutterActor or %NULL - */ -ClutterActor * -clutter_actor_meta_get_actor (ClutterActorMeta *meta) -{ - ClutterActorMetaPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL); - - priv = clutter_actor_meta_get_instance_private (meta); - - return priv->actor; -} - -void -_clutter_actor_meta_set_priority (ClutterActorMeta *meta, - gint priority) -{ - ClutterActorMetaPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR_META (meta)); - - priv = clutter_actor_meta_get_instance_private (meta); - - /* This property shouldn't be modified after the actor meta is in - use because ClutterMetaGroup doesn't resort the list when it - changes. If we made the priority public then we could either make - the priority a construct-only property or listen for - notifications on the property from the ClutterMetaGroup and - resort. */ - g_return_if_fail (priv->actor == NULL); - - priv->priority = priority; -} - -static gint -_clutter_actor_meta_get_priority (ClutterActorMeta *meta) -{ - ClutterActorMetaPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), 0); - - priv = clutter_actor_meta_get_instance_private (meta); - - return priv->priority; -} - -static gboolean -_clutter_actor_meta_is_internal (ClutterActorMeta *meta) -{ - ClutterActorMetaPrivate *priv = - clutter_actor_meta_get_instance_private (meta); - gint priority = priv->priority; - - return (priority <= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_LOW || - priority >= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_HIGH); -} - -/* - * ClutterMetaGroup: a collection of ClutterActorMeta instances - */ - -G_DEFINE_FINAL_TYPE (ClutterMetaGroup, _clutter_meta_group, G_TYPE_OBJECT); - -static void -_clutter_meta_group_dispose (GObject *gobject) -{ - _clutter_meta_group_clear_metas (CLUTTER_META_GROUP (gobject)); - - G_OBJECT_CLASS (_clutter_meta_group_parent_class)->dispose (gobject); -} - -static void -_clutter_meta_group_class_init (ClutterMetaGroupClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->dispose = _clutter_meta_group_dispose; -} - -static void -_clutter_meta_group_init (ClutterMetaGroup *self) -{ -} - -/* - * _clutter_meta_group_add_meta: - * @group: a #ClutterMetaGroup - * @meta: a #ClutterActorMeta to add - * - * Adds @meta to @group - * - * This function will remove the floating reference of @meta or, if the - * floating reference has already been sunk, add a reference to it - */ -void -_clutter_meta_group_add_meta (ClutterMetaGroup *group, - ClutterActorMeta *meta) -{ - ClutterActorMetaPrivate *priv = - clutter_actor_meta_get_instance_private (meta); - GList *prev = NULL, *l; - - if (priv->actor != NULL) - { - g_warning ("The meta of type '%s' with name '%s' is " - "already attached to actor '%s'", - G_OBJECT_TYPE_NAME (meta), - priv->name != NULL - ? priv->name - : "", - clutter_actor_get_name (priv->actor) != NULL - ? clutter_actor_get_name (priv->actor) - : G_OBJECT_TYPE_NAME (priv->actor)); - return; - } - - /* Find a meta that has lower priority and insert before that */ - for (l = group->meta; l; l = l->next) - if (_clutter_actor_meta_get_priority (l->data) < - _clutter_actor_meta_get_priority (meta)) - break; - else - prev = l; - - if (prev == NULL) - group->meta = g_list_prepend (group->meta, meta); - else - { - prev->next = g_list_prepend (prev->next, meta); - prev->next->prev = prev; - } - - g_object_ref_sink (meta); - - _clutter_actor_meta_set_actor (meta, group->actor); -} - -/* - * _clutter_meta_group_remove_meta: - * @group: a #ClutterMetaGroup - * @meta: a #ClutterActorMeta to remove - * - * Removes @meta from @group and releases the reference being held on it - */ -void -_clutter_meta_group_remove_meta (ClutterMetaGroup *group, - ClutterActorMeta *meta) -{ - ClutterActorMetaPrivate *priv = - clutter_actor_meta_get_instance_private (meta); - - if (priv->actor != group->actor) - { - g_warning ("The meta of type '%s' with name '%s' is not " - "attached to the actor '%s'", - G_OBJECT_TYPE_NAME (meta), - priv->name != NULL - ? priv->name - : "", - clutter_actor_get_name (group->actor) != NULL - ? clutter_actor_get_name (group->actor) - : G_OBJECT_TYPE_NAME (group->actor)); - return; - } - - _clutter_actor_meta_set_actor (meta, NULL); - - group->meta = g_list_remove (group->meta, meta); - g_object_unref (meta); -} - -/* - * _clutter_meta_group_peek_metas: - * @group: a #ClutterMetaGroup - * - * Returns a pointer to the #ClutterActorMeta list - * - * Return value: a const pointer to the #GList of #ClutterActorMeta - */ -const GList * -_clutter_meta_group_peek_metas (ClutterMetaGroup *group) -{ - return group->meta; -} - -/* - * _clutter_meta_group_get_metas_no_internal: - * @group: a #ClutterMetaGroup - * - * Returns a new allocated list containing all of the metas that don't - * have an internal priority. - * - * Return value: A GList containing non-internal metas. Free with - * g_list_free. - */ -GList * -_clutter_meta_group_get_metas_no_internal (ClutterMetaGroup *group) -{ - GList *ret = NULL; - GList *l; - - /* Build a new list filtering out the internal metas */ - for (l = group->meta; l; l = l->next) - if (!_clutter_actor_meta_is_internal (l->data)) - ret = g_list_prepend (ret, l->data); - - return g_list_reverse (ret); -} - -/* - * _clutter_meta_group_has_metas_no_internal: - * @group: a #ClutterMetaGroup - * - * Returns whether the group has any metas that don't have an internal priority. - * - * Return value: %TRUE if metas without internal priority exist - * %FALSE otherwise - */ -gboolean -_clutter_meta_group_has_metas_no_internal (ClutterMetaGroup *group) -{ - GList *l; - - for (l = group->meta; l; l = l->next) - if (!_clutter_actor_meta_is_internal (l->data)) - return TRUE; - - return FALSE; -} - -/* - * _clutter_meta_group_clear_metas: - * @group: a #ClutterMetaGroup - * - * Clears @group of all #ClutterActorMeta instances and releases - * the reference on them - */ -void -_clutter_meta_group_clear_metas (ClutterMetaGroup *group) -{ - g_list_foreach (group->meta, (GFunc) _clutter_actor_meta_set_actor, NULL); - - g_list_free_full (group->meta, g_object_unref); - group->meta = NULL; -} - -/* - * _clutter_meta_group_clear_metas_no_internal: - * @group: a #ClutterMetaGroup - * - * Clears @group of all #ClutterActorMeta instances that don't have an - * internal priority and releases the reference on them - */ -void -_clutter_meta_group_clear_metas_no_internal (ClutterMetaGroup *group) -{ - GList *internal_list = NULL; - GList *l, *next; - - for (l = group->meta; l; l = next) - { - next = l->next; - - if (_clutter_actor_meta_is_internal (l->data)) - { - if (internal_list) - internal_list->prev = l; - l->next = internal_list; - l->prev = NULL; - internal_list = l; - } - else - { - _clutter_actor_meta_set_actor (l->data, NULL); - g_object_unref (l->data); - g_list_free_1 (l); - } - } - - group->meta = g_list_reverse (internal_list); -} - -/* - * _clutter_meta_group_get_meta: - * @group: a #ClutterMetaGroup - * @name: the name of the #ClutterActorMeta to retrieve - * - * Retrieves a named #ClutterActorMeta from @group - * - * Return value: a #ClutterActorMeta for the given name, or %NULL - */ -ClutterActorMeta * -_clutter_meta_group_get_meta (ClutterMetaGroup *group, - const gchar *name) -{ - GList *l; - - for (l = group->meta; l != NULL; l = l->next) - { - ClutterActorMeta *meta = l->data; - ClutterActorMetaPrivate *priv = - clutter_actor_meta_get_instance_private (meta); - - if (g_strcmp0 (priv->name, name) == 0) - return meta; - } - - return NULL; -} - -/*< private > - * clutter_actor_meta_get_debug_name: - * @meta: a #ClutterActorMeta - * - * Retrieves the name of the @meta for debugging purposes. - * - * Return value: (transfer none): the name of the @meta. The returned - * string is owned by the @meta instance and it should not be - * modified or freed - */ -const gchar * -_clutter_actor_meta_get_debug_name (ClutterActorMeta *meta) -{ - ClutterActorMetaPrivate *priv = - clutter_actor_meta_get_instance_private (meta); - - return priv->name != NULL ? priv->name : G_OBJECT_TYPE_NAME (meta); -} diff --git a/mutter/clutter/clutter/clutter-actor-meta.h b/mutter/clutter/clutter/clutter-actor-meta.h deleted file mode 100644 index 4841772..0000000 --- a/mutter/clutter/clutter/clutter-actor-meta.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_ACTOR_META (clutter_actor_meta_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterActorMeta, clutter_actor_meta, - CLUTTER, ACTOR_META, GInitiallyUnowned); - -typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate; - -/** - * ClutterActorMetaClass: - * @set_actor: virtual function, invoked when attaching and detaching - * a #ClutterActorMeta instance to a #ClutterActor - * - * The #ClutterActorMetaClass structure contains - * only private data - */ -struct _ClutterActorMetaClass -{ - /*< private >*/ - GInitiallyUnownedClass parent_class; - - /*< public >*/ - - /** - * ClutterActorMetaClass::set_actor: - * @meta: a #ClutterActorMeta - * @actor: (allow-none): the actor attached to @meta, or %NULL - * - * Virtual function, called when @meta is attached or detached - * from a #ClutterActor. - */ - void (* set_actor) (ClutterActorMeta *meta, - ClutterActor *actor); - - void (* set_enabled) (ClutterActorMeta *meta, - gboolean is_enabled); -}; - -CLUTTER_EXPORT -void clutter_actor_meta_set_name (ClutterActorMeta *meta, - const gchar *name); -CLUTTER_EXPORT -const gchar * clutter_actor_meta_get_name (ClutterActorMeta *meta); -CLUTTER_EXPORT -void clutter_actor_meta_set_enabled (ClutterActorMeta *meta, - gboolean is_enabled); -CLUTTER_EXPORT -gboolean clutter_actor_meta_get_enabled (ClutterActorMeta *meta); - -CLUTTER_EXPORT -ClutterActor * clutter_actor_meta_get_actor (ClutterActorMeta *meta); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-actor-private.h b/mutter/clutter/clutter/clutter-actor-private.h deleted file mode 100644 index 4ad5046..0000000 --- a/mutter/clutter/clutter/clutter-actor-private.h +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#include "clutter/clutter-actor.h" -#include "clutter/clutter-grab.h" - -G_BEGIN_DECLS - -/*< private > - * ClutterActorTraverseFlags: - * CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST: Traverse the graph in - * a depth first order. - * CLUTTER_ACTOR_TRAVERSE_BREADTH_FIRST: Traverse the graph in a - * breadth first order. - * - * Controls some options for how clutter_actor_traverse() iterates - * through the graph. - */ -typedef enum -{ - CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST = 1L<<0, - CLUTTER_ACTOR_TRAVERSE_BREADTH_FIRST = 1L<<1 -} ClutterActorTraverseFlags; - -/*< private > - * ClutterActorTraverseVisitFlags: - * CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE: Continue traversing as - * normal - * CLUTTER_ACTOR_TRAVERSE_VISIT_SKIP_CHILDREN: Don't traverse the - * children of the last visited actor. (Not applicable when using - * %CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST_POST_ORDER since the children - * are visited before having an opportunity to bail out) - * CLUTTER_ACTOR_TRAVERSE_VISIT_BREAK: Immediately bail out without - * visiting any more actors. - * - * Each time an actor is visited during a scenegraph traversal the - * ClutterTraverseCallback can return a set of flags that may affect - * the continuing traversal. It may stop traversal completely, just - * skip over children for the current actor or continue as normal. - */ -typedef enum -{ - CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE = 1L<<0, - CLUTTER_ACTOR_TRAVERSE_VISIT_SKIP_CHILDREN = 1L<<1, - CLUTTER_ACTOR_TRAVERSE_VISIT_BREAK = 1L<<2 -} ClutterActorTraverseVisitFlags; - -/*< private > - * ClutterTraverseCallback: - * - * The callback prototype used with clutter_actor_traverse. The - * returned flags can be used to affect the continuing traversal - * either by continuing as normal, skipping over children of an - * actor or bailing out completely. - */ -typedef ClutterActorTraverseVisitFlags (*ClutterTraverseCallback) (ClutterActor *actor, - gint depth, - gpointer user_data); - -/*< private > - * ClutterForeachCallback: - * @actor: The actor being iterated - * @user_data: The private data specified when starting the iteration - * - * A generic callback for iterating over actor, such as with - * _clutter_actor_foreach_child. - * - * Return value: %TRUE to continue iterating or %FALSE to break iteration - * early. - */ -typedef gboolean (*ClutterForeachCallback) (ClutterActor *actor, - gpointer user_data); - -typedef struct _SizeRequest SizeRequest; - -typedef struct _ClutterLayoutInfo ClutterLayoutInfo; -typedef struct _ClutterTransformInfo ClutterTransformInfo; -typedef struct _ClutterAnimationInfo ClutterAnimationInfo; - -struct _SizeRequest -{ - guint age; - gfloat for_size; - gfloat min_size; - gfloat natural_size; -}; - -/*< private > - * ClutterLayoutInfo: - * @fixed_pos: the fixed position of the actor - * @margin: the composed margin of the actor - * @x_align: the horizontal alignment, if the actor expands horizontally - * @y_align: the vertical alignment, if the actor expands vertically - * @x_expand: whether the actor should expand horizontally - * @y_expand: whether the actor should expand vertically - * @minimum: the fixed minimum size - * @natural: the fixed natural size - * - * Ancillary layout information for an actor. - */ -struct _ClutterLayoutInfo -{ - /* fixed position coordinates */ - graphene_point_t fixed_pos; - - ClutterMargin margin; - - guint x_align : 4; - guint y_align : 4; - - guint x_expand : 1; - guint y_expand : 1; - - graphene_size_t minimum; - graphene_size_t natural; -}; - -const ClutterLayoutInfo * _clutter_actor_get_layout_info_or_defaults (ClutterActor *self); -ClutterLayoutInfo * _clutter_actor_get_layout_info (ClutterActor *self); -ClutterLayoutInfo * _clutter_actor_peek_layout_info (ClutterActor *self); - -struct _ClutterTransformInfo -{ - /* rotation */ - gdouble rx_angle; - gdouble ry_angle; - gdouble rz_angle; - - /* scaling */ - gdouble scale_x; - gdouble scale_y; - gdouble scale_z; - - /* translation */ - graphene_point3d_t translation; - - /* z_position */ - gfloat z_position; - - /* transformation center */ - graphene_point_t pivot; - gfloat pivot_z; - - graphene_matrix_t transform; - guint transform_set : 1; - - graphene_matrix_t child_transform; - guint child_transform_set : 1; -}; - -const ClutterTransformInfo * _clutter_actor_get_transform_info_or_defaults (ClutterActor *self); -ClutterTransformInfo * _clutter_actor_get_transform_info (ClutterActor *self); - -typedef struct _AState { - guint easing_duration; - guint easing_delay; - ClutterAnimationMode easing_mode; -} AState; - -struct _ClutterAnimationInfo -{ - GArray *states; - AState *cur_state; - - GHashTable *transitions; -}; - -const ClutterAnimationInfo * _clutter_actor_get_animation_info_or_defaults (ClutterActor *self); -ClutterAnimationInfo * _clutter_actor_get_animation_info (ClutterActor *self); - -ClutterTransition * _clutter_actor_create_transition (ClutterActor *self, - GParamSpec *pspec, - ...); -gboolean _clutter_actor_foreach_child (ClutterActor *self, - ClutterForeachCallback callback, - gpointer user_data); -void _clutter_actor_traverse (ClutterActor *actor, - ClutterActorTraverseFlags flags, - ClutterTraverseCallback before_children_callback, - ClutterTraverseCallback after_children_callback, - gpointer user_data); -ClutterActor * _clutter_actor_get_stage_internal (ClutterActor *actor); - -void _clutter_actor_apply_modelview_transform (ClutterActor *self, - graphene_matrix_t *matrix); -void _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self, - ClutterActor *ancestor, - graphene_matrix_t *matrix); - -void _clutter_actor_set_in_clone_paint (ClutterActor *self, - gboolean is_in_clone_paint); - -void _clutter_actor_set_enable_model_view_transform (ClutterActor *self, - gboolean enable); - -void _clutter_actor_set_enable_paint_unmapped (ClutterActor *self, - gboolean enable); - -void _clutter_actor_set_has_pointer (ClutterActor *self, - gboolean has_pointer); - -void _clutter_actor_set_has_key_focus (ClutterActor *self, - gboolean has_key_focus); - -void _clutter_actor_queue_redraw_full (ClutterActor *self, - const ClutterPaintVolume *volume, - ClutterEffect *effect); - -gboolean _clutter_actor_set_default_paint_volume (ClutterActor *self, - GType check_gtype, - ClutterPaintVolume *volume); - -const char * _clutter_actor_get_debug_name (ClutterActor *self); - -void _clutter_actor_push_clone_paint (void); -void _clutter_actor_pop_clone_paint (void); - -ClutterActorAlign _clutter_actor_get_effective_x_align (ClutterActor *self); - -void _clutter_actor_attach_clone (ClutterActor *actor, - ClutterActor *clone); -void _clutter_actor_detach_clone (ClutterActor *actor, - ClutterActor *clone); -void _clutter_actor_queue_only_relayout (ClutterActor *actor); -void clutter_actor_clear_stage_views_recursive (ClutterActor *actor, - gboolean stop_transitions); - -float clutter_actor_get_real_resource_scale (ClutterActor *actor); - -void clutter_actor_finish_layout (ClutterActor *self, - int phase); - -void clutter_actor_queue_immediate_relayout (ClutterActor *self); - -gboolean clutter_actor_is_painting_unmapped (ClutterActor *self); - -void clutter_actor_attach_grab (ClutterActor *actor, - ClutterGrab *grab); -void clutter_actor_detach_grab (ClutterActor *actor, - ClutterGrab *grab); - -void clutter_actor_collect_event_actors (ClutterActor *self, - ClutterActor *deepmost, - GPtrArray *actors); - -const GList * clutter_actor_peek_actions (ClutterActor *self); - -void clutter_actor_set_implicitly_grabbed (ClutterActor *actor, - gboolean is_implicitly_grabbed); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-actor.c b/mutter/clutter/clutter/clutter-actor.c deleted file mode 100644 index f9487b9..0000000 --- a/mutter/clutter/clutter/clutter-actor.c +++ /dev/null @@ -1,18606 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006, 2007, 2008 OpenedHand Ltd - * Copyright (C) 2009, 2010, 2011, 2012 Intel Corp - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/** - * ClutterActor: - * - * The basic element of the scene graph - * - * The ClutterActor class is the basic element of the scene graph in Clutter, - * and it encapsulates the position, size, and transformations of a node in - * the graph. - * - * ## Actor transformations - * - * Each actor can be transformed using methods like [method@Actor.set_scale] - * or [method@Actor.set_rotation_angle]. The order in which the transformations are - * applied is decided by Clutter and it is the following: - * - * 1. translation by the origin of the [property@Actor:allocation] property - * 2. translation by the actor's [property@Actor:z-position] property - * 3. translation by the actor's [property@Actor:pivot-point] property - * 4. scaling by the [property@Actor:scale-x] and [property@Actor:scale-y] factors - * 5. rotation around the [property@Actor:rotation-angle-x] - * 6. rotation around the [property@Actor:rotation-angle-y] - * 7. rotation around the [property@Actor:rotation-angle-z] - * 8. negative translation by the actor's [property@Actor:pivot-point] - * - * ## Modifying an actor's geometry - * - * Each actor has a bounding box, called [property@Actor:allocation] - * which is either set by its parent or explicitly through the - * [method@Actor.set_position] and [method@Actor.set_size] methods. - * Each actor also has an implicit preferred size. - * - * An actor’s preferred size can be defined by any subclass by - * overriding the [vfunc@Actor.get_preferred_width] and the - * [vfunc@Actor.get_preferred_height] virtual functions, or it can - * be explicitly set by using [method@Actor.set_width] and - * [method@Actor.set_height]. - * - * An actor’s position can be set explicitly by using - * [method@Actor.set_x] and [method@Actor.set_y]; the coordinates are - * relative to the origin of the actor’s parent. - * - * ## Managing actor children - * - * Each actor can have multiple children, by calling - * [method@Clutter.Actor.add_child] to add a new child actor, and - * [method@Clutter.Actor.remove_child] to remove an existing child. #ClutterActor - * will hold a reference on each child actor, which will be released when - * the child is removed from its parent, or destroyed using - * [method@Clutter.Actor.destroy]. - * - * ```c - * ClutterActor *actor = clutter_actor_new (); - * - * // set the bounding box of the actor - * clutter_actor_set_position (actor, 0, 0); - * clutter_actor_set_size (actor, 480, 640); - * - * // set the background color of the actor - * clutter_actor_set_background_color (actor, &CLUTTER_COLOR_INIT (0xf5, 0x79, 0x00, 0xff)); - * - * // set the bounding box of the child, relative to the parent - * ClutterActor *child = clutter_actor_new (); - * clutter_actor_set_position (child, 20, 20); - * clutter_actor_set_size (child, 80, 240); - * - * // set the background color of the child - * clutter_actor_set_background_color (child, &CLUTTER_COLOR_INIT (0x00, 0x00, 0xff, 0xff)); - * - * // add the child to the actor - * clutter_actor_add_child (actor, child); - * ``` - * - * Children can be inserted at a given index, or above and below - * another child actor. The order of insertion determines the order of the - * children when iterating over them. Iterating over children is performed - * by using [method@Clutter.Actor.get_first_child], [method@Clutter.Actor.get_previous_sibling], - * [method@Clutter.Actor.get_next_sibling], and [method@Clutter.Actor.get_last_child]. It is - * also possible to retrieve a list of children by using - * [method@Clutter.Actor.get_children], as well as retrieving a specific child at a - * given index by using [method@Clutter.Actor.get_child_at_index]. - * - * If you need to track additions of children to a [type@Clutter.Actor], use - * the [signal@Clutter.Actor::child-added] signal; similarly, to track - * removals of children from a ClutterActor, use the - * [signal@Clutter.Actor::child-removed] signal. - * - * ## Painting an actor - * - * There are three ways to paint an actor: - * - * - set a delegate #ClutterContent as the value for the [property@Clutter.Actor:content] property of the actor - * - subclass #ClutterActor and override the [vfunc@Clutter.Actor.paint_node] virtual function - * - subclass #ClutterActor and override the [vfunc@Clutter.Actor.paint] virtual function. - * - * A #ClutterContent is a delegate object that takes over the painting - * operations of one, or more actors. The #ClutterContent painting will - * be performed on top of the [property@Clutter.Actor:background-color] of the actor, - * and before calling the actor's own implementation of the - * [vfunc@Clutter.Actor.paint_node] virtual function. - * - * ```c - * ClutterActor *actor = clutter_actor_new (); - * - * // set the bounding box - * clutter_actor_set_position (actor, 50, 50); - * clutter_actor_set_size (actor, 100, 100); - * - * // set the content; the image_content variable is set elsewhere - * clutter_actor_set_content (actor, image_content); - * ``` - * - * The [vfunc@Clutter.Actor.paint_node] virtual function is invoked whenever - * an actor needs to be painted. The implementation of the virtual function - * must only paint the contents of the actor itself, and not the contents of - * its children, if the actor has any. - * - * The #ClutterPaintNode passed to the virtual function is the local root of - * the render tree; any node added to it will be rendered at the correct - * position, as defined by the actor's [property@Clutter.Actor:allocation]. - * - * ```c - * static void - * my_actor_paint_node (ClutterActor *actor, - * ClutterPaintNode *root) - * { - * ClutterPaintNode *node; - * ClutterActorBox box; - * - * // where the content of the actor should be painted - * clutter_actor_get_allocation_box (actor, &box); - * - * // the cogl_texture variable is set elsewhere - * node = clutter_texture_node_new (cogl_texture, &CLUTTER_COLOR_INIT (255, 255, 255, 255), - * CLUTTER_SCALING_FILTER_TRILINEAR, - * CLUTTER_SCALING_FILTER_LINEAR); - * - * // paint the content of the node using the allocation - * clutter_paint_node_add_rectangle (node, &box); - * - * // add the node, and transfer ownership - * clutter_paint_node_add_child (root, node); - * clutter_paint_node_unref (node); - * } - * ``` - * - * The [vfunc@Clutter.Actor.paint] virtual function function gives total - * control to the paint sequence of the actor itself, including the - * children of the actor, if any. It is strongly discouraged to override - * the [vfunc@Clutter.Actor.paint] virtual function and it will be removed - * when the Clutter API changes. - * - * ## Handling events on an actor - * - * A #ClutterActor can receive and handle input device events, for - * instance pointer events and key events, as long as its - * [property@Clutter.Actor:reactive] property is set to %TRUE. - * - * Once an actor has been determined to be the source of an event, - * Clutter will traverse the scene graph from the top-level actor towards the - * event source, emitting the [signal@Clutter.Actor::captured-event] signal on each - * ancestor until it reaches the source; this phase is also called - * the "capture" phase. If the event propagation was not stopped, the graph - * is walked backwards, from the source actor to the top-level, and the - * [signal@Clutter.Actor::event signal] is emitted, alongside eventual event-specific - * signals like [signal@Clutter.Actor::button-press-event] or [signal@Clutter.Actor::motion-event]; - * this phase is also called the "bubble" phase. - * - * At any point of the signal emission, signal handlers can stop the propagation - * through the scene graph by returning %CLUTTER_EVENT_STOP; otherwise, they can - * continue the propagation by returning %CLUTTER_EVENT_PROPAGATE. - * - * ## Animation - * - * Animation is a core concept of modern user interfaces; Clutter provides a - * complete and powerful animation framework that automatically tweens the - * actor's state without requiring direct, frame by frame manipulation from - * your application code. You have two models at your disposal: - * - * - an implicit animation model - * - an explicit animation model - * - * The implicit animation model of Clutter assumes that all the - * changes in an actor state should be gradual and asynchronous; Clutter - * will automatically transition an actor's property change between the - * current state and the desired one without manual intervention, if the - * property is defined to be animatable in its documentation. - * - * By default, in the 1.0 API series, the transition happens with a duration - * of zero milliseconds, and the implicit animation is an opt in feature to - * retain backwards compatibility. - * - * Implicit animations depend on the current easing state; in order to use - * the default easing state for an actor you should call the - * [method@Clutter.Actor.save_easing_state] function: - * - * ```c - * // assume that the actor is currently positioned at (100, 100) - * - * // store the current easing state and reset the new easing state to - * // its default values - * clutter_actor_save_easing_state (actor); - * - * // change the actor's position - * clutter_actor_set_position (actor, 500, 500); - * - * // restore the previously saved easing state - * clutter_actor_restore_easing_state (actor); - * ``` - * - * The example above will trigger an implicit animation of the - * actor between its current position to a new position. - * - * Implicit animations use a default duration of 250 milliseconds, - * and a default easing mode of %CLUTTER_EASE_OUT_CUBIC, unless you call - * [method@Clutter.Actor.set_easing_mode] and [method@Clutter.Actor.set_easing_duration] - * after changing the easing state of the actor. - * - * It is possible to animate multiple properties of an actor - * at the same time, and you can animate multiple actors at the same - * time as well, for instance: - * - * ```c - * clutter_actor_save_easing_state (actor); - * - * // animate the actor's opacity and depth - * clutter_actor_set_opacity (actor, 0); - * clutter_actor_set_z_position (actor, -100); - * - * clutter_actor_restore_easing_state (actor); - * - * clutter_actor_save_easing_state (another_actor); - * - * // animate another actor's opacity - * clutter_actor_set_opacity (another_actor, 255); - * clutter_actor_set_z_position (another_actor, 100); - * - * clutter_actor_restore_easing_state (another_actor); - * ``` - * - * Changing the easing state will affect all the following property - * transitions, but will not affect existing transitions. - * - * It is important to note that if you modify the state on an - * animatable property while a transition is in flight, the transition's - * final value will be updated, as well as its duration and progress - * mode by using the current easing state; for instance, in the following - * example: - * - * ```c - * clutter_actor_save_easing_state (actor); - * clutter_actor_set_easing_duration (actor, 1000); - * clutter_actor_set_x (actor, 200); - * clutter_actor_restore_easing_state (actor); - * - * clutter_actor_save_easing_state (actor); - * clutter_actor_set_easing_duration (actor, 500); - * clutter_actor_set_x (actor, 100); - * clutter_actor_restore_easing_state (actor); - * ``` - * - * the first call to [method@Clutter.Actor.set_x] will begin a transition - * of the [property@Clutter.Actor:x] property from the current value to the value of - * 200 over a duration of one second; the second call to [method@Clutter.Actor.set_x] - * will change the transition's final value to 100 and the duration to 500 - * milliseconds. - * - * It is possible to receive a notification of the completion of an - * implicit transition by using the [signal@Clutter.Actor::transition-stopped] - * signal, decorated with the name of the property. In case you want to - * know when all the currently in flight transitions are complete, use - * the [signal@Clutter.Actor::transitions-completed] signal instead. - * - * It is possible to retrieve the [class@Clutter.Transition] used by the - * animatable properties by using [method@Clutter.Actor.get_transition] and using - * the property name as the transition name. - * - * The explicit animation model supported by Clutter requires that - * you create a #ClutterTransition object, and optionally set the initial - * and final values. The transition will not start unless you add it to the - * #ClutterActor. - * - * ```c - * ClutterTransition *transition; - * - * transition = clutter_property_transition_new_for_actor (actor, "opacity"); - * clutter_timeline_set_duration (CLUTTER_TIMELINE (transition), 3000); - * clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), 2); - * clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (transition), TRUE); - * clutter_transition_set_from (transition, G_TYPE_UINT, 255); - * clutter_transition_set_to (transition, G_TYPE_UINT, 0); - * - * clutter_actor_add_transition (actor, "animate-opacity", transition); - * ``` - * - * The example above will animate the [property@Clutter.Actor:opacity] property - * of an actor between fully opaque and fully transparent, and back, over - * a span of 3 seconds. The animation does not begin until it is added to - * the actor. - * - * The explicit animation API applies to all #GObject properties, - * as well as the custom properties defined through the [iface@Clutter.Animatable] - * interface, regardless of whether they are defined as implicitly - * animatable or not. - * - * The explicit animation API should also be used when using custom - * animatable properties for [class@Clutter.Action], [class@Clutter.Constraint], and - * [class@Clutter.Effect] instances associated to an actor; see the section on - * custom animatable properties below for an example. - * - * Finally, explicit animations are useful for creating animations - * that run continuously, for instance: - * - * ```c - * // this animation will pulse the actor's opacity continuously - * ClutterTransition *transition; - * ClutterInterval *interval; - * - * transition = clutter_property_transition_new_for_actor (actor, "opacity"); - * - * // we want to animate the opacity between 0 and 255 - * clutter_transition_set_from (transition, G_TYPE_UINT, 0); - * clutter_transition_set_to (transition, G_TYPE_UINT, 255); - * - * // over a one second duration, running an infinite amount of times - * clutter_timeline_set_duration (CLUTTER_TIMELINE (transition), 1000); - * clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), -1); - * - * // we want to fade in and out, so we need to auto-reverse the transition - * clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (transition), TRUE); - * - * // and we want to use an easing function that eases both in and out - * clutter_timeline_set_progress_mode (CLUTTER_TIMELINE (transition), - * CLUTTER_EASE_IN_OUT_CUBIC); - * - * // add the transition to the desired actor to start it - * clutter_actor_add_transition (actor, "opacityAnimation", transition); - * ``` - * - * ## Implementing an actor - * - * Careful consideration should be given when deciding to implement - * a #ClutterActor sub-class. It is generally recommended to implement a - * sub-class of #ClutterActor only for actors that should be used as leaf - * nodes of a scene graph. - * - * By overriding the [vfunc@Clutter.Actor.get_preferred_width] and - * [vfunc@Clutter.Actor.get_preferred_height] virtual functions it is - * possible to change or provide the preferred size of an actor; similarly, - * by overriding the [vfunc@Clutter.Actor.allocate] virtual function it is - * possible to control the layout of the children of an actor. Make sure to - * always chain up to the parent implementation of the - * [vfunc@Clutter.Actor.allocate] virtual function. - * - * In general, it is strongly encouraged to use delegation and composition - * instead of direct subclassing. - * - * ## Custom animatable properties - * - * #ClutterActor allows accessing properties of [class@Clutter.Action], - * [class@Clutter.Effect], and [class@Clutter.Constraint] instances associated to an actor - * instance for animation purposes, as well as its [class@Clutter.LayoutManager]. - * - * In order to access a specific [class@Clutter.Action] or a [class@Clutter.Constraint] - * property it is necessary to set the [property@Clutter.ActorMeta:name] property on the - * given action or constraint. - * - * The property can be accessed using the following syntax: - * - * ``` - * @
.. - * ``` - * - * - the initial `@` is mandatory - * - the `section` fragment can be one between "actions", "constraints", "content", - * and "effects" - * - the `meta-name` fragment is the name of the action, effect, or constraint, as - * specified by the #ClutterActorMeta:name property of #ClutterActorMeta - * - the `property-name` fragment is the name of the action, effect, or constraint - * property to be animated. - * - * The example below animates a [class@Clutter.BindConstraint] applied to an actor - * using an explicit transition. The `rect` actor has a binding constraint - * on the `origin` actor, and in its initial state is overlapping the actor - * to which is bound to. - * - * As the actor has only one [class@Clutter.LayoutManager], the syntax for accessing its - * properties is simpler: - * - * ``` - * @layout. - * ``` - * - * ```c - * constraint = clutter_bind_constraint_new (origin, CLUTTER_BIND_X, 0.0); - * clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), "bind-x"); - * clutter_actor_add_constraint (rect, constraint); - * - * constraint = clutter_bind_constraint_new (origin, CLUTTER_BIND_Y, 0.0); - * clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), "bind-y"); - * clutter_actor_add_constraint (rect, constraint); - * - * clutter_actor_set_reactive (origin, TRUE); - * - * g_signal_connect (origin, "button-press-event", - * G_CALLBACK (on_button_press), - * rect); - * ``` - * - * On button press, the rectangle "slides" from behind the actor to - * which is bound to, using the #ClutterBindConstraint:offset property to - * achieve the effect: - * - * ```c - * gboolean - * on_button_press (ClutterActor *origin, - * ClutterEvent *event, - * ClutterActor *rect) - * { - * ClutterTransition *transition; - * - * // the offset that we want to apply; this will make the actor - * // slide in from behind the origin and rest at the right of - * // the origin, plus a padding value - * float new_offset = clutter_actor_get_width (origin) + h_padding; - * - * // the property we wish to animate; the "@constraints" section - * // tells Clutter to check inside the constraints associated - * // with the actor; the "bind-x" section is the name of the - * // constraint; and the "offset" is the name of the property - * // on the constraint - * const char *prop = "@constraints.bind-x.offset"; - * - * // create a new transition for the given property - * transition = clutter_property_transition_new_for_actor (rect, prop); - * - * // set the easing mode and duration - * clutter_timeline_set_progress_mode (CLUTTER_TIMELINE (transition), - * CLUTTER_EASE_OUT_CUBIC); - * clutter_timeline_set_duration (CLUTTER_TIMELINE (transition), 500); - * - * // create the interval with the initial and final values - * clutter_transition_set_from (transition, G_TYPE_FLOAT, 0.f); - * clutter_transition_set_to (transition, G_TYPE_FLOAT, new_offset); - * - * // add the transition to the actor; this causes the animation - * // to start. the name "offsetAnimation" can be used to retrieve - * // the transition later - * clutter_actor_add_transition (rect, "offsetAnimation", transition); - * - * // we handled the event - * return CLUTTER_EVENT_STOP; - * } - * ``` - */ - -#include "config.h" - -#include - -#include - -#include "cogl/cogl.h" - -#include "clutter/clutter-actor-private.h" - -#include "clutter/clutter-action.h" -#include "clutter/clutter-action-private.h" -#include "clutter/clutter-actor-meta-private.h" -#include "clutter/clutter-animatable.h" -#include "clutter/clutter-color-state.h" -#include "clutter/clutter-color.h" -#include "clutter/clutter-constraint-private.h" -#include "clutter/clutter-content-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-easing.h" -#include "clutter/clutter-effect-private.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-fixed-layout.h" -#include "clutter/clutter-flatten-effect.h" -#include "clutter/clutter-interval.h" -#include "clutter/clutter-main.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-mutter.h" -#include "clutter/clutter-paint-context-private.h" -#include "clutter/clutter-paint-nodes.h" -#include "clutter/clutter-paint-node-private.h" -#include "clutter/clutter-paint-volume-private.h" -#include "clutter/clutter-pick-context-private.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-property-transition.h" -#include "clutter/clutter-stage-private.h" -#include "clutter/clutter-stage-view-private.h" -#include "clutter/clutter-timeline.h" -#include "clutter/clutter-transition.h" - - -static const ClutterColor transparent = { 0x00, 0x00, 0x00, 0x00 }; - -/* Internal enum used to control mapped state update. This is a hint - * which indicates when to do something other than just enforce - * invariants. - */ -typedef enum -{ - MAP_STATE_CHECK, /* just enforce invariants. */ - MAP_STATE_MAKE_UNREALIZED, /* force unrealize, ignoring invariants, - * used when about to unparent. - */ - MAP_STATE_MAKE_MAPPED, /* set mapped, error if invariants not met; - * used to set mapped on toplevels. - */ - MAP_STATE_MAKE_UNMAPPED /* set unmapped, even if parent is mapped, - * used just before unmapping parent. - */ -} MapStateChange; - -/* 3 entries should be a good compromise, few layout managers - * will ask for 3 different preferred size in each allocation cycle */ -#define N_CACHED_SIZE_REQUESTS 3 - -struct _ClutterActorPrivate -{ - /* request mode */ - ClutterRequestMode request_mode; - - /* our cached size requests for different width / height */ - SizeRequest width_requests[N_CACHED_SIZE_REQUESTS]; - SizeRequest height_requests[N_CACHED_SIZE_REQUESTS]; - - /* An age of 0 means the entry is not set */ - guint cached_height_age; - guint cached_width_age; - - /* the bounding box of the actor, relative to the parent's - * allocation - */ - ClutterActorBox allocation; - - /* clip, in actor coordinates */ - graphene_rect_t clip; - - /* the cached transformation matrix; see apply_transform() */ - graphene_matrix_t transform; - - graphene_matrix_t stage_relative_modelview; - - float resource_scale; - - guint8 opacity; - gint opacity_override; - unsigned int inhibit_culling_counter; - - ClutterOffscreenRedirect offscreen_redirect; - - /* This is an internal effect used to implement the - offscreen-redirect property */ - ClutterEffect *flatten_effect; - - /* scene graph */ - ClutterActor *parent; - ClutterActor *prev_sibling; - ClutterActor *next_sibling; - ClutterActor *first_child; - ClutterActor *last_child; - - gint n_children; - - /* tracks whenever the children of an actor are changed; the - * age is incremented by 1 whenever an actor is added or - * removed. the age is not incremented when the first or the - * last child pointers are changed, or when grandchildren of - * an actor are changed. - */ - gint age; - - gchar *name; /* a non-unique name, used for debugging */ - - /* a back-pointer to the Pango context that we can use - * to create pre-configured PangoLayout - */ - PangoContext *pango_context; - - /* the text direction configured for this child - either by - * application code, or by the actor's parent - */ - ClutterTextDirection text_direction; - - /* meta classes */ - ClutterMetaGroup *actions; - ClutterMetaGroup *constraints; - ClutterMetaGroup *effects; - - /* delegate object used to allocate the children of this actor */ - ClutterLayoutManager *layout_manager; - - /* delegate object used to paint the contents of this actor */ - ClutterContent *content; - - ClutterActorBox content_box; - ClutterContentGravity content_gravity; - ClutterScalingFilter min_filter; - ClutterScalingFilter mag_filter; - ClutterContentRepeat content_repeat; - - /* used when painting, to update the paint volume */ - ClutterEffect *current_effect; - - /* color state contains properties like colorspace for - * each clutter actor */ - ClutterColorState *color_state; - - /* This is used to store an effect which needs to be redrawn. A - redraw can be queued to start from a particular effect. This is - used by parametrised effects that can cache an image of the - actor. If a parameter of the effect changes then it only needs to - redraw the cached image, not the actual actor. The pointer is - only valid if is_dirty == TRUE. If the pointer is NULL then the - whole actor is dirty. */ - ClutterEffect *effect_to_redraw; - - /* This is used when painting effects to implement the - clutter_actor_continue_paint() function. It points to the node in - the list of effects that is next in the chain */ - const GList *next_effect_to_paint; - - ClutterPaintVolume paint_volume; - - /* The paint volume of the actor when it was last drawn to the screen, - * stored in absolute coordinates. - */ - ClutterPaintVolume visible_paint_volume; - - ClutterColor bg_color; - - /* a string used for debugging messages */ - char *debug_name; - - /* a set of clones of the actor */ - GHashTable *clones; - - /* whether the actor is inside a cloned branch; this - * value is propagated to all the actor's children - */ - gulong in_cloned_branch; - - guint unmapped_paint_branch_counter; - - GListModel *child_model; - ClutterActorCreateChildFunc create_child_func; - gpointer create_child_data; - GDestroyNotify create_child_notify; - - gulong resolution_changed_id; - gulong font_changed_id; - gulong layout_changed_id; - - GList *stage_views; - GList *grabs; - - unsigned int n_pointers; - unsigned int implicitly_grabbed_count; - - GArray *next_redraw_clips; - - /* bitfields: KEEP AT THE END */ - - /* fixed position and sizes */ - guint position_set : 1; - guint min_width_set : 1; - guint min_height_set : 1; - guint natural_width_set : 1; - guint natural_height_set : 1; - /* cached request is invalid (implies allocation is too) */ - guint needs_width_request : 1; - /* cached request is invalid (implies allocation is too) */ - guint needs_height_request : 1; - /* cached allocation is invalid (request has changed, probably) */ - guint needs_allocation : 1; - guint show_on_set_parent : 1; - guint has_clip : 1; - guint clip_to_allocation : 1; - guint enable_model_view_transform : 1; - guint enable_paint_unmapped : 1; - guint has_key_focus : 1; - guint propagated_one_redraw : 1; - guint has_paint_volume : 1; - guint visible_paint_volume_valid : 1; - guint in_clone_paint : 1; - guint transform_valid : 1; - /* This is TRUE if anything has queued a redraw since we were last - painted. In this case effect_to_redraw will point to an effect - the redraw was queued from or it will be NULL if the redraw was - queued without an effect. */ - guint is_dirty : 1; - guint bg_color_set : 1; - guint content_box_valid : 1; - guint x_expand_set : 1; - guint y_expand_set : 1; - guint needs_compute_expand : 1; - guint needs_x_expand : 1; - guint needs_y_expand : 1; - guint needs_paint_volume_update : 1; - guint needs_visible_paint_volume_update : 1; - guint had_effects_on_last_paint_volume_update : 1; - guint needs_update_stage_views : 1; - guint clear_stage_views_needs_stage_views_changed : 1; - guint needs_redraw : 1; - guint needs_finish_layout : 1; - guint stage_relative_modelview_valid : 1; -}; - -enum -{ - PROP_0, - - PROP_NAME, - - /* X, Y, WIDTH, HEIGHT are "do what I mean" properties; - * when set they force a size request, when gotten they - * get the allocation if the allocation is valid, and the - * request otherwise - */ - PROP_X, - PROP_Y, - PROP_WIDTH, - PROP_HEIGHT, - - PROP_POSITION, - PROP_SIZE, - - /* Then the rest of these size-related properties are the "actual" - * underlying properties set or gotten by X, Y, WIDTH, HEIGHT - */ - PROP_FIXED_X, - PROP_FIXED_Y, - - PROP_FIXED_POSITION_SET, - - PROP_MIN_WIDTH, - PROP_MIN_WIDTH_SET, - - PROP_MIN_HEIGHT, - PROP_MIN_HEIGHT_SET, - - PROP_NATURAL_WIDTH, - PROP_NATURAL_WIDTH_SET, - - PROP_NATURAL_HEIGHT, - PROP_NATURAL_HEIGHT_SET, - - PROP_REQUEST_MODE, - - /* Allocation properties are read-only */ - PROP_ALLOCATION, - - PROP_Z_POSITION, - - PROP_CLIP_RECT, - PROP_HAS_CLIP, - PROP_CLIP_TO_ALLOCATION, - - PROP_OPACITY, - - PROP_OFFSCREEN_REDIRECT, - - PROP_VISIBLE, - PROP_MAPPED, - PROP_REALIZED, - PROP_REACTIVE, - - PROP_PIVOT_POINT, - PROP_PIVOT_POINT_Z, - - PROP_SCALE_X, - PROP_SCALE_Y, - PROP_SCALE_Z, - - PROP_ROTATION_ANGLE_X, /* XXX:2.0 rename to rotation-x */ - PROP_ROTATION_ANGLE_Y, /* XXX:2.0 rename to rotation-y */ - PROP_ROTATION_ANGLE_Z, /* XXX:2.0 rename to rotation-z */ - - PROP_TRANSLATION_X, - PROP_TRANSLATION_Y, - PROP_TRANSLATION_Z, - - PROP_TRANSFORM, - PROP_TRANSFORM_SET, - PROP_CHILD_TRANSFORM, - PROP_CHILD_TRANSFORM_SET, - - PROP_SHOW_ON_SET_PARENT, /*XXX:2.0 remove */ - - PROP_TEXT_DIRECTION, - PROP_HAS_POINTER, - - PROP_ACTIONS, - PROP_CONSTRAINTS, - PROP_EFFECT, - - PROP_LAYOUT_MANAGER, - - PROP_X_EXPAND, - PROP_Y_EXPAND, - PROP_X_ALIGN, - PROP_Y_ALIGN, - PROP_MARGIN_TOP, - PROP_MARGIN_BOTTOM, - PROP_MARGIN_LEFT, - PROP_MARGIN_RIGHT, - - PROP_BACKGROUND_COLOR, - PROP_BACKGROUND_COLOR_SET, - - PROP_FIRST_CHILD, - PROP_LAST_CHILD, - - PROP_CONTENT, - PROP_CONTENT_GRAVITY, - PROP_CONTENT_BOX, - PROP_MINIFICATION_FILTER, - PROP_MAGNIFICATION_FILTER, - PROP_CONTENT_REPEAT, - - PROP_COLOR_STATE, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -enum -{ - SHOW, - HIDE, - DESTROY, - PARENT_SET, - KEY_FOCUS_IN, - KEY_FOCUS_OUT, - PAINT, - PICK, - REALIZE, - UNREALIZE, - QUEUE_RELAYOUT, - EVENT, - CAPTURED_EVENT, - BUTTON_PRESS_EVENT, - BUTTON_RELEASE_EVENT, - SCROLL_EVENT, - KEY_PRESS_EVENT, - KEY_RELEASE_EVENT, - MOTION_EVENT, - ENTER_EVENT, - LEAVE_EVENT, - TRANSITIONS_COMPLETED, - TOUCH_EVENT, - TRANSITION_STOPPED, - STAGE_VIEWS_CHANGED, - RESOURCE_SCALE_CHANGED, - CHILD_ADDED, - CHILD_REMOVED, - CLONED, - DECLONED, - - LAST_SIGNAL -}; - -static guint actor_signals[LAST_SIGNAL] = { 0, }; - -typedef struct _TransitionClosure -{ - ClutterActor *actor; - ClutterTransition *transition; - gchar *name; - gulong completed_id; -} TransitionClosure; - -static void clutter_animatable_iface_init (ClutterAnimatableInterface *iface); -static void atk_implementor_iface_init (AtkImplementorIface *iface); - -/* These setters are all static for now, maybe they should be in the - * public API, but they are perhaps obscure enough to leave only as - * properties - */ -static void clutter_actor_set_min_width (ClutterActor *self, - gfloat min_width); -static void clutter_actor_set_min_height (ClutterActor *self, - gfloat min_height); -static void clutter_actor_set_natural_width (ClutterActor *self, - gfloat natural_width); -static void clutter_actor_set_natural_height (ClutterActor *self, - gfloat natural_height); -static void clutter_actor_set_min_width_set (ClutterActor *self, - gboolean use_min_width); -static void clutter_actor_set_min_height_set (ClutterActor *self, - gboolean use_min_height); -static void clutter_actor_set_natural_width_set (ClutterActor *self, - gboolean use_natural_width); -static void clutter_actor_set_natural_height_set (ClutterActor *self, - gboolean use_natural_height); -static void clutter_actor_update_map_state (ClutterActor *self, - MapStateChange change); -static void clutter_actor_unrealize_not_hiding (ClutterActor *self); - -static ClutterPaintVolume *_clutter_actor_get_paint_volume_mutable (ClutterActor *self); - -static guint8 clutter_actor_get_paint_opacity_internal (ClutterActor *self); - -static inline void clutter_actor_set_background_color_internal (ClutterActor *self, - const ClutterColor *color); - -static void on_layout_manager_changed (ClutterLayoutManager *manager, - ClutterActor *self); - -static inline void clutter_actor_queue_compute_expand (ClutterActor *self); - -static inline void clutter_actor_set_margin_internal (ClutterActor *self, - gfloat margin, - GParamSpec *pspec); - -static void clutter_actor_set_transform_internal (ClutterActor *self, - const graphene_matrix_t *transform); -static void clutter_actor_set_child_transform_internal (ClutterActor *self, - const graphene_matrix_t *transform); - -static void clutter_actor_realize_internal (ClutterActor *self); -static void clutter_actor_unrealize_internal (ClutterActor *self); - -static void clutter_actor_push_in_cloned_branch (ClutterActor *self, - gulong count); -static void clutter_actor_pop_in_cloned_branch (ClutterActor *self, - gulong count); -static void ensure_valid_actor_transform (ClutterActor *actor); - -static void push_in_paint_unmapped_branch (ClutterActor *self, - guint count); -static void pop_in_paint_unmapped_branch (ClutterActor *self, - guint count); - -static void clutter_actor_update_devices (ClutterActor *self); - -static GQuark quark_actor_layout_info = 0; -static GQuark quark_actor_transform_info = 0; -static GQuark quark_actor_animation_info = 0; - -static GQuark quark_key = 0; -static GQuark quark_motion = 0; -static GQuark quark_pointer_focus = 0; -static GQuark quark_button = 0; -static GQuark quark_scroll = 0; -static GQuark quark_stage = 0; -static GQuark quark_touch = 0; -static GQuark quark_touchpad = 0; -static GQuark quark_proximity = 0; -static GQuark quark_pad = 0; -static GQuark quark_im = 0; - -G_DEFINE_TYPE_WITH_CODE (ClutterActor, - clutter_actor, - G_TYPE_INITIALLY_UNOWNED, - G_ADD_PRIVATE (ClutterActor) - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_ANIMATABLE, - clutter_animatable_iface_init) - G_IMPLEMENT_INTERFACE (ATK_TYPE_IMPLEMENTOR, - atk_implementor_iface_init)); - -/*< private > - * clutter_actor_get_debug_name: - * @actor: a #ClutterActor - * - * Retrieves a printable name of @actor for debugging messages - * - * Return value: a string with a printable name - */ -const char * -_clutter_actor_get_debug_name (ClutterActor *actor) -{ - ClutterActorPrivate *priv; - const char *retval; - - if (!actor) - return "[NULL]"; - - priv = actor->priv; - - if (G_UNLIKELY (priv->debug_name == NULL)) - { - priv->debug_name = g_strdup_printf ("%s [%s]", - priv->name != NULL ? priv->name - : "unnamed", - G_OBJECT_TYPE_NAME (actor)); - } - - retval = priv->debug_name; - - return retval; -} - -#ifdef CLUTTER_ENABLE_DEBUG -/* XXX - this is for debugging only, remove once working (or leave - * in only in some debug mode). Should leave it for a little while - * until we're confident in the new map/realize/visible handling. - */ -static inline void -clutter_actor_verify_map_state (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - - if (clutter_actor_is_realized (self)) - { - if (priv->parent == NULL) - { - if (!CLUTTER_ACTOR_IS_TOPLEVEL (self)) - { - g_warning ("Realized non-toplevel actor '%s' should " - "have a parent", - _clutter_actor_get_debug_name (self)); - } - } - else if (!clutter_actor_is_realized (priv->parent)) - { - g_warning ("Realized actor %s has an unrealized parent %s", - _clutter_actor_get_debug_name (self), - _clutter_actor_get_debug_name (priv->parent)); - } - } - - if (clutter_actor_is_mapped (self)) - { - if (!clutter_actor_is_realized (self)) - g_warning ("Actor '%s' is mapped but not realized", - _clutter_actor_get_debug_name (self)); - - if (priv->parent == NULL) - { - if (CLUTTER_ACTOR_IS_TOPLEVEL (self)) - { - if (!clutter_actor_is_visible (self) && - !CLUTTER_ACTOR_IN_DESTRUCTION (self)) - { - g_warning ("Toplevel actor '%s' is mapped " - "but not visible", - _clutter_actor_get_debug_name (self)); - } - } - else - { - g_warning ("Mapped actor '%s' should have a parent", - _clutter_actor_get_debug_name (self)); - } - } - else - { - ClutterActor *iter = self; - - /* check for the enable_paint_unmapped flag on the actor - * and parents; if the flag is enabled at any point of this - * branch of the scene graph then all the later checks - * become pointless - */ - while (iter != NULL) - { - if (iter->priv->enable_paint_unmapped) - return; - - iter = iter->priv->parent; - } - - if (!clutter_actor_is_visible (priv->parent)) - { - g_warning ("Actor '%s' should not be mapped if parent '%s'" - "is not visible", - _clutter_actor_get_debug_name (self), - _clutter_actor_get_debug_name (priv->parent)); - } - - if (!clutter_actor_is_realized (priv->parent)) - { - g_warning ("Actor '%s' should not be mapped if parent '%s'" - "is not realized", - _clutter_actor_get_debug_name (self), - _clutter_actor_get_debug_name (priv->parent)); - } - - if (!CLUTTER_ACTOR_IS_TOPLEVEL (priv->parent)) - { - if (!clutter_actor_is_mapped (priv->parent)) - g_warning ("Actor '%s' is mapped but its non-toplevel " - "parent '%s' is not mapped", - _clutter_actor_get_debug_name (self), - _clutter_actor_get_debug_name (priv->parent)); - } - } - } -} - -#endif /* CLUTTER_ENABLE_DEBUG */ - -/** - * clutter_actor_pick_box: - * @self: The #ClutterActor being "pick" painted. - * @pick_context: The #ClutterPickContext - * @box: A rectangle in the actor's own local coordinates. - * - * Logs (does a virtual paint of) a rectangle for picking. Note that @box is - * in the actor's own local coordinates, so is usually {0,0,width,height} - * to include the whole actor. That is unless the actor has a shaped input - * region in which case you may wish to log the (multiple) smaller rectangles - * that make up the input region. - */ -void -clutter_actor_pick_box (ClutterActor *self, - ClutterPickContext *pick_context, - const ClutterActorBox *box) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (box != NULL); - - if (box->x1 >= box->x2 || box->y1 >= box->y2) - return; - - clutter_pick_context_log_pick (pick_context, box, self); -} - -static void -clutter_actor_set_mapped (ClutterActor *self, - gboolean mapped) -{ - if (clutter_actor_is_mapped (self) == mapped) - return; - - g_return_if_fail (!CLUTTER_ACTOR_IN_MAP_UNMAP (self)); - - CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_MAP_UNMAP); - - if (mapped) - { - CLUTTER_ACTOR_GET_CLASS (self)->map (self); - g_assert (clutter_actor_is_mapped (self)); - } - else - { - CLUTTER_ACTOR_GET_CLASS (self)->unmap (self); - g_assert (!clutter_actor_is_mapped (self)); - } - - CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_MAP_UNMAP); -} - -/* this function updates the mapped and realized states according to - * invariants, in the appropriate order. - */ -static void -clutter_actor_update_map_state (ClutterActor *self, - MapStateChange change) -{ - gboolean was_mapped; - - was_mapped = clutter_actor_is_mapped (self); - - if (CLUTTER_ACTOR_IS_TOPLEVEL (self)) - { - /* the mapped flag on top-level actors must be set by the - * per-backend implementation because it might be asynchronous. - * - * That is, the MAPPED flag on toplevels currently tracks the X - * server mapped-ness of the window, while the expected behavior - * (if used to GTK) may be to track WM_STATE!=WithdrawnState. - * This creates some weird complexity by breaking the invariant - * that if we're visible and all ancestors shown then we are - * also mapped - instead, we are mapped if all ancestors - * _possibly excepting_ the stage are mapped. The stage - * will map/unmap for example when it is minimized or - * moved to another workspace. - * - * So, the only invariant on the stage is that if visible it - * should be realized, and that it has to be visible to be - * mapped. - */ - if (clutter_actor_is_visible (self)) - clutter_actor_realize (self); - - switch (change) - { - case MAP_STATE_CHECK: - break; - - case MAP_STATE_MAKE_MAPPED: - g_assert (!was_mapped); - clutter_actor_set_mapped (self, TRUE); - break; - - case MAP_STATE_MAKE_UNMAPPED: - g_assert (was_mapped); - clutter_actor_set_mapped (self, FALSE); - break; - - case MAP_STATE_MAKE_UNREALIZED: - /* we only use MAKE_UNREALIZED in unparent, - * and unparenting a stage isn't possible. - * If someone wants to just unrealize a stage - * then clutter_actor_unrealize() doesn't - * go through this codepath. - */ - g_warning ("Trying to force unrealize stage is not allowed"); - break; - } - - if (clutter_actor_is_mapped (self) && - !clutter_actor_is_visible (self) && - !CLUTTER_ACTOR_IN_DESTRUCTION (self)) - { - g_warning ("Clutter toplevel of type '%s' is not visible, but " - "it is somehow still mapped", - _clutter_actor_get_debug_name (self)); - } - } - else - { - ClutterActorPrivate *priv = self->priv; - ClutterActor *parent = priv->parent; - gboolean should_be_mapped; - gboolean may_be_realized; - gboolean must_be_realized; - - should_be_mapped = FALSE; - may_be_realized = TRUE; - must_be_realized = FALSE; - - if (parent == NULL || change == MAP_STATE_MAKE_UNREALIZED) - { - may_be_realized = FALSE; - } - else - { - /* Maintain invariant that if parent is mapped, and we are - * visible, then we are mapped ... unless parent is a - * stage, in which case we map regardless of parent's map - * state but do require stage to be visible and realized. - * - * If parent is realized, that does not force us to be - * realized; but if parent is unrealized, that does force - * us to be unrealized. - * - * The reason we don't force children to realize with - * parents is _clutter_actor_rerealize(); if we require that - * a realized parent means children are realized, then to - * unrealize an actor we would have to unrealize its - * parents, which would end up meaning unrealizing and - * hiding the entire stage. So we allow unrealizing a - * child (as long as that child is not mapped) while that - * child still has a realized parent. - * - * Also, if we unrealize from leaf nodes to root, and - * realize from root to leaf, the invariants are never - * violated if we allow children to be unrealized - * while parents are realized. - * - * When unmapping, MAP_STATE_MAKE_UNMAPPED is specified - * to force us to unmap, even though parent is still - * mapped. This is because we're unmapping from leaf nodes - * up to root nodes. - */ - if (clutter_actor_is_visible (self) && - change != MAP_STATE_MAKE_UNMAPPED) - { - gboolean parent_is_visible_realized_toplevel; - - parent_is_visible_realized_toplevel = - (CLUTTER_ACTOR_IS_TOPLEVEL (parent) && - clutter_actor_is_visible (parent) && - clutter_actor_is_realized (parent)); - - if (clutter_actor_is_mapped (parent) || - parent_is_visible_realized_toplevel) - { - must_be_realized = TRUE; - should_be_mapped = TRUE; - } - } - - /* if the actor has been set to be painted even if unmapped - * then we should map it and check for realization as well; - * this is an override for the branch of the scene graph - * which begins with this node - */ - if (priv->enable_paint_unmapped) - { - should_be_mapped = TRUE; - must_be_realized = TRUE; - } - - if (!clutter_actor_is_realized (parent)) - may_be_realized = FALSE; - } - - if (change == MAP_STATE_MAKE_MAPPED && !should_be_mapped) - { - if (parent == NULL) - g_warning ("Attempting to map a child that does not " - "meet the necessary invariants: the actor '%s' " - "has no parent", - _clutter_actor_get_debug_name (self)); - else - g_warning ("Attempting to map a child that does not " - "meet the necessary invariants: the actor '%s' " - "is parented to an unmapped actor '%s'", - _clutter_actor_get_debug_name (self), - _clutter_actor_get_debug_name (priv->parent)); - } - - /* We want to go in the order "realize, map" and "unmap, unrealize" */ - - /* Unmap */ - if (!should_be_mapped) - clutter_actor_set_mapped (self, FALSE); - - /* Realize */ - if (must_be_realized) - clutter_actor_realize (self); - - /* if we must be realized then we may be, presumably */ - g_assert (!(must_be_realized && !may_be_realized)); - - /* Unrealize */ - if (!may_be_realized) - clutter_actor_unrealize_not_hiding (self); - - /* Map */ - if (should_be_mapped) - { - g_assert (should_be_mapped == must_be_realized); - - /* realization is allowed to fail (though I don't know what - * an app is supposed to do about that - shouldn't it just - * be a g_error? anyway, we have to avoid mapping if this - * happens) - */ - if (clutter_actor_is_realized (self)) - clutter_actor_set_mapped (self, TRUE); - } - } - -#ifdef CLUTTER_ENABLE_DEBUG - /* check all invariants were kept */ - clutter_actor_verify_map_state (self); -#endif -} - -static void queue_update_paint_volume (ClutterActor *actor); - -static void -queue_update_paint_volume_on_clones (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - GHashTableIter iter; - gpointer key; - - if (priv->clones == NULL) - return; - - g_hash_table_iter_init (&iter, priv->clones); - while (g_hash_table_iter_next (&iter, &key, NULL)) - queue_update_paint_volume (key); -} - -void -queue_update_paint_volume (ClutterActor *actor) -{ - queue_update_paint_volume_on_clones (actor); - - while (actor) - { - actor->priv->needs_paint_volume_update = TRUE; - actor->priv->needs_visible_paint_volume_update = TRUE; - actor->priv->needs_finish_layout = TRUE; - actor = actor->priv->parent; - } -} - -static void -clutter_actor_real_map (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActor *iter; - - g_assert (!clutter_actor_is_mapped (self)); - - CLUTTER_NOTE (ACTOR, "Mapping actor '%s'", - _clutter_actor_get_debug_name (self)); - - self->flags |= CLUTTER_ACTOR_MAPPED; - - if (priv->unmapped_paint_branch_counter == 0) - { - /* Invariant that needs_finish_layout is set all the way up to the stage - * needs to be met. - */ - if (priv->needs_finish_layout) - { - iter = priv->parent; - while (iter && !iter->priv->needs_finish_layout) - { - iter->priv->needs_finish_layout = TRUE; - iter = iter->priv->parent; - } - } - - /* Avoid the early return in clutter_actor_queue_relayout() */ - priv->needs_width_request = FALSE; - priv->needs_height_request = FALSE; - priv->needs_allocation = FALSE; - - clutter_actor_queue_relayout (self); - } - - /* notify on parent mapped before potentially mapping - * children, so apps see a top-down notification. - */ - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_MAPPED]); - - for (iter = priv->first_child; - iter != NULL; - iter = iter->priv->next_sibling) - { - clutter_actor_map (iter); - } -} - -/** - * clutter_actor_map: - * @self: A #ClutterActor - * - * Sets the %CLUTTER_ACTOR_MAPPED flag on the actor and possibly maps - * and realizes its children if they are visible. Does nothing if the - * actor is not visible. - * - * Calling this function is strongly discouraged: the default - * implementation of [vfunc@Clutter.Actor.map] will map all the children - * of an actor when mapping its parent. - * - * When overriding map, it is mandatory to chain up to the parent - * implementation. - */ -void -clutter_actor_map (ClutterActor *self) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (clutter_actor_is_mapped (self)) - return; - - if (!clutter_actor_is_visible (self)) - return; - - clutter_actor_update_map_state (self, MAP_STATE_MAKE_MAPPED); -} - -/** - * clutter_actor_is_mapped: - * @self: a #ClutterActor - * - * Checks whether a #ClutterActor has been set as mapped. - * - * See also [property@Clutter.Actor:mapped] - * - * Returns: %TRUE if the actor is mapped4 - */ -gboolean -clutter_actor_is_mapped (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - return (self->flags & CLUTTER_ACTOR_MAPPED) != FALSE; -} - -static void -maybe_unset_key_focus (ClutterActor *self) -{ - ClutterActor *stage; - - stage = _clutter_actor_get_stage_internal (self); - if (!stage) - return; - - if (self != clutter_stage_get_key_focus (CLUTTER_STAGE (stage))) - return; - - clutter_stage_set_key_focus (CLUTTER_STAGE (stage), NULL); -} - -static void -clutter_actor_clear_grabs (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActor *stage; - - if (!priv->grabs && !priv->implicitly_grabbed_count) - return; - - stage = _clutter_actor_get_stage_internal (self); - g_assert (stage != NULL); - - if (priv->implicitly_grabbed_count > 0) - clutter_stage_implicit_grab_actor_unmapped (CLUTTER_STAGE (stage), self); - - g_assert (priv->implicitly_grabbed_count == 0); - - /* Undo every grab that the actor may hold, priv->grabs - * will be updated internally in clutter_stage_unlink_grab(). - */ - while (priv->grabs) - clutter_stage_unlink_grab (CLUTTER_STAGE (stage), priv->grabs->data); -} - -static void -clutter_actor_real_unmap (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActor *iter; - - g_assert (clutter_actor_is_mapped (self)); - - CLUTTER_NOTE (ACTOR, "Unmapping actor '%s'", - _clutter_actor_get_debug_name (self)); - - for (iter = priv->first_child; - iter != NULL; - iter = iter->priv->next_sibling) - { - clutter_actor_unmap (iter); - } - - self->flags &= ~CLUTTER_ACTOR_MAPPED; - - if (priv->unmapped_paint_branch_counter == 0) - { - if (priv->parent && !CLUTTER_ACTOR_IN_DESTRUCTION (priv->parent)) - { - if (G_UNLIKELY (priv->parent->flags & CLUTTER_ACTOR_NO_LAYOUT)) - clutter_actor_queue_redraw (priv->parent); - else - clutter_actor_queue_relayout (priv->parent); - } - } - - /* notify on parent mapped after potentially unmapping - * children, so apps see a bottom-up notification. - */ - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_MAPPED]); - - if (priv->n_pointers > 0) - { - ClutterActor *stage = _clutter_actor_get_stage_internal (self); - - clutter_stage_invalidate_focus (CLUTTER_STAGE (stage), self); - } - - /* relinquish keyboard focus if we were unmapped while owning it */ - if (!CLUTTER_ACTOR_IS_TOPLEVEL (self)) - maybe_unset_key_focus (self); - - clutter_actor_clear_grabs (self); -} - -/** - * clutter_actor_unmap: - * @self: A #ClutterActor - * - * Unsets the %CLUTTER_ACTOR_MAPPED flag on the actor and possibly - * unmaps its children if they were mapped. - * - * Calling this function is not encouraged: the default #ClutterActor - * implementation of [vfunc@Clutter.Actor.unmap] will also unmap any - * eventual children by default when their parent is unmapped. - * - * When overriding [vfunc@Clutter.Actor.unmap], it is mandatory to - * chain up to the parent implementation. - * - * It is important to note that the implementation of the - * [vfunc@Clutter.Actor.unmap] virtual function may be called after - * the [vfunc@Clutter.Actor.destroy] or the [vfunc@GObject.Object.dispose] - * implementation, but it is guaranteed to be called before the - * [vfunc@GObject.Object.finalize] implementation. - */ -void -clutter_actor_unmap (ClutterActor *self) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (!clutter_actor_is_mapped (self)) - return; - - clutter_actor_update_map_state (self, MAP_STATE_MAKE_UNMAPPED); -} - -static void -clutter_actor_queue_shallow_relayout (ClutterActor *self) -{ - ClutterActor *stage = _clutter_actor_get_stage_internal (self); - - if (stage != NULL) - clutter_stage_queue_actor_relayout (CLUTTER_STAGE (stage), self); -} - -static void -clutter_actor_real_show (ClutterActor *self) -{ - if (clutter_actor_is_visible (self)) - return; - - self->flags |= CLUTTER_ACTOR_VISIBLE; - - /* we notify on the "visible" flag in the clutter_actor_show() - * wrapper so the entire show signal emission completes first, - * and the branch of the scene graph is in a stable state - */ - clutter_actor_update_map_state (self, MAP_STATE_CHECK); - - if (clutter_actor_has_mapped_clones (self)) - { - ClutterActorPrivate *priv = self->priv; - - /* Avoid the early return in clutter_actor_queue_relayout() */ - priv->needs_width_request = FALSE; - priv->needs_height_request = FALSE; - priv->needs_allocation = FALSE; - - clutter_actor_queue_relayout (self); - } -} - -static inline void -set_show_on_set_parent (ClutterActor *self, - gboolean set_show) -{ - ClutterActorPrivate *priv = self->priv; - - set_show = !!set_show; - - if (priv->show_on_set_parent == set_show) - return; - - if (priv->parent == NULL) - { - priv->show_on_set_parent = set_show; - g_object_notify_by_pspec (G_OBJECT (self), - obj_props[PROP_SHOW_ON_SET_PARENT]); - } -} - -static void -clutter_actor_queue_redraw_on_parent (ClutterActor *self) -{ - g_autoptr (ClutterPaintVolume) pv = NULL; - - if (!self->priv->parent) - return; - - /* A relayout/redraw is underway */ - if (self->priv->needs_allocation) - return; - - pv = clutter_actor_get_transformed_paint_volume (self, self->priv->parent); - _clutter_actor_queue_redraw_full (self->priv->parent, pv, NULL); -} - -/** - * clutter_actor_show: - * @self: A #ClutterActor - * - * Flags an actor to be displayed. An actor that isn't shown will not - * be rendered on the stage. - * - * Actors are visible by default. - * - * If this function is called on an actor without a parent, the - * [property@Clutter.Actor:show-on-set-parent] will be set to %TRUE as a side - * effect. - */ -void -clutter_actor_show (ClutterActor *self) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - /* simple optimization */ - if (clutter_actor_is_visible (self)) - { - /* we still need to set the :show-on-set-parent property, in - * case show() is called on an unparented actor - */ - set_show_on_set_parent (self, TRUE); - return; - } - -#ifdef CLUTTER_ENABLE_DEBUG - clutter_actor_verify_map_state (self); -#endif - - priv = self->priv; - - g_object_freeze_notify (G_OBJECT (self)); - - set_show_on_set_parent (self, TRUE); - - /* if we're showing a child that needs to expand, or may - * expand, then we need to recompute the expand flags for - * its parent as well - */ - if (priv->needs_compute_expand || - priv->needs_x_expand || - priv->needs_y_expand) - { - clutter_actor_queue_compute_expand (self); - } - - g_signal_emit (self, actor_signals[SHOW], 0); - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_VISIBLE]); - - if (priv->parent != NULL) - clutter_actor_queue_redraw (self); - - g_object_thaw_notify (G_OBJECT (self)); -} - -/** - * clutter_actor_is_visible: - * @self: a #ClutterActor - * - * Checks whether an actor is marked as visible. - * - * Returns: %TRUE if the actor visible4 - */ -gboolean -clutter_actor_is_visible (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - return (self->flags & CLUTTER_ACTOR_VISIBLE) != FALSE; -} - -static void -clutter_actor_real_hide (ClutterActor *self) -{ - if (!clutter_actor_is_visible (self)) - return; - - self->flags &= ~CLUTTER_ACTOR_VISIBLE; - - /* we notify on the "visible" flag in the clutter_actor_hide() - * wrapper so the entire hide signal emission completes first, - * and the branch of the scene graph is in a stable state - */ - clutter_actor_update_map_state (self, MAP_STATE_CHECK); -} - -/** - * clutter_actor_hide: - * @self: A #ClutterActor - * - * Flags an actor to be hidden. A hidden actor will not be - * rendered on the stage. - * - * Actors are visible by default. - * - * If this function is called on an actor without a parent, the - * [property@Clutter.Actor:show-on-set-parent] property will be set to %FALSE - * as a side-effect. - */ -void -clutter_actor_hide (ClutterActor *self) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - /* simple optimization */ - if (!clutter_actor_is_visible (self)) - { - /* we still need to set the :show-on-set-parent property, in - * case hide() is called on an unparented actor - */ - set_show_on_set_parent (self, FALSE); - return; - } - -#ifdef CLUTTER_ENABLE_DEBUG - clutter_actor_verify_map_state (self); -#endif - - priv = self->priv; - - g_object_freeze_notify (G_OBJECT (self)); - - set_show_on_set_parent (self, FALSE); - - /* if we're hiding a child that needs to expand, or may - * expand, then we need to recompute the expand flags for - * its parent as well - */ - if (priv->needs_compute_expand || - priv->needs_x_expand || - priv->needs_y_expand) - { - clutter_actor_queue_compute_expand (self); - } - - g_signal_emit (self, actor_signals[HIDE], 0); - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_VISIBLE]); - - if (priv->parent != NULL && priv->needs_allocation) - clutter_actor_queue_redraw (priv->parent); - else - clutter_actor_queue_redraw_on_parent (self); - - g_object_thaw_notify (G_OBJECT (self)); -} - -/** - * clutter_actor_realize: - * @self: A #ClutterActor - * - * Realization informs the actor that it is attached to a stage. It - * can use this to allocate resources if it wanted to delay allocation - * until it would be rendered. However it is perfectly acceptable for - * an actor to create resources before being realized because Clutter - * only ever has a single rendering context so that actor is free to - * be moved from one stage to another. - * - * This function does nothing if the actor is already realized. - * - * Because a realized actor must have realized parent actors, calling - * clutter_actor_realize() will also realize all parents of the actor. - * - * This function does not realize child actors, except in the special - * case that realizing the stage, when the stage is visible, will - * suddenly map (and thus realize) the children of the stage. - * - * Deprecated: 1.16: Actors are automatically realized, and nothing - * requires explicit realization. - */ -void -clutter_actor_realize (ClutterActor *self) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - clutter_actor_realize_internal (self); -} - -/** - * clutter_actor_is_realized: - * @self: a #ClutterActor - * - * Checks whether a #ClutterActor is realized. - * - * Returns: %TRUE if the actor is realized4 - */ -gboolean -clutter_actor_is_realized (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - return (self->flags & CLUTTER_ACTOR_REALIZED) != FALSE; -} - -static void -clutter_actor_realize_internal (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - -#ifdef CLUTTER_ENABLE_DEBUG - clutter_actor_verify_map_state (self); -#endif - - if (clutter_actor_is_realized (self)) - return; - - /* To be realized, our parent actors must be realized first. - * This will only succeed if we're inside a toplevel. - */ - if (priv->parent != NULL) - clutter_actor_realize (priv->parent); - - if (CLUTTER_ACTOR_IS_TOPLEVEL (self)) - { - /* toplevels can be realized at any time */ - } - else - { - /* "Fail" the realization if parent is missing or unrealized; - * this should really be a g_warning() not some kind of runtime - * failure; how can an app possibly recover? Instead it's a bug - * in the app and the app should get an explanatory warning so - * someone can fix it. But for now it's too hard to fix this - * because e.g. ClutterTexture needs reworking. - */ - if (priv->parent == NULL || - !clutter_actor_is_realized (priv->parent)) - return; - } - - CLUTTER_NOTE (ACTOR, "Realizing actor '%s'", _clutter_actor_get_debug_name (self)); - - self->flags |= CLUTTER_ACTOR_REALIZED; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_REALIZED]); - - g_signal_emit (self, actor_signals[REALIZE], 0); - - /* Stage actor is allowed to unset the realized flag again in its - * default signal handler, though that is a pathological situation. - */ - - /* If realization "failed" we'll have to update child state. */ - clutter_actor_update_map_state (self, MAP_STATE_CHECK); -} - -static void -clutter_actor_real_unrealize (ClutterActor *self) -{ - /* we must be unmapped (implying our children are also unmapped) */ - g_assert (!clutter_actor_is_mapped (self)); -} - -/** - * clutter_actor_unrealize: - * @self: A #ClutterActor - * - * Unrealization informs the actor that it may be being destroyed or - * moved to another stage. The actor may want to destroy any - * underlying graphics resources at this point. However it is - * perfectly acceptable for it to retain the resources until the actor - * is destroyed because Clutter only ever uses a single rendering - * context and all of the graphics resources are valid on any stage. - * - * Because mapped actors must be realized, actors may not be - * unrealized if they are mapped. This function hides the actor to be - * sure it isn't mapped, an application-visible side effect that you - * may not be expecting. - * - * This function should not be called by application code. - * - * This function should not really be in the public API, because - * there isn't a good reason to call it. ClutterActor will already - * unrealize things for you when it's important to do so. - * - * If you were using clutter_actor_unrealize() in a dispose - * implementation, then don't, just chain up to ClutterActor's - * dispose. - * - * If you were using clutter_actor_unrealize() to implement - * unrealizing children of your container, then don't, ClutterActor - * will already take care of that. - * - * Deprecated: 1.16: Actors are automatically unrealized, and nothing - * requires explicit realization. - */ -void -clutter_actor_unrealize (ClutterActor *self) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (!clutter_actor_is_mapped (self)); - - clutter_actor_unrealize_internal (self); -} - -/* If you were using clutter_actor_unrealize() to re-realize to - * create your resources in a different way, then use - * _clutter_actor_rerealize() (inside Clutter) or just call your - * code that recreates your resources directly (outside Clutter). - */ -static void -clutter_actor_unrealize_internal (ClutterActor *self) -{ -#ifdef CLUTTER_ENABLE_DEBUG - clutter_actor_verify_map_state (self); -#endif - - clutter_actor_hide (self); - - clutter_actor_unrealize_not_hiding (self); -} - -static ClutterActorTraverseVisitFlags -unrealize_actor_before_children_cb (ClutterActor *self, - int depth, - void *user_data) -{ - ClutterActor *stage; - - /* If an actor is already unrealized we know its children have also - * already been unrealized... */ - if (!clutter_actor_is_realized (self)) - return CLUTTER_ACTOR_TRAVERSE_VISIT_SKIP_CHILDREN; - - stage = _clutter_actor_get_stage_internal (self); - if (stage != NULL) - clutter_actor_clear_grabs (self); - - g_signal_emit (self, actor_signals[UNREALIZE], 0); - - return CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE; -} - -static ClutterActorTraverseVisitFlags -unrealize_actor_after_children_cb (ClutterActor *self, - int depth, - void *user_data) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActor *stage = user_data; - - /* We want to unset the realized flag only _after_ - * child actors are unrealized, to maintain invariants. - */ - self->flags &= ~CLUTTER_ACTOR_REALIZED; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_REALIZED]); - - if (stage != NULL && - priv->parent != NULL && - priv->parent->flags & CLUTTER_ACTOR_NO_LAYOUT) - clutter_stage_dequeue_actor_relayout (CLUTTER_STAGE (stage), self); - - if (priv->unmapped_paint_branch_counter == 0) - priv->allocation = (ClutterActorBox) CLUTTER_ACTOR_BOX_UNINITIALIZED; - - return CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE; -} - -/* - * clutter_actor_unrealize_not_hiding: - * @self: A #ClutterActor - * - * Unrealization informs the actor that it may be being destroyed or - * moved to another stage. The actor may want to destroy any - * underlying graphics resources at this point. However it is - * perfectly acceptable for it to retain the resources until the actor - * is destroyed because Clutter only ever uses a single rendering - * context and all of the graphics resources are valid on any stage. - * - * Because mapped actors must be realized, actors may not be - * unrealized if they are mapped. You must hide the actor or one of - * its parents before attempting to unrealize. - * - * This function is separate from clutter_actor_unrealize() because it - * does not automatically hide the actor. - * Actors need not be hidden to be unrealized, they just need to - * be unmapped. In fact we don't want to mess up the application's - * setting of the "visible" flag, so hiding is very undesirable. - * - * clutter_actor_unrealize() does a clutter_actor_hide() just for - * backward compatibility. - */ -static void -clutter_actor_unrealize_not_hiding (ClutterActor *self) -{ - ClutterActor *stage = _clutter_actor_get_stage_internal (self); - - _clutter_actor_traverse (self, - CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST, - unrealize_actor_before_children_cb, - unrealize_actor_after_children_cb, - stage); -} - -static void -clutter_actor_real_pick (ClutterActor *self, - ClutterPickContext *pick_context) -{ - ClutterActorPrivate *priv = self->priv; - - if (clutter_actor_should_pick (self, pick_context)) - { - ClutterActorBox box = { - .x1 = 0, - .y1 = 0, - .x2 = priv->allocation.x2 - priv->allocation.x1, - .y2 = priv->allocation.y2 - priv->allocation.y1, - }; - - clutter_actor_pick_box (self, pick_context, &box); - } - - /* XXX - this thoroughly sucks, but we need to maintain compatibility - * with existing container classes that override the pick() virtual - * and chain up to the default implementation - otherwise we'll end up - * painting our children twice. - * - * this has to go away for 2.0; hopefully along the pick() itself. - */ - if (CLUTTER_ACTOR_GET_CLASS (self)->pick == clutter_actor_real_pick) - { - ClutterActor *iter; - - for (iter = self->priv->first_child; - iter != NULL; - iter = iter->priv->next_sibling) - clutter_actor_pick (iter, pick_context); - } -} - -/** - * clutter_actor_should_pick: - * @self: A #ClutterActor - * @pick_context: a #ClutterPickContext - * - * Should be called inside the implementation of the - * [vfunc@Clutter.Actor.pick] virtual function in order to check whether - * the actor should be picked or not. - * - * This function should never be called directly by applications. - * - * Return value: %TRUE if the actor should be picked, %FALSE otherwise - */ -gboolean -clutter_actor_should_pick (ClutterActor *self, - ClutterPickContext *pick_context) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - if (clutter_actor_is_mapped (self) && - clutter_actor_box_is_initialized (&self->priv->allocation) && - (clutter_pick_context_get_mode (pick_context) == CLUTTER_PICK_ALL || - clutter_actor_get_reactive (self))) - return TRUE; - - return FALSE; -} - -static void -clutter_actor_real_get_preferred_width (ClutterActor *self, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p) -{ - ClutterActorPrivate *priv = self->priv; - - if (priv->layout_manager != NULL) - { - CLUTTER_NOTE (LAYOUT, "Querying the layout manager '%s'[%p] " - "for the preferred width", - G_OBJECT_TYPE_NAME (priv->layout_manager), - priv->layout_manager); - - clutter_layout_manager_get_preferred_width (priv->layout_manager, - self, - for_height, - min_width_p, - natural_width_p); - - return; - } - - /* Default implementation is always 0x0, usually an actor - * using this default is relying on someone to set the - * request manually - */ - CLUTTER_NOTE (LAYOUT, "Default preferred width: 0, 0"); - - if (min_width_p) - *min_width_p = 0; - - if (natural_width_p) - *natural_width_p = 0; -} - -static void -clutter_actor_real_get_preferred_height (ClutterActor *self, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p) -{ - ClutterActorPrivate *priv = self->priv; - - if (priv->layout_manager != NULL) - { - CLUTTER_NOTE (LAYOUT, "Querying the layout manager '%s'[%p] " - "for the preferred height", - G_OBJECT_TYPE_NAME (priv->layout_manager), - priv->layout_manager); - - clutter_layout_manager_get_preferred_height (priv->layout_manager, - self, - for_width, - min_height_p, - natural_height_p); - - return; - } - /* Default implementation is always 0x0, usually an actor - * using this default is relying on someone to set the - * request manually - */ - CLUTTER_NOTE (LAYOUT, "Default preferred height: 0, 0"); - - if (min_height_p) - *min_height_p = 0; - - if (natural_height_p) - *natural_height_p = 0; -} - -static void -clutter_actor_store_old_geometry (ClutterActor *self, - ClutterActorBox *box) -{ - *box = self->priv->allocation; -} - -static inline void -clutter_actor_notify_if_geometry_changed (ClutterActor *self, - const ClutterActorBox *old) -{ - ClutterActorPrivate *priv = self->priv; - GObject *obj = G_OBJECT (self); - - g_object_freeze_notify (obj); - - /* to avoid excessive requisition or allocation cycles we - * use the cached values. - * - * - if we don't have an allocation we assume that we need - * to notify anyway - * - if we don't have a width or a height request we notify - * width and height - * - if we have a valid allocation then we check the old - * bounding box with the current allocation and we notify - * the changes - */ - if (priv->needs_allocation) - { - g_object_notify_by_pspec (obj, obj_props[PROP_X]); - g_object_notify_by_pspec (obj, obj_props[PROP_Y]); - g_object_notify_by_pspec (obj, obj_props[PROP_POSITION]); - g_object_notify_by_pspec (obj, obj_props[PROP_WIDTH]); - g_object_notify_by_pspec (obj, obj_props[PROP_HEIGHT]); - g_object_notify_by_pspec (obj, obj_props[PROP_SIZE]); - } - else if (priv->needs_width_request || priv->needs_height_request) - { - g_object_notify_by_pspec (obj, obj_props[PROP_WIDTH]); - g_object_notify_by_pspec (obj, obj_props[PROP_HEIGHT]); - g_object_notify_by_pspec (obj, obj_props[PROP_SIZE]); - } - else - { - gfloat x, y; - gfloat width, height; - - x = priv->allocation.x1; - y = priv->allocation.y1; - width = priv->allocation.x2 - priv->allocation.x1; - height = priv->allocation.y2 - priv->allocation.y1; - - if (x != old->x1) - { - g_object_notify_by_pspec (obj, obj_props[PROP_X]); - g_object_notify_by_pspec (obj, obj_props[PROP_POSITION]); - } - - if (y != old->y1) - { - g_object_notify_by_pspec (obj, obj_props[PROP_Y]); - g_object_notify_by_pspec (obj, obj_props[PROP_POSITION]); - } - - if (width != (old->x2 - old->x1)) - { - g_object_notify_by_pspec (obj, obj_props[PROP_WIDTH]); - g_object_notify_by_pspec (obj, obj_props[PROP_SIZE]); - } - - if (height != (old->y2 - old->y1)) - { - g_object_notify_by_pspec (obj, obj_props[PROP_HEIGHT]); - g_object_notify_by_pspec (obj, obj_props[PROP_SIZE]); - } - } - - g_object_thaw_notify (obj); -} - -static void -absolute_geometry_changed (ClutterActor *actor) -{ - actor->priv->needs_update_stage_views = TRUE; - actor->priv->needs_visible_paint_volume_update = TRUE; - actor->priv->stage_relative_modelview_valid = FALSE; - - actor->priv->needs_finish_layout = TRUE; - /* needs_finish_layout is already TRUE on the whole parent tree thanks - * to queue_update_paint_volume() that was called by transform_changed(). - */ -} - -static ClutterActorTraverseVisitFlags -absolute_geometry_changed_cb (ClutterActor *actor, - int depth, - gpointer user_data) -{ - absolute_geometry_changed (actor); - - return CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE; -} - -static void -transform_changed (ClutterActor *actor) -{ - actor->priv->transform_valid = FALSE; - - if (actor->priv->parent) - queue_update_paint_volume (actor->priv->parent); - - _clutter_actor_traverse (actor, - CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST, - absolute_geometry_changed_cb, - NULL, - NULL); - - if (!clutter_actor_has_transitions (actor) && - !CLUTTER_ACTOR_IN_RELAYOUT (actor)) - clutter_actor_update_devices (actor); -} - -/*< private > - * clutter_actor_set_allocation_internal: - * @self: a #ClutterActor - * @box: a #ClutterActorBox - * @flags: allocation flags - * - * Stores the allocation of @self. - * - * This function only performs basic storage and property notification. - * - * This function should be called by clutter_actor_set_allocation() - * and by the default implementation of [vfunc@Clutter.Actor.destroyallocate - * - * Return value: %TRUE if the allocation of the #ClutterActor has been - * changed, and %FALSE otherwise - */ -static inline void -clutter_actor_set_allocation_internal (ClutterActor *self, - const ClutterActorBox *box) -{ - ClutterActorPrivate *priv = self->priv; - GObject *obj; - gboolean origin_changed, size_changed; - ClutterActorBox old_alloc = { 0, }; - - g_return_if_fail (!isnan (box->x1) && !isnan (box->x2) && - !isnan (box->y1) && !isnan (box->y2)); - - obj = G_OBJECT (self); - - g_object_freeze_notify (obj); - - clutter_actor_store_old_geometry (self, &old_alloc); - - origin_changed = - priv->allocation.x1 != box->x1 || priv->allocation.y1 != box->y1; - size_changed = - priv->allocation.x2 - priv->allocation.x1 != box->x2 - box->x1 || - priv->allocation.y2 - priv->allocation.y1 != box->y2 - box->y1; - - priv->allocation = *box; - - /* allocation is authoritative */ - priv->needs_width_request = FALSE; - priv->needs_height_request = FALSE; - priv->needs_allocation = FALSE; - - if (origin_changed || size_changed) - { - CLUTTER_NOTE (LAYOUT, "Allocation for '%s' changed", - _clutter_actor_get_debug_name (self)); - - /* This will also call absolute_geometry_changed() on the subtree */ - transform_changed (self); - - if (size_changed) - queue_update_paint_volume (self); - - g_object_notify_by_pspec (obj, obj_props[PROP_ALLOCATION]); - - /* if the allocation changes, so does the content box */ - if (priv->content != NULL) - { - priv->content_box_valid = FALSE; - g_object_notify_by_pspec (obj, obj_props[PROP_CONTENT_BOX]); - } - } - - clutter_actor_notify_if_geometry_changed (self, &old_alloc); - - g_object_thaw_notify (obj); -} - -static void -clutter_actor_real_allocate (ClutterActor *self, - const ClutterActorBox *box) -{ - ClutterActorPrivate *priv = self->priv; - - g_object_freeze_notify (G_OBJECT (self)); - - clutter_actor_set_allocation_internal (self, box); - - /* we allocate our children before we notify changes in our geometry, - * so that people connecting to properties will be able to get valid - * data out of the sub-tree of the scene graph that has this actor at - * the root. - */ - if (priv->n_children != 0 && - priv->layout_manager != NULL) - { - ClutterActorBox children_box; - - /* normalize the box passed to the layout manager */ - children_box.x1 = children_box.y1 = 0.f; - children_box.x2 = box->x2 - box->x1; - children_box.y2 = box->y2 - box->y1; - - CLUTTER_NOTE (LAYOUT, - "Allocating %d children of %s " - "at { %.2f, %.2f - %.2f x %.2f } " - "using %s", - priv->n_children, - _clutter_actor_get_debug_name (self), - box->x1, - box->y1, - (box->x2 - box->x1), - (box->y2 - box->y1), - G_OBJECT_TYPE_NAME (priv->layout_manager)); - - clutter_layout_manager_allocate (priv->layout_manager, - self, - &children_box); - } - - g_object_thaw_notify (G_OBJECT (self)); -} - -static void -_clutter_actor_queue_redraw_on_clones (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - GHashTableIter iter; - gpointer key; - - if (priv->clones == NULL) - return; - - g_hash_table_iter_init (&iter, priv->clones); - while (g_hash_table_iter_next (&iter, &key, NULL)) - clutter_actor_queue_redraw (key); -} - -static void -_clutter_actor_propagate_queue_redraw (ClutterActor *self) -{ - ClutterActor *origin = self; - - while (self) - { - /* no point in queuing a redraw on a destroyed actor */ - if (CLUTTER_ACTOR_IN_DESTRUCTION (self)) - break; - - _clutter_actor_queue_redraw_on_clones (self); - - self->priv->is_dirty = TRUE; - - /* If the queue redraw is coming from a child then the actor has - become dirty and any queued effect is no longer valid */ - if (self != origin) - self->priv->effect_to_redraw = NULL; - - /* If the actor isn't visible, we still had to emit the signal - * to allow for a ClutterClone, but the appearance of the parent - * won't change so we don't have to propagate up the hierarchy. - */ - if (!clutter_actor_is_visible (self)) - break; - - /* We guarantee that we will propagate a queue-redraw up the tree - * at least once so that all clones can get notified. - */ - if (self->priv->propagated_one_redraw) - break; - - self->priv->propagated_one_redraw = TRUE; - - self = self->priv->parent; - } -} - -static inline gboolean -clutter_actor_needs_relayout (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - - return (priv->needs_width_request || - priv->needs_height_request || - priv->needs_allocation); -} - -static void -clutter_actor_real_queue_relayout (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - - /* no point in queueing a redraw on a destroyed actor */ - if (CLUTTER_ACTOR_IN_DESTRUCTION (self)) - return; - - priv->needs_width_request = TRUE; - priv->needs_height_request = TRUE; - priv->needs_allocation = TRUE; - - /* reset the cached size requests */ - memset (priv->width_requests, 0, - N_CACHED_SIZE_REQUESTS * sizeof (SizeRequest)); - memset (priv->height_requests, 0, - N_CACHED_SIZE_REQUESTS * sizeof (SizeRequest)); - - /* We may need to go all the way up the hierarchy */ - if (priv->parent != NULL) - { - if (priv->parent->flags & CLUTTER_ACTOR_NO_LAYOUT) - clutter_actor_queue_shallow_relayout (self); - else - _clutter_actor_queue_only_relayout (priv->parent); - } -} - -/** - * clutter_actor_apply_relative_transform_to_point: - * @self: A #ClutterActor - * @ancestor: (nullable): A #ClutterActor ancestor, or %NULL to use the - * default #ClutterStage - * @point: A point as #graphene_point3d_t - * @vertex: (out caller-allocates): The translated #graphene_point3d_t - * - * Transforms @point in coordinates relative to the actor into - * ancestor-relative coordinates using the relevant transform - * stack (i.e. scale, rotation, etc). - * - * If @ancestor is %NULL the ancestor will be the #ClutterStage. In - * this case, the coordinates returned will be the coordinates on - * the stage before the projection is applied. This is different from - * the behaviour of clutter_actor_apply_transform_to_point(). - */ -void -clutter_actor_apply_relative_transform_to_point (ClutterActor *self, - ClutterActor *ancestor, - const graphene_point3d_t *point, - graphene_point3d_t *vertex) -{ - gfloat w; - graphene_matrix_t matrix; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (ancestor == NULL || CLUTTER_IS_ACTOR (ancestor)); - g_return_if_fail (point != NULL); - g_return_if_fail (vertex != NULL); - - *vertex = *point; - w = 1.0; - - if (ancestor == NULL) - ancestor = _clutter_actor_get_stage_internal (self); - - if (ancestor == NULL) - { - *vertex = *point; - return; - } - - clutter_actor_get_relative_transformation_matrix (self, ancestor, &matrix); - cogl_graphene_matrix_project_point (&matrix, - &vertex->x, - &vertex->y, - &vertex->z, - &w); -} - -static gboolean -_clutter_actor_fully_transform_vertices (ClutterActor *self, - const graphene_point3d_t *vertices_in, - graphene_point3d_t *vertices_out, - int n_vertices) -{ - ClutterActor *stage; - graphene_matrix_t modelview; - graphene_matrix_t projection; - float viewport[4]; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - stage = _clutter_actor_get_stage_internal (self); - - /* We really can't do anything meaningful in this case so don't try - * to do any transform */ - if (stage == NULL) - return FALSE; - - /* Note: we pass NULL as the ancestor because we don't just want the modelview - * that gets us to stage coordinates, we want to go all the way to eye - * coordinates */ - clutter_actor_get_relative_transformation_matrix (self, NULL, &modelview); - - /* Fetch the projection and viewport */ - _clutter_stage_get_projection_matrix (CLUTTER_STAGE (stage), &projection); - _clutter_stage_get_viewport (CLUTTER_STAGE (stage), - &viewport[0], - &viewport[1], - &viewport[2], - &viewport[3]); - - _clutter_util_fully_transform_vertices (&modelview, - &projection, - viewport, - vertices_in, - vertices_out, - n_vertices); - - return TRUE; -} - -/** - * clutter_actor_apply_transform_to_point: - * @self: A #ClutterActor - * @point: A point as #graphene_point3d_t - * @vertex: (out caller-allocates): The translated #graphene_point3d_t - * - * Transforms @point in coordinates relative to the actor - * into screen-relative coordinates with the current actor - * transformation (i.e. scale, rotation, etc) - **/ -void -clutter_actor_apply_transform_to_point (ClutterActor *self, - const graphene_point3d_t *point, - graphene_point3d_t *vertex) -{ - g_return_if_fail (point != NULL); - g_return_if_fail (vertex != NULL); - _clutter_actor_fully_transform_vertices (self, point, vertex, 1); -} - -/** - * clutter_actor_get_relative_transformation_matrix: - * @self: The actor whose coordinate space you want to transform from. - * @ancestor: (nullable): The ancestor actor whose coordinate space you want to transform to - * or %NULL if you want to transform all the way to eye coordinates. - * @matrix: (out caller-allocates): A #graphene_matrix_t to store the transformation - * - * This gets a transformation @matrix that will transform coordinates from the - * coordinate space of @self into the coordinate space of @ancestor. - * - * For example if you need a matrix that can transform the local actor - * coordinates of @self into stage coordinates you would pass the actor's stage - * pointer as the @ancestor. - * - * If you pass %NULL then the transformation will take you all the way through - * to eye coordinates. This can be useful if you want to extract the entire - * modelview transform that Clutter applies before applying the projection - * transformation. If you want to explicitly set a modelview on a CoglFramebuffer - * using cogl_set_modelview_matrix() for example then you would want a matrix - * that transforms into eye coordinates. - * - * Note: This function explicitly initializes the given @matrix. If you just - * want clutter to multiply a relative transformation with an existing matrix - * you can use clutter_actor_apply_relative_transformation_matrix() - * instead. - * - */ -void -clutter_actor_get_relative_transformation_matrix (ClutterActor *self, - ClutterActor *ancestor, - graphene_matrix_t *matrix) -{ - graphene_matrix_init_identity (matrix); - - _clutter_actor_apply_relative_transformation_matrix (self, ancestor, matrix); -} - -/* Project the given @box into stage window coordinates, writing the - * transformed vertices to @verts[]. */ -static gboolean -_clutter_actor_transform_and_project_box (ClutterActor *self, - const ClutterActorBox *box, - graphene_point3d_t *verts) -{ - graphene_point3d_t box_vertices[4]; - - box_vertices[0].x = box->x1; - box_vertices[0].y = box->y1; - box_vertices[0].z = 0; - box_vertices[1].x = box->x2; - box_vertices[1].y = box->y1; - box_vertices[1].z = 0; - box_vertices[2].x = box->x1; - box_vertices[2].y = box->y2; - box_vertices[2].z = 0; - box_vertices[3].x = box->x2; - box_vertices[3].y = box->y2; - box_vertices[3].z = 0; - - return - _clutter_actor_fully_transform_vertices (self, box_vertices, verts, 4); -} - -/** - * clutter_actor_get_abs_allocation_vertices: - * @self: A #ClutterActor - * @verts: (out) (array fixed-size=4): Pointer to a location of an array - * of 4 #graphene_point3d_t where to store the result. - * - * Calculates the transformed screen coordinates of the four corners of - * the actor; the returned vertices relate to the #ClutterActorBox - * coordinates as follows: - * - * - v[0] contains (x1, y1) - * - v[1] contains (x2, y1) - * - v[2] contains (x1, y2) - * - v[3] contains (x2, y2) - */ -void -clutter_actor_get_abs_allocation_vertices (ClutterActor *self, - graphene_point3d_t *verts) -{ - ClutterActorPrivate *priv; - ClutterActorBox actor_space_allocation; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - priv = self->priv; - - /* if the actor needs to be allocated we force a relayout, so that - * the actor allocation box will be valid for - * _clutter_actor_transform_and_project_box() - */ - if (priv->needs_allocation) - { - ClutterActor *stage = _clutter_actor_get_stage_internal (self); - /* There's nothing meaningful we can do now */ - if (!stage) - return; - - clutter_stage_maybe_relayout (stage); - } - - /* NB: _clutter_actor_transform_and_project_box expects a box in the actor's - * own coordinate space... */ - actor_space_allocation.x1 = 0; - actor_space_allocation.y1 = 0; - actor_space_allocation.x2 = priv->allocation.x2 - priv->allocation.x1; - actor_space_allocation.y2 = priv->allocation.y2 - priv->allocation.y1; - _clutter_actor_transform_and_project_box (self, - &actor_space_allocation, - verts); -} - -static void -clutter_actor_real_apply_transform (ClutterActor *self, - graphene_matrix_t *matrix) -{ - ClutterActorPrivate *priv = self->priv; - const ClutterTransformInfo *info; - graphene_point3d_t p; - float pivot_x = 0.f, pivot_y = 0.f; - - info = _clutter_actor_get_transform_info_or_defaults (self); - - /* compute the pivot point given the allocated size */ - pivot_x = (priv->allocation.x2 - priv->allocation.x1) - * info->pivot.x; - pivot_y = (priv->allocation.y2 - priv->allocation.y1) - * info->pivot.y; - - CLUTTER_NOTE (PAINT, - "Allocation: (%.2f, %2.f), " - "pivot: (%.2f, %.2f), " - "translation: (%.2f, %.2f) -> " - "new origin: (%.2f, %.2f)", - priv->allocation.x1, priv->allocation.y1, - info->pivot.x, info->pivot.y, - info->translation.x, info->translation.y, - priv->allocation.x1 + pivot_x + info->translation.x, - priv->allocation.y1 + pivot_y + info->translation.y); - - /* roll back the pivot translation */ - if (pivot_x != 0.f || pivot_y != 0.f || info->pivot_z != 0.f) - { - graphene_point3d_init (&p, -pivot_x, -pivot_y, -info->pivot_z); - graphene_matrix_translate (matrix, &p); - } - - /* if we have an overriding transformation, we use that, and get out */ - if (info->transform_set) - { - graphene_matrix_multiply (matrix, &info->transform, matrix); - - /* we still need to apply the :allocation's origin and :pivot-point - * translations, since :transform is relative to the actor's coordinate - * space, and to the pivot point - */ - graphene_point3d_init (&p, - priv->allocation.x1 + pivot_x, - priv->allocation.y1 + pivot_y, - info->pivot_z); - graphene_matrix_translate (matrix, &p); - goto roll_back; - } - - if (info->rx_angle) - graphene_matrix_rotate (matrix, info->rx_angle, graphene_vec3_x_axis ()); - - if (info->ry_angle) - graphene_matrix_rotate (matrix, info->ry_angle, graphene_vec3_y_axis ()); - - if (info->rz_angle) - graphene_matrix_rotate (matrix, info->rz_angle, graphene_vec3_z_axis ()); - - if (info->scale_x != 1.0 || info->scale_y != 1.0 || info->scale_z != 1.0) - graphene_matrix_scale (matrix, info->scale_x, info->scale_y, info->scale_z); - - /* basic translation: :allocation's origin and :z-position; instead - * of decomposing the pivot and translation info separate operations, - * we just compose everything into a single translation - */ - graphene_point3d_init (&p, - priv->allocation.x1 + pivot_x + info->translation.x, - priv->allocation.y1 + pivot_y + info->translation.y, - info->z_position + info->pivot_z + info->translation.z); - graphene_matrix_translate (matrix, &p); - -roll_back: - /* we apply the :child-transform from the parent actor, if we have one */ - if (priv->parent != NULL) - { - const ClutterTransformInfo *parent_info; - - parent_info = _clutter_actor_get_transform_info_or_defaults (priv->parent); - graphene_matrix_multiply (matrix, &parent_info->child_transform, matrix); - } -} - -/* Applies the transforms associated with this actor to the given - * matrix. */ - -static void -ensure_valid_actor_transform (ClutterActor *actor) -{ - ClutterActorPrivate *priv = actor->priv; - - if (priv->transform_valid) - return; - - graphene_matrix_init_identity (&priv->transform); - - CLUTTER_ACTOR_GET_CLASS (actor)->apply_transform (actor, &priv->transform); - - priv->transform_valid = TRUE; -} - -void -_clutter_actor_apply_modelview_transform (ClutterActor *self, - graphene_matrix_t *matrix) -{ - ClutterActorPrivate *priv = self->priv; - - ensure_valid_actor_transform (self); - graphene_matrix_multiply (&priv->transform, matrix, matrix); -} - -/* - * clutter_actor_apply_relative_transformation_matrix: - * @self: The actor whose coordinate space you want to transform from. - * @ancestor: The ancestor actor whose coordinate space you want to transform too - * or %NULL if you want to transform all the way to eye coordinates. - * @matrix: A #graphene_matrix_t to apply the transformation too. - * - * This multiplies a transform with @matrix that will transform coordinates - * from the coordinate space of @self into the coordinate space of @ancestor. - * - * For example if you need a matrix that can transform the local actor - * coordinates of @self into stage coordinates you would pass the actor's stage - * pointer as the @ancestor. - * - * If you pass %NULL then the transformation will take you all the way through - * to eye coordinates. This can be useful if you want to extract the entire - * modelview transform that Clutter applies before applying the projection - * transformation. If you want to explicitly set a modelview on a CoglFramebuffer - * using cogl_set_modelview_matrix() for example then you would want a matrix - * that transforms into eye coordinates. - * - * This function doesn't initialize the given @matrix, it simply - * multiplies the requested transformation matrix with the existing contents of - * @matrix. You can use graphene_matrix_init_identity() to initialize the @matrix - * before calling this function, or you can use - * clutter_actor_get_relative_transformation_matrix() instead. - */ -void -_clutter_actor_apply_relative_transformation_matrix (ClutterActor *self, - ClutterActor *ancestor, - graphene_matrix_t *matrix) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActor *stage = _clutter_actor_get_stage_internal (self); - graphene_matrix_t ancestor_modelview; - graphene_matrix_t inverse_ancestor_modelview; - - /* Note we terminate before ever calling stage->apply_transform() - * since that would conceptually be relative to the underlying - * window OpenGL coordinates so we'd need a special @ancestor - * value to represent the fake parent of the stage. */ - if (self == ancestor) - return; - - if (!priv->stage_relative_modelview_valid) - { - graphene_matrix_init_identity (&priv->stage_relative_modelview); - - if (priv->parent != NULL) - { - _clutter_actor_apply_relative_transformation_matrix (priv->parent, - stage, - &priv->stage_relative_modelview); - } - - _clutter_actor_apply_modelview_transform (self, - &priv->stage_relative_modelview); - - priv->stage_relative_modelview_valid = TRUE; - } - - if (ancestor == NULL) - { - _clutter_actor_apply_modelview_transform (stage, matrix); - graphene_matrix_multiply (&priv->stage_relative_modelview, matrix, matrix); - return; - } - - if (ancestor == stage) - { - graphene_matrix_multiply (&priv->stage_relative_modelview, matrix, matrix); - return; - } - - if (ancestor == priv->parent) - { - _clutter_actor_apply_modelview_transform (self, matrix); - return; - } - - graphene_matrix_init_identity (&ancestor_modelview); - _clutter_actor_apply_relative_transformation_matrix (ancestor, - stage, - &ancestor_modelview); - - if (graphene_matrix_near (&priv->stage_relative_modelview, - &ancestor_modelview, - FLT_EPSILON)) - return; - - if (graphene_matrix_is_identity (&ancestor_modelview)) - { - graphene_matrix_multiply (&priv->stage_relative_modelview, matrix, matrix); - return; - } - - if (graphene_matrix_inverse (&ancestor_modelview, - &inverse_ancestor_modelview)) - { - graphene_matrix_multiply (&inverse_ancestor_modelview, matrix, matrix); - graphene_matrix_multiply (&priv->stage_relative_modelview, matrix, matrix); - return; - } - - if (priv->parent != NULL) - _clutter_actor_apply_relative_transformation_matrix (priv->parent, - ancestor, - matrix); - - _clutter_actor_apply_modelview_transform (self, matrix); -} - -static void -_clutter_actor_draw_paint_volume_full (ClutterActor *self, - ClutterPaintVolume *pv, - const ClutterColor *color, - ClutterPaintNode *node) -{ - g_autoptr (ClutterPaintNode) pipeline_node = NULL; - static CoglPipeline *outline = NULL; - CoglPrimitive *prim; - graphene_point3d_t line_ends[12 * 2]; - int n_vertices; - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - CoglColor cogl_color; - - if (outline == NULL) - outline = cogl_pipeline_new (ctx); - - _clutter_paint_volume_complete (pv); - - n_vertices = pv->is_2d ? 4 * 2 : 12 * 2; - - /* Front face */ - line_ends[0] = pv->vertices[0]; line_ends[1] = pv->vertices[1]; - line_ends[2] = pv->vertices[1]; line_ends[3] = pv->vertices[2]; - line_ends[4] = pv->vertices[2]; line_ends[5] = pv->vertices[3]; - line_ends[6] = pv->vertices[3]; line_ends[7] = pv->vertices[0]; - - if (!pv->is_2d) - { - /* Back face */ - line_ends[8] = pv->vertices[4]; line_ends[9] = pv->vertices[5]; - line_ends[10] = pv->vertices[5]; line_ends[11] = pv->vertices[6]; - line_ends[12] = pv->vertices[6]; line_ends[13] = pv->vertices[7]; - line_ends[14] = pv->vertices[7]; line_ends[15] = pv->vertices[4]; - - /* Lines connecting front face to back face */ - line_ends[16] = pv->vertices[0]; line_ends[17] = pv->vertices[4]; - line_ends[18] = pv->vertices[1]; line_ends[19] = pv->vertices[5]; - line_ends[20] = pv->vertices[2]; line_ends[21] = pv->vertices[6]; - line_ends[22] = pv->vertices[3]; line_ends[23] = pv->vertices[7]; - } - - prim = cogl_primitive_new_p3 (ctx, COGL_VERTICES_MODE_LINES, - n_vertices, - (CoglVertexP3 *)line_ends); - - cogl_color_init_from_4f (&cogl_color, - color->red / 255.0, - color->green / 255.0, - color->blue / 255.0, - color->alpha / 255.0); - cogl_pipeline_set_color (outline, &cogl_color); - - pipeline_node = clutter_pipeline_node_new (outline); - clutter_paint_node_set_static_name (pipeline_node, - "ClutterActor (paint volume outline)"); - clutter_paint_node_add_primitive (pipeline_node, prim); - clutter_paint_node_add_child (node, pipeline_node); - g_object_unref (prim); -} - -static void -_clutter_actor_draw_paint_volume (ClutterActor *self, - ClutterPaintNode *node) -{ - ClutterPaintVolume *pv; - ClutterColor color; - - pv = _clutter_actor_get_paint_volume_mutable (self); - if (!pv) - { - gfloat width, height; - ClutterPaintVolume fake_pv; - - ClutterActor *stage = _clutter_actor_get_stage_internal (self); - _clutter_paint_volume_init_static (&fake_pv, stage); - - clutter_actor_get_size (self, &width, &height); - clutter_paint_volume_set_width (&fake_pv, width); - clutter_paint_volume_set_height (&fake_pv, height); - - clutter_color_init (&color, 0, 0, 255, 255); - _clutter_actor_draw_paint_volume_full (self, &fake_pv, - &color, - node); - - clutter_paint_volume_free (&fake_pv); - } - else - { - clutter_color_init (&color, 0, 255, 0, 255); - _clutter_actor_draw_paint_volume_full (self, pv, - &color, - node); - } -} - -static void -_clutter_actor_paint_cull_result (ClutterActor *self, - gboolean success, - ClutterCullResult result, - ClutterPaintNode *node) -{ - ClutterPaintVolume *pv; - ClutterColor color; - - if (success) - { - switch (result) - { - case CLUTTER_CULL_RESULT_IN: - clutter_color_init (&color, 0, 255, 0, 255); - break; - case CLUTTER_CULL_RESULT_OUT: - clutter_color_init (&color, 0, 0, 255, 255); - break; - default: - clutter_color_init (&color, 0, 255, 255, 255); - break; - } - } - else - clutter_color_init (&color, 255, 255, 255, 255); - - if (success && (pv = _clutter_actor_get_paint_volume_mutable (self))) - _clutter_actor_draw_paint_volume_full (self, pv, - &color, - node); -} - -static int clone_paint_level = 0; - -void -_clutter_actor_push_clone_paint (void) -{ - clone_paint_level++; -} - -void -_clutter_actor_pop_clone_paint (void) -{ - clone_paint_level--; -} - -static gboolean -in_clone_paint (void) -{ - return clone_paint_level > 0; -} - -/* Returns TRUE if the actor can be ignored */ -/* FIXME: we should return a ClutterCullResult, and - * clutter_actor_paint should understand that a CLUTTER_CULL_RESULT_IN - * means there's no point in trying to cull descendants of the current - * node. */ -static gboolean -cull_actor (ClutterActor *self, - ClutterPaintContext *paint_context, - ClutterCullResult *result_out) -{ - ClutterActorPrivate *priv = self->priv; - const GArray *clip_frusta; - ClutterCullResult result = CLUTTER_CULL_RESULT_IN; - int i; - - if (!priv->visible_paint_volume_valid) - { - CLUTTER_NOTE (CLIPPING, "Bail from cull_actor without culling (%s): " - "->visible_paint_volume_valid == FALSE", - _clutter_actor_get_debug_name (self)); - return FALSE; - } - - if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CULLING)) - return FALSE; - - if (clutter_paint_context_is_drawing_off_stage (paint_context)) - { - CLUTTER_NOTE (CLIPPING, "Bail from cull_actor without culling (%s): " - "Drawing off stage", - _clutter_actor_get_debug_name (self)); - return FALSE; - } - - clip_frusta = clutter_paint_context_get_clip_frusta (paint_context); - if (!clip_frusta) - { - *result_out = result; - return TRUE; - } - - for (i = 0; i < clip_frusta->len; i++) - { - const graphene_frustum_t *clip_frustum = - &g_array_index (clip_frusta, graphene_frustum_t, i); - - result = _clutter_paint_volume_cull (&priv->visible_paint_volume, - clip_frustum); - - if (result != CLUTTER_CULL_RESULT_OUT) - break; - } - - *result_out = result; - - return TRUE; -} - -/* This is the same as clutter_actor_add_effect except that it doesn't - queue a redraw and it doesn't notify on the effect property */ -static void -_clutter_actor_add_effect_internal (ClutterActor *self, - ClutterEffect *effect) -{ - ClutterActorPrivate *priv = self->priv; - - if (priv->effects == NULL) - { - priv->effects = g_object_new (CLUTTER_TYPE_META_GROUP, NULL); - priv->effects->actor = self; - } - - _clutter_meta_group_add_meta (priv->effects, CLUTTER_ACTOR_META (effect)); -} - -/* This is the same as clutter_actor_remove_effect except that it doesn't - queue a redraw and it doesn't notify on the effect property */ -static void -_clutter_actor_remove_effect_internal (ClutterActor *self, - ClutterEffect *effect) -{ - ClutterActorPrivate *priv = self->priv; - - if (priv->effects == NULL) - return; - - _clutter_meta_group_remove_meta (priv->effects, CLUTTER_ACTOR_META (effect)); - - if (_clutter_meta_group_peek_metas (priv->effects) == NULL) - g_clear_object (&priv->effects); -} - -static gboolean -needs_flatten_effect (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - - if (G_UNLIKELY (clutter_paint_debug_flags & - CLUTTER_DEBUG_DISABLE_OFFSCREEN_REDIRECT)) - return FALSE; - - /* We need to enable the effect immediately even in ON_IDLE because that can - * only be implemented efficiently within the effect itself. - * If it was implemented here using just priv->is_dirty then we would lose - * the ability to animate opacity without repaints. - */ - if ((priv->offscreen_redirect & CLUTTER_OFFSCREEN_REDIRECT_ALWAYS) || - (priv->offscreen_redirect & CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE)) - return TRUE; - else if (priv->offscreen_redirect & CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY) - { - if (clutter_actor_get_paint_opacity (self) < 255 && - clutter_actor_has_overlaps (self)) - return TRUE; - } - - return FALSE; -} - -static void -add_or_remove_flatten_effect (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - - /* Add or remove the flatten effect depending on the - offscreen-redirect property. */ - if (needs_flatten_effect (self)) - { - if (priv->flatten_effect == NULL) - { - ClutterActorMeta *actor_meta; - gint priority; - - priv->flatten_effect = _clutter_flatten_effect_new (); - /* Keep a reference to the effect so that we can queue - redraws from it */ - g_object_ref_sink (priv->flatten_effect); - - /* Set the priority of the effect to high so that it will - always be applied to the actor first. It uses an internal - priority so that it won't be visible to applications */ - actor_meta = CLUTTER_ACTOR_META (priv->flatten_effect); - priority = CLUTTER_ACTOR_META_PRIORITY_INTERNAL_HIGH; - _clutter_actor_meta_set_priority (actor_meta, priority); - - /* This will add the effect without queueing a redraw */ - _clutter_actor_add_effect_internal (self, priv->flatten_effect); - } - } - else - { - if (priv->flatten_effect != NULL) - { - /* Destroy the effect so that it will lose its fbo cache of - the actor */ - _clutter_actor_remove_effect_internal (self, priv->flatten_effect); - g_clear_object (&priv->flatten_effect); - } - } -} - -static void -clutter_actor_real_paint (ClutterActor *actor, - ClutterPaintContext *paint_context) -{ - ClutterActorPrivate *priv = actor->priv; - ClutterActor *iter; - - for (iter = priv->first_child; - iter != NULL; - iter = iter->priv->next_sibling) - { - CLUTTER_NOTE (PAINT, "Painting %s, child of %s, at { %.2f, %.2f - %.2f x %.2f }", - _clutter_actor_get_debug_name (iter), - _clutter_actor_get_debug_name (actor), - iter->priv->allocation.x1, - iter->priv->allocation.y1, - iter->priv->allocation.x2 - iter->priv->allocation.x1, - iter->priv->allocation.y2 - iter->priv->allocation.y1); - - clutter_actor_paint (iter, paint_context); - } -} - -static gboolean -clutter_actor_paint_node (ClutterActor *actor, - ClutterPaintNode *root, - ClutterPaintContext *paint_context) -{ - ClutterActorPrivate *priv = actor->priv; - ClutterActorBox box; - ClutterColor bg_color; - - box.x1 = 0.f; - box.y1 = 0.f; - box.x2 = clutter_actor_box_get_width (&priv->allocation); - box.y2 = clutter_actor_box_get_height (&priv->allocation); - - bg_color = priv->bg_color; - - if (!CLUTTER_ACTOR_IS_TOPLEVEL (actor) && - priv->bg_color_set && - !clutter_color_equal (&priv->bg_color, &transparent)) - { - ClutterPaintNode *node; - - bg_color.alpha = clutter_actor_get_paint_opacity_internal (actor) - * priv->bg_color.alpha - / 255; - - node = clutter_color_node_new (&bg_color); - clutter_paint_node_set_static_name (node, "backgroundColor"); - clutter_paint_node_add_rectangle (node, &box); - clutter_paint_node_add_child (root, node); - clutter_paint_node_unref (node); - } - - if (priv->content != NULL) - _clutter_content_paint_content (priv->content, actor, root, paint_context); - - if (CLUTTER_ACTOR_GET_CLASS (actor)->paint_node != NULL) - CLUTTER_ACTOR_GET_CLASS (actor)->paint_node (actor, root); - - if (clutter_paint_node_get_n_children (root) == 0) - return FALSE; - - clutter_paint_node_paint (root, paint_context); - - return TRUE; -} - -/** - * clutter_actor_paint: - * @self: A #ClutterActor - * - * Renders the actor to display. - * - * This function should not be called directly by applications. - * Call clutter_actor_queue_redraw() to queue paints, instead. - * - * This function is context-aware, and will either cause a - * regular paint or a pick paint. - * - * This function will call the [vfunc@Clutter.Actor.paint] virtual - * function. - * - * This function does not paint the actor if the actor is set to 0, - * unless it is performing a pick paint. - */ -void -clutter_actor_paint (ClutterActor *self, - ClutterPaintContext *paint_context) -{ - g_autoptr (ClutterPaintNode) actor_node = NULL; - g_autoptr (ClutterPaintNode) root_node = NULL; - ClutterActorPrivate *priv; - ClutterActorBox clip; - gboolean culling_inhibited; - gboolean clip_set = FALSE; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (CLUTTER_ACTOR_IN_DESTRUCTION (self)) - return; - - priv = self->priv; - priv->propagated_one_redraw = FALSE; - - /* It's an important optimization that we consider painting of - * actors with 0 opacity to be a NOP... */ - if (/* ignore top-levels, since they might be transparent */ - !CLUTTER_ACTOR_IS_TOPLEVEL (self) && - /* Use the override opacity if its been set */ - ((priv->opacity_override >= 0) ? - priv->opacity_override : priv->opacity) == 0) - return; - - /* if we aren't paintable (not in a toplevel with all - * parents paintable) then do nothing. - */ - if (!clutter_actor_is_mapped (self)) - return; - -#ifdef HAVE_PROFILER - COGL_TRACE_SCOPED_ANCHOR (ClutterActorPaint); - - if (G_UNLIKELY (clutter_debug_flags & CLUTTER_DEBUG_DETAILED_TRACE)) - { - COGL_TRACE_BEGIN_ANCHORED (ClutterActorPaint, - "Clutter::Actor::paint()"); - COGL_TRACE_DESCRIBE (ClutterActorPaint, - _clutter_actor_get_debug_name (self)); - } -#endif - - actor_node = clutter_actor_node_new (self, -1); - root_node = clutter_paint_node_ref (actor_node); - - if (priv->has_clip) - { - clip.x1 = priv->clip.origin.x; - clip.y1 = priv->clip.origin.y; - clip.x2 = priv->clip.origin.x + priv->clip.size.width; - clip.y2 = priv->clip.origin.y + priv->clip.size.height; - clip_set = TRUE; - } - else if (priv->clip_to_allocation) - { - clip.x1 = 0.f; - clip.y1 = 0.f; - clip.x2 = priv->allocation.x2 - priv->allocation.x1; - clip.y2 = priv->allocation.y2 - priv->allocation.y1; - clip_set = TRUE; - } - - if (clip_set) - { - ClutterPaintNode *clip_node; - - clip_node = clutter_clip_node_new (); - clutter_paint_node_add_rectangle (clip_node, &clip); - clutter_paint_node_add_child (clip_node, root_node); - clutter_paint_node_unref (root_node); - - root_node = g_steal_pointer (&clip_node); - } - - if (priv->enable_model_view_transform) - { - ClutterPaintNode *transform_node; - graphene_matrix_t transform; - - clutter_actor_get_transform (self, &transform); - - if (!graphene_matrix_is_identity (&transform)) - { - transform_node = clutter_transform_node_new (&transform); - clutter_paint_node_add_child (transform_node, root_node); - clutter_paint_node_unref (root_node); - - root_node = g_steal_pointer (&transform_node); - } - -#ifdef CLUTTER_ENABLE_DEBUG - /* Catch when out-of-band transforms have been made by actors not as part - * of an apply_transform vfunc... */ - if (G_UNLIKELY (clutter_debug_flags & CLUTTER_DEBUG_OOB_TRANSFORMS)) - { - graphene_matrix_t expected_matrix; - - clutter_actor_get_relative_transformation_matrix (self, NULL, - &expected_matrix); - - if (!graphene_matrix_equal_fast (&transform, &expected_matrix)) - { - GString *buf = g_string_sized_new (1024); - ClutterActor *parent; - - parent = self; - while (parent != NULL) - { - g_string_append (buf, _clutter_actor_get_debug_name (parent)); - - if (parent->priv->parent != NULL) - g_string_append (buf, "->"); - - parent = parent->priv->parent; - } - - g_warning ("Unexpected transform found when painting actor " - "\"%s\". This will be caused by one of the actor's " - "ancestors (%s) using the Cogl API directly to transform " - "children instead of using ::apply_transform().", - _clutter_actor_get_debug_name (self), - buf->str); - - g_string_free (buf, TRUE); - } - } -#endif /* CLUTTER_ENABLE_DEBUG */ - } - - /* We check whether we need to add the flatten effect before - * each paint so that we can avoid having a mechanism for - * applications to notify when the value of the - * has_overlaps virtual changes. - */ - add_or_remove_flatten_effect (self); - - culling_inhibited = priv->inhibit_culling_counter > 0; - if (!culling_inhibited && !in_clone_paint ()) - { - gboolean success; - gboolean should_cull_out = (clutter_paint_debug_flags & - (CLUTTER_DEBUG_DISABLE_CULLING | - CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS)) != - (CLUTTER_DEBUG_DISABLE_CULLING | - CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS); - /* annoyingly gcc warns if uninitialized even though - * the initialization is redundant :-( */ - ClutterCullResult result = CLUTTER_CULL_RESULT_IN; - - success = should_cull_out - ? cull_actor (self, paint_context, &result) - : FALSE; - - if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS)) - _clutter_actor_paint_cull_result (self, success, result, actor_node); - else if (result == CLUTTER_CULL_RESULT_OUT && success) - return; - } - - if (priv->effects == NULL) - priv->next_effect_to_paint = NULL; - else - priv->next_effect_to_paint = - _clutter_meta_group_peek_metas (priv->effects); - - if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_VOLUMES)) - _clutter_actor_draw_paint_volume (self, actor_node); - - clutter_paint_node_paint (root_node, paint_context); - - /* If we make it here then the actor has run through a complete - * paint run including all the effects so it's no longer dirty, - * unless a new redraw was queued up. - */ - priv->is_dirty = priv->propagated_one_redraw; -} - -/** - * clutter_actor_continue_paint: - * @self: A #ClutterActor - * - * Run the next stage of the paint sequence. This function should only - * be called within the implementation of the ‘run’ virtual of a - * #ClutterEffect. It will cause the run method of the next effect to - * be applied, or it will paint the actual actor if the current effect - * is the last effect in the chain. - */ -void -clutter_actor_continue_paint (ClutterActor *self, - ClutterPaintContext *paint_context) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - /* This should only be called from with in the ‘run’ implementation - of a ClutterEffect */ - g_return_if_fail (CLUTTER_ACTOR_IN_PAINT (self)); - - priv = self->priv; - - /* Skip any effects that are disabled */ - while (priv->next_effect_to_paint && - !clutter_actor_meta_get_enabled (priv->next_effect_to_paint->data)) - priv->next_effect_to_paint = priv->next_effect_to_paint->next; - - /* If this has come from the last effect then we'll just paint the - actual actor */ - if (priv->next_effect_to_paint == NULL) - { - CoglFramebuffer *framebuffer; - ClutterPaintNode *dummy; - - /* XXX - this will go away in 2.0, when we can get rid of this - * stuff and switch to a pure retained render tree of PaintNodes - * for the entire frame, starting from the Stage; the paint() - * virtual function can then be called directly. - */ - framebuffer = clutter_paint_context_get_base_framebuffer (paint_context); - dummy = _clutter_dummy_node_new (self, framebuffer); - clutter_paint_node_set_static_name (dummy, "Root"); - - /* XXX - for 1.12, we use the return value of paint_node() to - * decide whether we should call the paint() vfunc. - */ - clutter_actor_paint_node (self, dummy, paint_context); - clutter_paint_node_unref (dummy); - - CLUTTER_ACTOR_GET_CLASS (self)->paint (self, paint_context); - } - else - { - g_autoptr (ClutterPaintNode) effect_node = NULL; - ClutterEffect *old_current_effect; - ClutterEffectPaintFlags run_flags = 0; - - /* Cache the current effect so that we can put it back before - returning */ - old_current_effect = priv->current_effect; - - priv->current_effect = priv->next_effect_to_paint->data; - priv->next_effect_to_paint = priv->next_effect_to_paint->next; - - if (priv->is_dirty) - { - /* If there's an effect queued with this redraw then all - * effects up to that one will be considered dirty. It - * is expected the queued effect will paint the cached - * image and not call clutter_actor_continue_paint again - * (although it should work ok if it does) - */ - if (priv->effect_to_redraw == NULL || - priv->current_effect != priv->effect_to_redraw) - run_flags |= CLUTTER_EFFECT_PAINT_ACTOR_DIRTY; - } - - if (priv->current_effect == priv->flatten_effect && - priv->offscreen_redirect & CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE && - run_flags & CLUTTER_EFFECT_PAINT_ACTOR_DIRTY) - run_flags |= CLUTTER_EFFECT_PAINT_BYPASS_EFFECT; - - effect_node = clutter_effect_node_new (priv->current_effect); - - _clutter_effect_paint (priv->current_effect, - effect_node, - paint_context, - run_flags); - - clutter_paint_node_paint (effect_node, paint_context); - - priv->current_effect = old_current_effect; - } -} - -/** - * clutter_actor_pick: - * @actor: A #ClutterActor - * - * Asks @actor to perform a pick. - */ -void -clutter_actor_pick (ClutterActor *actor, - ClutterPickContext *pick_context) -{ - ClutterActorPrivate *priv; - ClutterActorBox clip; - gboolean transform_pushed = FALSE; - gboolean clip_set = FALSE; - gboolean should_cull = (clutter_paint_debug_flags & - (CLUTTER_DEBUG_DISABLE_CULLING | - CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS)) != - (CLUTTER_DEBUG_DISABLE_CULLING | - CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS); - - if (CLUTTER_ACTOR_IN_DESTRUCTION (actor)) - return; - - priv = actor->priv; - - /* if we aren't paintable (not in a toplevel with all - * parents paintable) then do nothing. - */ - if (!clutter_actor_is_mapped (actor)) - return; - - /* mark that we are in the paint process */ - CLUTTER_SET_PRIVATE_FLAGS (actor, CLUTTER_IN_PICK); - - if (should_cull && priv->has_paint_volume && priv->visible_paint_volume_valid) - { - graphene_box_t box; - - clutter_paint_volume_to_box (&priv->visible_paint_volume, &box); - if (!clutter_pick_context_intersects_box (pick_context, &box)) - { - clutter_pick_context_log_overlap (pick_context, actor); - goto out; - } - } - - if (priv->enable_model_view_transform) - { - graphene_matrix_t matrix; - - graphene_matrix_init_identity (&matrix); - _clutter_actor_apply_modelview_transform (actor, &matrix); - if (!graphene_matrix_is_identity (&matrix)) - { - clutter_pick_context_push_transform (pick_context, &matrix); - transform_pushed = TRUE; - } - } - - if (priv->has_clip) - { - clip.x1 = priv->clip.origin.x; - clip.y1 = priv->clip.origin.y; - clip.x2 = priv->clip.origin.x + priv->clip.size.width; - clip.y2 = priv->clip.origin.y + priv->clip.size.height; - clip_set = TRUE; - } - else if (priv->clip_to_allocation) - { - clip.x1 = 0.f; - clip.y1 = 0.f; - clip.x2 = priv->allocation.x2 - priv->allocation.x1; - clip.y2 = priv->allocation.y2 - priv->allocation.y1; - clip_set = TRUE; - } - - if (clip_set) - clutter_pick_context_push_clip (pick_context, &clip); - - priv->next_effect_to_paint = NULL; - if (priv->effects) - { - priv->next_effect_to_paint = - _clutter_meta_group_peek_metas (priv->effects); - } - - clutter_actor_continue_pick (actor, pick_context); - - if (clip_set) - clutter_pick_context_pop_clip (pick_context); - - if (transform_pushed) - clutter_pick_context_pop_transform (pick_context); - -out: - /* paint sequence complete */ - CLUTTER_UNSET_PRIVATE_FLAGS (actor, CLUTTER_IN_PICK); -} - -/** - * clutter_actor_continue_pick: - * @actor: A #ClutterActor - * - * Run the next stage of the pick sequence. This function should only - * be called within the implementation of the ‘pick’ virtual of a - * #ClutterEffect. It will cause the run method of the next effect to - * be applied, or it will pick the actual actor if the current effect - * is the last effect in the chain. - */ -void -clutter_actor_continue_pick (ClutterActor *actor, - ClutterPickContext *pick_context) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - g_return_if_fail (CLUTTER_ACTOR_IN_PICK (actor)); - - priv = actor->priv; - - /* Skip any effects that are disabled */ - while (priv->next_effect_to_paint && - !clutter_actor_meta_get_enabled (priv->next_effect_to_paint->data)) - priv->next_effect_to_paint = priv->next_effect_to_paint->next; - - /* If this has come from the last effect then we'll just pick the - * actual actor. - */ - if (priv->next_effect_to_paint == NULL) - { - /* The actor will log a silhouette of itself to the stage pick log. - * - * XXX:2.0 - Call the pick() virtual directly - */ - if (g_signal_has_handler_pending (actor, actor_signals[PICK], - 0, TRUE)) - g_signal_emit (actor, actor_signals[PICK], 0, pick_context); - else - CLUTTER_ACTOR_GET_CLASS (actor)->pick (actor, pick_context); - } - else - { - ClutterEffect *old_current_effect; - - /* Cache the current effect so that we can put it back before - * returning. - */ - old_current_effect = priv->current_effect; - - priv->current_effect = priv->next_effect_to_paint->data; - priv->next_effect_to_paint = priv->next_effect_to_paint->next; - - _clutter_effect_pick (priv->current_effect, pick_context); - - priv->current_effect = old_current_effect; - } -} - -static void -_clutter_actor_stop_transitions (ClutterActor *self) -{ - const ClutterAnimationInfo *info; - GHashTableIter iter; - gpointer value; - - info = _clutter_actor_get_animation_info_or_defaults (self); - if (info->transitions == NULL) - return; - - g_hash_table_iter_init (&iter, info->transitions); - while (g_hash_table_iter_next (&iter, NULL, &value)) - { - TransitionClosure *closure = value; - - if (clutter_transition_get_remove_on_complete (closure->transition)) - { - g_hash_table_iter_remove (&iter); - } - else - { - /* otherwise we stop it, and the transition will be removed - * later, either by the actor's destruction or by explicit - * removal - */ - clutter_timeline_stop (CLUTTER_TIMELINE (closure->transition)); - } - } -} - -static inline void -remove_child (ClutterActor *self, - ClutterActor *child) -{ - ClutterActor *prev_sibling, *next_sibling; - - prev_sibling = child->priv->prev_sibling; - next_sibling = child->priv->next_sibling; - - if (prev_sibling != NULL) - prev_sibling->priv->next_sibling = next_sibling; - - if (next_sibling != NULL) - next_sibling->priv->prev_sibling = prev_sibling; - - if (self->priv->first_child == child) - self->priv->first_child = next_sibling; - - if (self->priv->last_child == child) - self->priv->last_child = prev_sibling; - - child->priv->parent = NULL; - child->priv->prev_sibling = NULL; - child->priv->next_sibling = NULL; -} - -typedef enum -{ - REMOVE_CHILD_EMIT_PARENT_SET = 1 << 1, - REMOVE_CHILD_EMIT_CHILD_REMOVED = 1 << 2, - REMOVE_CHILD_CHECK_STATE = 1 << 3, - REMOVE_CHILD_NOTIFY_FIRST_LAST = 1 << 4, - REMOVE_CHILD_STOP_TRANSITIONS = 1 << 5, - REMOVE_CHILD_CLEAR_STAGE_VIEWS = 1 << 6, - - /* default flags for public API */ - REMOVE_CHILD_DEFAULT_FLAGS = REMOVE_CHILD_STOP_TRANSITIONS | - REMOVE_CHILD_EMIT_PARENT_SET | - REMOVE_CHILD_EMIT_CHILD_REMOVED | - REMOVE_CHILD_CHECK_STATE | - REMOVE_CHILD_NOTIFY_FIRST_LAST | - REMOVE_CHILD_CLEAR_STAGE_VIEWS, -} ClutterActorRemoveChildFlags; - -/*< private > - * clutter_actor_remove_child_internal: - * @self: a #ClutterActor - * @child: the child of @self that has to be removed - * @flags: control the removal operations - * - * Removes @child from the list of children of @self. - */ -static void -clutter_actor_remove_child_internal (ClutterActor *self, - ClutterActor *child, - ClutterActorRemoveChildFlags flags) -{ - ClutterActor *old_first, *old_last; - gboolean emit_parent_set, emit_child_removed, check_state; - gboolean notify_first_last; - gboolean stop_transitions; - gboolean clear_stage_views; - GObject *obj; - - if (self == child) - { - g_warning ("Cannot remove actor '%s' from itself.", - _clutter_actor_get_debug_name (self)); - return; - } - - emit_parent_set = (flags & REMOVE_CHILD_EMIT_PARENT_SET) != 0; - emit_child_removed = (flags & REMOVE_CHILD_EMIT_CHILD_REMOVED) != 0; - check_state = (flags & REMOVE_CHILD_CHECK_STATE) != 0; - notify_first_last = (flags & REMOVE_CHILD_NOTIFY_FIRST_LAST) != 0; - stop_transitions = (flags & REMOVE_CHILD_STOP_TRANSITIONS) != 0; - clear_stage_views = (flags & REMOVE_CHILD_CLEAR_STAGE_VIEWS) != 0; - - obj = G_OBJECT (self); - g_object_freeze_notify (obj); - - if (stop_transitions) - _clutter_actor_stop_transitions (child); - - if (check_state) - { - /* we need to unrealize *before* we set parent_actor to NULL, - * because in an unrealize method actors are dissociating from the - * stage, which means they need to be able to - * clutter_actor_get_stage(). - * - * yhis should unmap and unrealize, unless we're reparenting. - */ - clutter_actor_update_map_state (child, MAP_STATE_MAKE_UNREALIZED); - } - - old_first = self->priv->first_child; - old_last = self->priv->last_child; - - remove_child (self, child); - - self->priv->n_children -= 1; - - self->priv->age += 1; - - if (self->priv->in_cloned_branch) - clutter_actor_pop_in_cloned_branch (child, self->priv->in_cloned_branch); - - if (self->priv->unmapped_paint_branch_counter) - pop_in_paint_unmapped_branch (child, self->priv->unmapped_paint_branch_counter); - - /* if the child that got removed was visible and set to - * expand then we want to reset the parent's state in - * case the child was the only thing that was making it - * expand. - */ - if (clutter_actor_is_visible (child) && - (child->priv->needs_compute_expand || - child->priv->needs_x_expand || - child->priv->needs_y_expand)) - { - clutter_actor_queue_compute_expand (self); - } - - /* Only actors which are attached to a stage get notified about changes - * to the stage views, so make sure all the stage-views lists are - * cleared as the child and its children leave the actor tree. - */ - if (clear_stage_views && !CLUTTER_ACTOR_IN_DESTRUCTION (child)) - clutter_actor_clear_stage_views_recursive (child, stop_transitions); - - if (emit_parent_set && !CLUTTER_ACTOR_IN_DESTRUCTION (child)) - g_signal_emit (child, actor_signals[PARENT_SET], 0, self); - - /* we need to emit the signal before dropping the reference */ - if (emit_child_removed) - g_signal_emit (self, actor_signals[CHILD_REMOVED], 0, child); - - if (notify_first_last) - { - if (old_first != self->priv->first_child) - g_object_notify_by_pspec (obj, obj_props[PROP_FIRST_CHILD]); - - if (old_last != self->priv->last_child) - g_object_notify_by_pspec (obj, obj_props[PROP_LAST_CHILD]); - } - - g_object_thaw_notify (obj); - - /* remove the reference we acquired in clutter_actor_add_child() */ - g_object_unref (child); -} - -static ClutterTransformInfo default_transform_info = { - 0.0, /* rotation-x */ - 0.0, /* rotation-y */ - 0.0, /* rotation-z */ - - 1.0, 1.0, 1.0, /* scale */ - - GRAPHENE_POINT3D_INIT_ZERO, /* translation */ - - 0.f, /* z-position */ - - GRAPHENE_POINT_INIT_ZERO, /* pivot */ - 0.f, /* pivot-z */ - - { }, - FALSE, /* transform */ - { }, - FALSE, /* child-transform */ -}; - -static inline const ClutterTransformInfo * -get_default_transform_info (void) -{ - static gsize initialized = FALSE; - - if (G_UNLIKELY (g_once_init_enter (&initialized))) - { - graphene_matrix_init_identity (&default_transform_info.transform); - graphene_matrix_init_identity (&default_transform_info.child_transform); - g_once_init_leave (&initialized, TRUE); - } - - return &default_transform_info; -} - -/*< private > - * _clutter_actor_get_transform_info_or_defaults: - * @self: a #ClutterActor - * - * Retrieves the ClutterTransformInfo structure associated to an actor. - * - * If the actor does not have a ClutterTransformInfo structure associated - * to it, then the default structure will be returned. - * - * This function should only be used for getters. - * - * Return value: a const pointer to the ClutterTransformInfo structure - */ -const ClutterTransformInfo * -_clutter_actor_get_transform_info_or_defaults (ClutterActor *self) -{ - ClutterTransformInfo *info; - - info = g_object_get_qdata (G_OBJECT (self), quark_actor_transform_info); - if (info != NULL) - return info; - - return get_default_transform_info (); -} - -static void -clutter_transform_info_free (gpointer data) -{ - if (data != NULL) - g_free (data); -} - -/*< private > - * _clutter_actor_get_transform_info: - * @self: a #ClutterActor - * - * Retrieves a pointer to the ClutterTransformInfo structure. - * - * If the actor does not have a ClutterTransformInfo associated to it, one - * will be created and initialized to the default values. - * - * This function should be used for setters. - * - * For getters, you should use _clutter_actor_get_transform_info_or_defaults() - * instead. - * - * Return value: (transfer none): a pointer to the ClutterTransformInfo - * structure - */ -ClutterTransformInfo * -_clutter_actor_get_transform_info (ClutterActor *self) -{ - ClutterTransformInfo *info; - - info = g_object_get_qdata (G_OBJECT (self), quark_actor_transform_info); - if (info == NULL) - { - info = g_new0 (ClutterTransformInfo, 1); - - *info = *get_default_transform_info (); - - g_object_set_qdata_full (G_OBJECT (self), quark_actor_transform_info, - info, - clutter_transform_info_free); - } - - return info; -} - -static inline void -clutter_actor_set_pivot_point_internal (ClutterActor *self, - const graphene_point_t *pivot) -{ - ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info (self); - info->pivot = *pivot; - - transform_changed (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_PIVOT_POINT]); - - clutter_actor_queue_redraw (self); -} - -static inline void -clutter_actor_set_pivot_point_z_internal (ClutterActor *self, - float pivot_z) -{ - ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info (self); - info->pivot_z = pivot_z; - - transform_changed (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_PIVOT_POINT_Z]); - - clutter_actor_queue_redraw (self); -} - -/*< private > - * clutter_actor_set_translation_internal: - * @self: a #ClutterActor - * @axis: the axis of the translation to change - * @angle: the translation as a value along @axis - * - * Sets the translation on the given @axis - */ -static void -clutter_actor_set_translation_internal (ClutterActor *self, - gfloat value, - GParamSpec *pspec) -{ - GObject *obj = G_OBJECT (self); - ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info (self); - - if (pspec == obj_props[PROP_TRANSLATION_X]) - info->translation.x = value; - else if (pspec == obj_props[PROP_TRANSLATION_Y]) - info->translation.y = value; - else if (pspec == obj_props[PROP_TRANSLATION_Z]) - info->translation.z = value; - else - g_assert_not_reached (); - - transform_changed (self); - - clutter_actor_queue_redraw (self); - g_object_notify_by_pspec (obj, pspec); -} - -static inline void -clutter_actor_set_translation_factor (ClutterActor *self, - ClutterRotateAxis axis, - gdouble value) -{ - const ClutterTransformInfo *info; - const float *translate_p = NULL; - GParamSpec *pspec = NULL; - - info = _clutter_actor_get_transform_info_or_defaults (self); - - switch (axis) - { - case CLUTTER_X_AXIS: - pspec = obj_props[PROP_TRANSLATION_X]; - translate_p = &info->translation.x; - break; - - case CLUTTER_Y_AXIS: - pspec = obj_props[PROP_TRANSLATION_Y]; - translate_p = &info->translation.y; - break; - - case CLUTTER_Z_AXIS: - pspec = obj_props[PROP_TRANSLATION_Z]; - translate_p = &info->translation.z; - break; - } - - g_assert (pspec != NULL); - g_assert (translate_p != NULL); - - _clutter_actor_create_transition (self, pspec, *translate_p, value); -} - -/** - * clutter_actor_set_translation: - * @self: a #ClutterActor - * @translate_x: the translation along the X axis - * @translate_y: the translation along the Y axis - * @translate_z: the translation along the Z axis - * - * Sets an additional translation transformation on a #ClutterActor, - * relative to the [property@Clutter.Actor:pivot-point]. - */ -void -clutter_actor_set_translation (ClutterActor *self, - gfloat translate_x, - gfloat translate_y, - gfloat translate_z) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - g_object_freeze_notify (G_OBJECT (self)); - - clutter_actor_set_translation_factor (self, CLUTTER_X_AXIS, translate_x); - clutter_actor_set_translation_factor (self, CLUTTER_Y_AXIS, translate_y); - clutter_actor_set_translation_factor (self, CLUTTER_Z_AXIS, translate_z); - - g_object_thaw_notify (G_OBJECT (self)); -} - -/** - * clutter_actor_get_translation: - * @self: a #ClutterActor - * @translate_x: (out) (optional): return location for the X component - * of the translation, or %NULL - * @translate_y: (out) (optional): return location for the Y component - * of the translation, or %NULL - * @translate_z: (out) (optional): return location for the Z component - * of the translation, or %NULL - * - * Retrieves the translation set using clutter_actor_set_translation(). - */ -void -clutter_actor_get_translation (ClutterActor *self, - gfloat *translate_x, - gfloat *translate_y, - gfloat *translate_z) -{ - const ClutterTransformInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_transform_info_or_defaults (self); - - if (translate_x != NULL) - *translate_x = info->translation.x; - - if (translate_y != NULL) - *translate_y = info->translation.y; - - if (translate_z != NULL) - *translate_z = info->translation.z; -} - -/*< private > - * clutter_actor_set_rotation_angle_internal: - * @self: a #ClutterActor - * @angle: the angle of rotation - * @pspec: the #GParamSpec of the property - * - * Sets the rotation angle on the given axis without affecting the - * rotation center point. - */ -static inline void -clutter_actor_set_rotation_angle_internal (ClutterActor *self, - gdouble angle, - GParamSpec *pspec) -{ - ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info (self); - - if (pspec == obj_props[PROP_ROTATION_ANGLE_X]) - info->rx_angle = angle; - else if (pspec == obj_props[PROP_ROTATION_ANGLE_Y]) - info->ry_angle = angle; - else if (pspec == obj_props[PROP_ROTATION_ANGLE_Z]) - info->rz_angle = angle; - else - g_assert_not_reached (); - - transform_changed (self); - - clutter_actor_queue_redraw (self); - - g_object_notify_by_pspec (G_OBJECT (self), pspec); -} - -/** - * clutter_actor_set_rotation_angle: - * @self: a #ClutterActor - * @axis: the axis to set the angle one - * @angle: the angle of rotation, in degrees - * - * Sets the @angle of rotation of a #ClutterActor on the given @axis. - * - * This function is a convenience for setting the rotation properties - * [property@Clutter.Actor:rotation-angle-x], [property@Clutter.Actor:rotation-angle-y], - * and [property@Clutter.Actor:rotation-angle-z]. - * - * The center of rotation is established by the [property@Clutter.Actor:pivot-point] - * property. - */ -void -clutter_actor_set_rotation_angle (ClutterActor *self, - ClutterRotateAxis axis, - gdouble angle) -{ - const ClutterTransformInfo *info; - const double *cur_angle_p = NULL; - GParamSpec *pspec = NULL; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_transform_info_or_defaults (self); - - switch (axis) - { - case CLUTTER_X_AXIS: - cur_angle_p = &info->rx_angle; - pspec = obj_props[PROP_ROTATION_ANGLE_X]; - break; - - case CLUTTER_Y_AXIS: - cur_angle_p = &info->ry_angle; - pspec = obj_props[PROP_ROTATION_ANGLE_Y]; - break; - - case CLUTTER_Z_AXIS: - cur_angle_p = &info->rz_angle; - pspec = obj_props[PROP_ROTATION_ANGLE_Z]; - break; - } - - g_assert (pspec != NULL); - g_assert (cur_angle_p != NULL); - - _clutter_actor_create_transition (self, pspec, *cur_angle_p, angle); -} - -/** - * clutter_actor_get_rotation_angle: - * @self: a #ClutterActor - * @axis: the axis of the rotation - * - * Retrieves the angle of rotation set by clutter_actor_set_rotation_angle(). - * - * Return value: the angle of rotation, in degrees - */ -gdouble -clutter_actor_get_rotation_angle (ClutterActor *self, - ClutterRotateAxis axis) -{ - const ClutterTransformInfo *info; - gdouble retval; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0.0); - - info = _clutter_actor_get_transform_info_or_defaults (self); - - switch (axis) - { - case CLUTTER_X_AXIS: - retval = info->rx_angle; - break; - - case CLUTTER_Y_AXIS: - retval = info->ry_angle; - break; - - case CLUTTER_Z_AXIS: - retval = info->rz_angle; - break; - - default: - g_warn_if_reached (); - retval = 0.0; - break; - } - - return retval; -} - -static void -clutter_actor_set_scale_factor_internal (ClutterActor *self, - double factor, - GParamSpec *pspec) -{ - GObject *obj = G_OBJECT (self); - ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info (self); - - if (pspec == obj_props[PROP_SCALE_X]) - info->scale_x = factor; - else if (pspec == obj_props[PROP_SCALE_Y]) - info->scale_y = factor; - else if (pspec == obj_props[PROP_SCALE_Z]) - info->scale_z = factor; - else - g_assert_not_reached (); - - transform_changed (self); - - clutter_actor_queue_redraw (self); - g_object_notify_by_pspec (obj, pspec); -} - -static inline void -clutter_actor_set_scale_factor (ClutterActor *self, - ClutterRotateAxis axis, - gdouble factor) -{ - const ClutterTransformInfo *info; - const double *scale_p = NULL; - GParamSpec *pspec = NULL; - - info = _clutter_actor_get_transform_info_or_defaults (self); - - switch (axis) - { - case CLUTTER_X_AXIS: - pspec = obj_props[PROP_SCALE_X]; - scale_p = &info->scale_x; - break; - - case CLUTTER_Y_AXIS: - pspec = obj_props[PROP_SCALE_Y]; - scale_p = &info->scale_y; - break; - - case CLUTTER_Z_AXIS: - pspec = obj_props[PROP_SCALE_Z]; - scale_p = &info->scale_z; - break; - } - - g_assert (pspec != NULL); - g_assert (scale_p != NULL); - - if (*scale_p != factor) - _clutter_actor_create_transition (self, pspec, *scale_p, factor); -} - -static void -clutter_actor_set_clip_rect (ClutterActor *self, - const graphene_rect_t *clip) -{ - ClutterActorPrivate *priv = self->priv; - GObject *obj = G_OBJECT (self); - - if (clip != NULL) - { - priv->clip = *clip; - priv->has_clip = TRUE; - } - else - priv->has_clip = FALSE; - - queue_update_paint_volume (self); - clutter_actor_queue_redraw (self); - - g_object_notify_by_pspec (obj, obj_props[PROP_CLIP_RECT]); - g_object_notify_by_pspec (obj, obj_props[PROP_HAS_CLIP]); -} - -static void -clutter_actor_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterActor *actor = CLUTTER_ACTOR (object); - ClutterActorPrivate *priv = actor->priv; - - switch (prop_id) - { - case PROP_X: - clutter_actor_set_x (actor, g_value_get_float (value)); - break; - - case PROP_Y: - clutter_actor_set_y (actor, g_value_get_float (value)); - break; - - case PROP_POSITION: - { - const graphene_point_t *pos = g_value_get_boxed (value); - - if (pos != NULL) - clutter_actor_set_position (actor, pos->x, pos->y); - else - clutter_actor_set_fixed_position_set (actor, FALSE); - } - break; - - case PROP_WIDTH: - clutter_actor_set_width (actor, g_value_get_float (value)); - break; - - case PROP_HEIGHT: - clutter_actor_set_height (actor, g_value_get_float (value)); - break; - - case PROP_SIZE: - { - const graphene_size_t *size = g_value_get_boxed (value); - - if (size != NULL) - clutter_actor_set_size (actor, size->width, size->height); - else - clutter_actor_set_size (actor, -1, -1); - } - break; - - case PROP_FIXED_X: - clutter_actor_set_x (actor, g_value_get_float (value)); - break; - - case PROP_FIXED_Y: - clutter_actor_set_y (actor, g_value_get_float (value)); - break; - - case PROP_FIXED_POSITION_SET: - clutter_actor_set_fixed_position_set (actor, g_value_get_boolean (value)); - break; - - case PROP_MIN_WIDTH: - clutter_actor_set_min_width (actor, g_value_get_float (value)); - break; - - case PROP_MIN_HEIGHT: - clutter_actor_set_min_height (actor, g_value_get_float (value)); - break; - - case PROP_NATURAL_WIDTH: - clutter_actor_set_natural_width (actor, g_value_get_float (value)); - break; - - case PROP_NATURAL_HEIGHT: - clutter_actor_set_natural_height (actor, g_value_get_float (value)); - break; - - case PROP_MIN_WIDTH_SET: - clutter_actor_set_min_width_set (actor, g_value_get_boolean (value)); - break; - - case PROP_MIN_HEIGHT_SET: - clutter_actor_set_min_height_set (actor, g_value_get_boolean (value)); - break; - - case PROP_NATURAL_WIDTH_SET: - clutter_actor_set_natural_width_set (actor, g_value_get_boolean (value)); - break; - - case PROP_NATURAL_HEIGHT_SET: - clutter_actor_set_natural_height_set (actor, g_value_get_boolean (value)); - break; - - case PROP_REQUEST_MODE: - clutter_actor_set_request_mode (actor, g_value_get_enum (value)); - break; - - case PROP_Z_POSITION: - clutter_actor_set_z_position (actor, g_value_get_float (value)); - break; - - case PROP_OPACITY: - clutter_actor_set_opacity (actor, g_value_get_uint (value)); - break; - - case PROP_OFFSCREEN_REDIRECT: - clutter_actor_set_offscreen_redirect (actor, g_value_get_flags (value)); - break; - - case PROP_NAME: - clutter_actor_set_name (actor, g_value_get_string (value)); - break; - - case PROP_VISIBLE: - if (g_value_get_boolean (value) == TRUE) - clutter_actor_show (actor); - else - clutter_actor_hide (actor); - break; - - case PROP_PIVOT_POINT: - { - const graphene_point_t *pivot = g_value_get_boxed (value); - - if (pivot == NULL) - pivot = graphene_point_zero (); - - clutter_actor_set_pivot_point (actor, pivot->x, pivot->y); - } - break; - - case PROP_PIVOT_POINT_Z: - clutter_actor_set_pivot_point_z (actor, g_value_get_float (value)); - break; - - case PROP_TRANSLATION_X: - clutter_actor_set_translation_factor (actor, CLUTTER_X_AXIS, - g_value_get_float (value)); - break; - - case PROP_TRANSLATION_Y: - clutter_actor_set_translation_factor (actor, CLUTTER_Y_AXIS, - g_value_get_float (value)); - break; - - case PROP_TRANSLATION_Z: - clutter_actor_set_translation_factor (actor, CLUTTER_Z_AXIS, - g_value_get_float (value)); - break; - - case PROP_SCALE_X: - clutter_actor_set_scale_factor (actor, CLUTTER_X_AXIS, - g_value_get_double (value)); - break; - - case PROP_SCALE_Y: - clutter_actor_set_scale_factor (actor, CLUTTER_Y_AXIS, - g_value_get_double (value)); - break; - - case PROP_SCALE_Z: - clutter_actor_set_scale_factor (actor, CLUTTER_Z_AXIS, - g_value_get_double (value)); - break; - - case PROP_CLIP_RECT: - clutter_actor_set_clip_rect (actor, g_value_get_boxed (value)); - break; - - case PROP_CLIP_TO_ALLOCATION: - clutter_actor_set_clip_to_allocation (actor, g_value_get_boolean (value)); - break; - - case PROP_REACTIVE: - clutter_actor_set_reactive (actor, g_value_get_boolean (value)); - break; - - case PROP_ROTATION_ANGLE_X: - clutter_actor_set_rotation_angle (actor, - CLUTTER_X_AXIS, - g_value_get_double (value)); - break; - - case PROP_ROTATION_ANGLE_Y: - clutter_actor_set_rotation_angle (actor, - CLUTTER_Y_AXIS, - g_value_get_double (value)); - break; - - case PROP_ROTATION_ANGLE_Z: - clutter_actor_set_rotation_angle (actor, - CLUTTER_Z_AXIS, - g_value_get_double (value)); - break; - - case PROP_TRANSFORM: - clutter_actor_set_transform (actor, g_value_get_boxed (value)); - break; - - case PROP_CHILD_TRANSFORM: - clutter_actor_set_child_transform (actor, g_value_get_boxed (value)); - break; - - case PROP_SHOW_ON_SET_PARENT: /* XXX:2.0 - remove */ - priv->show_on_set_parent = g_value_get_boolean (value); - break; - - case PROP_TEXT_DIRECTION: - clutter_actor_set_text_direction (actor, g_value_get_enum (value)); - break; - - case PROP_ACTIONS: - clutter_actor_add_action (actor, g_value_get_object (value)); - break; - - case PROP_CONSTRAINTS: - clutter_actor_add_constraint (actor, g_value_get_object (value)); - break; - - case PROP_EFFECT: - clutter_actor_add_effect (actor, g_value_get_object (value)); - break; - - case PROP_LAYOUT_MANAGER: - clutter_actor_set_layout_manager (actor, g_value_get_object (value)); - break; - - case PROP_X_EXPAND: - clutter_actor_set_x_expand (actor, g_value_get_boolean (value)); - break; - - case PROP_Y_EXPAND: - clutter_actor_set_y_expand (actor, g_value_get_boolean (value)); - break; - - case PROP_X_ALIGN: - clutter_actor_set_x_align (actor, g_value_get_enum (value)); - break; - - case PROP_Y_ALIGN: - clutter_actor_set_y_align (actor, g_value_get_enum (value)); - break; - - case PROP_MARGIN_TOP: - clutter_actor_set_margin_top (actor, g_value_get_float (value)); - break; - - case PROP_MARGIN_BOTTOM: - clutter_actor_set_margin_bottom (actor, g_value_get_float (value)); - break; - - case PROP_MARGIN_LEFT: - clutter_actor_set_margin_left (actor, g_value_get_float (value)); - break; - - case PROP_MARGIN_RIGHT: - clutter_actor_set_margin_right (actor, g_value_get_float (value)); - break; - - case PROP_BACKGROUND_COLOR: - clutter_actor_set_background_color (actor, g_value_get_boxed (value)); - break; - - case PROP_CONTENT: - clutter_actor_set_content (actor, g_value_get_object (value)); - break; - - case PROP_CONTENT_GRAVITY: - clutter_actor_set_content_gravity (actor, g_value_get_enum (value)); - break; - - case PROP_MINIFICATION_FILTER: - clutter_actor_set_content_scaling_filters (actor, - g_value_get_enum (value), - actor->priv->mag_filter); - break; - - case PROP_MAGNIFICATION_FILTER: - clutter_actor_set_content_scaling_filters (actor, - actor->priv->min_filter, - g_value_get_enum (value)); - break; - - case PROP_CONTENT_REPEAT: - clutter_actor_set_content_repeat (actor, g_value_get_flags (value)); - break; - - case PROP_COLOR_STATE: - clutter_actor_set_color_state (actor, g_value_get_object (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_actor_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterActor *actor = CLUTTER_ACTOR (object); - ClutterActorPrivate *priv = actor->priv; - - switch (prop_id) - { - case PROP_X: - g_value_set_float (value, clutter_actor_get_x (actor)); - break; - - case PROP_Y: - g_value_set_float (value, clutter_actor_get_y (actor)); - break; - - case PROP_POSITION: - { - graphene_point_t position; - - graphene_point_init (&position, - clutter_actor_get_x (actor), - clutter_actor_get_y (actor)); - g_value_set_boxed (value, &position); - } - break; - - case PROP_WIDTH: - g_value_set_float (value, clutter_actor_get_width (actor)); - break; - - case PROP_HEIGHT: - g_value_set_float (value, clutter_actor_get_height (actor)); - break; - - case PROP_SIZE: - { - graphene_size_t size; - - graphene_size_init (&size, - clutter_actor_get_width (actor), - clutter_actor_get_height (actor)); - g_value_set_boxed (value, &size); - } - break; - - case PROP_FIXED_X: - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (actor); - g_value_set_float (value, info->fixed_pos.x); - } - break; - - case PROP_FIXED_Y: - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (actor); - g_value_set_float (value, info->fixed_pos.y); - } - break; - - case PROP_FIXED_POSITION_SET: - g_value_set_boolean (value, priv->position_set); - break; - - case PROP_MIN_WIDTH: - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (actor); - g_value_set_float (value, info->minimum.width); - } - break; - - case PROP_MIN_HEIGHT: - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (actor); - g_value_set_float (value, info->minimum.height); - } - break; - - case PROP_NATURAL_WIDTH: - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (actor); - g_value_set_float (value, info->natural.width); - } - break; - - case PROP_NATURAL_HEIGHT: - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (actor); - g_value_set_float (value, info->natural.height); - } - break; - - case PROP_MIN_WIDTH_SET: - g_value_set_boolean (value, priv->min_width_set); - break; - - case PROP_MIN_HEIGHT_SET: - g_value_set_boolean (value, priv->min_height_set); - break; - - case PROP_NATURAL_WIDTH_SET: - g_value_set_boolean (value, priv->natural_width_set); - break; - - case PROP_NATURAL_HEIGHT_SET: - g_value_set_boolean (value, priv->natural_height_set); - break; - - case PROP_REQUEST_MODE: - g_value_set_enum (value, priv->request_mode); - break; - - case PROP_ALLOCATION: - g_value_set_boxed (value, &priv->allocation); - break; - - case PROP_Z_POSITION: - g_value_set_float (value, clutter_actor_get_z_position (actor)); - break; - - case PROP_OPACITY: - g_value_set_uint (value, priv->opacity); - break; - - case PROP_OFFSCREEN_REDIRECT: - g_value_set_flags (value, priv->offscreen_redirect); - break; - - case PROP_NAME: - g_value_set_string (value, priv->name); - break; - - case PROP_VISIBLE: - g_value_set_boolean (value, clutter_actor_is_visible (actor)); - break; - - case PROP_MAPPED: - g_value_set_boolean (value, clutter_actor_is_mapped (actor)); - break; - - case PROP_REALIZED: - g_value_set_boolean (value, clutter_actor_is_realized (actor)); - break; - - case PROP_HAS_CLIP: - g_value_set_boolean (value, priv->has_clip); - break; - - case PROP_CLIP_RECT: - g_value_set_boxed (value, &priv->clip); - break; - - case PROP_CLIP_TO_ALLOCATION: - g_value_set_boolean (value, priv->clip_to_allocation); - break; - - case PROP_PIVOT_POINT: - { - const ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info_or_defaults (actor); - g_value_set_boxed (value, &info->pivot); - } - break; - - case PROP_PIVOT_POINT_Z: - { - const ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info_or_defaults (actor); - g_value_set_float (value, info->pivot_z); - } - break; - - case PROP_TRANSLATION_X: - { - const ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info_or_defaults (actor); - g_value_set_float (value, info->translation.x); - } - break; - - case PROP_TRANSLATION_Y: - { - const ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info_or_defaults (actor); - g_value_set_float (value, info->translation.y); - } - break; - - case PROP_TRANSLATION_Z: - { - const ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info_or_defaults (actor); - g_value_set_float (value, info->translation.z); - } - break; - - case PROP_SCALE_X: - { - const ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info_or_defaults (actor); - g_value_set_double (value, info->scale_x); - } - break; - - case PROP_SCALE_Y: - { - const ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info_or_defaults (actor); - g_value_set_double (value, info->scale_y); - } - break; - - case PROP_SCALE_Z: - { - const ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info_or_defaults (actor); - g_value_set_double (value, info->scale_z); - } - break; - - case PROP_REACTIVE: - g_value_set_boolean (value, clutter_actor_get_reactive (actor)); - break; - - case PROP_ROTATION_ANGLE_X: - { - const ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info_or_defaults (actor); - g_value_set_double (value, info->rx_angle); - } - break; - - case PROP_ROTATION_ANGLE_Y: - { - const ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info_or_defaults (actor); - g_value_set_double (value, info->ry_angle); - } - break; - - case PROP_ROTATION_ANGLE_Z: - { - const ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info_or_defaults (actor); - g_value_set_double (value, info->rz_angle); - } - break; - - case PROP_TRANSFORM: - { - graphene_matrix_t m; - - clutter_actor_get_transform (actor, &m); - g_value_set_boxed (value, &m); - } - break; - - case PROP_TRANSFORM_SET: - { - const ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info_or_defaults (actor); - g_value_set_boolean (value, info->transform_set); - } - break; - - case PROP_CHILD_TRANSFORM: - { - graphene_matrix_t m; - - clutter_actor_get_child_transform (actor, &m); - g_value_set_boxed (value, &m); - } - break; - - case PROP_CHILD_TRANSFORM_SET: - { - const ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info_or_defaults (actor); - g_value_set_boolean (value, info->child_transform_set); - } - break; - - case PROP_SHOW_ON_SET_PARENT: /* XXX:2.0 - remove */ - g_value_set_boolean (value, priv->show_on_set_parent); - break; - - case PROP_TEXT_DIRECTION: - g_value_set_enum (value, priv->text_direction); - break; - - case PROP_HAS_POINTER: - g_value_set_boolean (value, priv->n_pointers > 0); - break; - - case PROP_LAYOUT_MANAGER: - g_value_set_object (value, priv->layout_manager); - break; - - case PROP_X_EXPAND: - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (actor); - g_value_set_boolean (value, info->x_expand); - } - break; - - case PROP_Y_EXPAND: - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (actor); - g_value_set_boolean (value, info->y_expand); - } - break; - - case PROP_X_ALIGN: - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (actor); - g_value_set_enum (value, info->x_align); - } - break; - - case PROP_Y_ALIGN: - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (actor); - g_value_set_enum (value, info->y_align); - } - break; - - case PROP_MARGIN_TOP: - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (actor); - g_value_set_float (value, info->margin.top); - } - break; - - case PROP_MARGIN_BOTTOM: - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (actor); - g_value_set_float (value, info->margin.bottom); - } - break; - - case PROP_MARGIN_LEFT: - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (actor); - g_value_set_float (value, info->margin.left); - } - break; - - case PROP_MARGIN_RIGHT: - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (actor); - g_value_set_float (value, info->margin.right); - } - break; - - case PROP_BACKGROUND_COLOR_SET: - g_value_set_boolean (value, priv->bg_color_set); - break; - - case PROP_BACKGROUND_COLOR: - g_value_set_boxed (value, &priv->bg_color); - break; - - case PROP_FIRST_CHILD: - g_value_set_object (value, priv->first_child); - break; - - case PROP_LAST_CHILD: - g_value_set_object (value, priv->last_child); - break; - - case PROP_CONTENT: - g_value_set_object (value, priv->content); - break; - - case PROP_CONTENT_GRAVITY: - g_value_set_enum (value, priv->content_gravity); - break; - - case PROP_CONTENT_BOX: - { - ClutterActorBox box = { 0, }; - - clutter_actor_get_content_box (actor, &box); - g_value_set_boxed (value, &box); - } - break; - - case PROP_MINIFICATION_FILTER: - g_value_set_enum (value, priv->min_filter); - break; - - case PROP_MAGNIFICATION_FILTER: - g_value_set_enum (value, priv->mag_filter); - break; - - case PROP_CONTENT_REPEAT: - g_value_set_flags (value, priv->content_repeat); - break; - - case PROP_COLOR_STATE: - g_value_set_object (value, priv->color_state); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_actor_dispose (GObject *object) -{ - ClutterActor *self = CLUTTER_ACTOR (object); - ClutterActorPrivate *priv = self->priv; - ClutterBackend *backend = clutter_get_default_backend (); - - CLUTTER_NOTE (MISC, "Dispose actor (name='%s', ref_count:%d) of type '%s'", - _clutter_actor_get_debug_name (self), - object->ref_count, - g_type_name (G_OBJECT_TYPE (self))); - - maybe_unset_key_focus (self); - - /* Stop the emission of any property change */ - g_object_freeze_notify (object); - - g_signal_emit (self, actor_signals[DESTROY], 0); - - /* avoid recursing when called from clutter_actor_destroy() */ - if (priv->parent != NULL) - { - ClutterActor *parent = priv->parent; - clutter_actor_remove_child (parent, self); - } - - /* parent must be gone at this point */ - g_assert (priv->parent == NULL); - - if (!CLUTTER_ACTOR_IS_TOPLEVEL (self)) - { - /* can't be mapped or realized with no parent */ - g_assert (!clutter_actor_is_mapped (self)); - g_assert (!clutter_actor_is_realized (self)); - } - - g_clear_signal_handler (&priv->resolution_changed_id, backend); - g_clear_signal_handler (&priv->font_changed_id, backend); - - g_clear_object (&priv->pango_context); - g_clear_object (&priv->actions); - g_clear_object (&priv->color_state); - g_clear_object (&priv->constraints); - g_clear_object (&priv->effects); - g_clear_object (&priv->flatten_effect); - - if (priv->child_model != NULL) - { - if (priv->create_child_notify != NULL) - priv->create_child_notify (priv->create_child_data); - - priv->create_child_func = NULL; - priv->create_child_data = NULL; - priv->create_child_notify = NULL; - - g_clear_object (&priv->child_model); - } - - if (priv->layout_manager != NULL) - { - g_clear_signal_handler (&priv->layout_changed_id, priv->layout_manager); - clutter_layout_manager_set_container (priv->layout_manager, NULL); - g_clear_object (&priv->layout_manager); - } - - if (priv->content != NULL) - { - _clutter_content_detached (priv->content, self); - g_clear_object (&priv->content); - } - - if (priv->clones != NULL) - { - g_hash_table_unref (priv->clones); - priv->clones = NULL; - } - - g_clear_pointer (&priv->stage_views, g_list_free); - g_clear_pointer (&priv->next_redraw_clips, g_array_unref); - - G_OBJECT_CLASS (clutter_actor_parent_class)->dispose (object); -} - -static void -clutter_actor_finalize (GObject *object) -{ - ClutterActorPrivate *priv = CLUTTER_ACTOR (object)->priv; - - CLUTTER_NOTE (MISC, "Finalize actor (name='%s') of type '%s'", - _clutter_actor_get_debug_name ((ClutterActor *) object), - g_type_name (G_OBJECT_TYPE (object))); - - /* No new grabs should have happened after unrealizing */ - g_assert (priv->grabs == NULL); - g_free (priv->name); - - g_free (priv->debug_name); - - G_OBJECT_CLASS (clutter_actor_parent_class)->finalize (object); -} - - -/** - * clutter_actor_get_accessible: - * @self: a #ClutterActor - * - * Returns the accessible object that describes the actor to an - * assistive technology. - * - * If no class-specific #AtkObject implementation is available for the - * actor instance in question, it will inherit an #AtkObject - * implementation from the first ancestor class for which such an - * implementation is defined. - * - * The documentation of the [https://gnome.pages.gitlab.gnome.org/at-spi2-core/atk/](ATK) - * library contains more information about accessible objects and - * their uses. - * - * Returns: (transfer none): the #AtkObject associated with @actor - */ -AtkObject * -clutter_actor_get_accessible (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - return CLUTTER_ACTOR_GET_CLASS (self)->get_accessible (self); -} - -static AtkObject * -clutter_actor_real_get_accessible (ClutterActor *actor) -{ - return atk_gobject_accessible_for_object (G_OBJECT (actor)); -} - -static AtkObject * -_clutter_actor_ref_accessible (AtkImplementor *implementor) -{ - AtkObject *accessible; - - accessible = clutter_actor_get_accessible (CLUTTER_ACTOR (implementor)); - if (accessible != NULL) - g_object_ref (accessible); - - return accessible; -} - -static void -atk_implementor_iface_init (AtkImplementorIface *iface) -{ - iface->ref_accessible = _clutter_actor_ref_accessible; -} - -static gboolean -clutter_actor_real_get_paint_volume (ClutterActor *self, - ClutterPaintVolume *volume) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActor *child; - - /* this should be checked before we call this function, but it's a - * good idea to be explicit when it costs us nothing - */ - if (priv->needs_allocation) - return FALSE; - - if (priv->has_clip) - { - graphene_point3d_t origin; - - origin.x = priv->clip.origin.x; - origin.y = priv->clip.origin.y; - origin.z = 0; - - clutter_paint_volume_set_origin (volume, &origin); - clutter_paint_volume_set_width (volume, priv->clip.size.width); - clutter_paint_volume_set_height (volume, priv->clip.size.height); - - return TRUE; - } - - /* we start from the allocation */ - clutter_paint_volume_set_width (volume, - priv->allocation.x2 - priv->allocation.x1); - clutter_paint_volume_set_height (volume, - priv->allocation.y2 - priv->allocation.y1); - - /* if the actor has a clip set then we have a pretty definite - * size for the paint volume: the actor cannot possibly paint - * outside the clip region. - */ - if (priv->clip_to_allocation) - return TRUE; - - /* if we don't have children we just bail out here... */ - if (priv->n_children == 0) - return TRUE; - - /* ...but if we have children then we ask for their paint volume in - * our coordinates. if any of our children replies that it doesn't - * have a paint volume, we bail out - */ - for (child = priv->first_child; - child != NULL; - child = child->priv->next_sibling) - { - g_autoptr (ClutterPaintVolume) child_volume = NULL; - - /* we ignore unmapped children, since they won't be painted. - * - * XXX: we also have to ignore mapped children without a valid - * allocation, because apparently some code above Clutter allows - * them. - */ - if ((!clutter_actor_is_mapped (child) && - !clutter_actor_has_mapped_clones (child)) || - !clutter_actor_has_allocation (child)) - continue; - - child_volume = clutter_actor_get_transformed_paint_volume (child, self); - if (child_volume == NULL) - return FALSE; - - clutter_paint_volume_union (volume, child_volume); - } - - return TRUE; -} - -static gboolean -clutter_actor_real_has_overlaps (ClutterActor *self) -{ - /* By default we'll assume that all actors need an offscreen redirect to get - * the correct opacity. Actors such as ClutterTexture that would never need - * an offscreen redirect can override this to return FALSE. */ - return TRUE; -} - -static float -clutter_actor_real_calculate_resource_scale (ClutterActor *self, - int phase) -{ - GList *l; - float new_resource_scale = -1.f; - - for (l = clutter_actor_peek_stage_views (self); l; l = l->next) - { - ClutterStageView *view = l->data; - - new_resource_scale = MAX (clutter_stage_view_get_scale (view), - new_resource_scale); - } - - return new_resource_scale; -} - -static void -clutter_actor_real_destroy (ClutterActor *actor) -{ - clutter_actor_destroy_all_children (actor); -} - -static GObject * -clutter_actor_constructor (GType gtype, - guint n_props, - GObjectConstructParam *props) -{ - GObjectClass *gobject_class; - ClutterActor *self; - GObject *retval; - - gobject_class = G_OBJECT_CLASS (clutter_actor_parent_class); - retval = gobject_class->constructor (gtype, n_props, props); - self = CLUTTER_ACTOR (retval); - - if (self->priv->layout_manager == NULL) - { - ClutterActorClass *actor_class; - ClutterLayoutManager *default_layout; - GType layout_manager_type; - - actor_class = CLUTTER_ACTOR_GET_CLASS (self); - - layout_manager_type = clutter_actor_class_get_layout_manager_type (actor_class); - if (layout_manager_type == G_TYPE_INVALID) - layout_manager_type = CLUTTER_TYPE_FIXED_LAYOUT; - - CLUTTER_NOTE (LAYOUT, "Creating default layout manager"); - - default_layout = g_object_new (layout_manager_type, NULL); - clutter_actor_set_layout_manager (self, default_layout); - } - - return retval; -} - -static void -clutter_actor_class_init (ClutterActorClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - quark_actor_layout_info = g_quark_from_static_string ("-clutter-actor-layout-info"); - quark_actor_transform_info = g_quark_from_static_string ("-clutter-actor-transform-info"); - quark_actor_animation_info = g_quark_from_static_string ("-clutter-actor-animation-info"); - - quark_key = g_quark_from_static_string ("key"); - quark_motion = g_quark_from_static_string ("motion"); - quark_pointer_focus = g_quark_from_static_string ("pointer-focus"); - quark_button = g_quark_from_static_string ("button"); - quark_scroll = g_quark_from_static_string ("scroll"); - quark_stage = g_quark_from_static_string ("stage"); - quark_touch = g_quark_from_static_string ("touch"); - quark_touchpad = g_quark_from_static_string ("touchpad"); - quark_proximity = g_quark_from_static_string ("proximity"); - quark_pad = g_quark_from_static_string ("pad"); - quark_im = g_quark_from_static_string ("im"); - - object_class->constructor = clutter_actor_constructor; - object_class->set_property = clutter_actor_set_property; - object_class->get_property = clutter_actor_get_property; - object_class->dispose = clutter_actor_dispose; - object_class->finalize = clutter_actor_finalize; - - klass->show = clutter_actor_real_show; - klass->hide = clutter_actor_real_hide; - klass->hide_all = clutter_actor_hide; - klass->map = clutter_actor_real_map; - klass->unmap = clutter_actor_real_unmap; - klass->unrealize = clutter_actor_real_unrealize; - klass->pick = clutter_actor_real_pick; - klass->get_preferred_width = clutter_actor_real_get_preferred_width; - klass->get_preferred_height = clutter_actor_real_get_preferred_height; - klass->allocate = clutter_actor_real_allocate; - klass->queue_relayout = clutter_actor_real_queue_relayout; - klass->apply_transform = clutter_actor_real_apply_transform; - klass->get_accessible = clutter_actor_real_get_accessible; - klass->get_paint_volume = clutter_actor_real_get_paint_volume; - klass->has_overlaps = clutter_actor_real_has_overlaps; - klass->calculate_resource_scale = clutter_actor_real_calculate_resource_scale; - klass->paint = clutter_actor_real_paint; - klass->destroy = clutter_actor_real_destroy; - - klass->layout_manager_type = G_TYPE_INVALID; - - /** - * ClutterActor:x: - * - * X coordinate of the actor in pixels. If written, forces a fixed - * position for the actor. If read, returns the fixed position if any, - * otherwise the allocation if available, otherwise 0. - * - * The [property@Clutter.Actor:x] property is animatable. - */ - obj_props[PROP_X] = - g_param_spec_float ("x", NULL, NULL, - -G_MAXFLOAT, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:y: - * - * Y coordinate of the actor in pixels. If written, forces a fixed - * position for the actor. If read, returns the fixed position if - * any, otherwise the allocation if available, otherwise 0. - * - * The [property@Clutter.Actor:y] property is animatable. - */ - obj_props[PROP_Y] = - g_param_spec_float ("y", NULL, NULL, - -G_MAXFLOAT, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:position: - * - * The position of the origin of the actor. - * - * This property is a shorthand for setting and getting the - * [property@Clutter.Actor:x] and [property@Clutter.Actor:y] properties at the same - * time. - * - * The [property@Clutter.Actor:position] property is animatable. - */ - obj_props[PROP_POSITION] = - g_param_spec_boxed ("position", NULL, NULL, - GRAPHENE_TYPE_POINT, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:width: - * - * Width of the actor (in pixels). If written, forces the minimum and - * natural size request of the actor to the given width. If read, returns - * the allocated width if available, otherwise the width request. - * - * The [property@Clutter.Actor:width] property is animatable. - */ - obj_props[PROP_WIDTH] = - g_param_spec_float ("width", NULL, NULL, - -1.0f, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:height: - * - * Height of the actor (in pixels). If written, forces the minimum and - * natural size request of the actor to the given height. If read, returns - * the allocated height if available, otherwise the height request. - * - * The [property@Clutter.Actor:height] property is animatable. - */ - obj_props[PROP_HEIGHT] = - g_param_spec_float ("height", NULL, NULL, - -1.0f, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:size: - * - * The size of the actor. - * - * This property is a shorthand for setting and getting the - * [property@Clutter.Actor:width] and [property@Clutter.Actor:height] - * at the same time. - * - * The [property@Clutter.Actor:size] property is animatable. - */ - obj_props[PROP_SIZE] = - g_param_spec_boxed ("size", NULL, NULL, - GRAPHENE_TYPE_SIZE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:fixed-x: - * - * The fixed X position of the actor in pixels. - * - * Writing this property sets [property@Clutter.Actor:fixed-position-set] - * property as well, as a side effect - */ - obj_props[PROP_FIXED_X] = - g_param_spec_float ("fixed-x", NULL, NULL, - -G_MAXFLOAT, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:fixed-y: - * - * The fixed Y position of the actor in pixels. - * - * Writing this property sets the [property@Clutter.Actor:fixed-position-set] - * property as well, as a side effect - */ - obj_props[PROP_FIXED_Y] = - g_param_spec_float ("fixed-y", NULL, NULL, - -G_MAXFLOAT, G_MAXFLOAT, - 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:fixed-position-set: - * - * This flag controls whether the [property@Clutter.Actor:fixed-x] and - * [property@Clutter.Actor:fixed-y] properties are used - */ - obj_props[PROP_FIXED_POSITION_SET] = - g_param_spec_boolean ("fixed-position-set", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:min-width: - * - * A forced minimum width request for the actor, in pixels - * - * Writing this property sets the [property@Clutter.Actor:min-width-set] property - * as well, as a side effect. - * - *This property overrides the usual width request of the actor. - */ - obj_props[PROP_MIN_WIDTH] = - g_param_spec_float ("min-width", NULL, NULL, - 0.0, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:min-height: - * - * A forced minimum height request for the actor, in pixels - * - * Writing this property sets the [property@Clutter.Actor:min-height-set] property - * as well, as a side effect. This property overrides the usual height - * request of the actor. - */ - obj_props[PROP_MIN_HEIGHT] = - g_param_spec_float ("min-height", NULL, NULL, - 0.0, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:natural-width: - * - * A forced natural width request for the actor, in pixels - * - * Writing this property sets the [property@Clutter.Actor:natural-width-set] - * property as well, as a side effect. This property overrides the - * usual width request of the actor - */ - obj_props[PROP_NATURAL_WIDTH] = - g_param_spec_float ("natural-width", NULL, NULL, - 0.0, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:natural-height: - * - * A forced natural height request for the actor, in pixels - * - * Writing this property sets the [property@Clutter.Actor:natural-height-set] - * property as well, as a side effect. This property overrides the - * usual height request of the actor - */ - obj_props[PROP_NATURAL_HEIGHT] = - g_param_spec_float ("natural-height", NULL, NULL, - 0.0, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:min-width-set: - * - * This flag controls whether the [property@Clutter.Actor:min-width] property - * is used - */ - obj_props[PROP_MIN_WIDTH_SET] = - g_param_spec_boolean ("min-width-set", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:min-height-set: - * - * This flag controls whether the [property@Clutter.Actor:min-height] property - * is used - */ - obj_props[PROP_MIN_HEIGHT_SET] = - g_param_spec_boolean ("min-height-set", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:natural-width-set: - * - * This flag controls whether the [property@Clutter.Actor:natural-width] property - * is used - */ - obj_props[PROP_NATURAL_WIDTH_SET] = - g_param_spec_boolean ("natural-width-set", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:natural-height-set: - * - * This flag controls whether the [property@Clutter.Actor:natural-height] property - * is used - */ - obj_props[PROP_NATURAL_HEIGHT_SET] = - g_param_spec_boolean ("natural-height-set", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:allocation: - * - * The allocation for the actor, in pixels - * - * This is property is read-only, but you might monitor it to know when an - * actor moves or resizes - */ - obj_props[PROP_ALLOCATION] = - g_param_spec_boxed ("allocation", NULL, NULL, - CLUTTER_TYPE_ACTOR_BOX, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:request-mode: - * - * Request mode for the #ClutterActor. The request mode determines the - * type of geometry management used by the actor, either height for width - * (the default) or width for height. - * - * For actors implementing height for width, the parent container should get - * the preferred width first, and then the preferred height for that width. - * - * For actors implementing width for height, the parent container should get - * the preferred height first, and then the preferred width for that height. - * - * For instance: - * - * ```c - * ClutterRequestMode mode; - * gfloat natural_width, min_width; - * gfloat natural_height, min_height; - * - * mode = clutter_actor_get_request_mode (child); - * if (mode == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH) - * { - * clutter_actor_get_preferred_width (child, -1, - * &min_width, - * &natural_width); - * clutter_actor_get_preferred_height (child, natural_width, - * &min_height, - * &natural_height); - * } - * else if (mode == CLUTTER_REQUEST_WIDTH_FOR_HEIGHT) - * { - * clutter_actor_get_preferred_height (child, -1, - * &min_height, - * &natural_height); - * clutter_actor_get_preferred_width (child, natural_height, - * &min_width, - * &natural_width); - * } - * else if (mode == CLUTTER_REQUEST_CONTENT_SIZE) - * { - * ClutterContent *content = clutter_actor_get_content (child); - * - * min_width, min_height = 0; - * natural_width = natural_height = 0; - * - * if (content != NULL) - * clutter_content_get_preferred_size (content, &natural_width, &natural_height); - * } - * ``` - * - * will retrieve the minimum and natural width and height depending on the - * preferred request mode of the #ClutterActor "child". - * - * The [method@Clutter.Actor.get_preferred_size] function will implement this - * check for you. - */ - obj_props[PROP_REQUEST_MODE] = - g_param_spec_enum ("request-mode", NULL, NULL, - CLUTTER_TYPE_REQUEST_MODE, - CLUTTER_REQUEST_HEIGHT_FOR_WIDTH, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:z-position: - * - * The actor's position on the Z axis, relative to the parent's - * transformations. - * - * Positive values will bring the actor's position nearer to the user, - * whereas negative values will bring the actor's position farther from - * the user. - * - * The [property@Clutter.Actor:z-position] does not affect the paint or allocation - * order. - * - * The [property@Clutter.Actor:z-position] property is animatable. - */ - obj_props[PROP_Z_POSITION] = - g_param_spec_float ("z-position", NULL, NULL, - -G_MAXFLOAT, G_MAXFLOAT, - 0.0f, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:opacity: - * - * Opacity of an actor, between 0 (fully transparent) and - * 255 (fully opaque) - * - * The [property@Clutter.Actor:opacity] property is animatable. - */ - obj_props[PROP_OPACITY] = - g_param_spec_uint ("opacity", NULL, NULL, - 0, 255, - 255, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:offscreen-redirect: - * - * Determines the conditions in which the actor will be redirected - * to an offscreen framebuffer while being painted. For example this - * can be used to cache an actor in a framebuffer or for improved - * handling of transparent actors. See - * clutter_actor_set_offscreen_redirect() for details. - */ - obj_props[PROP_OFFSCREEN_REDIRECT] = - g_param_spec_flags ("offscreen-redirect", NULL, NULL, - CLUTTER_TYPE_OFFSCREEN_REDIRECT, - 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterActor:visible: - * - * Whether the actor is set to be visible or not - * - * See also [property@Clutter.Actor:mapped] - */ - obj_props[PROP_VISIBLE] = - g_param_spec_boolean ("visible", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:mapped: - * - * Whether the actor is mapped (will be painted when the stage - * to which it belongs is mapped) - */ - obj_props[PROP_MAPPED] = - g_param_spec_boolean ("mapped", NULL, NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:realized: - * - * Whether the actor has been realized - */ - obj_props[PROP_REALIZED] = - g_param_spec_boolean ("realized", NULL, NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:reactive: - * - * Whether the actor is reactive to events or not - * - * Only reactive actors will emit event-related signals - */ - obj_props[PROP_REACTIVE] = - g_param_spec_boolean ("reactive", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:has-clip: - * - * Whether the actor has the [property@Clutter.Actor:clip-rect] property set or not - */ - obj_props[PROP_HAS_CLIP] = - g_param_spec_boolean ("has-clip", NULL, NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:clip-rect: - * - * The visible region of the actor, in actor-relative coordinates, - * expressed as a #graphene_rect_t. - * - * Setting this property to %NULL will unset the existing clip. - * - * Setting this property will change the [property@Clutter.Actor:has-clip] - * property as a side effect. - */ - obj_props[PROP_CLIP_RECT] = - g_param_spec_boxed ("clip-rect", NULL, NULL, - GRAPHENE_TYPE_RECT, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:name: - * - * The name of the actor - */ - obj_props[PROP_NAME] = - g_param_spec_string ("name", NULL, NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:pivot-point: - * - * The point around which the scaling and rotation transformations occur. - * - * The pivot point is expressed in normalized coordinates space, with (0, 0) - * being the top left corner of the actor and (1, 1) the bottom right corner - * of the actor. - * - * The default pivot point is located at (0, 0). - * - * The [property@Clutter.Actor:pivot-point] property is animatable. - */ - obj_props[PROP_PIVOT_POINT] = - g_param_spec_boxed ("pivot-point", NULL, NULL, - GRAPHENE_TYPE_POINT, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:pivot-point-z: - * - * The Z component of the [property@Clutter.Actor:pivot-point], expressed as a value - * along the Z axis. - * - * The [property@Clutter.Actor:pivot-point-z] property is animatable. - */ - obj_props[PROP_PIVOT_POINT_Z] = - g_param_spec_float ("pivot-point-z", NULL, NULL, - -G_MAXFLOAT, G_MAXFLOAT, - 0.f, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:scale-x: - * - * The horizontal scale of the actor. - * - * The [property@Clutter.Actor:scale-x] property is animatable. - */ - obj_props[PROP_SCALE_X] = - g_param_spec_double ("scale-x", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, - 1.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:scale-y: - * - * The vertical scale of the actor. - * - * The [property@Clutter.Actor:scale-y] property is animatable. - */ - obj_props[PROP_SCALE_Y] = - g_param_spec_double ("scale-y", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, - 1.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:scale-z: - * - * The scale factor of the actor along the Z axis. - * - * The [property@Clutter.Actor:scale-y] property is animatable. - */ - obj_props[PROP_SCALE_Z] = - g_param_spec_double ("scale-z", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, - 1.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:rotation-angle-x: - * - * The rotation angle on the X axis. - * - * The [property@Clutter.Actor:rotation-angle-x] property is animatable. - */ - obj_props[PROP_ROTATION_ANGLE_X] = - g_param_spec_double ("rotation-angle-x", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:rotation-angle-y: - * - * The rotation angle on the Y axis - * - * The [property@Clutter.Actor:rotation-angle-y] property is animatable. - */ - obj_props[PROP_ROTATION_ANGLE_Y] = - g_param_spec_double ("rotation-angle-y", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:rotation-angle-z: - * - * The rotation angle on the Z axis - * - * The [property@Clutter.Actor:rotation-angle-z] property is animatable. - */ - obj_props[PROP_ROTATION_ANGLE_Z] = - g_param_spec_double ("rotation-angle-z", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:translation-x: - * - * An additional translation applied along the X axis, relative - * to the actor's [property@Clutter.Actor:pivot-point]. - * - * The [property@Clutter.Actor:translation-x] property is animatable. - */ - obj_props[PROP_TRANSLATION_X] = - g_param_spec_float ("translation-x", NULL, NULL, - -G_MAXFLOAT, G_MAXFLOAT, - 0.f, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:translation-y: - * - * An additional translation applied along the Y axis, relative - * to the actor's [property@Clutter.Actor:pivot-point]. - * - * The [property@Clutter.Actor:translation-y] property is animatable. - */ - obj_props[PROP_TRANSLATION_Y] = - g_param_spec_float ("translation-y", NULL, NULL, - -G_MAXFLOAT, G_MAXFLOAT, - 0.f, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:translation-z: - * - * An additional translation applied along the Z axis, relative - * to the actor's [property@Clutter.Actor:pivot-point]. - * - * The [property@Clutter.Actor:translation-z] property is animatable. - */ - obj_props[PROP_TRANSLATION_Z] = - g_param_spec_float ("translation-z", NULL, NULL, - -G_MAXFLOAT, G_MAXFLOAT, - 0.f, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:transform: - * - * Overrides the transformations of a #ClutterActor with a custom - * matrix. - * - * The matrix specified by the [property@Clutter.Actor:transform] property is - * applied to the actor and its children relative to the actor's - * [property@Clutter.Actor:allocation] and - * [property@Clutter.Actor:pivot-point]. - * - * Application code should rarely need to use this function directly. - * - * Setting this property with a #graphene_matrix_t will set the - * [property@Clutter.Actor:transform-set] property to %TRUE as a side effect; - * setting this property with %NULL will set the - * [property@Clutter.Actor:transform-set] property to %FALSE. - * - * The [property@Clutter.Actor:transform] property is animatable. - */ - obj_props[PROP_TRANSFORM] = - g_param_spec_boxed ("transform", NULL, NULL, - GRAPHENE_TYPE_MATRIX, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:transform-set: - * - * Whether the [property@Clutter.Actor:transform] property is set. - */ - obj_props[PROP_TRANSFORM_SET] = - g_param_spec_boolean ("transform-set", NULL, NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:child-transform: - * - * Applies a transformation matrix on each child of an actor. - * - * Setting this property with a #graphene_matrix_t will set the - * [property@Clutter.Actor:child-transform-set] property to %TRUE as a side effect; - * setting this property with %NULL will set the - * [property@Clutter.Actor:child-transform-set] property to %FALSE. - * - * The [property@Clutter.Actor:child-transform] property is animatable. - */ - obj_props[PROP_CHILD_TRANSFORM] = - g_param_spec_boxed ("child-transform", NULL, NULL, - GRAPHENE_TYPE_MATRIX, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:child-transform-set: - * - * Whether the [property@Clutter.Actor:child-transform] property is set. - */ - obj_props[PROP_CHILD_TRANSFORM_SET] = - g_param_spec_boolean ("child-transform-set", NULL, NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:show-on-set-parent: - * - * If %TRUE, the actor is automatically shown when parented. - * - * Calling clutter_actor_hide() on an actor which has not been - * parented will set this property to %FALSE as a side effect. - */ - obj_props[PROP_SHOW_ON_SET_PARENT] = /* XXX:2.0 - remove */ - g_param_spec_boolean ("show-on-set-parent", NULL, NULL, - TRUE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterActor:clip-to-allocation: - * - * Whether the clip region should track the allocated area - * of the actor. - * - * This property is ignored if a clip area has been explicitly - * set using clutter_actor_set_clip(). - */ - obj_props[PROP_CLIP_TO_ALLOCATION] = - g_param_spec_boolean ("clip-to-allocation", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:text-direction: - * - * The direction of the text inside a #ClutterActor. - */ - obj_props[PROP_TEXT_DIRECTION] = - g_param_spec_enum ("text-direction", NULL, NULL, - CLUTTER_TYPE_TEXT_DIRECTION, - CLUTTER_TEXT_DIRECTION_LTR, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:has-pointer: - * - * Whether the actor contains the pointer of a #ClutterInputDevice - * or not. - */ - obj_props[PROP_HAS_POINTER] = - g_param_spec_boolean ("has-pointer", NULL, NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:actions: - * - * Adds a #ClutterAction to the actor - */ - obj_props[PROP_ACTIONS] = - g_param_spec_object ("actions", NULL, NULL, - CLUTTER_TYPE_ACTION, - G_PARAM_WRITABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:constraints: - * - * Adds a #ClutterConstraint to the actor - */ - obj_props[PROP_CONSTRAINTS] = - g_param_spec_object ("constraints", NULL, NULL, - CLUTTER_TYPE_CONSTRAINT, - G_PARAM_WRITABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:effect: - * - * Adds #ClutterEffect to the list of effects be applied on a #ClutterActor - */ - obj_props[PROP_EFFECT] = - g_param_spec_object ("effect", NULL, NULL, - CLUTTER_TYPE_EFFECT, - G_PARAM_WRITABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:layout-manager: - * - * A delegate object for controlling the layout of the children of - * an actor. - */ - obj_props[PROP_LAYOUT_MANAGER] = - g_param_spec_object ("layout-manager", NULL, NULL, - CLUTTER_TYPE_LAYOUT_MANAGER, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:x-expand: - * - * Whether a layout manager should assign more space to the actor on - * the X axis. - */ - obj_props[PROP_X_EXPAND] = - g_param_spec_boolean ("x-expand", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:y-expand: - * - * Whether a layout manager should assign more space to the actor on - * the Y axis. - */ - obj_props[PROP_Y_EXPAND] = - g_param_spec_boolean ("y-expand", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:x-align: - * - * The alignment of an actor on the X axis, if the actor has been given - * extra space for its allocation. See also the [property@Clutter.Actor:x-expand] - * property. - */ - obj_props[PROP_X_ALIGN] = - g_param_spec_enum ("x-align", NULL, NULL, - CLUTTER_TYPE_ACTOR_ALIGN, - CLUTTER_ACTOR_ALIGN_FILL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:y-align: - * - * The alignment of an actor on the Y axis, if the actor has been given - * extra space for its allocation. - */ - obj_props[PROP_Y_ALIGN] = - g_param_spec_enum ("y-align", NULL, NULL, - CLUTTER_TYPE_ACTOR_ALIGN, - CLUTTER_ACTOR_ALIGN_FILL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:margin-top: - * - * The margin (in pixels) from the top of the actor. - * - * This property adds a margin to the actor's preferred size; the margin - * will be automatically taken into account when allocating the actor. - * - * The [property@Clutter.Actor:margin-top] property is animatable. - */ - obj_props[PROP_MARGIN_TOP] = - g_param_spec_float ("margin-top", NULL, NULL, - 0.0, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:margin-bottom: - * - * The margin (in pixels) from the bottom of the actor. - * - * This property adds a margin to the actor's preferred size; the margin - * will be automatically taken into account when allocating the actor. - * - * The [property@Clutter.Actor:margin-bottom] property is animatable. - */ - obj_props[PROP_MARGIN_BOTTOM] = - g_param_spec_float ("margin-bottom", NULL, NULL, - 0.0, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:margin-left: - * - * The margin (in pixels) from the left of the actor. - * - * This property adds a margin to the actor's preferred size; the margin - * will be automatically taken into account when allocating the actor. - * - * The [property@Clutter.Actor:margin-left] property is animatable. - */ - obj_props[PROP_MARGIN_LEFT] = - g_param_spec_float ("margin-left", NULL, NULL, - 0.0, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:margin-right: - * - * The margin (in pixels) from the right of the actor. - * - * This property adds a margin to the actor's preferred size; the margin - * will be automatically taken into account when allocating the actor. - * - * The [property@Clutter.Actor:margin-right] property is animatable. - */ - obj_props[PROP_MARGIN_RIGHT] = - g_param_spec_float ("margin-right", NULL, NULL, - 0.0, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:background-color-set: - * - * Whether the [property@Clutter.Actor:background-color] property has been set. - */ - obj_props[PROP_BACKGROUND_COLOR_SET] = - g_param_spec_boolean ("background-color-set", NULL, NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:background-color: - * - * Paints a solid fill of the actor's allocation using the specified - * color. - * - * The [property@Clutter.Actor:background-color] property is animatable. - */ - obj_props[PROP_BACKGROUND_COLOR] = - clutter_param_spec_color ("background-color", NULL, NULL, - &transparent, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - /** - * ClutterActor:first-child: - * - * The actor's first child. - */ - obj_props[PROP_FIRST_CHILD] = - g_param_spec_object ("first-child", NULL, NULL, - CLUTTER_TYPE_ACTOR, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:last-child: - * - * The actor's last child. - */ - obj_props[PROP_LAST_CHILD] = - g_param_spec_object ("last-child", NULL, NULL, - CLUTTER_TYPE_ACTOR, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:content: - * - * The #ClutterContent implementation that controls the content - * of the actor. - */ - obj_props[PROP_CONTENT] = - g_param_spec_object ("content", NULL, NULL, - CLUTTER_TYPE_CONTENT, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:content-gravity: - * - * The alignment that should be honoured by the #ClutterContent - * set with the [property@Clutter.Actor:content] property. - * - * Changing the value of this property will change the bounding box of - * the content; you can use the [property@Clutter.Actor:content-box] property to - * get the position and size of the content within the actor's - * allocation. - * - * This property is meaningful only for #ClutterContent implementations - * that have a preferred size, and if the preferred size is smaller than - * the actor's allocation. - * - * The [property@Clutter.Actor:content-gravity] property is animatable. - */ - obj_props[PROP_CONTENT_GRAVITY] = - g_param_spec_enum ("content-gravity", NULL, NULL, - CLUTTER_TYPE_CONTENT_GRAVITY, - CLUTTER_CONTENT_GRAVITY_RESIZE_FILL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:content-box: - * - * The bounding box for the #ClutterContent used by the actor. - * - * The value of this property is controlled by the [property@Clutter.Actor:allocation] - * and [property@Clutter.Actor:content-gravity] properties of #ClutterActor. - * - * The bounding box for the content is guaranteed to never exceed the - * allocation's of the actor. - */ - obj_props[PROP_CONTENT_BOX] = - g_param_spec_boxed ("content-box", NULL, NULL, - CLUTTER_TYPE_ACTOR_BOX, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY | - CLUTTER_PARAM_ANIMATABLE); - - obj_props[PROP_MINIFICATION_FILTER] = - g_param_spec_enum ("minification-filter", NULL, NULL, - CLUTTER_TYPE_SCALING_FILTER, - CLUTTER_SCALING_FILTER_LINEAR, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - obj_props[PROP_MAGNIFICATION_FILTER] = - g_param_spec_enum ("magnification-filter", NULL, NULL, - CLUTTER_TYPE_SCALING_FILTER, - CLUTTER_SCALING_FILTER_LINEAR, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:content-repeat: - * - * The repeat policy for the actor's [property@Clutter.Actor:content]. - */ - obj_props[PROP_CONTENT_REPEAT] = - g_param_spec_flags ("content-repeat", NULL, NULL, - CLUTTER_TYPE_CONTENT_REPEAT, - CLUTTER_REPEAT_NONE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterActor:color-state: - * - * The #ClutterColorState contains the properties like colorspace for each - * actors. - */ - obj_props[PROP_COLOR_STATE] = - g_param_spec_object ("color-state", NULL, NULL, - CLUTTER_TYPE_COLOR_STATE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - g_object_class_install_properties (object_class, PROP_LAST, obj_props); - - /** - * ClutterActor::destroy: - * @actor: the #ClutterActor which emitted the signal - * - * The signal notifies that all references held on the - * actor which emitted it should be released. - * - * The signal should be used by all holders of a reference - * on @actor. - * - * This signal might result in the finalization of the #ClutterActor - * if all references are released. - * - * Composite actors should override the default implementation of the - * class handler of this signal and call clutter_actor_destroy() on - * their children. When overriding the default class handler, it is - * required to chain up to the parent's implementation. - */ - actor_signals[DESTROY] = - g_signal_new (I_("destroy"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - G_STRUCT_OFFSET (ClutterActorClass, destroy), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - /** - * ClutterActor::show: - * @actor: the object which received the signal - * - * The signal is emitted when an actor is visible and - * rendered on the stage. - */ - actor_signals[SHOW] = - g_signal_new (I_("show"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterActorClass, show), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - /** - * ClutterActor::hide: - * @actor: the object which received the signal - * - * The signal is emitted when an actor is no longer rendered - * on the stage. - */ - actor_signals[HIDE] = - g_signal_new (I_("hide"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterActorClass, hide), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - /** - * ClutterActor::parent-set: - * @actor: the object which received the signal - * @old_parent: (nullable): the previous parent of the actor, or %NULL - * - * This signal is emitted when the parent of the actor changes. - */ - actor_signals[PARENT_SET] = - g_signal_new (I_("parent-set"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterActorClass, parent_set), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_ACTOR); - - /** - * ClutterActor::queue-relayout: - * @actor: the actor being queued for relayout - * - * The signal is emitted when clutter_actor_queue_relayout() - * is called on an actor. - * - * The default implementation for #ClutterActor chains up to the - * parent actor and queues a relayout on the parent, thus "bubbling" - * the relayout queue up through the actor graph. - * - * The main purpose of this signal is to allow relayout to be propagated - * properly in the procense of #ClutterClone actors. Applications will - * not normally need to connect to this signal. - */ - actor_signals[QUEUE_RELAYOUT] = - g_signal_new (I_("queue-relayout"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST | - G_SIGNAL_NO_HOOKS, - G_STRUCT_OFFSET (ClutterActorClass, queue_relayout), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - /** - * ClutterActor::event: - * @actor: the actor which received the event - * @event: a #ClutterEvent - * - * The signal is emitted each time an event is received - * by the @actor. This signal will be emitted on every actor, - * following the hierarchy chain, until it reaches the top-level - * container (the #ClutterStage). - * - * Return value: %TRUE if the event has been handled by the actor, - * or %FALSE to continue the emission. - */ - actor_signals[EVENT] = - g_signal_new (I_("event"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - G_STRUCT_OFFSET (ClutterActorClass, event), - _clutter_boolean_handled_accumulator, NULL, - _clutter_marshal_BOOLEAN__BOXED, - G_TYPE_BOOLEAN, 1, - CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (actor_signals[EVENT], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_BOOLEAN__BOXEDv); - /** - * ClutterActor::button-press-event: - * @actor: the actor which received the event - * @event: (type ClutterEvent): a button [struct@Event] - * - * The signal is emitted each time a mouse button - * is pressed on @actor. - * - * Return value: %TRUE if the event has been handled by the actor, - * or %FALSE to continue the emission. - */ - actor_signals[BUTTON_PRESS_EVENT] = - g_signal_new (I_("button-press-event"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterActorClass, button_press_event), - _clutter_boolean_handled_accumulator, NULL, - _clutter_marshal_BOOLEAN__BOXED, - G_TYPE_BOOLEAN, 1, - CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (actor_signals[BUTTON_PRESS_EVENT], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_BOOLEAN__BOXEDv); - /** - * ClutterActor::button-release-event: - * @actor: the actor which received the event - * @event: (type ClutterEvent): a button [struct@Event] - * - * The signal is emitted each time a mouse button - * is released on @actor. - * - * Return value: %TRUE if the event has been handled by the actor, - * or %FALSE to continue the emission. - */ - actor_signals[BUTTON_RELEASE_EVENT] = - g_signal_new (I_("button-release-event"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterActorClass, button_release_event), - _clutter_boolean_handled_accumulator, NULL, - _clutter_marshal_BOOLEAN__BOXED, - G_TYPE_BOOLEAN, 1, - CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (actor_signals[BUTTON_RELEASE_EVENT], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_BOOLEAN__BOXEDv); - /** - * ClutterActor::scroll-event: - * @actor: the actor which received the event - * @event: (type ClutterEvent): a scroll [struct@Event] - * - * The signal is emitted each time the mouse is - * scrolled on @actor - * - * Return value: %TRUE if the event has been handled by the actor, - * or %FALSE to continue the emission. - */ - actor_signals[SCROLL_EVENT] = - g_signal_new (I_("scroll-event"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterActorClass, scroll_event), - _clutter_boolean_handled_accumulator, NULL, - _clutter_marshal_BOOLEAN__BOXED, - G_TYPE_BOOLEAN, 1, - CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (actor_signals[SCROLL_EVENT], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_BOOLEAN__BOXEDv); - /** - * ClutterActor::key-press-event: - * @actor: the actor which received the event - * @event: (type ClutterEvent): a key [struct@Event] - * - * The signal is emitted each time a keyboard button - * is pressed while @actor has key focus (see clutter_stage_set_key_focus()). - * - * Return value: %TRUE if the event has been handled by the actor, - * or %FALSE to continue the emission. - */ - actor_signals[KEY_PRESS_EVENT] = - g_signal_new (I_("key-press-event"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterActorClass, key_press_event), - _clutter_boolean_handled_accumulator, NULL, - _clutter_marshal_BOOLEAN__BOXED, - G_TYPE_BOOLEAN, 1, - CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (actor_signals[KEY_PRESS_EVENT], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_BOOLEAN__BOXEDv); - /** - * ClutterActor::key-release-event: - * @actor: the actor which received the event - * @event: (type ClutterEvent): a key [struct@Event] - * - * The signal is emitted each time a keyboard button - * is released while @actor has key focus (see - * clutter_stage_set_key_focus()). - * - * Return value: %TRUE if the event has been handled by the actor, - * or %FALSE to continue the emission. - */ - actor_signals[KEY_RELEASE_EVENT] = - g_signal_new (I_("key-release-event"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterActorClass, key_release_event), - _clutter_boolean_handled_accumulator, NULL, - _clutter_marshal_BOOLEAN__BOXED, - G_TYPE_BOOLEAN, 1, - CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (actor_signals[KEY_RELEASE_EVENT], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_BOOLEAN__BOXEDv); - /** - * ClutterActor::motion-event: - * @actor: the actor which received the event - * @event: (type ClutterEvent): a motion [struct@Event] - * - * The signal is emitted each time the mouse pointer is - * moved over @actor. - * - * Return value: %TRUE if the event has been handled by the actor, - * or %FALSE to continue the emission. - */ - actor_signals[MOTION_EVENT] = - g_signal_new (I_("motion-event"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterActorClass, motion_event), - _clutter_boolean_handled_accumulator, NULL, - _clutter_marshal_BOOLEAN__BOXED, - G_TYPE_BOOLEAN, 1, - CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (actor_signals[MOTION_EVENT], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_BOOLEAN__BOXEDv); - - /** - * ClutterActor::key-focus-in: - * @actor: the actor which now has key focus - * - * The signal is emitted when @actor receives key focus. - */ - actor_signals[KEY_FOCUS_IN] = - g_signal_new (I_("key-focus-in"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterActorClass, key_focus_in), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - /** - * ClutterActor::key-focus-out: - * @actor: the actor which now has key focus - * - * The signal is emitted when @actor loses key focus. - */ - actor_signals[KEY_FOCUS_OUT] = - g_signal_new (I_("key-focus-out"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterActorClass, key_focus_out), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - /** - * ClutterActor::enter-event: - * @actor: the actor which the pointer has entered. - * @event: (type ClutterEvent): a crossing [struct@Event] - * - * The signal is emitted when the pointer enters the @actor - * - * Return value: %TRUE if the event has been handled by the actor, - * or %FALSE to continue the emission. - */ - actor_signals[ENTER_EVENT] = - g_signal_new (I_("enter-event"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterActorClass, enter_event), - _clutter_boolean_handled_accumulator, NULL, - _clutter_marshal_BOOLEAN__BOXED, - G_TYPE_BOOLEAN, 1, - CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (actor_signals[ENTER_EVENT], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_BOOLEAN__BOXEDv); - - /** - * ClutterActor::leave-event: - * @actor: the actor which the pointer has left - * @event: (type ClutterEvent): a crossing [struct@Event] - * - * The signal is emitted when the pointer leaves the @actor. - * - * Return value: %TRUE if the event has been handled by the actor, - * or %FALSE to continue the emission. - */ - actor_signals[LEAVE_EVENT] = - g_signal_new (I_("leave-event"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterActorClass, leave_event), - _clutter_boolean_handled_accumulator, NULL, - _clutter_marshal_BOOLEAN__BOXED, - G_TYPE_BOOLEAN, 1, - CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (actor_signals[LEAVE_EVENT], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_BOOLEAN__BOXEDv); - - /** - * ClutterActor::captured-event: - * @actor: the actor which received the signal - * @event: a #ClutterEvent - * - * The signal is emitted when an event is captured - * by Clutter. This signal will be emitted starting from the top-level - * container (the [class@Clutter.Stage]) to the actor which received the event - * going down the hierarchy. This signal can be used to intercept every - * event before the specialized events (like - * [signal@Clutter.Actor::button-press-event] or - * [signal@Clutter.Actor::button-release-event]) are - * emitted. - * - * Return value: %TRUE if the event has been handled by the actor, - * or %FALSE to continue the emission. - */ - actor_signals[CAPTURED_EVENT] = - g_signal_new (I_("captured-event"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - G_STRUCT_OFFSET (ClutterActorClass, captured_event), - _clutter_boolean_handled_accumulator, NULL, - _clutter_marshal_BOOLEAN__BOXED, - G_TYPE_BOOLEAN, 1, - CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (actor_signals[CAPTURED_EVENT], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_BOOLEAN__BOXEDv); - - /** - * ClutterActor::realize: - * @actor: the #ClutterActor that received the signal - * - * The signal is emitted each time an actor is being - * realized. - * - * Deprecated: 1.16: The signal should not be used in newly - * written code - */ - actor_signals[REALIZE] = - g_signal_new (I_("realize"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED, - G_STRUCT_OFFSET (ClutterActorClass, realize), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - /** - * ClutterActor::unrealize: - * @actor: the #ClutterActor that received the signal - * - * The signal is emitted each time an actor is being - * unrealized. - * - * Deprecated: 1.16: The signal should not be used in newly - * written code - */ - actor_signals[UNREALIZE] = - g_signal_new (I_("unrealize"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED, - G_STRUCT_OFFSET (ClutterActorClass, unrealize), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - /** - * ClutterActor::pick: - * @actor: the #ClutterActor that received the signal - * @pick_context: a #ClutterPickContext - * - * The signal is emitted each time an actor is being painted - * in "pick mode". The pick mode is used to identify the actor during - * the event handling phase, or by [method@Clutter.Stage.get_actor_at_pos]. - * - * Subclasses of #ClutterActor should override the class signal handler - * and paint themselves in that function. - * - * It is possible to connect a handler to the signal in order - * to set up some custom aspect of a paint in pick mode. - * Deprecated: 1.12: Override the [vfunc@Clutter.Actor.pick] virtual function - * instead. - */ - actor_signals[PICK] = - g_signal_new (I_("pick"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED, - G_STRUCT_OFFSET (ClutterActorClass, pick), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_PICK_CONTEXT); - - /** - * ClutterActor::transitions-completed: - * @actor: a #ClutterActor - * - * The signal is emitted once all transitions - * involving @actor are complete. - */ - actor_signals[TRANSITIONS_COMPLETED] = - g_signal_new (I_("transitions-completed"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - /** - * ClutterActor::transition-stopped: - * @actor: a #ClutterActor - * @name: the name of the transition - * @is_finished: whether the transition was finished, or stopped - * - * The signal is emitted once a transition - * is stopped; a transition is stopped once it reached its total - * duration (including eventual repeats), it has been stopped - * using [method@Clutter.Timeline.stop], or it has been removed from the - * transitions applied on @actor, using [method@Clutter.Actor.remove_transition]. - */ - actor_signals[TRANSITION_STOPPED] = - g_signal_new (I_("transition-stopped"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | - G_SIGNAL_NO_HOOKS | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - _clutter_marshal_VOID__STRING_BOOLEAN, - G_TYPE_NONE, 2, - G_TYPE_STRING, - G_TYPE_BOOLEAN); - g_signal_set_va_marshaller (actor_signals[TRANSITION_STOPPED], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_VOID__STRING_BOOLEANv); - - /** - * ClutterActor::touch-event: - * @actor: a #ClutterActor - * @event: a #ClutterEvent - * - * The signal is emitted each time a touch - * begin/end/update/cancel event. - * - * Return value: %CLUTTER_EVENT_STOP if the event has been handled by - * the actor, or %CLUTTER_EVENT_PROPAGATE to continue the emission. - */ - actor_signals[TOUCH_EVENT] = - g_signal_new (I_("touch-event"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterActorClass, touch_event), - _clutter_boolean_handled_accumulator, NULL, - _clutter_marshal_BOOLEAN__BOXED, - G_TYPE_BOOLEAN, 1, - CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (actor_signals[TOUCH_EVENT], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_BOOLEAN__BOXEDv); - - /** - * ClutterActor::stage-views-changed: - * @actor: a #ClutterActor - * - * The signal is emitted when the position or - * size an actor is being painted at have changed so that it's visible - * on different stage views. - * - * This signal is also emitted when the actor gets detached from the stage - * or when the views of the stage have been invalidated and will be - * replaced; it's not emitted when the actor gets hidden. - */ - actor_signals[STAGE_VIEWS_CHANGED] = - g_signal_new (I_("stage-views-changed"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - /** - * ClutterActor::resource-scale-changed: - * @actor: a #ClutterActor - * - * The signal is emitted when the resource scale - * value returned by [method@Clutter.Actor.get_resource_scale] changes. - * - * This signal can be used to get notified about the correct resource scale - * when the scale had to be queried outside of the paint cycle. - */ - actor_signals[RESOURCE_SCALE_CHANGED] = - g_signal_new (I_("resource-scale-changed"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterActorClass, resource_scale_changed), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - /** - * ClutterActor::child-added: - * @actor: the actor which received the signal - * @child: the new child that has been added to @actor - * - * The signal is emitted each time an actor - * has been added to @actor. - */ - actor_signals[CHILD_ADDED] = - g_signal_new (I_("child-added"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterActorClass, child_added), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_ACTOR); - /** - * ClutterActor::child-removed: - * @actor: the actor which received the signal - * @child: the child that has been removed from @actor - * - * The signal is emitted each time an actor - * is removed from @actor. - */ - actor_signals[CHILD_REMOVED] = - g_signal_new (I_("child-removed"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterActorClass, child_removed), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_ACTOR); - - /*< private > */ - actor_signals[CLONED] = - g_signal_new ("cloned", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_CLONE); - - /*< private > */ - actor_signals[DECLONED] = - g_signal_new ("decloned", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_CLONE); -} - -static void -clutter_actor_init (ClutterActor *self) -{ - ClutterActorPrivate *priv; - - self->priv = priv = clutter_actor_get_instance_private (self); - - priv->allocation = (ClutterActorBox) CLUTTER_ACTOR_BOX_UNINITIALIZED; - - priv->opacity = 0xff; - priv->show_on_set_parent = TRUE; - priv->resource_scale = -1.0f; - - priv->needs_width_request = TRUE; - priv->needs_height_request = TRUE; - priv->needs_allocation = TRUE; - priv->needs_paint_volume_update = TRUE; - priv->needs_visible_paint_volume_update = TRUE; - priv->needs_update_stage_views = TRUE; - priv->needs_finish_layout = TRUE; - - priv->cached_width_age = 1; - priv->cached_height_age = 1; - - priv->opacity_override = -1; - priv->enable_model_view_transform = TRUE; - - priv->transform_valid = FALSE; - priv->stage_relative_modelview_valid = FALSE; - - /* the default is to stretch the content, to match the - * current behaviour of basically all actors. also, it's - * the easiest thing to compute. - */ - priv->content_gravity = CLUTTER_CONTENT_GRAVITY_RESIZE_FILL; - priv->min_filter = CLUTTER_SCALING_FILTER_LINEAR; - priv->mag_filter = CLUTTER_SCALING_FILTER_LINEAR; - - /* this flag will be set to TRUE if the actor gets a child - * or if the [xy]-expand flags are explicitly set; until - * then, the actor does not need to expand. - * - * this also allows us to avoid computing the expand flag - * when building up a scene. - */ - priv->needs_compute_expand = FALSE; - - priv->next_redraw_clips = - g_array_sized_new (FALSE, TRUE, sizeof (ClutterPaintVolume), 3); - - /* we start with an easing state with duration forcibly set - * to 0, for backward compatibility. - */ - clutter_actor_save_easing_state (self); - clutter_actor_set_easing_duration (self, 0); -} - -/** - * clutter_actor_new: - * - * Creates a new #ClutterActor. - * - * A newly created actor has a floating reference, which will be sunk - * when it is added to another actor. - * - * Return value: the newly created #ClutterActor - */ -ClutterActor * -clutter_actor_new (void) -{ - return g_object_new (CLUTTER_TYPE_ACTOR, NULL); -} - -/** - * clutter_actor_destroy: - * @self: a #ClutterActor - * - * Destroys an actor. When an actor is destroyed, it will break any - * references it holds to other objects. If the actor is inside a - * container, the actor will be removed. - * - * When you destroy a container, its children will be destroyed as well. - */ -void -clutter_actor_destroy (ClutterActor *self) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - g_object_ref (self); - - /* avoid recursion while destroying */ - if (!CLUTTER_ACTOR_IN_DESTRUCTION (self)) - { - CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_DESTRUCTION); - - g_object_run_dispose (G_OBJECT (self)); - - CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_DESTRUCTION); - } - - g_object_unref (self); -} - -void -_clutter_actor_queue_redraw_full (ClutterActor *self, - const ClutterPaintVolume *volume, - ClutterEffect *effect) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActor *stage; - - /* ignore queueing a redraw for actors being destroyed */ - if (CLUTTER_ACTOR_IN_DESTRUCTION (self)) - return; - - /* we can ignore unmapped actors, unless they are inside a cloned branch - * of the scene graph, as unmapped actors will simply be left unpainted. - * - * this allows us to ignore redraws queued on leaf nodes when one - * of their parents has been hidden - */ - if (!clutter_actor_is_mapped (self) && - !clutter_actor_has_mapped_clones (self)) - { - CLUTTER_NOTE (PAINT, - "Skipping queue_redraw('%s'): mapped=%s, " - "has_mapped_clones=%s", - _clutter_actor_get_debug_name (self), - clutter_actor_is_mapped (self) ? "yes" : "no", - clutter_actor_has_mapped_clones (self) ? "yes" : "no"); - return; - } - - /* given the check above we could end up queueing a redraw on an - * unmapped actor with mapped clones, so we cannot assume that - * get_stage() will return a Stage - */ - stage = _clutter_actor_get_stage_internal (self); - if (stage == NULL) - return; - - /* ignore queueing a redraw on stages that are being destroyed */ - if (CLUTTER_ACTOR_IN_DESTRUCTION (stage)) - return; - - if (priv->needs_redraw && priv->next_redraw_clips->len == 0) - { - /* priv->needs_redraw is TRUE while priv->next_redraw_clips->len is 0, this - * means an unclipped redraw is already queued, no need to do anything. - */ - } - else - { - if (!priv->needs_redraw) - { - ClutterActor *iter = self; - - priv->needs_redraw = TRUE; - - clutter_stage_schedule_update (CLUTTER_STAGE (stage)); - - while (iter && !iter->priv->needs_finish_layout) - { - iter->priv->needs_finish_layout = TRUE; - iter = iter->priv->parent; - } - } - - if (volume) - g_array_append_val (priv->next_redraw_clips, *volume); - else - priv->next_redraw_clips->len = 0; - } - - /* If this is the first redraw queued then we can directly use the - effect parameter */ - if (!priv->is_dirty) - priv->effect_to_redraw = effect; - /* Otherwise we need to merge it with the existing effect parameter */ - else if (effect != NULL) - { - /* If there's already an effect then we need to use whichever is - later in the chain of actors. Otherwise a full redraw has - already been queued on the actor so we need to ignore the - effect parameter */ - if (priv->effect_to_redraw != NULL) - { - if (priv->effects == NULL) - g_warning ("Redraw queued with an effect that is " - "not applied to the actor"); - else - { - const GList *l; - - for (l = _clutter_meta_group_peek_metas (priv->effects); - l != NULL; - l = l->next) - { - if (l->data == priv->effect_to_redraw || - l->data == effect) - priv->effect_to_redraw = l->data; - } - } - } - } - else - { - /* If no effect is specified then we need to redraw the whole - actor */ - priv->effect_to_redraw = NULL; - } - - if (!priv->propagated_one_redraw) - _clutter_actor_propagate_queue_redraw (self); -} - -/** - * clutter_actor_queue_redraw: - * @self: A #ClutterActor - * - * Queues up a redraw of an actor and any children. The redraw occurs - * once the main loop becomes idle (after the current batch of events - * has been processed, roughly). - * - * Applications rarely need to call this, as redraws are handled - * automatically by modification functions. - * - * This function will not do anything if @self is not visible, or - * if the actor is inside an invisible part of the scenegraph. - * - * Also be aware that painting is a NOP for actors with an opacity of - * 0 - * - * When you are implementing a custom actor you must queue a redraw - * whenever some private state changes that will affect painting or - * picking of your actor. - */ -void -clutter_actor_queue_redraw (ClutterActor *self) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - _clutter_actor_queue_redraw_full (self, - NULL, /* clip volume */ - NULL /* effect */); -} - -static void -_clutter_actor_queue_relayout_on_clones (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - GHashTableIter iter; - gpointer key; - - if (priv->clones == NULL) - return; - - g_hash_table_iter_init (&iter, priv->clones); - while (g_hash_table_iter_next (&iter, &key, NULL)) - clutter_actor_queue_relayout (key); -} - -void -_clutter_actor_queue_only_relayout (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - - if (CLUTTER_ACTOR_IN_DESTRUCTION (self)) - return; - - if (priv->needs_width_request && - priv->needs_height_request && - priv->needs_allocation) - return; /* save some cpu cycles */ - -#ifdef CLUTTER_ENABLE_DEBUG - if (!CLUTTER_ACTOR_IS_TOPLEVEL (self) && CLUTTER_ACTOR_IN_RELAYOUT (self)) - { - g_warning ("The actor '%s' is currently inside an allocation " - "cycle; calling clutter_actor_queue_relayout() is " - "not recommended", - _clutter_actor_get_debug_name (self)); - } -#endif /* CLUTTER_ENABLE_DEBUG */ - - _clutter_actor_queue_relayout_on_clones (self); - - g_signal_emit (self, actor_signals[QUEUE_RELAYOUT], 0); -} - -/** - * clutter_actor_queue_redraw_with_clip: - * @self: a #ClutterActor - * @clip: (nullable): a rectangular clip region, or %NULL - * - * Queues a redraw on @self limited to a specific, actor-relative - * rectangular area. - * - * If @clip is %NULL this function is equivalent to - * clutter_actor_queue_redraw(). - */ -void -clutter_actor_queue_redraw_with_clip (ClutterActor *self, - const MtkRectangle *clip) -{ - ClutterPaintVolume volume; - graphene_point3d_t origin; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (clip == NULL) - { - clutter_actor_queue_redraw (self); - return; - } - - _clutter_paint_volume_init_static (&volume, self); - - origin.x = clip->x; - origin.y = clip->y; - origin.z = 0.0f; - - clutter_paint_volume_set_origin (&volume, &origin); - clutter_paint_volume_set_width (&volume, clip->width); - clutter_paint_volume_set_height (&volume, clip->height); - - _clutter_actor_queue_redraw_full (self, &volume, NULL); - - clutter_paint_volume_free (&volume); -} - -/** - * clutter_actor_queue_relayout: - * @self: A #ClutterActor - * - * Indicates that the actor's size request or other layout-affecting - * properties may have changed. This function is used inside #ClutterActor - * subclass implementations, not by applications directly. - * - * Queueing a new layout automatically queues a redraw as well. - */ -void -clutter_actor_queue_relayout (ClutterActor *self) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - _clutter_actor_queue_only_relayout (self); - clutter_actor_queue_redraw (self); -} - -/** - * clutter_actor_get_preferred_size: - * @self: a #ClutterActor - * @min_width_p: (out) (optional): return location for the minimum - * width, or %NULL - * @min_height_p: (out) (optional): return location for the minimum - * height, or %NULL - * @natural_width_p: (out) (optional): return location for the natural - * width, or %NULL - * @natural_height_p: (out) (optional): return location for the natural - * height, or %NULL - * - * Computes the preferred minimum and natural size of an actor, taking into - * account the actor's geometry management (either height-for-width - * or width-for-height). - * - * The width and height used to compute the preferred height and preferred - * width are the actor's natural ones. - * - * If you need to control the height for the preferred width, or the width for - * the preferred height, you should [method@Clutter.Actor.get_preferred_width] - * and [method@Clutter.Actor.get_preferred_height], and check the actor's preferred - * geometry management using the [property@Clutter.Actor:request-mode] property. - */ -void -clutter_actor_get_preferred_size (ClutterActor *self, - gfloat *min_width_p, - gfloat *min_height_p, - gfloat *natural_width_p, - gfloat *natural_height_p) -{ - ClutterActorPrivate *priv; - gfloat min_width, min_height; - gfloat natural_width, natural_height; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - priv = self->priv; - - min_width = min_height = 0; - natural_width = natural_height = 0; - - if (priv->request_mode == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH) - { - CLUTTER_NOTE (LAYOUT, "Preferred size (height-for-width)"); - clutter_actor_get_preferred_width (self, -1, - &min_width, - &natural_width); - clutter_actor_get_preferred_height (self, natural_width, - &min_height, - &natural_height); - } - else if (priv->request_mode == CLUTTER_REQUEST_WIDTH_FOR_HEIGHT) - { - CLUTTER_NOTE (LAYOUT, "Preferred size (width-for-height)"); - clutter_actor_get_preferred_height (self, -1, - &min_height, - &natural_height); - clutter_actor_get_preferred_width (self, natural_height, - &min_width, - &natural_width); - } - else if (priv->request_mode == CLUTTER_REQUEST_CONTENT_SIZE) - { - CLUTTER_NOTE (LAYOUT, "Preferred size (content-size)"); - - if (priv->content != NULL) - clutter_content_get_preferred_size (priv->content, &natural_width, &natural_height); - } - else - { - CLUTTER_NOTE (LAYOUT, "Unknown request mode"); - } - - if (min_width_p) - *min_width_p = min_width; - - if (min_height_p) - *min_height_p = min_height; - - if (natural_width_p) - *natural_width_p = natural_width; - - if (natural_height_p) - *natural_height_p = natural_height; -} - -/*< private > - * effective_align: - * @align: a #ClutterActorAlign - * @direction: a #ClutterTextDirection - * - * Retrieves the correct alignment depending on the text direction - * - * Return value: the effective alignment - */ -static ClutterActorAlign -effective_align (ClutterActorAlign align, - ClutterTextDirection direction) -{ - ClutterActorAlign res; - - switch (align) - { - case CLUTTER_ACTOR_ALIGN_START: - res = (direction == CLUTTER_TEXT_DIRECTION_RTL) - ? CLUTTER_ACTOR_ALIGN_END - : CLUTTER_ACTOR_ALIGN_START; - break; - - case CLUTTER_ACTOR_ALIGN_END: - res = (direction == CLUTTER_TEXT_DIRECTION_RTL) - ? CLUTTER_ACTOR_ALIGN_START - : CLUTTER_ACTOR_ALIGN_END; - break; - - default: - res = align; - break; - } - - return res; -} - -/*< private > - * _clutter_actor_get_effective_x_align: - * @self: a #ClutterActor - * - * Retrieves the effective horizontal alignment, taking into - * consideration the text direction of @self. - * - * Return value: the effective horizontal alignment - */ -ClutterActorAlign -_clutter_actor_get_effective_x_align (ClutterActor *self) -{ - return effective_align (clutter_actor_get_x_align (self), - clutter_actor_get_text_direction (self)); -} - -static inline void -adjust_for_margin (float margin_start, - float margin_end, - float *minimum_size, - float *natural_size, - float *allocated_start, - float *allocated_end) -{ - float min_size = *minimum_size; - float nat_size = *natural_size; - float start = *allocated_start; - float end = *allocated_end; - - min_size = MAX (min_size - (margin_start + margin_end), 0); - nat_size = MAX (nat_size - (margin_start + margin_end), 0); - - *minimum_size = min_size; - *natural_size = nat_size; - - start += margin_start; - end -= margin_end; - - if (end - start >= 0) - { - *allocated_start = start; - *allocated_end = end; - } -} - -static inline void -adjust_for_alignment (ClutterActorAlign alignment, - float natural_size, - float *allocated_start, - float *allocated_end) -{ - float allocated_size = *allocated_end - *allocated_start; - - if (allocated_size <= 0.f) - return; - - switch (alignment) - { - case CLUTTER_ACTOR_ALIGN_FILL: - /* do nothing */ - break; - - case CLUTTER_ACTOR_ALIGN_START: - /* keep start */ - *allocated_end = *allocated_start + MIN (natural_size, allocated_size); - break; - - case CLUTTER_ACTOR_ALIGN_END: - if (allocated_size > natural_size) - { - *allocated_start += (allocated_size - natural_size); - *allocated_end = *allocated_start + natural_size; - } - break; - - case CLUTTER_ACTOR_ALIGN_CENTER: - if (allocated_size > natural_size) - { - *allocated_start += floorf ((allocated_size - natural_size) / 2); - *allocated_end = *allocated_start + MIN (allocated_size, natural_size); - } - break; - } -} - -/*< private > - * clutter_actor_adjust_width: - * @self: a #ClutterActor - * @minimum_width: (inout): the actor's preferred minimum width, which - * will be adjusted depending on the margin - * @natural_width: (inout): the actor's preferred natural width, which - * will be adjusted depending on the margin - * @adjusted_x1: (out): the adjusted x1 for the actor's bounding box - * @adjusted_x2: (out): the adjusted x2 for the actor's bounding box - * - * Adjusts the preferred and allocated position and size of an actor, - * depending on the margin and alignment properties. - */ -static void -clutter_actor_adjust_width (ClutterActor *self, - gfloat *minimum_width, - gfloat *natural_width, - gfloat *adjusted_x1, - gfloat *adjusted_x2) -{ - ClutterTextDirection text_dir; - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (self); - text_dir = clutter_actor_get_text_direction (self); - - CLUTTER_NOTE (LAYOUT, "Adjusting allocated X and width"); - - /* this will tweak natural_width to remove the margin, so that - * adjust_for_alignment() will use the correct size - */ - adjust_for_margin (info->margin.left, info->margin.right, - minimum_width, natural_width, - adjusted_x1, adjusted_x2); - - adjust_for_alignment (effective_align (info->x_align, text_dir), - *natural_width, - adjusted_x1, adjusted_x2); -} - -/*< private > - * clutter_actor_adjust_height: - * @self: a #ClutterActor - * @minimum_height: (inout): the actor's preferred minimum height, which - * will be adjusted depending on the margin - * @natural_height: (inout): the actor's preferred natural height, which - * will be adjusted depending on the margin - * @adjusted_y1: (out): the adjusted y1 for the actor's bounding box - * @adjusted_y2: (out): the adjusted y2 for the actor's bounding box - * - * Adjusts the preferred and allocated position and size of an actor, - * depending on the margin and alignment properties. - */ -static void -clutter_actor_adjust_height (ClutterActor *self, - gfloat *minimum_height, - gfloat *natural_height, - gfloat *adjusted_y1, - gfloat *adjusted_y2) -{ - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (self); - - CLUTTER_NOTE (LAYOUT, "Adjusting allocated Y and height"); - - /* this will tweak natural_height to remove the margin, so that - * adjust_for_alignment() will use the correct size - */ - adjust_for_margin (info->margin.top, info->margin.bottom, - minimum_height, natural_height, - adjusted_y1, - adjusted_y2); - - /* we don't use effective_align() here, because text direction - * only affects the horizontal axis - */ - adjust_for_alignment (info->y_align, - *natural_height, - adjusted_y1, - adjusted_y2); - -} - -/* looks for a cached size request for this for_size. If not - * found, returns the oldest entry so it can be overwritten */ -static gboolean -_clutter_actor_get_cached_size_request (gfloat for_size, - SizeRequest *cached_size_requests, - SizeRequest **result) -{ - guint i; - - *result = &cached_size_requests[0]; - - for (i = 0; i < N_CACHED_SIZE_REQUESTS; i++) - { - SizeRequest *sr; - - sr = &cached_size_requests[i]; - - if (sr->age > 0 && - sr->for_size == for_size) - { - CLUTTER_NOTE (LAYOUT, "Size cache hit for size: %.2f", for_size); - *result = sr; - return TRUE; - } - else if (sr->age < (*result)->age) - { - *result = sr; - } - } - - CLUTTER_NOTE (LAYOUT, "Size cache miss for size: %.2f", for_size); - - return FALSE; -} - -static void -clutter_actor_update_preferred_size_for_constraints (ClutterActor *self, - ClutterOrientation direction, - float for_size, - float *minimum_size, - float *natural_size) -{ - ClutterActorPrivate *priv = self->priv; - const GList *constraints, *l; - - if (priv->constraints == NULL) - return; - - constraints = _clutter_meta_group_peek_metas (priv->constraints); - for (l = constraints; l != NULL; l = l->next) - { - ClutterConstraint *constraint = l->data; - ClutterActorMeta *meta = l->data; - - if (!clutter_actor_meta_get_enabled (meta)) - continue; - - clutter_constraint_update_preferred_size (constraint, self, - direction, - for_size, - minimum_size, - natural_size); - - CLUTTER_NOTE (LAYOUT, - "Preferred %s of '%s' after constraint '%s': " - "{ min:%.2f, nat:%.2f }", - direction == CLUTTER_ORIENTATION_HORIZONTAL - ? "width" - : "height", - _clutter_actor_get_debug_name (self), - _clutter_actor_meta_get_debug_name (meta), - *minimum_size, *natural_size); - } -} - -/** - * clutter_actor_get_preferred_width: - * @self: A #ClutterActor - * @for_height: available height when computing the preferred width, - * or a negative value to indicate that no height is defined - * @min_width_p: (out) (optional): return location for minimum width, - * or %NULL - * @natural_width_p: (out) (optional): return location for the natural - * width, or %NULL - * - * Computes the requested minimum and natural widths for an actor, - * optionally depending on the specified height, or if they are - * already computed, returns the cached values. - * - * An actor may not get its request - depending on the layout - * manager that's in effect. - * - * A request should not incorporate the actor's scaleor translation; - * those transformations do not affect layout, only rendering. - */ -void -clutter_actor_get_preferred_width (ClutterActor *self, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p) -{ - float request_min_width, request_natural_width; - SizeRequest *cached_size_request; - const ClutterLayoutInfo *info; - ClutterActorPrivate *priv; - gboolean found_in_cache; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - priv = self->priv; - - info = _clutter_actor_get_layout_info_or_defaults (self); - - /* we shortcircuit the case of a fixed size set using set_width() */ - if (priv->min_width_set && priv->natural_width_set) - { - if (min_width_p != NULL) - *min_width_p = info->minimum.width + (info->margin.left + info->margin.right); - - if (natural_width_p != NULL) - *natural_width_p = info->natural.width + (info->margin.left + info->margin.right); - - return; - } - - /* if the request mode is CONTENT_SIZE we simply return the content width */ - if (priv->request_mode == CLUTTER_REQUEST_CONTENT_SIZE) - { - float content_width = 0.f; - - if (priv->content != NULL) - clutter_content_get_preferred_size (priv->content, &content_width, NULL); - - if (min_width_p != NULL) - *min_width_p = content_width; - - if (natural_width_p != NULL) - *natural_width_p = content_width; - - return; - } - - CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_PREF_WIDTH); - - /* the remaining cases are: - * - * - either min_width or natural_width have been set - * - neither min_width or natural_width have been set - * - * in both cases, we go through the cache (and through the actor in case - * of cache misses) and determine the authoritative value depending on - * the *_set flags. - */ - - if (!priv->needs_width_request) - { - found_in_cache = - _clutter_actor_get_cached_size_request (for_height, - priv->width_requests, - &cached_size_request); - } - else - { - /* if the actor needs a width request we use the first slot */ - found_in_cache = FALSE; - cached_size_request = &priv->width_requests[0]; - } - - if (!found_in_cache) - { - gfloat minimum_width, natural_width; - ClutterActorClass *klass; - - minimum_width = natural_width = 0; - - /* adjust for the margin */ - if (for_height >= 0) - { - for_height -= (info->margin.top + info->margin.bottom); - if (for_height < 0) - for_height = 0; - } - - CLUTTER_NOTE (LAYOUT, "Width request for %.2f px", for_height); - - klass = CLUTTER_ACTOR_GET_CLASS (self); - klass->get_preferred_width (self, for_height, - &minimum_width, - &natural_width); - - /* adjust for constraints */ - clutter_actor_update_preferred_size_for_constraints (self, - CLUTTER_ORIENTATION_HORIZONTAL, - for_height, - &minimum_width, - &natural_width); - - /* adjust for the margin */ - minimum_width += (info->margin.left + info->margin.right); - natural_width += (info->margin.left + info->margin.right); - - /* Due to accumulated float errors, it's better not to warn - * on this, but just fix it. - */ - if (natural_width < minimum_width) - natural_width = minimum_width; - - cached_size_request->min_size = minimum_width; - cached_size_request->natural_size = natural_width; - cached_size_request->for_size = for_height; - cached_size_request->age = priv->cached_width_age; - - priv->cached_width_age += 1; - priv->needs_width_request = FALSE; - } - - if (!priv->min_width_set) - request_min_width = cached_size_request->min_size; - else - request_min_width = info->margin.left - + info->minimum.width - + info->margin.right; - - if (!priv->natural_width_set) - request_natural_width = cached_size_request->natural_size; - else - request_natural_width = info->margin.left - + info->natural.width - + info->margin.right; - - if (min_width_p) - *min_width_p = request_min_width; - - if (natural_width_p) - *natural_width_p = request_natural_width; - - CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_PREF_WIDTH); -} - -/** - * clutter_actor_get_preferred_height: - * @self: A #ClutterActor - * @for_width: available width to assume in computing desired height, - * or a negative value to indicate that no width is defined - * @min_height_p: (out) (optional): return location for minimum height, - * or %NULL - * @natural_height_p: (out) (optional): return location for natural - * height, or %NULL - * - * Computes the requested minimum and natural heights for an actor, - * or if they are already computed, returns the cached values. - * - * An actor may not get its request - depending on the layout - * manager that's in effect. - * - * A request should not incorporate the actor's scale or translation; - * those transformations do not affect layout, only rendering. - */ -void -clutter_actor_get_preferred_height (ClutterActor *self, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p) -{ - float request_min_height, request_natural_height; - SizeRequest *cached_size_request; - const ClutterLayoutInfo *info; - ClutterActorPrivate *priv; - gboolean found_in_cache; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - priv = self->priv; - - info = _clutter_actor_get_layout_info_or_defaults (self); - - /* we shortcircuit the case of a fixed size set using set_height() */ - if (priv->min_height_set && priv->natural_height_set) - { - if (min_height_p != NULL) - *min_height_p = info->minimum.height + (info->margin.top + info->margin.bottom); - - if (natural_height_p != NULL) - *natural_height_p = info->natural.height + (info->margin.top + info->margin.bottom); - - return; - } - - /* if the request mode is CONTENT_SIZE we simply return the content height */ - if (priv->request_mode == CLUTTER_REQUEST_CONTENT_SIZE) - { - float content_height = 0.f; - - if (priv->content != NULL) - clutter_content_get_preferred_size (priv->content, NULL, &content_height); - - if (min_height_p != NULL) - *min_height_p = content_height; - - if (natural_height_p != NULL) - *natural_height_p = content_height; - - return; - } - - CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_PREF_HEIGHT); - - /* the remaining cases are: - * - * - either min_height or natural_height have been set - * - neither min_height or natural_height have been set - * - * in both cases, we go through the cache (and through the actor in case - * of cache misses) and determine the authoritative value depending on - * the *_set flags. - */ - - if (!priv->needs_height_request) - { - found_in_cache = - _clutter_actor_get_cached_size_request (for_width, - priv->height_requests, - &cached_size_request); - } - else - { - found_in_cache = FALSE; - cached_size_request = &priv->height_requests[0]; - } - - if (!found_in_cache) - { - gfloat minimum_height, natural_height; - ClutterActorClass *klass; - - minimum_height = natural_height = 0; - - CLUTTER_NOTE (LAYOUT, "Height request for %.2f px", for_width); - - /* adjust for margin */ - if (for_width >= 0) - { - for_width -= (info->margin.left + info->margin.right); - if (for_width < 0) - for_width = 0; - } - - klass = CLUTTER_ACTOR_GET_CLASS (self); - klass->get_preferred_height (self, for_width, - &minimum_height, - &natural_height); - - /* adjust for constraints */ - clutter_actor_update_preferred_size_for_constraints (self, - CLUTTER_ORIENTATION_VERTICAL, - for_width, - &minimum_height, - &natural_height); - - /* adjust for margin */ - minimum_height += (info->margin.top + info->margin.bottom); - natural_height += (info->margin.top + info->margin.bottom); - - /* Due to accumulated float errors, it's better not to warn - * on this, but just fix it. - */ - if (natural_height < minimum_height) - natural_height = minimum_height; - - cached_size_request->min_size = minimum_height; - cached_size_request->natural_size = natural_height; - cached_size_request->for_size = for_width; - cached_size_request->age = priv->cached_height_age; - - priv->cached_height_age += 1; - priv->needs_height_request = FALSE; - } - - if (!priv->min_height_set) - request_min_height = cached_size_request->min_size; - else - request_min_height = info->margin.top - + info->minimum.height - + info->margin.bottom; - - if (!priv->natural_height_set) - request_natural_height = cached_size_request->natural_size; - else - request_natural_height = info->margin.top - + info->natural.height - + info->margin.bottom; - - if (min_height_p) - *min_height_p = request_min_height; - - if (natural_height_p) - *natural_height_p = request_natural_height; - - CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_PREF_HEIGHT); -} - -/** - * clutter_actor_get_allocation_box: - * @self: A #ClutterActor - * @box: (out): the function fills this in with the actor's allocation - * - * Gets the layout box an actor has been assigned. The allocation can - * only be assumed valid inside a paint() method; anywhere else, it - * may be out-of-date. - * - * An allocation does not incorporate the actor's scale or translation; - * those transformations do not affect layout, only rendering. - * - * Do not call any of the clutter_actor_get_allocation_*() family - * of functions inside the implementation of the get_preferred_width() - * or get_preferred_height() virtual functions. - */ -void -clutter_actor_get_allocation_box (ClutterActor *self, - ClutterActorBox *box) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - /* XXX - if needs_allocation=TRUE, we can either 1) g_return_if_fail, - * which limits calling get_allocation to inside paint() basically; or - * we can 2) force a layout, which could be expensive if someone calls - * get_allocation somewhere silly; or we can 3) just return the latest - * value, allowing it to be out-of-date, and assume people know what - * they are doing. - * - * The least-surprises approach that keeps existing code working is - * likely to be 2). People can end up doing some inefficient things, - * though, and in general code that requires 2) is probably broken. - */ - - /* this implements 2) */ - if (G_UNLIKELY (self->priv->needs_allocation)) - { - ClutterActor *stage = _clutter_actor_get_stage_internal (self); - - /* do not queue a relayout on an unparented actor */ - if (stage) - clutter_stage_maybe_relayout (stage); - } - - /* commenting out the code above and just keeping this assignment - * implements 3) - */ - *box = self->priv->allocation; -} - -static void -clutter_actor_update_constraints (ClutterActor *self, - ClutterActorBox *allocation) -{ - ClutterActorPrivate *priv = self->priv; - const GList *constraints, *l; - - if (priv->constraints == NULL) - return; - - constraints = _clutter_meta_group_peek_metas (priv->constraints); - for (l = constraints; l != NULL; l = l->next) - { - ClutterConstraint *constraint = l->data; - ClutterActorMeta *meta = l->data; - gboolean changed = FALSE; - - if (clutter_actor_meta_get_enabled (meta)) - { - changed |= - clutter_constraint_update_allocation (constraint, - self, - allocation); - - CLUTTER_NOTE (LAYOUT, - "Allocation of '%s' after constraint '%s': " - "{ %.2f, %.2f, %.2f, %.2f } (changed:%s)", - _clutter_actor_get_debug_name (self), - _clutter_actor_meta_get_debug_name (meta), - allocation->x1, - allocation->y1, - allocation->x2, - allocation->y2, - changed ? "yes" : "no"); - } - } -} - -/*< private > - * clutter_actor_adjust_allocation: - * @self: a #ClutterActor - * @allocation: (inout): the allocation to adjust - * - * Adjusts the passed allocation box taking into account the actor's - * layout information, like alignment, expansion, and margin. - */ -static void -clutter_actor_adjust_allocation (ClutterActor *self, - ClutterActorBox *allocation) -{ - ClutterActorBox adj_allocation; - float alloc_width, alloc_height; - float min_width, min_height; - float nat_width, nat_height; - ClutterRequestMode req_mode; - - adj_allocation = *allocation; - - clutter_actor_box_get_size (allocation, &alloc_width, &alloc_height); - - /* There's no point in trying to adjust a zero-sized actor */ - if (alloc_width == 0.f && alloc_height == 0.f) - return; - - /* we want to hit the cache, so we use the public API */ - req_mode = clutter_actor_get_request_mode (self); - - if (req_mode == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH) - { - clutter_actor_get_preferred_width (self, -1, - &min_width, - &nat_width); - clutter_actor_get_preferred_height (self, alloc_width, - &min_height, - &nat_height); - } - else if (req_mode == CLUTTER_REQUEST_WIDTH_FOR_HEIGHT) - { - clutter_actor_get_preferred_height (self, -1, - &min_height, - &nat_height); - clutter_actor_get_preferred_width (self, alloc_height, - &min_width, - &nat_width); - } - else if (req_mode == CLUTTER_REQUEST_CONTENT_SIZE) - { - min_width = min_height = 0; - nat_width = nat_height = 0; - - if (self->priv->content != NULL) - clutter_content_get_preferred_size (self->priv->content, &nat_width, &nat_height); - } - -#ifdef CLUTTER_ENABLE_DEBUG - /* warn about underallocations */ - if (_clutter_diagnostic_enabled () && - (floorf (min_width - alloc_width) > 0 || - floorf (min_height - alloc_height) > 0)) - { - ClutterActor *parent = clutter_actor_get_parent (self); - - /* the only actors that are allowed to be underallocated are the Stage, - * as it doesn't have an implicit size, and Actors that specifically - * told us that they want to opt-out from layout control mechanisms - * through the NO_LAYOUT escape hatch. - */ - if (parent != NULL && - !(self->flags & CLUTTER_ACTOR_NO_LAYOUT) != 0) - { - g_warning (G_STRLOC ": The actor '%s' is getting an allocation " - "of %.2f x %.2f from its parent actor '%s', but its " - "requested minimum size is of %.2f x %.2f", - _clutter_actor_get_debug_name (self), - alloc_width, alloc_height, - _clutter_actor_get_debug_name (parent), - min_width, min_height); - } - } -#endif - - clutter_actor_adjust_width (self, - &min_width, - &nat_width, - &adj_allocation.x1, - &adj_allocation.x2); - - clutter_actor_adjust_height (self, - &min_height, - &nat_height, - &adj_allocation.y1, - &adj_allocation.y2); - - /* we maintain the invariant that an allocation cannot be adjusted - * to be outside the parent-given box - */ - if (adj_allocation.x1 < allocation->x1 || - adj_allocation.y1 < allocation->y1 || - adj_allocation.x2 > allocation->x2 || - adj_allocation.y2 > allocation->y2) - { - g_warning (G_STRLOC ": The actor '%s' tried to adjust its allocation " - "to { %.2f, %.2f, %.2f, %.2f }, which is outside of its " - "original allocation of { %.2f, %.2f, %.2f, %.2f }", - _clutter_actor_get_debug_name (self), - adj_allocation.x1, adj_allocation.y1, - adj_allocation.x2 - adj_allocation.x1, - adj_allocation.y2 - adj_allocation.y1, - allocation->x1, allocation->y1, - allocation->x2 - allocation->x1, - allocation->y2 - allocation->y1); - return; - } - - *allocation = adj_allocation; -} - -static void -clutter_actor_allocate_internal (ClutterActor *self, - const ClutterActorBox *allocation) -{ - ClutterActorClass *klass; - - CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_RELAYOUT); - - CLUTTER_NOTE (LAYOUT, "Calling %s::allocate()", - _clutter_actor_get_debug_name (self)); - - klass = CLUTTER_ACTOR_GET_CLASS (self); - klass->allocate (self, allocation); - - CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_RELAYOUT); - - /* Caller should call clutter_actor_queue_redraw() if needed - * for that particular case. - */ -} - -/** - * clutter_actor_allocate: - * @self: A #ClutterActor - * @box: new allocation of the actor, in parent-relative coordinates - * - * Assigns the size of a #ClutterActor from the given @box. - * - * This function should only be called on the children of an actor when - * overriding the [vfunc@Clutter.Actor.allocate] virtual function. - * - * This function will adjust the stored allocation to take into account - * the alignment flags set in the [property@Clutter.Actor:x-align] and - * [property@Clutter.Actor:y-align] properties, as well as the margin values set in - * the[property@Clutter.Actor:margin-top], [property@Clutter.Actor:margin-right], - * [property@Clutter.Actor:margin-bottom], and - * [property@Clutter.Actor:margin-left] properties. - * - * This function will respect the easing state of the #ClutterActor and - * interpolate between the current allocation and the new one if the - * easing state duration is a positive value. - * - * Actors can know from their allocation box whether they have moved - * with respect to their parent actor. The @flags parameter describes - * additional information about the allocation, for instance whether - * the parent has moved with respect to the stage, for example because - * a grandparent's origin has moved. - */ -void -clutter_actor_allocate (ClutterActor *self, - const ClutterActorBox *box) -{ - ClutterActorBox old_allocation, real_allocation; - gboolean origin_changed, size_changed; - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - if (G_UNLIKELY (_clutter_actor_get_stage_internal (self) == NULL)) - { - g_warning ("Spurious clutter_actor_allocate called for actor %p/%s " - "which isn't a descendent of the stage!\n", - self, _clutter_actor_get_debug_name (self)); - return; - } - - priv = self->priv; - - if (!CLUTTER_ACTOR_IS_TOPLEVEL (self) && - !clutter_actor_is_mapped (self) && - !clutter_actor_has_mapped_clones (self)) - return; - -#ifdef HAVE_PROFILER - COGL_TRACE_SCOPED_ANCHOR (ClutterActorAllocate); - - if (G_UNLIKELY (clutter_debug_flags & CLUTTER_DEBUG_DETAILED_TRACE)) - { - COGL_TRACE_BEGIN_ANCHORED (ClutterActorAllocate, - "Clutter::Actor::allocate()"); - COGL_TRACE_DESCRIBE (ClutterActorAllocate, - _clutter_actor_get_debug_name (self)); - } -#endif - - old_allocation = priv->allocation; - real_allocation = *box; - - g_return_if_fail (!isnan (real_allocation.x1) && - !isnan (real_allocation.x2) && - !isnan (real_allocation.y1) && - !isnan (real_allocation.y2)); - - /* constraints are allowed to modify the allocation only here; we do - * this prior to all the other checks so that we can bail out if the - * allocation did not change - */ - clutter_actor_update_constraints (self, &real_allocation); - - /* adjust the allocation depending on the align/margin properties */ - clutter_actor_adjust_allocation (self, &real_allocation); - - if (real_allocation.x2 < real_allocation.x1 || - real_allocation.y2 < real_allocation.y1) - { - g_warning (G_STRLOC ": Actor '%s' tried to allocate a size of %.2f x %.2f", - _clutter_actor_get_debug_name (self), - real_allocation.x2 - real_allocation.x1, - real_allocation.y2 - real_allocation.y1); - } - - /* we allow 0-sized actors, but not negative-sized ones */ - real_allocation.x2 = MAX (real_allocation.x2, real_allocation.x1); - real_allocation.y2 = MAX (real_allocation.y2, real_allocation.y1); - - origin_changed = (real_allocation.x1 != old_allocation.x1 || - real_allocation.y1 != old_allocation.y1); - - size_changed = (real_allocation.x2 != old_allocation.x2 || - real_allocation.y2 != old_allocation.y2); - - /* When needs_allocation is set but we didn't move nor resize, we still - * want to call the allocate() vfunc because a child probably called - * queue_relayout() and needs a new allocation. - * - * In case needs_allocation isn't set and we didn't move nor resize, we - * can safely stop allocating. - */ - if (!priv->needs_allocation && !origin_changed && !size_changed) - { - CLUTTER_NOTE (LAYOUT, "No allocation needed"); - return; - } - - if (!origin_changed && !size_changed) - { - /* If the actor didn't move but needs_allocation is set, we just - * need to allocate the children (see comment above) */ - clutter_actor_allocate_internal (self, &real_allocation); - return; - } - - if (_clutter_actor_create_transition (self, obj_props[PROP_ALLOCATION], - &priv->allocation, - &real_allocation)) - clutter_actor_allocate_internal (self, &priv->allocation); -} - -/** - * clutter_actor_set_allocation: - * @self: a #ClutterActor - * @box: a #ClutterActorBox - * - * Stores the allocation of @self as defined by @box. - * - * This function can only be called from within the implementation of - * the [vfunc@Clutter.Actor.allocate] virtual function. - * - * The allocation @box should have been adjusted to take into account - * constraints, alignment, and margin properties. - * - * This function should only be used by subclasses of #ClutterActor - * that wish to store their allocation but cannot chain up to the - * parent's implementation; the default implementation of the - * [vfunc@Clutter.Actor.allocate] virtual function will call this - * function. - */ -void -clutter_actor_set_allocation (ClutterActor *self, - const ClutterActorBox *box) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (box != NULL); - - if (G_UNLIKELY (!CLUTTER_ACTOR_IN_RELAYOUT (self))) - { - g_critical (G_STRLOC ": The clutter_actor_set_allocation() function " - "can only be called from within the implementation of " - "the ClutterActor::allocate() virtual function."); - return; - } - - g_object_freeze_notify (G_OBJECT (self)); - - clutter_actor_set_allocation_internal (self, box); - - g_object_thaw_notify (G_OBJECT (self)); -} - -/** - * clutter_actor_set_position: - * @self: A #ClutterActor - * @x: New left position of actor in pixels. - * @y: New top position of actor in pixels. - * - * Sets the actor's fixed position in pixels relative to any parent - * actor. - * - * If a layout manager is in use, this position will override the - * layout manager and force a fixed position. - */ -void -clutter_actor_set_position (ClutterActor *self, - gfloat x, - gfloat y) -{ - graphene_point_t new_position; - graphene_point_t cur_position; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - graphene_point_init (&new_position, x, y); - - cur_position.x = clutter_actor_get_x (self); - cur_position.y = clutter_actor_get_y (self); - - if (!graphene_point_equal (&cur_position, &new_position)) - _clutter_actor_create_transition (self, obj_props[PROP_POSITION], - &cur_position, - &new_position); -} - -/** - * clutter_actor_get_fixed_position_set: - * @self: A #ClutterActor - * - * Checks whether an actor has a fixed position set (and will thus be - * unaffected by any layout manager). - * - * Return value: %TRUE if the fixed position is set on the actor - */ -gboolean -clutter_actor_get_fixed_position_set (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - return self->priv->position_set; -} - -/** - * clutter_actor_set_fixed_position_set: - * @self: A #ClutterActor - * @is_set: whether to use fixed position - * - * Sets whether an actor has a fixed position set (and will thus be - * unaffected by any layout manager). - */ -void -clutter_actor_set_fixed_position_set (ClutterActor *self, - gboolean is_set) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (self->priv->position_set == (is_set != FALSE)) - return; - - if (!is_set) - { - ClutterLayoutInfo *info; - - /* Ensure we set back the default fixed position of 0,0 so that setting - just one of x/y always atomically gets 0 for the other */ - info = _clutter_actor_peek_layout_info (self); - if (info != NULL) - { - info->fixed_pos.x = 0; - info->fixed_pos.y = 0; - } - } - - self->priv->position_set = is_set != FALSE; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_FIXED_POSITION_SET]); - - clutter_actor_queue_relayout (self); -} - -/** - * clutter_actor_move_by: - * @self: A #ClutterActor - * @dx: Distance to move Actor on X axis. - * @dy: Distance to move Actor on Y axis. - * - * Moves an actor by the specified distance relative to its current - * position in pixels. - * - * This function modifies the fixed position of an actor and thus removes - * it from any layout management. Another way to move an actor is with an - * additional translation, using clutter_actor_set_translation(). - */ -void -clutter_actor_move_by (ClutterActor *self, - gfloat dx, - gfloat dy) -{ - const ClutterLayoutInfo *info; - gfloat x, y; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_layout_info_or_defaults (self); - x = info->fixed_pos.x; - y = info->fixed_pos.y; - - clutter_actor_set_position (self, x + dx, y + dy); -} - -static void -clutter_actor_set_min_width (ClutterActor *self, - gfloat min_width) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActorBox old = { 0, }; - ClutterLayoutInfo *info; - - if (CLUTTER_ACTOR_IS_TOPLEVEL (self)) - { - g_warning ("Can't set the minimal width of a stage"); - return; - } - - info = _clutter_actor_get_layout_info (self); - - if (priv->min_width_set && min_width == info->minimum.width) - return; - - g_object_freeze_notify (G_OBJECT (self)); - - clutter_actor_store_old_geometry (self, &old); - - info->minimum.width = min_width; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_MIN_WIDTH]); - clutter_actor_set_min_width_set (self, TRUE); - - clutter_actor_notify_if_geometry_changed (self, &old); - - g_object_thaw_notify (G_OBJECT (self)); - - clutter_actor_queue_relayout (self); -} - -static void -clutter_actor_set_min_height (ClutterActor *self, - gfloat min_height) - -{ - ClutterActorPrivate *priv = self->priv; - ClutterActorBox old = { 0, }; - ClutterLayoutInfo *info; - - if (CLUTTER_ACTOR_IS_TOPLEVEL (self)) - { - g_warning ("Can't set the minimal height of a stage"); - return; - } - - info = _clutter_actor_get_layout_info (self); - - if (priv->min_height_set && min_height == info->minimum.height) - return; - - g_object_freeze_notify (G_OBJECT (self)); - - clutter_actor_store_old_geometry (self, &old); - - info->minimum.height = min_height; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_MIN_HEIGHT]); - clutter_actor_set_min_height_set (self, TRUE); - - clutter_actor_notify_if_geometry_changed (self, &old); - - g_object_thaw_notify (G_OBJECT (self)); - - clutter_actor_queue_relayout (self); -} - -static void -clutter_actor_set_natural_width (ClutterActor *self, - gfloat natural_width) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActorBox old = { 0, }; - ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info (self); - - if (priv->natural_width_set && natural_width == info->natural.width) - return; - - g_object_freeze_notify (G_OBJECT (self)); - - clutter_actor_store_old_geometry (self, &old); - - info->natural.width = natural_width; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_NATURAL_WIDTH]); - clutter_actor_set_natural_width_set (self, TRUE); - - clutter_actor_notify_if_geometry_changed (self, &old); - - g_object_thaw_notify (G_OBJECT (self)); - - clutter_actor_queue_relayout (self); -} - -static void -clutter_actor_set_natural_height (ClutterActor *self, - gfloat natural_height) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActorBox old = { 0, }; - ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info (self); - - if (priv->natural_height_set && natural_height == info->natural.height) - return; - - g_object_freeze_notify (G_OBJECT (self)); - - clutter_actor_store_old_geometry (self, &old); - - info->natural.height = natural_height; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_NATURAL_HEIGHT]); - clutter_actor_set_natural_height_set (self, TRUE); - - clutter_actor_notify_if_geometry_changed (self, &old); - - g_object_thaw_notify (G_OBJECT (self)); - - clutter_actor_queue_relayout (self); -} - -static void -clutter_actor_set_min_width_set (ClutterActor *self, - gboolean use_min_width) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActorBox old = { 0, }; - - if (priv->min_width_set == (use_min_width != FALSE)) - return; - - clutter_actor_store_old_geometry (self, &old); - - priv->min_width_set = use_min_width != FALSE; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_MIN_WIDTH_SET]); - - clutter_actor_notify_if_geometry_changed (self, &old); - - clutter_actor_queue_relayout (self); -} - -static void -clutter_actor_set_min_height_set (ClutterActor *self, - gboolean use_min_height) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActorBox old = { 0, }; - - if (priv->min_height_set == (use_min_height != FALSE)) - return; - - clutter_actor_store_old_geometry (self, &old); - - priv->min_height_set = use_min_height != FALSE; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_MIN_HEIGHT_SET]); - - clutter_actor_notify_if_geometry_changed (self, &old); - - clutter_actor_queue_relayout (self); -} - -static void -clutter_actor_set_natural_width_set (ClutterActor *self, - gboolean use_natural_width) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActorBox old = { 0, }; - - if (priv->natural_width_set == (use_natural_width != FALSE)) - return; - - clutter_actor_store_old_geometry (self, &old); - - priv->natural_width_set = use_natural_width != FALSE; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_NATURAL_WIDTH_SET]); - - clutter_actor_notify_if_geometry_changed (self, &old); - - clutter_actor_queue_relayout (self); -} - -static void -clutter_actor_set_natural_height_set (ClutterActor *self, - gboolean use_natural_height) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActorBox old = { 0, }; - - if (priv->natural_height_set == (use_natural_height != FALSE)) - return; - - clutter_actor_store_old_geometry (self, &old); - - priv->natural_height_set = use_natural_height != FALSE; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_NATURAL_HEIGHT_SET]); - - clutter_actor_notify_if_geometry_changed (self, &old); - - clutter_actor_queue_relayout (self); -} - -/** - * clutter_actor_set_request_mode: - * @self: a #ClutterActor - * @mode: the request mode - * - * Sets the geometry request mode of @self. - * - * The @mode determines the order for invoking - [method@Clutter.Actor.get_preferred_width] and - [method@Clutter.Actor.get_preferred_height] - */ -void -clutter_actor_set_request_mode (ClutterActor *self, - ClutterRequestMode mode) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - priv = self->priv; - - if (priv->request_mode == mode) - return; - - priv->request_mode = mode; - - priv->needs_width_request = TRUE; - priv->needs_height_request = TRUE; - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_REQUEST_MODE]); - - clutter_actor_queue_relayout (self); -} - -/** - * clutter_actor_get_request_mode: - * @self: a #ClutterActor - * - * Retrieves the geometry request mode of @self - * - * Return value: the request mode for the actor - */ -ClutterRequestMode -clutter_actor_get_request_mode (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), - CLUTTER_REQUEST_HEIGHT_FOR_WIDTH); - - return self->priv->request_mode; -} - -/* variant of set_width() without checks and without notification - * freeze+thaw, for internal usage only - */ -static inline void -clutter_actor_set_width_internal (ClutterActor *self, - gfloat width) -{ - if (width >= 0) - { - /* the Stage will use the :min-width to control the minimum - * width to be resized to, so we should not be setting it - * along with the :natural-width - */ - if (!CLUTTER_ACTOR_IS_TOPLEVEL (self)) - clutter_actor_set_min_width (self, width); - - clutter_actor_set_natural_width (self, width); - } - else - { - /* we only unset the :natural-width for the Stage */ - if (!CLUTTER_ACTOR_IS_TOPLEVEL (self)) - clutter_actor_set_min_width_set (self, FALSE); - - clutter_actor_set_natural_width_set (self, FALSE); - } -} - -/* variant of set_height() without checks and without notification - * freeze+thaw, for internal usage only - */ -static inline void -clutter_actor_set_height_internal (ClutterActor *self, - gfloat height) -{ - if (height >= 0) - { - /* see the comment above in set_width_internal() */ - if (!CLUTTER_ACTOR_IS_TOPLEVEL (self)) - clutter_actor_set_min_height (self, height); - - clutter_actor_set_natural_height (self, height); - } - else - { - /* see the comment above in set_width_internal() */ - if (!CLUTTER_ACTOR_IS_TOPLEVEL (self)) - clutter_actor_set_min_height_set (self, FALSE); - - clutter_actor_set_natural_height_set (self, FALSE); - } -} - -static void -clutter_actor_set_size_internal (ClutterActor *self, - const graphene_size_t *size) -{ - if (size != NULL) - { - clutter_actor_set_width_internal (self, size->width); - clutter_actor_set_height_internal (self, size->height); - } - else - { - clutter_actor_set_width_internal (self, -1); - clutter_actor_set_height_internal (self, -1); - } -} - -/** - * clutter_actor_set_size: - * @self: A #ClutterActor - * @width: New width of actor in pixels, or -1 - * @height: New height of actor in pixels, or -1 - * - * Sets the actor's size request in pixels. This overrides any - * "normal" size request the actor would have. For example - * a text actor might normally request the size of the text; - * this function would force a specific size instead. - * - * If @width and/or @height are -1 the actor will use its - * "normal" size request instead of overriding it, i.e. - * you can "unset" the size with -1. - * - * This function sets or unsets both the minimum and natural size. - */ -void -clutter_actor_set_size (ClutterActor *self, - gfloat width, - gfloat height) -{ - graphene_size_t new_size; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - graphene_size_init (&new_size, width, height); - - /* minor optimization: if we don't have a duration then we can - * skip the get_size() below, to avoid the chance of going through - * get_preferred_width() and get_preferred_height() just to jump to - * a new desired size - */ - if (clutter_actor_get_easing_duration (self) == 0) - { - g_object_freeze_notify (G_OBJECT (self)); - - clutter_actor_set_size_internal (self, &new_size); - - g_object_thaw_notify (G_OBJECT (self)); - - return; - } - else - { - graphene_size_t cur_size; - - graphene_size_init (&cur_size, - clutter_actor_get_width (self), - clutter_actor_get_height (self)); - - _clutter_actor_create_transition (self, - obj_props[PROP_SIZE], - &cur_size, - &new_size); - } -} - -/** - * clutter_actor_get_size: - * @self: A #ClutterActor - * @width: (out) (optional): return location for the width, or %NULL. - * @height: (out) (optional): return location for the height, or %NULL. - * - * This function tries to "do what you mean" and return - * the size an actor will have. If the actor has a valid - * allocation, the allocation will be returned; otherwise, - * the actors natural size request will be returned. - * - * If you care whether you get the request vs. the allocation, you - * should probably call a different function like - * [method@Clutter.Actor.get_allocation_box] or - * [method@Clutter.Actor.get_preferred_width]. - */ -void -clutter_actor_get_size (ClutterActor *self, - gfloat *width, - gfloat *height) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (width) - *width = clutter_actor_get_width (self); - - if (height) - *height = clutter_actor_get_height (self); -} - -/** - * clutter_actor_get_position: - * @self: a #ClutterActor - * @x: (out) (optional): return location for the X coordinate, or %NULL - * @y: (out) (optional): return location for the Y coordinate, or %NULL - * - * This function tries to "do what you mean" and tell you where the - * actor is, prior to any transformations. Retrieves the fixed - * position of an actor in pixels, if one has been set; otherwise, if - * the allocation is valid, returns the actor's allocated position; - * otherwise, returns 0,0. - * - * The returned position is in pixels. - */ -void -clutter_actor_get_position (ClutterActor *self, - gfloat *x, - gfloat *y) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (x) - *x = clutter_actor_get_x (self); - - if (y) - *y = clutter_actor_get_y (self); -} - -/** - * clutter_actor_get_fixed_position: - * @self: a #ClutterActor - * @x: (out) (optional): return location for the X coordinate, or %NULL - * @y: (out) (optional): return location for the Y coordinate, or %NULL - * - * This function gets the fixed position of the actor, if set. If there - * is no fixed position set, this function returns %FALSE and doesn't set - * the x and y coordinates. - * - * Returns: %TRUE if the fixed position is set, %FALSE if it isn't - */ -gboolean -clutter_actor_get_fixed_position (ClutterActor *self, - float *x, - float *y) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - if (self->priv->position_set) - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (self); - - if (x) - *x = info->fixed_pos.x; - - if (y) - *y = info->fixed_pos.y; - - return TRUE; - } - - return FALSE; -} - -/** - * clutter_actor_get_transformed_extents: - * @self: A #ClutterActor - * @rect: (out): return location for the transformed bounding rect - * - * Gets the transformed bounding rect of an actor, in pixels relative to the stage. - */ -void -clutter_actor_get_transformed_extents (ClutterActor *self, - graphene_rect_t *rect) -{ - graphene_quad_t quad; - graphene_point3d_t v[4]; - ClutterActorBox box; - - box.x1 = 0; - box.y1 = 0; - box.x2 = clutter_actor_box_get_width (&self->priv->allocation); - box.y2 = clutter_actor_box_get_height (&self->priv->allocation); - if (_clutter_actor_transform_and_project_box (self, &box, v)) - { - graphene_quad_init (&quad, - (graphene_point_t *) &v[0], - (graphene_point_t *) &v[1], - (graphene_point_t *) &v[2], - (graphene_point_t *) &v[3]); - - if (rect) - graphene_quad_bounds (&quad, rect); - } -} - -/** - * clutter_actor_get_transformed_position: - * @self: A #ClutterActor - * @x: (out) (optional): return location for the X coordinate, or %NULL - * @y: (out) (optional): return location for the Y coordinate, or %NULL - * - * Gets the absolute position of an actor, in pixels relative to the stage. - */ -void -clutter_actor_get_transformed_position (ClutterActor *self, - gfloat *x, - gfloat *y) -{ - graphene_point3d_t v1; - graphene_point3d_t v2; - - v1.x = v1.y = v1.z = 0; - - if (!_clutter_actor_fully_transform_vertices (self, &v1, &v2, 1)) - return; - - if (x) - *x = v2.x; - - if (y) - *y = v2.y; -} - -/** - * clutter_actor_get_transformed_size: - * @self: A #ClutterActor - * @width: (out) (optional): return location for the width, or %NULL - * @height: (out) (optional): return location for the height, or %NULL - * - * Gets the absolute size of an actor in pixels, taking into account the - * scaling factors. - * - * If the actor has a valid allocation, the allocated size will be used. - * If the actor has not a valid allocation then the preferred size will - * be transformed and returned. - * - * If you want the transformed allocation, see - * [method@Clutter.Actor.get_abs_allocation_vertices] instead. - * - * When the actor (or one of its ancestors) is rotated around the - * X or Y axis, it no longer appears as on the stage as a rectangle, but - * as a generic quadrangle; in that case this function returns the size - * of the smallest rectangle that encapsulates the entire quad. Please - * note that in this case no assumptions can be made about the relative - * position of this envelope to the absolute position of the actor, as - * returned by [method@Clutter.Actor.get_transformed_position]; if you need this - * information, you need to use [method@Clutter.Actor.get_abs_allocation_vertices] - * to get the coords of the actual quadrangle. - */ -void -clutter_actor_get_transformed_size (ClutterActor *self, - gfloat *width, - gfloat *height) -{ - ClutterActorPrivate *priv; - graphene_point3d_t v[4]; - gfloat x_min, x_max, y_min, y_max; - gint i; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - priv = self->priv; - - /* if the actor hasn't been allocated yet, get the preferred - * size and transform that - */ - if (priv->needs_allocation) - { - gfloat natural_width, natural_height; - ClutterActorBox box; - - /* Make a fake allocation to transform. - * - * NB: _clutter_actor_transform_and_project_box expects a box in - * the actor's coordinate space... */ - - box.x1 = 0; - box.y1 = 0; - - natural_width = natural_height = 0; - clutter_actor_get_preferred_size (self, NULL, NULL, - &natural_width, - &natural_height); - - box.x2 = natural_width; - box.y2 = natural_height; - - _clutter_actor_transform_and_project_box (self, &box, v); - } - else - clutter_actor_get_abs_allocation_vertices (self, v); - - x_min = x_max = v[0].x; - y_min = y_max = v[0].y; - - for (i = 1; i < G_N_ELEMENTS (v); ++i) - { - if (v[i].x < x_min) - x_min = v[i].x; - - if (v[i].x > x_max) - x_max = v[i].x; - - if (v[i].y < y_min) - y_min = v[i].y; - - if (v[i].y > y_max) - y_max = v[i].y; - } - - if (width) - *width = x_max - x_min; - - if (height) - *height = y_max - y_min; -} - -/** - * clutter_actor_get_width: - * @self: A #ClutterActor - * - * Retrieves the width of a #ClutterActor. - * - * If the actor has a valid allocation, this function will return the - * width of the allocated area given to the actor. - * - * If the actor does not have a valid allocation, this function will - * return the actor's natural width, that is the preferred width of - * the actor. - * - * If you care whether you get the preferred width or the width that - * has been assigned to the actor, you should probably call a different - * function like [method@Clutter.Actor.get_allocation_box] to retrieve the - * allocated size [method@Clutter.Actor.get_preferred_width] to retrieve the - * preferred width. - * - * If an actor has a fixed width, for instance a width that has been - * assigned using [method@Clutter.Actor.set_width], the width returned will - * be the same value. - * - * Return value: the width of the actor, in pixels - */ -gfloat -clutter_actor_get_width (ClutterActor *self) -{ - ClutterActorPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0); - - priv = self->priv; - - if (priv->needs_allocation) - { - gfloat natural_width = 0; - - if (priv->request_mode == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH) - { - clutter_actor_get_preferred_width (self, -1, NULL, &natural_width); - } - else if (priv->request_mode == CLUTTER_REQUEST_WIDTH_FOR_HEIGHT) - { - gfloat natural_height = 0; - - clutter_actor_get_preferred_height (self, -1, NULL, &natural_height); - clutter_actor_get_preferred_width (self, natural_height, - NULL, - &natural_width); - } - else if (priv->request_mode == CLUTTER_REQUEST_CONTENT_SIZE && priv->content != NULL) - { - clutter_content_get_preferred_size (priv->content, &natural_width, NULL); - } - - return natural_width; - } - else - return priv->allocation.x2 - priv->allocation.x1; -} - -/** - * clutter_actor_get_height: - * @self: A #ClutterActor - * - * Retrieves the height of a #ClutterActor. - * - * If the actor has a valid allocation, this function will return the - * height of the allocated area given to the actor. - * - * If the actor does not have a valid allocation, this function will - * return the actor's natural height, that is the preferred height of - * the actor. - * - * If you care whether you get the preferred height or the height that - * has been assigned to the actor, you should probably call a different - * function like [method@Clutter.Actor.get_allocation_box] to retrieve the - * allocated size [method@Clutter.Actor.get_preferred_height] to retrieve the - * preferred height. - * - * If an actor has a fixed height, for instance a height that has been - * assigned using [method@Clutter.Actor.set_height], the height returned will - * be the same value. - * - * Return value: the height of the actor, in pixels - */ -gfloat -clutter_actor_get_height (ClutterActor *self) -{ - ClutterActorPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0); - - priv = self->priv; - - if (priv->needs_allocation) - { - gfloat natural_height = 0; - - if (priv->request_mode == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH) - { - gfloat natural_width = 0; - - clutter_actor_get_preferred_width (self, -1, NULL, &natural_width); - clutter_actor_get_preferred_height (self, natural_width, - NULL, &natural_height); - } - else if (priv->request_mode == CLUTTER_REQUEST_WIDTH_FOR_HEIGHT) - { - clutter_actor_get_preferred_height (self, -1, NULL, &natural_height); - } - else if (priv->request_mode == CLUTTER_REQUEST_CONTENT_SIZE && priv->content != NULL) - { - clutter_content_get_preferred_size (priv->content, NULL, &natural_height); - } - - return natural_height; - } - else - return priv->allocation.y2 - priv->allocation.y1; -} - -/** - * clutter_actor_set_width: - * @self: A #ClutterActor - * @width: Requested new width for the actor, in pixels, or -1 - * - * Forces a width on an actor, causing the actor's preferred width - * and height (if any) to be ignored. - * - * If @width is -1 the actor will use its preferred width request - * instead of overriding it, i.e. you can "unset" the width with -1. - * - * This function sets both the minimum and natural size of the actor. - */ -void -clutter_actor_set_width (ClutterActor *self, - gfloat width) -{ - float cur_size; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - /* minor optimization: if we don't have a duration - * then we can skip the get_width() below, to avoid - * the chance of going through get_preferred_width() - * just to jump to a new desired width. - */ - if (clutter_actor_get_easing_duration (self) == 0) - { - g_object_freeze_notify (G_OBJECT (self)); - - clutter_actor_set_width_internal (self, width); - - g_object_thaw_notify (G_OBJECT (self)); - - return; - } - else - cur_size = clutter_actor_get_width (self); - - _clutter_actor_create_transition (self, - obj_props[PROP_WIDTH], - cur_size, - width); -} - -/** - * clutter_actor_set_height: - * @self: A #ClutterActor - * @height: Requested new height for the actor, in pixels, or -1 - * - * Forces a height on an actor, causing the actor's preferred width - * and height (if any) to be ignored. - * - * If @height is -1 the actor will use its preferred height instead of - * overriding it, i.e. you can "unset" the height with -1. - * - * This function sets both the minimum and natural size of the actor. - */ -void -clutter_actor_set_height (ClutterActor *self, - gfloat height) -{ - float cur_size; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - /* see the comment [method@Clutter.Actor.or_set_width] above */ - if (clutter_actor_get_easing_duration (self) == 0) - { - g_object_freeze_notify (G_OBJECT (self)); - - clutter_actor_set_height_internal (self, height); - - g_object_thaw_notify (G_OBJECT (self)); - - return; - } - else - cur_size = clutter_actor_get_height (self); - - _clutter_actor_create_transition (self, - obj_props[PROP_HEIGHT], - cur_size, - height); -} - -static inline void -clutter_actor_set_x_internal (ClutterActor *self, - float x) -{ - ClutterActorPrivate *priv = self->priv; - ClutterLayoutInfo *linfo; - ClutterActorBox old = { 0, }; - - linfo = _clutter_actor_get_layout_info (self); - - if (priv->position_set && linfo->fixed_pos.x == x) - return; - - clutter_actor_store_old_geometry (self, &old); - - linfo->fixed_pos.x = x; - clutter_actor_set_fixed_position_set (self, TRUE); - - clutter_actor_notify_if_geometry_changed (self, &old); - - clutter_actor_queue_relayout (self); -} - -static inline void -clutter_actor_set_y_internal (ClutterActor *self, - float y) -{ - ClutterActorPrivate *priv = self->priv; - ClutterLayoutInfo *linfo; - ClutterActorBox old = { 0, }; - - linfo = _clutter_actor_get_layout_info (self); - - if (priv->position_set && linfo->fixed_pos.y == y) - return; - - clutter_actor_store_old_geometry (self, &old); - - linfo->fixed_pos.y = y; - clutter_actor_set_fixed_position_set (self, TRUE); - - clutter_actor_notify_if_geometry_changed (self, &old); - - clutter_actor_queue_relayout (self); -} - -static void -clutter_actor_set_position_internal (ClutterActor *self, - const graphene_point_t *position) -{ - ClutterActorPrivate *priv = self->priv; - ClutterLayoutInfo *linfo; - ClutterActorBox old = { 0, }; - - linfo = _clutter_actor_get_layout_info (self); - - if (priv->position_set && - graphene_point_equal (position, &linfo->fixed_pos)) - return; - - clutter_actor_store_old_geometry (self, &old); - - if (position != NULL) - { - linfo->fixed_pos = *position; - clutter_actor_set_fixed_position_set (self, TRUE); - } - else - clutter_actor_set_fixed_position_set (self, FALSE); - - clutter_actor_notify_if_geometry_changed (self, &old); - - clutter_actor_queue_relayout (self); -} - -/** - * clutter_actor_set_x: - * @self: a #ClutterActor - * @x: the actor's position on the X axis - * - * Sets the actor's X coordinate, relative to its parent, in pixels. - * - * Overrides any layout manager and forces a fixed position for - * the actor. - * - * The [property@Clutter.Actor:x] property is animatable. - */ -void -clutter_actor_set_x (ClutterActor *self, - gfloat x) -{ - float cur_position = clutter_actor_get_x (self); - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - _clutter_actor_create_transition (self, obj_props[PROP_X], - cur_position, - x); -} - -/** - * clutter_actor_set_y: - * @self: a #ClutterActor - * @y: the actor's position on the Y axis - * - * Sets the actor's Y coordinate, relative to its parent, in pixels.# - * - * Overrides any layout manager and forces a fixed position for - * the actor. - * - * The [property@Clutter.Actor:y] property is animatable. - */ -void -clutter_actor_set_y (ClutterActor *self, - gfloat y) -{ - float cur_position = clutter_actor_get_y (self); - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - _clutter_actor_create_transition (self, obj_props[PROP_Y], - cur_position, - y); -} - -/** - * clutter_actor_get_x: - * @self: A #ClutterActor - * - * Retrieves the X coordinate of a #ClutterActor. - * - * This function tries to "do what you mean", by returning the - * correct value depending on the actor's state. - * - * If the actor has a valid allocation, this function will return - * the X coordinate of the origin of the allocation box. - * - * If the actor has any fixed coordinate set using [method@Clutter.Actor.set_x], - * [method@Clutter.Actor.set_position], this function will return that coordinate. - * - * If both the allocation and a fixed position are missing, this function - * will return 0. - * - * Return value: the X coordinate, in pixels, ignoring any - * transformation (i.e. scaling, rotation) - */ -gfloat -clutter_actor_get_x (ClutterActor *self) -{ - ClutterActorPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0); - - priv = self->priv; - - if (priv->needs_allocation) - { - if (priv->position_set) - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (self); - - return info->fixed_pos.x; - } - else - return 0; - } - else - return priv->allocation.x1; -} - -/** - * clutter_actor_get_y: - * @self: A #ClutterActor - * - * Retrieves the Y coordinate of a #ClutterActor. - * - * This function tries to "do what you mean", by returning the - * correct value depending on the actor's state. - * - * If the actor has a valid allocation, this function will return - * the Y coordinate of the origin of the allocation box. - * - * If the actor has any fixed coordinate set using [method@Clutter.Actor.set_y], - * [method@Clutter.Actor.set_position], this function will return that coordinate. - * - * If both the allocation and a fixed position are missing, this function - * will return 0. - * - * Return value: the Y coordinate, in pixels, ignoring any - * transformation (i.e. scaling, rotation) - */ -gfloat -clutter_actor_get_y (ClutterActor *self) -{ - ClutterActorPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0); - - priv = self->priv; - - if (priv->needs_allocation) - { - if (priv->position_set) - { - const ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info_or_defaults (self); - - return info->fixed_pos.y; - } - else - return 0; - } - else - return priv->allocation.y1; -} - -/** - * clutter_actor_set_scale: - * @self: A #ClutterActor - * @scale_x: double factor to scale actor by horizontally. - * @scale_y: double factor to scale actor by vertically. - * - * Scales an actor with the given factors. - * - * The scale transformation is relative the [property@Clutter.Actor:pivot-point]. - * - * The [property@Clutter.Actor:scale-x] and [property@Clutter.Actor:scale-y] - * properties are animatable. - */ -void -clutter_actor_set_scale (ClutterActor *self, - gdouble scale_x, - gdouble scale_y) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - g_object_freeze_notify (G_OBJECT (self)); - - clutter_actor_set_scale_factor (self, CLUTTER_X_AXIS, scale_x); - clutter_actor_set_scale_factor (self, CLUTTER_Y_AXIS, scale_y); - - g_object_thaw_notify (G_OBJECT (self)); -} - -/** - * clutter_actor_set_scale_z: - * @self: a #ClutterActor - * @scale_z: the scaling factor along the Z axis - * - * Scales an actor on the Z axis by the given @scale_z factor. - * - * The scale transformation is relative the the [property@Clutter.Actor:pivot-point]. - * - * The [property@Clutter.Actor:scale-z] property is animatable. - */ -void -clutter_actor_set_scale_z (ClutterActor *self, - gdouble scale_z) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - clutter_actor_set_scale_factor (self, CLUTTER_Z_AXIS, scale_z); -} - -/** - * clutter_actor_get_scale: - * @self: A #ClutterActor - * @scale_x: (out) (optional): Location to store horizontal - * scale factor, or %NULL. - * @scale_y: (out) (optional): Location to store vertical - * scale factor, or %NULL. - * - * Retrieves an actors scale factors. - */ -void -clutter_actor_get_scale (ClutterActor *self, - gdouble *scale_x, - gdouble *scale_y) -{ - const ClutterTransformInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_transform_info_or_defaults (self); - - if (scale_x) - *scale_x = info->scale_x; - - if (scale_y) - *scale_y = info->scale_y; -} - -/** - * clutter_actor_get_scale_z: - * @self: A #ClutterActor - * - * Retrieves the scaling factor along the Z axis, as set using - * [method@Clutter.Actor.set_scale_z]. - * - * Return value: the scaling factor along the Z axis - */ -gdouble -clutter_actor_get_scale_z (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 1.0); - - return _clutter_actor_get_transform_info_or_defaults (self)->scale_z; -} - -static inline void -clutter_actor_set_opacity_internal (ClutterActor *self, - guint8 opacity) -{ - ClutterActorPrivate *priv = self->priv; - - if (priv->opacity != opacity) - { - priv->opacity = opacity; - - /* Queue a redraw from the flatten effect so that it can use - its cached image if available instead of having to redraw the - actual actor. If it doesn't end up using the FBO then the - effect is still able to continue the paint anyway. If there - is no flatten effect yet then this is equivalent to queueing - a full redraw */ - _clutter_actor_queue_redraw_full (self, - NULL, /* clip */ - priv->flatten_effect); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_OPACITY]); - } -} - -/** - * clutter_actor_set_opacity: - * @self: A #ClutterActor - * @opacity: New opacity value for the actor. - * - * Sets the actor's opacity, with zero being completely transparent and - * 255 (0xff) being fully opaque. - * - * The [property@Clutter.Actor:opacity] property is animatable. - */ -void -clutter_actor_set_opacity (ClutterActor *self, - guint8 opacity) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - _clutter_actor_create_transition (self, obj_props[PROP_OPACITY], - self->priv->opacity, - opacity); -} - -/* - * clutter_actor_get_paint_opacity_internal: - * @self: a #ClutterActor - * - * Retrieves the absolute opacity of the actor, as it appears on the stage - * - * This function does not do type checks - * - * Return value: the absolute opacity of the actor - */ -static guint8 -clutter_actor_get_paint_opacity_internal (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActor *parent; - - /* override the top-level opacity to always be 255; even in - * case of ClutterStage:use-alpha being TRUE we want the rest - * of the scene to be painted - */ - if (CLUTTER_ACTOR_IS_TOPLEVEL (self)) - return 255; - - if (priv->opacity_override >= 0) - return priv->opacity_override; - - parent = priv->parent; - - /* Factor in the actual actors opacity with parents */ - if (parent != NULL) - { - guint8 opacity = clutter_actor_get_paint_opacity_internal (parent); - - if (opacity != 0xff) - return (opacity * priv->opacity) / 0xff; - } - - return priv->opacity; - -} - -/** - * clutter_actor_get_paint_opacity: - * @self: A #ClutterActor - * - * Retrieves the absolute opacity of the actor, as it appears on the stage. - * - * This function traverses the hierarchy chain and composites the opacity of - * the actor with that of its parents. - * - * This function is intended for subclasses to use in the paint virtual - * function, to paint themselves with the correct opacity. - * - * Return value: The actor opacity value. - */ -guint8 -clutter_actor_get_paint_opacity (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0); - - return clutter_actor_get_paint_opacity_internal (self); -} - -/** - * clutter_actor_get_opacity: - * @self: a #ClutterActor - * - * Retrieves the opacity value of an actor, as set by - * clutter_actor_set_opacity(). - * - * For retrieving the absolute opacity of the actor inside a paint - * virtual function, see clutter_actor_get_paint_opacity(). - * - * Return value: the opacity of the actor - */ -guint8 -clutter_actor_get_opacity (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0); - - return self->priv->opacity; -} - -/** - * clutter_actor_set_offscreen_redirect: - * @self: A #ClutterActor - * @redirect: New offscreen redirect flags for the actor. - * - * Defines the circumstances where the actor should be redirected into - * an offscreen image. The offscreen image is used to flatten the - * actor into a single image while painting for two main reasons. - * Firstly, when the actor is painted a second time without any of its - * contents changing it can simply repaint the cached image without - * descending further down the actor hierarchy. Secondly, it will make - * the opacity look correct even if there are overlapping primitives - * in the actor. - * - * Caching the actor could in some cases be a performance win and in - * some cases be a performance lose so it is important to determine - * which value is right for an actor before modifying this value. For - * example, there is never any reason to flatten an actor that is just - * a single texture (such as a #ClutterTexture) because it is - * effectively already cached in an image so the offscreen would be - * redundant. Also if the actor contains primitives that are far apart - * with a large transparent area in the middle (such as a large - * CluterGroup with a small actor in the top left and a small actor in - * the bottom right) then the cached image will contain the entire - * image of the large area and the paint will waste time blending all - * of the transparent pixels in the middle. - * - * The default method of implementing opacity on a container simply - * forwards on the opacity to all of the children. If the children are - * overlapping then it will appear as if they are two separate glassy - * objects and there will be a break in the color where they - * overlap. By redirecting to an offscreen buffer it will be as if the - * two opaque objects are combined into one and then made transparent - * which is usually what is expected. - * - * The image below demonstrates the difference between redirecting and - * not. The image shows two Clutter groups, each containing a red and - * a green rectangle which overlap. The opacity on the group is set to - * 128 (which is 50%). When the offscreen redirect is not used, the - * red rectangle can be seen through the blue rectangle as if the two - * rectangles were separately transparent. When the redirect is used - * the group as a whole is transparent instead so the red rectangle is - * not visible where they overlap. - * - *
- * Sample of using an offscreen redirect for transparency - * - *
- * - * The default value for this property is 0, so we effectively will - * never redirect an actor offscreen by default. This means that there - * are times that transparent actors may look glassy as described - * above. The reason this is the default is because there is a - * performance trade off between quality and performance here. In many - * cases the default form of glassy opacity looks good enough, but if - * it's not you will need to set the - * %CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY flag to enable - * redirection for opacity. - * - * Custom actors that don't contain any overlapping primitives are - * recommended to override the has_overlaps() virtual to return %FALSE - * for maximum efficiency. - */ -void -clutter_actor_set_offscreen_redirect (ClutterActor *self, - ClutterOffscreenRedirect redirect) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - priv = self->priv; - - if (priv->offscreen_redirect != redirect) - { - priv->offscreen_redirect = redirect; - - /* Queue a redraw from the effect so that it can use its cached - image if available instead of having to redraw the actual - actor. If it doesn't end up using the FBO then the effect is - still able to continue the paint anyway. If there is no - effect then this is equivalent to queuing a full redraw */ - _clutter_actor_queue_redraw_full (self, - NULL, /* clip */ - priv->flatten_effect); - - g_object_notify_by_pspec (G_OBJECT (self), - obj_props[PROP_OFFSCREEN_REDIRECT]); - } -} - -/** - * clutter_actor_get_offscreen_redirect: - * @self: a #ClutterActor - * - * Retrieves whether to redirect the actor to an offscreen buffer, as - * set by clutter_actor_set_offscreen_redirect(). - * - * Return value: the value of the offscreen-redirect property of the actor - */ -ClutterOffscreenRedirect -clutter_actor_get_offscreen_redirect (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0); - - return self->priv->offscreen_redirect; -} - -/** - * clutter_actor_set_name: - * @self: A #ClutterActor - * @name: (nullable): Textual tag to apply to actor - * - * Sets the given name to @self. The name can be used to identify - * a #ClutterActor. - */ -void -clutter_actor_set_name (ClutterActor *self, - const gchar *name) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - g_free (self->priv->name); - self->priv->name = g_strdup (name); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_NAME]); -} - -/** - * clutter_actor_get_name: - * @self: A #ClutterActor - * - * Retrieves the name of @self. - * - * Return value: (nullable): the name of the actor, or %NULL. The returned - * string is owned by the actor and should not be modified or freed. - */ -const gchar * -clutter_actor_get_name (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - return self->priv->name; -} - -static inline void -clutter_actor_set_z_position_internal (ClutterActor *self, - float z_position) -{ - ClutterTransformInfo *info; - - info = _clutter_actor_get_transform_info (self); - - if (memcmp (&info->z_position, &z_position, sizeof (float)) != 0) - { - info->z_position = z_position; - - transform_changed (self); - - clutter_actor_queue_redraw (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_Z_POSITION]); - } -} - -/** - * clutter_actor_set_z_position: - * @self: a #ClutterActor - * @z_position: the position on the Z axis - * - * Sets the actor's position on the Z axis. - * - * See [property@Clutter.Actor:z-position]. - */ -void -clutter_actor_set_z_position (ClutterActor *self, - gfloat z_position) -{ - const ClutterTransformInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_transform_info_or_defaults (self); - - _clutter_actor_create_transition (self, obj_props[PROP_Z_POSITION], - info->z_position, - z_position); -} - -/** - * clutter_actor_get_z_position: - * @self: a #ClutterActor - * - * Retrieves the actor's position on the Z axis. - * - * Return value: the position on the Z axis. - */ -gfloat -clutter_actor_get_z_position (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0.f); - - return _clutter_actor_get_transform_info_or_defaults (self)->z_position; -} - -/** - * clutter_actor_set_pivot_point: - * @self: a #ClutterActor - * @pivot_x: the normalized X coordinate of the pivot point - * @pivot_y: the normalized Y coordinate of the pivot point - * - * Sets the position of the [property@Clutter.Actor:pivot-point] around which the - * scaling and rotation transformations occur. - * - * The pivot point's coordinates are in normalized space, with the (0, 0) - * point being the top left corner of the actor, and the (1, 1) point being - * the bottom right corner. - */ -void -clutter_actor_set_pivot_point (ClutterActor *self, - gfloat pivot_x, - gfloat pivot_y) -{ - graphene_point_t pivot = GRAPHENE_POINT_INIT (pivot_x, pivot_y); - const ClutterTransformInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_transform_info_or_defaults (self); - _clutter_actor_create_transition (self, obj_props[PROP_PIVOT_POINT], - &info->pivot, - &pivot); -} - -/** - * clutter_actor_get_pivot_point: - * @self: a #ClutterActor - * @pivot_x: (out) (optional): return location for the normalized X - * coordinate of the pivot point, or %NULL - * @pivot_y: (out) (optional): return location for the normalized Y - * coordinate of the pivot point, or %NULL - * - * Retrieves the coordinates of the [property@Clutter.Actor:pivot-point]. - */ -void -clutter_actor_get_pivot_point (ClutterActor *self, - gfloat *pivot_x, - gfloat *pivot_y) -{ - const ClutterTransformInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_transform_info_or_defaults (self); - - if (pivot_x != NULL) - *pivot_x = info->pivot.x; - - if (pivot_y != NULL) - *pivot_y = info->pivot.y; -} - -/** - * clutter_actor_set_pivot_point_z: - * @self: a #ClutterActor - * @pivot_z: the Z coordinate of the actor's pivot point - * - * Sets the component on the Z axis of the [property@Clutter.Actor:pivot-point] around - * which the scaling and rotation transformations occur. - * - * The @pivot_z value is expressed as a distance along the Z axis. - */ -void -clutter_actor_set_pivot_point_z (ClutterActor *self, - gfloat pivot_z) -{ - const ClutterTransformInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_transform_info_or_defaults (self); - _clutter_actor_create_transition (self, obj_props[PROP_PIVOT_POINT_Z], - info->pivot_z, - pivot_z); -} - -/** - * clutter_actor_get_pivot_point_z: - * @self: a #ClutterActor - * - * Retrieves the Z component of the [property@Clutter.Actor:pivot-point]. - */ -gfloat -clutter_actor_get_pivot_point_z (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0.f); - - return _clutter_actor_get_transform_info_or_defaults (self)->pivot_z; -} - -/** - * clutter_actor_set_clip: - * @self: A #ClutterActor - * @xoff: X offset of the clip rectangle - * @yoff: Y offset of the clip rectangle - * @width: Width of the clip rectangle - * @height: Height of the clip rectangle - * - * Sets clip area for @self. The clip area is always computed from the - * upper left corner of the actor. - */ -void -clutter_actor_set_clip (ClutterActor *self, - gfloat xoff, - gfloat yoff, - gfloat width, - gfloat height) -{ - ClutterActorPrivate *priv; - GObject *obj; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - priv = self->priv; - - if (priv->has_clip && - priv->clip.origin.x == xoff && - priv->clip.origin.y == yoff && - priv->clip.size.width == width && - priv->clip.size.height == height) - return; - - obj = G_OBJECT (self); - - priv->clip.origin.x = xoff; - priv->clip.origin.y = yoff; - priv->clip.size.width = width; - priv->clip.size.height = height; - - priv->has_clip = TRUE; - - queue_update_paint_volume (self); - clutter_actor_queue_redraw (self); - - g_object_notify_by_pspec (obj, obj_props[PROP_CLIP_RECT]); - g_object_notify_by_pspec (obj, obj_props[PROP_HAS_CLIP]); -} - -/** - * clutter_actor_remove_clip: - * @self: A #ClutterActor - * - * Removes clip area from @self. - */ -void -clutter_actor_remove_clip (ClutterActor *self) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (!self->priv->has_clip) - return; - - self->priv->has_clip = FALSE; - - queue_update_paint_volume (self); - clutter_actor_queue_redraw (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_HAS_CLIP]); -} - -/** - * clutter_actor_has_clip: - * @self: a #ClutterActor - * - * Determines whether the actor has a clip area set or not. - * - * Return value: %TRUE if the actor has a clip area set. - */ -gboolean -clutter_actor_has_clip (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - return self->priv->has_clip; -} - -/** - * clutter_actor_get_clip: - * @self: a #ClutterActor - * @xoff: (out) (optional): return location for the X offset of - * the clip rectangle, or %NULL - * @yoff: (out) (optional): return location for the Y offset of - * the clip rectangle, or %NULL - * @width: (out) (optional): return location for the width of - * the clip rectangle, or %NULL - * @height: (out) (optional): return location for the height of - * the clip rectangle, or %NULL - * - * Gets the clip area for @self, if any is set. - */ -void -clutter_actor_get_clip (ClutterActor *self, - gfloat *xoff, - gfloat *yoff, - gfloat *width, - gfloat *height) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - priv = self->priv; - - if (!priv->has_clip) - return; - - if (xoff != NULL) - *xoff = priv->clip.origin.x; - - if (yoff != NULL) - *yoff = priv->clip.origin.y; - - if (width != NULL) - *width = priv->clip.size.width; - - if (height != NULL) - *height = priv->clip.size.height; -} - -/** - * clutter_actor_get_children: - * @self: a #ClutterActor - * - * Retrieves the list of children of @self. - * - * Return value: (transfer container) (element-type ClutterActor): A newly - * allocated #GList of `ClutterActor`s. Use g_list_free() when - * done. - */ -GList * -clutter_actor_get_children (ClutterActor *self) -{ - ClutterActor *iter; - GList *res; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - /* we walk the list backward so that we can use prepend(), - * which is O(1) - */ - for (iter = self->priv->last_child, res = NULL; - iter != NULL; - iter = iter->priv->prev_sibling) - { - res = g_list_prepend (res, iter); - } - - return res; -} - -/*< private > - * insert_child_at_depth: - * @self: a #ClutterActor - * @child: a #ClutterActor - * - * Inserts @child inside the list of children held by @self, using - * the depth as the insertion criteria. - * - * This sadly makes the insertion not O(1), but we can keep the - * list sorted so that the painters algorithm we use for painting - * the children will work correctly. - */ -static void -insert_child_at_depth (ClutterActor *self, - ClutterActor *child, - gpointer dummy G_GNUC_UNUSED) -{ - ClutterActor *iter; - float child_depth; - - child->priv->parent = self; - - child_depth = - _clutter_actor_get_transform_info_or_defaults (child)->z_position; - - /* special-case the first child */ - if (self->priv->n_children == 0) - { - self->priv->first_child = child; - self->priv->last_child = child; - - child->priv->next_sibling = NULL; - child->priv->prev_sibling = NULL; - - return; - } - - /* Find the right place to insert the child so that it will still be - sorted and the child will be after all of the actors at the same - dept */ - for (iter = self->priv->first_child; - iter != NULL; - iter = iter->priv->next_sibling) - { - float iter_depth; - - iter_depth = - _clutter_actor_get_transform_info_or_defaults (iter)->z_position; - - if (iter_depth > child_depth) - break; - } - - if (iter != NULL) - { - ClutterActor *tmp = iter->priv->prev_sibling; - - if (tmp != NULL) - tmp->priv->next_sibling = child; - - /* Insert the node before the found one */ - child->priv->prev_sibling = iter->priv->prev_sibling; - child->priv->next_sibling = iter; - iter->priv->prev_sibling = child; - } - else - { - ClutterActor *tmp = self->priv->last_child; - - if (tmp != NULL) - tmp->priv->next_sibling = child; - - /* insert the node at the end of the list */ - child->priv->prev_sibling = self->priv->last_child; - child->priv->next_sibling = NULL; - } - - if (child->priv->prev_sibling == NULL) - self->priv->first_child = child; - - if (child->priv->next_sibling == NULL) - self->priv->last_child = child; -} - -static void -insert_child_at_index (ClutterActor *self, - ClutterActor *child, - gpointer data_) -{ - gint index_ = GPOINTER_TO_INT (data_); - - child->priv->parent = self; - - if (index_ == 0) - { - ClutterActor *tmp = self->priv->first_child; - - if (tmp != NULL) - tmp->priv->prev_sibling = child; - - child->priv->prev_sibling = NULL; - child->priv->next_sibling = tmp; - } - else if (index_ < 0 || index_ >= self->priv->n_children) - { - ClutterActor *tmp = self->priv->last_child; - - if (tmp != NULL) - tmp->priv->next_sibling = child; - - child->priv->prev_sibling = tmp; - child->priv->next_sibling = NULL; - } - else - { - ClutterActor *iter; - int i; - - for (iter = self->priv->first_child, i = 0; - iter != NULL; - iter = iter->priv->next_sibling, i += 1) - { - if (index_ == i) - { - ClutterActor *tmp = iter->priv->prev_sibling; - - child->priv->prev_sibling = tmp; - child->priv->next_sibling = iter; - - iter->priv->prev_sibling = child; - - if (tmp != NULL) - tmp->priv->next_sibling = child; - - break; - } - } - } - - if (child->priv->prev_sibling == NULL) - self->priv->first_child = child; - - if (child->priv->next_sibling == NULL) - self->priv->last_child = child; -} - -static void -insert_child_above (ClutterActor *self, - ClutterActor *child, - gpointer data) -{ - ClutterActor *sibling = data; - - child->priv->parent = self; - - if (sibling == NULL) - sibling = self->priv->last_child; - - child->priv->prev_sibling = sibling; - - if (sibling != NULL) - { - ClutterActor *tmp = sibling->priv->next_sibling; - - child->priv->next_sibling = tmp; - - if (tmp != NULL) - tmp->priv->prev_sibling = child; - - sibling->priv->next_sibling = child; - } - else - child->priv->next_sibling = NULL; - - if (child->priv->prev_sibling == NULL) - self->priv->first_child = child; - - if (child->priv->next_sibling == NULL) - self->priv->last_child = child; -} - -static void -insert_child_below (ClutterActor *self, - ClutterActor *child, - gpointer data) -{ - ClutterActor *sibling = data; - - child->priv->parent = self; - - if (sibling == NULL) - sibling = self->priv->first_child; - - child->priv->next_sibling = sibling; - - if (sibling != NULL) - { - ClutterActor *tmp = sibling->priv->prev_sibling; - - child->priv->prev_sibling = tmp; - - if (tmp != NULL) - tmp->priv->next_sibling = child; - - sibling->priv->prev_sibling = child; - } - else - child->priv->prev_sibling = NULL; - - if (child->priv->prev_sibling == NULL) - self->priv->first_child = child; - - if (child->priv->next_sibling == NULL) - self->priv->last_child = child; -} - -typedef void (* ClutterActorAddChildFunc) (ClutterActor *parent, - ClutterActor *child, - gpointer data); - -typedef enum -{ - ADD_CHILD_EMIT_PARENT_SET = 1 << 1, - ADD_CHILD_EMIT_CHILD_ADDED = 1 << 2, - ADD_CHILD_CHECK_STATE = 1 << 3, - ADD_CHILD_NOTIFY_FIRST_LAST = 1 << 4, - ADD_CHILD_SHOW_ON_SET_PARENT = 1 << 5, - - /* default flags for public API */ - ADD_CHILD_DEFAULT_FLAGS = ADD_CHILD_EMIT_PARENT_SET | - ADD_CHILD_EMIT_CHILD_ADDED | - ADD_CHILD_CHECK_STATE | - ADD_CHILD_NOTIFY_FIRST_LAST | - ADD_CHILD_SHOW_ON_SET_PARENT, -} ClutterActorAddChildFlags; - -/*< private > - * clutter_actor_add_child_internal: - * @self: a #ClutterActor - * @child: a #ClutterActor - * @flags: control flags for actions - * @add_func: delegate function - * @data: (closure): data to pass to @add_func - * - * Adds @child to the list of children of @self. - * - * The actual insertion inside the list is delegated to @add_func: this - * function will just set up the state, perform basic checks, and emit - * signals. - * - * The @flags argument is used to perform additional operations. - */ -static inline void -clutter_actor_add_child_internal (ClutterActor *self, - ClutterActor *child, - ClutterActorAddChildFlags flags, - ClutterActorAddChildFunc add_func, - gpointer data) -{ - ClutterTextDirection text_dir; - gboolean emit_parent_set, emit_child_added; - gboolean check_state; - gboolean notify_first_last; - gboolean show_on_set_parent; - ClutterActor *old_first_child, *old_last_child; - GObject *obj; - - if (self == child) - { - g_warning ("Cannot add the actor '%s' to itself.", - _clutter_actor_get_debug_name (self)); - return; - } - - if (child->priv->parent != NULL) - { - g_warning ("The actor '%s' already has a parent, '%s'. You must " - "use clutter_actor_remove_child() first.", - _clutter_actor_get_debug_name (child), - _clutter_actor_get_debug_name (child->priv->parent)); - return; - } - - if (CLUTTER_ACTOR_IS_TOPLEVEL (child)) - { - g_warning ("The actor '%s' is a top-level actor, and cannot be " - "a child of another actor.", - _clutter_actor_get_debug_name (child)); - return; - } - - /* the following check disallows calling methods that change the stacking - * order within the destruction sequence, by triggering a critical - * warning first, and leaving the actor in an undefined state, which - * then ends up being caught by an assertion. - * - * the reproducible sequence is: - * - * - actor gets destroyed; - * - another actor, linked to the first, will try to change the - * stacking order of the first actor; - * - changing the stacking order is a composite operation composed - * by the following steps: - * 1. ref() the child; - * 2. remove_child_internal(), which removes the reference; - * 3. add_child_internal(), which adds a reference; - * - the state of the actor is not changed between (2) and (3), as - * it could be an expensive recomputation; - * - if (3) bails out, then the actor is in an undefined state, but - * still alive; - * - the destruction sequence terminates, but the actor is unparented - * while its state indicates being parented instead. - * - assertion failure. - * - * the obvious fix would be to decompose each set_child_*_sibling() - * method into proper remove_child()/add_child(), with state validation; - * this may cause excessive work, though, and trigger a cascade of other - * bugs in code that assumes that a change in the stacking order is an - * atomic operation. - * - * another potential fix is to just remove this check here, and let - * code doing stacking order changes inside the destruction sequence - * of an actor continue doing the stacking changes as before; this - * option still performs more work than necessary. - * - * the third fix is to silently bail out early from every - * set_child_*_sibling() and set_child_at_index() method, and avoid - * doing stack changes altogether; Clutter implements this last option. - * - * see bug: https://bugzilla.gnome.org/show_bug.cgi?id=670647 - */ - if (CLUTTER_ACTOR_IN_DESTRUCTION (child)) - { - g_warning ("The actor '%s' is currently being destroyed, and " - "cannot be added as a child of another actor.", - _clutter_actor_get_debug_name (child)); - return; - } - - emit_parent_set = (flags & ADD_CHILD_EMIT_PARENT_SET) != 0; - emit_child_added = (flags & ADD_CHILD_EMIT_CHILD_ADDED) != 0; - check_state = (flags & ADD_CHILD_CHECK_STATE) != 0; - notify_first_last = (flags & ADD_CHILD_NOTIFY_FIRST_LAST) != 0; - show_on_set_parent = (flags & ADD_CHILD_SHOW_ON_SET_PARENT) != 0; - - old_first_child = self->priv->first_child; - old_last_child = self->priv->last_child; - - obj = G_OBJECT (self); - g_object_freeze_notify (obj); - - g_object_ref_sink (child); - child->priv->parent = NULL; - child->priv->next_sibling = NULL; - child->priv->prev_sibling = NULL; - - /* delegate the actual insertion */ - add_func (self, child, data); - - g_assert (child->priv->parent == self); - - self->priv->n_children += 1; - - self->priv->age += 1; - - if (self->priv->in_cloned_branch) - clutter_actor_push_in_cloned_branch (child, self->priv->in_cloned_branch); - - if (self->priv->unmapped_paint_branch_counter) - push_in_paint_unmapped_branch (child, self->priv->unmapped_paint_branch_counter); - - /* children may cause their parent to expand, if they are set - * to expand; if a child is not expanded then it cannot change - * its parent's state. any further change later on will queue - * an expand state check. - * - * this check, with the initial state of the needs_compute_expand - * flag set to FALSE, should avoid recomputing the expand flags - * state while building the actor tree. - */ - if (clutter_actor_is_visible (child) && - (child->priv->needs_compute_expand || - child->priv->needs_x_expand || - child->priv->needs_y_expand)) - { - clutter_actor_queue_compute_expand (self); - } - - if (emit_parent_set) - g_signal_emit (child, actor_signals[PARENT_SET], 0, NULL); - - if (check_state) - { - /* If parent is mapped or realized, we need to also be mapped or - * realized once we're inside the parent. - */ - clutter_actor_update_map_state (child, MAP_STATE_CHECK); - - /* propagate the parent's text direction to the child */ - text_dir = clutter_actor_get_text_direction (self); - clutter_actor_set_text_direction (child, text_dir); - } - - /* this may end up queueing a redraw, in case the actor is - * not visible but the show-on-set-parent property is still - * set. - * - * XXX:2.0 - remove this check and unconditionally show() the - * actor once we remove the show-on-set-parent property - */ - if (show_on_set_parent && child->priv->show_on_set_parent) - clutter_actor_show (child); - - /* on the other hand, this will catch any other case where - * the actor is supposed to be visible when it's added - */ - if (clutter_actor_is_mapped (child)) - clutter_actor_queue_redraw (child); - - if (clutter_actor_has_mapped_clones (self)) - { - ClutterActorPrivate *priv = self->priv; - - /* Avoid the early return in clutter_actor_queue_relayout() */ - priv->needs_width_request = FALSE; - priv->needs_height_request = FALSE; - priv->needs_allocation = FALSE; - - clutter_actor_queue_relayout (self); - } - - if (emit_child_added) - g_signal_emit (self, actor_signals[CHILD_ADDED], 0, child); - - if (notify_first_last) - { - if (old_first_child != self->priv->first_child) - g_object_notify_by_pspec (obj, obj_props[PROP_FIRST_CHILD]); - - if (old_last_child != self->priv->last_child) - g_object_notify_by_pspec (obj, obj_props[PROP_LAST_CHILD]); - } - - g_object_thaw_notify (obj); -} - -/** - * clutter_actor_add_child: - * @self: a #ClutterActor - * @child: a #ClutterActor - * - * Adds @child to the children of @self. - * - * This function will acquire a reference on @child that will only - * be released when calling [method@Clutter.Actor.remove_child]. - * - * This function will take into consideration the depth - * of @child, and will keep the list of children sorted. - * - * This function will emit the [signal@Clutter.Actor::child-added] signal - * on @self. - */ -void -clutter_actor_add_child (ClutterActor *self, - ClutterActor *child) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (CLUTTER_IS_ACTOR (child)); - g_return_if_fail (self != child); - g_return_if_fail (child->priv->parent == NULL); - - clutter_actor_add_child_internal (self, child, - ADD_CHILD_DEFAULT_FLAGS, - insert_child_at_depth, - NULL); -} - -/** - * clutter_actor_insert_child_at_index: - * @self: a #ClutterActor - * @child: a #ClutterActor - * @index_: the index - * - * Inserts @child into the list of children of @self, using the - * given @index_. If @index_ is greater than the number of children - * in @self, or is less than 0, then the new child is added at the end. - * - * This function will acquire a reference on @child that will only - * be released when calling [method@Clutter.Actor.remove_child]. - * - * This function will not take into consideration the depth - * of @child. - * - * This function will emit the [signal@Clutter.Actor::child-added] signal - * on @self. - */ -void -clutter_actor_insert_child_at_index (ClutterActor *self, - ClutterActor *child, - gint index_) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (CLUTTER_IS_ACTOR (child)); - g_return_if_fail (self != child); - g_return_if_fail (child->priv->parent == NULL); - - clutter_actor_add_child_internal (self, child, - ADD_CHILD_DEFAULT_FLAGS, - insert_child_at_index, - GINT_TO_POINTER (index_)); -} - -/** - * clutter_actor_insert_child_above: - * @self: a #ClutterActor - * @child: a #ClutterActor - * @sibling: (nullable): a child of @self, or %NULL - * - * Inserts @child into the list of children of @self, above another - * child of @self or, if @sibling is %NULL, above all the children - * of @self. - * - * This function will acquire a reference on @child that will only - * be released when calling [method@Clutter.Actor.remove_child]. - * - * This function will not take into consideration the depth - * of @child. - * - * This function will emit the [signal@Clutter.Actor::child-added] signal - * on @self. - */ -void -clutter_actor_insert_child_above (ClutterActor *self, - ClutterActor *child, - ClutterActor *sibling) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (CLUTTER_IS_ACTOR (child)); - g_return_if_fail (self != child); - g_return_if_fail (child != sibling); - g_return_if_fail (child->priv->parent == NULL); - g_return_if_fail (sibling == NULL || - (CLUTTER_IS_ACTOR (sibling) && - sibling->priv->parent == self)); - - clutter_actor_add_child_internal (self, child, - ADD_CHILD_DEFAULT_FLAGS, - insert_child_above, - sibling); -} - -/** - * clutter_actor_insert_child_below: - * @self: a #ClutterActor - * @child: a #ClutterActor - * @sibling: (nullable): a child of @self, or %NULL - * - * Inserts @child into the list of children of @self, below another - * child of @self or, if @sibling is %NULL, below all the children - * of @self. - * - * This function will acquire a reference on @child that will only - * be released when calling [method@Clutter.Actor.remove_child]. - * - * This function will not take into consideration the depth - * of @child. - * - * This function will emit the [signal@Clutter.Actor::child-added] signal - * on @self. - */ -void -clutter_actor_insert_child_below (ClutterActor *self, - ClutterActor *child, - ClutterActor *sibling) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (CLUTTER_IS_ACTOR (child)); - g_return_if_fail (self != child); - g_return_if_fail (child != sibling); - g_return_if_fail (child->priv->parent == NULL); - g_return_if_fail (sibling == NULL || - (CLUTTER_IS_ACTOR (sibling) && - sibling->priv->parent == self)); - - clutter_actor_add_child_internal (self, child, - ADD_CHILD_DEFAULT_FLAGS, - insert_child_below, - sibling); -} - -/** - * clutter_actor_get_parent: - * @self: A #ClutterActor - * - * Retrieves the parent of @self. - * - * Return Value: (transfer none) (nullable): The #ClutterActor parent, or %NULL - * if no parent is set - */ -ClutterActor * -clutter_actor_get_parent (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - return self->priv->parent; -} - -/** - * clutter_actor_get_paint_visibility: - * @self: A #ClutterActor - * - * Retrieves the 'paint' visibility of an actor recursively checking for non - * visible parents. - * - * This is by definition the same as clutter_actor_is_mapped. - * - * Return Value: %TRUE if the actor is visible and will be painted. - */ -gboolean -clutter_actor_get_paint_visibility (ClutterActor *actor) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE); - - return clutter_actor_is_mapped (actor); -} - -/** - * clutter_actor_remove_child: - * @self: a #ClutterActor - * @child: a #ClutterActor - * - * Removes @child from the children of @self. - * - * This function will release the reference added by - * [method@Clutter.Actor.add_child], so if you want to keep using @child - * you will have to acquire a referenced on it before calling this - * function. - * - * This function will emit the [signal@Clutter.Actor::child-removed] - * signal on @self. - */ -void -clutter_actor_remove_child (ClutterActor *self, - ClutterActor *child) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (CLUTTER_IS_ACTOR (child)); - g_return_if_fail (self != child); - g_return_if_fail (child->priv->parent != NULL); - g_return_if_fail (child->priv->parent == self); - - clutter_actor_remove_child_internal (self, child, - REMOVE_CHILD_DEFAULT_FLAGS); -} - -/** - * clutter_actor_remove_all_children: - * @self: a #ClutterActor - * - * Removes all children of @self. - * - * This function releases the reference added by inserting a child actor - * in the list of children of @self. - * - * If the reference count of a child drops to zero, the child will be - * destroyed. If you want to ensure the destruction of all the children - * of @self, use clutter_actor_destroy_all_children(). - */ -void -clutter_actor_remove_all_children (ClutterActor *self) -{ - ClutterActorIter iter; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (self->priv->n_children == 0) - return; - - g_object_freeze_notify (G_OBJECT (self)); - - clutter_actor_iter_init (&iter, self); - while (clutter_actor_iter_next (&iter, NULL)) - clutter_actor_iter_remove (&iter); - - g_object_thaw_notify (G_OBJECT (self)); - - /* sanity check */ - g_assert (self->priv->first_child == NULL); - g_assert (self->priv->last_child == NULL); - g_assert (self->priv->n_children == 0); -} - -/** - * clutter_actor_destroy_all_children: - * @self: a #ClutterActor - * - * Destroys all children of @self. - * - * This function releases the reference added by inserting a child - * actor in the list of children of @self, and ensures that the - * [signal@Clutter.Actor::destroy] signal is emitted on each child of the - * actor. - * - * By default, #ClutterActor will emit the [signal@Clutter.Actor::destroy] signal - * when its reference count drops to 0; the default handler of the - * [signal@Clutter.Actor::destroy] signal will destroy all the children of an - * actor. This function ensures that all children are destroyed, instead - * of just removed from @self, unlike [method@Clutter.Actor.remove_all_children] - * which will merely release the reference and remove each child. - * - * Unless you acquired an additional reference on each child of @self - * prior to calling [method@Clutter.Actor.remove_all_children] and want to reuse - * the actors, you should use [method@Clutter.Actor.destroy_all_children] in - * order to make sure that children are destroyed and signal handlers - * are disconnected even in cases where circular references prevent this - * from automatically happening through reference counting alone. - */ -void -clutter_actor_destroy_all_children (ClutterActor *self) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (self->priv->n_children == 0) - return; - - g_object_freeze_notify (G_OBJECT (self)); - - while (self->priv->first_child != NULL) - { - gint prev_n_children = self->priv->n_children; - - clutter_actor_destroy (self->priv->first_child); - - g_assert (self->priv->n_children < prev_n_children); - } - - g_object_thaw_notify (G_OBJECT (self)); - - /* sanity check */ - g_assert (self->priv->first_child == NULL); - g_assert (self->priv->last_child == NULL); - g_assert (self->priv->n_children == 0); -} - -typedef struct _InsertBetweenData { - ClutterActor *prev_sibling; - ClutterActor *next_sibling; -} InsertBetweenData; - -static void -insert_child_between (ClutterActor *self, - ClutterActor *child, - gpointer data_) -{ - InsertBetweenData *data = data_; - ClutterActor *prev_sibling = data->prev_sibling; - ClutterActor *next_sibling = data->next_sibling; - - child->priv->parent = self; - child->priv->prev_sibling = prev_sibling; - child->priv->next_sibling = next_sibling; - - if (prev_sibling != NULL) - prev_sibling->priv->next_sibling = child; - - if (next_sibling != NULL) - next_sibling->priv->prev_sibling = child; - - if (child->priv->prev_sibling == NULL) - self->priv->first_child = child; - - if (child->priv->next_sibling == NULL) - self->priv->last_child = child; -} - -/** - * clutter_actor_replace_child: - * @self: a #ClutterActor - * @old_child: the child of @self to replace - * @new_child: the #ClutterActor to replace @old_child - * - * Replaces @old_child with @new_child in the list of children of @self. - */ -void -clutter_actor_replace_child (ClutterActor *self, - ClutterActor *old_child, - ClutterActor *new_child) -{ - ClutterActor *prev_sibling, *next_sibling; - InsertBetweenData clos; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (CLUTTER_IS_ACTOR (old_child)); - g_return_if_fail (old_child->priv->parent == self); - g_return_if_fail (CLUTTER_IS_ACTOR (new_child)); - g_return_if_fail (old_child != new_child); - g_return_if_fail (new_child != self); - g_return_if_fail (new_child->priv->parent == NULL); - - prev_sibling = old_child->priv->prev_sibling; - next_sibling = old_child->priv->next_sibling; - clutter_actor_remove_child_internal (self, old_child, - REMOVE_CHILD_DEFAULT_FLAGS); - - clos.prev_sibling = prev_sibling; - clos.next_sibling = next_sibling; - clutter_actor_add_child_internal (self, new_child, - ADD_CHILD_DEFAULT_FLAGS, - insert_child_between, - &clos); -} - -/** - * clutter_actor_contains: - * @self: A #ClutterActor - * @descendant: A #ClutterActor, possibly contained in @self - * - * Determines if @descendant is contained inside @self (either as an - * immediate child, or as a deeper descendant). If @self and - * @descendant point to the same actor then it will also return %TRUE. - * - * Return value: whether @descendent is contained within @self - */ -gboolean -clutter_actor_contains (ClutterActor *self, - ClutterActor *descendant) -{ - ClutterActor *actor; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - g_return_val_if_fail (CLUTTER_IS_ACTOR (descendant), FALSE); - - for (actor = descendant; actor; actor = actor->priv->parent) - if (actor == self) - return TRUE; - - return FALSE; -} - -/** - * clutter_actor_set_child_above_sibling: - * @self: a #ClutterActor - * @child: a #ClutterActor child of @self - * @sibling: (nullable): a #ClutterActor child of @self, or %NULL - * - * Sets @child to be above @sibling in the list of children of @self. - * - * If @sibling is %NULL, @child will be the new last child of @self. - * - * This function is logically equivalent to removing @child and using - * clutter_actor_insert_child_above(), but it will not emit signals - * or change state on @child. - */ -void -clutter_actor_set_child_above_sibling (ClutterActor *self, - ClutterActor *child, - ClutterActor *sibling) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (CLUTTER_IS_ACTOR (child)); - g_return_if_fail (child->priv->parent == self); - g_return_if_fail (child != sibling); - g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling)); - - if (sibling != NULL) - g_return_if_fail (sibling->priv->parent == self); - - if (CLUTTER_ACTOR_IN_DESTRUCTION (self) || - CLUTTER_ACTOR_IN_DESTRUCTION (child) || - (sibling != NULL && CLUTTER_ACTOR_IN_DESTRUCTION (sibling))) - return; - - /* we don't want to change the state of child, or emit signals, or - * regenerate ChildMeta instances here, but we still want to follow - * the correct sequence of steps encoded in remove_child() and - * add_child(), so that correctness is ensured, and we only go - * through one known code path. - */ - g_object_ref (child); - clutter_actor_remove_child_internal (self, child, 0); - clutter_actor_add_child_internal (self, child, - ADD_CHILD_NOTIFY_FIRST_LAST, - insert_child_above, - sibling); - g_object_unref(child); - - clutter_actor_queue_relayout (self); -} - -/** - * clutter_actor_set_child_below_sibling: - * @self: a #ClutterActor - * @child: a #ClutterActor child of @self - * @sibling: (nullable): a #ClutterActor child of @self, or %NULL - * - * Sets @child to be below @sibling in the list of children of @self. - * - * If @sibling is %NULL, @child will be the new first child of @self. - * - * This function is logically equivalent to removing @self and using - * clutter_actor_insert_child_below(), but it will not emit signals - * or change state on @child. - */ -void -clutter_actor_set_child_below_sibling (ClutterActor *self, - ClutterActor *child, - ClutterActor *sibling) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (CLUTTER_IS_ACTOR (child)); - g_return_if_fail (child->priv->parent == self); - g_return_if_fail (child != sibling); - g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling)); - - if (sibling != NULL) - g_return_if_fail (sibling->priv->parent == self); - - if (CLUTTER_ACTOR_IN_DESTRUCTION (self) || - CLUTTER_ACTOR_IN_DESTRUCTION (child) || - (sibling != NULL && CLUTTER_ACTOR_IN_DESTRUCTION (sibling))) - return; - - /* see the comment in set_child_above_sibling() */ - g_object_ref (child); - clutter_actor_remove_child_internal (self, child, 0); - clutter_actor_add_child_internal (self, child, - ADD_CHILD_NOTIFY_FIRST_LAST, - insert_child_below, - sibling); - g_object_unref(child); - - clutter_actor_queue_relayout (self); -} - -/** - * clutter_actor_set_child_at_index: - * @self: a #ClutterActor - * @child: a #ClutterActor child of @self - * @index_: the new index for @child - * - * Changes the index of @child in the list of children of @self. - * - * This function is logically equivalent to removing @child and - * calling clutter_actor_insert_child_at_index(), but it will not - * emit signals or change state on @child. - */ -void -clutter_actor_set_child_at_index (ClutterActor *self, - ClutterActor *child, - gint index_) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (CLUTTER_IS_ACTOR (child)); - g_return_if_fail (child->priv->parent == self); - g_return_if_fail (index_ <= self->priv->n_children); - - if (CLUTTER_ACTOR_IN_DESTRUCTION (self) || - CLUTTER_ACTOR_IN_DESTRUCTION (child)) - return; - - g_object_ref (child); - clutter_actor_remove_child_internal (self, child, 0); - clutter_actor_add_child_internal (self, child, - ADD_CHILD_NOTIFY_FIRST_LAST, - insert_child_at_index, - GINT_TO_POINTER (index_)); - g_object_unref (child); - - clutter_actor_queue_relayout (self); -} - -/* - * Event handling - */ - -/** - * clutter_actor_event: - * @actor: a #ClutterActor - * @event: a #ClutterEvent - * @capture: %TRUE if event in in capture phase, %FALSE otherwise. - * - * This function is used to emit an event on the main stage. - * You should rarely need to use this function, except for - * synthetising events. - * - * Return value: the return value from the signal emission: %TRUE - * if the actor handled the event, or %FALSE if the event was - * not handled - */ -gboolean -clutter_actor_event (ClutterActor *actor, - const ClutterEvent *event, - gboolean capture) -{ - gboolean retval = FALSE; - gint signal_num = -1; - GQuark detail = 0; - ClutterEventType event_type; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - COGL_TRACE_BEGIN_SCOPED (Event, "Clutter::Actor::event()"); - COGL_TRACE_DESCRIBE (Event, _clutter_actor_get_debug_name (actor)); - - g_object_ref (actor); - - event_type = clutter_event_type (event); - - switch (event_type) - { - case CLUTTER_NOTHING: - break; - case CLUTTER_BUTTON_PRESS: - signal_num = BUTTON_PRESS_EVENT; - detail = quark_button; - break; - case CLUTTER_BUTTON_RELEASE: - signal_num = BUTTON_RELEASE_EVENT; - detail = quark_button; - break; - case CLUTTER_SCROLL: - signal_num = SCROLL_EVENT; - detail = quark_scroll; - break; - case CLUTTER_KEY_PRESS: - signal_num = KEY_PRESS_EVENT; - detail = quark_key; - break; - case CLUTTER_KEY_RELEASE: - signal_num = KEY_RELEASE_EVENT; - detail = quark_key; - break; - case CLUTTER_MOTION: - signal_num = MOTION_EVENT; - detail = quark_motion; - break; - case CLUTTER_ENTER: - signal_num = ENTER_EVENT; - detail = quark_pointer_focus; - break; - case CLUTTER_LEAVE: - signal_num = LEAVE_EVENT; - detail = quark_pointer_focus; - break; - case CLUTTER_TOUCH_BEGIN: - case CLUTTER_TOUCH_END: - case CLUTTER_TOUCH_UPDATE: - case CLUTTER_TOUCH_CANCEL: - signal_num = TOUCH_EVENT; - detail = quark_touch; - break; - case CLUTTER_TOUCHPAD_PINCH: - case CLUTTER_TOUCHPAD_SWIPE: - case CLUTTER_TOUCHPAD_HOLD: - signal_num = -1; - detail = quark_touchpad; - break; - case CLUTTER_PROXIMITY_IN: - case CLUTTER_PROXIMITY_OUT: - signal_num = -1; - detail = quark_proximity; - break; - case CLUTTER_PAD_BUTTON_PRESS: - case CLUTTER_PAD_BUTTON_RELEASE: - case CLUTTER_PAD_STRIP: - case CLUTTER_PAD_RING: - signal_num = -1; - detail = quark_pad; - break; - case CLUTTER_IM_COMMIT: - case CLUTTER_IM_DELETE: - case CLUTTER_IM_PREEDIT: - signal_num = -1; - detail = quark_im; - case CLUTTER_DEVICE_ADDED: - case CLUTTER_DEVICE_REMOVED: - break; - case CLUTTER_EVENT_LAST: /* Just keep compiler warnings quiet */ - break; - } - - if (capture) - g_signal_emit (actor, actor_signals[CAPTURED_EVENT], detail, event, &retval); - else - { - g_signal_emit (actor, actor_signals[EVENT], detail, event, &retval); - - if (!retval && signal_num != -1) - g_signal_emit (actor, actor_signals[signal_num], 0, event, &retval); - } - - g_object_unref (actor); - - if (event_type == CLUTTER_ENTER || event_type == CLUTTER_LEAVE) - { - g_warn_if_fail (retval == CLUTTER_EVENT_PROPAGATE); - return CLUTTER_EVENT_PROPAGATE; - } - - return retval; -} - -/** - * clutter_actor_set_reactive: - * @actor: a #ClutterActor - * @reactive: whether the actor should be reactive to events - * - * Sets @actor as reactive. Reactive actors will receive events. - */ -void -clutter_actor_set_reactive (ClutterActor *actor, - gboolean reactive) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - priv = actor->priv; - - if (reactive == clutter_actor_get_reactive (actor)) - return; - - if (reactive) - actor->flags |= CLUTTER_ACTOR_REACTIVE; - else - actor->flags &= ~CLUTTER_ACTOR_REACTIVE; - - g_object_notify_by_pspec (G_OBJECT (actor), obj_props[PROP_REACTIVE]); - - if (!clutter_actor_get_reactive (actor) && priv->n_pointers > 0) - { - ClutterActor *stage = _clutter_actor_get_stage_internal (actor); - - clutter_stage_invalidate_focus (CLUTTER_STAGE (stage), actor); - } - else if (clutter_actor_get_reactive (actor)) - { - ClutterActor *parent; - - /* Check whether the closest parent has pointer focus, - * and whether it should move to this actor. - */ - parent = priv->parent; - - while (parent) - { - if (clutter_actor_get_reactive (parent)) - break; - - parent = parent->priv->parent; - } - - if (parent && parent->priv->n_pointers > 0) - { - ClutterActor *stage = _clutter_actor_get_stage_internal (actor); - - clutter_stage_maybe_invalidate_focus (CLUTTER_STAGE (stage), parent); - } - } -} - -/** - * clutter_actor_get_reactive: - * @actor: a #ClutterActor - * - * Checks whether @actor is marked as reactive. - * - * Return value: %TRUE if the actor is reactive - */ -gboolean -clutter_actor_get_reactive (ClutterActor *actor) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE); - - return (actor->flags & CLUTTER_ACTOR_REACTIVE) != FALSE; -} - -static void -clutter_actor_store_content_box (ClutterActor *self, - const ClutterActorBox *box) -{ - if (box != NULL) - { - self->priv->content_box = *box; - self->priv->content_box_valid = TRUE; - } - else - self->priv->content_box_valid = FALSE; - - clutter_actor_queue_redraw (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CONTENT_BOX]); -} - -static gboolean -get_layout_from_animation_property (ClutterActor *actor, - const gchar *name, - gchar **name_p) -{ - g_auto (GStrv) tokens = NULL; - - if (!g_str_has_prefix (name, "@layout")) - return FALSE; - - tokens = g_strsplit (name, ".", -1); - if (tokens == NULL || g_strv_length (tokens) != 2) - { - CLUTTER_NOTE (ANIMATION, "Invalid property name '%s'", - name + 1); - return FALSE; - } - - if (name_p != NULL) - *name_p = g_strdup (tokens[1]); - - return TRUE; -} - -static gboolean -get_content_from_animation_property (ClutterActor *actor, - const gchar *name, - gchar **name_p) -{ - g_auto (GStrv) tokens = NULL; - - if (!g_str_has_prefix (name, "@content")) - return FALSE; - - if (!actor->priv->content) - { - CLUTTER_NOTE (ANIMATION, "No ClutterContent available for '%s'", - name + 1); - return FALSE; - } - - tokens = g_strsplit (name, ".", -1); - if (tokens == NULL || g_strv_length (tokens) != 2) - { - CLUTTER_NOTE (ANIMATION, "Invalid property name '%s'", - name + 1); - return FALSE; - } - - if (name_p != NULL) - *name_p = g_strdup (tokens[1]); - - return TRUE; -} - -static ClutterActorMeta * -get_meta_from_animation_property (ClutterActor *actor, - const gchar *name, - gchar **name_p) -{ - ClutterActorPrivate *priv = actor->priv; - ClutterActorMeta *meta = NULL; - gchar **tokens; - - /* if this is not a special property, fall through */ - if (name[0] != '@') - return NULL; - - /* detect the properties named using the following spec: - * - * @
.. - * - * where
can be one of the following: - * - * - actions - * - constraints - * - effects - * - * and is the name set on a specific ActorMeta - */ - - tokens = g_strsplit (name + 1, ".", -1); - if (tokens == NULL || g_strv_length (tokens) != 3) - { - CLUTTER_NOTE (ANIMATION, "Invalid property name '%s'", - name + 1); - g_strfreev (tokens); - return NULL; - } - - if (strcmp (tokens[0], "actions") == 0) - meta = _clutter_meta_group_get_meta (priv->actions, tokens[1]); - - if (strcmp (tokens[0], "constraints") == 0) - meta = _clutter_meta_group_get_meta (priv->constraints, tokens[1]); - - if (strcmp (tokens[0], "effects") == 0) - meta = _clutter_meta_group_get_meta (priv->effects, tokens[1]); - - if (name_p != NULL) - *name_p = g_strdup (tokens[2]); - - CLUTTER_NOTE (ANIMATION, - "Looking for property '%s' of object '%s' in section '%s'", - tokens[2], - tokens[1], - tokens[0]); - - g_strfreev (tokens); - - return meta; -} - -static GParamSpec * -clutter_actor_find_property (ClutterAnimatable *animatable, - const gchar *property_name) -{ - ClutterActor *actor = CLUTTER_ACTOR (animatable); - ClutterActorMeta *meta = NULL; - GObjectClass *klass = NULL; - GParamSpec *pspec = NULL; - gchar *p_name = NULL; - gboolean use_content = FALSE; - gboolean use_layout; - - use_layout = get_layout_from_animation_property (actor, - property_name, - &p_name); - - if (!use_layout) - use_content = get_content_from_animation_property (actor, - property_name, - &p_name); - - if (!use_layout && !use_content) - meta = get_meta_from_animation_property (actor, - property_name, - &p_name); - - if (meta != NULL) - { - klass = G_OBJECT_GET_CLASS (meta); - - pspec = g_object_class_find_property (klass, p_name); - } - else if (use_layout) - { - klass = G_OBJECT_GET_CLASS (actor->priv->layout_manager); - - pspec = g_object_class_find_property (klass, p_name); - } - else if (use_content) - { - klass = G_OBJECT_GET_CLASS (actor->priv->content); - - pspec = g_object_class_find_property (klass, p_name); - } - else - { - klass = G_OBJECT_GET_CLASS (animatable); - - pspec = g_object_class_find_property (klass, property_name); - } - - g_free (p_name); - - return pspec; -} - -static void -clutter_actor_get_initial_state (ClutterAnimatable *animatable, - const gchar *property_name, - GValue *initial) -{ - ClutterActor *actor = CLUTTER_ACTOR (animatable); - ClutterActorMeta *meta = NULL; - gchar *p_name = NULL; - gboolean use_content = FALSE; - gboolean use_layout; - - use_layout = get_layout_from_animation_property (actor, - property_name, - &p_name); - - if (!use_layout) - use_content = get_content_from_animation_property (actor, - property_name, - &p_name); - - if (!use_layout && !use_content) - meta = get_meta_from_animation_property (actor, - property_name, - &p_name); - - if (meta != NULL) - g_object_get_property (G_OBJECT (meta), p_name, initial); - else if (use_layout) - g_object_get_property (G_OBJECT (actor->priv->layout_manager), p_name, initial); - else if (use_content) - g_object_get_property (G_OBJECT (actor->priv->content), p_name, initial); - else - g_object_get_property (G_OBJECT (animatable), property_name, initial); - - g_free (p_name); -} - -/* - * clutter_actor_set_animatable_property: - * @actor: a #ClutterActor - * @prop_id: the paramspec id - * @value: the value to set - * @pspec: the paramspec - * - * Sets values of animatable properties. - * - * This is a variant of clutter_actor_set_property() that gets called - * by the #ClutterAnimatable implementation of #ClutterActor for the - * properties with the %CLUTTER_PARAM_ANIMATABLE flag set on their - * #GParamSpec. - * - * Unlike the implementation of #GObjectClass.set_property(), this - * function will not update the interval if a transition involving an - * animatable property is in progress - this avoids cycles with the - * transition API calling the public API. - */ -static void -clutter_actor_set_animatable_property (ClutterActor *actor, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GObject *obj = G_OBJECT (actor); - - g_object_freeze_notify (obj); - - switch (prop_id) - { - case PROP_X: - clutter_actor_set_x_internal (actor, g_value_get_float (value)); - break; - - case PROP_Y: - clutter_actor_set_y_internal (actor, g_value_get_float (value)); - break; - - case PROP_POSITION: - clutter_actor_set_position_internal (actor, g_value_get_boxed (value)); - break; - - case PROP_WIDTH: - clutter_actor_set_width_internal (actor, g_value_get_float (value)); - break; - - case PROP_HEIGHT: - clutter_actor_set_height_internal (actor, g_value_get_float (value)); - break; - - case PROP_SIZE: - clutter_actor_set_size_internal (actor, g_value_get_boxed (value)); - break; - - case PROP_ALLOCATION: - clutter_actor_allocate_internal (actor, g_value_get_boxed (value)); - clutter_actor_queue_redraw (actor); - break; - - case PROP_Z_POSITION: - clutter_actor_set_z_position_internal (actor, g_value_get_float (value)); - break; - - case PROP_OPACITY: - clutter_actor_set_opacity_internal (actor, g_value_get_uint (value)); - break; - - case PROP_BACKGROUND_COLOR: - clutter_actor_set_background_color_internal (actor, clutter_value_get_color (value)); - break; - - case PROP_PIVOT_POINT: - clutter_actor_set_pivot_point_internal (actor, g_value_get_boxed (value)); - break; - - case PROP_PIVOT_POINT_Z: - clutter_actor_set_pivot_point_z_internal (actor, g_value_get_float (value)); - break; - - case PROP_TRANSLATION_X: - case PROP_TRANSLATION_Y: - case PROP_TRANSLATION_Z: - clutter_actor_set_translation_internal (actor, - g_value_get_float (value), - pspec); - break; - - case PROP_SCALE_X: - case PROP_SCALE_Y: - case PROP_SCALE_Z: - clutter_actor_set_scale_factor_internal (actor, - g_value_get_double (value), - pspec); - break; - - case PROP_ROTATION_ANGLE_X: - case PROP_ROTATION_ANGLE_Y: - case PROP_ROTATION_ANGLE_Z: - clutter_actor_set_rotation_angle_internal (actor, - g_value_get_double (value), - pspec); - break; - - case PROP_CONTENT_BOX: - clutter_actor_store_content_box (actor, g_value_get_boxed (value)); - break; - - case PROP_MARGIN_TOP: - case PROP_MARGIN_BOTTOM: - case PROP_MARGIN_LEFT: - case PROP_MARGIN_RIGHT: - clutter_actor_set_margin_internal (actor, g_value_get_float (value), - pspec); - break; - - case PROP_TRANSFORM: - clutter_actor_set_transform_internal (actor, g_value_get_boxed (value)); - break; - - case PROP_CHILD_TRANSFORM: - clutter_actor_set_child_transform_internal (actor, g_value_get_boxed (value)); - break; - - default: - g_object_set_property (obj, pspec->name, value); - break; - } - - g_object_thaw_notify (obj); -} - -static void -clutter_actor_update_devices (ClutterActor *self) -{ - ClutterStage *stage; - - stage = CLUTTER_STAGE (_clutter_actor_get_stage_internal (self)); - if (stage) - clutter_stage_invalidate_devices (stage); -} - -static void -clutter_actor_set_final_state (ClutterAnimatable *animatable, - const gchar *property_name, - const GValue *final) -{ - ClutterActor *actor = CLUTTER_ACTOR (animatable); - ClutterActorMeta *meta = NULL; - gchar *p_name = NULL; - gboolean use_content = FALSE; - gboolean use_layout; - - use_layout = get_layout_from_animation_property (actor, - property_name, - &p_name); - - if (!use_layout) - use_content = get_content_from_animation_property (actor, - property_name, - &p_name); - - if (!use_layout && !use_content) - meta = get_meta_from_animation_property (actor, - property_name, - &p_name); - - if (meta != NULL) - g_object_set_property (G_OBJECT (meta), p_name, final); - else if (use_layout) - g_object_set_property (G_OBJECT (actor->priv->layout_manager), p_name, final); - else if (use_content) - g_object_set_property (G_OBJECT (actor->priv->content), p_name, final); - else - { - GObjectClass *obj_class = G_OBJECT_GET_CLASS (animatable); - GParamSpec *pspec; - - pspec = g_object_class_find_property (obj_class, property_name); - - if (pspec != NULL) - { - if ((pspec->flags & CLUTTER_PARAM_ANIMATABLE) != 0) - { - /* XXX - I'm going to the special hell for this */ - clutter_actor_set_animatable_property (actor, pspec->param_id, final, pspec); - } - else - g_object_set_property (G_OBJECT (animatable), pspec->name, final); - } - } - - clutter_actor_update_devices (actor); - - g_free (p_name); -} - -static ClutterActor * -clutter_actor_get_actor (ClutterAnimatable *animatable) -{ - return CLUTTER_ACTOR (animatable); -} - -static void -clutter_animatable_iface_init (ClutterAnimatableInterface *iface) -{ - iface->find_property = clutter_actor_find_property; - iface->get_initial_state = clutter_actor_get_initial_state; - iface->set_final_state = clutter_actor_set_final_state; - iface->get_actor = clutter_actor_get_actor; -} - -/** - * clutter_actor_transform_stage_point: - * @self: A #ClutterActor - * @x: (in): x screen coordinate of the point to unproject - * @y: (in): y screen coordinate of the point to unproject - * @x_out: (out) (nullable): return location for the unprojected x coordinance - * @y_out: (out) (nullable): return location for the unprojected y coordinance - * - * This function translates screen coordinates (@x, @y) to - * coordinates relative to the actor. For example, it can be used to translate - * screen events from global screen coordinates into actor-local coordinates. - * - * The conversion can fail, notably if the transform stack results in the - * actor being projected on the screen as a mere line. - * - * The conversion should not be expected to be pixel-perfect due to the - * nature of the operation. In general the error grows when the skewing - * of the actor rectangle on screen increases. - * - * This function can be computationally intensive. - * - * This function only works when the allocation is up-to-date, i.e. inside of - * the [vfunc@Clutter.Actor.paint] implementation - * - * Return value: %TRUE if conversion was successful. - */ -gboolean -clutter_actor_transform_stage_point (ClutterActor *self, - gfloat x, - gfloat y, - gfloat *x_out, - gfloat *y_out) -{ - graphene_point3d_t v[4]; - double ST[3][3]; - double RQ[3][3]; - int du, dv; - double px, py; - double det; - float xf, yf, wf; - ClutterActorPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - priv = self->priv; - - /* This implementation is based on the quad -> quad projection algorithm - * described by Paul Heckbert in: - * - * http://www.cs.cmu.edu/~ph/texfund/texfund.pdf - * - * and the sample implementation at: - * - * http://www.cs.cmu.edu/~ph/src/texfund/ - * - * Our texture is a rectangle with origin [0, 0], so we are mapping from - * quad to rectangle only, which significantly simplifies things. - * Function calls have been unrolled. - */ - clutter_actor_get_abs_allocation_vertices (self, v); - - /* Keeping these as ints simplifies the multiplication (no significant - * loss of precision here). - */ - du = ceilf (priv->allocation.x2 - priv->allocation.x1); - dv = ceilf (priv->allocation.y2 - priv->allocation.y1); - - if (du == 0 || dv == 0) - return FALSE; - -#define DET(a,b,c,d) (((a) * (d)) - ((b) * (c))) - - /* First, find mapping from unit uv square to xy quadrilateral; this - * equivalent to the pmap_square_quad() functions in the sample - * implementation, which we can simplify, since our target is always - * a rectangle. - */ - px = v[0].x - v[1].x + v[3].x - v[2].x; - py = v[0].y - v[1].y + v[3].y - v[2].y; - - if ((int) px == 0 && (int) py == 0) - { - /* affine transform */ - RQ[0][0] = v[1].x - v[0].x; - RQ[1][0] = v[3].x - v[1].x; - RQ[2][0] = v[0].x; - RQ[0][1] = v[1].y - v[0].y; - RQ[1][1] = v[3].y - v[1].y; - RQ[2][1] = v[0].y; - RQ[0][2] = 0.0; - RQ[1][2] = 0.0; - RQ[2][2] = 1.0; - } - else - { - /* projective transform */ - double dx1, dx2, dy1, dy2; - - dx1 = v[1].x - v[3].x; - dx2 = v[2].x - v[3].x; - dy1 = v[1].y - v[3].y; - dy2 = v[2].y - v[3].y; - - det = DET (dx1, dx2, dy1, dy2); - if (fabs (det) <= DBL_EPSILON) - return FALSE; - - RQ[0][2] = DET (px, dx2, py, dy2) / det; - RQ[1][2] = DET (dx1, px, dy1, py) / det; - RQ[2][2] = 1.0; - RQ[0][0] = v[1].x - v[0].x + (RQ[0][2] * v[1].x); - RQ[1][0] = v[2].x - v[0].x + (RQ[1][2] * v[2].x); - RQ[2][0] = v[0].x; - RQ[0][1] = v[1].y - v[0].y + (RQ[0][2] * v[1].y); - RQ[1][1] = v[2].y - v[0].y + (RQ[1][2] * v[2].y); - RQ[2][1] = v[0].y; - } - - /* - * Now combine with transform from our rectangle (u0,v0,u1,v1) to unit - * square. Since our rectangle is based at 0,0 we only need to scale. - */ - RQ[0][0] /= du; - RQ[1][0] /= dv; - RQ[0][1] /= du; - RQ[1][1] /= dv; - RQ[0][2] /= du; - RQ[1][2] /= dv; - - /* - * Now RQ is transform from uv rectangle to xy quadrilateral; we need an - * inverse of that. - */ - ST[0][0] = DET (RQ[1][1], RQ[1][2], RQ[2][1], RQ[2][2]); - ST[1][0] = DET (RQ[1][2], RQ[1][0], RQ[2][2], RQ[2][0]); - ST[2][0] = DET (RQ[1][0], RQ[1][1], RQ[2][0], RQ[2][1]); - ST[0][1] = DET (RQ[2][1], RQ[2][2], RQ[0][1], RQ[0][2]); - ST[1][1] = DET (RQ[2][2], RQ[2][0], RQ[0][2], RQ[0][0]); - ST[2][1] = DET (RQ[2][0], RQ[2][1], RQ[0][0], RQ[0][1]); - ST[0][2] = DET (RQ[0][1], RQ[0][2], RQ[1][1], RQ[1][2]); - ST[1][2] = DET (RQ[0][2], RQ[0][0], RQ[1][2], RQ[1][0]); - ST[2][2] = DET (RQ[0][0], RQ[0][1], RQ[1][0], RQ[1][1]); - - /* - * Check the resulting matrix is OK. - */ - det = (RQ[0][0] * ST[0][0]) - + (RQ[0][1] * ST[0][1]) - + (RQ[0][2] * ST[0][2]); - if (fabs (det) <= DBL_EPSILON) - return FALSE; - - /* - * Now transform our point with the ST matrix; the notional w - * coordinate is 1, hence the last part is simply added. - */ - xf = x * ST[0][0] + y * ST[1][0] + ST[2][0]; - yf = x * ST[0][1] + y * ST[1][1] + ST[2][1]; - wf = x * ST[0][2] + y * ST[1][2] + ST[2][2]; - - if (x_out) - *x_out = xf / wf; - - if (y_out) - *y_out = yf / wf; - -#undef DET - - return TRUE; -} - -/** - * clutter_actor_is_rotated: - * @self: a #ClutterActor - * - * Checks whether any rotation is applied to the actor. - * - * Return value: %TRUE if the actor is rotated. - */ -gboolean -clutter_actor_is_rotated (ClutterActor *self) -{ - const ClutterTransformInfo *info; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - info = _clutter_actor_get_transform_info_or_defaults (self); - - if (info->rx_angle || info->ry_angle || info->rz_angle) - return TRUE; - - return FALSE; -} - -/** - * clutter_actor_is_scaled: - * @self: a #ClutterActor - * - * Checks whether the actor is scaled in either dimension. - * - * Return value: %TRUE if the actor is scaled. - */ -gboolean -clutter_actor_is_scaled (ClutterActor *self) -{ - const ClutterTransformInfo *info; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - info = _clutter_actor_get_transform_info_or_defaults (self); - - if (info->scale_x != 1.0 || info->scale_y != 1.0) - return TRUE; - - return FALSE; -} - -ClutterActor * -_clutter_actor_get_stage_internal (ClutterActor *actor) -{ - while (actor && !CLUTTER_ACTOR_IS_TOPLEVEL (actor)) - actor = actor->priv->parent; - - return actor; -} - -/** - * clutter_actor_get_stage: - * @actor: a #ClutterActor - * - * Retrieves the #ClutterStage where @actor is contained. - * - * Return value: (transfer none) (type Clutter.Stage): the stage - * containing the actor, or %NULL - */ -ClutterActor * -clutter_actor_get_stage (ClutterActor *actor) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); - - return _clutter_actor_get_stage_internal (actor); -} - -/** - * clutter_actor_allocate_available_size: - * @self: a #ClutterActor - * @x: the actor's X coordinate - * @y: the actor's Y coordinate - * @available_width: the maximum available width, or -1 to use the - * actor's natural width - * @available_height: the maximum available height, or -1 to use the - * actor's natural height - * - * Allocates @self taking into account the #ClutterActor's - * preferred size, but limiting it to the maximum available width - * and height provided. - * - * This function will do the right thing when dealing with the - * actor's request mode. - * - * The implementation of this function is equivalent to: - * - * ```c - * if (request_mode == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH) - * { - * clutter_actor_get_preferred_width (self, available_height, - * &min_width, - * &natural_width); - * width = CLAMP (natural_width, min_width, available_width); - * - * clutter_actor_get_preferred_height (self, width, - * &min_height, - * &natural_height); - * height = CLAMP (natural_height, min_height, available_height); - * } - * else if (request_mode == CLUTTER_REQUEST_WIDTH_FOR_HEIGHT) - * { - * clutter_actor_get_preferred_height (self, available_width, - * &min_height, - * &natural_height); - * height = CLAMP (natural_height, min_height, available_height); - * - * clutter_actor_get_preferred_width (self, height, - * &min_width, - * &natural_width); - * width = CLAMP (natural_width, min_width, available_width); - * } - * else if (request_mode == CLUTTER_REQUEST_CONTENT_SIZE) - * { - * clutter_content_get_preferred_size (content, &natural_width, &natural_height); - * - * width = CLAMP (natural_width, 0, available_width); - * height = CLAMP (natural_height, 0, available_height); - * } - * - * box.x1 = x; box.y1 = y; - * box.x2 = box.x1 + available_width; - * box.y2 = box.y1 + available_height; - * clutter_actor_allocate (self, &box); - * ``` - * - * This function can be used by fluid layout managers to allocate - * an actor's preferred size without making it bigger than the area - * available for the container. - */ -void -clutter_actor_allocate_available_size (ClutterActor *self, - gfloat x, - gfloat y, - gfloat available_width, - gfloat available_height) -{ - ClutterActorPrivate *priv; - gfloat width, height; - gfloat min_width, min_height; - gfloat natural_width, natural_height; - ClutterActorBox box; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - priv = self->priv; - - width = height = 0.0; - - switch (priv->request_mode) - { - case CLUTTER_REQUEST_HEIGHT_FOR_WIDTH: - clutter_actor_get_preferred_width (self, available_height, - &min_width, - &natural_width); - width = CLAMP (natural_width, min_width, available_width); - - clutter_actor_get_preferred_height (self, width, - &min_height, - &natural_height); - height = CLAMP (natural_height, min_height, available_height); - break; - - case CLUTTER_REQUEST_WIDTH_FOR_HEIGHT: - clutter_actor_get_preferred_height (self, available_width, - &min_height, - &natural_height); - height = CLAMP (natural_height, min_height, available_height); - - clutter_actor_get_preferred_width (self, height, - &min_width, - &natural_width); - width = CLAMP (natural_width, min_width, available_width); - break; - - case CLUTTER_REQUEST_CONTENT_SIZE: - if (priv->content != NULL) - { - clutter_content_get_preferred_size (priv->content, &natural_width, &natural_height); - - width = CLAMP (natural_width, 0, available_width); - height = CLAMP (natural_height, 0, available_height); - } - break; - } - - - box.x1 = x; - box.y1 = y; - box.x2 = box.x1 + width; - box.y2 = box.y1 + height; - clutter_actor_allocate (self, &box); -} - -/** - * clutter_actor_allocate_preferred_size: - * @self: a #ClutterActor - * @x: the actor's X coordinate - * @y: the actor's Y coordinate - * - * Allocates the natural size of @self. - * - * This function is a utility call for #ClutterActor implementations - * that allocates the actor's preferred natural size. It can be used - * by fixed layout managers (like #ClutterGroup or so called - * 'composite actors') inside the [vfunc@Clutter.Actor.allocate] - * implementation to give each child exactly how much space it - * requires, regardless of the size of the parent. - * - * This function is not meant to be used by applications. It is also - * not meant to be used outside the implementation of the - * #ClutterActorClass.allocate virtual function. - */ -void -clutter_actor_allocate_preferred_size (ClutterActor *self, - float x, - float y) -{ - gfloat natural_width, natural_height; - ClutterActorBox actor_box; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - clutter_actor_get_preferred_size (self, - NULL, NULL, - &natural_width, - &natural_height); - - actor_box.x1 = x; - actor_box.y1 = y; - actor_box.x2 = actor_box.x1 + natural_width; - actor_box.y2 = actor_box.y1 + natural_height; - - clutter_actor_allocate (self, &actor_box); -} - -/** - * clutter_actor_allocate_align_fill: - * @self: a #ClutterActor - * @box: a #ClutterActorBox, containing the available width and height - * @x_align: the horizontal alignment, between 0 and 1 - * @y_align: the vertical alignment, between 0 and 1 - * @x_fill: whether the actor should fill horizontally - * @y_fill: whether the actor should fill vertically - * - * Allocates @self by taking into consideration the available allocation - * area; an alignment factor on either axis; and whether the actor should - * fill the allocation on either axis. - * - * The @box should contain the available allocation width and height; - * if the x1 and y1 members of #ClutterActorBox are not set to 0, the - * allocation will be offset by their value. - * - * This function takes into consideration the geometry request specified by - * the [property@Clutter.Actor:request-mode] property, and the text direction. - * - * This function is useful for fluid layout managers using legacy alignment - * flags. Newly written layout managers should use the - * [property@Clutter.Actor:x-align] and [property@Clutter.Actor:y-align] - * properties, instead, and just call [method@Clutter.Actor.allocate] - * inside their [vfunc@Clutter.Actor.allocate] implementation. - */ -void -clutter_actor_allocate_align_fill (ClutterActor *self, - const ClutterActorBox *box, - gdouble x_align, - gdouble y_align, - gboolean x_fill, - gboolean y_fill) -{ - ClutterActorPrivate *priv; - ClutterActorBox allocation = CLUTTER_ACTOR_BOX_INIT_ZERO; - gfloat x_offset, y_offset; - gfloat available_width, available_height; - gfloat child_width = 0.f, child_height = 0.f; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (box != NULL); - g_return_if_fail (x_align >= 0.0 && x_align <= 1.0); - g_return_if_fail (y_align >= 0.0 && y_align <= 1.0); - - priv = self->priv; - - clutter_actor_box_get_origin (box, &x_offset, &y_offset); - clutter_actor_box_get_size (box, &available_width, &available_height); - - if (available_width <= 0) - available_width = 0.f; - - if (available_height <= 0) - available_height = 0.f; - - allocation.x1 = x_offset; - allocation.y1 = y_offset; - - if (available_width == 0.f && available_height == 0.f) - goto out; - - if (x_fill) - child_width = available_width; - - if (y_fill) - child_height = available_height; - - /* if we are filling horizontally and vertically then we're done */ - if (x_fill && y_fill) - goto out; - - if (priv->request_mode == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH) - { - gfloat min_width, natural_width; - gfloat min_height, natural_height; - - if (!x_fill) - { - clutter_actor_get_preferred_width (self, available_height, - &min_width, - &natural_width); - - child_width = CLAMP (natural_width, min_width, available_width); - } - - if (!y_fill) - { - clutter_actor_get_preferred_height (self, child_width, - &min_height, - &natural_height); - - child_height = CLAMP (natural_height, min_height, available_height); - } - } - else if (priv->request_mode == CLUTTER_REQUEST_WIDTH_FOR_HEIGHT) - { - gfloat min_width, natural_width; - gfloat min_height, natural_height; - - if (!y_fill) - { - clutter_actor_get_preferred_height (self, available_width, - &min_height, - &natural_height); - - child_height = CLAMP (natural_height, min_height, available_height); - } - - if (!x_fill) - { - clutter_actor_get_preferred_width (self, child_height, - &min_width, - &natural_width); - - child_width = CLAMP (natural_width, min_width, available_width); - } - } - else if (priv->request_mode == CLUTTER_REQUEST_CONTENT_SIZE && priv->content != NULL) - { - gfloat natural_width, natural_height; - - clutter_content_get_preferred_size (priv->content, &natural_width, &natural_height); - - if (!x_fill) - child_width = CLAMP (natural_width, 0, available_width); - - if (!y_fill) - child_height = CLAMP (natural_height, 0, available_height); - } - - /* invert the horizontal alignment for RTL languages */ - if (priv->text_direction == CLUTTER_TEXT_DIRECTION_RTL) - x_align = 1.0 - x_align; - - if (!x_fill) - allocation.x1 += ((available_width - child_width) * x_align); - - if (!y_fill) - allocation.y1 += ((available_height - child_height) * y_align); - -out: - - allocation.x1 = floorf (allocation.x1); - allocation.y1 = floorf (allocation.y1); - allocation.x2 = ceilf (allocation.x1 + MAX (child_width, 0)); - allocation.y2 = ceilf (allocation.y1 + MAX (child_height, 0)); - - clutter_actor_allocate (self, &allocation); -} - -/** - * clutter_actor_grab_key_focus: - * @self: a #ClutterActor - * - * Sets the key focus of the #ClutterStage including @self - * to this #ClutterActor. - */ -void -clutter_actor_grab_key_focus (ClutterActor *self) -{ - ClutterActor *stage; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (self->priv->has_key_focus) - return; - - stage = _clutter_actor_get_stage_internal (self); - if (stage != NULL) - clutter_stage_set_key_focus (CLUTTER_STAGE (stage), self); -} - -static void -update_pango_context (ClutterBackend *backend, - PangoContext *context) -{ - ClutterSettings *settings; - PangoFontDescription *font_desc; - const cairo_font_options_t *font_options; - ClutterTextDirection dir; - PangoDirection pango_dir; - gchar *font_name; - gdouble resolution; - - settings = clutter_settings_get_default (); - - /* update the text direction */ - dir = clutter_get_default_text_direction (); - pango_dir = clutter_text_direction_to_pango_direction (dir); - - pango_context_set_base_dir (context, pango_dir); - - g_object_get (settings, "font-name", &font_name, NULL); - - /* get the configuration for the PangoContext from the backend */ - font_options = clutter_backend_get_font_options (backend); - resolution = clutter_backend_get_resolution (backend); - - font_desc = pango_font_description_from_string (font_name); - - if (resolution < 0) - resolution = 96.0; /* fall back */ - - pango_context_set_font_description (context, font_desc); - pango_cairo_context_set_font_options (context, font_options); - pango_cairo_context_set_resolution (context, resolution); - - pango_font_description_free (font_desc); - g_free (font_name); -} - -/** - * clutter_actor_get_pango_context: - * @self: a #ClutterActor - * - * Retrieves the #PangoContext for @self. The actor's #PangoContext - * is already configured using the appropriate font map, resolution - * and font options. - * - * Unlike clutter_actor_create_pango_context(), this context is owend - * by the #ClutterActor and it will be updated each time the options - * stored by the #ClutterBackend change. - * - * You can use the returned #PangoContext to create a #PangoLayout - * and render text using cogl_pango_show_layout() to reuse the - * glyphs cache also used by Clutter. - * - * Return value: (transfer none): the #PangoContext for a #ClutterActor. - * The returned #PangoContext is owned by the actor and should not be - * unreferenced by the application code - */ -PangoContext * -clutter_actor_get_pango_context (ClutterActor *self) -{ - ClutterActorPrivate *priv; - ClutterBackend *backend = clutter_get_default_backend (); - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - priv = self->priv; - - if (G_UNLIKELY (priv->pango_context == NULL)) - { - priv->pango_context = clutter_actor_create_pango_context (self); - - priv->resolution_changed_id = - g_signal_connect (backend, "resolution-changed", - G_CALLBACK (update_pango_context), priv->pango_context); - priv->font_changed_id = - g_signal_connect (backend, "font-changed", - G_CALLBACK (update_pango_context), priv->pango_context); - } - else - update_pango_context (backend, priv->pango_context); - - return priv->pango_context; -} - -/** - * clutter_actor_create_pango_context: - * @self: a #ClutterActor - * - * Creates a #PangoContext for the given actor. The #PangoContext - * is already configured using the appropriate font map, resolution - * and font options. - * - * See also [method@Clutter.Actor.get_pango_context]. - * - * Return value: (transfer full): the newly created #PangoContext. - * Use g_object_unref() on the returned value to deallocate its - * resources - */ -PangoContext * -clutter_actor_create_pango_context (ClutterActor *self) -{ - CoglPangoFontMap *font_map; - PangoContext *context; - - font_map = COGL_PANGO_FONT_MAP (clutter_get_font_map ()); - - context = cogl_pango_font_map_create_context (font_map); - update_pango_context (clutter_get_default_backend (), context); - pango_context_set_language (context, pango_language_get_default ()); - - return context; -} - -/** - * clutter_actor_create_pango_layout: - * @self: a #ClutterActor - * @text: (nullable): the text to set on the #PangoLayout, or %NULL - * - * Creates a new #PangoLayout from the same #PangoContext used - * by the #ClutterActor. The #PangoLayout is already configured - * with the font map, resolution and font options, and the - * given @text. - * - * If you want to keep around a #PangoLayout created by this - * function you will have to connect to the #ClutterBackend::font-changed - * and #ClutterBackend::resolution-changed signals, and call - * pango_layout_context_changed() in response to them. - * - * Return value: (transfer full): the newly created #PangoLayout. - * Use g_object_unref() when done - */ -PangoLayout * -clutter_actor_create_pango_layout (ClutterActor *self, - const gchar *text) -{ - PangoContext *context; - PangoLayout *layout; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - context = clutter_actor_get_pango_context (self); - layout = pango_layout_new (context); - - if (text) - pango_layout_set_text (layout, text, -1); - - return layout; -} - -/** - * clutter_actor_set_opacity_override: - * @self: a #ClutterActor - * @opacity: the override opacity value, or -1 to reset - * - * Allows overriding the calculated paint opacity (as returned by - * clutter_actor_get_paint_opacity()). This is used internally by - * ClutterClone and ClutterOffscreenEffect, and should be used by - * actors that need to mimic those. - * - * In almost all cases this should not used by applications. - */ -void -clutter_actor_set_opacity_override (ClutterActor *self, - gint opacity) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - /* ensure bounds */ - if (opacity >= 0) - opacity = CLAMP (opacity, 0, 255); - else - opacity = -1; - - self->priv->opacity_override = opacity; -} - -/** - * clutter_actor_get_opacity_override: - * @self: a #ClutterActor - * - * See clutter_actor_set_opacity_override() - * - * Returns: the override value for the actor's opacity, or -1 if no override - * is set.2 - */ -gint -clutter_actor_get_opacity_override (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), -1); - - return self->priv->opacity_override; -} - -/** - * clutter_actor_inhibit_culling: - * @actor: a #ClutterActor - * - * Increases the culling inhibitor counter. Inhibiting culling - * forces the actor to be painted even when outside the visible - * bounds of the stage view. - * - * This is usually necessary when an actor is being painted on - * another paint context. - * - * Pair with clutter_actor_uninhibit_culling() when the actor doesn't - * need to be painted anymore. - */ -void -clutter_actor_inhibit_culling (ClutterActor *actor) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - priv = actor->priv; - - priv->inhibit_culling_counter++; - _clutter_actor_set_enable_paint_unmapped (actor, TRUE); -} - -/** - * clutter_actor_uninhibit_culling: - * @actor: a #ClutterActor - * - * Decreases the culling inhibitor counter. See clutter_actor_inhibit_culling() - * for when inhibit culling is necessary. - * - * Calling this function without a matching call to - * clutter_actor_inhibit_culling() is a programming error. - */ -void -clutter_actor_uninhibit_culling (ClutterActor *actor) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - priv = actor->priv; - - if (priv->inhibit_culling_counter == 0) - { - g_critical ("Unpaired call to clutter_actor_uninhibit_culling"); - return; - } - - priv->inhibit_culling_counter--; - if (priv->inhibit_culling_counter == 0) - _clutter_actor_set_enable_paint_unmapped (actor, FALSE); -} - -/* Allows you to disable applying the actors model view transform during - * a paint. Used by ClutterClone. */ -void -_clutter_actor_set_enable_model_view_transform (ClutterActor *self, - gboolean enable) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - self->priv->enable_model_view_transform = enable; -} - -void -_clutter_actor_set_enable_paint_unmapped (ClutterActor *self, - gboolean enable) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - priv = self->priv; - - if (priv->enable_paint_unmapped == enable) - return; - - priv->enable_paint_unmapped = enable; - - if (enable) - { - push_in_paint_unmapped_branch (self, 1); - - /* Make sure that the parents of the widget are realized first; - * otherwise checks in clutter_actor_update_map_state() will - * fail. - */ - clutter_actor_realize (self); - - /* If the actor isn't ultimately connected to a toplevel, it can't be - * realized or painted. - */ - if (clutter_actor_is_realized (self)) - clutter_actor_update_map_state (self, MAP_STATE_MAKE_MAPPED); - } - else - { - clutter_actor_update_map_state (self, MAP_STATE_CHECK); - pop_in_paint_unmapped_branch (self, 1); - } -} - -/** - * clutter_actor_get_flags: - * @self: a #ClutterActor - * - * Retrieves the flags set on @self - * - * Return value: a bitwise or of #ClutterActorFlags or 0 - */ -ClutterActorFlags -clutter_actor_get_flags (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0); - - return self->flags; -} - -/** - * clutter_actor_set_flags: - * @self: a #ClutterActor - * @flags: the flags to set - * - * Sets @flags on @self - * - * This function will emit notifications for the changed properties - */ -void -clutter_actor_set_flags (ClutterActor *self, - ClutterActorFlags flags) -{ - ClutterActorFlags old_flags; - GObject *obj; - gboolean was_reactive_set, reactive_set; - gboolean was_realized_set, realized_set; - gboolean was_mapped_set, mapped_set; - gboolean was_visible_set, visible_set; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (self->flags == flags) - return; - - obj = G_OBJECT (self); - g_object_ref (obj); - g_object_freeze_notify (obj); - - old_flags = self->flags; - - was_reactive_set = ((old_flags & CLUTTER_ACTOR_REACTIVE) != 0); - was_realized_set = ((old_flags & CLUTTER_ACTOR_REALIZED) != 0); - was_mapped_set = ((old_flags & CLUTTER_ACTOR_MAPPED) != 0); - was_visible_set = ((old_flags & CLUTTER_ACTOR_VISIBLE) != 0); - - self->flags |= flags; - - reactive_set = ((self->flags & CLUTTER_ACTOR_REACTIVE) != 0); - realized_set = ((self->flags & CLUTTER_ACTOR_REALIZED) != 0); - mapped_set = ((self->flags & CLUTTER_ACTOR_MAPPED) != 0); - visible_set = ((self->flags & CLUTTER_ACTOR_VISIBLE) != 0); - - if (reactive_set != was_reactive_set) - g_object_notify_by_pspec (obj, obj_props[PROP_REACTIVE]); - - if (realized_set != was_realized_set) - g_object_notify_by_pspec (obj, obj_props[PROP_REALIZED]); - - if (mapped_set != was_mapped_set) - g_object_notify_by_pspec (obj, obj_props[PROP_MAPPED]); - - if (visible_set != was_visible_set) - g_object_notify_by_pspec (obj, obj_props[PROP_VISIBLE]); - - g_object_thaw_notify (obj); - g_object_unref (obj); -} - -/** - * clutter_actor_unset_flags: - * @self: a #ClutterActor - * @flags: the flags to unset - * - * Unsets @flags on @self - * - * This function will emit notifications for the changed properties - */ -void -clutter_actor_unset_flags (ClutterActor *self, - ClutterActorFlags flags) -{ - ClutterActorFlags old_flags; - GObject *obj; - gboolean was_reactive_set, reactive_set; - gboolean was_realized_set, realized_set; - gboolean was_mapped_set, mapped_set; - gboolean was_visible_set, visible_set; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - obj = G_OBJECT (self); - g_object_freeze_notify (obj); - - old_flags = self->flags; - - was_reactive_set = ((old_flags & CLUTTER_ACTOR_REACTIVE) != 0); - was_realized_set = ((old_flags & CLUTTER_ACTOR_REALIZED) != 0); - was_mapped_set = ((old_flags & CLUTTER_ACTOR_MAPPED) != 0); - was_visible_set = ((old_flags & CLUTTER_ACTOR_VISIBLE) != 0); - - self->flags &= ~flags; - - if (self->flags == old_flags) - return; - - reactive_set = ((self->flags & CLUTTER_ACTOR_REACTIVE) != 0); - realized_set = ((self->flags & CLUTTER_ACTOR_REALIZED) != 0); - mapped_set = ((self->flags & CLUTTER_ACTOR_MAPPED) != 0); - visible_set = ((self->flags & CLUTTER_ACTOR_VISIBLE) != 0); - - if (reactive_set != was_reactive_set) - g_object_notify_by_pspec (obj, obj_props[PROP_REACTIVE]); - - if (realized_set != was_realized_set) - g_object_notify_by_pspec (obj, obj_props[PROP_REALIZED]); - - if (mapped_set != was_mapped_set) - g_object_notify_by_pspec (obj, obj_props[PROP_MAPPED]); - - if (visible_set != was_visible_set) - g_object_notify_by_pspec (obj, obj_props[PROP_VISIBLE]); - - g_object_thaw_notify (obj); -} - -static void -clutter_actor_set_transform_internal (ClutterActor *self, - const graphene_matrix_t *transform) -{ - ClutterTransformInfo *info; - gboolean was_set; - GObject *obj; - - obj = G_OBJECT (self); - - info = _clutter_actor_get_transform_info (self); - - was_set = info->transform_set; - - info->transform = *transform; - info->transform_set = !graphene_matrix_is_identity (&info->transform); - - transform_changed (self); - - clutter_actor_queue_redraw (self); - - g_object_notify_by_pspec (obj, obj_props[PROP_TRANSFORM]); - - if (was_set != info->transform_set) - g_object_notify_by_pspec (obj, obj_props[PROP_TRANSFORM_SET]); -} - -/** - * clutter_actor_set_transform: - * @self: a #ClutterActor - * @transform: (nullable): a #graphene_matrix_t, or %NULL to - * unset a custom transformation - * - * Overrides the transformations of a #ClutterActor with a custom - * matrix, which will be applied relative to the origin of the - * actor's allocation and to the actor's pivot point. - * - * The [property@Clutter.Actor:transform] property is animatable. - */ -void -clutter_actor_set_transform (ClutterActor *self, - const graphene_matrix_t *transform) -{ - const ClutterTransformInfo *info; - graphene_matrix_t new_transform; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_transform_info_or_defaults (self); - - if (transform != NULL) - graphene_matrix_init_from_matrix (&new_transform, transform); - else - graphene_matrix_init_identity (&new_transform); - - _clutter_actor_create_transition (self, obj_props[PROP_TRANSFORM], - &info->transform, - &new_transform); -} - -/** - * clutter_actor_get_transform: - * @self: a #ClutterActor - * @transform: (out caller-allocates): a #graphene_matrix_t - * - * Retrieves the current transformation matrix of a #ClutterActor. - */ -void -clutter_actor_get_transform (ClutterActor *self, - graphene_matrix_t *transform) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (transform != NULL); - - graphene_matrix_init_identity (transform); - _clutter_actor_apply_modelview_transform (self, transform); -} - -void -_clutter_actor_set_in_clone_paint (ClutterActor *self, - gboolean is_in_clone_paint) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - self->priv->in_clone_paint = is_in_clone_paint; -} - -/** - * clutter_actor_is_in_clone_paint: - * @self: a #ClutterActor - * - * Checks whether @self is being currently painted by a #ClutterClone - * - * This function is useful only inside implementations of the - * [vfunc@Clutter.Actor.paint] virtual function. - * - * This function should not be used by applications - * - * Return value: %TRUE if the #ClutterActor is currently being painted - * by a #ClutterClone, and %FALSE otherwise - */ -gboolean -clutter_actor_is_in_clone_paint (ClutterActor *self) -{ - ClutterActor *parent; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - if (self->priv->in_clone_paint) - return TRUE; - - if (self->priv->in_cloned_branch == 0) - return FALSE; - - parent = self->priv->parent; - while (parent != NULL) - { - if (parent->priv->in_cloned_branch == 0) - break; - - if (parent->priv->in_clone_paint) - return TRUE; - - parent = parent->priv->parent; - } - - return FALSE; -} - -gboolean -clutter_actor_is_painting_unmapped (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - return self->priv->unmapped_paint_branch_counter > 0; -} - -gboolean -clutter_actor_has_damage (ClutterActor *actor) -{ - return actor->priv->is_dirty; -} - -static gboolean -set_direction_recursive (ClutterActor *actor, - gpointer user_data) -{ - ClutterTextDirection text_dir = GPOINTER_TO_INT (user_data); - - clutter_actor_set_text_direction (actor, text_dir); - - return TRUE; -} - -/** - * clutter_actor_set_text_direction: - * @self: a #ClutterActor - * @text_dir: the text direction for @self - * - * Sets the #ClutterTextDirection for an actor - * - * The passed text direction must not be %CLUTTER_TEXT_DIRECTION_DEFAULT - * - * This function will recurse inside all the children of @self - */ -void -clutter_actor_set_text_direction (ClutterActor *self, - ClutterTextDirection text_dir) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (text_dir != CLUTTER_TEXT_DIRECTION_DEFAULT); - - priv = self->priv; - - if (priv->text_direction != text_dir) - { - priv->text_direction = text_dir; - - /* we need to emit the notify::text-direction first, so that - * the sub-classes can catch that and do specific handling of - * the text direction; see clutter_text_direction_changed_cb() - * inside clutter-text.c - */ - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_TEXT_DIRECTION]); - - _clutter_actor_foreach_child (self, set_direction_recursive, - GINT_TO_POINTER (text_dir)); - - clutter_actor_queue_relayout (self); - } -} - -void -_clutter_actor_set_has_pointer (ClutterActor *self, - gboolean has_pointer) -{ - ClutterActorPrivate *priv = self->priv; - - if (has_pointer) - { - g_assert (CLUTTER_IS_STAGE (self) || clutter_actor_is_mapped (self)); - - priv->n_pointers++; - } - else - { - g_assert (priv->n_pointers > 0); - - priv->n_pointers--; - } - - if (priv->n_pointers == 0 || priv->n_pointers == 1) - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_HAS_POINTER]); -} - -void -_clutter_actor_set_has_key_focus (ClutterActor *self, - gboolean has_key_focus) -{ - ClutterActorPrivate *priv = self->priv; - - if (priv->has_key_focus != has_key_focus) - { - priv->has_key_focus = has_key_focus; - - if (CLUTTER_ACTOR_IN_DESTRUCTION (self)) - return; - - if (has_key_focus) - g_signal_emit (self, actor_signals[KEY_FOCUS_IN], 0); - else - g_signal_emit (self, actor_signals[KEY_FOCUS_OUT], 0); - } -} - -/** - * clutter_actor_get_text_direction: - * @self: a #ClutterActor - * - * Retrieves the value set using clutter_actor_set_text_direction() - * - * If no text direction has been previously set, the default text - * direction, as returned by clutter_get_default_text_direction(), will - * be returned instead - * - * Return value: the #ClutterTextDirection for the actor - */ -ClutterTextDirection -clutter_actor_get_text_direction (ClutterActor *self) -{ - ClutterActorPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), - CLUTTER_TEXT_DIRECTION_LTR); - - priv = self->priv; - - /* if no direction has been set yet use the default */ - if (priv->text_direction == CLUTTER_TEXT_DIRECTION_DEFAULT) - priv->text_direction = clutter_get_default_text_direction (); - - return priv->text_direction; -} - -/** - * clutter_actor_has_pointer: - * @self: a #ClutterActor - * - * Checks whether an actor contains the pointer of a - * #ClutterInputDevice - * - * Return value: %TRUE if the actor contains the pointer, and - * %FALSE otherwise - */ -gboolean -clutter_actor_has_pointer (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - return self->priv->n_pointers > 0; -} - -/** - * clutter_actor_has_allocation: - * @self: a #ClutterActor - * - * Checks if the actor has an up-to-date allocation assigned to - * it. This means that the actor should have an allocation: it's - * visible and has a parent. It also means that there is no - * outstanding relayout request in progress for the actor or its - * children (There might be other outstanding layout requests in - * progress that will cause the actor to get a new allocation - * when the stage is laid out, however). - * - * If this function returns %FALSE, then the actor will normally - * be allocated before it is next drawn on the screen. - * - * Return value: %TRUE if the actor has an up-to-date allocation - */ -gboolean -clutter_actor_has_allocation (ClutterActor *self) -{ - ClutterActorPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - priv = self->priv; - - return priv->parent != NULL && - clutter_actor_is_visible (self) && - !priv->needs_allocation; -} - -static void -clutter_actor_add_action_internal (ClutterActor *self, - ClutterAction *action, - ClutterEventPhase phase) -{ - ClutterActorPrivate *priv; - - priv = self->priv; - - if (priv->actions == NULL) - { - priv->actions = g_object_new (CLUTTER_TYPE_META_GROUP, NULL); - priv->actions->actor = self; - } - - clutter_action_set_phase (action, phase); - _clutter_meta_group_add_meta (priv->actions, CLUTTER_ACTOR_META (action)); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ACTIONS]); -} - -/** - * clutter_actor_add_action: - * @self: a #ClutterActor - * @action: a #ClutterAction - * - * Adds @action to the list of actions applied to @self - * - * A #ClutterAction can only belong to one actor at a time - * - * The #ClutterActor will hold a reference on @action until either - * [method@Clutter.Actor.remove_action] or [method@Clutter.Actor.clear_actions] - * is called - */ -void -clutter_actor_add_action (ClutterActor *self, - ClutterAction *action) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (CLUTTER_IS_ACTION (action)); - - clutter_actor_add_action_internal (self, action, CLUTTER_PHASE_BUBBLE); -} - -/** - * clutter_actor_add_action_with_name: - * @self: a #ClutterActor - * @name: the name to set on the action - * @action: a #ClutterAction - * - * A convenience function for setting the name of a #ClutterAction - * while adding it to the list of actions applied to @self - * - * This function is the logical equivalent of: - * - * ```c - * clutter_actor_meta_set_name (CLUTTER_ACTOR_META (action), name); - * clutter_actor_add_action (self, action); - * ``` - */ -void -clutter_actor_add_action_with_name (ClutterActor *self, - const gchar *name, - ClutterAction *action) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (name != NULL); - g_return_if_fail (CLUTTER_IS_ACTION (action)); - - clutter_actor_meta_set_name (CLUTTER_ACTOR_META (action), name); - clutter_actor_add_action (self, action); -} - -void -clutter_actor_add_action_full (ClutterActor *self, - const char *name, - ClutterEventPhase phase, - ClutterAction *action) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (name != NULL); - g_return_if_fail (CLUTTER_IS_ACTION (action)); - g_return_if_fail (phase == CLUTTER_PHASE_BUBBLE || - phase == CLUTTER_PHASE_CAPTURE); - - clutter_actor_meta_set_name (CLUTTER_ACTOR_META (action), name); - clutter_actor_add_action_internal (self, action, phase); -} - -/** - * clutter_actor_remove_action: - * @self: a #ClutterActor - * @action: a #ClutterAction - * - * Removes @action from the list of actions applied to @self - * - * The reference held by @self on the #ClutterAction will be released - */ -void -clutter_actor_remove_action (ClutterActor *self, - ClutterAction *action) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (CLUTTER_IS_ACTION (action)); - - priv = self->priv; - - if (priv->actions == NULL) - return; - - _clutter_meta_group_remove_meta (priv->actions, CLUTTER_ACTOR_META (action)); - - if (_clutter_meta_group_peek_metas (priv->actions) == NULL) - g_clear_object (&priv->actions); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ACTIONS]); -} - -/** - * clutter_actor_remove_action_by_name: - * @self: a #ClutterActor - * @name: the name of the action to remove - * - * Removes the #ClutterAction with the given name from the list - * of actions applied to @self - */ -void -clutter_actor_remove_action_by_name (ClutterActor *self, - const gchar *name) -{ - ClutterActorPrivate *priv; - ClutterActorMeta *meta; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (name != NULL); - - priv = self->priv; - - if (priv->actions == NULL) - return; - - meta = _clutter_meta_group_get_meta (priv->actions, name); - if (meta == NULL) - return; - - _clutter_meta_group_remove_meta (priv->actions, meta); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ACTIONS]); -} - -/** - * clutter_actor_get_actions: - * @self: a #ClutterActor - * - * Retrieves the list of actions applied to @self - * - * Return value: (transfer container) (element-type Clutter.Action): a copy - * of the list of `ClutterAction`s. The contents of the list are - * owned by the #ClutterActor. Use g_list_free() to free the resources - * allocated by the returned #GList - */ -GList * -clutter_actor_get_actions (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - if (self->priv->actions == NULL) - return NULL; - - return _clutter_meta_group_get_metas_no_internal (self->priv->actions); -} - -/** - * clutter_actor_get_action: - * @self: a #ClutterActor - * @name: the name of the action to retrieve - * - * Retrieves the #ClutterAction with the given name in the list - * of actions applied to @self - * - * Return value: (transfer none) (nullable): a #ClutterAction for the given - * name, or %NULL. The returned #ClutterAction is owned by the - * actor and it should not be unreferenced directly - */ -ClutterAction * -clutter_actor_get_action (ClutterActor *self, - const gchar *name) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - g_return_val_if_fail (name != NULL, NULL); - - if (self->priv->actions == NULL) - return NULL; - - return CLUTTER_ACTION (_clutter_meta_group_get_meta (self->priv->actions, name)); -} - -/** - * clutter_actor_clear_actions: - * @self: a #ClutterActor - * - * Clears the list of actions applied to @self - */ -void -clutter_actor_clear_actions (ClutterActor *self) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (self->priv->actions == NULL) - return; - - _clutter_meta_group_clear_metas_no_internal (self->priv->actions); -} - -/** - * clutter_actor_add_constraint: - * @self: a #ClutterActor - * @constraint: a #ClutterConstraint - * - * Adds @constraint to the list`of `ClutterConstraint`s applied - * to @self - * - * The #ClutterActor will hold a reference on the @constraint until - * either [method@Clutter.Actor.remove_constraint] or - * [method@Clutter.Actor.clear_constraints] is called. - */ -void -clutter_actor_add_constraint (ClutterActor *self, - ClutterConstraint *constraint) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (CLUTTER_IS_CONSTRAINT (constraint)); - - priv = self->priv; - - if (priv->constraints == NULL) - { - priv->constraints = g_object_new (CLUTTER_TYPE_META_GROUP, NULL); - priv->constraints->actor = self; - } - - _clutter_meta_group_add_meta (priv->constraints, - CLUTTER_ACTOR_META (constraint)); - clutter_actor_queue_relayout (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CONSTRAINTS]); -} - -/** - * clutter_actor_add_constraint_with_name: - * @self: a #ClutterActor - * @name: the name to set on the constraint - * @constraint: a #ClutterConstraint - * - * A convenience function for setting the name of a #ClutterConstraint - * while adding it to the list of constraints applied to @self - * - * This function is the logical equivalent of: - * - * ```c - * clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), name); - * clutter_actor_add_constraint (self, constraint); - * ``` - */ -void -clutter_actor_add_constraint_with_name (ClutterActor *self, - const gchar *name, - ClutterConstraint *constraint) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (name != NULL); - g_return_if_fail (CLUTTER_IS_CONSTRAINT (constraint)); - - clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), name); - clutter_actor_add_constraint (self, constraint); -} - -/** - * clutter_actor_remove_constraint: - * @self: a #ClutterActor - * @constraint: a #ClutterConstraint - * - * Removes @constraint from the list of constraints applied to @self - * - * The reference held by @self on the #ClutterConstraint will be released - */ -void -clutter_actor_remove_constraint (ClutterActor *self, - ClutterConstraint *constraint) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (CLUTTER_IS_CONSTRAINT (constraint)); - - priv = self->priv; - - if (priv->constraints == NULL) - return; - - _clutter_meta_group_remove_meta (priv->constraints, - CLUTTER_ACTOR_META (constraint)); - - if (_clutter_meta_group_peek_metas (priv->constraints) == NULL) - g_clear_object (&priv->constraints); - - clutter_actor_queue_relayout (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CONSTRAINTS]); -} - -/** - * clutter_actor_remove_constraint_by_name: - * @self: a #ClutterActor - * @name: the name of the constraint to remove - * - * Removes the #ClutterConstraint with the given name from the list - * of constraints applied to @self - */ -void -clutter_actor_remove_constraint_by_name (ClutterActor *self, - const gchar *name) -{ - ClutterActorPrivate *priv; - ClutterActorMeta *meta; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (name != NULL); - - priv = self->priv; - - if (priv->constraints == NULL) - return; - - meta = _clutter_meta_group_get_meta (priv->constraints, name); - if (meta == NULL) - return; - - _clutter_meta_group_remove_meta (priv->constraints, meta); - clutter_actor_queue_relayout (self); -} - -/** - * clutter_actor_get_constraints: - * @self: a #ClutterActor - * - * Retrieves the list of constraints applied to @self - * - * Return value: (transfer container) (element-type Clutter.Constraint): a copy - * of the list of `ClutterConstraint`s. The contents of the list are - * owned by the #ClutterActor. Use g_list_free() to free the resources - * allocated by the returned #GList - */ -GList * -clutter_actor_get_constraints (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - if (self->priv->constraints == NULL) - return NULL; - - return _clutter_meta_group_get_metas_no_internal (self->priv->constraints); -} - -/** - * clutter_actor_get_constraint: - * @self: a #ClutterActor - * @name: the name of the constraint to retrieve - * - * Retrieves the #ClutterConstraint with the given name in the list - * of constraints applied to @self - * - * Return value: (transfer none) (nullable): a #ClutterConstraint for the given - * name, or %NULL. The returned #ClutterConstraint is owned by the - * actor and it should not be unreferenced directly - */ -ClutterConstraint * -clutter_actor_get_constraint (ClutterActor *self, - const gchar *name) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - g_return_val_if_fail (name != NULL, NULL); - - if (self->priv->constraints == NULL) - return NULL; - - return CLUTTER_CONSTRAINT (_clutter_meta_group_get_meta (self->priv->constraints, name)); -} - -/** - * clutter_actor_clear_constraints: - * @self: a #ClutterActor - * - * Clears the list of constraints applied to @self - */ -void -clutter_actor_clear_constraints (ClutterActor *self) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (self->priv->constraints == NULL) - return; - - _clutter_meta_group_clear_metas_no_internal (self->priv->constraints); - - clutter_actor_queue_relayout (self); -} - -/** - * clutter_actor_set_clip_to_allocation: - * @self: a #ClutterActor - * @clip_set: %TRUE to apply a clip tracking the allocation - * - * Sets whether @self should be clipped to the same size as its - * allocation - */ -void -clutter_actor_set_clip_to_allocation (ClutterActor *self, - gboolean clip_set) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - clip_set = !!clip_set; - - priv = self->priv; - - if (priv->clip_to_allocation != clip_set) - { - priv->clip_to_allocation = clip_set; - - queue_update_paint_volume (self); - clutter_actor_queue_redraw (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CLIP_TO_ALLOCATION]); - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_HAS_CLIP]); - } -} - -/** - * clutter_actor_get_clip_to_allocation: - * @self: a #ClutterActor - * - * Retrieves the value set using clutter_actor_set_clip_to_allocation() - * - * Return value: %TRUE if the #ClutterActor is clipped to its allocation - */ -gboolean -clutter_actor_get_clip_to_allocation (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - return self->priv->clip_to_allocation; -} - -/** - * clutter_actor_add_effect: - * @self: a #ClutterActor - * @effect: a #ClutterEffect - * - * Adds @effect to the list of [class@Clutter.Effect]s applied to @self - * - * The #ClutterActor will hold a reference on the @effect until either - * [method@Clutter.Actor.remove_effect] or [method@Clutter.Actor.clear_effects] is - * called. - */ -void -clutter_actor_add_effect (ClutterActor *self, - ClutterEffect *effect) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (CLUTTER_IS_EFFECT (effect)); - - _clutter_actor_add_effect_internal (self, effect); - - clutter_actor_queue_redraw (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_EFFECT]); -} - -/** - * clutter_actor_add_effect_with_name: - * @self: a #ClutterActor - * @name: the name to set on the effect - * @effect: a #ClutterEffect - * - * A convenience function for setting the name of a #ClutterEffect - * while adding it to the list of effectss applied to @self - * - * This function is the logical equivalent of: - * - * ```c - * clutter_actor_meta_set_name (CLUTTER_ACTOR_META (effect), name); - * clutter_actor_add_effect (self, effect); - * ``` - */ -void -clutter_actor_add_effect_with_name (ClutterActor *self, - const gchar *name, - ClutterEffect *effect) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (name != NULL); - g_return_if_fail (CLUTTER_IS_EFFECT (effect)); - - clutter_actor_meta_set_name (CLUTTER_ACTOR_META (effect), name); - clutter_actor_add_effect (self, effect); -} - -/** - * clutter_actor_remove_effect: - * @self: a #ClutterActor - * @effect: a #ClutterEffect - * - * Removes @effect from the list of effects applied to @self - * - * The reference held by @self on the #ClutterEffect will be released - */ -void -clutter_actor_remove_effect (ClutterActor *self, - ClutterEffect *effect) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (CLUTTER_IS_EFFECT (effect)); - - _clutter_actor_remove_effect_internal (self, effect); - - clutter_actor_queue_redraw (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_EFFECT]); -} - -/** - * clutter_actor_remove_effect_by_name: - * @self: a #ClutterActor - * @name: the name of the effect to remove - * - * Removes the #ClutterEffect with the given name from the list - * of effects applied to @self - */ -void -clutter_actor_remove_effect_by_name (ClutterActor *self, - const gchar *name) -{ - ClutterActorPrivate *priv; - ClutterActorMeta *meta; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (name != NULL); - - priv = self->priv; - - if (priv->effects == NULL) - return; - - meta = _clutter_meta_group_get_meta (priv->effects, name); - if (meta == NULL) - return; - - clutter_actor_remove_effect (self, CLUTTER_EFFECT (meta)); -} - -/** - * clutter_actor_get_effects: - * @self: a #ClutterActor - * - * Retrieves the `ClutterEffect`s applied on @self, if any - * - * Return value: (transfer container) (element-type Clutter.Effect): a list - * of `ClutterEffect`s, or %NULL. The elements of the returned - * list are owned by Clutter and they should not be freed. You should - * free the returned list using g_list_free() when done - */ -GList * -clutter_actor_get_effects (ClutterActor *self) -{ - ClutterActorPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - priv = self->priv; - - if (priv->effects == NULL) - return NULL; - - return _clutter_meta_group_get_metas_no_internal (priv->effects); -} - -/** - * clutter_actor_get_effect: - * @self: a #ClutterActor - * @name: the name of the effect to retrieve - * - * Retrieves the #ClutterEffect with the given name in the list - * of effects applied to @self - * - * Return value: (transfer none) (nullable): a #ClutterEffect for the given - * name, or %NULL. The returned #ClutterEffect is owned by the - * actor and it should not be unreferenced directly - */ -ClutterEffect * -clutter_actor_get_effect (ClutterActor *self, - const gchar *name) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - g_return_val_if_fail (name != NULL, NULL); - - if (self->priv->effects == NULL) - return NULL; - - return CLUTTER_EFFECT (_clutter_meta_group_get_meta (self->priv->effects, name)); -} - -/** - * clutter_actor_clear_effects: - * @self: a #ClutterActor - * - * Clears the list of effects applied to @self - */ -void -clutter_actor_clear_effects (ClutterActor *self) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (self->priv->effects == NULL) - return; - - _clutter_meta_group_clear_metas_no_internal (self->priv->effects); - - clutter_actor_queue_redraw (self); -} - -/** - * clutter_actor_has_key_focus: - * @self: a #ClutterActor - * - * Checks whether @self is the #ClutterActor that has key focus - * - * Return value: %TRUE if the actor has key focus, and %FALSE otherwise - */ -gboolean -clutter_actor_has_key_focus (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - return self->priv->has_key_focus; -} - -static gboolean -_clutter_actor_get_paint_volume_real (ClutterActor *self, - ClutterPaintVolume *pv) -{ - ClutterActorPrivate *priv = self->priv; - - /* Actors are only expected to report a valid paint volume - * while they have a valid allocation. */ - if (G_UNLIKELY (priv->needs_allocation)) - { - CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): " - "Actor needs allocation", - _clutter_actor_get_debug_name (self)); - return FALSE; - } - - _clutter_paint_volume_init_static (pv, self); - - if (!CLUTTER_ACTOR_GET_CLASS (self)->get_paint_volume (self, pv)) - { - clutter_paint_volume_free (pv); - CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): " - "Actor failed to report a volume", - _clutter_actor_get_debug_name (self)); - return FALSE; - } - - /* since effects can modify the paint volume, we allow them to actually - * do this by making get_paint_volume() "context sensitive" - */ - if (priv->effects != NULL) - { - if (priv->current_effect != NULL) - { - const GList *effects, *l; - - /* if we are being called from within the paint sequence of - * an actor, get the paint volume up to the current effect - */ - effects = _clutter_meta_group_peek_metas (priv->effects); - for (l = effects; - l != NULL && l->data != priv->current_effect; - l = l->next) - { - if (!_clutter_effect_modify_paint_volume (l->data, pv)) - { - clutter_paint_volume_free (pv); - CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): " - "Effect (%s) failed to report a volume", - _clutter_actor_get_debug_name (self), - _clutter_actor_meta_get_debug_name (l->data)); - return FALSE; - } - } - } - else - { - const GList *effects, *l; - - /* otherwise, get the cumulative volume */ - effects = _clutter_meta_group_peek_metas (priv->effects); - for (l = effects; l != NULL; l = l->next) - if (!_clutter_effect_modify_paint_volume (l->data, pv)) - { - clutter_paint_volume_free (pv); - CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): " - "Effect (%s) failed to report a volume", - _clutter_actor_get_debug_name (self), - _clutter_actor_meta_get_debug_name (l->data)); - return FALSE; - } - } - } - - return TRUE; -} - -static gboolean -_clutter_actor_has_active_paint_volume_override_effects (ClutterActor *self) -{ - const GList *l; - - if (self->priv->effects == NULL) - return FALSE; - - /* We just need to all effects current effect to see - * if anyone wants to override the paint volume. If so, then - * we need to recompute, since the paint volume returned can - * change from call to call. */ - for (l = _clutter_meta_group_peek_metas (self->priv->effects); - l != NULL; - l = l->next) - { - ClutterEffect *effect = l->data; - - if (clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)) && - _clutter_effect_has_custom_paint_volume (effect)) - return TRUE; - } - - return FALSE; -} - -static void -ensure_paint_volume (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - gboolean has_paint_volume_override_effects; - gboolean must_update_paint_volume; - - has_paint_volume_override_effects = _clutter_actor_has_active_paint_volume_override_effects (self); - - /* If effects are applied, the actor paint volume - * needs to be recomputed on each paint, since those - * paint volumes could change over the duration of the - * effect. - * - * We also need to update the paint volume if we went - * from having effects to not having effects on the last - * paint volume update. - * - * FIXME: This opens the door for some tricky issues: If our paint volume - * is invalid, it's implied that all parent paint volumes are invalid. If - * we don't want to break that invariant, we should find a better solution - * to deal with effects. - */ - must_update_paint_volume = - priv->current_effect != NULL || - has_paint_volume_override_effects || - priv->had_effects_on_last_paint_volume_update; - - priv->needs_paint_volume_update |= must_update_paint_volume; - - if (priv->needs_paint_volume_update) - { - priv->had_effects_on_last_paint_volume_update = has_paint_volume_override_effects; - - if (priv->has_paint_volume) - clutter_paint_volume_free (&priv->paint_volume); - - priv->has_paint_volume = FALSE; - - if (_clutter_actor_get_paint_volume_real (self, &priv->paint_volume)) - { - priv->has_paint_volume = TRUE; - priv->needs_paint_volume_update = FALSE; - } - } -} - -/* The public clutter_actor_get_paint_volume API returns a const - * pointer since we return a pointer directly to the cached - * PaintVolume associated with the actor and don't want the user to - * inadvertently modify it, but for internal uses we sometimes need - * access to the same PaintVolume but need to apply some book-keeping - * modifications to it so we don't want a const pointer. - */ -static ClutterPaintVolume * -_clutter_actor_get_paint_volume_mutable (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - - ensure_paint_volume (self); - - if (priv->has_paint_volume) - return &priv->paint_volume; - - return NULL; -} - -/** - * clutter_actor_get_paint_volume: - * @self: a #ClutterActor - * - * Retrieves the paint volume of the passed #ClutterActor, or %NULL - * when a paint volume can't be determined. - * - * The paint volume is defined as the 3D space occupied by an actor - * when being painted. - * - * This function will call the [vfunc@Clutter.Actor.get_paint_volume] - * virtual function of the #ClutterActor class. Sub-classes of #ClutterActor - * should not usually care about overriding the default implementation, - * unless they are, for instance: painting outside their allocation, or - * actors with a depth factor (not in terms of depth but real - * 3D depth). - * - * Note: 2D actors overriding [vfunc@Clutter.Actor.get_paint_volume] - * should ensure that their volume has a depth of 0. (This will be true - * as long as you don't call [method@Clutter.PaintVolume.set_depth].) - * - * Return value: (transfer none) (nullable): a pointer to a #ClutterPaintVolume, - * or %NULL if no volume could be determined. The returned pointer - * is not guaranteed to be valid across multiple frames; if you want - * to keep it, you will need to copy it using [method@Clutter.PaintVolume.copy]. - */ -const ClutterPaintVolume * -clutter_actor_get_paint_volume (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - return _clutter_actor_get_paint_volume_mutable (self); -} - -/** - * clutter_actor_get_transformed_paint_volume: - * @self: a #ClutterActor - * @relative_to_ancestor: A #ClutterActor that is an ancestor of @self - * (or %NULL for the stage) - * - * Retrieves the 3D paint volume of an actor like - * [method@Clutter.Actor.get_paint_volume] does and it additionally - * transforms the paint volume into the coordinate - * space of @relative_to_ancestor. (Or the stage if %NULL - * is passed for @relative_to_ancestor) - * - * This can be used by containers that base their paint volume on - * the volume of their children. Such containers can query the - * transformed paint volume of all of its children and union them - * together using [method@Clutter.PaintVolume.union]. - * - * Return value: (transfer full) (nullable): a pointer to a #ClutterPaintVolume, - * or %NULL if no volume could be determined. - */ -ClutterPaintVolume * -clutter_actor_get_transformed_paint_volume (ClutterActor *self, - ClutterActor *relative_to_ancestor) -{ - const ClutterPaintVolume *volume; - ClutterActor *stage; - ClutterPaintVolume *transformed_volume; - - stage = _clutter_actor_get_stage_internal (self); - if (G_UNLIKELY (stage == NULL)) - return NULL; - - if (relative_to_ancestor == NULL) - relative_to_ancestor = stage; - - volume = clutter_actor_get_paint_volume (self); - if (volume == NULL) - return NULL; - - transformed_volume = clutter_paint_volume_copy (volume); - - _clutter_paint_volume_transform_relative (transformed_volume, - relative_to_ancestor); - - return transformed_volume; -} - -/** - * clutter_actor_get_paint_box: - * @self: a #ClutterActor - * @box: (out): return location for a #ClutterActorBox - * - * Retrieves the paint volume of the passed #ClutterActor, and - * transforms it into a 2D bounding box in stage coordinates. - * - * This function is useful to determine the on screen area occupied by - * the actor. The box is only an approximation and may often be - * considerably larger due to the optimizations used to calculate the - * box. The box is never smaller though, so it can reliably be used - * for culling. - * - * There are times when a 2D paint box can't be determined, e.g. - * because the actor isn't yet parented under a stage or because - * the actor is unable to determine a paint volume. - * - * Return value: %TRUE if a 2D paint box could be determined, else - * %FALSE. - */ -gboolean -clutter_actor_get_paint_box (ClutterActor *self, - ClutterActorBox *box) -{ - ClutterActor *stage; - ClutterPaintVolume *pv; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - g_return_val_if_fail (box != NULL, FALSE); - - stage = _clutter_actor_get_stage_internal (self); - if (G_UNLIKELY (!stage)) - return FALSE; - - pv = _clutter_actor_get_paint_volume_mutable (self); - if (G_UNLIKELY (!pv)) - return FALSE; - - _clutter_paint_volume_get_stage_paint_box (pv, CLUTTER_STAGE (stage), box); - - return TRUE; -} - -static ClutterActorTraverseVisitFlags -clear_stage_views_cb (ClutterActor *actor, - int depth, - gpointer user_data) -{ - gboolean stop_transitions = GPOINTER_TO_INT (user_data); - g_autoptr (GList) old_stage_views = NULL; - - if (stop_transitions) - _clutter_actor_stop_transitions (actor); - - actor->priv->needs_update_stage_views = TRUE; - actor->priv->needs_finish_layout = TRUE; - - old_stage_views = g_steal_pointer (&actor->priv->stage_views); - - if (old_stage_views || CLUTTER_ACTOR_IS_TOPLEVEL (actor)) - actor->priv->clear_stage_views_needs_stage_views_changed = TRUE; - - return CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE; -} - -static ClutterActorTraverseVisitFlags -maybe_emit_stage_views_changed_cb (ClutterActor *actor, - int depth, - gpointer user_data) -{ - if (actor->priv->clear_stage_views_needs_stage_views_changed) - { - actor->priv->clear_stage_views_needs_stage_views_changed = FALSE; - g_signal_emit (actor, actor_signals[STAGE_VIEWS_CHANGED], 0); - } - - return CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE; -} - -void -clutter_actor_clear_stage_views_recursive (ClutterActor *self, - gboolean stop_transitions) -{ - _clutter_actor_traverse (self, - CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST, - clear_stage_views_cb, - NULL, - GINT_TO_POINTER (stop_transitions)); - _clutter_actor_traverse (self, - CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST, - maybe_emit_stage_views_changed_cb, - NULL, - NULL); -} - -float -clutter_actor_get_real_resource_scale (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - float guessed_scale; - - if (priv->resource_scale != -1.f) - return priv->resource_scale; - - /* If the scale hasn't been computed yet, we return a best guess */ - - if (priv->parent != NULL) - { - /* If the scale hasn't been calculated yet, assume this actor is located - * inside its parents box and go up the hierarchy. - */ - guessed_scale = clutter_actor_get_real_resource_scale (priv->parent); - } - else if (CLUTTER_ACTOR_IS_TOPLEVEL (self)) - { - /* This must be the first allocation cycle and the resource scale of - * the stage has not been updated yet, so return it manually. - */ - GList *l; - ClutterStage *stage = CLUTTER_STAGE (self); - float max_scale = -1.f; - - for (l = clutter_stage_peek_stage_views (stage); l; l = l->next) - { - ClutterStageView *view = l->data; - - max_scale = MAX (clutter_stage_view_get_scale (view), max_scale); - } - - if (max_scale < 0.f) - max_scale = 1.f; - - guessed_scale = max_scale; - } - else - { - ClutterBackend *backend = clutter_get_default_backend (); - - guessed_scale = clutter_backend_get_fallback_resource_scale (backend); - } - - g_assert (guessed_scale >= 0.5); - - /* Always return this value until we compute the correct one later. - * If our guess turns out to be wrong, we'll emit "resource-scale-changed" - * and correct it before painting. - */ - priv->resource_scale = guessed_scale; - - return priv->resource_scale; -} - -/** - * clutter_actor_get_resource_scale: - * @self: A #ClutterActor - * - * Retrieves the resource scale for this actor. - * - * The resource scale refers to the scale the actor should use for its resources. - * For example if an actor draws a a picture of size 100 x 100 in the stage - * coordinate space, it should use a texture of twice the size (i.e. 200 x 200) - * if the resource scale is 2. - * - * The resource scale is determined by calculating the highest #ClutterStageView - * scale the actor will get painted on. - * - * Note that the scale returned by this function is only guaranteed to be - * correct when queried during the paint cycle, in all other cases this - * function will only return a best guess. If your implementation really - * needs to get a resource scale outside of the paint cycle, make sure to - * subscribe to the "resource-scale-changed" signal to get notified about - * the new, correct resource scale before painting. - * - * Also avoid getting the resource scale for actors that are not attached - * to a stage. There's no sane way for Clutter to guess which #ClutterStageView - * the actor is going to be painted on, so you'll probably end up receiving - * the "resource-scale-changed" signal and having to rebuild your resources. - * - * The best guess this function may return is usually just the last resource - * scale the actor got painted with. If this resource scale couldn't be found - * because the actor was never painted so far or Clutter was unable to - * determine its position and size, this function will return the resource - * scale of a parent. - * - * Returns: The resource scale the actor should use for its textures - */ -float -clutter_actor_get_resource_scale (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 1.f); - - return ceilf (clutter_actor_get_real_resource_scale (self)); -} - -static void -add_actor_to_redraw_clip (ClutterActor *self, - gboolean actor_moved, - ClutterPaintVolume *old_visible_paint_volume) -{ - ClutterActorPrivate *priv = self->priv; - ClutterStage *stage = CLUTTER_STAGE (_clutter_actor_get_stage_internal (self)); - - if (priv->next_redraw_clips->len != 0) - { - unsigned int i; - - for (i = 0; i < priv->next_redraw_clips->len; i++) - clutter_stage_add_to_redraw_clip (stage, &g_array_index (priv->next_redraw_clips, ClutterPaintVolume, i)); - - priv->next_redraw_clips->len = 0; - } - else if (actor_moved) - { - /* For a clipped redraw to work we need both the old paint volume and the new - * one, if any is missing we'll need to do an unclipped redraw. - */ - if (old_visible_paint_volume == NULL || !priv->visible_paint_volume_valid) - goto full_stage_redraw; - - clutter_stage_add_to_redraw_clip (stage, old_visible_paint_volume); - clutter_stage_add_to_redraw_clip (stage, &priv->visible_paint_volume); - } - else - { - if (!priv->visible_paint_volume_valid) - goto full_stage_redraw; - - clutter_stage_add_to_redraw_clip (stage, &priv->visible_paint_volume); - } - - return; - -full_stage_redraw: - clutter_stage_add_to_redraw_clip (stage, NULL); -} - -static gboolean -sorted_lists_equal (GList *list_a, - GList *list_b) -{ - GList *a, *b; - - if (!list_a && !list_b) - return TRUE; - - for (a = list_a, b = list_b; - a && b; - a = a->next, b = b->next) - { - if (a->data != b->data) - break; - - if (!a->next && !b->next) - return TRUE; - } - - return FALSE; -} - -static void -update_stage_views (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - g_autoptr (GList) old_stage_views = NULL; - ClutterStage *stage; - graphene_rect_t bounding_rect; - - if (CLUTTER_ACTOR_IS_TOPLEVEL (self)) - return; - - stage = CLUTTER_STAGE (_clutter_actor_get_stage_internal (self)); - g_return_if_fail (stage); - - old_stage_views = g_steal_pointer (&priv->stage_views); - - if (priv->needs_allocation) - { - g_warning ("Can't update stage views actor %s is on because it needs an " - "allocation.", _clutter_actor_get_debug_name (self)); - priv->stage_views = g_list_copy (clutter_stage_peek_stage_views (stage)); - goto out; - } - - clutter_actor_get_transformed_extents (self, &bounding_rect); - - if (bounding_rect.size.width == 0.0 || - bounding_rect.size.height == 0.0) - goto out; - - priv->stage_views = clutter_stage_get_views_for_rect (stage, - &bounding_rect); - -out: - if (!sorted_lists_equal (old_stage_views, priv->stage_views)) - g_signal_emit (self, actor_signals[STAGE_VIEWS_CHANGED], 0); -} - -static void -update_resource_scale (ClutterActor *self, - int phase) -{ - ClutterActorPrivate *priv = self->priv; - float new_resource_scale, old_resource_scale; - - new_resource_scale = - CLUTTER_ACTOR_GET_CLASS (self)->calculate_resource_scale (self, phase); - - if (priv->resource_scale == new_resource_scale) - return; - - /* If the actor moved out of the stage, simply keep the last scale */ - if (new_resource_scale == -1.f) - return; - - old_resource_scale = priv->resource_scale; - priv->resource_scale = new_resource_scale; - - /* Never notify the initial change, otherwise, to be consistent, - * we'd also have to notify if we guessed correctly in - * clutter_actor_get_real_resource_scale(). - */ - if (old_resource_scale == -1.f) - return; - - if (ceilf (old_resource_scale) != ceilf (priv->resource_scale)) - g_signal_emit (self, actor_signals[RESOURCE_SCALE_CHANGED], 0); -} - -void -clutter_actor_finish_layout (ClutterActor *self, - gboolean use_max_scale) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActor *child; - gboolean actor_moved = FALSE; - gboolean old_visible_paint_volume_valid = FALSE; - ClutterPaintVolume old_visible_paint_volume; - - if (!priv->needs_finish_layout) - return; - - if ((!clutter_actor_is_mapped (self) && - !clutter_actor_has_mapped_clones (self)) || - CLUTTER_ACTOR_IN_DESTRUCTION (self)) - return; - - if (priv->needs_visible_paint_volume_update) - { - ensure_paint_volume (self); - - actor_moved = TRUE; - old_visible_paint_volume = priv->visible_paint_volume; - old_visible_paint_volume_valid = priv->visible_paint_volume_valid; - - if (priv->has_paint_volume) - { - _clutter_paint_volume_copy_static (&priv->paint_volume, - &priv->visible_paint_volume); - _clutter_paint_volume_transform_relative (&priv->visible_paint_volume, - NULL); /* eye coordinates */ - } - - priv->visible_paint_volume_valid = priv->has_paint_volume; - priv->needs_visible_paint_volume_update = FALSE; - } - - if (priv->needs_update_stage_views) - { - update_stage_views (self); - update_resource_scale (self, use_max_scale); - - priv->needs_update_stage_views = FALSE; - } - - if (priv->needs_redraw) - { - add_actor_to_redraw_clip (self, - actor_moved, - old_visible_paint_volume_valid ? &old_visible_paint_volume : NULL); - priv->needs_redraw = FALSE; - } - - priv->needs_finish_layout = FALSE; - - for (child = priv->first_child; child; child = child->priv->next_sibling) - clutter_actor_finish_layout (child, use_max_scale); -} - -/** - * clutter_actor_peek_stage_views: - * @self: A #ClutterActor - * - * Retrieves the list of `ClutterStageView`s the actor is being - * painted on. - * - * If this function is called during the paint cycle, the list is guaranteed - * to be up-to-date, if called outside the paint cycle, the list will - * contain the views the actor was painted on last. - * - * The list returned by this function is not updated when the actors - * visibility changes: If an actor gets hidden and is not being painted - * anymore, this function will return the list of views the actor was - * painted on last. - * - * If an actor is not attached to a stage (realized), this function will - * always return an empty list. - * - * Returns: (transfer none) (element-type Clutter.StageView): The list of - * `ClutterStageView`s the actor is being painted on. The list and - * its contents are owned by the #ClutterActor and the list may not be - * freed or modified. - */ -GList * -clutter_actor_peek_stage_views (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - return CLUTTER_ACTOR_IS_TOPLEVEL (self) - ? clutter_stage_peek_stage_views (CLUTTER_STAGE (self)) - : self->priv->stage_views; -} - -gboolean -clutter_actor_is_effectively_on_stage_view (ClutterActor *self, - ClutterStageView *view) -{ - ClutterActor *actor; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - if (!clutter_actor_is_mapped (self) && - !clutter_actor_has_mapped_clones (self)) - return FALSE; - - if (g_list_find (clutter_actor_peek_stage_views (self), view)) - return TRUE; - - for (actor = self; actor; actor = actor->priv->parent) - { - if (actor->priv->clones) - { - GHashTableIter iter; - gpointer key; - - g_hash_table_iter_init (&iter, actor->priv->clones); - while (g_hash_table_iter_next (&iter, &key, NULL)) - { - ClutterActor *clone = key; - GList *clone_views; - - if (!clutter_actor_is_mapped (clone)) - continue; - - clone_views = clutter_actor_peek_stage_views (clone); - if (g_list_find (clone_views, view)) - return TRUE; - } - } - - /* Clones will force-show their own source actor but not children of - * it, so if we're hidden and an actor up the hierarchy has a clone, - * we won't be visible. - */ - if (!clutter_actor_is_visible (actor)) - return FALSE; - } - - return FALSE; -} - -/** - * clutter_actor_pick_frame_clock: (skip) - * @self: a #ClutterActor - * @out_actor: (out) (nullable) (optional): a pointer to an #ClutterActor - * - * Pick the most suitable frame clock for driving animations for this actor. - * - * The #ClutterActor used for picking the frame clock is written @out_actor. - * - * Returns: (transfer none) (nullable): a #ClutterFrameClock - */ -ClutterFrameClock * -clutter_actor_pick_frame_clock (ClutterActor *self, - ClutterActor **out_actor) -{ - ClutterActorPrivate *priv = self->priv; - GList *stage_views_list; - float max_refresh_rate = 0.0; - ClutterStageView *best_view = NULL; - GList *l; - - stage_views_list = clutter_actor_peek_stage_views (self); - - if (!stage_views_list) - { - if (priv->parent) - return clutter_actor_pick_frame_clock (priv->parent, out_actor); - else - return NULL; - } - - for (l = stage_views_list; l; l = l->next) - { - ClutterStageView *view = CLUTTER_STAGE_VIEW (l->data); - float refresh_rate; - - refresh_rate = clutter_stage_view_get_refresh_rate (view); - if (refresh_rate > max_refresh_rate) - { - best_view = view; - max_refresh_rate = refresh_rate; - } - } - - if (best_view) - { - if (out_actor) - *out_actor = self; - return clutter_stage_view_get_frame_clock (best_view); - } - else - { - return NULL; - } -} - -/** - * clutter_actor_has_overlaps: - * @self: A #ClutterActor - * - * Asks the actor's implementation whether it may contain overlapping - * primitives. - * - * For example; Clutter may use this to determine whether the painting - * should be redirected to an offscreen buffer to correctly implement - * the opacity property. - * - * Custom actors can override the default response by implementing the - * [vfunc@Clutter.Actor.has_overlaps]. See - * [method@Clutter.Actor.set_offscreen_redirect] for more information. - * - * Return value: %TRUE if the actor may have overlapping primitives, and - * %FALSE otherwise - */ -gboolean -clutter_actor_has_overlaps (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), TRUE); - - return CLUTTER_ACTOR_GET_CLASS (self)->has_overlaps (self); -} - -/** - * clutter_actor_has_effects: - * @self: A #ClutterActor - * - * Returns whether the actor has any effects applied. - * - * Return value: %TRUE if the actor has any effects, - * %FALSE otherwise - */ -gboolean -clutter_actor_has_effects (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - if (self->priv->effects == NULL) - return FALSE; - - return _clutter_meta_group_has_metas_no_internal (self->priv->effects); -} - -/** - * clutter_actor_has_constraints: - * @self: A #ClutterActor - * - * Returns whether the actor has any constraints applied. - * - * Return value: %TRUE if the actor has any constraints, - * %FALSE otherwise - */ -gboolean -clutter_actor_has_constraints (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - if (self->priv->constraints == NULL) - return FALSE; - - return _clutter_meta_group_has_metas_no_internal (self->priv->constraints); -} - -/** - * clutter_actor_has_actions: - * @self: A #ClutterActor - * - * Returns whether the actor has any actions applied. - * - * Return value: %TRUE if the actor has any actions, - * %FALSE otherwise - */ -gboolean -clutter_actor_has_actions (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - if (self->priv->actions == NULL) - return FALSE; - - return _clutter_meta_group_has_metas_no_internal (self->priv->actions); -} - -/** - * clutter_actor_get_n_children: - * @self: a #ClutterActor - * - * Retrieves the number of children of @self. - * - * Return value: the number of children of an actor - */ -gint -clutter_actor_get_n_children (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0); - - return self->priv->n_children; -} - -/** - * clutter_actor_get_child_at_index: - * @self: a #ClutterActor - * @index_: the position in the list of children - * - * Retrieves the actor at the given @index_ inside the list of - * children of @self. - * - * Return value: (transfer none) (nullable): a pointer to a #ClutterActor, - * or %NULL - */ -ClutterActor * -clutter_actor_get_child_at_index (ClutterActor *self, - gint index_) -{ - ClutterActor *iter; - int i; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - g_return_val_if_fail (index_ <= self->priv->n_children, NULL); - - for (iter = self->priv->first_child, i = 0; - iter != NULL && i < index_; - iter = iter->priv->next_sibling, i += 1) - ; - - return iter; -} - -/*< private > - * _clutter_actor_foreach_child: - * @actor: The actor whose children you want to iterate - * @callback: The function to call for each child - * @user_data: Private data to pass to @callback - * - * Calls a given @callback once for each child of the specified @actor and - * passing the @user_data pointer each time. - * - * Return value: returns %TRUE if all children were iterated, else - * %FALSE if a callback broke out of iteration early. - */ -gboolean -_clutter_actor_foreach_child (ClutterActor *self, - ClutterForeachCallback callback, - gpointer user_data) -{ - ClutterActor *iter; - gboolean cont; - - if (self->priv->first_child == NULL) - return TRUE; - - cont = TRUE; - iter = self->priv->first_child; - - /* we use this form so that it's safe to change the children - * list while iterating it - */ - while (cont && iter != NULL) - { - ClutterActor *next = iter->priv->next_sibling; - - cont = callback (iter, user_data); - - iter = next; - } - - return cont; -} - -#if 0 -/* For debugging purposes this gives us a simple way to print out - * the scenegraph e.g in gdb using: - * [| - * _clutter_actor_traverse (stage, - * 0, - * clutter_debug_print_actor_cb, - * NULL, - * NULL); - * |] - */ -static ClutterActorTraverseVisitFlags -clutter_debug_print_actor_cb (ClutterActor *actor, - int depth, - void *user_data) -{ - g_print ("%*s%s:%p\n", - depth * 2, "", - _clutter_actor_get_debug_name (actor), - actor); - - return CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE; -} -#endif - -static void -_clutter_actor_traverse_breadth (ClutterActor *actor, - ClutterTraverseCallback callback, - gpointer user_data) -{ - GQueue *queue = g_queue_new (); - ClutterActor dummy; - int current_depth = 0; - - g_queue_push_tail (queue, actor); - g_queue_push_tail (queue, &dummy); /* use to delimit depth changes */ - - while ((actor = g_queue_pop_head (queue))) - { - ClutterActorTraverseVisitFlags flags; - - if (actor == &dummy) - { - current_depth++; - g_queue_push_tail (queue, &dummy); - continue; - } - - flags = callback (actor, current_depth, user_data); - if (flags & CLUTTER_ACTOR_TRAVERSE_VISIT_BREAK) - break; - else if (!(flags & CLUTTER_ACTOR_TRAVERSE_VISIT_SKIP_CHILDREN)) - { - ClutterActor *iter; - - for (iter = actor->priv->first_child; - iter != NULL; - iter = iter->priv->next_sibling) - { - g_queue_push_tail (queue, iter); - } - } - } - - g_queue_free (queue); -} - -static ClutterActorTraverseVisitFlags -_clutter_actor_traverse_depth (ClutterActor *actor, - ClutterTraverseCallback before_children_callback, - ClutterTraverseCallback after_children_callback, - int current_depth, - gpointer user_data) -{ - ClutterActorTraverseVisitFlags flags; - - flags = before_children_callback (actor, current_depth, user_data); - if (flags & CLUTTER_ACTOR_TRAVERSE_VISIT_BREAK) - return CLUTTER_ACTOR_TRAVERSE_VISIT_BREAK; - - if (!(flags & CLUTTER_ACTOR_TRAVERSE_VISIT_SKIP_CHILDREN)) - { - ClutterActor *iter; - - for (iter = actor->priv->first_child; - iter != NULL; - iter = iter->priv->next_sibling) - { - flags = _clutter_actor_traverse_depth (iter, - before_children_callback, - after_children_callback, - current_depth + 1, - user_data); - - if (flags & CLUTTER_ACTOR_TRAVERSE_VISIT_BREAK) - return CLUTTER_ACTOR_TRAVERSE_VISIT_BREAK; - } - } - - if (after_children_callback) - return after_children_callback (actor, current_depth, user_data); - else - return CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE; -} - -/* _clutter_actor_traverse: - * @actor: The actor to start traversing the graph from - * @flags: These flags may affect how the traversal is done - * @before_children_callback: A function to call before visiting the - * children of the current actor. - * @after_children_callback: A function to call after visiting the - * children of the current actor. (Ignored if - * %CLUTTER_ACTOR_TRAVERSE_BREADTH_FIRST is passed to @flags.) - * @user_data: The private data to pass to the callbacks - * - * Traverses the scenegraph starting at the specified @actor and - * descending through all its children and its children's children. - * For each actor traversed @before_children_callback and - * @after_children_callback are called with the specified - * @user_data, before and after visiting that actor's children. - * - * The callbacks can return flags that affect the ongoing traversal - * such as by skipping over an actors children or bailing out of - * any further traversing. - */ -void -_clutter_actor_traverse (ClutterActor *actor, - ClutterActorTraverseFlags flags, - ClutterTraverseCallback before_children_callback, - ClutterTraverseCallback after_children_callback, - gpointer user_data) -{ - if (flags & CLUTTER_ACTOR_TRAVERSE_BREADTH_FIRST) - _clutter_actor_traverse_breadth (actor, - before_children_callback, - user_data); - else /* DEPTH_FIRST */ - _clutter_actor_traverse_depth (actor, - before_children_callback, - after_children_callback, - 0, /* start depth */ - user_data); -} - -static void -on_layout_manager_changed (ClutterLayoutManager *manager, - ClutterActor *self) -{ - clutter_actor_queue_relayout (self); -} - -/** - * clutter_actor_set_layout_manager: - * @self: a #ClutterActor - * @manager: (nullable): a #ClutterLayoutManager, or %NULL to unset it - * - * Sets the #ClutterLayoutManager delegate object that will be used to - * lay out the children of @self. - * - * The #ClutterActor will take a reference on the passed @manager which - * will be released either when the layout manager is removed, or when - * the actor is destroyed. - */ -void -clutter_actor_set_layout_manager (ClutterActor *self, - ClutterLayoutManager *manager) -{ - ClutterActorPrivate *priv; - GType expected_type, manager_type; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (manager == NULL || CLUTTER_IS_LAYOUT_MANAGER (manager)); - - priv = self->priv; - - expected_type = clutter_actor_class_get_layout_manager_type (CLUTTER_ACTOR_GET_CLASS (self)); - manager_type = manager != NULL ? G_TYPE_FROM_INSTANCE (manager) : G_TYPE_INVALID; - - if (expected_type != G_TYPE_INVALID && - manager_type != G_TYPE_INVALID && - !g_type_is_a (manager_type, expected_type)) - { - g_warning ("Trying to set layout manager of type %s, but actor only accepts %s", - g_type_name (manager_type), g_type_name (expected_type)); - return; - } - - if (priv->layout_manager != NULL) - { - g_clear_signal_handler (&priv->layout_changed_id, priv->layout_manager); - clutter_layout_manager_set_container (priv->layout_manager, NULL); - g_clear_object (&priv->layout_manager); - } - - priv->layout_manager = manager; - - if (priv->layout_manager != NULL) - { - g_object_ref_sink (priv->layout_manager); - clutter_layout_manager_set_container (priv->layout_manager, self); - priv->layout_changed_id = - g_signal_connect (priv->layout_manager, "layout-changed", - G_CALLBACK (on_layout_manager_changed), - self); - } - - clutter_actor_queue_relayout (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_LAYOUT_MANAGER]); -} - -/** - * clutter_actor_get_layout_manager: - * @self: a #ClutterActor - * - * Retrieves the #ClutterLayoutManager used by @self. - * - * Return value: (transfer none) (nullable): a pointer to the - * #ClutterLayoutManager, or %NULL - */ -ClutterLayoutManager * -clutter_actor_get_layout_manager (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - return self->priv->layout_manager; -} - -static const ClutterLayoutInfo default_layout_info = { - GRAPHENE_POINT_INIT_ZERO, /* fixed-pos */ - { 0, 0, 0, 0 }, /* margin */ - CLUTTER_ACTOR_ALIGN_FILL, /* x-align */ - CLUTTER_ACTOR_ALIGN_FILL, /* y-align */ - FALSE, FALSE, /* expand */ - GRAPHENE_SIZE_INIT_ZERO, /* minimum */ - GRAPHENE_SIZE_INIT_ZERO, /* natural */ -}; - -static void -layout_info_free (gpointer data) -{ - if (G_LIKELY (data != NULL)) - g_free (data); -} - -/*< private > - * _clutter_actor_peek_layout_info: - * @self: a #ClutterActor - * - * Retrieves a pointer to the ClutterLayoutInfo structure. - * - * If the actor does not have a ClutterLayoutInfo associated to it, %NULL is returned. - * - * Return value: (transfer none) (nullable): a pointer to the ClutterLayoutInfo - * structure - */ -ClutterLayoutInfo * -_clutter_actor_peek_layout_info (ClutterActor *self) -{ - return g_object_get_qdata (G_OBJECT (self), quark_actor_layout_info); -} - -/*< private > - * _clutter_actor_get_layout_info: - * @self: a #ClutterActor - * - * Retrieves a pointer to the ClutterLayoutInfo structure. - * - * If the actor does not have a ClutterLayoutInfo associated to it, one - * will be created and initialized to the default values. - * - * This function should be used for setters. - * - * For getters, you should use _clutter_actor_get_layout_info_or_defaults() - * instead. - * - * Return value: (transfer none): a pointer to the ClutterLayoutInfo structure - */ -ClutterLayoutInfo * -_clutter_actor_get_layout_info (ClutterActor *self) -{ - ClutterLayoutInfo *retval; - - retval = _clutter_actor_peek_layout_info (self); - if (retval == NULL) - { - retval = g_new0 (ClutterLayoutInfo, 1); - - *retval = default_layout_info; - - g_object_set_qdata_full (G_OBJECT (self), quark_actor_layout_info, - retval, - layout_info_free); - } - - return retval; -} - -/*< private > - * _clutter_actor_get_layout_info_or_defaults: - * @self: a #ClutterActor - * - * Retrieves the ClutterLayoutInfo structure associated to an actor. - * - * If the actor does not have a ClutterLayoutInfo structure associated to it, - * then the default structure will be returned. - * - * This function should only be used for getters. - * - * Return value: (transfer none): a const pointer to the ClutterLayoutInfo - * structure - */ -const ClutterLayoutInfo * -_clutter_actor_get_layout_info_or_defaults (ClutterActor *self) -{ - const ClutterLayoutInfo *info; - - info = _clutter_actor_peek_layout_info (self); - if (info == NULL) - return &default_layout_info; - - return info; -} - -/** - * clutter_actor_set_x_align: - * @self: a #ClutterActor - * @x_align: the horizontal alignment policy - * - * Sets the horizontal alignment policy of a #ClutterActor, in case the - * actor received extra horizontal space. - * - * See also the [property@Clutter.Actor:x-align] property. - */ -void -clutter_actor_set_x_align (ClutterActor *self, - ClutterActorAlign x_align) -{ - ClutterLayoutInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_layout_info (self); - - if (info->x_align != x_align) - { - info->x_align = x_align; - - clutter_actor_queue_relayout (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_X_ALIGN]); - } -} - -/** - * clutter_actor_get_x_align: - * @self: a #ClutterActor - * - * Retrieves the horizontal alignment policy set using - * [method@Clutter.Actor.set_x_align]. - * - * Return value: the horizontal alignment policy. - */ -ClutterActorAlign -clutter_actor_get_x_align (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), CLUTTER_ACTOR_ALIGN_FILL); - - return _clutter_actor_get_layout_info_or_defaults (self)->x_align; -} - -/** - * clutter_actor_set_y_align: - * @self: a #ClutterActor - * @y_align: the vertical alignment policy - * - * Sets the vertical alignment policy of a #ClutterActor, in case the - * actor received extra vertical space. - * - * See also the [property@Clutter.Actor:y-align] property. - */ -void -clutter_actor_set_y_align (ClutterActor *self, - ClutterActorAlign y_align) -{ - ClutterLayoutInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_layout_info (self); - - if (info->y_align != y_align) - { - info->y_align = y_align; - - clutter_actor_queue_relayout (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_Y_ALIGN]); - } -} - -/** - * clutter_actor_get_y_align: - * @self: a #ClutterActor - * - * Retrieves the vertical alignment policy set using - * [method@Clutter.Actor.set_y_align]. - * - * Return value: the vertical alignment policy. - */ -ClutterActorAlign -clutter_actor_get_y_align (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), CLUTTER_ACTOR_ALIGN_FILL); - - return _clutter_actor_get_layout_info_or_defaults (self)->y_align; -} - -static inline void -clutter_actor_set_margin_internal (ClutterActor *self, - gfloat margin, - GParamSpec *pspec) -{ - ClutterLayoutInfo *info; - - info = _clutter_actor_get_layout_info (self); - - if (pspec == obj_props[PROP_MARGIN_TOP]) - info->margin.top = margin; - else if (pspec == obj_props[PROP_MARGIN_RIGHT]) - info->margin.right = margin; - else if (pspec == obj_props[PROP_MARGIN_BOTTOM]) - info->margin.bottom = margin; - else - info->margin.left = margin; - - clutter_actor_queue_relayout (self); - g_object_notify_by_pspec (G_OBJECT (self), pspec); -} - -/** - * clutter_actor_set_margin: - * @self: a #ClutterActor - * @margin: a #ClutterMargin - * - * Sets all the components of the margin of a #ClutterActor. - */ -void -clutter_actor_set_margin (ClutterActor *self, - const ClutterMargin *margin) -{ - ClutterLayoutInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (margin != NULL); - - info = _clutter_actor_get_layout_info (self); - - if (info->margin.top != margin->top) - clutter_actor_set_margin_top (self, margin->top); - - if (info->margin.right != margin->right) - clutter_actor_set_margin_right (self, margin->right); - - if (info->margin.bottom != margin->bottom) - clutter_actor_set_margin_bottom (self, margin->bottom); - - if (info->margin.left != margin->left) - clutter_actor_set_margin_left (self, margin->left); -} - -/** - * clutter_actor_get_margin: - * @self: a #ClutterActor - * @margin: (out caller-allocates): return location for a #ClutterMargin - * - * Retrieves all the components of the margin of a #ClutterActor. - */ -void -clutter_actor_get_margin (ClutterActor *self, - ClutterMargin *margin) -{ - const ClutterLayoutInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (margin != NULL); - - info = _clutter_actor_get_layout_info_or_defaults (self); - - *margin = info->margin; -} - -/** - * clutter_actor_set_margin_top: - * @self: a #ClutterActor - * @margin: the top margin - * - * Sets the margin from the top of a #ClutterActor. - * - * The [property@Clutter.Actor:margin-top] property is animatable. - */ -void -clutter_actor_set_margin_top (ClutterActor *self, - gfloat margin) -{ - const ClutterLayoutInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (margin >= 0.f); - - info = _clutter_actor_get_layout_info_or_defaults (self); - - if (info->margin.top == margin) - return; - - _clutter_actor_create_transition (self, obj_props[PROP_MARGIN_TOP], - info->margin.top, - margin); -} - -/** - * clutter_actor_get_margin_top: - * @self: a #ClutterActor - * - * Retrieves the top margin of a #ClutterActor. - * - * Return value: the top margin - */ -gfloat -clutter_actor_get_margin_top (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0.f); - - return _clutter_actor_get_layout_info_or_defaults (self)->margin.top; -} - -/** - * clutter_actor_set_margin_bottom: - * @self: a #ClutterActor - * @margin: the bottom margin - * - * Sets the margin from the bottom of a #ClutterActor. - * - * The [property@Clutter.Actor:margin-bottom] property is animatable. - */ -void -clutter_actor_set_margin_bottom (ClutterActor *self, - gfloat margin) -{ - const ClutterLayoutInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (margin >= 0.f); - - info = _clutter_actor_get_layout_info_or_defaults (self); - - if (info->margin.bottom == margin) - return; - - _clutter_actor_create_transition (self, obj_props[PROP_MARGIN_BOTTOM], - info->margin.bottom, - margin); -} - -/** - * clutter_actor_get_margin_bottom: - * @self: a #ClutterActor - * - * Retrieves the bottom margin of a #ClutterActor. - * - * Return value: the bottom margin - */ -gfloat -clutter_actor_get_margin_bottom (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0.f); - - return _clutter_actor_get_layout_info_or_defaults (self)->margin.bottom; -} - -/** - * clutter_actor_set_margin_left: - * @self: a #ClutterActor - * @margin: the left margin - * - * Sets the margin from the left of a #ClutterActor. - * - * The [property@Clutter.Actor:margin-left] property is animatable. - */ -void -clutter_actor_set_margin_left (ClutterActor *self, - gfloat margin) -{ - const ClutterLayoutInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (margin >= 0.f); - - info = _clutter_actor_get_layout_info_or_defaults (self); - - if (info->margin.left == margin) - return; - - _clutter_actor_create_transition (self, obj_props[PROP_MARGIN_LEFT], - info->margin.left, - margin); -} - -/** - * clutter_actor_get_margin_left: - * @self: a #ClutterActor - * - * Retrieves the left margin of a #ClutterActor. - * - * Return value: the left margin - */ -gfloat -clutter_actor_get_margin_left (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0.f); - - return _clutter_actor_get_layout_info_or_defaults (self)->margin.left; -} - -/** - * clutter_actor_set_margin_right: - * @self: a #ClutterActor - * @margin: the right margin - * - * Sets the margin from the right of a #ClutterActor. - * - * The [property@Clutter.Actor:margin-right] property is animatable. - */ -void -clutter_actor_set_margin_right (ClutterActor *self, - gfloat margin) -{ - const ClutterLayoutInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (margin >= 0.f); - - info = _clutter_actor_get_layout_info_or_defaults (self); - - if (info->margin.right == margin) - return; - - _clutter_actor_create_transition (self, obj_props[PROP_MARGIN_RIGHT], - info->margin.right, - margin); -} - -/** - * clutter_actor_get_margin_right: - * @self: a #ClutterActor - * - * Retrieves the right margin of a #ClutterActor. - * - * Return value: the right margin - */ -gfloat -clutter_actor_get_margin_right (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0.f); - - return _clutter_actor_get_layout_info_or_defaults (self)->margin.right; -} - -static inline void -clutter_actor_set_background_color_internal (ClutterActor *self, - const ClutterColor *color) -{ - ClutterActorPrivate *priv = self->priv; - GObject *obj; - - if (priv->bg_color_set && clutter_color_equal (color, &priv->bg_color)) - return; - - obj = G_OBJECT (self); - - priv->bg_color = *color; - priv->bg_color_set = TRUE; - - clutter_actor_queue_redraw (self); - - g_object_notify_by_pspec (obj, obj_props[PROP_BACKGROUND_COLOR_SET]); - g_object_notify_by_pspec (obj, obj_props[PROP_BACKGROUND_COLOR]); -} - -/** - * clutter_actor_set_background_color: - * @self: a #ClutterActor - * @color: (nullable): a #ClutterColor, or %NULL to unset a previously - * set color - * - * Sets the background color of a #ClutterActor. - * - * The background color will be used to cover the whole allocation of the - * actor. The default background color of an actor is transparent. - * - * To check whether an actor has a background color, you can use the - * [property@Clutter.Actor:background-color-set] actor property. - * - * The [property@Clutter.Actor:background-color] property is animatable. - */ -void -clutter_actor_set_background_color (ClutterActor *self, - const ClutterColor *color) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - priv = self->priv; - - if (color == NULL) - { - GObject *obj = G_OBJECT (self); - - priv->bg_color_set = FALSE; - - clutter_actor_queue_redraw (self); - - g_object_notify_by_pspec (obj, obj_props[PROP_BACKGROUND_COLOR_SET]); - } - else - _clutter_actor_create_transition (self, - obj_props[PROP_BACKGROUND_COLOR], - &priv->bg_color, - color); -} - -/** - * clutter_actor_get_background_color: - * @self: a #ClutterActor - * @color: (out caller-allocates): return location for a #ClutterColor - * - * Retrieves the color set using [method@Clutter.Actor.set_background_color]. - */ -void -clutter_actor_get_background_color (ClutterActor *self, - ClutterColor *color) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (color != NULL); - - *color = self->priv->bg_color; -} - -/** - * clutter_actor_get_previous_sibling: - * @self: a #ClutterActor - * - * Retrieves the sibling of @self that comes before it in the list - * of children of @self's parent. - * - * The returned pointer is only valid until the scene graph changes; it - * is not safe to modify the list of children of @self while iterating - * it. - * - * Return value: (transfer none) (nullable): a pointer to a #ClutterActor, - * or %NULL - */ -ClutterActor * -clutter_actor_get_previous_sibling (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - return self->priv->prev_sibling; -} - -/** - * clutter_actor_get_next_sibling: - * @self: a #ClutterActor - * - * Retrieves the sibling of @self that comes after it in the list - * of children of @self's parent. - * - * The returned pointer is only valid until the scene graph changes; it - * is not safe to modify the list of children of @self while iterating - * it. - * - * Return value: (transfer none) (nullable): a pointer to a #ClutterActor, - * or %NULL - */ -ClutterActor * -clutter_actor_get_next_sibling (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - return self->priv->next_sibling; -} - -/** - * clutter_actor_get_first_child: - * @self: a #ClutterActor - * - * Retrieves the first child of @self. - * - * The returned pointer is only valid until the scene graph changes; it - * is not safe to modify the list of children of @self while iterating - * it. - * - * Return value: (transfer none) (nullable): a pointer to a #ClutterActor, - * or %NULL - */ -ClutterActor * -clutter_actor_get_first_child (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - return self->priv->first_child; -} - -/** - * clutter_actor_get_last_child: - * @self: a #ClutterActor - * - * Retrieves the last child of @self. - * - * The returned pointer is only valid until the scene graph changes; it - * is not safe to modify the list of children of @self while iterating - * it. - * - * Return value: (transfer none) (nullable): a pointer to a #ClutterActor, - * or %NULL - */ -ClutterActor * -clutter_actor_get_last_child (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - return self->priv->last_child; -} - -/* easy way to have properly named fields instead of the dummy ones - * we use in the public structure - */ -typedef struct _RealActorIter -{ - ClutterActor *root; /* dummy1 */ - ClutterActor *current; /* dummy2 */ - gint age; /* dummy3 */ -} RealActorIter; - -/** - * clutter_actor_iter_init: - * @iter: a #ClutterActorIter - * @root: a #ClutterActor - * - * Initializes a #ClutterActorIter, which can then be used to iterate - * efficiently over a section of the scene graph, and associates it - * with @root. - * - * Modifying the scene graph section that contains @root will invalidate - * the iterator. - * - * ```c - * ClutterActorIter iter; - * ClutterActor *child; - * - * clutter_actor_iter_init (&iter, container); - * while (clutter_actor_iter_next (&iter, &child)) - * { - * // do something with child - * } - * ``` - */ -void -clutter_actor_iter_init (ClutterActorIter *iter, - ClutterActor *root) -{ - RealActorIter *ri = (RealActorIter *) iter; - - g_return_if_fail (iter != NULL); - g_return_if_fail (CLUTTER_IS_ACTOR (root)); - - ri->root = root; - ri->current = NULL; - ri->age = root->priv->age; -} - -/** - * clutter_actor_iter_is_valid: - * @iter: a #ClutterActorIter - * - * Checks whether a #ClutterActorIter is still valid. - * - * An iterator is considered valid if it has been initialized, and - * if the #ClutterActor that it refers to hasn't been modified after - * the initialization. - * - * Return value: %TRUE if the iterator is valid, and %FALSE otherwise - */ -gboolean -clutter_actor_iter_is_valid (const ClutterActorIter *iter) -{ - RealActorIter *ri = (RealActorIter *) iter; - - g_return_val_if_fail (iter != NULL, FALSE); - - if (ri->root == NULL) - return FALSE; - - return ri->root->priv->age == ri->age; -} - -/** - * clutter_actor_iter_next: - * @iter: a #ClutterActorIter - * @child: (out) (transfer none) (optional) (nullable): return location for a - * #ClutterActor - * - * Advances the @iter and retrieves the next child of the root #ClutterActor - * that was used to initialize the #ClutterActorIterator. - * - * If the iterator can advance, this function returns %TRUE and sets the - * @child argument. - * - * If the iterator cannot advance, this function returns %FALSE, and - * the contents of @child are undefined. - * - * Return value: %TRUE if the iterator could advance, and %FALSE otherwise. - */ -gboolean -clutter_actor_iter_next (ClutterActorIter *iter, - ClutterActor **child) -{ - RealActorIter *ri = (RealActorIter *) iter; - - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (ri->root != NULL, FALSE); -#ifndef G_DISABLE_ASSERT - g_return_val_if_fail (ri->age == ri->root->priv->age, FALSE); -#endif - - if (ri->current == NULL) - ri->current = ri->root->priv->first_child; - else - ri->current = ri->current->priv->next_sibling; - - if (child != NULL) - *child = ri->current; - - return ri->current != NULL; -} - -/** - * clutter_actor_iter_prev: - * @iter: a #ClutterActorIter - * @child: (out) (transfer none) (optional) (nullable): return location for a - * #ClutterActor - * - * Advances the @iter and retrieves the previous child of the root - * #ClutterActor that was used to initialize the #ClutterActorIterator. - * - * If the iterator can advance, this function returns %TRUE and sets the - * @child argument. - * - * If the iterator cannot advance, this function returns %FALSE, and - * the contents of @child are undefined. - * - * Return value: %TRUE if the iterator could advance, and %FALSE otherwise. - */ -gboolean -clutter_actor_iter_prev (ClutterActorIter *iter, - ClutterActor **child) -{ - RealActorIter *ri = (RealActorIter *) iter; - - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (ri->root != NULL, FALSE); -#ifndef G_DISABLE_ASSERT - g_return_val_if_fail (ri->age == ri->root->priv->age, FALSE); -#endif - - if (ri->current == NULL) - ri->current = ri->root->priv->last_child; - else - ri->current = ri->current->priv->prev_sibling; - - if (child != NULL) - *child = ri->current; - - return ri->current != NULL; -} - -/** - * clutter_actor_iter_remove: - * @iter: a #ClutterActorIter - * - * Safely removes the #ClutterActor currently pointer to by the iterator - * from its parent. - * - * This function can only be called after [method@Clutter.ActorIter.next] or - [method@Clutter.ActorIter.prev] returned %TRUE, and cannot be called more - * than once for the same actor. - * - * This function will call [method@Clutter.Actor.remove_child] internally. - */ -void -clutter_actor_iter_remove (ClutterActorIter *iter) -{ - RealActorIter *ri = (RealActorIter *) iter; - ClutterActor *cur; - - g_return_if_fail (iter != NULL); - g_return_if_fail (ri->root != NULL); -#ifndef G_DISABLE_ASSERT - g_return_if_fail (ri->age == ri->root->priv->age); -#endif - g_return_if_fail (ri->current != NULL); - - cur = ri->current; - - if (cur != NULL) - { - ri->current = cur->priv->prev_sibling; - - clutter_actor_remove_child_internal (ri->root, cur, - REMOVE_CHILD_DEFAULT_FLAGS); - - ri->age += 1; - } -} - -/** - * clutter_actor_iter_destroy: - * @iter: a #ClutterActorIter - * - * Safely destroys the #ClutterActor currently pointer to by the iterator - * from its parent. - * - * This function can only be called after [method@Clutter.ActorIter.next] or - * [method@Clutter.ActorIter.prev] returned %TRUE, and cannot be called more - * than once for the same actor. - * - * This function will call [method@Clutter.Actor.destroy] internally. - */ -void -clutter_actor_iter_destroy (ClutterActorIter *iter) -{ - RealActorIter *ri = (RealActorIter *) iter; - ClutterActor *cur; - - g_return_if_fail (iter != NULL); - g_return_if_fail (ri->root != NULL); -#ifndef G_DISABLE_ASSERT - g_return_if_fail (ri->age == ri->root->priv->age); -#endif - g_return_if_fail (ri->current != NULL); - - cur = ri->current; - - if (cur != NULL) - { - ri->current = cur->priv->prev_sibling; - - clutter_actor_destroy (cur); - - ri->age += 1; - } -} - -static const ClutterAnimationInfo default_animation_info = { - NULL, /* states */ - NULL, /* cur_state */ - NULL, /* transitions */ -}; - -static void -clutter_animation_info_free (gpointer data) -{ - if (data != NULL) - { - ClutterAnimationInfo *info = data; - - if (info->transitions != NULL) - g_hash_table_unref (info->transitions); - - if (info->states != NULL) - g_array_unref (info->states); - - g_free (info); - } -} - -const ClutterAnimationInfo * -_clutter_actor_get_animation_info_or_defaults (ClutterActor *self) -{ - const ClutterAnimationInfo *res; - GObject *obj = G_OBJECT (self); - - res = g_object_get_qdata (obj, quark_actor_animation_info); - if (res != NULL) - return res; - - return &default_animation_info; -} - -ClutterAnimationInfo * -_clutter_actor_get_animation_info (ClutterActor *self) -{ - GObject *obj = G_OBJECT (self); - ClutterAnimationInfo *res; - - res = g_object_get_qdata (obj, quark_actor_animation_info); - if (res == NULL) - { - res = g_new0 (ClutterAnimationInfo, 1); - - *res = default_animation_info; - - g_object_set_qdata_full (obj, quark_actor_animation_info, - res, - clutter_animation_info_free); - } - - return res; -} - -static void -transition_closure_free (gpointer data) -{ - if (G_LIKELY (data != NULL)) - { - TransitionClosure *clos = data; - ClutterTimeline *timeline; - - timeline = CLUTTER_TIMELINE (clos->transition); - - /* we disconnect the signal handler before stopping the timeline, - * so that we don't end up inside on_transition_stopped() from - * a call to g_hash_table_remove(). - */ - g_clear_signal_handler (&clos->completed_id, clos->transition); - - if (clutter_timeline_is_playing (timeline)) - clutter_timeline_stop (timeline); - else if (clutter_timeline_get_delay (timeline) > 0) - clutter_timeline_cancel_delay (timeline); - - /* remove the reference added in add_transition_internal() */ - g_object_unref (clos->transition); - - g_free (clos->name); - - g_free (clos); - } -} - -static void -on_transition_stopped (ClutterTransition *transition, - gboolean is_finished, - TransitionClosure *clos) -{ - ClutterActor *actor = clos->actor; - ClutterAnimationInfo *info; - GQuark t_quark; - gchar *t_name; - - if (clos->name == NULL) - return; - - /* reset the caches used by animations */ - clutter_actor_store_content_box (actor, NULL); - - info = _clutter_actor_get_animation_info (actor); - - /* we need copies because we emit the signal after the - * TransitionClosure data structure has been freed - */ - t_quark = g_quark_from_string (clos->name); - t_name = g_strdup (clos->name); - - if (clutter_transition_get_remove_on_complete (transition)) - { - /* this is safe, because the timeline has now stopped, - * so we won't recurse; the reference on the Animatable - * will be dropped by the ::stopped signal closure in - * ClutterTransition, which is RUN_LAST, and thus will - * be called after this handler - */ - g_hash_table_remove (info->transitions, clos->name); - } - - /* we emit the ::transition-stopped after removing the - * transition, so that we can chain up new transitions - * without interfering with the one that just finished - */ - g_signal_emit (actor, actor_signals[TRANSITION_STOPPED], t_quark, - t_name, - is_finished); - - g_free (t_name); - - /* if it's the last transition then we clean up */ - if (g_hash_table_size (info->transitions) == 0) - { - g_hash_table_unref (info->transitions); - info->transitions = NULL; - - CLUTTER_NOTE (ANIMATION, "Transitions for '%s' completed", - _clutter_actor_get_debug_name (actor)); - - g_signal_emit (actor, actor_signals[TRANSITIONS_COMPLETED], 0); - } -} - -static void -clutter_actor_add_transition_internal (ClutterActor *self, - const gchar *name, - ClutterTransition *transition) -{ - ClutterTimeline *timeline; - TransitionClosure *clos; - ClutterAnimationInfo *info; - - info = _clutter_actor_get_animation_info (self); - - if (info->transitions == NULL) - info->transitions = g_hash_table_new_full (g_str_hash, g_str_equal, - NULL, - transition_closure_free); - - if (g_hash_table_lookup (info->transitions, name) != NULL) - { - g_warning ("A transition with name '%s' already exists for " - "the actor '%s'", - name, - _clutter_actor_get_debug_name (self)); - return; - } - - clutter_transition_set_animatable (transition, CLUTTER_ANIMATABLE (self)); - - timeline = CLUTTER_TIMELINE (transition); - - clos = g_new0 (TransitionClosure, 1); - clos->actor = self; - clos->transition = g_object_ref (transition); - clos->name = g_strdup (name); - clos->completed_id = g_signal_connect (timeline, "stopped", - G_CALLBACK (on_transition_stopped), - clos); - - CLUTTER_NOTE (ANIMATION, - "Adding transition '%s' [%p] to actor '%s'", - clos->name, - clos->transition, - _clutter_actor_get_debug_name (self)); - - g_hash_table_insert (info->transitions, clos->name, clos); - clutter_timeline_start (timeline); -} - -static gboolean -should_skip_implicit_transition (ClutterActor *self, - GParamSpec *pspec) -{ - ClutterActorPrivate *priv = self->priv; - const ClutterAnimationInfo *info; - - /* this function is called from _clutter_actor_create_transition() which - * calls _clutter_actor_get_animation_info() first, so we're guaranteed - * to have the correct ClutterAnimationInfo pointer - */ - info = _clutter_actor_get_animation_info_or_defaults (self); - - /* if the easing state has a non-zero duration we always want an - * implicit transition to occur - */ - if (info->cur_state->easing_duration == 0) - return TRUE; - - /* on the other hand, if the actor hasn't been allocated yet, we want to - * skip all transitions on the :allocation, to avoid actors "flying in" - * into their new position and size - */ - if (pspec == obj_props[PROP_ALLOCATION] && - !clutter_actor_box_is_initialized (&priv->allocation)) - return TRUE; - - /* if the actor is not mapped and is not part of a branch of the scene - * graph that is being cloned, then we always skip implicit transitions - * on the account of the fact that the actor is not going to be visible - * when those transitions happen - */ - if (!clutter_actor_is_mapped (self) && - !clutter_actor_has_mapped_clones (self)) - return TRUE; - - return FALSE; -} - -/*< private >* - * _clutter_actor_create_transition: - * @actor: a #ClutterActor - * @pspec: the property used for the transition - * @...: initial and final state - * - * Creates a #ClutterTransition for the property represented by @pspec. - * - * Return value: a #ClutterTransition - */ -ClutterTransition * -_clutter_actor_create_transition (ClutterActor *actor, - GParamSpec *pspec, - ...) -{ - ClutterTimeline *timeline; - ClutterInterval *interval; - ClutterAnimationInfo *info; - ClutterTransition *res = NULL; - gboolean call_restore = FALSE; - TransitionClosure *clos; - va_list var_args; - g_auto (GValue) initial = G_VALUE_INIT; - g_auto (GValue) final = G_VALUE_INIT; - GType ptype; - char *error; - - g_assert (pspec != NULL); - g_assert ((pspec->flags & CLUTTER_PARAM_ANIMATABLE) != 0); - - info = _clutter_actor_get_animation_info (actor); - - /* XXX - this will go away in 2.0 - * - * if no state has been pushed, we assume that the easing state is - * in "compatibility mode": all transitions have a duration of 0 - * msecs, which means that they happen immediately. in Clutter 2.0 - * this will turn into a g_assert(info->states != NULL), as every - * actor will start with a predefined easing state - */ - if (info->states == NULL) - { - clutter_actor_save_easing_state (actor); - clutter_actor_set_easing_duration (actor, 0); - call_restore = TRUE; - } - - if (info->transitions == NULL) - info->transitions = g_hash_table_new_full (g_str_hash, g_str_equal, - NULL, - transition_closure_free); - - va_start (var_args, pspec); - - ptype = G_PARAM_SPEC_VALUE_TYPE (pspec); - - G_VALUE_COLLECT_INIT (&initial, ptype, - var_args, 0, - &error); - if (error != NULL) - { - g_critical ("%s: %s", G_STRLOC, error); - g_free (error); - goto out; - } - - G_VALUE_COLLECT_INIT (&final, ptype, - var_args, 0, - &error); - if (error != NULL) - { - g_critical ("%s: %s", G_STRLOC, error); - g_free (error); - goto out; - } - - if (should_skip_implicit_transition (actor, pspec)) - { - CLUTTER_NOTE (ANIMATION, "Skipping implicit transition for '%s::%s'", - _clutter_actor_get_debug_name (actor), - pspec->name); - - /* remove a transition, if one exists */ - clutter_actor_remove_transition (actor, pspec->name); - - /* we don't go through the Animatable interface because we - * already know we got here through an animatable property. - */ - clutter_actor_set_animatable_property (actor, - pspec->param_id, - &final, - pspec); - - goto out; - } - - clos = g_hash_table_lookup (info->transitions, pspec->name); - if (clos == NULL) - { - res = clutter_property_transition_new (pspec->name); - - clutter_transition_set_remove_on_complete (res, TRUE); - - interval = clutter_interval_new_with_values (ptype, &initial, &final); - clutter_transition_set_interval (res, interval); - - timeline = CLUTTER_TIMELINE (res); - clutter_timeline_set_delay (timeline, info->cur_state->easing_delay); - clutter_timeline_set_duration (timeline, info->cur_state->easing_duration); - clutter_timeline_set_progress_mode (timeline, info->cur_state->easing_mode); - -#ifdef CLUTTER_ENABLE_DEBUG - if (CLUTTER_HAS_DEBUG (ANIMATION)) - { - gchar *initial_v, *final_v; - - initial_v = g_strdup_value_contents (&initial); - final_v = g_strdup_value_contents (&final); - - CLUTTER_NOTE (ANIMATION, - "Created transition for %s:%s " - "(len:%u, mode:%s, delay:%u) " - "initial:%s, final:%s", - _clutter_actor_get_debug_name (actor), - pspec->name, - info->cur_state->easing_duration, - clutter_get_easing_name_for_mode (info->cur_state->easing_mode), - info->cur_state->easing_delay, - initial_v, final_v); - - g_free (initial_v); - g_free (final_v); - } -#endif /* CLUTTER_ENABLE_DEBUG */ - - /* this will start the transition as well */ - clutter_actor_add_transition_internal (actor, pspec->name, res); - - /* the actor now owns the transition */ - g_object_unref (res); - } - else - { - ClutterAnimationMode cur_mode; - guint cur_duration; - - CLUTTER_NOTE (ANIMATION, "Existing transition for %s:%s", - _clutter_actor_get_debug_name (actor), - pspec->name); - - timeline = CLUTTER_TIMELINE (clos->transition); - - cur_duration = clutter_timeline_get_duration (timeline); - if (cur_duration != info->cur_state->easing_duration) - clutter_timeline_set_duration (timeline, info->cur_state->easing_duration); - - cur_mode = clutter_timeline_get_progress_mode (timeline); - if (cur_mode != info->cur_state->easing_mode) - clutter_timeline_set_progress_mode (timeline, info->cur_state->easing_mode); - - clutter_timeline_rewind (timeline); - - interval = clutter_transition_get_interval (clos->transition); - clutter_interval_set_initial_value (interval, &initial); - clutter_interval_set_final_value (interval, &final); - - res = clos->transition; - } - -out: - if (call_restore) - clutter_actor_restore_easing_state (actor); - - va_end (var_args); - - return res; -} - -/** - * clutter_actor_add_transition: - * @self: a #ClutterActor - * @name: the name of the transition to add - * @transition: the #ClutterTransition to add - * - * Adds a @transition to the #ClutterActor's list of animations. - * - * The @name string is a per-actor unique identifier of the @transition: only - * one #ClutterTransition can be associated to the specified @name. - * - * The @transition will be started once added. - * - * This function will take a reference on the @transition. - * - * This function is usually called implicitly when modifying an animatable - * property. - */ -void -clutter_actor_add_transition (ClutterActor *self, - const char *name, - ClutterTransition *transition) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (name != NULL); - g_return_if_fail (CLUTTER_IS_TRANSITION (transition)); - - clutter_actor_add_transition_internal (self, name, transition); -} - -/** - * clutter_actor_remove_transition: - * @self: a #ClutterActor - * @name: the name of the transition to remove - * - * Removes the transition stored inside a #ClutterActor using @name - * identifier. - * - * If the transition is currently in progress, it will be stopped. - * - * This function releases the reference acquired when the transition - * was added to the #ClutterActor. - */ -void -clutter_actor_remove_transition (ClutterActor *self, - const char *name) -{ - const ClutterAnimationInfo *info; - TransitionClosure *clos; - gboolean was_playing; - GQuark t_quark; - gchar *t_name; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (name != NULL); - - info = _clutter_actor_get_animation_info_or_defaults (self); - - if (info->transitions == NULL) - return; - - clos = g_hash_table_lookup (info->transitions, name); - if (clos == NULL) - return; - - was_playing = - clutter_timeline_is_playing (CLUTTER_TIMELINE (clos->transition)); - t_quark = g_quark_from_string (clos->name); - t_name = g_strdup (clos->name); - - g_hash_table_remove (info->transitions, name); - - /* we want to maintain the invariant that ::transition-stopped is - * emitted after the transition has been removed, to allow replacing - * or chaining; removing the transition from the hash table will - * stop it, but transition_closure_free() will disconnect the signal - * handler we install in add_transition_internal(), to avoid loops - * or segfaults. - * - * since we know already that a transition will stop once it's removed - * from an actor, we can simply emit the ::transition-stopped here - * ourselves, if the timeline was playing (if it wasn't, then the - * signal was already emitted at least once). - */ - if (was_playing) - { - g_signal_emit (self, actor_signals[TRANSITION_STOPPED], - t_quark, - t_name, - FALSE); - } - - g_free (t_name); -} - -/** - * clutter_actor_remove_all_transitions: - * @self: a #ClutterActor - * - * Removes all transitions associated to @self. - */ -void -clutter_actor_remove_all_transitions (ClutterActor *self) -{ - const ClutterAnimationInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_animation_info_or_defaults (self); - if (info->transitions == NULL) - return; - - g_hash_table_remove_all (info->transitions); -} - -/** - * clutter_actor_set_easing_duration: - * @self: a #ClutterActor - * @msecs: the duration of the easing, or %NULL - * - * Sets the duration of the tweening for animatable properties - * of @self for the current easing state. - */ -void -clutter_actor_set_easing_duration (ClutterActor *self, - guint msecs) -{ - ClutterAnimationInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_animation_info (self); - - if (info->cur_state == NULL) - { - g_warning ("You must call clutter_actor_save_easing_state() prior " - "to calling clutter_actor_set_easing_duration()."); - return; - } - - if (info->cur_state->easing_duration != msecs) - info->cur_state->easing_duration = msecs; -} - -/** - * clutter_actor_get_easing_duration: - * @self: a #ClutterActor - * - * Retrieves the duration of the tweening for animatable - * properties of @self for the current easing state. - * - * Return value: the duration of the tweening, in milliseconds - */ -guint -clutter_actor_get_easing_duration (ClutterActor *self) -{ - const ClutterAnimationInfo *info; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0); - - info = _clutter_actor_get_animation_info_or_defaults (self); - - if (info->cur_state != NULL) - return info->cur_state->easing_duration; - - return 0; -} - -/** - * clutter_actor_set_easing_mode: - * @self: a #ClutterActor - * @mode: an easing mode, excluding %CLUTTER_CUSTOM_MODE - * - * Sets the easing mode for the tweening of animatable properties - * of @self. - */ -void -clutter_actor_set_easing_mode (ClutterActor *self, - ClutterAnimationMode mode) -{ - ClutterAnimationInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (mode != CLUTTER_CUSTOM_MODE); - g_return_if_fail (mode < CLUTTER_ANIMATION_LAST); - - info = _clutter_actor_get_animation_info (self); - - if (info->cur_state == NULL) - { - g_warning ("You must call clutter_actor_save_easing_state() prior " - "to calling clutter_actor_set_easing_mode()."); - return; - } - - if (info->cur_state->easing_mode != mode) - info->cur_state->easing_mode = mode; -} - -/** - * clutter_actor_get_easing_mode: - * @self: a #ClutterActor - * - * Retrieves the easing mode for the tweening of animatable properties - * of @self for the current easing state. - * - * Return value: an easing mode - */ -ClutterAnimationMode -clutter_actor_get_easing_mode (ClutterActor *self) -{ - const ClutterAnimationInfo *info; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), CLUTTER_EASE_OUT_CUBIC); - - info = _clutter_actor_get_animation_info_or_defaults (self); - - if (info->cur_state != NULL) - return info->cur_state->easing_mode; - - return CLUTTER_EASE_OUT_CUBIC; -} - -/** - * clutter_actor_set_easing_delay: - * @self: a #ClutterActor - * @msecs: the delay before the start of the tweening, in milliseconds - * - * Sets the delay that should be applied before tweening animatable - * properties. - */ -void -clutter_actor_set_easing_delay (ClutterActor *self, - guint msecs) -{ - ClutterAnimationInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_animation_info (self); - - if (info->cur_state == NULL) - { - g_warning ("You must call clutter_actor_save_easing_state() prior " - "to calling clutter_actor_set_easing_delay()."); - return; - } - - if (info->cur_state->easing_delay != msecs) - info->cur_state->easing_delay = msecs; -} - -/** - * clutter_actor_get_easing_delay: - * @self: a #ClutterActor - * - * Retrieves the delay that should be applied when tweening animatable - * properties. - * - * Return value: a delay, in milliseconds - */ -guint -clutter_actor_get_easing_delay (ClutterActor *self) -{ - const ClutterAnimationInfo *info; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0); - - info = _clutter_actor_get_animation_info_or_defaults (self); - - if (info->cur_state != NULL) - return info->cur_state->easing_delay; - - return 0; -} - -/** - * clutter_actor_get_transition: - * @self: a #ClutterActor - * @name: the name of the transition - * - * Retrieves the #ClutterTransition of a #ClutterActor by using the - * transition @name. - * - * Transitions created for animatable properties use the name of the - * property itself, for instance the code below: - * - * ```c - * clutter_actor_set_easing_duration (actor, 1000); - * clutter_actor_set_rotation_angle (actor, CLUTTER_Y_AXIS, 360.0); - * - * transition = clutter_actor_get_transition (actor, "rotation-angle-y"); - * g_signal_connect (transition, "stopped", - * G_CALLBACK (on_transition_stopped), - * actor); - * ``` - * - * will call the `on_transition_stopped` callback when the transition - * is finished. - * - * If you just want to get notifications of the completion of a transition, - * you should use the [signal@Clutter.Actor::transition-stopped] signal, using the - * transition name as the signal detail. - * - * Return value: (transfer none) (nullable): a #ClutterTransition, or %NULL if - * none was found to match the passed name; the returned instance is owned - * by Clutter and it should not be freed - */ -ClutterTransition * -clutter_actor_get_transition (ClutterActor *self, - const char *name) -{ - TransitionClosure *clos; - const ClutterAnimationInfo *info; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - g_return_val_if_fail (name != NULL, NULL); - - info = _clutter_actor_get_animation_info_or_defaults (self); - if (info->transitions == NULL) - return NULL; - - clos = g_hash_table_lookup (info->transitions, name); - if (clos == NULL) - return NULL; - - return clos->transition; -} - -/** - * clutter_actor_has_transitions: (skip) - */ -gboolean -clutter_actor_has_transitions (ClutterActor *self) -{ - const ClutterAnimationInfo *info; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - info = _clutter_actor_get_animation_info_or_defaults (self); - if (info->transitions == NULL) - return FALSE; - - return g_hash_table_size (info->transitions) > 0; -} - -/** - * clutter_actor_save_easing_state: - * @self: a #ClutterActor - * - * Saves the current easing state for animatable properties, and creates - * a new state with the default values for easing mode and duration. - * - * New transitions created after calling this function will inherit the - * duration, easing mode, and delay of the new easing state; this also - * applies to transitions modified in flight. - */ -void -clutter_actor_save_easing_state (ClutterActor *self) -{ - ClutterAnimationInfo *info; - AState new_state; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_animation_info (self); - - if (info->states == NULL) - info->states = g_array_new (FALSE, FALSE, sizeof (AState)); - - new_state.easing_mode = CLUTTER_EASE_OUT_CUBIC; - new_state.easing_duration = 250; - new_state.easing_delay = 0; - - g_array_append_val (info->states, new_state); - - info->cur_state = &g_array_index (info->states, AState, info->states->len - 1); -} - -/** - * clutter_actor_restore_easing_state: - * @self: a #ClutterActor - * - * Restores the easing state as it was prior to a call to - * [method@Clutter.Actor.save_easing_state]. - */ -void -clutter_actor_restore_easing_state (ClutterActor *self) -{ - ClutterAnimationInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_animation_info (self); - - if (info->states == NULL) - { - g_critical ("The function clutter_actor_restore_easing_state() has " - "been called without a previous call to " - "clutter_actor_save_easing_state()."); - return; - } - - g_array_remove_index (info->states, info->states->len - 1); - - if (info->states->len > 0) - info->cur_state = &g_array_index (info->states, AState, info->states->len - 1); - else - { - g_array_unref (info->states); - info->states = NULL; - info->cur_state = NULL; - } -} - -/** - * clutter_actor_set_content: - * @self: a #ClutterActor - * @content: (nullable): a #ClutterContent, or %NULL - * - * Sets the contents of a #ClutterActor. - */ -void -clutter_actor_set_content (ClutterActor *self, - ClutterContent *content) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (content == NULL || CLUTTER_IS_CONTENT (content)); - - priv = self->priv; - - if (priv->content == content) - return; - - if (priv->content != NULL) - { - _clutter_content_detached (priv->content, self); - g_clear_object (&priv->content); - } - - priv->content = content; - - if (priv->content != NULL) - { - g_object_ref (priv->content); - _clutter_content_attached (priv->content, self); - } - - /* if the actor's preferred size is the content's preferred size, - * then we need to conditionally queue a relayout here... - */ - if (priv->request_mode == CLUTTER_REQUEST_CONTENT_SIZE) - _clutter_actor_queue_only_relayout (self); - - clutter_actor_queue_redraw (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CONTENT]); - - /* if the content gravity is not resize-fill, and the new content has a - * different preferred size than the previous one, then the content box - * may have been changed. since we compute that lazily, we just notify - * here, and let whomever watches :content-box do whatever they need to - * do. - */ - if (priv->content_gravity != CLUTTER_CONTENT_GRAVITY_RESIZE_FILL) - { - if (priv->content_box_valid) - { - ClutterActorBox from_box, to_box; - - clutter_actor_get_content_box (self, &from_box); - - /* invalidate the cached content box */ - priv->content_box_valid = FALSE; - clutter_actor_get_content_box (self, &to_box); - - if (!clutter_actor_box_equal (&from_box, &to_box)) - _clutter_actor_create_transition (self, obj_props[PROP_CONTENT_BOX], - &from_box, - &to_box); - } - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CONTENT_BOX]); - } -} - -/** - * clutter_actor_get_content: - * @self: a #ClutterActor - * - * Retrieves the contents of @self. - * - * Return value: (transfer none) (nullable): a pointer to the #ClutterContent - * instance, or %NULL if none was set - */ -ClutterContent * -clutter_actor_get_content (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - return self->priv->content; -} - -/** - * clutter_actor_set_content_gravity: - * @self: a #ClutterActor - * @gravity: the #ClutterContentGravity - * - * Sets the gravity of the #ClutterContent used by @self. - * - * See the description of the [property@Clutter.Actor:content-gravity] property for - * more information. - * - * The [property@Clutter.Actor:content-gravity] property is animatable. - */ -void -clutter_actor_set_content_gravity (ClutterActor *self, - ClutterContentGravity gravity) -{ - ClutterActorPrivate *priv; - ClutterActorBox from_box, to_box; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - priv = self->priv; - - if (priv->content_gravity == gravity) - return; - - priv->content_box_valid = FALSE; - - clutter_actor_get_content_box (self, &from_box); - - priv->content_gravity = gravity; - - clutter_actor_get_content_box (self, &to_box); - - _clutter_actor_create_transition (self, obj_props[PROP_CONTENT_BOX], - &from_box, - &to_box); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CONTENT_GRAVITY]); -} - -/** - * clutter_actor_get_content_gravity: - * @self: a #ClutterActor - * - * Retrieves the content gravity as set using - * [method@Clutter.Actor.set_content_gravity]. - * - * Return value: the content gravity - */ -ClutterContentGravity -clutter_actor_get_content_gravity (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), - CLUTTER_CONTENT_GRAVITY_RESIZE_FILL); - - return self->priv->content_gravity; -} - -/** - * clutter_actor_get_content_box: - * @self: a #ClutterActor - * @box: (out caller-allocates): the return location for the bounding - * box for the #ClutterContent - * - * Retrieves the bounding box for the #ClutterContent of @self. - * - * The bounding box is relative to the actor's allocation. - * - * If no #ClutterContent is set for @self, or if @self has not been - * allocated yet, then the result is undefined. - * - * The content box is guaranteed to be, at most, as big as the allocation - * of the #ClutterActor. - * - * If the #ClutterContent used by the actor has a preferred size, then - * it is possible to modify the content box by using the - * [property@Clutter.Actor:content-gravity] property. - */ -void -clutter_actor_get_content_box (ClutterActor *self, - ClutterActorBox *box) -{ - ClutterActorPrivate *priv; - gfloat content_w, content_h; - gfloat alloc_w, alloc_h; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (box != NULL); - - priv = self->priv; - - box->x1 = 0.f; - box->y1 = 0.f; - box->x2 = priv->allocation.x2 - priv->allocation.x1; - box->y2 = priv->allocation.y2 - priv->allocation.y1; - - if (priv->content_box_valid) - { - *box = priv->content_box; - return; - } - - /* no need to do any more work */ - if (priv->content_gravity == CLUTTER_CONTENT_GRAVITY_RESIZE_FILL) - return; - - if (priv->content == NULL) - return; - - /* if the content does not have a preferred size then there is - * no point in computing the content box - */ - if (!clutter_content_get_preferred_size (priv->content, - &content_w, - &content_h)) - return; - - alloc_w = box->x2; - alloc_h = box->y2; - - switch (priv->content_gravity) - { - case CLUTTER_CONTENT_GRAVITY_TOP_LEFT: - box->x2 = box->x1 + MIN (content_w, alloc_w); - box->y2 = box->y1 + MIN (content_h, alloc_h); - break; - - case CLUTTER_CONTENT_GRAVITY_TOP: - if (alloc_w > content_w) - { - box->x1 += ceilf ((alloc_w - content_w) / 2.0); - box->x2 = box->x1 + content_w; - } - box->y2 = box->y1 + MIN (content_h, alloc_h); - break; - - case CLUTTER_CONTENT_GRAVITY_TOP_RIGHT: - if (alloc_w > content_w) - { - box->x1 += (alloc_w - content_w); - box->x2 = box->x1 + content_w; - } - box->y2 = box->y1 + MIN (content_h, alloc_h); - break; - - case CLUTTER_CONTENT_GRAVITY_LEFT: - box->x2 = box->x1 + MIN (content_w, alloc_w); - if (alloc_h > content_h) - { - box->y1 += ceilf ((alloc_h - content_h) / 2.0); - box->y2 = box->y1 + content_h; - } - break; - - case CLUTTER_CONTENT_GRAVITY_CENTER: - if (alloc_w > content_w) - { - box->x1 += ceilf ((alloc_w - content_w) / 2.0); - box->x2 = box->x1 + content_w; - } - if (alloc_h > content_h) - { - box->y1 += ceilf ((alloc_h - content_h) / 2.0); - box->y2 = box->y1 + content_h; - } - break; - - case CLUTTER_CONTENT_GRAVITY_RIGHT: - if (alloc_w > content_w) - { - box->x1 += (alloc_w - content_w); - box->x2 = box->x1 + content_w; - } - if (alloc_h > content_h) - { - box->y1 += ceilf ((alloc_h - content_h) / 2.0); - box->y2 = box->y1 + content_h; - } - break; - - case CLUTTER_CONTENT_GRAVITY_BOTTOM_LEFT: - box->x2 = box->x1 + MIN (content_w, alloc_w); - if (alloc_h > content_h) - { - box->y1 += (alloc_h - content_h); - box->y2 = box->y1 + content_h; - } - break; - - case CLUTTER_CONTENT_GRAVITY_BOTTOM: - if (alloc_w > content_w) - { - box->x1 += ceilf ((alloc_w - content_w) / 2.0); - box->x2 = box->x1 + content_w; - } - if (alloc_h > content_h) - { - box->y1 += (alloc_h - content_h); - box->y2 = box->y1 + content_h; - } - break; - - case CLUTTER_CONTENT_GRAVITY_BOTTOM_RIGHT: - if (alloc_w > content_w) - { - box->x1 += (alloc_w - content_w); - box->x2 = box->x1 + content_w; - } - if (alloc_h > content_h) - { - box->y1 += (alloc_h - content_h); - box->y2 = box->y1 + content_h; - } - break; - - case CLUTTER_CONTENT_GRAVITY_RESIZE_FILL: - g_assert_not_reached (); - break; - - case CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT: - { - double r_c = content_w / content_h; - - if ((alloc_w / r_c) > alloc_h) - { - box->y1 = 0.f; - box->y2 = alloc_h; - - box->x1 = (alloc_w - (alloc_h * r_c)) / 2.0f; - box->x2 = box->x1 + (alloc_h * r_c); - } - else - { - box->x1 = 0.f; - box->x2 = alloc_w; - - box->y1 = (alloc_h - (alloc_w / r_c)) / 2.0f; - box->y2 = box->y1 + (alloc_w / r_c); - } - - CLUTTER_NOTE (LAYOUT, - "r_c: %.3f, r_a: %.3f\t" - "a: [%.2fx%.2f], c: [%.2fx%.2f]\t" - "b: [%.2f, %.2f, %.2f, %.2f]", - r_c, alloc_w / alloc_h, - alloc_w, alloc_h, - content_w, content_h, - box->x1, box->y1, box->x2, box->y2); - } - break; - } -} - -/** - * clutter_actor_set_content_scaling_filters: - * @self: a #ClutterActor - * @min_filter: the minification filter for the content - * @mag_filter: the magnification filter for the content - * - * Sets the minification and magnification filter to be applied when - * scaling the [property@Clutter.Actor:content] of a #ClutterActor. - * - * The [property@Clutter.Actor:minification-filter] will be used when reducing - * the size of the content; the [property@Clutter.Actor:magnification-filter] - * will be used when increasing the size of the content. - */ -void -clutter_actor_set_content_scaling_filters (ClutterActor *self, - ClutterScalingFilter min_filter, - ClutterScalingFilter mag_filter) -{ - ClutterActorPrivate *priv; - gboolean changed; - GObject *obj; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - priv = self->priv; - obj = G_OBJECT (self); - - g_object_freeze_notify (obj); - - changed = FALSE; - - if (priv->min_filter != min_filter) - { - priv->min_filter = min_filter; - changed = TRUE; - - g_object_notify_by_pspec (obj, obj_props[PROP_MINIFICATION_FILTER]); - } - - if (priv->mag_filter != mag_filter) - { - priv->mag_filter = mag_filter; - changed = TRUE; - - g_object_notify_by_pspec (obj, obj_props[PROP_MAGNIFICATION_FILTER]); - } - - if (changed) - clutter_actor_queue_redraw (self); - - g_object_thaw_notify (obj); -} - -/** - * clutter_actor_get_content_scaling_filters: - * @self: a #ClutterActor - * @min_filter: (out) (optional): return location for the minification - * filter, or %NULL - * @mag_filter: (out) (optional): return location for the magnification - * filter, or %NULL - * - * Retrieves the values set using [method@Clutter.Actor.set_content_scaling_filters]. - */ -void -clutter_actor_get_content_scaling_filters (ClutterActor *self, - ClutterScalingFilter *min_filter, - ClutterScalingFilter *mag_filter) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (min_filter != NULL) - *min_filter = self->priv->min_filter; - - if (mag_filter != NULL) - *mag_filter = self->priv->mag_filter; -} - -/* - * clutter_actor_queue_compute_expand: - * @self: a #ClutterActor - * - * Invalidates the needs_x_expand and needs_y_expand flags on @self - * and its parents up to the top-level actor. - * - * This function also queues a relayout if anything changed. - */ -static inline void -clutter_actor_queue_compute_expand (ClutterActor *self) -{ - ClutterActor *parent; - gboolean changed; - - if (self->priv->needs_compute_expand) - return; - - changed = FALSE; - parent = self; - while (parent != NULL) - { - if (!parent->priv->needs_compute_expand) - { - parent->priv->needs_compute_expand = TRUE; - changed = TRUE; - } - - parent = parent->priv->parent; - } - - if (changed) - clutter_actor_queue_relayout (self); -} - -/** - * clutter_actor_set_x_expand: - * @self: a #ClutterActor - * @expand: whether the actor should expand horizontally - * - * Sets whether a #ClutterActor should expand horizontally; this means - * that layout manager should allocate extra space for the actor, if - * possible. - * - * Setting an actor to expand will also make all its parent expand, so - * that it's possible to build an actor tree and only set this flag on - * its leaves and not on every single actor. - */ -void -clutter_actor_set_x_expand (ClutterActor *self, - gboolean expand) -{ - ClutterLayoutInfo *info; - gboolean changed; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - expand = !!expand; - - info = _clutter_actor_get_layout_info (self); - changed = info->x_expand != expand; - - if (changed || !self->priv->x_expand_set) - { - info->x_expand = expand; - - self->priv->x_expand_set = TRUE; - - clutter_actor_queue_compute_expand (self); - - if (changed) - g_object_notify_by_pspec (G_OBJECT (self), - obj_props[PROP_X_EXPAND]); - } -} - -/** - * clutter_actor_get_x_expand: - * @self: a #ClutterActor - * - * Retrieves the value set with [method@Clutter.Actor.set_x_expand]. - * - * See also: [method@Clutter.Actor.needs_expand] - * - * Return value: %TRUE if the actor has been set to expand - */ -gboolean -clutter_actor_get_x_expand (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - return _clutter_actor_get_layout_info_or_defaults (self)->x_expand; -} - -/** - * clutter_actor_set_y_expand: - * @self: a #ClutterActor - * @expand: whether the actor should expand vertically - * - * Sets whether a #ClutterActor should expand horizontally; this means - * that layout manager should allocate extra space for the actor, if - * possible. - * - * Setting an actor to expand will also make all its parent expand, so - * that it's possible to build an actor tree and only set this flag on - * its leaves and not on every single actor. - */ -void -clutter_actor_set_y_expand (ClutterActor *self, - gboolean expand) -{ - ClutterLayoutInfo *info; - gboolean changed; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - expand = !!expand; - - info = _clutter_actor_get_layout_info (self); - changed = info->y_expand != expand; - - if (changed || !self->priv->y_expand_set) - { - info->y_expand = expand; - - self->priv->y_expand_set = TRUE; - - clutter_actor_queue_compute_expand (self); - - if (changed) - g_object_notify_by_pspec (G_OBJECT (self), - obj_props[PROP_Y_EXPAND]); - } -} - -/** - * clutter_actor_get_y_expand: - * @self: a #ClutterActor - * - * Retrieves the value set with [method@Clutter.Actor.set_y_expand]. - * - * See also: [method@Clutter.Actor.needs_expand] - * - * Return value: %TRUE if the actor has been set to expand - */ -gboolean -clutter_actor_get_y_expand (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - return _clutter_actor_get_layout_info_or_defaults (self)->y_expand; -} - -static void -clutter_actor_compute_expand_recursive (ClutterActor *self, - gboolean *x_expand_p, - gboolean *y_expand_p) -{ - ClutterActorIter iter; - ClutterActor *child; - gboolean x_expand, y_expand; - - x_expand = y_expand = FALSE; - - /* note that we don't recurse into children if we're already set to expand; - * this avoids traversing the whole actor tree, even if it may lead to some - * child left with the needs_compute_expand flag set. - */ - clutter_actor_iter_init (&iter, self); - while (clutter_actor_iter_next (&iter, &child)) - { - x_expand = x_expand || - clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_HORIZONTAL); - - y_expand = y_expand || - clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_VERTICAL); - } - - *x_expand_p = x_expand; - *y_expand_p = y_expand; -} - -static void -clutter_actor_compute_expand (ClutterActor *self) -{ - if (self->priv->needs_compute_expand) - { - const ClutterLayoutInfo *info; - gboolean x_expand, y_expand; - - info = _clutter_actor_get_layout_info_or_defaults (self); - - if (self->priv->x_expand_set) - x_expand = info->x_expand; - else - x_expand = FALSE; - - if (self->priv->y_expand_set) - y_expand = info->y_expand; - else - y_expand = FALSE; - - /* we don't need to recurse down to the children if the - * actor has been forcibly set to expand - */ - if (!(self->priv->x_expand_set && self->priv->y_expand_set)) - { - if (self->priv->n_children != 0) - { - gboolean *x_expand_p, *y_expand_p; - gboolean ignored = FALSE; - - x_expand_p = self->priv->x_expand_set ? &ignored : &x_expand; - y_expand_p = self->priv->y_expand_set ? &ignored : &y_expand; - - clutter_actor_compute_expand_recursive (self, - x_expand_p, - y_expand_p); - } - } - - self->priv->needs_compute_expand = FALSE; - self->priv->needs_x_expand = (x_expand != FALSE); - self->priv->needs_y_expand = (y_expand != FALSE); - } -} - -/** - * clutter_actor_needs_expand: - * @self: a #ClutterActor - * @orientation: the direction of expansion - * - * Checks whether an actor, or any of its children, is set to expand - * horizontally or vertically. - * - * This function should only be called by layout managers that can - * assign extra space to their children. - * - * If you want to know whether the actor was explicitly set to expand, - * use [method@Clutter.Actor.get_x_expand] or [method@Clutter.Actor.get_y_expand]. - * - * Return value: %TRUE if the actor should expand - */ -gboolean -clutter_actor_needs_expand (ClutterActor *self, - ClutterOrientation orientation) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - if (!clutter_actor_is_visible (self)) - return FALSE; - - if (CLUTTER_ACTOR_IN_DESTRUCTION (self)) - return FALSE; - - clutter_actor_compute_expand (self); - - switch (orientation) - { - case CLUTTER_ORIENTATION_HORIZONTAL: - return self->priv->needs_x_expand; - - case CLUTTER_ORIENTATION_VERTICAL: - return self->priv->needs_y_expand; - } - - return FALSE; -} - -/** - * clutter_actor_set_content_repeat: - * @self: a #ClutterActor - * @repeat: the repeat policy - * - * Sets the policy for repeating the [property@Clutter.Actor:content] of a - * #ClutterActor. The behaviour is deferred to the #ClutterContent - * implementation. - */ -void -clutter_actor_set_content_repeat (ClutterActor *self, - ClutterContentRepeat repeat) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - if (self->priv->content_repeat == repeat) - return; - - self->priv->content_repeat = repeat; - - clutter_actor_queue_redraw (self); -} - -/** - * clutter_actor_get_content_repeat: - * @self: a #ClutterActor - * - * Retrieves the repeat policy for a #ClutterActor set by - * [method@Clutter.Actor.set_content_repeat]. - * - * Return value: the content repeat policy - */ -ClutterContentRepeat -clutter_actor_get_content_repeat (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), CLUTTER_REPEAT_NONE); - - return self->priv->content_repeat; -} - -static ClutterColorState * -create_srgb_color_state (ClutterActor *self) -{ - ClutterColorState *color_state; - - /* create default sRGB color state */ - color_state = clutter_color_state_new (CLUTTER_COLORSPACE_SRGB); - - return color_state; -} - -/** - * clutter_actor_set_color_state: - * @self: a #ClutterActor - * @color_state: (nullable): a #ClutterColorState - * - * Set @self's color state to @color_state, or a default sRGB one if %NULL. - */ -void -clutter_actor_set_color_state (ClutterActor *self, - ClutterColorState *color_state) -{ - ClutterActorPrivate *priv; - g_autoptr (ClutterColorState) srgb = NULL; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - priv = clutter_actor_get_instance_private (self); - - if (!color_state) - color_state = srgb = create_srgb_color_state (self); - - if (g_set_object (&priv->color_state, color_state)) - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_COLOR_STATE]); -} - -/** - * clutter_actor_get_color_state: - * @self: a #ClutterActor - * - * Retrieves the color_state of a [class@Actor] set by - * [method@Actor.set_color_state]. - * - * Returns: (transfer none): the #ClutterColorState - */ -ClutterColorState * -clutter_actor_get_color_state (ClutterActor *self) -{ - ClutterActorPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - priv = clutter_actor_get_instance_private (self); - - return priv->color_state; -} - -static void -clutter_actor_set_child_transform_internal (ClutterActor *self, - const graphene_matrix_t *transform) -{ - ClutterTransformInfo *info = _clutter_actor_get_transform_info (self); - ClutterActorIter iter; - ClutterActor *child; - GObject *obj; - gboolean was_set = info->child_transform_set; - - graphene_matrix_init_from_matrix (&info->child_transform, transform); - - /* if it's the identity matrix, we need to toggle the boolean flag */ - info->child_transform_set = !graphene_matrix_is_identity (transform); - - /* we need to reset the transform_valid flag on each child */ - clutter_actor_iter_init (&iter, self); - while (clutter_actor_iter_next (&iter, &child)) - transform_changed (child); - - clutter_actor_queue_redraw (self); - - obj = G_OBJECT (self); - g_object_notify_by_pspec (obj, obj_props[PROP_CHILD_TRANSFORM]); - - if (was_set != info->child_transform_set) - g_object_notify_by_pspec (obj, obj_props[PROP_CHILD_TRANSFORM_SET]); -} - -/** - * clutter_actor_set_child_transform: - * @self: a #ClutterActor - * @transform: (nullable): a #graphene_matrix_t, or %NULL - * - * Sets the transformation matrix to be applied to all the children - * of @self prior to their own transformations. The default child - * transformation is the identity matrix. - * - * If @transform is %NULL, the child transform will be unset. - * - * The [property@Clutter.Actor:child-transform] property is animatable. - */ -void -clutter_actor_set_child_transform (ClutterActor *self, - const graphene_matrix_t *transform) -{ - const ClutterTransformInfo *info; - graphene_matrix_t new_transform; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_transform_info_or_defaults (self); - - if (transform != NULL) - graphene_matrix_init_from_matrix (&new_transform, transform); - else - graphene_matrix_init_identity (&new_transform); - - _clutter_actor_create_transition (self, obj_props[PROP_CHILD_TRANSFORM], - &info->child_transform, - &new_transform); -} - -/** - * clutter_actor_get_child_transform: - * @self: a #ClutterActor - * @transform: (out caller-allocates): a #graphene_matrix_t - * - * Retrieves the child transformation matrix set using - * [method@Clutter.Actor.set_child_transform]; if none is currently set, - * the @transform matrix will be initialized to the identity matrix. - */ -void -clutter_actor_get_child_transform (ClutterActor *self, - graphene_matrix_t *transform) -{ - const ClutterTransformInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (transform != NULL); - - info = _clutter_actor_get_transform_info_or_defaults (self); - - if (info->child_transform_set) - graphene_matrix_init_from_matrix (transform, &info->child_transform); - else - graphene_matrix_init_identity (transform); -} - -static void -clutter_actor_push_in_cloned_branch (ClutterActor *self, - gulong count) -{ - ClutterActor *iter; - - for (iter = self->priv->first_child; - iter != NULL; - iter = iter->priv->next_sibling) - clutter_actor_push_in_cloned_branch (iter, count); - - self->priv->in_cloned_branch += count; -} - -static void -clutter_actor_pop_in_cloned_branch (ClutterActor *self, - gulong count) -{ - ClutterActor *iter; - - self->priv->in_cloned_branch -= count; - - for (iter = self->priv->first_child; - iter != NULL; - iter = iter->priv->next_sibling) - clutter_actor_pop_in_cloned_branch (iter, count); -} - -void -_clutter_actor_attach_clone (ClutterActor *actor, - ClutterActor *clone) -{ - ClutterActorPrivate *priv = actor->priv; - - g_assert (clone != NULL); - - if (priv->clones == NULL) - priv->clones = g_hash_table_new (NULL, NULL); - - g_hash_table_add (priv->clones, clone); - - clutter_actor_push_in_cloned_branch (actor, 1); - - g_signal_emit (actor, actor_signals[CLONED], 0, clone); -} - -void -_clutter_actor_detach_clone (ClutterActor *actor, - ClutterActor *clone) -{ - ClutterActorPrivate *priv = actor->priv; - - g_assert (clone != NULL); - - if (priv->clones == NULL || - g_hash_table_lookup (priv->clones, clone) == NULL) - return; - - clutter_actor_pop_in_cloned_branch (actor, 1); - - g_hash_table_remove (priv->clones, clone); - - if (g_hash_table_size (priv->clones) == 0) - { - g_hash_table_unref (priv->clones); - priv->clones = NULL; - } - - g_signal_emit (actor, actor_signals[DECLONED], 0, clone); -} - -/** - * clutter_actor_has_mapped_clones: - * @self: a #ClutterActor - * - * Returns whether a #ClutterActor or any parent actors have mapped clones - * that are clone-painting @self. - * - * Returns: %TRUE if the actor has mapped clones, %FALSE otherwise - */ -gboolean -clutter_actor_has_mapped_clones (ClutterActor *self) -{ - ClutterActor *actor; - GHashTableIter iter; - gpointer key; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - - if (self->priv->in_cloned_branch == 0) - return FALSE; - - for (actor = self; actor; actor = actor->priv->parent) - { - if (actor->priv->clones) - { - g_hash_table_iter_init (&iter, actor->priv->clones); - while (g_hash_table_iter_next (&iter, &key, NULL)) - { - if (clutter_actor_is_mapped (key)) - return TRUE; - } - } - - /* Clones will force-show their own source actor but not children of - * it, so if we're hidden and an actor up the hierarchy has a clone, - * we won't be visible. - */ - if (!clutter_actor_is_visible (actor)) - return FALSE; - } - - return FALSE; -} - -static void -push_in_paint_unmapped_branch (ClutterActor *self, - guint count) -{ - ClutterActor *iter; - - for (iter = self->priv->first_child; - iter != NULL; - iter = iter->priv->next_sibling) - push_in_paint_unmapped_branch (iter, count); - - self->priv->unmapped_paint_branch_counter += count; -} - -static void -pop_in_paint_unmapped_branch (ClutterActor *self, - guint count) -{ - ClutterActor *iter; - - self->priv->unmapped_paint_branch_counter -= count; - - for (iter = self->priv->first_child; - iter != NULL; - iter = iter->priv->next_sibling) - pop_in_paint_unmapped_branch (iter, count); -} - -static void -clutter_actor_child_model__items_changed (GListModel *model, - guint position, - guint removed, - guint added, - gpointer user_data) -{ - ClutterActor *parent = user_data; - ClutterActorPrivate *priv = parent->priv; - guint i; - - while (removed--) - { - ClutterActor *child = clutter_actor_get_child_at_index (parent, position); - clutter_actor_destroy (child); - } - - for (i = 0; i < added; i++) - { - GObject *item = g_list_model_get_item (model, position + i); - ClutterActor *child = priv->create_child_func (item, priv->create_child_data); - - /* The actor returned by the function can have a floating reference, - * if the implementation is in pure C, or have a full reference, usually - * the case for language bindings. To avoid leaking references, we - * try to assume ownership of the instance, and release the reference - * at the end unconditionally, leaving the only reference to the actor - * itself. - */ - if (g_object_is_floating (child)) - g_object_ref_sink (child); - - clutter_actor_insert_child_at_index (parent, child, position + i); - - g_object_unref (child); - g_object_unref (item); - } -} - -/** - * clutter_actor_bind_model: - * @self: a #ClutterActor - * @model: (nullable): a #GListModel - * @create_child_func: a function that creates #ClutterActor instances - * from the contents of the @model - * @user_data: user data passed to @create_child_func - * @notify: function called when unsetting the @model - * - * Binds a #GListModel to a #ClutterActor. - * - * If the #ClutterActor was already bound to a #GListModel, the previous - * binding is destroyed. - * - * The existing children of #ClutterActor are destroyed when setting a - * model, and new children are created and added, representing the contents - * of the @model. The #ClutterActor is updated whenever the @model changes. - * If @model is %NULL, the #ClutterActor is left empty. - * - * When a #ClutterActor is bound to a model, adding and removing children - * directly is undefined behaviour.4 - */ -void -clutter_actor_bind_model (ClutterActor *self, - GListModel *model, - ClutterActorCreateChildFunc create_child_func, - gpointer user_data, - GDestroyNotify notify) -{ - ClutterActorPrivate *priv = clutter_actor_get_instance_private (self); - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model)); - g_return_if_fail (model == NULL || create_child_func != NULL); - - if (priv->child_model != NULL) - { - if (priv->create_child_notify != NULL) - priv->create_child_notify (priv->create_child_data); - - g_signal_handlers_disconnect_by_func (priv->child_model, - clutter_actor_child_model__items_changed, - self); - g_clear_object (&priv->child_model); - priv->create_child_func = NULL; - priv->create_child_data = NULL; - priv->create_child_notify = NULL; - } - - clutter_actor_destroy_all_children (self); - - if (model == NULL) - return; - - priv->child_model = g_object_ref (model); - priv->create_child_func = create_child_func; - priv->create_child_data = user_data; - priv->create_child_notify = notify; - - g_signal_connect (priv->child_model, "items-changed", - G_CALLBACK (clutter_actor_child_model__items_changed), - self); - - clutter_actor_child_model__items_changed (priv->child_model, - 0, - 0, - g_list_model_get_n_items (priv->child_model), - self); -} - -typedef struct { - GType child_type; - GArray *props; -} BindClosure; - -typedef struct { - const char *model_property; - const char *child_property; - GBindingFlags flags; -} BindProperty; - -static void -bind_closure_free (gpointer data_) -{ - BindClosure *data = data_; - - if (data == NULL) - return; - - g_array_unref (data->props); - g_free (data); -} - -static ClutterActor * -bind_child_with_properties (gpointer item, - gpointer data_) -{ - BindClosure *data = data_; - ClutterActor *res; - guint i; - - res = g_object_new (data->child_type, NULL); - - for (i = 0; i < data->props->len; i++) - { - const BindProperty *prop = &g_array_index (data->props, BindProperty, i); - - g_object_bind_property (item, prop->model_property, - res, prop->child_property, - prop->flags); - } - - return res; -} - -/** - * clutter_actor_bind_model_with_properties: - * @self: a #ClutterActor - * @model: a #GListModel - * @child_type: the type of #ClutterActor to use when creating - * children mapping to items inside the @model - * @first_model_property: the first property of @model to bind - * @...: tuples of property names on the @model, on the child, and the - * #GBindingFlags used to bind them, terminated by %NULL - * - * Binds a #GListModel to a #ClutterActor. - * - * Unlike clutter_actor_bind_model(), this function automatically creates - * a child #ClutterActor of type @child_type, and binds properties on the - * items inside the @model to the corresponding properties on the child, - * for instance: - * - * ```c - * clutter_actor_bind_model_with_properties (actor, model, - * MY_TYPE_CHILD_VIEW, - * "label", "text", G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE, - * "icon", "image", G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE, - * "selected", "selected", G_BINDING_BIDIRECTIONAL, - * "active", "active", G_BINDING_BIDIRECTIONAL, - * NULL); - * ``` - * - * is the equivalent of calling clutter_actor_bind_model() with a - * #ClutterActorCreateChildFunc of: - * - * ```c - * ClutterActor *res = g_object_new (MY_TYPE_CHILD_VIEW, NULL); - * - * g_object_bind_property (item, "label", res, "text", G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); - * g_object_bind_property (item, "icon", res, "image", G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); - * g_object_bind_property (item, "selected", res, "selected", G_BINDING_BIDIRECTIONAL); - * g_object_bind_property (item, "active", res, "active", G_BINDING_BIDIRECTIONAL); - * - * return res; - * ``` - * - * If the #ClutterActor was already bound to a #GListModel, the previous - * binding is destroyed. - * - * When a #ClutterActor is bound to a model, adding and removing children - * directly is undefined behaviour. - * - * See also: clutter_actor_bind_model()4 - */ -void -clutter_actor_bind_model_with_properties (ClutterActor *self, - GListModel *model, - GType child_type, - const char *first_model_property, - ...) -{ - va_list args; - BindClosure *clos; - const char *model_property; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (G_IS_LIST_MODEL (model)); - g_return_if_fail (g_type_is_a (child_type, CLUTTER_TYPE_ACTOR)); - - clos = g_new0 (BindClosure, 1); - clos->child_type = child_type; - clos->props = g_array_new (FALSE, FALSE, sizeof (BindProperty)); - - va_start (args, first_model_property); - model_property = first_model_property; - while (model_property != NULL) - { - const char *child_property = va_arg (args, char *); - GBindingFlags binding_flags = va_arg (args, guint); - BindProperty bind; - - bind.model_property = g_intern_string (model_property); - bind.child_property = g_intern_string (child_property); - bind.flags = binding_flags; - - g_array_append_val (clos->props, bind); - - model_property = va_arg (args, char *); - } - va_end (args); - - clutter_actor_bind_model (self, model, bind_child_with_properties, clos, bind_closure_free); -} - -/** - * clutter_actor_create_texture_paint_node: - * @self: a #ClutterActor - * @texture: a #CoglTexture - * - * Creates a #ClutterPaintNode initialized using the state of the - * given #ClutterActor, ready to be used inside the implementation - * of the #ClutterActorClass.paint_node virtual function. - * - * The returned paint node has the geometry set to the size of the - * [property@Clutter.Actor:content-box] property; it uses the filters specified - * in the [property@Clutter.Actor:minification-filter] - * and [property@Clutter.Actor:magnification-filter] - * properties; and respects the [property@Clutter.Actor:content-repeat] property. - * - * Returns: (transfer full): The newly created #ClutterPaintNode4 - */ -ClutterPaintNode * -clutter_actor_create_texture_paint_node (ClutterActor *self, - CoglTexture *texture) -{ - ClutterActorPrivate *priv = clutter_actor_get_instance_private (self); - ClutterPaintNode *node; - ClutterActorBox box; - ClutterColor color; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - g_return_val_if_fail (texture != NULL, NULL); - - clutter_actor_get_content_box (self, &box); - - /* ClutterTextureNode will premultiply the blend color, so we - * want it to be white with the paint opacity - */ - color.red = 255; - color.green = 255; - color.blue = 255; - color.alpha = clutter_actor_get_paint_opacity_internal (self); - - node = clutter_texture_node_new (texture, &color, priv->min_filter, priv->mag_filter); - clutter_paint_node_set_static_name (node, "Texture"); - - if (priv->content_repeat == CLUTTER_REPEAT_NONE) - clutter_paint_node_add_rectangle (node, &box); - else - { - float t_w = 1.f, t_h = 1.f; - - if ((priv->content_repeat & CLUTTER_REPEAT_X_AXIS) != FALSE) - t_w = (box.x2 - box.x1) / cogl_texture_get_width (texture); - - if ((priv->content_repeat & CLUTTER_REPEAT_Y_AXIS) != FALSE) - t_h = (box.y2 - box.y1) / cogl_texture_get_height (texture); - - clutter_paint_node_add_texture_rectangle (node, &box, - 0.f, 0.f, - t_w, t_h); - } - - return node; -} - -gboolean -clutter_actor_has_accessible (ClutterActor *actor) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE); - - if (CLUTTER_ACTOR_GET_CLASS (actor)->has_accessible) - return CLUTTER_ACTOR_GET_CLASS (actor)->has_accessible (actor); - - return TRUE; -} - -void -clutter_actor_queue_immediate_relayout (ClutterActor *self) -{ - ClutterStage *stage; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - clutter_actor_queue_relayout (self); - - stage = CLUTTER_STAGE (_clutter_actor_get_stage_internal (self)); - if (stage) - clutter_stage_set_actor_needs_immediate_relayout (stage); -} - -/** - * clutter_actor_invalidate_transform: - * @self: A #ClutterActor - * - * Invalidate the cached transformation matrix of @self. - * This is needed for implementations overriding the apply_transform() - * vfunc and has to be called if the matrix returned by apply_transform() - * would change. - */ -void -clutter_actor_invalidate_transform (ClutterActor *self) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - transform_changed (self); -} - -/** - * clutter_actor_invalidate_paint_volume: - * @self: A #ClutterActor - * - * Invalidates the cached paint volume of @self. This is needed for - * implementations overriding the [vfunc@Clutter.Actor.get_paint_volume] - * virtual function and has to be called every time the paint volume - * returned by that function would change. - */ -void -clutter_actor_invalidate_paint_volume (ClutterActor *self) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - queue_update_paint_volume (self); -} - -void -clutter_actor_attach_grab (ClutterActor *self, - ClutterGrab *grab) -{ - ClutterActorPrivate *priv = self->priv; - - priv->grabs = g_list_prepend (priv->grabs, grab); -} - -void -clutter_actor_detach_grab (ClutterActor *self, - ClutterGrab *grab) -{ - ClutterActorPrivate *priv = self->priv; - - priv->grabs = g_list_remove (priv->grabs, grab); -} - -void -clutter_actor_collect_event_actors (ClutterActor *self, - ClutterActor *deepmost, - GPtrArray *actors) -{ - ClutterActor *iter; - gboolean in_root = FALSE; - - g_assert (actors->len == 0); - - iter = deepmost; - while (iter != NULL) - { - ClutterActor *parent = iter->priv->parent; - - if (clutter_actor_get_reactive (iter) || /* an actor must be reactive */ - parent == NULL) /* unless it's the stage */ - g_ptr_array_add (actors, iter); - - if (iter == self) - { - in_root = TRUE; - break; - } - - iter = parent; - } - - /* The grab root conceptually extends infinitely in all - * directions, so it handles the events that fall outside of - * the actor. - */ - if (!in_root) - { - g_ptr_array_remove_range (actors, 0, actors->len); - g_ptr_array_add (actors, self); - } -} - -const GList * -clutter_actor_peek_actions (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - - if (priv->actions == NULL) - return NULL; - - return _clutter_meta_group_peek_metas (priv->actions); -} - -void clutter_actor_set_implicitly_grabbed (ClutterActor *self, - gboolean is_implicitly_grabbed) -{ - ClutterActorPrivate *priv = self->priv; - - if (is_implicitly_grabbed) - priv->implicitly_grabbed_count++; - else - priv->implicitly_grabbed_count--; - - g_assert (priv->implicitly_grabbed_count >= 0); -} - -/** - * clutter_actor_notify_transform_invalid: - * @self: A #ClutterActor - * - * Invalidate the cached transformation matrix of @self and queue a redraw - * if the transformation matrix has changed. - * This is needed for implementations overriding the apply_transform() - * vfunc and has to be called if the matrix returned by apply_transform() - * would change due to state outside of the object itself. - */ -void -clutter_actor_notify_transform_invalid (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - graphene_matrix_t old_transform; - - if (!priv->transform_valid) - { - clutter_actor_queue_redraw (self); - return; - } - - graphene_matrix_init_from_matrix (&old_transform, &priv->transform); - - transform_changed (self); - ensure_valid_actor_transform (self); - - - g_assert (priv->transform_valid); - - if (!graphene_matrix_equal (&old_transform, &priv->transform)) - clutter_actor_queue_redraw (self); -} - -/** - * clutter_actor_class_set_layout_manager_type - * @actor_class: A #ClutterActor class - * @type: A #GType - * - * Sets the type to be used for creating layout managers for - * actors of @actor_class. - * - * The given @type must be a subtype of [class@Clutter.LayoutManager]. - * - * This function should only be called from class init functions of actors. - */ -void -clutter_actor_class_set_layout_manager_type (ClutterActorClass *actor_class, - GType type) -{ - g_return_if_fail (CLUTTER_IS_ACTOR_CLASS (actor_class)); - g_return_if_fail (g_type_is_a (type, CLUTTER_TYPE_LAYOUT_MANAGER)); - - actor_class->layout_manager_type = type; -} - -/** - * clutter_actor_class_get_layout_manager_type - * @actor_class: A #ClutterActor class - * - * Retrieves the type of the [class@Clutter.LayoutManager] - * used by actors of class @actor_class. - * - * See also: [method@Clutter.ActorClass.set_layout_manager_type]. - * - * Returns: type of a `ClutterLayoutManager` subclass, or %G_TYPE_INVALID - */ -GType -clutter_actor_class_get_layout_manager_type (ClutterActorClass *actor_class) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR_CLASS (actor_class), G_TYPE_INVALID); - - return actor_class->layout_manager_type; -} diff --git a/mutter/clutter/clutter/clutter-actor.h b/mutter/clutter/clutter/clutter-actor.h deleted file mode 100644 index c0510c9..0000000 --- a/mutter/clutter/clutter/clutter-actor.h +++ /dev/null @@ -1,882 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006, 2007, 2008 OpenedHand Ltd - * Copyright (C) 2009, 2010 Intel Corp - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -/* clutter-actor.h */ - -#include -#include -#include - -#include "cogl/cogl.h" - -#include "clutter/clutter-types.h" -#include "clutter/clutter-event.h" -#include "clutter/clutter-paint-context.h" -#include "clutter/clutter-pick-context.h" -#include "mtk/mtk.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_ACTOR (clutter_actor_get_type ()) -#define CLUTTER_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTOR, ClutterActor)) -#define CLUTTER_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTOR, ClutterActorClass)) -#define CLUTTER_IS_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTOR)) -#define CLUTTER_IS_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTOR)) -#define CLUTTER_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTOR, ClutterActorClass)) - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActor, g_object_unref) - -typedef struct _ClutterActorClass ClutterActorClass; -typedef struct _ClutterActorPrivate ClutterActorPrivate; - - -struct _ClutterActor -{ - /*< private >*/ - GInitiallyUnowned parent_instance; - - /*< public >*/ - guint32 flags; - - /*< private >*/ - guint32 private_flags; - - ClutterActorPrivate *priv; -}; - -/** - * ClutterActorClass: - * @show: signal class handler for [signal@Clutter.Actor::show]; it must chain - * up to the parent's implementation - * @hide: signal class handler for [signal@Clutter.Actor::hide]; it must chain - * up to the parent's implementation - * @hide_all: virtual function for containers and composite actors, to - * determine which children should be shown when calling - * clutter_actor_hide_all() on the actor. Defaults to calling - * clutter_actor_hide(). This virtual function is deprecated and it - * should not be overridden. - * @realize: virtual function, used to allocate resources for the actor; - * it should chain up to the parent's implementation. This virtual - * function is deprecated and should not be overridden in newly - * written code. - * @unrealize: virtual function, used to deallocate resources allocated - * in ::realize; it should chain up to the parent's implementation. This - * function is deprecated and should not be overridden in newly - * written code. - * @map: virtual function for containers and composite actors, to - * map their children; it must chain up to the parent's implementation. - * Overriding this function is optional. - * @unmap: virtual function for containers and composite actors, to - * unmap their children; it must chain up to the parent's implementation. - * Overriding this function is optional. - * @paint: virtual function, used to paint the actor - * @get_preferred_width: virtual function, used when querying the minimum - * and natural widths of an actor for a given height; it is used by - * clutter_actor_get_preferred_width() - * @get_preferred_height: virtual function, used when querying the minimum - * and natural heights of an actor for a given width; it is used by - * clutter_actor_get_preferred_height() - * @allocate: virtual function, used when setting the coordinates of an - * actor; it is used by clutter_actor_allocate(); when overriding this - * function without chaining up, clutter_actor_set_allocation() must be - * called and children must be allocated by the implementation, when - * chaining up though, those things will be done by the parent's - * implementation. - * @apply_transform: virtual function, used when applying the transformations - * to an actor before painting it or when transforming coordinates or - * the allocation; if the transformation calculated by this function may - * have changed, the cached transformation must be invalidated by calling - * clutter_actor_invalidate_transform(); it must chain up to the parent's - * implementation - * @parent_set: signal class handler for the [signal@Clutter.Actor::parent-set] - * @destroy: signal class handler for [signal@Clutter.Actor::destroy]. It must - * chain up to the parent's implementation - * @pick: virtual function, used to draw an outline of the actor with - * the given color - * @event: class handler for [signal@Clutter.Actor::event] - * @button_press_event: class handler for [signal@Clutter.Actor::button-press-event] - * @button_release_event: class handler for - * [signal@Clutter.Actor::button-release-event] - * @scroll_event: signal class closure for [signal@Clutter.Actor::scroll-event] - * @key_press_event: signal class closure for [signal@Clutter.Actor::key-press-event] - * @key_release_event: signal class closure for - * [signal@Clutter.Actor::key-release-event] - * @motion_event: signal class closure for [signal@Clutter.Actor::motion-event] - * @enter_event: signal class closure for [signal@Clutter.Actor::enter-event] - * @leave_event: signal class closure for [signal@Clutter.Actor::leave-event] - * @captured_event: signal class closure for [signal@Clutter.Actor::captured-event] - * @key_focus_in: signal class closure for [signal@Clutter.Actor::key-focus-in] - * @key_focus_out: signal class closure for [signal@Clutter.Actor::key-focus-out] - * @queue_relayout: class handler for [signal@Clutter.Actor::queue-relayout] - * @get_accessible: virtual function, returns the accessible object that - * describes the actor to an assistive technology. - * @get_paint_volume: virtual function, for sub-classes to define their - * #ClutterPaintVolume - * @has_overlaps: virtual function for - * sub-classes to advertise whether they need an offscreen redirect - * to get the correct opacity. See - * clutter_actor_set_offscreen_redirect() for details. - * @paint_node: virtual function for creating paint nodes and attaching - * them to the render tree - * @touch_event: signal class closure for [signal@Clutter.Actor::touch-event] - * - * Base class for actors. - */ -struct _ClutterActorClass -{ - /*< private >*/ - GInitiallyUnownedClass parent_class; - - /*< public >*/ - void (* show) (ClutterActor *self); - void (* hide) (ClutterActor *self); - void (* hide_all) (ClutterActor *self); - void (* realize) (ClutterActor *self); - void (* unrealize) (ClutterActor *self); - void (* map) (ClutterActor *self); - void (* unmap) (ClutterActor *self); - void (* paint) (ClutterActor *self, - ClutterPaintContext *paint_context); - void (* parent_set) (ClutterActor *actor, - ClutterActor *old_parent); - - void (* destroy) (ClutterActor *self); - void (* pick) (ClutterActor *actor, - ClutterPickContext *pick_context); - - /* size negotiation */ - void (* get_preferred_width) (ClutterActor *self, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p); - void (* get_preferred_height) (ClutterActor *self, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p); - void (* allocate) (ClutterActor *self, - const ClutterActorBox *box); - - /* transformations */ - void (* apply_transform) (ClutterActor *actor, - graphene_matrix_t *matrix); - - /* event signals */ - gboolean (* event) (ClutterActor *actor, - ClutterEvent *event); - gboolean (* button_press_event) (ClutterActor *actor, - ClutterEvent *event); - gboolean (* button_release_event) (ClutterActor *actor, - ClutterEvent *event); - gboolean (* scroll_event) (ClutterActor *actor, - ClutterEvent *event); - gboolean (* key_press_event) (ClutterActor *actor, - ClutterEvent *event); - gboolean (* key_release_event) (ClutterActor *actor, - ClutterEvent *event); - gboolean (* motion_event) (ClutterActor *actor, - ClutterEvent *event); - gboolean (* enter_event) (ClutterActor *actor, - ClutterEvent *event); - gboolean (* leave_event) (ClutterActor *actor, - ClutterEvent *event); - gboolean (* captured_event) (ClutterActor *actor, - ClutterEvent *event); - void (* key_focus_in) (ClutterActor *actor); - void (* key_focus_out) (ClutterActor *actor); - - void (* queue_relayout) (ClutterActor *self); - - /* accessibility support */ - AtkObject * (* get_accessible) (ClutterActor *self); - - gboolean (* get_paint_volume) (ClutterActor *actor, - ClutterPaintVolume *volume); - - gboolean (* has_overlaps) (ClutterActor *self); - - void (* paint_node) (ClutterActor *self, - ClutterPaintNode *root); - - gboolean (* touch_event) (ClutterActor *self, - ClutterEvent *event); - gboolean (* has_accessible) (ClutterActor *self); - void (* resource_scale_changed) (ClutterActor *self); - float (* calculate_resource_scale) (ClutterActor *self, - int phase); - - void (* child_added) (ClutterActor *self, - ClutterActor *child); - void (* child_removed) (ClutterActor *self, - ClutterActor *child); - - /* private */ - GType layout_manager_type; -}; - -/** - * ClutterActorIter: - * - * An iterator structure that allows to efficiently iterate over a - * section of the scene graph. - * - * The contents of the #ClutterActorIter structure - * are private and should only be accessed using the provided API. - */ -struct _ClutterActorIter -{ - /*< private >*/ - gpointer CLUTTER_PRIVATE_FIELD (dummy1); - gpointer CLUTTER_PRIVATE_FIELD (dummy2); - gint CLUTTER_PRIVATE_FIELD (dummy3); -}; - -CLUTTER_EXPORT -GType clutter_actor_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterActor * clutter_actor_new (void); - -CLUTTER_EXPORT -void clutter_actor_set_flags (ClutterActor *self, - ClutterActorFlags flags); -CLUTTER_EXPORT -void clutter_actor_unset_flags (ClutterActor *self, - ClutterActorFlags flags); -CLUTTER_EXPORT -ClutterActorFlags clutter_actor_get_flags (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_show (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_hide (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_realize (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_unrealize (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_map (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_unmap (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_paint (ClutterActor *self, - ClutterPaintContext *paint_context); -CLUTTER_EXPORT -void clutter_actor_continue_paint (ClutterActor *self, - ClutterPaintContext *paint_context); -CLUTTER_EXPORT -ClutterPaintNode * clutter_actor_create_texture_paint_node (ClutterActor *self, - CoglTexture *texture); -CLUTTER_EXPORT -void clutter_actor_pick (ClutterActor *actor, - ClutterPickContext *pick_context); -CLUTTER_EXPORT -void clutter_actor_continue_pick (ClutterActor *actor, - ClutterPickContext *pick_context); -CLUTTER_EXPORT -void clutter_actor_queue_redraw (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_queue_redraw_with_clip (ClutterActor *self, - const MtkRectangle *clip); -CLUTTER_EXPORT -void clutter_actor_queue_relayout (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_destroy (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_name (ClutterActor *self, - const gchar *name); -CLUTTER_EXPORT -const gchar * clutter_actor_get_name (ClutterActor *self); -CLUTTER_EXPORT -AtkObject * clutter_actor_get_accessible (ClutterActor *self); -CLUTTER_EXPORT -gboolean clutter_actor_has_accessible (ClutterActor *self); - -CLUTTER_EXPORT -gboolean clutter_actor_is_visible (ClutterActor *self); -CLUTTER_EXPORT -gboolean clutter_actor_is_mapped (ClutterActor *self); -CLUTTER_EXPORT -gboolean clutter_actor_is_realized (ClutterActor *self); - -/* Size negotiation */ -CLUTTER_EXPORT -void clutter_actor_set_request_mode (ClutterActor *self, - ClutterRequestMode mode); -CLUTTER_EXPORT -ClutterRequestMode clutter_actor_get_request_mode (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_get_preferred_width (ClutterActor *self, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p); -CLUTTER_EXPORT -void clutter_actor_get_preferred_height (ClutterActor *self, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p); -CLUTTER_EXPORT -void clutter_actor_get_preferred_size (ClutterActor *self, - gfloat *min_width_p, - gfloat *min_height_p, - gfloat *natural_width_p, - gfloat *natural_height_p); -CLUTTER_EXPORT -void clutter_actor_allocate (ClutterActor *self, - const ClutterActorBox *box); -CLUTTER_EXPORT -void clutter_actor_allocate_preferred_size (ClutterActor *self, - float x, - float y); -CLUTTER_EXPORT -void clutter_actor_allocate_available_size (ClutterActor *self, - gfloat x, - gfloat y, - gfloat available_width, - gfloat available_height); -CLUTTER_EXPORT -void clutter_actor_allocate_align_fill (ClutterActor *self, - const ClutterActorBox *box, - gdouble x_align, - gdouble y_align, - gboolean x_fill, - gboolean y_fill); -CLUTTER_EXPORT -void clutter_actor_set_allocation (ClutterActor *self, - const ClutterActorBox *box); -CLUTTER_EXPORT -void clutter_actor_get_allocation_box (ClutterActor *self, - ClutterActorBox *box); -CLUTTER_EXPORT -gboolean clutter_actor_has_allocation (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_size (ClutterActor *self, - gfloat width, - gfloat height); -CLUTTER_EXPORT -void clutter_actor_get_size (ClutterActor *self, - gfloat *width, - gfloat *height); -CLUTTER_EXPORT -void clutter_actor_set_position (ClutterActor *self, - gfloat x, - gfloat y); -CLUTTER_EXPORT -gboolean clutter_actor_get_fixed_position (ClutterActor *self, - float *x, - float *y); -CLUTTER_EXPORT -void clutter_actor_get_position (ClutterActor *self, - gfloat *x, - gfloat *y); -CLUTTER_EXPORT -gboolean clutter_actor_get_fixed_position_set (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_fixed_position_set (ClutterActor *self, - gboolean is_set); -CLUTTER_EXPORT -void clutter_actor_move_by (ClutterActor *self, - gfloat dx, - gfloat dy); - -/* Actor geometry */ -CLUTTER_EXPORT -gfloat clutter_actor_get_width (ClutterActor *self); -CLUTTER_EXPORT -gfloat clutter_actor_get_height (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_width (ClutterActor *self, - gfloat width); -CLUTTER_EXPORT -void clutter_actor_set_height (ClutterActor *self, - gfloat height); -CLUTTER_EXPORT -gfloat clutter_actor_get_x (ClutterActor *self); -CLUTTER_EXPORT -gfloat clutter_actor_get_y (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_x (ClutterActor *self, - gfloat x); -CLUTTER_EXPORT -void clutter_actor_set_y (ClutterActor *self, - gfloat y); -CLUTTER_EXPORT -void clutter_actor_set_z_position (ClutterActor *self, - gfloat z_position); -CLUTTER_EXPORT -gfloat clutter_actor_get_z_position (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_layout_manager (ClutterActor *self, - ClutterLayoutManager *manager); -CLUTTER_EXPORT -ClutterLayoutManager * clutter_actor_get_layout_manager (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_x_align (ClutterActor *self, - ClutterActorAlign x_align); -CLUTTER_EXPORT -ClutterActorAlign clutter_actor_get_x_align (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_y_align (ClutterActor *self, - ClutterActorAlign y_align); -CLUTTER_EXPORT -ClutterActorAlign clutter_actor_get_y_align (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_margin_top (ClutterActor *self, - gfloat margin); -CLUTTER_EXPORT -gfloat clutter_actor_get_margin_top (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_margin_bottom (ClutterActor *self, - gfloat margin); -CLUTTER_EXPORT -gfloat clutter_actor_get_margin_bottom (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_margin_left (ClutterActor *self, - gfloat margin); -CLUTTER_EXPORT -gfloat clutter_actor_get_margin_left (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_margin_right (ClutterActor *self, - gfloat margin); -CLUTTER_EXPORT -gfloat clutter_actor_get_margin_right (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_margin (ClutterActor *self, - const ClutterMargin *margin); -CLUTTER_EXPORT -void clutter_actor_get_margin (ClutterActor *self, - ClutterMargin *margin); -CLUTTER_EXPORT -void clutter_actor_set_x_expand (ClutterActor *self, - gboolean expand); -CLUTTER_EXPORT -gboolean clutter_actor_get_x_expand (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_y_expand (ClutterActor *self, - gboolean expand); -CLUTTER_EXPORT -gboolean clutter_actor_get_y_expand (ClutterActor *self); -CLUTTER_EXPORT -gboolean clutter_actor_needs_expand (ClutterActor *self, - ClutterOrientation orientation); - -/* Paint */ -CLUTTER_EXPORT -void clutter_actor_set_clip (ClutterActor *self, - gfloat xoff, - gfloat yoff, - gfloat width, - gfloat height); -CLUTTER_EXPORT -void clutter_actor_remove_clip (ClutterActor *self); -CLUTTER_EXPORT -gboolean clutter_actor_has_clip (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_get_clip (ClutterActor *self, - gfloat *xoff, - gfloat *yoff, - gfloat *width, - gfloat *height); -CLUTTER_EXPORT -void clutter_actor_set_clip_to_allocation (ClutterActor *self, - gboolean clip_set); -CLUTTER_EXPORT -gboolean clutter_actor_get_clip_to_allocation (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_opacity (ClutterActor *self, - guint8 opacity); -CLUTTER_EXPORT -guint8 clutter_actor_get_opacity (ClutterActor *self); -CLUTTER_EXPORT -guint8 clutter_actor_get_paint_opacity (ClutterActor *self); -CLUTTER_EXPORT -gboolean clutter_actor_get_paint_visibility (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_offscreen_redirect (ClutterActor *self, - ClutterOffscreenRedirect redirect); -CLUTTER_EXPORT -ClutterOffscreenRedirect clutter_actor_get_offscreen_redirect (ClutterActor *self); -CLUTTER_EXPORT -gboolean clutter_actor_should_pick (ClutterActor *self, - ClutterPickContext *pick_context); -CLUTTER_EXPORT -gboolean clutter_actor_is_in_clone_paint (ClutterActor *self); -CLUTTER_EXPORT -gboolean clutter_actor_get_paint_box (ClutterActor *self, - ClutterActorBox *box); - -CLUTTER_EXPORT -float clutter_actor_get_resource_scale (ClutterActor *self); - -CLUTTER_EXPORT -gboolean clutter_actor_has_overlaps (ClutterActor *self); - -/* Content */ -CLUTTER_EXPORT -void clutter_actor_set_content (ClutterActor *self, - ClutterContent *content); -CLUTTER_EXPORT -ClutterContent * clutter_actor_get_content (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_content_gravity (ClutterActor *self, - ClutterContentGravity gravity); -CLUTTER_EXPORT -ClutterContentGravity clutter_actor_get_content_gravity (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_content_scaling_filters (ClutterActor *self, - ClutterScalingFilter min_filter, - ClutterScalingFilter mag_filter); -CLUTTER_EXPORT -void clutter_actor_get_content_scaling_filters (ClutterActor *self, - ClutterScalingFilter *min_filter, - ClutterScalingFilter *mag_filter); -CLUTTER_EXPORT -void clutter_actor_set_content_repeat (ClutterActor *self, - ClutterContentRepeat repeat); -CLUTTER_EXPORT -ClutterContentRepeat clutter_actor_get_content_repeat (ClutterActor *self); - -CLUTTER_EXPORT -void clutter_actor_set_color_state (ClutterActor *self, - ClutterColorState *color_state); -CLUTTER_EXPORT -ClutterColorState *clutter_actor_get_color_state (ClutterActor *self); - -CLUTTER_EXPORT -void clutter_actor_get_content_box (ClutterActor *self, - ClutterActorBox *box); -CLUTTER_EXPORT -void clutter_actor_set_background_color (ClutterActor *self, - const ClutterColor *color); -CLUTTER_EXPORT -void clutter_actor_get_background_color (ClutterActor *self, - ClutterColor *color); -CLUTTER_EXPORT -const ClutterPaintVolume * clutter_actor_get_paint_volume (ClutterActor *self); -CLUTTER_EXPORT -ClutterPaintVolume * clutter_actor_get_transformed_paint_volume (ClutterActor *self, - ClutterActor *relative_to_ancestor); - -/* Events */ -CLUTTER_EXPORT -void clutter_actor_set_reactive (ClutterActor *actor, - gboolean reactive); -CLUTTER_EXPORT -gboolean clutter_actor_get_reactive (ClutterActor *actor); -CLUTTER_EXPORT -gboolean clutter_actor_has_key_focus (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_grab_key_focus (ClutterActor *self); -CLUTTER_EXPORT -gboolean clutter_actor_event (ClutterActor *actor, - const ClutterEvent *event, - gboolean capture); -CLUTTER_EXPORT -gboolean clutter_actor_has_pointer (ClutterActor *self); - -/* Text */ -CLUTTER_EXPORT -PangoContext * clutter_actor_get_pango_context (ClutterActor *self); -CLUTTER_EXPORT -PangoContext * clutter_actor_create_pango_context (ClutterActor *self); -CLUTTER_EXPORT -PangoLayout * clutter_actor_create_pango_layout (ClutterActor *self, - const gchar *text); -CLUTTER_EXPORT -void clutter_actor_set_text_direction (ClutterActor *self, - ClutterTextDirection text_dir); -CLUTTER_EXPORT -ClutterTextDirection clutter_actor_get_text_direction (ClutterActor *self); - -/* Actor hierarchy */ -CLUTTER_EXPORT -void clutter_actor_add_child (ClutterActor *self, - ClutterActor *child); -CLUTTER_EXPORT -void clutter_actor_insert_child_at_index (ClutterActor *self, - ClutterActor *child, - gint index_); -CLUTTER_EXPORT -void clutter_actor_insert_child_above (ClutterActor *self, - ClutterActor *child, - ClutterActor *sibling); -CLUTTER_EXPORT -void clutter_actor_insert_child_below (ClutterActor *self, - ClutterActor *child, - ClutterActor *sibling); -CLUTTER_EXPORT -void clutter_actor_replace_child (ClutterActor *self, - ClutterActor *old_child, - ClutterActor *new_child); -CLUTTER_EXPORT -void clutter_actor_remove_child (ClutterActor *self, - ClutterActor *child); -CLUTTER_EXPORT -void clutter_actor_remove_all_children (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_destroy_all_children (ClutterActor *self); -CLUTTER_EXPORT -GList * clutter_actor_get_children (ClutterActor *self); -CLUTTER_EXPORT -gint clutter_actor_get_n_children (ClutterActor *self); -CLUTTER_EXPORT -ClutterActor * clutter_actor_get_child_at_index (ClutterActor *self, - gint index_); -CLUTTER_EXPORT -ClutterActor * clutter_actor_get_previous_sibling (ClutterActor *self); -CLUTTER_EXPORT -ClutterActor * clutter_actor_get_next_sibling (ClutterActor *self); -CLUTTER_EXPORT -ClutterActor * clutter_actor_get_first_child (ClutterActor *self); -CLUTTER_EXPORT -ClutterActor * clutter_actor_get_last_child (ClutterActor *self); -CLUTTER_EXPORT -ClutterActor * clutter_actor_get_parent (ClutterActor *self); -CLUTTER_EXPORT -gboolean clutter_actor_contains (ClutterActor *self, - ClutterActor *descendant); -CLUTTER_EXPORT -ClutterActor* clutter_actor_get_stage (ClutterActor *actor); -CLUTTER_EXPORT -void clutter_actor_set_child_below_sibling (ClutterActor *self, - ClutterActor *child, - ClutterActor *sibling); -CLUTTER_EXPORT -void clutter_actor_set_child_above_sibling (ClutterActor *self, - ClutterActor *child, - ClutterActor *sibling); -CLUTTER_EXPORT -void clutter_actor_set_child_at_index (ClutterActor *self, - ClutterActor *child, - gint index_); -CLUTTER_EXPORT -void clutter_actor_iter_init (ClutterActorIter *iter, - ClutterActor *root); -CLUTTER_EXPORT -gboolean clutter_actor_iter_next (ClutterActorIter *iter, - ClutterActor **child); -CLUTTER_EXPORT -gboolean clutter_actor_iter_prev (ClutterActorIter *iter, - ClutterActor **child); -CLUTTER_EXPORT -void clutter_actor_iter_remove (ClutterActorIter *iter); -CLUTTER_EXPORT -void clutter_actor_iter_destroy (ClutterActorIter *iter); -CLUTTER_EXPORT -gboolean clutter_actor_iter_is_valid (const ClutterActorIter *iter); - -/* Transformations */ -CLUTTER_EXPORT -gboolean clutter_actor_is_rotated (ClutterActor *self); -CLUTTER_EXPORT -gboolean clutter_actor_is_scaled (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_pivot_point (ClutterActor *self, - gfloat pivot_x, - gfloat pivot_y); -CLUTTER_EXPORT -void clutter_actor_get_pivot_point (ClutterActor *self, - gfloat *pivot_x, - gfloat *pivot_y); -CLUTTER_EXPORT -void clutter_actor_set_pivot_point_z (ClutterActor *self, - gfloat pivot_z); -CLUTTER_EXPORT -gfloat clutter_actor_get_pivot_point_z (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_rotation_angle (ClutterActor *self, - ClutterRotateAxis axis, - gdouble angle); -CLUTTER_EXPORT -gdouble clutter_actor_get_rotation_angle (ClutterActor *self, - ClutterRotateAxis axis); -CLUTTER_EXPORT -void clutter_actor_set_scale (ClutterActor *self, - gdouble scale_x, - gdouble scale_y); -CLUTTER_EXPORT -void clutter_actor_get_scale (ClutterActor *self, - gdouble *scale_x, - gdouble *scale_y); -CLUTTER_EXPORT -void clutter_actor_set_scale_z (ClutterActor *self, - gdouble scale_z); -CLUTTER_EXPORT -gdouble clutter_actor_get_scale_z (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_translation (ClutterActor *self, - gfloat translate_x, - gfloat translate_y, - gfloat translate_z); -CLUTTER_EXPORT -void clutter_actor_get_translation (ClutterActor *self, - gfloat *translate_x, - gfloat *translate_y, - gfloat *translate_z); -CLUTTER_EXPORT -void clutter_actor_set_transform (ClutterActor *self, - const graphene_matrix_t *transform); -CLUTTER_EXPORT -void clutter_actor_get_transform (ClutterActor *self, - graphene_matrix_t *transform); -CLUTTER_EXPORT -void clutter_actor_set_child_transform (ClutterActor *self, - const graphene_matrix_t *transform); -CLUTTER_EXPORT -void clutter_actor_get_child_transform (ClutterActor *self, - graphene_matrix_t *transform); - -CLUTTER_EXPORT -void clutter_actor_get_transformed_extents (ClutterActor *self, - graphene_rect_t *rect); - -CLUTTER_EXPORT -void clutter_actor_get_transformed_position (ClutterActor *self, - gfloat *x, - gfloat *y); -CLUTTER_EXPORT -void clutter_actor_get_transformed_size (ClutterActor *self, - gfloat *width, - gfloat *height); -CLUTTER_EXPORT -gboolean clutter_actor_transform_stage_point (ClutterActor *self, - gfloat x, - gfloat y, - gfloat *x_out, - gfloat *y_out); -CLUTTER_EXPORT -void clutter_actor_get_abs_allocation_vertices (ClutterActor *self, - graphene_point3d_t *verts); -CLUTTER_EXPORT -void clutter_actor_apply_transform_to_point (ClutterActor *self, - const graphene_point3d_t *point, - graphene_point3d_t *vertex); -CLUTTER_EXPORT -void clutter_actor_apply_relative_transform_to_point (ClutterActor *self, - ClutterActor *ancestor, - const graphene_point3d_t *point, - graphene_point3d_t *vertex); - -/* Implicit animations */ -CLUTTER_EXPORT -void clutter_actor_save_easing_state (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_restore_easing_state (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_easing_mode (ClutterActor *self, - ClutterAnimationMode mode); -CLUTTER_EXPORT -ClutterAnimationMode clutter_actor_get_easing_mode (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_easing_duration (ClutterActor *self, - guint msecs); -CLUTTER_EXPORT -guint clutter_actor_get_easing_duration (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_easing_delay (ClutterActor *self, - guint msecs); -CLUTTER_EXPORT -guint clutter_actor_get_easing_delay (ClutterActor *self); -CLUTTER_EXPORT -ClutterTransition * clutter_actor_get_transition (ClutterActor *self, - const char *name); -CLUTTER_EXPORT -void clutter_actor_add_transition (ClutterActor *self, - const char *name, - ClutterTransition *transition); -CLUTTER_EXPORT -void clutter_actor_remove_transition (ClutterActor *self, - const char *name); -CLUTTER_EXPORT -void clutter_actor_remove_all_transitions (ClutterActor *self); - - -CLUTTER_EXPORT -gboolean clutter_actor_has_mapped_clones (ClutterActor *self); -CLUTTER_EXPORT -void clutter_actor_set_opacity_override (ClutterActor *self, - gint opacity); -CLUTTER_EXPORT -gint clutter_actor_get_opacity_override (ClutterActor *self); - -CLUTTER_EXPORT -void clutter_actor_inhibit_culling (ClutterActor *actor); -CLUTTER_EXPORT -void clutter_actor_uninhibit_culling (ClutterActor *actor); - -/** - * ClutterActorCreateChildFunc: - * @item: (type GObject): the item in the model - * @user_data: Data passed to clutter_actor_bind_model() - * - * Creates a #ClutterActor using the @item in the model. - * - * The usual way to implement this function is to create a #ClutterActor - * instance and then bind the #GObject properties to the actor properties - * of interest, using g_object_bind_property(). This way, when the @item - * in the #GListModel changes, the #ClutterActor changes as well. - * - * Returns: (transfer full): The newly created child #ClutterActor4 - */ -typedef ClutterActor * (* ClutterActorCreateChildFunc) (gpointer item, - gpointer user_data); - -CLUTTER_EXPORT -void clutter_actor_bind_model (ClutterActor *self, - GListModel *model, - ClutterActorCreateChildFunc create_child_func, - gpointer user_data, - GDestroyNotify notify); -CLUTTER_EXPORT -void clutter_actor_bind_model_with_properties (ClutterActor *self, - GListModel *model, - GType child_type, - const char *first_model_property, - ...); - -CLUTTER_EXPORT -void clutter_actor_pick_box (ClutterActor *self, - ClutterPickContext *pick_context, - const ClutterActorBox *box); - -CLUTTER_EXPORT -GList * clutter_actor_peek_stage_views (ClutterActor *self); - -CLUTTER_EXPORT -void clutter_actor_invalidate_transform (ClutterActor *self); - -CLUTTER_EXPORT -void clutter_actor_invalidate_paint_volume (ClutterActor *self); - -CLUTTER_EXPORT -void clutter_actor_class_set_layout_manager_type (ClutterActorClass *actor_class, - GType type); -CLUTTER_EXPORT -GType clutter_actor_class_get_layout_manager_type (ClutterActorClass *actor_class); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-align-constraint.c b/mutter/clutter/clutter/clutter-align-constraint.c deleted file mode 100644 index 6c922ba..0000000 --- a/mutter/clutter/clutter/clutter-align-constraint.c +++ /dev/null @@ -1,607 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterAlignConstraint: - * - * A constraint aligning the position of an actor - * - * #ClutterAlignConstraint is a [class@Constraint] that aligns the position - * of the [class@Actor] to which it is applied to the size of another - * [class@Actor] using an alignment factor - */ - -#include "config.h" - -#include "clutter/clutter-align-constraint.h" - -#include "clutter/clutter-actor-meta-private.h" -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-constraint.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-private.h" - -#include - -struct _ClutterAlignConstraint -{ - ClutterConstraint parent_instance; - - ClutterActor *actor; - ClutterActor *source; - ClutterAlignAxis align_axis; - graphene_point_t pivot; - gfloat factor; -}; - -enum -{ - PROP_0, - - PROP_SOURCE, - PROP_ALIGN_AXIS, - PROP_PIVOT_POINT, - PROP_FACTOR, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -G_DEFINE_FINAL_TYPE (ClutterAlignConstraint, - clutter_align_constraint, - CLUTTER_TYPE_CONSTRAINT); - -static void -source_queue_relayout (ClutterActor *actor, - ClutterAlignConstraint *align) -{ - if (align->actor != NULL) - _clutter_actor_queue_only_relayout (align->actor); -} - -static void -source_destroyed (ClutterActor *actor, - ClutterAlignConstraint *align) -{ - align->source = NULL; -} - -static void -clutter_align_constraint_set_actor (ClutterActorMeta *meta, - ClutterActor *new_actor) -{ - ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (meta); - ClutterActorMetaClass *parent; - - if (new_actor != NULL && - align->source != NULL && - clutter_actor_contains (new_actor, align->source)) - { - g_warning (G_STRLOC ": The source actor '%s' is contained " - "by the actor '%s' associated to the constraint " - "'%s'", - _clutter_actor_get_debug_name (align->source), - _clutter_actor_get_debug_name (new_actor), - _clutter_actor_meta_get_debug_name (meta)); - return; - } - - /* store the pointer to the actor, for later use */ - align->actor = new_actor; - - parent = CLUTTER_ACTOR_META_CLASS (clutter_align_constraint_parent_class); - parent->set_actor (meta, new_actor); -} - -static void -clutter_align_constraint_update_allocation (ClutterConstraint *constraint, - ClutterActor *actor, - ClutterActorBox *allocation) -{ - ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (constraint); - gfloat source_width, source_height; - gfloat actor_width, actor_height; - gfloat offset_x_start, offset_y_start; - gfloat pivot_x, pivot_y; - - if (align->source == NULL) - return; - - clutter_actor_box_get_size (allocation, &actor_width, &actor_height); - - clutter_actor_get_size (align->source, &source_width, &source_height); - - pivot_x = align->pivot.x == -1.f - ? align->factor - : align->pivot.x; - pivot_y = align->pivot.y == -1.f - ? align->factor - : align->pivot.y; - - offset_x_start = pivot_x * -actor_width; - offset_y_start = pivot_y * -actor_height; - - switch (align->align_axis) - { - case CLUTTER_ALIGN_X_AXIS: - allocation->x1 += offset_x_start + (source_width * align->factor); - allocation->x2 = allocation->x1 + actor_width; - break; - - case CLUTTER_ALIGN_Y_AXIS: - allocation->y1 += offset_y_start + (source_height * align->factor); - allocation->y2 = allocation->y1 + actor_height; - break; - - case CLUTTER_ALIGN_BOTH: - allocation->x1 += offset_x_start + (source_width * align->factor); - allocation->y1 += offset_y_start + (source_height * align->factor); - allocation->x2 = allocation->x1 + actor_width; - allocation->y2 = allocation->y1 + actor_height; - break; - - default: - g_assert_not_reached (); - break; - } - - clutter_actor_box_clamp_to_pixel (allocation); -} - -static void -clutter_align_constraint_dispose (GObject *gobject) -{ - ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (gobject); - - if (align->source != NULL) - { - g_signal_handlers_disconnect_by_func (align->source, - G_CALLBACK (source_destroyed), - align); - g_signal_handlers_disconnect_by_func (align->source, - G_CALLBACK (source_queue_relayout), - align); - align->source = NULL; - } - - G_OBJECT_CLASS (clutter_align_constraint_parent_class)->dispose (gobject); -} - -static void -clutter_align_constraint_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (gobject); - - switch (prop_id) - { - case PROP_SOURCE: - clutter_align_constraint_set_source (align, g_value_get_object (value)); - break; - - case PROP_ALIGN_AXIS: - clutter_align_constraint_set_align_axis (align, g_value_get_enum (value)); - break; - - case PROP_PIVOT_POINT: - clutter_align_constraint_set_pivot_point (align, g_value_get_boxed (value)); - break; - - case PROP_FACTOR: - clutter_align_constraint_set_factor (align, g_value_get_float (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_align_constraint_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (gobject); - - switch (prop_id) - { - case PROP_SOURCE: - g_value_set_object (value, align->source); - break; - - case PROP_ALIGN_AXIS: - g_value_set_enum (value, align->align_axis); - break; - - case PROP_PIVOT_POINT: - { - graphene_point_t point; - - clutter_align_constraint_get_pivot_point (align, &point); - - g_value_set_boxed (value, &point); - } - break; - - case PROP_FACTOR: - g_value_set_float (value, align->factor); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); - ClutterConstraintClass *constraint_class = CLUTTER_CONSTRAINT_CLASS (klass); - - meta_class->set_actor = clutter_align_constraint_set_actor; - - constraint_class->update_allocation = clutter_align_constraint_update_allocation; - - /** - * ClutterAlignConstraint:source: - * - * The #ClutterActor used as the source for the alignment. - * - * The #ClutterActor must not be a child or a grandchild of the actor - * using the constraint. - */ - obj_props[PROP_SOURCE] = - g_param_spec_object ("source", NULL, NULL, - CLUTTER_TYPE_ACTOR, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT); - - /** - * ClutterAlignConstraint:align-axis: - * - * The axis to be used to compute the alignment - */ - obj_props[PROP_ALIGN_AXIS] = - g_param_spec_enum ("align-axis", NULL, NULL, - CLUTTER_TYPE_ALIGN_AXIS, - CLUTTER_ALIGN_X_AXIS, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT); - - /** - * ClutterAlignConstraint:pivot-point: - * - * The pivot point used by the constraint. The pivot point is the - * point in the constraint actor around which the aligning is applied, - * with (0, 0) being the top left corner of the actor and (1, 1) the - * bottom right corner of the actor. - * - * For example, setting the pivot point to (0.5, 0.5) and using a factor - * of 1 for both axes will align the actors horizontal and vertical - * center point with the bottom right corner of the source actor. - * - * By default, the pivot point is set to (-1, -1), which means it's not - * used and the constrained actor will be aligned to always stay inside - * the source actor. - */ - obj_props[PROP_PIVOT_POINT] = - g_param_spec_boxed ("pivot-point", NULL, NULL, - GRAPHENE_TYPE_POINT, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterAlignConstraint:factor: - * - * The alignment factor, as a normalized value between 0.0 and 1.0 - * - * The factor depends on the #ClutterAlignConstraint:align-axis property: - * with an align-axis value of %CLUTTER_ALIGN_X_AXIS, 0.0 means left and - * 1.0 means right; with a value of %CLUTTER_ALIGN_Y_AXIS, 0.0 means top - * and 1.0 means bottom. - */ - obj_props[PROP_FACTOR] = - g_param_spec_float ("factor", NULL, NULL, - 0.0, 1.0, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT); - - gobject_class->dispose = clutter_align_constraint_dispose; - gobject_class->set_property = clutter_align_constraint_set_property; - gobject_class->get_property = clutter_align_constraint_get_property; - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); -} - -static void -clutter_align_constraint_init (ClutterAlignConstraint *self) -{ - self->actor = NULL; - self->source = NULL; - self->align_axis = CLUTTER_ALIGN_X_AXIS; - self->pivot.x = -1.f; - self->pivot.y = -1.f; - self->factor = 0.0f; -} - -/** - * clutter_align_constraint_new: - * @source: (allow-none): the #ClutterActor to use as the source of the - * alignment, or %NULL - * @axis: the axis to be used to compute the alignment - * @factor: the alignment factor, between 0.0 and 1.0 - * - * Creates a new constraint, aligning a #ClutterActor's position with - * regards of the size of the actor to @source, with the given - * alignment @factor - * - * Return value: the newly created #ClutterAlignConstraint - */ -ClutterConstraint * -clutter_align_constraint_new (ClutterActor *source, - ClutterAlignAxis axis, - gfloat factor) -{ - g_return_val_if_fail (source == NULL || CLUTTER_IS_ACTOR (source), NULL); - - return g_object_new (CLUTTER_TYPE_ALIGN_CONSTRAINT, - "source", source, - "align-axis", axis, - "factor", factor, - NULL); -} - -/** - * clutter_align_constraint_set_source: - * @align: a #ClutterAlignConstraint - * @source: (allow-none): a #ClutterActor, or %NULL to unset the source - * - * Sets the source of the alignment constraint - */ -void -clutter_align_constraint_set_source (ClutterAlignConstraint *align, - ClutterActor *source) -{ - ClutterActor *old_source, *actor; - ClutterActorMeta *meta; - - g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align)); - g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source)); - - if (align->source == source) - return; - - meta = CLUTTER_ACTOR_META (align); - actor = clutter_actor_meta_get_actor (meta); - if (actor != NULL && source != NULL) - { - if (clutter_actor_contains (actor, source)) - { - g_warning (G_STRLOC ": The source actor '%s' is contained " - "by the actor '%s' associated to the constraint " - "'%s'", - _clutter_actor_get_debug_name (source), - _clutter_actor_get_debug_name (actor), - _clutter_actor_meta_get_debug_name (meta)); - return; - } - } - - old_source = align->source; - if (old_source != NULL) - { - g_signal_handlers_disconnect_by_func (old_source, - G_CALLBACK (source_destroyed), - align); - g_signal_handlers_disconnect_by_func (old_source, - G_CALLBACK (source_queue_relayout), - align); - } - - align->source = source; - if (align->source != NULL) - { - g_signal_connect (align->source, "queue-relayout", - G_CALLBACK (source_queue_relayout), - align); - g_signal_connect (align->source, "destroy", - G_CALLBACK (source_destroyed), - align); - - if (align->actor != NULL) - clutter_actor_queue_relayout (align->actor); - } - - g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_SOURCE]); -} - -/** - * clutter_align_constraint_get_source: - * @align: a #ClutterAlignConstraint - * - * Retrieves the source of the alignment - * - * Return value: (transfer none): the #ClutterActor used as the source - * of the alignment - */ -ClutterActor * -clutter_align_constraint_get_source (ClutterAlignConstraint *align) -{ - g_return_val_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align), NULL); - - return align->source; -} - -/** - * clutter_align_constraint_set_align_axis: - * @align: a #ClutterAlignConstraint - * @axis: the axis to which the alignment refers to - * - * Sets the axis to which the alignment refers to - */ -void -clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align, - ClutterAlignAxis axis) -{ - g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align)); - - if (align->align_axis == axis) - return; - - align->align_axis = axis; - - if (align->actor != NULL) - clutter_actor_queue_relayout (align->actor); - - g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_ALIGN_AXIS]); -} - -/** - * clutter_align_constraint_get_align_axis: - * @align: a #ClutterAlignConstraint - * - * Retrieves the value set using [method@Clutter.AlignConstraint.set_align_axis] - * - * Return value: the alignment axis - */ -ClutterAlignAxis -clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align) -{ - g_return_val_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align), - CLUTTER_ALIGN_X_AXIS); - - return align->align_axis; -} - -/** - * clutter_align_constraint_set_pivot_point: - * @align: a #ClutterAlignConstraint - * @pivot_point: A #GraphenePoint - * - * Sets the pivot point used by the constraint, the pivot point is the - * point in the constraint actor around which the aligning is applied, - * with (0, 0) being the top left corner of the actor and (1, 1) the - * bottom right corner of the actor. - * - * If -1 is used, the pivot point is unset and the constrained actor - * will be aligned to always stay inside the source actor. - */ -void -clutter_align_constraint_set_pivot_point (ClutterAlignConstraint *align, - const graphene_point_t *pivot_point) -{ - g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align)); - g_return_if_fail (pivot_point != NULL); - g_return_if_fail (pivot_point->x == -1.f || - (pivot_point->x >= 0.f && pivot_point->x <= 1.f)); - g_return_if_fail (pivot_point->y == -1.f || - (pivot_point->y >= 0.f && pivot_point->y <= 1.f)); - - if (graphene_point_equal (&align->pivot, pivot_point)) - return; - - align->pivot = *pivot_point; - - if (align->actor != NULL) - clutter_actor_queue_relayout (align->actor); - - g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_PIVOT_POINT]); -} - -/** - * clutter_align_constraint_get_pivot_point - * @align: a #ClutterAlignConstraint - * @pivot_point: (out caller-allocates): return location for a #GraphenePoint - * - * Gets the pivot point used by the constraint set with - * [method@Clutter.AlignConstraint.set_pivot_point]. If no custom pivot - * point is set, -1 is set. - */ -void -clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align, - graphene_point_t *pivot_point) -{ - g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align)); - g_return_if_fail (pivot_point != NULL); - - *pivot_point = align->pivot; -} - -/** - * clutter_align_constraint_set_factor: - * @align: a #ClutterAlignConstraint - * @factor: the alignment factor, between 0.0 and 1.0 - * - * Sets the alignment factor of the constraint - * - * The factor depends on the #ClutterAlignConstraint:align-axis property - * and it is a value between 0.0 (meaning left, when - * #ClutterAlignConstraint:align-axis is set to %CLUTTER_ALIGN_X_AXIS; or - * meaning top, when #ClutterAlignConstraint:align-axis is set to - * %CLUTTER_ALIGN_Y_AXIS) and 1.0 (meaning right, when - * #ClutterAlignConstraint:align-axis is set to %CLUTTER_ALIGN_X_AXIS; or - * meaning bottom, when #ClutterAlignConstraint:align-axis is set to - * %CLUTTER_ALIGN_Y_AXIS). A value of 0.5 aligns in the middle in either - * cases - */ -void -clutter_align_constraint_set_factor (ClutterAlignConstraint *align, - gfloat factor) -{ - g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align)); - - align->factor = CLAMP (factor, 0.0, 1.0); - - if (align->actor != NULL) - clutter_actor_queue_relayout (align->actor); - - g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_FACTOR]); -} - -/** - * clutter_align_constraint_get_factor: - * @align: a #ClutterAlignConstraint - * - * Retrieves the factor set using [method@Clutter.AlignConstraint.set_factor] - * - * Return value: the alignment factor - */ -gfloat -clutter_align_constraint_get_factor (ClutterAlignConstraint *align) -{ - g_return_val_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align), 0.0); - - return align->factor; -} diff --git a/mutter/clutter/clutter/clutter-align-constraint.h b/mutter/clutter/clutter/clutter-align-constraint.h deleted file mode 100644 index 2b5957f..0000000 --- a/mutter/clutter/clutter/clutter-align-constraint.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-constraint.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_ALIGN_CONSTRAINT (clutter_align_constraint_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_FINAL_TYPE (ClutterAlignConstraint, clutter_align_constraint, - CLUTTER, ALIGN_CONSTRAINT, ClutterConstraint) - -CLUTTER_EXPORT -ClutterConstraint *clutter_align_constraint_new (ClutterActor *source, - ClutterAlignAxis axis, - gfloat factor); - -CLUTTER_EXPORT -void clutter_align_constraint_set_source (ClutterAlignConstraint *align, - ClutterActor *source); -CLUTTER_EXPORT -ClutterActor * clutter_align_constraint_get_source (ClutterAlignConstraint *align); -CLUTTER_EXPORT -void clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align, - ClutterAlignAxis axis); -CLUTTER_EXPORT -ClutterAlignAxis clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align); -CLUTTER_EXPORT -void clutter_align_constraint_set_pivot_point (ClutterAlignConstraint *align, - const graphene_point_t *pivot_point); -CLUTTER_EXPORT -void clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align, - graphene_point_t *pivot_point); -CLUTTER_EXPORT -void clutter_align_constraint_set_factor (ClutterAlignConstraint *align, - gfloat factor); -CLUTTER_EXPORT -gfloat clutter_align_constraint_get_factor (ClutterAlignConstraint *align); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-animatable.c b/mutter/clutter/clutter/clutter-animatable.c deleted file mode 100644 index bae5cd7..0000000 --- a/mutter/clutter/clutter/clutter-animatable.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterAnimatable: - * - * Interface for animatable classes - * - * #ClutterAnimatable is an interface that allows a [class@GObject.Object] class - * to control how an actor will animate a property. - * - * Each #ClutterAnimatable should implement the - * [vfunc@Animatable.interpolate_value] virtual function of the - * interface to compute the animation state between two values of an interval - * depending on a progress factor, expressed as a floating point value. - */ - -#include "config.h" - -#include "clutter/clutter-animatable.h" -#include "clutter/clutter-interval.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-private.h" - -G_DEFINE_INTERFACE (ClutterAnimatable, clutter_animatable, G_TYPE_OBJECT); - -static void -clutter_animatable_default_init (ClutterAnimatableInterface *iface) -{ -} - -/** - * clutter_animatable_find_property: - * @animatable: a #ClutterAnimatable - * @property_name: the name of the animatable property to find - * - * Finds the [class@GObject.ParamSpec] for @property_name - * - * Return value: (transfer none): The #GParamSpec for the given property - * or %NULL - */ -GParamSpec * -clutter_animatable_find_property (ClutterAnimatable *animatable, - const gchar *property_name) -{ - ClutterAnimatableInterface *iface; - - g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), NULL); - g_return_val_if_fail (property_name != NULL, NULL); - - CLUTTER_NOTE (ANIMATION, "Looking for property '%s'", property_name); - - iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable); - if (iface->find_property != NULL) - return iface->find_property (animatable, property_name); - - return g_object_class_find_property (G_OBJECT_GET_CLASS (animatable), - property_name); -} - -/** - * clutter_animatable_get_initial_state: - * @animatable: a #ClutterAnimatable - * @property_name: the name of the animatable property to retrieve - * @value: a #GValue initialized to the type of the property to retrieve - * - * Retrieves the current state of @property_name and sets @value with it - */ -void -clutter_animatable_get_initial_state (ClutterAnimatable *animatable, - const gchar *property_name, - GValue *value) -{ - ClutterAnimatableInterface *iface; - - g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable)); - g_return_if_fail (property_name != NULL); - - CLUTTER_NOTE (ANIMATION, "Getting initial state of '%s'", property_name); - - iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable); - if (iface->get_initial_state != NULL) - iface->get_initial_state (animatable, property_name, value); - else - g_object_get_property (G_OBJECT (animatable), property_name, value); -} - -/** - * clutter_animatable_set_final_state: - * @animatable: a #ClutterAnimatable - * @property_name: the name of the animatable property to set - * @value: the value of the animatable property to set - * - * Sets the current state of @property_name to @value - */ -void -clutter_animatable_set_final_state (ClutterAnimatable *animatable, - const gchar *property_name, - const GValue *value) -{ - ClutterAnimatableInterface *iface; - - g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable)); - g_return_if_fail (property_name != NULL); - - CLUTTER_NOTE (ANIMATION, "Setting state of property '%s'", property_name); - - iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable); - if (iface->set_final_state != NULL) - iface->set_final_state (animatable, property_name, value); - else - g_object_set_property (G_OBJECT (animatable), property_name, value); -} - -/** - * clutter_animatable_interpolate_value: - * @animatable: a #ClutterAnimatable - * @property_name: the name of the property to interpolate - * @interval: a #ClutterInterval with the animation range - * @progress: the progress to use to interpolate between the - * initial and final values of the @interval - * @value: (out): return location for an initialized #GValue - * using the same type of the @interval - * - * Asks a #ClutterAnimatable implementation to interpolate a - * a named property between the initial and final values of - * a #ClutterInterval, using @progress as the interpolation - * value, and store the result inside @value. - * - * This function should be used for every property animation - * involving `ClutterAnimatable`s. - * - * Return value: %TRUE if the interpolation was successful, - * and %FALSE otherwise - */ -gboolean -clutter_animatable_interpolate_value (ClutterAnimatable *animatable, - const gchar *property_name, - ClutterInterval *interval, - gdouble progress, - GValue *value) -{ - ClutterAnimatableInterface *iface; - - g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), FALSE); - g_return_val_if_fail (property_name != NULL, FALSE); - g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), FALSE); - g_return_val_if_fail (value != NULL, FALSE); - - CLUTTER_NOTE (ANIMATION, "Interpolating '%s' (progress: %.3f)", - property_name, - progress); - - iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable); - if (iface->interpolate_value != NULL) - { - return iface->interpolate_value (animatable, property_name, - interval, - progress, - value); - } - else - return clutter_interval_compute_value (interval, progress, value); -} - -/** - * clutter_animatable_get_actor: - * @animatable: a #ClutterAnimatable - * - * Get animated actor. - * - * Return value: (transfer none): a #ClutterActor - */ -ClutterActor * -clutter_animatable_get_actor (ClutterAnimatable *animatable) -{ - ClutterAnimatableInterface *iface; - - g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), NULL); - - iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable); - - g_return_val_if_fail (iface->get_actor, NULL); - - return iface->get_actor (animatable); -} diff --git a/mutter/clutter/clutter/clutter-animatable.h b/mutter/clutter/clutter/clutter-animatable.h deleted file mode 100644 index 64c4c5f..0000000 --- a/mutter/clutter/clutter/clutter-animatable.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_ANIMATABLE (clutter_animatable_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_INTERFACE (ClutterAnimatable, clutter_animatable, - CLUTTER, ANIMATABLE, - GObject) - -/** - * ClutterAnimatableInterface: - * @find_property: virtual function for retrieving the #GParamSpec of - * an animatable property - * @get_initial_state: virtual function for retrieving the initial - * state of an animatable property - * @set_final_state: virtual function for setting the state of an - * animatable property - * @interpolate_value: virtual function for interpolating the progress - * of a property - * @get_actor: virtual function for getting associated actor - */ -struct _ClutterAnimatableInterface -{ - /*< private >*/ - GTypeInterface parent_iface; - - /*< public >*/ - GParamSpec *(* find_property) (ClutterAnimatable *animatable, - const gchar *property_name); - void (* get_initial_state) (ClutterAnimatable *animatable, - const gchar *property_name, - GValue *value); - void (* set_final_state) (ClutterAnimatable *animatable, - const gchar *property_name, - const GValue *value); - gboolean (* interpolate_value) (ClutterAnimatable *animatable, - const gchar *property_name, - ClutterInterval *interval, - gdouble progress, - GValue *value); - ClutterActor * (* get_actor) (ClutterAnimatable *animatable); -}; - -CLUTTER_EXPORT -GParamSpec *clutter_animatable_find_property (ClutterAnimatable *animatable, - const gchar *property_name); -CLUTTER_EXPORT -void clutter_animatable_get_initial_state (ClutterAnimatable *animatable, - const gchar *property_name, - GValue *value); -CLUTTER_EXPORT -void clutter_animatable_set_final_state (ClutterAnimatable *animatable, - const gchar *property_name, - const GValue *value); -CLUTTER_EXPORT -gboolean clutter_animatable_interpolate_value (ClutterAnimatable *animatable, - const gchar *property_name, - ClutterInterval *interval, - gdouble progress, - GValue *value); - -CLUTTER_EXPORT -ClutterActor * clutter_animatable_get_actor (ClutterAnimatable *animatable); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-backend-private.h b/mutter/clutter/clutter/clutter-backend-private.h deleted file mode 100644 index 41738e8..0000000 --- a/mutter/clutter/clutter/clutter-backend-private.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#include "clutter/clutter-backend.h" -#include "clutter/clutter-seat.h" -#include "clutter/clutter-stage-window.h" - -#define CLUTTER_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BACKEND, ClutterBackendClass)) -#define CLUTTER_IS_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BACKEND)) -#define CLUTTER_BACKEND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BACKEND, ClutterBackendClass)) - -G_BEGIN_DECLS - -typedef struct _ClutterBackendPrivate ClutterBackendPrivate; - -struct _ClutterBackend -{ - /*< private >*/ - GObject parent_instance; - - CoglRenderer *cogl_renderer; - CoglDisplay *cogl_display; - CoglContext *cogl_context; - GSource *cogl_source; - - CoglOnscreen *dummy_onscreen; - - cairo_font_options_t *font_options; - - gchar *font_name; - - float fallback_resource_scale; - - ClutterStageWindow *stage_window; - - ClutterInputMethod *input_method; -}; - -struct _ClutterBackendClass -{ - /*< private >*/ - GObjectClass parent_class; - - /* vfuncs */ - ClutterStageWindow * (* create_stage) (ClutterBackend *backend, - ClutterStage *wrapper, - GError **error); - CoglRenderer * (* get_renderer) (ClutterBackend *backend, - GError **error); - CoglDisplay * (* get_display) (ClutterBackend *backend, - CoglRenderer *renderer, - CoglSwapChain *swap_chain, - GError **error); - gboolean (* create_context) (ClutterBackend *backend, - GError **error); - - ClutterSeat * (* get_default_seat) (ClutterBackend *backend); - - gboolean (* is_display_server) (ClutterBackend *backend); - - /* signals */ - void (* resolution_changed) (ClutterBackend *backend); - void (* font_changed) (ClutterBackend *backend); - void (* settings_changed) (ClutterBackend *backend); -}; - -ClutterStageWindow * _clutter_backend_create_stage (ClutterBackend *backend, - ClutterStage *wrapper, - GError **error); -gboolean _clutter_backend_create_context (ClutterBackend *backend, - GError **error); - -CLUTTER_EXPORT -ClutterStageWindow * clutter_backend_get_stage_window (ClutterBackend *backend); - -CLUTTER_EXPORT -void clutter_backend_set_fallback_resource_scale (ClutterBackend *backend, - float fallback_resource_scale); - -float clutter_backend_get_fallback_resource_scale (ClutterBackend *backend); - -gboolean clutter_backend_is_display_server (ClutterBackend *backend); - -CLUTTER_EXPORT -void clutter_backend_destroy (ClutterBackend *backend); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-backend.c b/mutter/clutter/clutter/clutter-backend.c deleted file mode 100644 index 297461d..0000000 --- a/mutter/clutter/clutter/clutter-backend.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By: - * Matthew Allum - * Emmanuele Bassi - * - * Copyright (C) 2006, 2007, 2008 OpenedHand Ltd - * Copyright (C) 2009, 2010 Intel Corp - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/** - * ClutterBackend: - * - * Backend abstraction - * - * Clutter can be compiled against different backends. Each backend - * has to implement a set of functions, in order to be used by Clutter. - * - * #ClutterBackend is the base class abstracting the various implementation; - * it provides a basic API to query the backend for generic information - * and settings. - */ - -#include "config.h" - -#include "clutter/clutter-backend-private.h" -#include "clutter/clutter-context-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-event-private.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-mutter.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-stage-manager-private.h" -#include "clutter/clutter-stage-private.h" -#include "clutter/clutter-stage-window.h" - -#include "cogl/cogl.h" - -#define DEFAULT_FONT_NAME "Sans 10" - -enum -{ - RESOLUTION_CHANGED, - FONT_CHANGED, - SETTINGS_CHANGED, - - LAST_SIGNAL -}; - -G_DEFINE_ABSTRACT_TYPE (ClutterBackend, clutter_backend, G_TYPE_OBJECT) - -static guint backend_signals[LAST_SIGNAL] = { 0, }; - -static void -clutter_backend_dispose (GObject *gobject) -{ - ClutterBackend *backend = CLUTTER_BACKEND (gobject); - - /* clear the events still in the queue of the main context */ - _clutter_clear_events_queue (); - - g_clear_object (&backend->dummy_onscreen); - if (backend->stage_window) - { - g_object_remove_weak_pointer (G_OBJECT (backend->stage_window), - (gpointer *) &backend->stage_window); - backend->stage_window = NULL; - } - - g_clear_pointer (&backend->cogl_source, g_source_destroy); - g_clear_pointer (&backend->font_name, g_free); - g_clear_pointer (&backend->font_options, cairo_font_options_destroy); - g_clear_object (&backend->input_method); - - G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject); -} - -static void -clutter_backend_real_resolution_changed (ClutterBackend *backend) -{ - ClutterContext *context; - ClutterSettings *settings; - gdouble resolution; - gint dpi; - - settings = clutter_settings_get_default (); - g_object_get (settings, "font-dpi", &dpi, NULL); - - if (dpi < 0) - resolution = 96.0; - else - resolution = dpi / 1024.0; - - context = _clutter_context_get_default (); - if (context->font_map != NULL) - cogl_pango_font_map_set_resolution (context->font_map, resolution); -} - -static gboolean -clutter_backend_do_real_create_context (ClutterBackend *backend, - CoglDriver driver_id, - GError **error) -{ - ClutterBackendClass *klass; - CoglSwapChain *swap_chain; - - klass = CLUTTER_BACKEND_GET_CLASS (backend); - - swap_chain = NULL; - - CLUTTER_NOTE (BACKEND, "Creating Cogl renderer"); - backend->cogl_renderer = klass->get_renderer (backend, error); - - if (backend->cogl_renderer == NULL) - goto error; - - CLUTTER_NOTE (BACKEND, "Connecting the renderer"); - cogl_renderer_set_driver (backend->cogl_renderer, driver_id); - if (!cogl_renderer_connect (backend->cogl_renderer, error)) - goto error; - - CLUTTER_NOTE (BACKEND, "Creating Cogl swap chain"); - swap_chain = cogl_swap_chain_new (); - - CLUTTER_NOTE (BACKEND, "Creating Cogl display"); - if (klass->get_display != NULL) - { - backend->cogl_display = klass->get_display (backend, - backend->cogl_renderer, - swap_chain, - error); - } - else - { - CoglOnscreenTemplate *tmpl; - gboolean res; - - tmpl = cogl_onscreen_template_new (swap_chain); - - /* XXX: I have some doubts that this is a good design. - * - * Conceptually should we be able to check an onscreen_template - * without more details about the CoglDisplay configuration? - */ - res = cogl_renderer_check_onscreen_template (backend->cogl_renderer, - tmpl, - error); - - if (!res) - goto error; - - backend->cogl_display = cogl_display_new (backend->cogl_renderer, tmpl); - - /* the display owns the template */ - g_object_unref (tmpl); - } - - if (backend->cogl_display == NULL) - goto error; - - CLUTTER_NOTE (BACKEND, "Setting up the display"); - if (!cogl_display_setup (backend->cogl_display, error)) - goto error; - - CLUTTER_NOTE (BACKEND, "Creating the Cogl context"); - backend->cogl_context = cogl_context_new (backend->cogl_display, error); - if (backend->cogl_context == NULL) - goto error; - - /* the display owns the renderer and the swap chain */ - g_object_unref (backend->cogl_renderer); - g_object_unref (swap_chain); - - return TRUE; - -error: - g_clear_object (&backend->cogl_display); - g_clear_object (&backend->cogl_renderer); - - if (swap_chain != NULL) - g_object_unref (swap_chain); - - return FALSE; -} - -static const struct { - const char *driver_name; - const char *driver_desc; - CoglDriver driver_id; -} all_known_drivers[] = { - { "gl3", "OpenGL 3.1 core profile", COGL_DRIVER_GL3 }, - { "gles2", "OpenGL ES 2.0", COGL_DRIVER_GLES2 }, - { "any", "Default Cogl driver", COGL_DRIVER_ANY }, -}; - -static gboolean -clutter_backend_real_create_context (ClutterBackend *backend, - GError **error) -{ - GError *internal_error = NULL; - const char *drivers_list; - char **known_drivers; - int i; - - if (backend->cogl_context != NULL) - return TRUE; - - drivers_list = g_getenv ("CLUTTER_DRIVER"); - if (drivers_list == NULL) - drivers_list = "*"; - - known_drivers = g_strsplit (drivers_list, ",", 0); - - for (i = 0; backend->cogl_context == NULL && known_drivers[i] != NULL; i++) - { - const char *driver_name = known_drivers[i]; - gboolean is_any = g_str_equal (driver_name, "*"); - int j; - - for (j = 0; j < G_N_ELEMENTS (all_known_drivers); j++) - { - if (is_any || - g_str_equal (all_known_drivers[j].driver_name, driver_name)) - { - CLUTTER_NOTE (BACKEND, "Checking for the %s driver", all_known_drivers[j].driver_desc); - - if (clutter_backend_do_real_create_context (backend, all_known_drivers[j].driver_id, &internal_error)) - break; - - if (internal_error) - { - CLUTTER_NOTE (BACKEND, "Unable to use the %s driver: %s", - all_known_drivers[j].driver_desc, - internal_error->message); - g_clear_error (&internal_error); - } - } - } - } - - g_strfreev (known_drivers); - - if (backend->cogl_context == NULL) - { - if (internal_error != NULL) - g_propagate_error (error, internal_error); - else - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unable to initialize the Clutter backend: no available drivers found."); - - return FALSE; - } - - backend->cogl_source = cogl_glib_source_new (backend->cogl_context, G_PRIORITY_DEFAULT); - g_source_attach (backend->cogl_source, NULL); - - return TRUE; -} - -static void -clutter_backend_class_init (ClutterBackendClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->dispose = clutter_backend_dispose; - - /** - * ClutterBackend::resolution-changed: - * @backend: the #ClutterBackend that emitted the signal - * - * The signal is emitted each time the font - * resolutions has been changed through #ClutterSettings. - */ - backend_signals[RESOLUTION_CHANGED] = - g_signal_new (I_("resolution-changed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterBackendClass, resolution_changed), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - /** - * ClutterBackend::font-changed: - * @backend: the #ClutterBackend that emitted the signal - * - * The signal is emitted each time the font options - * have been changed through #ClutterSettings. - */ - backend_signals[FONT_CHANGED] = - g_signal_new (I_("font-changed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterBackendClass, font_changed), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - /** - * ClutterBackend::settings-changed: - * @backend: the #ClutterBackend that emitted the signal - * - * The signal is emitted each time the #ClutterSettings - * properties have been changed. - */ - backend_signals[SETTINGS_CHANGED] = - g_signal_new (I_("settings-changed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterBackendClass, settings_changed), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - klass->resolution_changed = clutter_backend_real_resolution_changed; - - klass->create_context = clutter_backend_real_create_context; -} - -static void -clutter_backend_init (ClutterBackend *self) -{ - self->dummy_onscreen = NULL; - - self->fallback_resource_scale = 1.f; -} - -ClutterStageWindow * -_clutter_backend_create_stage (ClutterBackend *backend, - ClutterStage *wrapper, - GError **error) -{ - ClutterBackendClass *klass; - ClutterStageWindow *stage_window; - - g_assert (CLUTTER_IS_BACKEND (backend)); - g_assert (CLUTTER_IS_STAGE (wrapper)); - - klass = CLUTTER_BACKEND_GET_CLASS (backend); - if (klass->create_stage != NULL) - stage_window = klass->create_stage (backend, wrapper, error); - else - stage_window = NULL; - - if (stage_window == NULL) - return NULL; - - g_assert (CLUTTER_IS_STAGE_WINDOW (stage_window)); - - backend->stage_window = stage_window; - g_object_add_weak_pointer (G_OBJECT (backend->stage_window), - (gpointer *) &backend->stage_window); - - return stage_window; -} - -gboolean -_clutter_backend_create_context (ClutterBackend *backend, - GError **error) -{ - ClutterBackendClass *klass; - - klass = CLUTTER_BACKEND_GET_CLASS (backend); - - return klass->create_context (backend, error); -} - -/** - * clutter_get_default_backend: - * - * Retrieves the default #ClutterBackend used by Clutter. The - * #ClutterBackend holds backend-specific configuration options. - * - * Return value: (transfer none): the default backend. You should - * not ref or unref the returned object. Applications should rarely - * need to use this. - */ -ClutterBackend * -clutter_get_default_backend (void) -{ - ClutterContext *clutter_context; - - clutter_context = _clutter_context_get_default (); - - return clutter_context->backend; -} - -/** - * clutter_backend_get_resolution: - * @backend: a #ClutterBackend - * - * Gets the resolution for font handling on the screen. - * - * The resolution is a scale factor between points specified in a - * #PangoFontDescription and cairo units. The default value is 96.0, - * meaning that a 10 point font will be 13 units - * high (10 * 96. / 72. = 13.3). - * - * Clutter will set the resolution using the current backend when - * initializing; the resolution is also stored in the - * #ClutterSettings:font-dpi property. - * - * Return value: the current resolution, or -1 if no resolution - * has been set. - */ -gdouble -clutter_backend_get_resolution (ClutterBackend *backend) -{ - ClutterSettings *settings; - gint resolution; - - g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), -1.0); - - settings = clutter_settings_get_default (); - g_object_get (settings, "font-dpi", &resolution, NULL); - - if (resolution < 0) - return 96.0; - - return resolution / 1024.0; -} - -/** - * clutter_backend_set_font_options: - * @backend: a #ClutterBackend - * @options: Cairo font options for the backend, or %NULL - * - * Sets the new font options for @backend. The #ClutterBackend will - * copy the #cairo_font_options_t. - * - * If @options is %NULL, the first following call to - * [method@Clutter.Backend.get_font_options] will return the default font - * options for @backend. - * - * This function is intended for actors creating a Pango layout - * using the PangoCairo API. - */ -void -clutter_backend_set_font_options (ClutterBackend *backend, - const cairo_font_options_t *options) -{ - g_return_if_fail (CLUTTER_IS_BACKEND (backend)); - - if (backend->font_options != options) - { - if (backend->font_options) - cairo_font_options_destroy (backend->font_options); - - if (options) - backend->font_options = cairo_font_options_copy (options); - else - backend->font_options = NULL; - - g_signal_emit (backend, backend_signals[FONT_CHANGED], 0); - } -} - -/** - * clutter_backend_get_font_options: - * @backend: a #ClutterBackend - * - * Retrieves the font options for @backend. - * - * Return value: (transfer none): the font options of the #ClutterBackend. - * The returned #cairo_font_options_t is owned by the backend and should - * not be modified or freed - */ -const cairo_font_options_t * -clutter_backend_get_font_options (ClutterBackend *backend) -{ - g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), NULL); - - if (G_LIKELY (backend->font_options)) - return backend->font_options; - - backend->font_options = cairo_font_options_create (); - - cairo_font_options_set_hint_style (backend->font_options, CAIRO_HINT_STYLE_NONE); - cairo_font_options_set_subpixel_order (backend->font_options, CAIRO_SUBPIXEL_ORDER_DEFAULT); - cairo_font_options_set_antialias (backend->font_options, CAIRO_ANTIALIAS_DEFAULT); - - g_signal_emit (backend, backend_signals[FONT_CHANGED], 0); - - return backend->font_options; -} - -/** - * clutter_backend_get_cogl_context: - * @backend: a #ClutterBackend - * - * Retrieves the #CoglContext associated with the given clutter - * @backend. A #CoglContext is required when using some of the - * experimental 2.0 Cogl API. - * - * Since CoglContext is itself experimental API this API should - * be considered experimental too. - * - * This API is not yet supported on OSX because OSX still - * uses the stub Cogl winsys and the Clutter backend doesn't - * explicitly create a CoglContext. - * - * Return value: (transfer none): The #CoglContext associated with @backend. - */ -CoglContext * -clutter_backend_get_cogl_context (ClutterBackend *backend) -{ - return backend->cogl_context; -} - -/** - * clutter_backend_get_input_method: - * @backend: the #CLutterBackend - * - * Returns the input method used by Clutter - * - * Returns: (transfer none): the input method - **/ -ClutterInputMethod * -clutter_backend_get_input_method (ClutterBackend *backend) -{ - return backend->input_method; -} - -/** - * clutter_backend_set_input_method: - * @backend: the #ClutterBackend - * @method: (nullable): the input method - * - * Sets the input method to be used by Clutter - **/ -void -clutter_backend_set_input_method (ClutterBackend *backend, - ClutterInputMethod *method) -{ - if (backend->input_method == method) - return; - - if (backend->input_method) - clutter_input_method_focus_out (backend->input_method); - - g_set_object (&backend->input_method, method); -} - -ClutterStageWindow * -clutter_backend_get_stage_window (ClutterBackend *backend) -{ - return backend->stage_window; -} - -/** - * clutter_backend_get_default_seat: - * @backend: the #ClutterBackend - * - * Returns the default seat - * - * Returns: (transfer none): the default seat - **/ -ClutterSeat * -clutter_backend_get_default_seat (ClutterBackend *backend) -{ - g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), NULL); - - return CLUTTER_BACKEND_GET_CLASS (backend)->get_default_seat (backend); -} - -void -clutter_backend_set_fallback_resource_scale (ClutterBackend *backend, - float fallback_resource_scale) -{ - backend->fallback_resource_scale = fallback_resource_scale; -} - -float -clutter_backend_get_fallback_resource_scale (ClutterBackend *backend) -{ - return backend->fallback_resource_scale; -} - -gboolean -clutter_backend_is_display_server (ClutterBackend *backend) -{ - return CLUTTER_BACKEND_GET_CLASS (backend)->is_display_server (backend); -} - -void -clutter_backend_destroy (ClutterBackend *backend) -{ - g_object_run_dispose (G_OBJECT (backend)); - g_object_unref (backend); -} diff --git a/mutter/clutter/clutter/clutter-backend.h b/mutter/clutter/clutter/clutter-backend.h deleted file mode 100644 index f04bf45..0000000 --- a/mutter/clutter/clutter/clutter-backend.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * 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 . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -#include "cogl/cogl.h" - -#include "clutter/clutter-keymap.h" -#include "clutter/clutter-types.h" -#include "clutter/clutter-seat.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_BACKEND (clutter_backend_get_type ()) -#define CLUTTER_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BACKEND, ClutterBackend)) -#define CLUTTER_IS_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BACKEND)) - -typedef struct _ClutterBackend ClutterBackend; -typedef struct _ClutterBackendClass ClutterBackendClass; - -CLUTTER_EXPORT -GType clutter_backend_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterBackend * clutter_get_default_backend (void); - -CLUTTER_EXPORT -gdouble clutter_backend_get_resolution (ClutterBackend *backend); - -CLUTTER_EXPORT -void clutter_backend_set_font_options (ClutterBackend *backend, - const cairo_font_options_t *options); -CLUTTER_EXPORT -const cairo_font_options_t * clutter_backend_get_font_options (ClutterBackend *backend); - -CLUTTER_EXPORT -CoglContext * clutter_backend_get_cogl_context (ClutterBackend *backend); - -CLUTTER_EXPORT -ClutterInputMethod * clutter_backend_get_input_method (ClutterBackend *backend); - -CLUTTER_EXPORT -void clutter_backend_set_input_method (ClutterBackend *backend, - ClutterInputMethod *method); -CLUTTER_EXPORT -ClutterSeat * clutter_backend_get_default_seat (ClutterBackend *backend); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackend, g_object_unref) - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-base-types.c b/mutter/clutter/clutter/clutter-base-types.c deleted file mode 100644 index db581ea..0000000 --- a/mutter/clutter/clutter/clutter-base-types.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * 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 . - */ -#include "config.h" - -#include "clutter/clutter-types.h" -#include "clutter/clutter-private.h" - -#include - -#define FLOAT_EPSILON (1e-15) - -/* - * ClutterMargin - */ - -/** - * clutter_margin_new: - * - * Creates a new #ClutterMargin. - * - * Return value: (transfer full): a newly allocated #ClutterMargin. Use - * [method@Clutter.Margin.free] to free the resources associated with it when - * done. - */ -ClutterMargin * -clutter_margin_new (void) -{ - return g_new0 (ClutterMargin, 1); -} - -/** - * clutter_margin_copy: - * @margin_: a #ClutterMargin - * - * Creates a new #ClutterMargin and copies the contents of @margin_ into - * the newly created structure. - * - * Return value: (transfer full): a copy of the #ClutterMargin. - */ -ClutterMargin * -clutter_margin_copy (const ClutterMargin *margin_) -{ - if (G_LIKELY (margin_ != NULL)) - return g_memdup2 (margin_, sizeof (ClutterMargin)); - - return NULL; -} - -/** - * clutter_margin_free: - * @margin_: a #ClutterMargin - * - * Frees the resources allocated by [ctor@Clutter.Margin.new] and - * [method@Clutter.Margin.copy]. - */ -void -clutter_margin_free (ClutterMargin *margin_) -{ - if (G_LIKELY (margin_ != NULL)) - g_free (margin_); -} - -G_DEFINE_BOXED_TYPE (ClutterMargin, clutter_margin, - clutter_margin_copy, - clutter_margin_free) diff --git a/mutter/clutter/clutter/clutter-bin-layout.c b/mutter/clutter/clutter/clutter-bin-layout.c deleted file mode 100644 index ade7870..0000000 --- a/mutter/clutter/clutter/clutter-bin-layout.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterBinLayout: - * - * A simple layout manager - * - * #ClutterBinLayout is a layout manager which implements the following - * policy: - * - * - the preferred size is the maximum preferred size - * between all the children of the container using the - * layout; - * - each child is allocated in "layers", on on top - * of the other; - * - for each layer there are horizontal and vertical - * alignment policies. - */ - -#include "config.h" - -#include - -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-animatable.h" -#include "clutter/clutter-bin-layout.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-layout-meta.h" -#include "clutter/clutter-private.h" - -G_DEFINE_TYPE (ClutterBinLayout, - clutter_bin_layout, - CLUTTER_TYPE_LAYOUT_MANAGER) - -static void -clutter_bin_layout_get_preferred_width (ClutterLayoutManager *manager, - ClutterActor *container, - gfloat for_height, - gfloat *min_width_p, - gfloat *nat_width_p) -{ - ClutterActor *actor = CLUTTER_ACTOR (container); - ClutterActorIter iter; - ClutterActor *child; - gfloat min_width, nat_width; - - min_width = nat_width = 0.0; - - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) - { - gfloat minimum, natural; - - if (!clutter_actor_is_visible (child)) - continue; - - clutter_actor_get_preferred_width (child, for_height, - &minimum, - &natural); - - min_width = MAX (min_width, minimum); - nat_width = MAX (nat_width, natural); - } - - if (min_width_p) - *min_width_p = min_width; - - if (nat_width_p) - *nat_width_p = nat_width; -} - -static void -clutter_bin_layout_get_preferred_height (ClutterLayoutManager *manager, - ClutterActor *container, - gfloat for_width, - gfloat *min_height_p, - gfloat *nat_height_p) -{ - ClutterActor *actor = CLUTTER_ACTOR (container); - ClutterActorIter iter; - ClutterActor *child; - gfloat min_height, nat_height; - - min_height = nat_height = 0.0; - - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) - { - gfloat minimum, natural; - - if (!clutter_actor_is_visible (child)) - continue; - - clutter_actor_get_preferred_height (child, for_width, - &minimum, - &natural); - - min_height = MAX (min_height, minimum); - nat_height = MAX (nat_height, natural); - } - - if (min_height_p) - *min_height_p = min_height; - - if (nat_height_p) - *nat_height_p = nat_height; -} - -static gdouble -get_actor_align_factor (ClutterActorAlign alignment) -{ - switch (alignment) - { - case CLUTTER_ACTOR_ALIGN_CENTER: - return 0.5; - - case CLUTTER_ACTOR_ALIGN_START: - return 0.0; - - case CLUTTER_ACTOR_ALIGN_END: - return 1.0; - - case CLUTTER_ACTOR_ALIGN_FILL: - return 0.0; - } - - return 0.0; -} - -static void -clutter_bin_layout_allocate (ClutterLayoutManager *manager, - ClutterActor *container, - const ClutterActorBox *allocation) -{ - gfloat allocation_x, allocation_y; - gfloat available_w, available_h; - ClutterActor *actor, *child; - ClutterActorIter iter; - - clutter_actor_box_get_origin (allocation, &allocation_x, &allocation_y); - clutter_actor_box_get_size (allocation, &available_w, &available_h); - - actor = CLUTTER_ACTOR (container); - - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) - { - ClutterActorBox child_alloc = { 0, }; - gdouble x_align, y_align; - gboolean x_fill, y_fill, is_fixed_position_set; - float fixed_x, fixed_y; - - if (!clutter_actor_is_visible (child)) - continue; - - fixed_x = fixed_y = 0.f; - g_object_get (child, - "fixed-position-set", &is_fixed_position_set, - "fixed-x", &fixed_x, - "fixed-y", &fixed_y, - NULL); - - if (is_fixed_position_set) - { - if (is_fixed_position_set) - child_alloc.x1 = fixed_x; - else - child_alloc.x1 = clutter_actor_get_x (child); - } - else - child_alloc.x1 = allocation_x; - - if (is_fixed_position_set) - { - if (is_fixed_position_set) - child_alloc.y1 = fixed_y; - else - child_alloc.y1 = clutter_actor_get_y (child); - } - else - child_alloc.y1 = allocation_y; - - child_alloc.x2 = allocation_x + available_w; - child_alloc.y2 = allocation_y + available_h; - - if (clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_HORIZONTAL)) - { - ClutterActorAlign align; - - align = clutter_actor_get_x_align (child); - x_fill = align == CLUTTER_ACTOR_ALIGN_FILL; - x_align = get_actor_align_factor (align); - } - else - { - x_fill = FALSE; - - if (!is_fixed_position_set) - x_align = 0.5; - else - x_align = 0.0; - } - - if (clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_VERTICAL)) - { - ClutterActorAlign align; - - align = clutter_actor_get_y_align (child); - y_fill = align == CLUTTER_ACTOR_ALIGN_FILL; - y_align = get_actor_align_factor (align); - } - else - { - y_fill = FALSE; - - if (!is_fixed_position_set) - y_align = 0.5; - else - y_align = 0.0; - } - - clutter_actor_allocate_align_fill (child, &child_alloc, - x_align, y_align, - x_fill, y_fill); - } -} - -static void -clutter_bin_layout_class_init (ClutterBinLayoutClass *klass) -{ - ClutterLayoutManagerClass *layout_class = - CLUTTER_LAYOUT_MANAGER_CLASS (klass); - - layout_class->get_preferred_width = clutter_bin_layout_get_preferred_width; - layout_class->get_preferred_height = clutter_bin_layout_get_preferred_height; - layout_class->allocate = clutter_bin_layout_allocate; -} - -static void -clutter_bin_layout_init (ClutterBinLayout *self) -{ -} - -/** - * clutter_bin_layout_new: - * - * Creates a new #ClutterBinLayout layout manager - * - * Return value: the newly created layout manager - */ -ClutterLayoutManager * -clutter_bin_layout_new (void) -{ - return g_object_new (CLUTTER_TYPE_BIN_LAYOUT, - NULL); -} diff --git a/mutter/clutter/clutter/clutter-bin-layout.h b/mutter/clutter/clutter/clutter-bin-layout.h deleted file mode 100644 index 8ebf511..0000000 --- a/mutter/clutter/clutter/clutter-bin-layout.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-layout-manager.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_BIN_LAYOUT (clutter_bin_layout_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterBinLayout, - clutter_bin_layout, - CLUTTER, - BIN_LAYOUT, - ClutterLayoutManager) - -/** - * ClutterBinLayoutClass: - * - * The #ClutterBinLayoutClass structure contains only private - * data and should be accessed using the provided API - */ -struct _ClutterBinLayoutClass -{ - /*< private >*/ - ClutterLayoutManagerClass parent_class; -}; - -CLUTTER_EXPORT -ClutterLayoutManager * clutter_bin_layout_new (void); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-bind-constraint.c b/mutter/clutter/clutter/clutter-bind-constraint.c deleted file mode 100644 index 6e8e105..0000000 --- a/mutter/clutter/clutter/clutter-bind-constraint.c +++ /dev/null @@ -1,617 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterBindConstraint: - * - * A constraint binding the position or size of an actor - * - * #ClutterBindConstraint is a [class@Constraint] that binds the - * position or the size of the [class@Actor] to which it is applied - * to the the position or the size of another [class@Actor], or - * "source". - * - * An offset can be applied to the constraint, to avoid overlapping. The offset - * can also be animated. For instance, the following code will set up three - * actors to be bound to the same origin: - * - * ```c - * // source - * rect[0] = clutter_actor_new (); - * clutter_actor_set_background_color (rect[0], &red_color); - * clutter_actor_set_position (rect[0], x_pos, y_pos); - * clutter_actor_set_size (rect[0], 100, 100); - * - * // second rectangle - * rect[1] = clutter_actor_new (); - * clutter_actor_set_background_color (rect[1], &green_color); - * clutter_actor_set_size (rect[1], 100, 100); - * clutter_actor_set_opacity (rect[1], 0); - * - * constraint = clutter_bind_constraint_new (rect[0], CLUTTER_BIND_X, 0.0); - * clutter_actor_add_constraint_with_name (rect[1], "green-x", constraint); - * constraint = clutter_bind_constraint_new (rect[0], CLUTTER_BIND_Y, 0.0); - * clutter_actor_add_constraint_with_name (rect[1], "green-y", constraint); - * - * // third rectangle - * rect[2] = clutter_actor_new (); - * clutter_actor_set_background_color (rect[2], &blue_color); - * clutter_actor_set_size (rect[2], 100, 100); - * clutter_actor_set_opacity (rect[2], 0); - * - * constraint = clutter_bind_constraint_new (rect[0], CLUTTER_BIND_X, 0.0); - * clutter_actor_add_constraint_with_name (rect[2], "blue-x", constraint); - * constraint = clutter_bind_constraint_new (rect[0], CLUTTER_BIND_Y, 0.0); - * clutter_actor_add_constraint_with_name (rect[2], "blue-y", constraint); - * ``` - * - * The following code animates the second and third rectangles to "expand" - * them horizontally from underneath the first rectangle: - * - * ```c - * clutter_actor_animate (rect[1], CLUTTER_EASE_OUT_CUBIC, 250, - * "@constraints.green-x.offset", 100.0, - * "opacity", 255, - * NULL); - * clutter_actor_animate (rect[2], CLUTTER_EASE_OUT_CUBIC, 250, - * "@constraints.blue-x.offset", 200.0, - * "opacity", 255, - * NULL); - * ``` - */ - -#include "config.h" - -#include - -#include "clutter/clutter-bind-constraint.h" - -#include "clutter/clutter-actor-meta-private.h" -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-constraint.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-private.h" - -struct _ClutterBindConstraint -{ - ClutterConstraint parent_instance; - - ClutterActor *actor; - ClutterActor *source; - ClutterBindCoordinate coordinate; - gfloat offset; -}; - -enum -{ - PROP_0, - - PROP_SOURCE, - PROP_COORDINATE, - PROP_OFFSET, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -G_DEFINE_FINAL_TYPE (ClutterBindConstraint, - clutter_bind_constraint, - CLUTTER_TYPE_CONSTRAINT); - -static void -source_queue_relayout (ClutterActor *source, - ClutterBindConstraint *bind) -{ - if (bind->actor != NULL) - _clutter_actor_queue_only_relayout (bind->actor); -} - -static void -source_destroyed (ClutterActor *actor, - ClutterBindConstraint *bind) -{ - bind->source = NULL; -} - -static void -clutter_bind_constraint_update_preferred_size (ClutterConstraint *constraint, - ClutterActor *actor, - ClutterOrientation direction, - float for_size, - float *minimum_size, - float *natural_size) -{ - ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint); - float source_min, source_nat; - - if (bind->source == NULL) - return; - - /* only these bindings affect the preferred size */ - if (!(bind->coordinate == CLUTTER_BIND_WIDTH || - bind->coordinate == CLUTTER_BIND_HEIGHT || - bind->coordinate == CLUTTER_BIND_SIZE || - bind->coordinate == CLUTTER_BIND_ALL)) - return; - - if (clutter_actor_contains (bind->source, actor)) - return; - - switch (direction) - { - case CLUTTER_ORIENTATION_HORIZONTAL: - if (bind->coordinate != CLUTTER_BIND_HEIGHT) - { - clutter_actor_get_preferred_width (bind->source, for_size, - &source_min, - &source_nat); - - *minimum_size = source_min; - *natural_size = source_nat; - } - break; - - case CLUTTER_ORIENTATION_VERTICAL: - if (bind->coordinate != CLUTTER_BIND_WIDTH) - { - clutter_actor_get_preferred_height (bind->source, for_size, - &source_min, - &source_nat); - - *minimum_size = source_min; - *natural_size = source_nat; - } - break; - } -} - -static void -clutter_bind_constraint_update_allocation (ClutterConstraint *constraint, - ClutterActor *actor, - ClutterActorBox *allocation) -{ - ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint); - gfloat source_width, source_height; - gfloat actor_width, actor_height; - graphene_point3d_t source_position; - - source_position = GRAPHENE_POINT3D_INIT (0.f, 0.f, 0.f); - - if (bind->source == NULL) - return; - - source_position.x = clutter_actor_get_x (bind->source); - source_position.y = clutter_actor_get_y (bind->source); - clutter_actor_get_size (bind->source, &source_width, &source_height); - - clutter_actor_box_get_size (allocation, &actor_width, &actor_height); - - switch (bind->coordinate) - { - case CLUTTER_BIND_X: - allocation->x1 = source_position.x + bind->offset; - allocation->x2 = allocation->x1 + actor_width; - break; - - case CLUTTER_BIND_Y: - allocation->y1 = source_position.y + bind->offset; - allocation->y2 = allocation->y1 + actor_height; - break; - - case CLUTTER_BIND_POSITION: - allocation->x1 = source_position.x + bind->offset; - allocation->y1 = source_position.y + bind->offset; - allocation->x2 = allocation->x1 + actor_width; - allocation->y2 = allocation->y1 + actor_height; - break; - - case CLUTTER_BIND_WIDTH: - allocation->x2 = allocation->x1 + source_width + bind->offset; - break; - - case CLUTTER_BIND_HEIGHT: - allocation->y2 = allocation->y1 + source_height + bind->offset; - break; - - case CLUTTER_BIND_SIZE: - allocation->x2 = allocation->x1 + source_width + bind->offset; - allocation->y2 = allocation->y1 + source_height + bind->offset; - break; - - case CLUTTER_BIND_ALL: - allocation->x1 = source_position.x + bind->offset; - allocation->y1 = source_position.y + bind->offset; - allocation->x2 = allocation->x1 + source_width + bind->offset; - allocation->y2 = allocation->y1 + source_height + bind->offset; - break; - - default: - g_assert_not_reached (); - break; - } - - clutter_actor_box_clamp_to_pixel (allocation); -} - -static void -clutter_bind_constraint_set_actor (ClutterActorMeta *meta, - ClutterActor *new_actor) -{ - ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (meta); - ClutterActorMetaClass *parent; - - if (new_actor != NULL && - bind->source != NULL && - clutter_actor_contains (new_actor, bind->source)) - { - g_warning (G_STRLOC ": The source actor '%s' is contained " - "by the actor '%s' associated to the constraint " - "'%s'", - _clutter_actor_get_debug_name (bind->source), - _clutter_actor_get_debug_name (new_actor), - _clutter_actor_meta_get_debug_name (meta)); - return; - } - - /* store the pointer to the actor, for later use */ - bind->actor = new_actor; - - parent = CLUTTER_ACTOR_META_CLASS (clutter_bind_constraint_parent_class); - parent->set_actor (meta, new_actor); -} - -static void -clutter_bind_constraint_dispose (GObject *gobject) -{ - ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (gobject); - - if (bind->source != NULL) - { - g_signal_handlers_disconnect_by_func (bind->source, - G_CALLBACK (source_destroyed), - bind); - g_signal_handlers_disconnect_by_func (bind->source, - G_CALLBACK (source_queue_relayout), - bind); - bind->source = NULL; - } - - G_OBJECT_CLASS (clutter_bind_constraint_parent_class)->dispose (gobject); -} - -static void -clutter_bind_constraint_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (gobject); - - switch (prop_id) - { - case PROP_SOURCE: - clutter_bind_constraint_set_source (bind, g_value_get_object (value)); - break; - - case PROP_COORDINATE: - clutter_bind_constraint_set_coordinate (bind, g_value_get_enum (value)); - break; - - case PROP_OFFSET: - clutter_bind_constraint_set_offset (bind, g_value_get_float (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_bind_constraint_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (gobject); - - switch (prop_id) - { - case PROP_SOURCE: - g_value_set_object (value, bind->source); - break; - - case PROP_COORDINATE: - g_value_set_enum (value, bind->coordinate); - break; - - case PROP_OFFSET: - g_value_set_float (value, bind->offset); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_bind_constraint_class_init (ClutterBindConstraintClass *klass) -{ - ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); - ClutterConstraintClass *constraint_class = CLUTTER_CONSTRAINT_CLASS (klass); - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->set_property = clutter_bind_constraint_set_property; - gobject_class->get_property = clutter_bind_constraint_get_property; - gobject_class->dispose = clutter_bind_constraint_dispose; - - meta_class->set_actor = clutter_bind_constraint_set_actor; - - constraint_class->update_allocation = clutter_bind_constraint_update_allocation; - constraint_class->update_preferred_size = clutter_bind_constraint_update_preferred_size; - - /** - * ClutterBindConstraint:source: - * - * The #ClutterActor used as the source for the binding. - * - * The #ClutterActor must not be contained inside the actor associated - * to the constraint. - */ - obj_props[PROP_SOURCE] = - g_param_spec_object ("source", NULL, NULL, - CLUTTER_TYPE_ACTOR, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT); - - /** - * ClutterBindConstraint:coordinate: - * - * The coordinate to be bound - */ - obj_props[PROP_COORDINATE] = - g_param_spec_enum ("coordinate", NULL, NULL, - CLUTTER_TYPE_BIND_COORDINATE, - CLUTTER_BIND_X, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT); - - /** - * ClutterBindConstraint:offset: - * - * The offset, in pixels, to be applied to the binding - */ - obj_props[PROP_OFFSET] = - g_param_spec_float ("offset", NULL, NULL, - -G_MAXFLOAT, G_MAXFLOAT, - 0.0f, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT); - - g_object_class_install_properties (gobject_class, - PROP_LAST, - obj_props); -} - -static void -clutter_bind_constraint_init (ClutterBindConstraint *self) -{ - self->actor = NULL; - self->source = NULL; - self->coordinate = CLUTTER_BIND_X; - self->offset = 0.0f; -} - -/** - * clutter_bind_constraint_new: - * @source: (allow-none): the #ClutterActor to use as the source of - * the binding, or %NULL - * @coordinate: the coordinate to bind - * @offset: the offset to apply to the binding, in pixels - * - * Creates a new constraint, binding a #ClutterActor's position to - * the given @coordinate of the position of @source - * - * Return value: the newly created #ClutterBindConstraint - */ -ClutterConstraint * -clutter_bind_constraint_new (ClutterActor *source, - ClutterBindCoordinate coordinate, - gfloat offset) -{ - g_return_val_if_fail (source == NULL || CLUTTER_IS_ACTOR (source), NULL); - - return g_object_new (CLUTTER_TYPE_BIND_CONSTRAINT, - "source", source, - "coordinate", coordinate, - "offset", offset, - NULL); -} - -/** - * clutter_bind_constraint_set_source: - * @constraint: a #ClutterBindConstraint - * @source: (allow-none): a #ClutterActor, or %NULL to unset the source - * - * Sets the source #ClutterActor for the constraint - */ -void -clutter_bind_constraint_set_source (ClutterBindConstraint *constraint, - ClutterActor *source) -{ - ClutterActor *old_source, *actor; - ClutterActorMeta *meta; - - g_return_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint)); - g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source)); - - if (constraint->source == source) - return; - - meta = CLUTTER_ACTOR_META (constraint); - actor = clutter_actor_meta_get_actor (meta); - if (source != NULL && actor != NULL) - { - if (clutter_actor_contains (actor, source)) - { - g_warning (G_STRLOC ": The source actor '%s' is contained " - "by the actor '%s' associated to the constraint " - "'%s'", - _clutter_actor_get_debug_name (source), - _clutter_actor_get_debug_name (actor), - _clutter_actor_meta_get_debug_name (meta)); - return; - } - } - - old_source = constraint->source; - if (old_source != NULL) - { - g_signal_handlers_disconnect_by_func (old_source, - G_CALLBACK (source_destroyed), - constraint); - g_signal_handlers_disconnect_by_func (old_source, - G_CALLBACK (source_queue_relayout), - constraint); - } - - constraint->source = source; - if (constraint->source != NULL) - { - g_signal_connect (constraint->source, "queue-relayout", - G_CALLBACK (source_queue_relayout), - constraint); - g_signal_connect (constraint->source, "destroy", - G_CALLBACK (source_destroyed), - constraint); - - if (constraint->actor != NULL) - clutter_actor_queue_relayout (constraint->actor); - } - - g_object_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_SOURCE]); -} - -/** - * clutter_bind_constraint_get_source: - * @constraint: a #ClutterBindConstraint - * - * Retrieves the #ClutterActor set using [method@Clutter.BindConstraint.set_source] - * - * Return value: (transfer none): a pointer to the source actor - */ -ClutterActor * -clutter_bind_constraint_get_source (ClutterBindConstraint *constraint) -{ - g_return_val_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint), NULL); - - return constraint->source; -} - -/** - * clutter_bind_constraint_set_coordinate: - * @constraint: a #ClutterBindConstraint - * @coordinate: the coordinate to bind - * - * Sets the coordinate to bind in the constraint - */ -void -clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint, - ClutterBindCoordinate coordinate) -{ - g_return_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint)); - - if (constraint->coordinate == coordinate) - return; - - constraint->coordinate = coordinate; - - if (constraint->actor != NULL) - clutter_actor_queue_relayout (constraint->actor); - - g_object_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_COORDINATE]); -} - -/** - * clutter_bind_constraint_get_coordinate: - * @constraint: a #ClutterBindConstraint - * - * Retrieves the bound coordinate of the constraint - * - * Return value: the bound coordinate - */ -ClutterBindCoordinate -clutter_bind_constraint_get_coordinate (ClutterBindConstraint *constraint) -{ - g_return_val_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint), - CLUTTER_BIND_X); - - return constraint->coordinate; -} - -/** - * clutter_bind_constraint_set_offset: - * @constraint: a #ClutterBindConstraint - * @offset: the offset to apply, in pixels - * - * Sets the offset to be applied to the constraint - */ -void -clutter_bind_constraint_set_offset (ClutterBindConstraint *constraint, - gfloat offset) -{ - g_return_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint)); - - if (fabs (constraint->offset - offset) < 0.00001f) - return; - - constraint->offset = offset; - - if (constraint->actor != NULL) - clutter_actor_queue_relayout (constraint->actor); - - g_object_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_OFFSET]); -} - -/** - * clutter_bind_constraint_get_offset: - * @constraint: a #ClutterBindConstraint - * - * Retrieves the offset set using [method@Clutter.BindConstraint.set_offset] - * - * Return value: the offset, in pixels - */ -gfloat -clutter_bind_constraint_get_offset (ClutterBindConstraint *bind) -{ - g_return_val_if_fail (CLUTTER_IS_BIND_CONSTRAINT (bind), 0.0); - - return bind->offset; -} diff --git a/mutter/clutter/clutter/clutter-bind-constraint.h b/mutter/clutter/clutter/clutter-bind-constraint.h deleted file mode 100644 index 5cf25f3..0000000 --- a/mutter/clutter/clutter/clutter-bind-constraint.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-constraint.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_BIND_CONSTRAINT (clutter_bind_constraint_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_FINAL_TYPE (ClutterBindConstraint, clutter_bind_constraint, - CLUTTER, BIND_CONSTRAINT, ClutterConstraint) - -CLUTTER_EXPORT -ClutterConstraint * clutter_bind_constraint_new (ClutterActor *source, - ClutterBindCoordinate coordinate, - gfloat offset); - -CLUTTER_EXPORT -void clutter_bind_constraint_set_source (ClutterBindConstraint *constraint, - ClutterActor *source); -CLUTTER_EXPORT -ClutterActor * clutter_bind_constraint_get_source (ClutterBindConstraint *constraint); -CLUTTER_EXPORT -void clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint, - ClutterBindCoordinate coordinate); -CLUTTER_EXPORT -ClutterBindCoordinate clutter_bind_constraint_get_coordinate (ClutterBindConstraint *constraint); -CLUTTER_EXPORT -void clutter_bind_constraint_set_offset (ClutterBindConstraint *constraint, - gfloat offset); -CLUTTER_EXPORT -gfloat clutter_bind_constraint_get_offset (ClutterBindConstraint *constraint); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-binding-pool.c b/mutter/clutter/clutter/clutter-binding-pool.c deleted file mode 100644 index 97f3db5..0000000 --- a/mutter/clutter/clutter/clutter-binding-pool.c +++ /dev/null @@ -1,898 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2008 Intel Corporation. - * - * Authored By: Emmanuele Bassi - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/** - * ClutterBindingPool - * - * Pool for key bindings - * - * #ClutterBindingPool is a data structure holding a set of key bindings. - * Each key binding associates a key symbol (eventually with modifiers) - * to an action. A callback function is associated to each action. - * - * For a given key symbol and modifier mask combination there can be only one - * action; for each action there can be only one callback. There can be - * multiple actions with the same name, and the same callback can be used - * to handle multiple key bindings. - * - * Actors requiring key bindings should create a new #ClutterBindingPool - * inside their class initialization function and then install actions - * like this: - * - * ```c - * static void - * foo_class_init (FooClass *klass) - * { - * ClutterBindingPool *binding_pool; - * - * binding_pool = clutter_binding_pool_get_for_class (klass); - * - * clutter_binding_pool_install_action (binding_pool, "move-up", - * CLUTTER_Up, 0, - * G_CALLBACK (foo_action_move_up), - * NULL, NULL); - * clutter_binding_pool_install_action (binding_pool, "move-up", - * CLUTTER_KP_Up, 0, - * G_CALLBACK (foo_action_move_up), - * NULL, NULL); - * } - * ``` - * - * The callback has a signature of: - * - * ```c - * gboolean (* callback) (GObject *instance, - * const gchar *action_name, - * guint key_val, - * ClutterModifierType modifiers, - * gpointer user_data); - * ``` - * - * The actor should then override the [signal@Actor::key-press-event] and - * use [method@BindingPool.activate] to match a [struct@Event] key event - * structure to one of the actions: - * - * ```c - * ClutterBindingPool *pool; - * - * // retrieve the binding pool for the type of the actor - * pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (actor)); - * - * // activate any callback matching the key symbol and modifiers - * // mask of the key event. the returned value can be directly - * // used to signal that the actor has handled the event. - * return clutter_binding_pool_activate (pool, - * key_event->keyval, - * key_event->modifier_state, - * G_OBJECT (actor)); - * ``` - * - * The [method@BindingPool.activate] function will return %FALSE if - * no action for the given key binding was found, if the action was - * blocked (using [method@BindingPool.block_action]) or if the - * key binding handler returned %FALSE. - */ - -#include "config.h" - -#include "clutter/clutter-binding-pool.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-private.h" - -#define BINDING_MOD_MASK ((CLUTTER_SHIFT_MASK | \ - CLUTTER_CONTROL_MASK | \ - CLUTTER_MOD1_MASK | \ - CLUTTER_SUPER_MASK | \ - CLUTTER_HYPER_MASK | \ - CLUTTER_META_MASK) | CLUTTER_RELEASE_MASK) - -typedef struct _ClutterBindingEntry ClutterBindingEntry; - -static GSList *clutter_binding_pools = NULL; -static GQuark key_class_bindings = 0; - -struct _ClutterBindingPool -{ - GObject parent_instance; - - gchar *name; /* interned string, do not free */ - - GSList *entries; - GHashTable *entries_hash; -}; - -struct _ClutterBindingEntry -{ - gchar *name; /* interned string, do not free */ - - guint key_val; - ClutterModifierType modifiers; - - GClosure *closure; - - guint is_blocked : 1; -}; - -enum -{ - PROP_0, - - PROP_NAME, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -G_DEFINE_FINAL_TYPE (ClutterBindingPool, clutter_binding_pool, G_TYPE_OBJECT); - -static guint -binding_entry_hash (gconstpointer v) -{ - const ClutterBindingEntry *e = v; - guint h; - - h = e->key_val; - h ^= e->modifiers; - - return h; -} - -static gint -binding_entry_compare (gconstpointer v1, - gconstpointer v2) -{ - const ClutterBindingEntry *e1 = v1; - const ClutterBindingEntry *e2 = v2; - - return (e1->key_val == e2->key_val && e1->modifiers == e2->modifiers); -} - -static ClutterBindingEntry * -binding_entry_new (const gchar *name, - guint key_val, - ClutterModifierType modifiers) -{ - ClutterBindingEntry *entry; - - modifiers = modifiers & BINDING_MOD_MASK; - - entry = g_new0 (ClutterBindingEntry, 1); - entry->key_val = key_val; - entry->modifiers = modifiers; - entry->name = (gchar *) g_intern_string (name); - entry->closure = NULL; - entry->is_blocked = FALSE; - - return entry; -} - -static ClutterBindingEntry * -binding_pool_lookup_entry (ClutterBindingPool *pool, - guint key_val, - ClutterModifierType modifiers) -{ - ClutterBindingEntry lookup_entry = { 0, }; - - lookup_entry.key_val = key_val; - lookup_entry.modifiers = modifiers; - - return g_hash_table_lookup (pool->entries_hash, &lookup_entry); -} - -static void -binding_entry_free (gpointer data) -{ - if (G_LIKELY (data)) - { - ClutterBindingEntry *entry = data; - - g_closure_unref (entry->closure); - - g_free (entry); - } -} - -static void -clutter_binding_pool_finalize (GObject *gobject) -{ - ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject); - - /* remove from the pools */ - clutter_binding_pools = g_slist_remove (clutter_binding_pools, pool); - - g_hash_table_destroy (pool->entries_hash); - - g_slist_free_full (pool->entries, (GDestroyNotify) binding_entry_free); - - G_OBJECT_CLASS (clutter_binding_pool_parent_class)->finalize (gobject); -} - -static void -clutter_binding_pool_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject); - - switch (prop_id) - { - case PROP_NAME: - pool->name = (gchar *) g_intern_string (g_value_get_string (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_binding_pool_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject); - - switch (prop_id) - { - case PROP_NAME: - g_value_set_string (value, pool->name); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_binding_pool_constructed (GObject *gobject) -{ - ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject); - - /* bad monkey! bad, bad monkey! */ - if (G_UNLIKELY (pool->name == NULL)) - g_critical ("No name set for ClutterBindingPool %p", pool); - - if (G_OBJECT_CLASS (clutter_binding_pool_parent_class)->constructed) - G_OBJECT_CLASS (clutter_binding_pool_parent_class)->constructed (gobject); -} - -static void -clutter_binding_pool_class_init (ClutterBindingPoolClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->constructed = clutter_binding_pool_constructed; - gobject_class->set_property = clutter_binding_pool_set_property; - gobject_class->get_property = clutter_binding_pool_get_property; - gobject_class->finalize = clutter_binding_pool_finalize; - - /** - * ClutterBindingPool:name: - * - * The unique name of the #ClutterBindingPool. - */ - obj_props[PROP_NAME] = - g_param_spec_string ("name", NULL, NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - g_object_class_install_properties (gobject_class, - PROP_LAST, - obj_props); -} - -static void -clutter_binding_pool_init (ClutterBindingPool *pool) -{ - pool->name = NULL; - pool->entries = NULL; - pool->entries_hash = g_hash_table_new (binding_entry_hash, - binding_entry_compare); - - clutter_binding_pools = g_slist_prepend (clutter_binding_pools, pool); -} - -/** - * clutter_binding_pool_new: - * @name: the name of the binding pool - * - * Creates a new #ClutterBindingPool that can be used to store - * key bindings for an actor. The @name must be a unique identifier - * for the binding pool, so that [func@Clutter.BindingPool.find] will - * be able to return the correct binding pool. - * - * Return value: the newly created binding pool with the given - * name. Use g_object_unref() when done. - */ -ClutterBindingPool * -clutter_binding_pool_new (const gchar *name) -{ - ClutterBindingPool *pool; - - g_return_val_if_fail (name != NULL, NULL); - - pool = clutter_binding_pool_find (name); - if (G_UNLIKELY (pool)) - { - g_warning ("A binding pool named '%s' is already present " - "in the binding pools list", - pool->name); - return NULL; - } - - return g_object_new (CLUTTER_TYPE_BINDING_POOL, "name", name, NULL); -} - -/** - * clutter_binding_pool_get_for_class: - * @klass: a #GObjectClass pointer - * - * Retrieves the #ClutterBindingPool for the given #GObject class - * and, eventually, creates it. This function is a wrapper around - * [ctor@Clutter.BindingPool.new] and uses the class type name as the - * unique name for the binding pool. - * - * Calling this function multiple times will return the same - * #ClutterBindingPool. - * - * A binding pool for a class can also be retrieved using - * [func@Clutter.BindingPool.find] with the class type name: - * - * ``` - * pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (instance)); - * ``` - * - * Return value: (transfer none): the binding pool for the given class. - * The returned #ClutterBindingPool is owned by Clutter and should not - * be freed directly - */ -ClutterBindingPool * -clutter_binding_pool_get_for_class (gpointer klass) -{ - ClutterBindingPool *pool; - - g_return_val_if_fail (G_IS_OBJECT_CLASS (klass), NULL); - - if (G_UNLIKELY (key_class_bindings == 0)) - key_class_bindings = g_quark_from_static_string ("clutter-bindings-set"); - - pool = g_dataset_id_get_data (klass, key_class_bindings); - if (pool) - return pool; - - pool = clutter_binding_pool_new (G_OBJECT_CLASS_NAME (klass)); - g_dataset_id_set_data_full (klass, key_class_bindings, - pool, - g_object_unref); - - return pool; -} - -/** - * clutter_binding_pool_find: - * @name: the name of the binding pool to find - * - * Finds the #ClutterBindingPool with @name. - * - * Return value: (transfer none): a pointer to the #ClutterBindingPool, or %NULL - */ -ClutterBindingPool * -clutter_binding_pool_find (const gchar *name) -{ - GSList *l; - - g_return_val_if_fail (name != NULL, NULL); - - for (l = clutter_binding_pools; l != NULL; l = l->next) - { - ClutterBindingPool *pool = l->data; - - if (g_str_equal (pool->name, (gpointer) name)) - return pool; - } - - return NULL; -} - -/** - * clutter_binding_pool_install_action: - * @pool: a #ClutterBindingPool - * @action_name: the name of the action - * @key_val: key symbol - * @modifiers: bitmask of modifiers - * @callback: function to be called - * when the action is activated - * @data: data to be passed to @callback - * @notify: function to be called when the action is removed - * from the pool - * - * Installs a new action inside a #ClutterBindingPool. The action - * is bound to @key_val and @modifiers. - * - * The same action name can be used for multiple @key_val, @modifiers - * pairs. - * - * When an action has been activated using [method@Clutter.BindingPool.activate] - * the passed @callback will be invoked (with @data). - * - * Actions can be blocked with [method@Clutter.BindingPool.block_action] - * and then unblocked using [method@Clutter.BindingPool.unblock_action]. - */ -void -clutter_binding_pool_install_action (ClutterBindingPool *pool, - const gchar *action_name, - guint key_val, - ClutterModifierType modifiers, - GCallback callback, - gpointer data, - GDestroyNotify notify) -{ - ClutterBindingEntry *entry; - GClosure *closure; - - g_return_if_fail (pool != NULL); - g_return_if_fail (action_name != NULL); - g_return_if_fail (key_val != 0); - g_return_if_fail (callback != NULL); - - entry = binding_pool_lookup_entry (pool, key_val, modifiers); - if (G_UNLIKELY (entry)) - { - g_warning ("There already is an action '%s' for the given " - "key symbol of %d (modifiers: %d) installed inside " - "the binding pool.", - entry->name, - entry->key_val, entry->modifiers); - return; - } - else - entry = binding_entry_new (action_name, key_val, modifiers); - - closure = g_cclosure_new (callback, data, (GClosureNotify) notify); - entry->closure = g_closure_ref (closure); - g_closure_sink (closure); - - if (G_CLOSURE_NEEDS_MARSHAL (closure)) - { - GClosureMarshal marshal; - - marshal = _clutter_marshal_BOOLEAN__STRING_UINT_FLAGS; - g_closure_set_marshal (closure, marshal); - } - - pool->entries = g_slist_prepend (pool->entries, entry); - g_hash_table_insert (pool->entries_hash, entry, entry); -} - -/** - * clutter_binding_pool_install_closure: - * @pool: a #ClutterBindingPool - * @action_name: the name of the action - * @key_val: key symbol - * @modifiers: bitmask of modifiers - * @closure: a #GClosure - * - * A #GClosure variant of [method@Clutter.BindingPool.install_action]. - * - * Installs a new action inside a #ClutterBindingPool. The action - * is bound to @key_val and @modifiers. - * - * The same action name can be used for multiple @key_val, @modifiers - * pairs. - * - * When an action has been activated using [method@Clutter.BindingPool.activate] - * the passed @closure will be invoked. - * - * Actions can be blocked with [method@Clutter.BindingPool.block_action] - * and then unblocked using [method@Clutter.BindingPool.unblock_action]. - */ -void -clutter_binding_pool_install_closure (ClutterBindingPool *pool, - const gchar *action_name, - guint key_val, - ClutterModifierType modifiers, - GClosure *closure) -{ - ClutterBindingEntry *entry; - - g_return_if_fail (pool != NULL); - g_return_if_fail (action_name != NULL); - g_return_if_fail (key_val != 0); - g_return_if_fail (closure != NULL); - - entry = binding_pool_lookup_entry (pool, key_val, modifiers); - if (G_UNLIKELY (entry)) - { - g_warning ("There already is an action '%s' for the given " - "key symbol of %d (modifiers: %d) installed inside " - "the binding pool.", - entry->name, - entry->key_val, entry->modifiers); - return; - } - else - entry = binding_entry_new (action_name, key_val, modifiers); - - entry->closure = g_closure_ref (closure); - g_closure_sink (closure); - - if (G_CLOSURE_NEEDS_MARSHAL (closure)) - { - GClosureMarshal marshal; - - marshal = _clutter_marshal_BOOLEAN__STRING_UINT_FLAGS; - g_closure_set_marshal (closure, marshal); - } - - pool->entries = g_slist_prepend (pool->entries, entry); - g_hash_table_insert (pool->entries_hash, entry, entry); -} - -/** - * clutter_binding_pool_override_action: - * @pool: a #ClutterBindingPool - * @key_val: key symbol - * @modifiers: bitmask of modifiers - * @callback: function to be called when the action is activated - * @data: data to be passed to @callback - * @notify: function to be called when the action is removed - * from the pool - * - * Allows overriding the action for @key_val and @modifiers inside a - * #ClutterBindingPool. See [method@Clutter.BindingPool.install_action]. - * - * When an action has been activated using [method@Clutter.BindingPool.activate] - * the passed @callback will be invoked (with @data). - * - * Actions can be blocked with [method@Clutter.BindingPool.block_action] - * and then unblocked using [method@Clutter.BindingPool.unblock_action]. - */ -void -clutter_binding_pool_override_action (ClutterBindingPool *pool, - guint key_val, - ClutterModifierType modifiers, - GCallback callback, - gpointer data, - GDestroyNotify notify) -{ - ClutterBindingEntry *entry; - GClosure *closure; - - g_return_if_fail (pool != NULL); - g_return_if_fail (key_val != 0); - g_return_if_fail (callback != NULL); - - entry = binding_pool_lookup_entry (pool, key_val, modifiers); - if (G_UNLIKELY (entry == NULL)) - { - g_warning ("There is no action for the given key symbol " - "of %d (modifiers: %d) installed inside the " - "binding pool.", - key_val, modifiers); - return; - } - - if (entry->closure) - { - g_closure_unref (entry->closure); - entry->closure = NULL; - } - - closure = g_cclosure_new (callback, data, (GClosureNotify) notify); - entry->closure = g_closure_ref (closure); - g_closure_sink (closure); - - if (G_CLOSURE_NEEDS_MARSHAL (closure)) - { - GClosureMarshal marshal; - - marshal = _clutter_marshal_BOOLEAN__STRING_UINT_FLAGS; - g_closure_set_marshal (closure, marshal); - } -} - -/** - * clutter_binding_pool_override_closure: - * @pool: a #ClutterBindingPool - * @key_val: key symbol - * @modifiers: bitmask of modifiers - * @closure: a #GClosure - * - * A #GClosure variant of [method@Clutter.BindingPool.override_action]. - * - * Allows overriding the action for @key_val and @modifiers inside a - * #ClutterBindingPool. See [method@Clutter.BindingPool.install_closure]. - * - * When an action has been activated using [method@Clutter.BindingPool.activate] - * the passed @callback will be invoked (with @data). - * - * Actions can be blocked with [method@Clutter.BindingPool.block_action] - * and then unblocked using [method@Clutter.BindingPool.unblock_action]. - */ -void -clutter_binding_pool_override_closure (ClutterBindingPool *pool, - guint key_val, - ClutterModifierType modifiers, - GClosure *closure) -{ - ClutterBindingEntry *entry; - - g_return_if_fail (pool != NULL); - g_return_if_fail (key_val != 0); - g_return_if_fail (closure != NULL); - - entry = binding_pool_lookup_entry (pool, key_val, modifiers); - if (G_UNLIKELY (entry == NULL)) - { - g_warning ("There is no action for the given key symbol " - "of %d (modifiers: %d) installed inside the " - "binding pool.", - key_val, modifiers); - return; - } - - if (entry->closure) - { - g_closure_unref (entry->closure); - entry->closure = NULL; - } - - entry->closure = g_closure_ref (closure); - g_closure_sink (closure); - - if (G_CLOSURE_NEEDS_MARSHAL (closure)) - { - GClosureMarshal marshal; - - marshal = _clutter_marshal_BOOLEAN__STRING_UINT_FLAGS; - g_closure_set_marshal (closure, marshal); - } -} - -/** - * clutter_binding_pool_find_action: - * @pool: a #ClutterBindingPool - * @key_val: a key symbol - * @modifiers: a bitmask for the modifiers - * - * Retrieves the name of the action matching the given key symbol - * and modifiers bitmask. - * - * Return value: the name of the action, if found, or %NULL. The - * returned string is owned by the binding pool and should never - * be modified or freed - */ -const gchar * -clutter_binding_pool_find_action (ClutterBindingPool *pool, - guint key_val, - ClutterModifierType modifiers) -{ - ClutterBindingEntry *entry; - - g_return_val_if_fail (pool != NULL, NULL); - g_return_val_if_fail (key_val != 0, NULL); - - entry = binding_pool_lookup_entry (pool, key_val, modifiers); - if (!entry) - return NULL; - - return entry->name; -} - -/** - * clutter_binding_pool_remove_action: - * @pool: a #ClutterBindingPool - * @key_val: a key symbol - * @modifiers: a bitmask for the modifiers - * - * Removes the action matching the given @key_val, @modifiers pair, - * if any exists. - */ -void -clutter_binding_pool_remove_action (ClutterBindingPool *pool, - guint key_val, - ClutterModifierType modifiers) -{ - ClutterBindingEntry remove_entry = { 0, }; - GSList *l; - - g_return_if_fail (pool != NULL); - g_return_if_fail (key_val != 0); - - modifiers = modifiers & BINDING_MOD_MASK; - - remove_entry.key_val = key_val; - remove_entry.modifiers = modifiers; - - for (l = pool->entries; l != NULL; l = l->data) - { - ClutterBindingEntry *e = l->data; - - if (e->key_val == remove_entry.key_val && - e->modifiers == remove_entry.modifiers) - { - pool->entries = g_slist_remove_link (pool->entries, l); - break; - } - } - - g_hash_table_remove (pool->entries_hash, &remove_entry); -} - -static gboolean -clutter_binding_entry_invoke (ClutterBindingEntry *entry, - GObject *gobject) -{ - GValue params[4] = { - G_VALUE_INIT, - G_VALUE_INIT, - G_VALUE_INIT, - G_VALUE_INIT - }; - GValue result = G_VALUE_INIT; - gboolean retval = TRUE; - - g_value_init (¶ms[0], G_TYPE_OBJECT); - g_value_set_object (¶ms[0], gobject); - - g_value_init (¶ms[1], G_TYPE_STRING); - g_value_set_static_string (¶ms[1], entry->name); - - g_value_init (¶ms[2], G_TYPE_UINT); - g_value_set_uint (¶ms[2], entry->key_val); - - g_value_init (¶ms[3], CLUTTER_TYPE_MODIFIER_TYPE); - g_value_set_flags (¶ms[3], entry->modifiers); - - g_value_init (&result, G_TYPE_BOOLEAN); - - g_closure_invoke (entry->closure, &result, 4, params, NULL); - - retval = g_value_get_boolean (&result); - - g_value_unset (&result); - - g_value_unset (¶ms[0]); - g_value_unset (¶ms[1]); - g_value_unset (¶ms[2]); - g_value_unset (¶ms[3]); - - return retval; -} - -/** - * clutter_binding_pool_activate: - * @pool: a #ClutterBindingPool - * @key_val: the key symbol - * @modifiers: bitmask for the modifiers - * @gobject: a #GObject - * - * Activates the callback associated to the action that is - * bound to the @key_val and @modifiers pair. - * - * The callback has the following signature: - * - * ``` - * void (* callback) (GObject *gobject, - * const gchar *action_name, - * guint key_val, - * ClutterModifierType modifiers, - * gpointer user_data); - * ``` - * - * Where the #GObject instance is @gobject and the user data - * is the one passed when installing the action with - * [method@Clutter.BindingPool.install_action]. - * - * If the action bound to the @key_val, @modifiers pair has been - * blocked using [method@Clutter.BindingPool.block_action], the callback - * will not be invoked, and this function will return %FALSE. - * - * Return value: %TRUE if an action was found and was activated - */ -gboolean -clutter_binding_pool_activate (ClutterBindingPool *pool, - guint key_val, - ClutterModifierType modifiers, - GObject *gobject) -{ - ClutterBindingEntry *entry = NULL; - - g_return_val_if_fail (pool != NULL, FALSE); - g_return_val_if_fail (key_val != 0, FALSE); - g_return_val_if_fail (G_IS_OBJECT (gobject), FALSE); - - modifiers = (modifiers & BINDING_MOD_MASK); - - entry = binding_pool_lookup_entry (pool, key_val, modifiers); - if (!entry) - return FALSE; - - if (!entry->is_blocked) - return clutter_binding_entry_invoke (entry, gobject); - - return FALSE; -} - -/** - * clutter_binding_pool_block_action: - * @pool: a #ClutterBindingPool - * @action_name: an action name - * - * Blocks all the actions with name @action_name inside @pool. - */ -void -clutter_binding_pool_block_action (ClutterBindingPool *pool, - const gchar *action_name) -{ - GSList *l; - - g_return_if_fail (pool != NULL); - g_return_if_fail (action_name != NULL); - - for (l = pool->entries; l != NULL; l = l->next) - { - ClutterBindingEntry *entry = l->data; - - if (g_str_equal (entry->name, (gpointer) action_name)) - entry->is_blocked = TRUE; - } -} - -/** - * clutter_binding_pool_unblock_action: - * @pool: a #ClutterBindingPool - * @action_name: an action name - * - * Unblockes all the actions with name @action_name inside @pool. - * - * Unblocking an action does not cause the callback bound to it to - * be invoked in case [method@Clutter.BindingPool.activate] was called on - * an action previously blocked with [method@Clutter.BindingPool.block_action]. - */ -void -clutter_binding_pool_unblock_action (ClutterBindingPool *pool, - const gchar *action_name) -{ - GSList *l; - - g_return_if_fail (pool != NULL); - g_return_if_fail (action_name != NULL); - - for (l = pool->entries; l != NULL; l = l->next) - { - ClutterBindingEntry *entry = l->data; - - if (g_str_equal (entry->name, (gpointer) action_name)) - entry->is_blocked = FALSE; - } -} diff --git a/mutter/clutter/clutter/clutter-binding-pool.h b/mutter/clutter/clutter/clutter-binding-pool.h deleted file mode 100644 index 4b09bf6..0000000 --- a/mutter/clutter/clutter/clutter-binding-pool.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2008 Intel Corporation. - * - * Authored By: Emmanuele Bassi - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -#include "clutter/clutter-event.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_BINDING_POOL (clutter_binding_pool_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_FINAL_TYPE (ClutterBindingPool, - clutter_binding_pool, - CLUTTER, - BINDING_POOL, - GObject) - -CLUTTER_EXPORT -ClutterBindingPool * clutter_binding_pool_new (const gchar *name); -CLUTTER_EXPORT -ClutterBindingPool * clutter_binding_pool_get_for_class (gpointer klass); -CLUTTER_EXPORT -ClutterBindingPool * clutter_binding_pool_find (const gchar *name); - -CLUTTER_EXPORT -void clutter_binding_pool_install_action (ClutterBindingPool *pool, - const gchar *action_name, - guint key_val, - ClutterModifierType modifiers, - GCallback callback, - gpointer data, - GDestroyNotify notify); -CLUTTER_EXPORT -void clutter_binding_pool_install_closure (ClutterBindingPool *pool, - const gchar *action_name, - guint key_val, - ClutterModifierType modifiers, - GClosure *closure); -CLUTTER_EXPORT -void clutter_binding_pool_override_action (ClutterBindingPool *pool, - guint key_val, - ClutterModifierType modifiers, - GCallback callback, - gpointer data, - GDestroyNotify notify); -CLUTTER_EXPORT -void clutter_binding_pool_override_closure (ClutterBindingPool *pool, - guint key_val, - ClutterModifierType modifiers, - GClosure *closure); - -CLUTTER_EXPORT -const gchar * clutter_binding_pool_find_action (ClutterBindingPool *pool, - guint key_val, - ClutterModifierType modifiers); -CLUTTER_EXPORT -void clutter_binding_pool_remove_action (ClutterBindingPool *pool, - guint key_val, - ClutterModifierType modifiers); - -CLUTTER_EXPORT -gboolean clutter_binding_pool_activate (ClutterBindingPool *pool, - guint key_val, - ClutterModifierType modifiers, - GObject *gobject); - -CLUTTER_EXPORT -void clutter_binding_pool_block_action (ClutterBindingPool *pool, - const gchar *action_name); -CLUTTER_EXPORT -void clutter_binding_pool_unblock_action (ClutterBindingPool *pool, - const gchar *action_name); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-blur-effect.c b/mutter/clutter/clutter/clutter-blur-effect.c deleted file mode 100644 index 5ceadcd..0000000 --- a/mutter/clutter/clutter/clutter-blur-effect.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterBlurEffect: - * - * A blur effect - * - * #ClutterBlurEffect is a sub-class of #ClutterEffect that allows blurring a - * actor and its contents. - */ -#include "config.h" - -#include "clutter/clutter-blur-effect.h" - -#include "cogl/cogl.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-private.h" - -#define BLUR_PADDING 2 - -/* FIXME - lame shader; we should really have a decoupled - * horizontal/vertical two pass shader for the gaussian blur - */ -static const gchar *box_blur_glsl_declarations = -"uniform vec2 pixel_step;\n"; -#define SAMPLE(offx, offy) \ - "cogl_texel += texture2D (cogl_sampler, cogl_tex_coord.st + pixel_step * " \ - "vec2 (" G_STRINGIFY (offx) ", " G_STRINGIFY (offy) "));\n" -static const gchar *box_blur_glsl_shader = -" cogl_texel = texture2D (cogl_sampler, cogl_tex_coord.st);\n" - SAMPLE (-1.0, -1.0) - SAMPLE ( 0.0, -1.0) - SAMPLE (+1.0, -1.0) - SAMPLE (-1.0, 0.0) - SAMPLE (+1.0, 0.0) - SAMPLE (-1.0, +1.0) - SAMPLE ( 0.0, +1.0) - SAMPLE (+1.0, +1.0) -" cogl_texel /= 9.0;\n"; -#undef SAMPLE - -typedef struct _ClutterBlurEffectPrivate -{ - /* a back pointer to our actor, so that we can query it */ - ClutterActor *actor; - - gint pixel_step_uniform; - - CoglPipeline *pipeline; -} ClutterBlurEffectPrivate; - - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterBlurEffect, - clutter_blur_effect, - CLUTTER_TYPE_OFFSCREEN_EFFECT); - -static CoglPipeline * -clutter_blur_effect_create_pipeline (ClutterOffscreenEffect *effect, - CoglTexture *texture) -{ - ClutterBlurEffect *blur_effect = CLUTTER_BLUR_EFFECT (effect); - ClutterBlurEffectPrivate *priv = - clutter_blur_effect_get_instance_private (blur_effect); - - if (priv->pixel_step_uniform > -1) - { - float pixel_step[2]; - int tex_width, tex_height; - - tex_width = cogl_texture_get_width (texture); - tex_height = cogl_texture_get_height (texture); - - pixel_step[0] = 1.0f / tex_width; - pixel_step[1] = 1.0f / tex_height; - - cogl_pipeline_set_uniform_float (priv->pipeline, - priv->pixel_step_uniform, - 2, /* n_components */ - 1, /* count */ - pixel_step); - } - - cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture); - - return g_object_ref (priv->pipeline); -} - -static gboolean -clutter_blur_effect_modify_paint_volume (ClutterEffect *effect, - ClutterPaintVolume *volume) -{ - gfloat cur_width, cur_height; - graphene_point3d_t origin; - - clutter_paint_volume_get_origin (volume, &origin); - cur_width = clutter_paint_volume_get_width (volume); - cur_height = clutter_paint_volume_get_height (volume); - - origin.x -= BLUR_PADDING; - origin.y -= BLUR_PADDING; - cur_width += 2 * BLUR_PADDING; - cur_height += 2 * BLUR_PADDING; - clutter_paint_volume_set_origin (volume, &origin); - clutter_paint_volume_set_width (volume, cur_width); - clutter_paint_volume_set_height (volume, cur_height); - - return TRUE; -} - -static void -clutter_blur_effect_dispose (GObject *gobject) -{ - ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (gobject); - ClutterBlurEffectPrivate *priv = - clutter_blur_effect_get_instance_private (self); - - g_clear_object (&priv->pipeline); - - G_OBJECT_CLASS (clutter_blur_effect_parent_class)->dispose (gobject); -} - -static void -clutter_blur_effect_class_init (ClutterBlurEffectClass *klass) -{ - ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass); - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterOffscreenEffectClass *offscreen_class; - - gobject_class->dispose = clutter_blur_effect_dispose; - - effect_class->modify_paint_volume = clutter_blur_effect_modify_paint_volume; - - offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); - offscreen_class->create_pipeline = clutter_blur_effect_create_pipeline; -} - -static void -clutter_blur_effect_init (ClutterBlurEffect *self) -{ - ClutterBlurEffectClass *klass = CLUTTER_BLUR_EFFECT_GET_CLASS (self); - ClutterBlurEffectPrivate *priv = - clutter_blur_effect_get_instance_private (self); - - if (G_UNLIKELY (klass->base_pipeline == NULL)) - { - CoglSnippet *snippet; - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - - klass->base_pipeline = cogl_pipeline_new (ctx); - - snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP, - box_blur_glsl_declarations, - NULL); - cogl_snippet_set_replace (snippet, box_blur_glsl_shader); - cogl_pipeline_add_layer_snippet (klass->base_pipeline, 0, snippet); - g_object_unref (snippet); - - cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0); - } - - priv->pipeline = cogl_pipeline_copy (klass->base_pipeline); - - priv->pixel_step_uniform = - cogl_pipeline_get_uniform_location (priv->pipeline, "pixel_step"); -} - -/** - * clutter_blur_effect_new: - * - * Creates a new #ClutterBlurEffect to be used with - * [method@Clutter.Actor.add_effect] - * - * Return value: the newly created #ClutterBlurEffect or %NULL - */ -ClutterEffect * -clutter_blur_effect_new (void) -{ - return g_object_new (CLUTTER_TYPE_BLUR_EFFECT, NULL); -} diff --git a/mutter/clutter/clutter/clutter-blur-effect.h b/mutter/clutter/clutter/clutter-blur-effect.h deleted file mode 100644 index ef1f644..0000000 --- a/mutter/clutter/clutter/clutter-blur-effect.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-effect.h" -#include "clutter/clutter-offscreen-effect.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_BLUR_EFFECT (clutter_blur_effect_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterBlurEffect, - clutter_blur_effect, - CLUTTER, BLUR_EFFECT, - ClutterOffscreenEffect) - -struct _ClutterBlurEffectClass -{ - ClutterOffscreenEffectClass parent_class; - - CoglPipeline *base_pipeline; -}; - -CLUTTER_EXPORT -ClutterEffect *clutter_blur_effect_new (void); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-blur-private.h b/mutter/clutter/clutter/clutter-blur-private.h deleted file mode 100644 index 7a47f73..0000000 --- a/mutter/clutter/clutter/clutter-blur-private.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2020 Endless OS Foundation, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#include - -#include "cogl/cogl.h" - -G_BEGIN_DECLS - -typedef struct _ClutterBlur ClutterBlur; - -ClutterBlur * clutter_blur_new (CoglTexture *texture, - float radius); - -void clutter_blur_apply (ClutterBlur *blur); - -CoglTexture * clutter_blur_get_texture (ClutterBlur *blur); - -void clutter_blur_free (ClutterBlur *blur); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-blur.c b/mutter/clutter/clutter/clutter-blur.c deleted file mode 100644 index c6d3ea7..0000000 --- a/mutter/clutter/clutter/clutter-blur.c +++ /dev/null @@ -1,436 +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 . - */ - -#include "config.h" - -#include "clutter/clutter-blur-private.h" - -#include "clutter/clutter-backend.h" - -/** - * ClutterBlur: - * - * Blur textures - * - * #ClutterBlur is a moderately fast gaussian blur implementation. - * - * # Optimizations - * - * There are a number of optimizations in place to make this blur implementation - * real-time. All in all, the implementation performs best when using large - * blur-radii that allow downscaling the texture to smaller sizes, at small - * radii where no downscaling is possible this can easily halve the framerate. - * - * ## Multipass - * - * It is implemented in 2 passes: vertical and horizontal. - * - * ## Downscaling - * - * #ClutterBlur uses dynamic downscaling to speed up blurring. Downscaling - * happens in factors of 2 (the image is downscaled either by 2, 4, 8, 16, …) - * and depends on the blur radius, the texture size, among others. - * - * The texture is drawn into a downscaled framebuffer; the blur passes are - * applied on the downscaled texture contents; and finally, the blurred - * contents are drawn - * upscaled again. - * - * ## Hardware Interpolation - * - * This blur implementation cuts down the number of sampling operations by - * exploiting the hardware interpolation that is performed when sampling between - * pixel boundaries. This technique is described at: - * - * http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/ - * - * ## Incremental gauss-factor calculation - * - * The kernel values for the gaussian kernel are computed incrementally instead - * of running the expensive calculations multiple times inside the blur shader. - * The implementation is based on the algorithm presented by K. Turkowski in - * GPU Gems 3, chapter 40: - * - * https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch40.html - * - */ - -static const char *gaussian_blur_glsl_declarations = -"uniform float sigma; \n" -"uniform float pixel_step; \n" -"uniform vec2 direction; \n"; - -static const char *gaussian_blur_glsl = -" vec2 uv = vec2 (cogl_tex_coord.st); \n" -" \n" -" vec3 gauss_coefficient; \n" -" gauss_coefficient.x = 1.0 / (sqrt (2.0 * 3.14159265) * sigma); \n" -" gauss_coefficient.y = exp (-0.5 / (sigma * sigma)); \n" -" gauss_coefficient.z = gauss_coefficient.y * gauss_coefficient.y; \n" -" \n" -" float gauss_coefficient_total = gauss_coefficient.x; \n" -" \n" -" vec4 ret = texture2D (cogl_sampler, uv) * gauss_coefficient.x; \n" -" gauss_coefficient.xy *= gauss_coefficient.yz; \n" -" \n" -" int n_steps = int (ceil (1.5 * sigma)) * 2; \n" -" \n" -" for (int i = 1; i <= n_steps; i += 2) { \n" -" float coefficient_subtotal = gauss_coefficient.x; \n" -" gauss_coefficient.xy *= gauss_coefficient.yz; \n" -" coefficient_subtotal += gauss_coefficient.x; \n" -" \n" -" float gauss_ratio = gauss_coefficient.x / coefficient_subtotal; \n" -" \n" -" float foffset = float (i) + gauss_ratio; \n" -" vec2 offset = direction * foffset * pixel_step; \n" -" \n" -" ret += texture2D (cogl_sampler, uv + offset) * coefficient_subtotal; \n" -" ret += texture2D (cogl_sampler, uv - offset) * coefficient_subtotal; \n" -" \n" -" gauss_coefficient_total += 2.0 * coefficient_subtotal; \n" -" gauss_coefficient.xy *= gauss_coefficient.yz; \n" -" } \n" -" \n" -" cogl_texel = ret / gauss_coefficient_total; \n"; - -#define MIN_DOWNSCALE_SIZE 256.f -#define MAX_SIGMA 6.f - -enum -{ - VERTICAL, - HORIZONTAL, -}; - -typedef struct -{ - CoglFramebuffer *framebuffer; - CoglPipeline *pipeline; - CoglTexture *texture; - int orientation; -} BlurPass; - -struct _ClutterBlur -{ - CoglTexture *source_texture; - float sigma; - float downscale_factor; - - BlurPass pass[2]; -}; - -static CoglPipeline* -create_blur_pipeline (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); - g_object_unref (snippet); - - cogl_context_set_named_pipeline (ctx, &blur_pipeline_key, blur_pipeline); - } - - return cogl_pipeline_copy (blur_pipeline); -} - -static void -update_blur_uniforms (ClutterBlur *blur, - BlurPass *pass) -{ - gboolean vertical = pass->orientation == VERTICAL; - int sigma_uniform; - int pixel_step_uniform; - int direction_uniform; - - pixel_step_uniform = - cogl_pipeline_get_uniform_location (pass->pipeline, "pixel_step"); - if (pixel_step_uniform > -1) - { - float pixel_step; - - if (vertical) - pixel_step = 1.f / cogl_texture_get_height (pass->texture); - else - pixel_step = 1.f / cogl_texture_get_width (pass->texture); - - cogl_pipeline_set_uniform_1f (pass->pipeline, - pixel_step_uniform, - pixel_step); - } - - sigma_uniform = cogl_pipeline_get_uniform_location (pass->pipeline, "sigma"); - if (sigma_uniform > -1) - { - cogl_pipeline_set_uniform_1f (pass->pipeline, - sigma_uniform, - blur->sigma / blur->downscale_factor); - } - - direction_uniform = - cogl_pipeline_get_uniform_location (pass->pipeline, "direction"); - if (direction_uniform > -1) - { - gboolean horizontal = !vertical; - float direction[2] = { - horizontal, - vertical, - }; - - cogl_pipeline_set_uniform_float (pass->pipeline, - direction_uniform, - 2, 1, - direction); - } -} - -static gboolean -create_fbo (ClutterBlur *blur, - 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_object (&pass->texture); - g_clear_object (&pass->framebuffer); - - width = cogl_texture_get_width (blur->source_texture); - height = cogl_texture_get_height (blur->source_texture); - scaled_width = floorf (width / blur->downscale_factor); - scaled_height = floorf (height / blur->downscale_factor); - - pass->texture = cogl_texture_2d_new_with_size (ctx, - 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_4f (&transparent, 0.0, 0.0, 0.0, 0.0); - - cogl_framebuffer_clear (pass->framebuffer, - COGL_BUFFER_BIT_COLOR, - &transparent); - - cogl_framebuffer_draw_rectangle (pass->framebuffer, - pass->pipeline, - 0, 0, - cogl_texture_get_width (pass->texture), - cogl_texture_get_height (pass->texture)); -} - -static void -clear_blur_pass (BlurPass *pass) -{ - g_clear_object (&pass->pipeline); - g_clear_object (&pass->texture); - g_clear_object (&pass->framebuffer); -} - -/** - * clutter_blur_new: - * @texture: a #CoglTexture - * @sigma: blur sigma - * - * Creates a new #ClutterBlur. - * - * Returns: (transfer full) (nullable): A newly created #ClutterBlur - */ -ClutterBlur * -clutter_blur_new (CoglTexture *texture, - float radius) -{ - ClutterBlur *blur; - unsigned int height; - unsigned int width; - BlurPass *hpass; - BlurPass *vpass; - - g_return_val_if_fail (texture != NULL, NULL); - g_return_val_if_fail (radius >= 0.0, NULL); - - width = cogl_texture_get_width (texture); - height = cogl_texture_get_height (texture); - - blur = g_new0 (ClutterBlur, 1); - blur->sigma = radius / 2.0; - blur->source_texture = g_object_ref (texture); - blur->downscale_factor = calculate_downscale_factor (width, - height, - blur->sigma); - - if (G_APPROX_VALUE (blur->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 - * [method@Clutter.Blur.get_texture]. - */ -void -clutter_blur_apply (ClutterBlur *blur) -{ - if (G_APPROX_VALUE (blur->sigma, 0.0, FLT_EPSILON)) - return; - - apply_blur_pass (&blur->pass[VERTICAL]); - apply_blur_pass (&blur->pass[HORIZONTAL]); -} - -/** - * clutter_blur_get_texture: - * @blur: a #ClutterBlur - * - * Retrieves the texture where the blurred contents are stored. The - * contents are undefined until [method@Clutter.Blur.apply] is called. - * - * Returns: (transfer none): a #CoglTexture - */ -CoglTexture * -clutter_blur_get_texture (ClutterBlur *blur) -{ - if (G_APPROX_VALUE (blur->sigma, 0.0, FLT_EPSILON)) - return blur->source_texture; - else - return blur->pass[HORIZONTAL].texture; -} - -/** - * clutter_blur_free: - * @blur: A #ClutterBlur - * - * Frees @blur. - */ -void -clutter_blur_free (ClutterBlur *blur) -{ - g_assert (blur); - - clear_blur_pass (&blur->pass[VERTICAL]); - clear_blur_pass (&blur->pass[HORIZONTAL]); - g_clear_object (&blur->source_texture); - g_free (blur); -} diff --git a/mutter/clutter/clutter/clutter-box-layout.c b/mutter/clutter/clutter/clutter-box-layout.c deleted file mode 100644 index 1982667..0000000 --- a/mutter/clutter/clutter/clutter-box-layout.c +++ /dev/null @@ -1,1148 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - * - * Based on the NBTK NbtkBoxLayout actor by: - * Thomas Wood - */ - -/** - * ClutterBoxLayout: - * - * A layout manager arranging children on a single line - * - * The #ClutterBoxLayout is a [class@Clutter.LayoutManager] implementing the - * following layout policy: - * - * - all children are arranged on a single line - * - the axis used is controlled by the [property@Clutter.BoxLayout:orientation] property - * - each child will be allocated to its natural size or, if [property@Clutter.Actor:x-expand] or - * [property@Clutter.Actor:y-expand] are set, the available size - * - honours the #ClutterActor's [property@Clutter.Actor:x-align] and [property@Clutter.Actor:y-align] properties - * to fill the available size - * - if the [property@Clutter.BoxLayout:homogeneous] boolean property 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 - * #ClutterBoxLayout by using [method@Clutter.BoxLayout.set_spacing]. - */ - -#include "config.h" - -#include - -#include "clutter/clutter-box-layout.h" - -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-layout-meta.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-types.h" - -typedef struct _ClutterBoxLayoutPrivate -{ - ClutterActor *container; - - guint spacing; - - ClutterAnimationMode easing_mode; - guint easing_duration; - - ClutterOrientation orientation; - - guint is_homogeneous : 1; -} ClutterBoxLayoutPrivate; - -enum -{ - PROP_0, - - PROP_SPACING, - PROP_HOMOGENEOUS, - PROP_ORIENTATION, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST] = { NULL, }; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterBoxLayout, - clutter_box_layout, - CLUTTER_TYPE_LAYOUT_MANAGER) - - -typedef struct _RequestedSize -{ - ClutterActor *actor; - - gfloat minimum_size; - gfloat natural_size; -} RequestedSize; - -static float distribute_natural_allocation (float extra_space, - unsigned int n_requested_sizes, - RequestedSize *sizes); -static void count_expand_children (ClutterLayoutManager *layout, - ClutterActor *container, - gint *visible_children, - gint *expand_children); - -static void -clutter_box_layout_set_container (ClutterLayoutManager *layout, - ClutterActor *container) -{ - ClutterBoxLayout *self = CLUTTER_BOX_LAYOUT (layout); - ClutterBoxLayoutPrivate *priv = - clutter_box_layout_get_instance_private (self); - ClutterLayoutManagerClass *parent_class; - - priv->container = container; - - if (priv->container != NULL) - { - ClutterRequestMode request_mode; - - /* we need to change the :request-mode of the container - * to match the orientation - */ - request_mode = priv->orientation == CLUTTER_ORIENTATION_VERTICAL - ? CLUTTER_REQUEST_HEIGHT_FOR_WIDTH - : CLUTTER_REQUEST_WIDTH_FOR_HEIGHT; - clutter_actor_set_request_mode (CLUTTER_ACTOR (priv->container), - request_mode); - } - - parent_class = CLUTTER_LAYOUT_MANAGER_CLASS (clutter_box_layout_parent_class); - parent_class->set_container (layout, container); -} - -static void -get_child_size (ClutterActor *actor, - ClutterOrientation orientation, - gfloat for_size, - gfloat *min_size_p, - gfloat *natural_size_p) -{ - if (orientation == CLUTTER_ORIENTATION_HORIZONTAL) - clutter_actor_get_preferred_width (actor, for_size, min_size_p, natural_size_p); - else - clutter_actor_get_preferred_height (actor, for_size, min_size_p, natural_size_p); -} - -/* Handle the request in the orientation of the box (i.e. width request of horizontal box) */ -static void -get_preferred_size_for_orientation (ClutterBoxLayout *self, - ClutterActor *container, - gfloat for_size, - gfloat *min_size_p, - gfloat *natural_size_p) -{ - ClutterBoxLayoutPrivate *priv = - clutter_box_layout_get_instance_private (self); - ClutterActorIter iter; - 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)) - { - gfloat child_min = 0, child_nat = 0; - - if (!clutter_actor_is_visible (child)) - continue; - - n_children++; - - 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; - } - - if (n_children > 1) - { - minimum += priv->spacing * (n_children - 1); - natural += priv->spacing * (n_children - 1); - } - - if (min_size_p) - *min_size_p = minimum; - - if (natural_size_p) - *natural_size_p = natural; -} - -static void -get_base_size_for_opposite_orientation (ClutterBoxLayout *self, - ClutterActor *container, - gfloat *min_size_p, - gfloat *natural_size_p) -{ - ClutterBoxLayoutPrivate *priv = - clutter_box_layout_get_instance_private (self); - ClutterActorIter iter; - ClutterActor *child; - gint n_children = 0; - gfloat minimum, natural; - ClutterOrientation opposite_orientation = - priv->orientation == CLUTTER_ORIENTATION_HORIZONTAL - ? CLUTTER_ORIENTATION_VERTICAL - : CLUTTER_ORIENTATION_HORIZONTAL; - - minimum = natural = 0; - - clutter_actor_iter_init (&iter, container); - while (clutter_actor_iter_next (&iter, &child)) - { - gfloat child_min = 0, child_nat = 0; - - if (!clutter_actor_is_visible (child)) - continue; - - n_children++; - - get_child_size (child, opposite_orientation, -1, &child_min, &child_nat); - - minimum = MAX (minimum, child_min); - natural = MAX (natural, child_nat); - } - - if (min_size_p) - *min_size_p = minimum; - - if (natural_size_p) - *natural_size_p = natural; -} - - -/* Handle the request in the opposite orientation of the box - * (i.e. height request of horizontal box) - * - * This operation requires a virtual allocation in the natural - * orientation of the box, after that each element must be asked - * for the size-for-virtually-allocated-size and the maximums of - * each child sample will be reported as the overall - * "size-for-size-in-opposite-orientation" - */ -static void -get_preferred_size_for_opposite_orientation (ClutterBoxLayout *self, - ClutterActor *container, - gfloat for_size, - gfloat *min_size_p, - gfloat *natural_size_p) -{ - ClutterLayoutManager *layout = CLUTTER_LAYOUT_MANAGER (self); - ClutterBoxLayoutPrivate *priv = - clutter_box_layout_get_instance_private (self); - ClutterActor *child; - ClutterActorIter iter; - gint nvis_children = 0, n_extra_widgets = 0; - gint nexpand_children = 0, i; - RequestedSize *sizes; - gfloat minimum, natural, size, extra = 0; - ClutterOrientation opposite_orientation = - priv->orientation == CLUTTER_ORIENTATION_HORIZONTAL - ? CLUTTER_ORIENTATION_VERTICAL - : CLUTTER_ORIENTATION_HORIZONTAL; - - minimum = natural = 0; - - count_expand_children (layout, container, &nvis_children, &nexpand_children); - - if (nvis_children < 1) - { - if (min_size_p) - *min_size_p = 0; - - if (natural_size_p) - *natural_size_p = 0; - - return; - } - - /* First collect the requested sizes in the natural orientation of the box */ - sizes = g_newa (RequestedSize, nvis_children); - size = for_size; - - i = 0; - clutter_actor_iter_init (&iter, container); - while (clutter_actor_iter_next (&iter, &child)) - { - if (!clutter_actor_is_visible (child)) - continue; - - get_child_size (child, priv->orientation, -1, - &sizes[i].minimum_size, - &sizes[i].natural_size); - - size -= sizes[i].minimum_size; - i++; - } - - if (priv->is_homogeneous) - { - size = for_size - (nvis_children - 1) * priv->spacing; - extra = size / nvis_children; - n_extra_widgets = ((gint)size) % nvis_children; - } - else - { - size -= (nvis_children - 1) * priv->spacing; - - /* Bring children up to size first */ - if (isnormal (size) || size == 0) - { - size = distribute_natural_allocation (MAX (0, size), - nvis_children, - sizes); - } - else - { - g_critical ("Actor %s (%p) received the invalid " - "value %f as minimum/natural size\n", - G_OBJECT_TYPE_NAME (container), container, size); - size = 0; - } - - /* Calculate space which hasn't distributed yet, - * and is available for expanding children. - */ - if (nexpand_children > 0) - { - extra = size / nexpand_children; - n_extra_widgets = ((gint)size) % nexpand_children; - } - } - - /* Distribute expand space to children */ - i = 0; - clutter_actor_iter_init (&iter, container); - while (clutter_actor_iter_next (&iter, &child)) - { - /* If widget is not visible, skip it. */ - if (!clutter_actor_is_visible (child)) - continue; - - if (priv->is_homogeneous) - { - sizes[i].minimum_size = extra; - - if (n_extra_widgets > 0) - { - sizes[i].minimum_size++; - n_extra_widgets--; - } - } - else - { - if (clutter_actor_needs_expand (child, priv->orientation)) - { - sizes[i].minimum_size += extra; - - if (n_extra_widgets > 0) - { - sizes[i].minimum_size++; - n_extra_widgets--; - } - } - } - i++; - } - - /* Virtual allocation finished, now we can finally ask for the right size-for-size */ - i = 0; - clutter_actor_iter_init (&iter, container); - while (clutter_actor_iter_next (&iter, &child)) - { - gfloat child_min = 0, child_nat = 0; - - if (!clutter_actor_is_visible (child)) - continue; - - get_child_size (child, opposite_orientation, - sizes[i].minimum_size, - &child_min, &child_nat); - - minimum = MAX (minimum, child_min); - natural = MAX (natural, child_nat); - - i++; - } - - if (min_size_p) - *min_size_p = minimum; - - if (natural_size_p) - *natural_size_p = natural; -} - - -static void -allocate_box_child (ClutterBoxLayout *self, - ClutterActor *container, - ClutterActor *child, - ClutterActorBox *child_box) -{ - CLUTTER_NOTE (LAYOUT, "Allocation for %s { %.2f, %.2f, %.2f, %.2f }", - _clutter_actor_get_debug_name (child), - child_box->x1, child_box->y1, - child_box->x2 - child_box->x1, - child_box->y2 - child_box->y1); - - clutter_actor_allocate (child, child_box); -} - -static void -clutter_box_layout_get_preferred_width (ClutterLayoutManager *layout, - ClutterActor *container, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p) -{ - ClutterBoxLayout *self = CLUTTER_BOX_LAYOUT (layout); - ClutterBoxLayoutPrivate *priv = - clutter_box_layout_get_instance_private (self); - - if (priv->orientation == CLUTTER_ORIENTATION_VERTICAL) - { - if (for_height < 0) - get_base_size_for_opposite_orientation (self, CLUTTER_ACTOR (container), - min_width_p, natural_width_p); - else - get_preferred_size_for_opposite_orientation (self, CLUTTER_ACTOR (container), for_height, - min_width_p, natural_width_p); - } - else - get_preferred_size_for_orientation (self, CLUTTER_ACTOR (container), for_height, - min_width_p, natural_width_p); -} - -static void -clutter_box_layout_get_preferred_height (ClutterLayoutManager *layout, - ClutterActor *container, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p) -{ - ClutterBoxLayout *self = CLUTTER_BOX_LAYOUT (layout); - ClutterBoxLayoutPrivate *priv = - clutter_box_layout_get_instance_private (self); - - if (priv->orientation == CLUTTER_ORIENTATION_HORIZONTAL) - { - if (for_width < 0) - get_base_size_for_opposite_orientation (self, CLUTTER_ACTOR (container), - min_height_p, natural_height_p); - else - get_preferred_size_for_opposite_orientation (self, CLUTTER_ACTOR (container), for_width, - min_height_p, natural_height_p); - } - else - get_preferred_size_for_orientation (self, CLUTTER_ACTOR (container), for_width, - min_height_p, natural_height_p); -} - -static void -count_expand_children (ClutterLayoutManager *layout, - ClutterActor *container, - gint *visible_children, - gint *expand_children) -{ - ClutterBoxLayout *self = CLUTTER_BOX_LAYOUT (layout); - ClutterBoxLayoutPrivate *priv = - clutter_box_layout_get_instance_private (self); - ClutterActor *child; - ClutterActorIter iter; - - *visible_children = *expand_children = 0; - - clutter_actor_iter_init (&iter, container); - while (clutter_actor_iter_next (&iter, &child)) - { - if (clutter_actor_is_visible (child)) - { - *visible_children += 1; - - if (clutter_actor_needs_expand (child, priv->orientation)) - *expand_children += 1; - } - } -} - -/* Pulled from gtksizerequest.c from Gtk+ */ -static gint -compare_gap (gconstpointer p1, - gconstpointer p2, - gpointer data) -{ - RequestedSize *sizes = data; - const guint *c1 = p1; - const guint *c2 = p2; - - const gint d1 = MAX (sizes[*c1].natural_size - - sizes[*c1].minimum_size, - 0); - const gint d2 = MAX (sizes[*c2].natural_size - - sizes[*c2].minimum_size, - 0); - - gint delta = (d2 - d1); - - if (0 == delta) - delta = (*c2 - *c1); - - return delta; -} - -/* - * distribute_natural_allocation: - * @extra_space: Extra space to redistribute among children after subtracting - * minimum sizes and any child padding from the overall allocation - * @n_requested_sizes: Number of requests to fit into the allocation - * @sizes: An array of structs with a client pointer and a minimum/natural size - * in the orientation of the allocation. - * - * Distributes @extra_space to child @sizes by bringing smaller - * children up to natural size first. - * - * The remaining space will be added to the @minimum_size member of the - * RequestedSize struct. If all sizes reach their natural size then - * the remaining space is returned. - * - * Returns: The remainder of @extra_space after redistributing space - * to @sizes. - * - * Pulled from gtksizerequest.c from Gtk+ - */ -static float -distribute_natural_allocation (float extra_space, - unsigned int n_requested_sizes, - RequestedSize *sizes) -{ - unsigned int *spreading; - int i; - - g_return_val_if_fail (isnormal (extra_space) || extra_space == 0, 0); - g_return_val_if_fail (extra_space >= 0, 0); - - spreading = g_newa (unsigned int, n_requested_sizes); - - for (i = 0; i < n_requested_sizes; i++) - spreading[i] = i; - - /* Distribute the container's extra space c_gap. We want to assign - * this space such that the sum of extra space assigned to children - * (c^i_gap) is equal to c_cap. The case that there's not enough - * space for all children to take their natural size needs some - * attention. The goals we want to achieve are: - * - * a) Maximize number of children taking their natural size. - * b) The allocated size of children should be a continuous - * function of c_gap. That is, increasing the container size by - * one pixel should never make drastic changes in the distribution. - * c) If child i takes its natural size and child j doesn't, - * child j should have received at least as much gap as child i. - * - * The following code distributes the additional space by following - * these rules. - */ - - /* Sort descending by gap and position. */ - g_qsort_with_data (spreading, - n_requested_sizes, sizeof (unsigned int), - compare_gap, sizes); - - /* Distribute available space. - * This master piece of a loop was conceived by Behdad Esfahbod. - */ - for (i = n_requested_sizes - 1; extra_space > 0.0 && i >= 0; --i) - { - /* Divide remaining space by number of remaining children. - * Sort order and reducing remaining space by assigned space - * ensures that space is distributed equally. - */ - float glue = (extra_space + i) / (i + 1.0); - float gap = - sizes[(spreading[i])].natural_size - sizes[(spreading[i])].minimum_size; - - float extra = MIN (glue, gap); - - sizes[spreading[i]].minimum_size += extra; - - extra_space -= extra; - } - - return extra_space; -} - -/* Pulled from gtkbox.c from Gtk+ */ - -static void -clutter_box_layout_allocate (ClutterLayoutManager *layout, - ClutterActor *container, - const ClutterActorBox *box) -{ - ClutterBoxLayout *self = CLUTTER_BOX_LAYOUT (layout); - ClutterBoxLayoutPrivate *priv = - clutter_box_layout_get_instance_private (self); - ClutterActor *actor, *child; - gint nvis_children; - gint nexpand_children; - gboolean is_rtl; - ClutterActorIter iter; - - ClutterActorBox child_allocation; - RequestedSize *sizes; - - gint size; - gint extra; - gint n_extra_widgets = 0; /* Number of widgets that receive 1 extra px */ - gint x = 0, y = 0, i; - gfloat child_size; - - count_expand_children (layout, container, &nvis_children, &nexpand_children); - - CLUTTER_NOTE (LAYOUT, "BoxLayout for %s: visible=%d, expand=%d", - _clutter_actor_get_debug_name (CLUTTER_ACTOR (container)), - nvis_children, - nexpand_children); - - /* If there is no visible child, simply return. */ - if (nvis_children <= 0) - return; - - sizes = g_newa (RequestedSize, nvis_children); - - if (priv->orientation == CLUTTER_ORIENTATION_VERTICAL) - size = box->y2 - box->y1 - (nvis_children - 1) * priv->spacing; - else - size = box->x2 - box->x1 - (nvis_children - 1) * priv->spacing; - - actor = CLUTTER_ACTOR (container); - - /* Retrieve desired size for visible children. */ - i = 0; - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) - { - if (!clutter_actor_is_visible (child)) - continue; - - if (priv->orientation == CLUTTER_ORIENTATION_VERTICAL) - clutter_actor_get_preferred_height (child, - box->x2 - box->x1, - &sizes[i].minimum_size, - &sizes[i].natural_size); - else - clutter_actor_get_preferred_width (child, - box->y2 - box->y1, - &sizes[i].minimum_size, - &sizes[i].natural_size); - - - /* Assert the api is working properly */ - if (sizes[i].minimum_size < 0) - g_error ("ClutterBoxLayout child %s minimum %s: %f < 0 for %s %f", - _clutter_actor_get_debug_name (child), - priv->orientation == CLUTTER_ORIENTATION_VERTICAL - ? "height" - : "width", - sizes[i].minimum_size, - priv->orientation == CLUTTER_ORIENTATION_VERTICAL - ? "width" - : "height", - priv->orientation == CLUTTER_ORIENTATION_VERTICAL - ? box->x2 - box->x1 - : box->y2 - box->y1); - - if (sizes[i].natural_size < sizes[i].minimum_size) - g_error ("ClutterBoxLayout child %s natural %s: %f < minimum %f for %s %f", - _clutter_actor_get_debug_name (child), - priv->orientation == CLUTTER_ORIENTATION_VERTICAL - ? "height" - : "width", - sizes[i].natural_size, - sizes[i].minimum_size, - priv->orientation == CLUTTER_ORIENTATION_VERTICAL - ? "width" - : "height", - priv->orientation == CLUTTER_ORIENTATION_VERTICAL - ? box->x2 - box->x1 - : box->y2 - box->y1); - - size -= sizes[i].minimum_size; - - sizes[i].actor = child; - - i += 1; - } - - if (priv->is_homogeneous) - { - /* If were homogeneous 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) - size = box->y2 - box->y1 - (nvis_children - 1) * priv->spacing; - else - size = box->x2 - box->x1 - (nvis_children - 1) * priv->spacing; - - extra = size / nvis_children; - n_extra_widgets = size % nvis_children; - } - else - { - /* Bring children up to size first */ - size = (gint) distribute_natural_allocation (MAX (0, (float) size), - nvis_children, - sizes); - - /* Calculate space which hasn't distributed yet, - * and is available for expanding children. - */ - if (nexpand_children > 0) - { - extra = size / nexpand_children; - n_extra_widgets = size % nexpand_children; - } - else - extra = 0; - } - - if (priv->orientation == CLUTTER_ORIENTATION_HORIZONTAL) - { - ClutterTextDirection text_dir; - - text_dir = clutter_actor_get_text_direction (CLUTTER_ACTOR (container)); - is_rtl = (text_dir == CLUTTER_TEXT_DIRECTION_RTL) ? TRUE : FALSE; - } - else - is_rtl = FALSE; - - /* Allocate child positions. */ - if (priv->orientation == CLUTTER_ORIENTATION_VERTICAL) - { - child_allocation.x1 = box->x1; - child_allocation.x2 = MAX (1.0, box->x2); - y = box->y1; - } - else - { - child_allocation.y1 = box->y1; - child_allocation.y2 = MAX (1.0, box->y2); - x = box->x1; - } - - i = 0; - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) - { - /* If widget is not visible, skip it. */ - if (!clutter_actor_is_visible (child)) - continue; - - /* Assign the child's size. */ - if (priv->is_homogeneous) - { - child_size = extra; - - if (n_extra_widgets > 0) - { - child_size++; - n_extra_widgets--; - } - } - else - { - child_size = sizes[i].minimum_size; - - if (clutter_actor_needs_expand (child, priv->orientation)) - { - child_size += extra; - - if (n_extra_widgets > 0) - { - child_size++; - n_extra_widgets--; - } - } - } - - /* Assign the child's position. */ - if (priv->orientation == CLUTTER_ORIENTATION_VERTICAL) - { - if (clutter_actor_needs_expand (child, priv->orientation)) - { - child_allocation.y1 = y; - child_allocation.y2 = child_allocation.y1 + MAX (1.0, child_size); - } - else - { - child_allocation.y1 = y + (child_size - sizes[i].minimum_size) / 2; - child_allocation.y2 = child_allocation.y1 + sizes[i].minimum_size; - } - - y += child_size + priv->spacing; - } - else /* CLUTTER_ORIENTATION_HORIZONTAL */ - { - if (clutter_actor_needs_expand (child, priv->orientation)) - { - child_allocation.x1 = x; - child_allocation.x2 = child_allocation.x1 + MAX (1.0, child_size); - } - else - { - child_allocation.x1 = x + (child_size - sizes[i].minimum_size) / 2; - child_allocation.x2 = child_allocation.x1 + sizes[i].minimum_size; - } - - x += child_size + priv->spacing; - - if (is_rtl) - { - gfloat width = child_allocation.x2 - child_allocation.x1; - - child_allocation.x2 = box->x1 + (box->x2 - child_allocation.x1); - child_allocation.x1 = child_allocation.x2 - width; - } - - } - - allocate_box_child (CLUTTER_BOX_LAYOUT (layout), - container, - child, - &child_allocation); - - i += 1; - } -} - -static void -clutter_box_layout_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterBoxLayout *self = CLUTTER_BOX_LAYOUT (gobject); - - switch (prop_id) - { - case PROP_ORIENTATION: - clutter_box_layout_set_orientation (self, g_value_get_enum (value)); - break; - - case PROP_HOMOGENEOUS: - clutter_box_layout_set_homogeneous (self, g_value_get_boolean (value)); - break; - - case PROP_SPACING: - clutter_box_layout_set_spacing (self, g_value_get_uint (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_box_layout_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterBoxLayout *self = CLUTTER_BOX_LAYOUT (gobject); - ClutterBoxLayoutPrivate *priv = - clutter_box_layout_get_instance_private (self); - - switch (prop_id) - { - case PROP_ORIENTATION: - g_value_set_enum (value, priv->orientation); - break; - - case PROP_HOMOGENEOUS: - g_value_set_boolean (value, priv->is_homogeneous); - break; - - case PROP_SPACING: - g_value_set_uint (value, priv->spacing); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_box_layout_class_init (ClutterBoxLayoutClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterLayoutManagerClass *layout_class; - - layout_class = CLUTTER_LAYOUT_MANAGER_CLASS (klass); - - layout_class->get_preferred_width = clutter_box_layout_get_preferred_width; - layout_class->get_preferred_height = clutter_box_layout_get_preferred_height; - layout_class->allocate = clutter_box_layout_allocate; - layout_class->set_container = clutter_box_layout_set_container; - - /** - * ClutterBoxLayout:orientation: - * - * The orientation of the #ClutterBoxLayout, either horizontal - * or vertical - */ - obj_props[PROP_ORIENTATION] = - g_param_spec_enum ("orientation", NULL, NULL, - CLUTTER_TYPE_ORIENTATION, - CLUTTER_ORIENTATION_HORIZONTAL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterBoxLayout:homogeneous: - * - * Whether the #ClutterBoxLayout should arrange its children - * homogeneously, i.e. all children get the same size - */ - obj_props[PROP_HOMOGENEOUS] = - g_param_spec_boolean ("homogeneous", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterBoxLayout:spacing: - * - * The spacing between children of the #ClutterBoxLayout, in pixels - */ - obj_props[PROP_SPACING] = - g_param_spec_uint ("spacing", NULL, NULL, - 0, G_MAXUINT, 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - gobject_class->set_property = clutter_box_layout_set_property; - gobject_class->get_property = clutter_box_layout_get_property; - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); -} - -static void -clutter_box_layout_init (ClutterBoxLayout *self) -{ - ClutterBoxLayoutPrivate *priv = - clutter_box_layout_get_instance_private (self); - - priv->orientation = CLUTTER_ORIENTATION_HORIZONTAL; - priv->is_homogeneous = FALSE; - priv->spacing = 0; - - priv->easing_mode = CLUTTER_EASE_OUT_CUBIC; - priv->easing_duration = 500; -} - -/** - * clutter_box_layout_new: - * - * Creates a new #ClutterBoxLayout layout manager - * - * Return value: the newly created #ClutterBoxLayout - */ -ClutterLayoutManager * -clutter_box_layout_new (void) -{ - return g_object_new (CLUTTER_TYPE_BOX_LAYOUT, NULL); -} - -/** - * clutter_box_layout_set_spacing: - * @layout: a #ClutterBoxLayout - * @spacing: the spacing between children of the layout, in pixels - * - * Sets the spacing between children of @layout - */ -void -clutter_box_layout_set_spacing (ClutterBoxLayout *layout, - guint spacing) -{ - ClutterBoxLayoutPrivate *priv; - - g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout)); - - priv = clutter_box_layout_get_instance_private (layout); - if (priv->spacing != spacing) - { - ClutterLayoutManager *manager; - - priv->spacing = spacing; - - manager = CLUTTER_LAYOUT_MANAGER (layout); - - clutter_layout_manager_layout_changed (manager); - - g_object_notify (G_OBJECT (layout), "spacing"); - } -} - -/** - * clutter_box_layout_get_spacing: - * @layout: a #ClutterBoxLayout - * - * Retrieves the spacing set using [method@Clutter.BoxLayout.set_spacing] - * - * Return value: the spacing between children of the #ClutterBoxLayout - */ -guint -clutter_box_layout_get_spacing (ClutterBoxLayout *layout) -{ - ClutterBoxLayoutPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout), 0); - - priv = clutter_box_layout_get_instance_private (layout); - return priv->spacing; -} - -/** - * clutter_box_layout_set_orientation: - * @layout: a #ClutterBoxLayout - * @orientation: the orientation of the #ClutterBoxLayout - * - * Sets the orientation of the #ClutterBoxLayout layout manager. - */ -void -clutter_box_layout_set_orientation (ClutterBoxLayout *layout, - ClutterOrientation orientation) -{ - ClutterLayoutManager *manager; - ClutterBoxLayoutPrivate *priv; - - g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout)); - - priv = clutter_box_layout_get_instance_private (layout); - if (priv->orientation == orientation) - return; - - priv->orientation = orientation; - - manager = CLUTTER_LAYOUT_MANAGER (layout); - - clutter_layout_manager_layout_changed (manager); - - g_object_notify_by_pspec (G_OBJECT (layout), obj_props[PROP_ORIENTATION]); -} - -/** - * clutter_box_layout_get_orientation: - * @layout: a #ClutterBoxLayout - * - * Retrieves the orientation of the @layout. - * - * Return value: the orientation of the layout - */ -ClutterOrientation -clutter_box_layout_get_orientation (ClutterBoxLayout *layout) -{ - ClutterBoxLayoutPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout), - CLUTTER_ORIENTATION_HORIZONTAL); - - priv = clutter_box_layout_get_instance_private (layout); - return priv->orientation; -} - -/** - * clutter_box_layout_set_homogeneous: - * @layout: a #ClutterBoxLayout - * @homogeneous: %TRUE if the layout should be homogeneous - * - * Sets whether the size of @layout children should be - * homogeneous - */ -void -clutter_box_layout_set_homogeneous (ClutterBoxLayout *layout, - gboolean homogeneous) -{ - ClutterBoxLayoutPrivate *priv; - - g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout)); - - priv = clutter_box_layout_get_instance_private (layout); - if (priv->is_homogeneous != homogeneous) - { - ClutterLayoutManager *manager; - - priv->is_homogeneous = !!homogeneous; - - manager = CLUTTER_LAYOUT_MANAGER (layout); - - clutter_layout_manager_layout_changed (manager); - - g_object_notify (G_OBJECT (layout), "homogeneous"); - } -} - -/** - * clutter_box_layout_get_homogeneous: - * @layout: a #ClutterBoxLayout - * - * Retrieves if the children sizes are allocated homogeneously. - * - * Return value: %TRUE if the #ClutterBoxLayout is arranging its children - * homogeneously, and %FALSE otherwise - */ -gboolean -clutter_box_layout_get_homogeneous (ClutterBoxLayout *layout) -{ - ClutterBoxLayoutPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout), FALSE); - - priv = clutter_box_layout_get_instance_private (layout); - return priv->is_homogeneous; -} - diff --git a/mutter/clutter/clutter/clutter-box-layout.h b/mutter/clutter/clutter/clutter-box-layout.h deleted file mode 100644 index 90088d6..0000000 --- a/mutter/clutter/clutter/clutter-box-layout.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - * - * Based on the NBTK NbtkBoxLayout actor by: - * Thomas Wood - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-layout-manager.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_BOX_LAYOUT (clutter_box_layout_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterBoxLayout, - clutter_box_layout, - CLUTTER, BOX_LAYOUT, - ClutterLayoutManager) - -struct _ClutterBoxLayoutClass -{ - /*< private >*/ - ClutterLayoutManagerClass parent_class; -}; - -CLUTTER_EXPORT -ClutterLayoutManager * clutter_box_layout_new (void); - -CLUTTER_EXPORT -void clutter_box_layout_set_orientation (ClutterBoxLayout *layout, - ClutterOrientation orientation); -CLUTTER_EXPORT -ClutterOrientation clutter_box_layout_get_orientation (ClutterBoxLayout *layout); - -CLUTTER_EXPORT -void clutter_box_layout_set_spacing (ClutterBoxLayout *layout, - guint spacing); -CLUTTER_EXPORT -guint clutter_box_layout_get_spacing (ClutterBoxLayout *layout); -CLUTTER_EXPORT -void clutter_box_layout_set_homogeneous (ClutterBoxLayout *layout, - gboolean homogeneous); -CLUTTER_EXPORT -gboolean clutter_box_layout_get_homogeneous (ClutterBoxLayout *layout); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-brightness-contrast-effect.c b/mutter/clutter/clutter/clutter-brightness-contrast-effect.c deleted file mode 100644 index 35049d8..0000000 --- a/mutter/clutter/clutter/clutter-brightness-contrast-effect.c +++ /dev/null @@ -1,595 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010-2012 Inclusive Design Research Centre, OCAD University. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Joseph Scheuhammer - */ - -/** - * ClutterBrightnessContrastEffect: - * - * Increase/decrease brightness and/or contrast of actor. - * - * #ClutterBrightnessContrastEffect is a sub-class of #ClutterEffect that - * changes the overall brightness of a #ClutterActor. - */ -#include "config.h" - -#include - -#include "cogl/cogl.h" - -#include "clutter/clutter-brightness-contrast-effect.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-private.h" - -typedef struct _ClutterBrightnessContrastEffectPrivate -{ - /* Brightness and contrast changes. */ - gfloat brightness_red; - gfloat brightness_green; - gfloat brightness_blue; - - gfloat contrast_red; - gfloat contrast_green; - gfloat contrast_blue; - - gint brightness_multiplier_uniform; - gint brightness_offset_uniform; - gint contrast_uniform; - - CoglPipeline *pipeline; -} ClutterBrightnessContrastEffectPrivate; - - -/* Brightness effects in GLSL. - */ -static const gchar *brightness_contrast_decls = - "uniform vec3 brightness_multiplier;\n" - "uniform vec3 brightness_offset;\n" - "uniform vec3 contrast;\n"; - -static const gchar *brightness_contrast_source = - /* Apply the brightness. The brightness_offset is multiplied by the - alpha to keep the color pre-multiplied */ - "cogl_color_out.rgb = (cogl_color_out.rgb * brightness_multiplier +\n" - " brightness_offset * cogl_color_out.a);\n" - /* Apply the contrast */ - "cogl_color_out.rgb = ((cogl_color_out.rgb - 0.5 * cogl_color_out.a) *\n" - " contrast + 0.5 * cogl_color_out.a);\n"; - -static const ClutterColor no_brightness_change = { 0x7f, 0x7f, 0x7f, 0xff }; -static const ClutterColor no_contrast_change = { 0x7f, 0x7f, 0x7f, 0xff }; -static const gfloat no_change = 0.0f; - -enum -{ - PROP_0, - - PROP_BRIGHTNESS, - PROP_CONTRAST, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterBrightnessContrastEffect, - clutter_brightness_contrast_effect, - CLUTTER_TYPE_OFFSCREEN_EFFECT) - -static gboolean -will_have_no_effect (ClutterBrightnessContrastEffect *self) -{ - ClutterBrightnessContrastEffectPrivate *priv = - clutter_brightness_contrast_effect_get_instance_private (self); - - return (G_APPROX_VALUE (priv->brightness_red, no_change, FLT_EPSILON) && - G_APPROX_VALUE (priv->brightness_green, no_change, FLT_EPSILON) && - G_APPROX_VALUE (priv->brightness_blue, no_change, FLT_EPSILON) && - G_APPROX_VALUE (priv->contrast_red, no_change, FLT_EPSILON) && - G_APPROX_VALUE (priv->contrast_green, no_change, FLT_EPSILON) && - G_APPROX_VALUE (priv->contrast_blue, no_change, FLT_EPSILON)); -} - -static CoglPipeline * -clutter_brightness_contrast_effect_create_pipeline (ClutterOffscreenEffect *effect, - CoglTexture *texture) -{ - ClutterBrightnessContrastEffect *self = - CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect); - ClutterBrightnessContrastEffectPrivate *priv = - clutter_brightness_contrast_effect_get_instance_private (self); - - cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture); - - return g_object_ref (priv->pipeline); -} - -static gboolean -clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect); - ClutterEffectClass *parent_class; - - if (will_have_no_effect (self)) - return FALSE; - - parent_class = - CLUTTER_EFFECT_CLASS (clutter_brightness_contrast_effect_parent_class); - - return parent_class->pre_paint (effect, node, paint_context); -} - -static void -clutter_brightness_contrast_effect_dispose (GObject *gobject) -{ - ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (gobject); - ClutterBrightnessContrastEffectPrivate *priv = - clutter_brightness_contrast_effect_get_instance_private (self); - - g_clear_object (&priv->pipeline); - - G_OBJECT_CLASS (clutter_brightness_contrast_effect_parent_class)->dispose (gobject); -} - -static void -clutter_brightness_contrast_effect_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterBrightnessContrastEffect *effect = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (gobject); - - switch (prop_id) - { - case PROP_BRIGHTNESS: - { - const ClutterColor *color = clutter_value_get_color (value); - clutter_brightness_contrast_effect_set_brightness_full (effect, - color->red / 127.0f - 1.0f, - color->green / 127.0f - 1.0f, - color->blue / 127.0f - 1.0f); - } - break; - - case PROP_CONTRAST: - { - const ClutterColor *color = clutter_value_get_color (value); - clutter_brightness_contrast_effect_set_contrast_full (effect, - color->red / 127.0f - 1.0f, - color->green / 127.0f - 1.0f, - color->blue / 127.0f - 1.0f); - } - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_brightness_contrast_effect_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterBrightnessContrastEffect *effect = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (gobject); - ClutterBrightnessContrastEffectPrivate *priv = - clutter_brightness_contrast_effect_get_instance_private (effect); - ClutterColor color; - - switch (prop_id) - { - case PROP_BRIGHTNESS: - { - color.red = (priv->brightness_red + 1.0f) * 127.0f; - color.green = (priv->brightness_green + 1.0f) * 127.0f; - color.blue = (priv->brightness_blue + 1.0f) * 127.0f; - color.alpha = 0xff; - - clutter_value_set_color (value, &color); - } - break; - - case PROP_CONTRAST: - { - color.red = (priv->contrast_red + 1.0f) * 127.0f; - color.green = (priv->contrast_green + 1.0f) * 127.0f; - color.blue = (priv->contrast_blue + 1.0f) * 127.0f; - color.alpha = 0xff; - - clutter_value_set_color (value, &color); - } - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_brightness_contrast_effect_class_init (ClutterBrightnessContrastEffectClass *klass) -{ - ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass); - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterOffscreenEffectClass *offscreen_class; - - offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); - offscreen_class->create_pipeline = clutter_brightness_contrast_effect_create_pipeline; - - effect_class->pre_paint = clutter_brightness_contrast_effect_pre_paint; - - gobject_class->set_property = clutter_brightness_contrast_effect_set_property; - gobject_class->get_property = clutter_brightness_contrast_effect_get_property; - gobject_class->dispose = clutter_brightness_contrast_effect_dispose; - - /** - * ClutterBrightnessContrastEffect:brightness: - * - * The brightness change to apply to the effect. - * - * This property uses a #ClutterColor to represent the changes to each - * color channel. The range is [ 0, 255 ], with 127 as the value used - * to indicate no change; values smaller than 127 indicate a decrease - * in brightness, and values larger than 127 indicate an increase in - * brightness. - */ - obj_props[PROP_BRIGHTNESS] = - clutter_param_spec_color ("brightness", NULL, NULL, - &no_brightness_change, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterBrightnessContrastEffect:contrast: - * - * The contrast change to apply to the effect. - * - * This property uses a #ClutterColor to represent the changes to each - * color channel. The range is [ 0, 255 ], with 127 as the value used - * to indicate no change; values smaller than 127 indicate a decrease - * in contrast, and values larger than 127 indicate an increase in - * contrast. - */ - obj_props[PROP_CONTRAST] = - clutter_param_spec_color ("contrast", NULL, NULL, - &no_contrast_change, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); -} - -static void -get_brightness_values (gfloat value, - gfloat *multiplier, - gfloat *offset) -{ - if (value < 0.0f) - { - *multiplier = 1.0f + value; - *offset = 0.0f; - } - else - { - *multiplier = 1.0f - value; - *offset = value; - } -} - -static inline void -update_uniforms (ClutterBrightnessContrastEffect *self) -{ - ClutterBrightnessContrastEffectPrivate *priv = - clutter_brightness_contrast_effect_get_instance_private (self); - - if (priv->brightness_multiplier_uniform > -1 && - priv->brightness_offset_uniform > -1) - { - float brightness_multiplier[3]; - float brightness_offset[3]; - - get_brightness_values (priv->brightness_red, - brightness_multiplier + 0, - brightness_offset + 0); - get_brightness_values (priv->brightness_green, - brightness_multiplier + 1, - brightness_offset + 1); - get_brightness_values (priv->brightness_blue, - brightness_multiplier + 2, - brightness_offset + 2); - - cogl_pipeline_set_uniform_float (priv->pipeline, - priv->brightness_multiplier_uniform, - 3, /* n_components */ - 1, /* count */ - brightness_multiplier); - cogl_pipeline_set_uniform_float (priv->pipeline, - priv->brightness_offset_uniform, - 3, /* n_components */ - 1, /* count */ - brightness_offset); - } - - if (priv->contrast_uniform > -1) - { - float contrast[3] = { - tan ((priv->contrast_red + 1) * G_PI_4), - tan ((priv->contrast_green + 1) * G_PI_4), - tan ((priv->contrast_blue + 1) * G_PI_4) - }; - - cogl_pipeline_set_uniform_float (priv->pipeline, - priv->contrast_uniform, - 3, /* n_components */ - 1, /* count */ - contrast); - } -} - -static void -clutter_brightness_contrast_effect_init (ClutterBrightnessContrastEffect *self) -{ - ClutterBrightnessContrastEffectClass *klass; - ClutterBrightnessContrastEffectPrivate *priv = - clutter_brightness_contrast_effect_get_instance_private (self); - - priv->brightness_red = no_change; - priv->brightness_green = no_change; - priv->brightness_blue = no_change; - - priv->contrast_red = no_change; - priv->contrast_green = no_change; - priv->contrast_blue = no_change; - - klass = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_GET_CLASS (self); - - if (G_UNLIKELY (klass->base_pipeline == NULL)) - { - CoglSnippet *snippet; - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - - klass->base_pipeline = cogl_pipeline_new (ctx); - - snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, - brightness_contrast_decls, - brightness_contrast_source); - cogl_pipeline_add_snippet (klass->base_pipeline, snippet); - g_object_unref (snippet); - - cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0); - } - - priv->pipeline = cogl_pipeline_copy (klass->base_pipeline); - - priv->brightness_multiplier_uniform = - cogl_pipeline_get_uniform_location (priv->pipeline, - "brightness_multiplier"); - priv->brightness_offset_uniform = - cogl_pipeline_get_uniform_location (priv->pipeline, - "brightness_offset"); - priv->contrast_uniform = - cogl_pipeline_get_uniform_location (priv->pipeline, "contrast"); - - update_uniforms (self); -} - -/** - * clutter_brightness_contrast_effect_new: - * - * Creates a new #ClutterBrightnessContrastEffect to be used with - * [method@Clutter.Actor.add_effect] - * - * Return value: (transfer full): the newly created - * #ClutterBrightnessContrastEffect or %NULL. Use g_object_unref() when - * done. - */ -ClutterEffect * -clutter_brightness_contrast_effect_new (void) -{ - return g_object_new (CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT, NULL); -} - -/** - * clutter_brightness_contrast_effect_set_brightness_full: - * @effect: a #ClutterBrightnessContrastEffect - * @red: red component of the change in brightness - * @green: green component of the change in brightness - * @blue: blue component of the change in brightness - * - * The range for each component is [-1.0, 1.0] where 0.0 designates no change, - * values below 0.0 mean a decrease in brightness, and values above indicate - * an increase. - */ -void -clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContrastEffect *effect, - gfloat red, - gfloat green, - gfloat blue) -{ - ClutterBrightnessContrastEffectPrivate *priv; - - g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect)); - - priv = clutter_brightness_contrast_effect_get_instance_private (effect); - if (G_APPROX_VALUE (red, priv->brightness_red, FLT_EPSILON) && - G_APPROX_VALUE (green, priv->brightness_green, FLT_EPSILON) && - G_APPROX_VALUE (blue, priv->brightness_blue, FLT_EPSILON)) - return; - - priv->brightness_red = red; - priv->brightness_green = green; - priv->brightness_blue = blue; - - update_uniforms (effect); - - clutter_effect_queue_repaint (CLUTTER_EFFECT (effect)); - - g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_BRIGHTNESS]); -} - -/** - * clutter_brightness_contrast_effect_get_brightness: - * @effect: a #ClutterBrightnessContrastEffect - * @red: (out) (allow-none): return location for red component of the - * change in brightness - * @green: (out) (allow-none): return location for green component of the - * change in brightness - * @blue: (out) (allow-none): return location for blue component of the - * change in brightness - * - * Retrieves the change in brightness used by @effect. - */ -void -clutter_brightness_contrast_effect_get_brightness (ClutterBrightnessContrastEffect *effect, - gfloat *red, - gfloat *green, - gfloat *blue) -{ - ClutterBrightnessContrastEffectPrivate *priv; - - g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect)); - - priv = clutter_brightness_contrast_effect_get_instance_private (effect); - if (red != NULL) - *red = priv->brightness_red; - - if (green != NULL) - *green = priv->brightness_green; - - if (blue != NULL) - *blue = priv->brightness_blue; -} - -/** - * clutter_brightness_contrast_effect_set_brightness: - * @effect: a #ClutterBrightnessContrastEffect - * @brightness: the brightness change for all three components (r, g, b) - * - * The range of @brightness is [-1.0, 1.0], where 0.0 designates no change; - * a value below 0.0 indicates a decrease in brightness; and a value - * above 0.0 indicates an increase of brightness. - */ -void -clutter_brightness_contrast_effect_set_brightness (ClutterBrightnessContrastEffect *effect, - gfloat brightness) -{ - clutter_brightness_contrast_effect_set_brightness_full (effect, - brightness, - brightness, - brightness); -} - -/** - * clutter_brightness_contrast_effect_set_contrast_full: - * @effect: a #ClutterBrightnessContrastEffect - * @red: red component of the change in contrast - * @green: green component of the change in contrast - * @blue: blue component of the change in contrast - * - * The range for each component is [-1.0, 1.0] where 0.0 designates no change, - * values below 0.0 mean a decrease in contrast, and values above indicate - * an increase. - */ -void -clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastEffect *effect, - gfloat red, - gfloat green, - gfloat blue) -{ - ClutterBrightnessContrastEffectPrivate *priv; - - g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect)); - - priv = clutter_brightness_contrast_effect_get_instance_private (effect); - if (G_APPROX_VALUE (red, priv->contrast_red, FLT_EPSILON) && - G_APPROX_VALUE (green, priv->contrast_green, FLT_EPSILON) && - G_APPROX_VALUE (blue, priv->contrast_blue, FLT_EPSILON)) - return; - - priv->contrast_red = red; - priv->contrast_green = green; - priv->contrast_blue = blue; - - update_uniforms (effect); - - clutter_effect_queue_repaint (CLUTTER_EFFECT (effect)); - - g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_CONTRAST]); -} - -/** - * clutter_brightness_contrast_effect_get_contrast: - * @effect: a #ClutterBrightnessContrastEffect - * @red: (out) (allow-none): return location for red component of the - * change in contrast - * @green: (out) (allow-none): return location for green component of the - * change in contrast - * @blue: (out) (allow-none): return location for blue component of the - * change in contrast - * - * Retrieves the contrast value used by @effect. - */ -void -clutter_brightness_contrast_effect_get_contrast (ClutterBrightnessContrastEffect *effect, - gfloat *red, - gfloat *green, - gfloat *blue) -{ - ClutterBrightnessContrastEffectPrivate *priv; - - g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect)); - - priv = clutter_brightness_contrast_effect_get_instance_private (effect); - if (red != NULL) - *red = priv->contrast_red; - - if (green != NULL) - *green = priv->contrast_green; - - if (blue != NULL) - *blue = priv->contrast_blue; -} - -/** - * clutter_brightness_contrast_effect_set_contrast: - * @effect: a #ClutterBrightnessContrastEffect - * @contrast: contrast change for all three channels - * - * The range for @contrast is [-1.0, 1.0], where 0.0 designates no change; - * a value below 0.0 indicates a decrease in contrast; and a value above - * 0.0 indicates an increase. - */ -void -clutter_brightness_contrast_effect_set_contrast (ClutterBrightnessContrastEffect *effect, - gfloat contrast) -{ - clutter_brightness_contrast_effect_set_contrast_full (effect, - contrast, - contrast, - contrast); -} diff --git a/mutter/clutter/clutter/clutter-brightness-contrast-effect.h b/mutter/clutter/clutter/clutter-brightness-contrast-effect.h deleted file mode 100644 index 6e3b390..0000000 --- a/mutter/clutter/clutter/clutter-brightness-contrast-effect.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010-2012 Inclusive Design Research Centre, OCAD University. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Joseph Scheuhammer - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-color.h" -#include "clutter/clutter-effect.h" -#include "clutter/clutter-offscreen-effect.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT (clutter_brightness_contrast_effect_get_type ()) - - -struct _ClutterBrightnessContrastEffectClass -{ - ClutterOffscreenEffectClass parent_class; - - CoglPipeline *base_pipeline; -}; - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterBrightnessContrastEffect, - clutter_brightness_contrast_effect, - CLUTTER, BRIGHTNESS_CONTRAST_EFFECT, - ClutterOffscreenEffect) - -CLUTTER_EXPORT -ClutterEffect * clutter_brightness_contrast_effect_new (void); - -CLUTTER_EXPORT -void clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContrastEffect *effect, - float red, - float green, - float blue); -CLUTTER_EXPORT -void clutter_brightness_contrast_effect_set_brightness (ClutterBrightnessContrastEffect *effect, - float brightness); -CLUTTER_EXPORT -void clutter_brightness_contrast_effect_get_brightness (ClutterBrightnessContrastEffect *effect, - float *red, - float *green, - float *blue); - -CLUTTER_EXPORT -void clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastEffect *effect, - float red, - float green, - float blue); -CLUTTER_EXPORT -void clutter_brightness_contrast_effect_set_contrast (ClutterBrightnessContrastEffect *effect, - float contrast); -CLUTTER_EXPORT -void clutter_brightness_contrast_effect_get_contrast (ClutterBrightnessContrastEffect *effect, - float *red, - float *green, - float *blue); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-click-action.c b/mutter/clutter/clutter/clutter-click-action.c deleted file mode 100644 index d306749..0000000 --- a/mutter/clutter/clutter/clutter-click-action.c +++ /dev/null @@ -1,785 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterClickAction: - * - * Action for clickable actors - * - * #ClutterClickAction is a sub-class of [class@Action] that implements - * the logic for clickable actors, by using the low level events of - * [class@Actor], such as [signal@Actor::button-press-event] and - * [signal@Actor::button-release-event], to synthesize the high level - * [signal@ClickAction::clicked] signal. - * - * To use #ClutterClickAction you just need to apply it to a [class@Actor] - * using [method@Actor.add_action] and connect to the - * [signal@ClickAction::clicked] signal: - * - * ```c - * ClutterAction *action = clutter_click_action_new (); - * - * clutter_actor_add_action (actor, action); - * - * g_signal_connect (action, "clicked", G_CALLBACK (on_clicked), NULL); - * ``` - * - * #ClutterClickAction also supports long press gestures: a long press is - * activated if the pointer remains pressed within a certain threshold (as - * defined by the [property@ClickAction:long-press-threshold] property) for a - * minimum amount of time (as the defined by the - * [property@ClickAction:long-press-duration] property). - * The [signal@ClickAction::long-press] signal is emitted multiple times, - * using different [enum@LongPressState] values; to handle long presses - * you should connect to the [signal@ClickAction::long-press] signal and - * handle the different states: - * - * ```c - * static gboolean - * on_long_press (ClutterClickAction *action, - * ClutterActor *actor, - * ClutterLongPressState state) - * { - * switch (state) - * { - * case CLUTTER_LONG_PRESS_QUERY: - * // return TRUE if the actor should support long press - * // gestures, and FALSE otherwise; this state will be - * // emitted on button presses - * return TRUE; - * - * case CLUTTER_LONG_PRESS_ACTIVATE: - * // this state is emitted if the minimum duration has - * // been reached without the gesture being cancelled. - * // the return value is not used - * return TRUE; - * - * case CLUTTER_LONG_PRESS_CANCEL: - * // this state is emitted if the long press was cancelled; - * // for instance, the pointer went outside the actor or the - * // allowed threshold, or the button was released before - * // the minimum duration was reached. the return value is - * // not used - * return FALSE; - * } - * } - * ``` - */ - -#include "config.h" - -#include "clutter/clutter-click-action.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-private.h" - -struct _ClutterClickActionPrivate -{ - ClutterActor *stage; - - guint long_press_id; - - gint long_press_threshold; - gint long_press_duration; - gint drag_threshold; - - guint press_button; - ClutterInputDevice *press_device; - ClutterEventSequence *press_sequence; - ClutterModifierType modifier_state; - gfloat press_x; - gfloat press_y; - - guint is_held : 1; - guint is_pressed : 1; -}; - -enum -{ - PROP_0, - - PROP_HELD, - PROP_PRESSED, - PROP_LONG_PRESS_THRESHOLD, - PROP_LONG_PRESS_DURATION, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST] = { NULL, }; - -enum -{ - CLICKED, - LONG_PRESS, - - LAST_SIGNAL -}; - -static guint click_signals[LAST_SIGNAL] = { 0, }; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterClickAction, clutter_click_action, CLUTTER_TYPE_ACTION) - -static inline void -click_action_set_pressed (ClutterClickAction *action, - gboolean is_pressed) -{ - ClutterClickActionPrivate *priv = - clutter_click_action_get_instance_private (action); - - is_pressed = !!is_pressed; - - if (priv->is_pressed == is_pressed) - return; - - priv->is_pressed = is_pressed; - g_object_notify_by_pspec (G_OBJECT (action), obj_props[PROP_PRESSED]); -} - -static inline void -click_action_set_held (ClutterClickAction *action, - gboolean is_held) -{ - ClutterClickActionPrivate *priv = - clutter_click_action_get_instance_private (action); - - is_held = !!is_held; - - if (priv->is_held == is_held) - return; - - priv->is_held = is_held; - g_object_notify_by_pspec (G_OBJECT (action), obj_props[PROP_HELD]); -} - -static gboolean -click_action_emit_long_press (gpointer data) -{ - ClutterClickAction *action = data; - ClutterClickActionPrivate *priv = - clutter_click_action_get_instance_private (action); - ClutterActor *actor; - gboolean result; - - priv->long_press_id = 0; - - actor = clutter_actor_meta_get_actor (data); - - g_signal_emit (action, click_signals[LONG_PRESS], 0, - actor, - CLUTTER_LONG_PRESS_ACTIVATE, - &result); - - click_action_set_pressed (action, FALSE); - click_action_set_held (action, FALSE); - - return FALSE; -} - -static inline void -click_action_query_long_press (ClutterClickAction *action) -{ - ClutterClickActionPrivate *priv = - clutter_click_action_get_instance_private (action); - ClutterActor *actor; - gboolean result = FALSE; - gint timeout; - - if (priv->long_press_duration < 0) - { - ClutterSettings *settings = clutter_settings_get_default (); - - g_object_get (settings, - "long-press-duration", &timeout, - NULL); - } - else - timeout = priv->long_press_duration; - - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); - - g_signal_emit (action, click_signals[LONG_PRESS], 0, - actor, - CLUTTER_LONG_PRESS_QUERY, - &result); - - if (result) - { - g_clear_handle_id (&priv->long_press_id, g_source_remove); - priv->long_press_id = - clutter_threads_add_timeout (timeout, - click_action_emit_long_press, - action); - } -} - -static inline void -click_action_cancel_long_press (ClutterClickAction *action) -{ - ClutterClickActionPrivate *priv = - clutter_click_action_get_instance_private (action); - - if (priv->long_press_id != 0) - { - ClutterActor *actor; - gboolean result; - - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); - - g_clear_handle_id (&priv->long_press_id, g_source_remove); - - g_signal_emit (action, click_signals[LONG_PRESS], 0, - actor, - CLUTTER_LONG_PRESS_CANCEL, - &result); - } -} - -static inline gboolean -event_within_drag_threshold (ClutterClickAction *click_action, - const ClutterEvent *event) -{ - ClutterClickActionPrivate *priv = - clutter_click_action_get_instance_private (click_action); - float motion_x, motion_y; - float delta_x, delta_y; - - clutter_event_get_coords (event, &motion_x, &motion_y); - - delta_x = ABS (motion_x - priv->press_x); - delta_y = ABS (motion_y - priv->press_y); - - return delta_x <= priv->drag_threshold && delta_y <= priv->drag_threshold; -} - -static gboolean -clutter_click_action_handle_event (ClutterAction *action, - const ClutterEvent *event) -{ - ClutterClickAction *click_action = CLUTTER_CLICK_ACTION (action); - ClutterClickActionPrivate *priv = - clutter_click_action_get_instance_private (click_action); - ClutterActor *actor = - clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); - gboolean has_button = TRUE; - ClutterModifierType modifier_state; - ClutterActor *target; - - if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action))) - return CLUTTER_EVENT_PROPAGATE; - - if (priv->press_sequence != NULL && - clutter_event_get_event_sequence (event) != priv->press_sequence) - { - click_action_set_held (click_action, FALSE); - click_action_cancel_long_press (click_action); - return CLUTTER_EVENT_PROPAGATE; - } - - switch (clutter_event_type (event)) - { - case CLUTTER_TOUCH_BEGIN: - has_button = FALSE; - - G_GNUC_FALLTHROUGH; - case CLUTTER_BUTTON_PRESS: - if (priv->is_held) - return CLUTTER_EVENT_STOP; - - target = clutter_stage_get_device_actor (CLUTTER_STAGE (clutter_actor_get_stage (actor)), - clutter_event_get_device (event), - clutter_event_get_event_sequence (event)); - - if (!clutter_actor_contains (actor, target)) - return CLUTTER_EVENT_PROPAGATE; - - priv->press_button = has_button ? clutter_event_get_button (event) : 0; - priv->press_device = clutter_event_get_device (event); - priv->press_sequence = clutter_event_get_event_sequence (event); - priv->modifier_state = clutter_event_get_state (event); - clutter_event_get_coords (event, &priv->press_x, &priv->press_y); - - if (priv->long_press_threshold < 0) - { - ClutterSettings *settings = clutter_settings_get_default (); - - g_object_get (settings, - "dnd-drag-threshold", &priv->drag_threshold, - NULL); - } - else - priv->drag_threshold = priv->long_press_threshold; - - if (priv->stage == NULL) - priv->stage = clutter_actor_get_stage (actor); - - click_action_set_pressed (click_action, TRUE); - click_action_set_held (click_action, TRUE); - click_action_query_long_press (click_action); - break; - - case CLUTTER_ENTER: - click_action_set_pressed (click_action, priv->is_held); - return CLUTTER_EVENT_PROPAGATE; - - case CLUTTER_LEAVE: - click_action_set_pressed (click_action, FALSE); - click_action_cancel_long_press (click_action); - return CLUTTER_EVENT_PROPAGATE; - - case CLUTTER_TOUCH_CANCEL: - clutter_click_action_release (click_action); - break; - - case CLUTTER_TOUCH_END: - has_button = FALSE; - - G_GNUC_FALLTHROUGH; - case CLUTTER_BUTTON_RELEASE: - if (!priv->is_held) - return CLUTTER_EVENT_PROPAGATE; - - if ((has_button && clutter_event_get_button (event) != priv->press_button) || - clutter_event_get_device (event) != priv->press_device || - clutter_event_get_event_sequence (event) != priv->press_sequence) - return CLUTTER_EVENT_PROPAGATE; - - click_action_set_held (click_action, FALSE); - click_action_cancel_long_press (click_action); - - g_clear_handle_id (&priv->long_press_id, g_source_remove); - - target = clutter_stage_get_device_actor (CLUTTER_STAGE (clutter_actor_get_stage (actor)), - clutter_event_get_device (event), - clutter_event_get_event_sequence (event)); - - if (!clutter_actor_contains (actor, target)) - return CLUTTER_EVENT_PROPAGATE; - - /* exclude any button-mask so that we can compare - * the press and release states properly */ - modifier_state = clutter_event_get_state (event) & - ~(CLUTTER_BUTTON1_MASK | - CLUTTER_BUTTON2_MASK | - CLUTTER_BUTTON3_MASK | - CLUTTER_BUTTON4_MASK | - CLUTTER_BUTTON5_MASK); - - /* if press and release states don't match we - * simply ignore modifier keys. i.e. modifier keys - * are expected to be pressed throughout the whole - * click */ - if (modifier_state != priv->modifier_state) - priv->modifier_state = 0; - - click_action_set_pressed (click_action, FALSE); - - if (event_within_drag_threshold (click_action, event)) - g_signal_emit (click_action, click_signals[CLICKED], 0, actor); - break; - - case CLUTTER_MOTION: - case CLUTTER_TOUCH_UPDATE: - { - if (clutter_event_get_device (event) != priv->press_device || - clutter_event_get_event_sequence (event) != priv->press_sequence) - return CLUTTER_EVENT_PROPAGATE; - - if (!priv->is_held) - return CLUTTER_EVENT_PROPAGATE; - - if (!event_within_drag_threshold (click_action, event)) - clutter_click_action_release (click_action); - } - break; - - default: - break; - } - - return priv->is_held ? CLUTTER_EVENT_STOP : CLUTTER_EVENT_PROPAGATE; -} - -static void -clutter_click_action_sequence_cancelled (ClutterAction *action, - ClutterInputDevice *device, - ClutterEventSequence *sequence) -{ - ClutterClickAction *self = CLUTTER_CLICK_ACTION (action); - ClutterClickActionPrivate *priv = - clutter_click_action_get_instance_private (self); - - if (priv->press_device == device && priv->press_sequence == sequence) - clutter_click_action_release (self); -} - -static void -clutter_click_action_set_actor (ClutterActorMeta *meta, - ClutterActor *actor) -{ - ClutterClickAction *action = CLUTTER_CLICK_ACTION (meta); - ClutterClickActionPrivate *priv = - clutter_click_action_get_instance_private (action); - - g_clear_handle_id (&priv->long_press_id, g_source_remove); - - click_action_set_pressed (action, FALSE); - click_action_set_held (action, FALSE); - - CLUTTER_ACTOR_META_CLASS (clutter_click_action_parent_class)->set_actor (meta, actor); -} - -static void -clutter_click_action_set_enabled (ClutterActorMeta *meta, - gboolean is_enabled) -{ - ClutterClickAction *click_action = CLUTTER_CLICK_ACTION (meta); - ClutterActorMetaClass *parent_class = - CLUTTER_ACTOR_META_CLASS (clutter_click_action_parent_class); - - if (!is_enabled) - clutter_click_action_release (click_action); - - parent_class->set_enabled (meta, is_enabled); -} - -static void -clutter_click_action_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterClickActionPrivate *priv = - clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject)); - - switch (prop_id) - { - case PROP_LONG_PRESS_DURATION: - priv->long_press_duration = g_value_get_int (value); - break; - - case PROP_LONG_PRESS_THRESHOLD: - priv->long_press_threshold = g_value_get_int (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_click_action_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterClickActionPrivate *priv = - clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject)); - - switch (prop_id) - { - case PROP_HELD: - g_value_set_boolean (value, priv->is_held); - break; - - case PROP_PRESSED: - g_value_set_boolean (value, priv->is_pressed); - break; - - case PROP_LONG_PRESS_DURATION: - g_value_set_int (value, priv->long_press_duration); - break; - - case PROP_LONG_PRESS_THRESHOLD: - g_value_set_int (value, priv->long_press_threshold); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_click_action_dispose (GObject *gobject) -{ - ClutterClickActionPrivate *priv = - clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject)); - - g_clear_handle_id (&priv->long_press_id, g_source_remove); - - G_OBJECT_CLASS (clutter_click_action_parent_class)->dispose (gobject); -} - -static void -clutter_click_action_class_init (ClutterClickActionClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); - ClutterActionClass *action_class = CLUTTER_ACTION_CLASS (klass); - - action_class->handle_event = clutter_click_action_handle_event; - action_class->sequence_cancelled = clutter_click_action_sequence_cancelled; - - meta_class->set_actor = clutter_click_action_set_actor; - meta_class->set_enabled = clutter_click_action_set_enabled; - - gobject_class->dispose = clutter_click_action_dispose; - gobject_class->set_property = clutter_click_action_set_property; - gobject_class->get_property = clutter_click_action_get_property; - - /** - * ClutterClickAction:pressed: - * - * Whether the clickable actor should be in "pressed" state - */ - obj_props[PROP_PRESSED] = - g_param_spec_boolean ("pressed", NULL, NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterClickAction:held: - * - * Whether the clickable actor has the pointer grabbed - */ - obj_props[PROP_HELD] = - g_param_spec_boolean ("held", NULL, NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterClickAction:long-press-duration: - * - * The minimum duration of a press for it to be recognized as a long - * press gesture, in milliseconds. - * - * A value of -1 will make the #ClutterClickAction use the value of - * the [property@Settings:long-press-duration] property. - */ - obj_props[PROP_LONG_PRESS_DURATION] = - g_param_spec_int ("long-press-duration", NULL, NULL, - -1, G_MAXINT, - -1, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterClickAction:long-press-threshold: - * - * The maximum allowed distance that can be covered (on both axes) before - * a long press gesture is cancelled, in pixels. - * - * A value of -1 will make the #ClutterClickAction use the value of - * the [property@Settings:dnd-drag-threshold] property. - */ - obj_props[PROP_LONG_PRESS_THRESHOLD] = - g_param_spec_int ("long-press-threshold", NULL, NULL, - -1, G_MAXINT, - -1, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (gobject_class, - PROP_LAST, - obj_props); - - /** - * ClutterClickAction::clicked: - * @action: the #ClutterClickAction that emitted the signal - * @actor: the #ClutterActor attached to the @action - * - * The signal is emitted when the [class@Actor] to which - * a #ClutterClickAction has been applied should respond to a - * pointer button press and release events - */ - click_signals[CLICKED] = - g_signal_new (I_("clicked"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterClickActionClass, clicked), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_ACTOR); - - /** - * ClutterClickAction::long-press: - * @action: the #ClutterClickAction that emitted the signal - * @actor: the #ClutterActor attached to the @action - * @state: the long press state - * - * The signal is emitted during the long press gesture - * handling. - * - * This signal can be emitted multiple times with different states. - * - * The %CLUTTER_LONG_PRESS_QUERY state will be emitted on button presses, - * and its return value will determine whether the long press handling - * should be initiated. If the signal handlers will return %TRUE, the - * %CLUTTER_LONG_PRESS_QUERY state will be followed either by a signal - * emission with the %CLUTTER_LONG_PRESS_ACTIVATE state if the long press - * constraints were respected, or by a signal emission with the - * %CLUTTER_LONG_PRESS_CANCEL state if the long press was cancelled. - * - * It is possible to forcibly cancel a long press detection using - * [method@ClickAction.release]. - * - * Return value: Only the %CLUTTER_LONG_PRESS_QUERY state uses the - * returned value of the handler; other states will ignore it - */ - click_signals[LONG_PRESS] = - g_signal_new (I_("long-press"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterClickActionClass, long_press), - NULL, NULL, - _clutter_marshal_BOOLEAN__OBJECT_ENUM, - G_TYPE_BOOLEAN, 2, - CLUTTER_TYPE_ACTOR, - CLUTTER_TYPE_LONG_PRESS_STATE); -} - -static void -clutter_click_action_init (ClutterClickAction *self) -{ - ClutterClickActionPrivate *priv = - clutter_click_action_get_instance_private (self); - - priv->long_press_threshold = -1; - priv->long_press_duration = -1; -} - -/** - * clutter_click_action_new: - * - * Creates a new #ClutterClickAction instance - * - * Return value: the newly created #ClutterClickAction - */ -ClutterAction * -clutter_click_action_new (void) -{ - return g_object_new (CLUTTER_TYPE_CLICK_ACTION, NULL); -} - -/** - * clutter_click_action_release: - * @action: a #ClutterClickAction - * - * Emulates a release of the pointer button, which ungrabs the pointer - * and unsets the [property@ClickAction:pressed] state. - * - * This function will also cancel the long press gesture if one was - * initiated. - * - * This function is useful to break a grab, for instance after a certain - * amount of time has passed. - */ -void -clutter_click_action_release (ClutterClickAction *action) -{ - ClutterClickActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_CLICK_ACTION (action)); - - priv = clutter_click_action_get_instance_private (action); - - if (!priv->is_held) - return; - - click_action_cancel_long_press (action); - click_action_set_held (action, FALSE); - click_action_set_pressed (action, FALSE); -} - -/** - * clutter_click_action_get_button: - * @action: a #ClutterClickAction - * - * Retrieves the button that was pressed. - * - * Return value: the button value - */ -guint -clutter_click_action_get_button (ClutterClickAction *action) -{ - ClutterClickActionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0); - - priv = clutter_click_action_get_instance_private (action); - - return priv->press_button; -} - -/** - * clutter_click_action_get_state: - * @action: a #ClutterClickAction - * - * Retrieves the modifier state of the click action. - * - * Return value: the modifier state parameter, or 0 - */ -ClutterModifierType -clutter_click_action_get_state (ClutterClickAction *action) -{ - ClutterClickActionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0); - - priv = clutter_click_action_get_instance_private (action); - - return priv->modifier_state; -} - -/** - * clutter_click_action_get_coords: - * @action: a #ClutterClickAction - * @press_x: (out): return location for the X coordinate, or %NULL - * @press_y: (out): return location for the Y coordinate, or %NULL - * - * Retrieves the screen coordinates of the button press. - */ -void -clutter_click_action_get_coords (ClutterClickAction *action, - gfloat *press_x, - gfloat *press_y) -{ - ClutterClickActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTION (action)); - - priv = clutter_click_action_get_instance_private (action); - - if (press_x != NULL) - *press_x = priv->press_x; - - if (press_y != NULL) - *press_y = priv->press_y; -} diff --git a/mutter/clutter/clutter/clutter-click-action.h b/mutter/clutter/clutter/clutter-click-action.h deleted file mode 100644 index 0ce9b65..0000000 --- a/mutter/clutter/clutter/clutter-click-action.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - * - * Inspired by the StClickable class in GNOME Shell, written by: - * Colin Walters - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-action.h" -#include "clutter/clutter-event.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_CLICK_ACTION (clutter_click_action_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterClickAction, clutter_click_action, - CLUTTER, CLICK_ACTION, ClutterAction); - -typedef struct _ClutterClickActionPrivate ClutterClickActionPrivate; - -/** - * ClutterClickActionClass: - * @clicked: class handler for the #ClutterClickAction::clicked signal - * @long_press: class handler for the #ClutterClickAction::long-press signal - * - * The #ClutterClickActionClass structure - * contains only private data - */ -struct _ClutterClickActionClass -{ - /*< private >*/ - ClutterActionClass parent_class; - - /*< public >*/ - void (* clicked) (ClutterClickAction *action, - ClutterActor *actor); - - gboolean (* long_press) (ClutterClickAction *action, - ClutterActor *actor, - ClutterLongPressState state); -}; - -CLUTTER_EXPORT -ClutterAction * clutter_click_action_new (void); - -CLUTTER_EXPORT -guint clutter_click_action_get_button (ClutterClickAction *action); -CLUTTER_EXPORT -ClutterModifierType clutter_click_action_get_state (ClutterClickAction *action); -CLUTTER_EXPORT -void clutter_click_action_get_coords (ClutterClickAction *action, - gfloat *press_x, - gfloat *press_y); - -CLUTTER_EXPORT -void clutter_click_action_release (ClutterClickAction *action); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-clone.c b/mutter/clutter/clutter/clutter-clone.c deleted file mode 100644 index d230eef..0000000 --- a/mutter/clutter/clutter/clutter-clone.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2008 Intel Corporation. - * - * Authored By: Robert Bragg - * - * 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 . - */ - -/** - * ClutterClone: - * - * An actor that displays a clone of a source actor - * - * #ClutterClone is a [class@Clutter.Actor] which draws with the paint - * function of another actor, scaled to fit its own allocation. - * - * #ClutterClone can be used to efficiently clone any other actor. - * - * #ClutterClone does not require the presence of support for FBOs - * in the underlying GL or GLES implementation. - */ - -#include "config.h" - -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-clone.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-main.h" -#include "clutter/clutter-paint-volume-private.h" -#include "clutter/clutter-private.h" - -#include "cogl/cogl.h" - -typedef struct _ClutterClonePrivate -{ - ClutterActor *clone_source; - float x_scale, y_scale; - - gulong source_destroy_id; -} ClutterClonePrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterClone, clutter_clone, CLUTTER_TYPE_ACTOR) - -enum -{ - PROP_0, - - PROP_SOURCE, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -static void clutter_clone_set_source_internal (ClutterClone *clone, - ClutterActor *source); -static void -clutter_clone_get_preferred_width (ClutterActor *self, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p) -{ - ClutterClonePrivate *priv = - clutter_clone_get_instance_private (CLUTTER_CLONE (self)); - ClutterActor *clone_source = priv->clone_source; - - if (clone_source == NULL) - { - if (min_width_p) - *min_width_p = 0; - - if (natural_width_p) - *natural_width_p = 0; - } - else - clutter_actor_get_preferred_width (clone_source, - for_height, - min_width_p, - natural_width_p); -} - -static void -clutter_clone_get_preferred_height (ClutterActor *self, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p) -{ - ClutterClonePrivate *priv = - clutter_clone_get_instance_private (CLUTTER_CLONE (self)); - ClutterActor *clone_source = priv->clone_source; - - if (clone_source == NULL) - { - if (min_height_p) - *min_height_p = 0; - - if (natural_height_p) - *natural_height_p = 0; - } - else - clutter_actor_get_preferred_height (clone_source, - for_width, - min_height_p, - natural_height_p); -} - -static void -clutter_clone_paint (ClutterActor *actor, - ClutterPaintContext *paint_context) -{ - ClutterClone *self = CLUTTER_CLONE (actor); - ClutterClonePrivate *priv = clutter_clone_get_instance_private (self); - gboolean was_unmapped = FALSE; - - if (priv->clone_source == NULL) - return; - - CLUTTER_NOTE (PAINT, "painting clone actor '%s'", - _clutter_actor_get_debug_name (actor)); - - /* The final bits of magic: - * - We need to override the paint opacity of the actor with our own - * opacity. - * - We need to inform the actor that it's in a clone paint (for the function - * clutter_actor_is_in_clone_paint()) - * - We need to stop clutter_actor_paint applying the model view matrix of - * the clone source actor. - */ - _clutter_actor_set_in_clone_paint (priv->clone_source, TRUE); - clutter_actor_set_opacity_override (priv->clone_source, - clutter_actor_get_paint_opacity (actor)); - _clutter_actor_set_enable_model_view_transform (priv->clone_source, FALSE); - - if (!clutter_actor_is_mapped (priv->clone_source)) - { - _clutter_actor_set_enable_paint_unmapped (priv->clone_source, TRUE); - was_unmapped = TRUE; - } - - /* If the source isn't ultimately parented to a toplevel, it can't be - * realized or painted. - */ - if (clutter_actor_is_realized (priv->clone_source)) - { - CoglFramebuffer *fb = NULL; - - if (priv->x_scale != 1.0 || priv->y_scale != 1.0) - { - fb = clutter_paint_context_get_framebuffer (paint_context); - - cogl_framebuffer_push_matrix (fb); - cogl_framebuffer_scale (fb, priv->x_scale, priv->y_scale, 1.0f); - } - - _clutter_actor_push_clone_paint (); - clutter_actor_paint (priv->clone_source, paint_context); - _clutter_actor_pop_clone_paint (); - - if (fb != NULL) - cogl_framebuffer_pop_matrix (fb); - } - - if (was_unmapped) - _clutter_actor_set_enable_paint_unmapped (priv->clone_source, FALSE); - - _clutter_actor_set_enable_model_view_transform (priv->clone_source, TRUE); - clutter_actor_set_opacity_override (priv->clone_source, -1); - _clutter_actor_set_in_clone_paint (priv->clone_source, FALSE); -} - -static gboolean -clutter_clone_get_paint_volume (ClutterActor *actor, - ClutterPaintVolume *volume) -{ - ClutterClonePrivate *priv = - clutter_clone_get_instance_private (CLUTTER_CLONE (actor)); - const ClutterPaintVolume *source_volume; - - /* if the source is not set the paint volume is defined to be empty */ - if (priv->clone_source == NULL) - return TRUE; - - /* query the volume of the source actor and simply masquerade it as - * the clones volume... */ - source_volume = clutter_actor_get_paint_volume (priv->clone_source); - if (source_volume == NULL) - return FALSE; - - _clutter_paint_volume_set_from_volume (volume, source_volume); - _clutter_paint_volume_set_reference_actor (volume, actor); - - return TRUE; -} - -static gboolean -clutter_clone_has_overlaps (ClutterActor *actor) -{ - ClutterClonePrivate *priv = - clutter_clone_get_instance_private (CLUTTER_CLONE (actor)); - - /* The clone has overlaps iff the source has overlaps */ - - if (priv->clone_source == NULL) - return FALSE; - - return clutter_actor_has_overlaps (priv->clone_source); -} - -static void -clutter_clone_allocate (ClutterActor *self, - const ClutterActorBox *box) -{ - ClutterClonePrivate *priv = - clutter_clone_get_instance_private (CLUTTER_CLONE (self)); - ClutterActorClass *parent_class; - ClutterActorBox source_box; - float x_scale, y_scale; - - /* chain up */ - parent_class = CLUTTER_ACTOR_CLASS (clutter_clone_parent_class); - parent_class->allocate (self, box); - - if (priv->clone_source == NULL) - return; - - /* ClutterActor delays allocating until the actor is shown; however - * we cannot paint it correctly in that case, so force an allocation. - */ - if (clutter_actor_get_parent (priv->clone_source) != NULL && - !clutter_actor_has_allocation (priv->clone_source)) - { - float x = 0.f; - float y = 0.f; - - clutter_actor_get_fixed_position (priv->clone_source, &x, &y); - clutter_actor_allocate_preferred_size (priv->clone_source, x, y); - } - - clutter_actor_get_allocation_box (priv->clone_source, &source_box); - - /* We need to scale what the clone-source actor paints to fill our own - * allocation... - */ - x_scale = clutter_actor_box_get_width (box) - / clutter_actor_box_get_width (&source_box); - y_scale = clutter_actor_box_get_height (box) - / clutter_actor_box_get_height (&source_box); - - if (!G_APPROX_VALUE (priv->x_scale, x_scale, FLT_EPSILON) || - !G_APPROX_VALUE (priv->y_scale, y_scale, FLT_EPSILON)) - { - priv->x_scale = x_scale; - priv->y_scale = y_scale; - clutter_actor_queue_redraw (self); - } - -#if 0 - /* XXX - this is wrong: ClutterClone cannot clone unparented - * actors, as it will break all invariants - */ - - /* we act like a "foster parent" for the source we are cloning; - * if the source has not been parented we have to force an - * allocation on it, so that we can paint it correctly from - * within our paint() implementation. since the actor does not - * have a parent, and thus it won't be painted by the usual - * paint cycle, we can safely give it as much size as it requires - */ - if (clutter_actor_get_parent (priv->clone_source) == NULL) - clutter_actor_allocate_preferred_size (priv->clone_source); -#endif -} - -static void -clutter_clone_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterClone *self = CLUTTER_CLONE (gobject); - - switch (prop_id) - { - case PROP_SOURCE: - clutter_clone_set_source (self, g_value_get_object (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_clone_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterClonePrivate *priv = - clutter_clone_get_instance_private (CLUTTER_CLONE (gobject)); - - switch (prop_id) - { - case PROP_SOURCE: - g_value_set_object (value, priv->clone_source); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_clone_dispose (GObject *gobject) -{ - clutter_clone_set_source_internal (CLUTTER_CLONE (gobject), NULL); - - G_OBJECT_CLASS (clutter_clone_parent_class)->dispose (gobject); -} - -static void -clutter_clone_class_init (ClutterCloneClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - - actor_class->paint = clutter_clone_paint; - actor_class->get_paint_volume = clutter_clone_get_paint_volume; - actor_class->get_preferred_width = clutter_clone_get_preferred_width; - actor_class->get_preferred_height = clutter_clone_get_preferred_height; - actor_class->allocate = clutter_clone_allocate; - actor_class->has_overlaps = clutter_clone_has_overlaps; - - gobject_class->dispose = clutter_clone_dispose; - gobject_class->set_property = clutter_clone_set_property; - gobject_class->get_property = clutter_clone_get_property; - - /** - * ClutterClone:source: - * - * This property specifies the source actor being cloned. - */ - obj_props[PROP_SOURCE] = - g_param_spec_object ("source", NULL, NULL, - CLUTTER_TYPE_ACTOR, - G_PARAM_CONSTRUCT | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); -} - -static void -clutter_clone_init (ClutterClone *self) -{ - ClutterClonePrivate *priv = clutter_clone_get_instance_private (self); - - priv->x_scale = 1.f; - priv->y_scale = 1.f; -} - -/** - * clutter_clone_new: - * @source: a #ClutterActor, or %NULL - * - * Creates a new #ClutterActor which clones @source/ - * - * Return value: the newly created #ClutterClone - */ -ClutterActor * -clutter_clone_new (ClutterActor *source) -{ - return g_object_new (CLUTTER_TYPE_CLONE, "source", source, NULL); -} - -static void -on_source_destroyed (ClutterActor *source, - ClutterClone *self) -{ - clutter_clone_set_source_internal (self, NULL); -} - -static void -clutter_clone_set_source_internal (ClutterClone *self, - ClutterActor *source) -{ - ClutterClonePrivate *priv = clutter_clone_get_instance_private (self); - - if (priv->clone_source == source) - return; - - if (priv->clone_source != NULL) - { - g_clear_signal_handler (&priv->source_destroy_id, priv->clone_source); - _clutter_actor_detach_clone (priv->clone_source, CLUTTER_ACTOR (self)); - g_object_unref (priv->clone_source); - priv->clone_source = NULL; - } - - if (source != NULL) - { - priv->clone_source = g_object_ref (source); - _clutter_actor_attach_clone (priv->clone_source, CLUTTER_ACTOR (self)); - priv->source_destroy_id = g_signal_connect (priv->clone_source, "destroy", - G_CALLBACK (on_source_destroyed), self); - } - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SOURCE]); - - clutter_actor_queue_relayout (CLUTTER_ACTOR (self)); -} - -/** - * clutter_clone_set_source: - * @self: a #ClutterClone - * @source: (allow-none): a #ClutterActor, or %NULL - * - * Sets @source as the source actor to be cloned by @self. - */ -void -clutter_clone_set_source (ClutterClone *self, - ClutterActor *source) -{ - g_return_if_fail (CLUTTER_IS_CLONE (self)); - g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source)); - - clutter_clone_set_source_internal (self, source); - clutter_actor_queue_relayout (CLUTTER_ACTOR (self)); -} - -/** - * clutter_clone_get_source: - * @self: a #ClutterClone - * - * Retrieves the source #ClutterActor being cloned by @self. - * - * Return value: (transfer none): the actor source for the clone - */ -ClutterActor * -clutter_clone_get_source (ClutterClone *self) -{ - ClutterClonePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_CLONE (self), NULL); - - priv = clutter_clone_get_instance_private (self); - return priv->clone_source; -} diff --git a/mutter/clutter/clutter/clutter-clone.h b/mutter/clutter/clutter/clutter-clone.h deleted file mode 100644 index 0dfbb64..0000000 --- a/mutter/clutter/clutter/clutter-clone.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2008 Intel Corporation. - * - * Authored By: Robert Bragg - * - * 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 . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-actor.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_CLONE (clutter_clone_get_type ()) - -/** - * ClutterCloneClass: - * - * The #ClutterCloneClass structure contains only private data - */ -struct _ClutterCloneClass -{ - /*< private >*/ - ClutterActorClass parent_class; -}; - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterClone, - clutter_clone, - CLUTTER, CLONE, - ClutterActor) - -CLUTTER_EXPORT -ClutterActor * clutter_clone_new (ClutterActor *source); -CLUTTER_EXPORT -void clutter_clone_set_source (ClutterClone *self, - ClutterActor *source); -CLUTTER_EXPORT -ClutterActor * clutter_clone_get_source (ClutterClone *self); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-color-state.c b/mutter/clutter/clutter/clutter-color-state.c deleted file mode 100644 index e72749e..0000000 --- a/mutter/clutter/clutter/clutter-color-state.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2022 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Naveen Kumar - */ - -/** - * ClutterColorState: - * - * Color state of each ClutterActor - * - * The #ClutterColorState class contains the colorspace of each color - * states (e.g. sRGB colorspace). - * - * Each [class@Actor] would own such an object. - * - * A single #ClutterColorState object can be shared by multiple [class@Actor] - * or maybe a separate color state for each [class@Actor] (depending on whether - * #ClutterColorState would be statefull or stateless). - * - * #ClutterColorState, if not set during construction, it will default to sRGB - * color state - * - * The #ClutterColorState would have API to get the colorspace, whether the - * actor content is in pq or not, and things like that - */ - -#include "config.h" - -#include "clutter/clutter-color-state.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-private.h" - -enum -{ - PROP_0, - - PROP_COLORSPACE, - - N_PROPS -}; - -static GParamSpec *obj_props[N_PROPS]; - -typedef struct _ClutterColorStatePrivate ClutterColorStatePrivate; - -struct _ClutterColorState -{ - GObject parent_instance; -}; - -struct _ClutterColorStatePrivate -{ - ClutterColorspace colorspace; -}; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterColorState, - clutter_color_state, - G_TYPE_OBJECT) - -ClutterColorspace -clutter_color_state_get_colorspace (ClutterColorState *color_state) -{ - ClutterColorStatePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_COLOR_STATE (color_state), - CLUTTER_COLORSPACE_UNKNOWN); - - priv = clutter_color_state_get_instance_private (color_state); - - return priv->colorspace; -} - -static void -clutter_color_state_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterColorState *color_state = CLUTTER_COLOR_STATE (object); - ClutterColorStatePrivate *priv; - - priv = clutter_color_state_get_instance_private (color_state); - - switch (prop_id) - { - case PROP_COLORSPACE: - priv->colorspace = g_value_get_enum (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_color_state_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterColorState *color_state = CLUTTER_COLOR_STATE (object); - - switch (prop_id) - { - case PROP_COLORSPACE: - g_value_set_enum (value, - clutter_color_state_get_colorspace (color_state)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_color_state_class_init (ClutterColorStateClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->set_property = clutter_color_state_set_property; - gobject_class->get_property = clutter_color_state_get_property; - - /** - * ClutterColorState:colorspace: - * - * Colorspace information of the each color state, - * defaults to sRGB colorspace - */ - obj_props[PROP_COLORSPACE] = - g_param_spec_enum ("colorspace", NULL, NULL, - CLUTTER_TYPE_COLORSPACE, - CLUTTER_COLORSPACE_SRGB, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - g_object_class_install_properties (gobject_class, N_PROPS, obj_props); -} - -static void -clutter_color_state_init (ClutterColorState *color_state) -{ -} - -/** - * clutter_color_state_new: - * - * Create a new ClutterColorState object. - * - * Return value: A new ClutterColorState object. - **/ -ClutterColorState* -clutter_color_state_new (ClutterColorspace colorspace) -{ - return g_object_new (CLUTTER_TYPE_COLOR_STATE, - "colorspace", colorspace, - NULL); -} diff --git a/mutter/clutter/clutter/clutter-color-state.h b/mutter/clutter/clutter/clutter-color-state.h deleted file mode 100644 index 43029c4..0000000 --- a/mutter/clutter/clutter/clutter-color-state.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2022 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Naveen Kumar - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_COLOR_STATE (clutter_color_state_get_type ()) -CLUTTER_EXPORT -G_DECLARE_FINAL_TYPE (ClutterColorState, clutter_color_state, - CLUTTER, COLOR_STATE, - GObject) - -CLUTTER_EXPORT -ClutterColorState * clutter_color_state_new (ClutterColorspace colorspace); - -CLUTTER_EXPORT -ClutterColorspace clutter_color_state_get_colorspace (ClutterColorState *color_state); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-color.c b/mutter/clutter/clutter/clutter-color.c deleted file mode 100644 index 0e35127..0000000 --- a/mutter/clutter/clutter/clutter-color.c +++ /dev/null @@ -1,962 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * 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 . - */ - -#include "config.h" - -#include - -#include - -#include "clutter/clutter-interval.h" -#include "clutter/clutter-main.h" -#include "clutter/clutter-color.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-debug.h" - -/** - * clutter_color_to_hls: - * @color: a #ClutterColor - * @hue: (out): return location for the hue value or %NULL - * @luminance: (out): return location for the luminance value or %NULL - * @saturation: (out): return location for the saturation value or %NULL - * - * Converts @color to the HLS format. - * - * The @hue value is in the 0 .. 360 range. The @luminance and - * @saturation values are in the 0 .. 1 range. - */ -void -clutter_color_to_hls (const ClutterColor *color, - float *hue, - float *luminance, - float *saturation) -{ - float red, green, blue; - float min, max, delta; - float h, l, s; - - g_return_if_fail (color != NULL); - - red = color->red / 255.0; - green = color->green / 255.0; - blue = color->blue / 255.0; - - if (red > green) - { - if (red > blue) - max = red; - else - max = blue; - - if (green < blue) - min = green; - else - min = blue; - } - else - { - if (green > blue) - max = green; - else - max = blue; - - if (red < blue) - min = red; - else - min = blue; - } - - l = (max + min) / 2; - s = 0; - h = 0; - - if (max != min) - { - if (l <= 0.5) - s = (max - min) / (max + min); - else - s = (max - min) / (2.0 - max - min); - - delta = max - min; - - if (red == max) - h = (green - blue) / delta; - else if (green == max) - h = 2.0 + (blue - red) / delta; - else if (blue == max) - h = 4.0 + (red - green) / delta; - - h *= 60; - - if (h < 0) - h += 360.0; - } - - if (hue) - *hue = h; - - if (luminance) - *luminance = l; - - if (saturation) - *saturation = s; -} - -/** - * clutter_color_from_hls: - * @color: (out): return location for a #ClutterColor - * @hue: hue value, in the 0 .. 360 range - * @luminance: luminance value, in the 0 .. 1 range - * @saturation: saturation value, in the 0 .. 1 range - * - * Converts a color expressed in HLS (hue, luminance and saturation) - * values into a #ClutterColor. - */ -void -clutter_color_from_hls (ClutterColor *color, - float hue, - float luminance, - float saturation) -{ - float tmp1, tmp2; - float tmp3[3]; - float clr[3]; - int i; - - hue /= 360.0; - - if (saturation == 0) - { - color->red = color->green = color->blue = (luminance * 255); - - return; - } - - if (luminance <= 0.5) - tmp2 = luminance * (1.0 + saturation); - else - tmp2 = luminance + saturation - (luminance * saturation); - - tmp1 = 2.0 * luminance - tmp2; - - tmp3[0] = hue + 1.0 / 3.0; - tmp3[1] = hue; - tmp3[2] = hue - 1.0 / 3.0; - - for (i = 0; i < 3; i++) - { - if (tmp3[i] < 0) - tmp3[i] += 1.0; - - if (tmp3[i] > 1) - tmp3[i] -= 1.0; - - if (6.0 * tmp3[i] < 1.0) - clr[i] = tmp1 + (tmp2 - tmp1) * tmp3[i] * 6.0; - else if (2.0 * tmp3[i] < 1.0) - clr[i] = tmp2; - else if (3.0 * tmp3[i] < 2.0) - clr[i] = (tmp1 + (tmp2 - tmp1) * ((2.0 / 3.0) - tmp3[i]) * 6.0); - else - clr[i] = tmp1; - } - - color->red = floorf (clr[0] * 255.0 + 0.5); - color->green = floorf (clr[1] * 255.0 + 0.5); - color->blue = floorf (clr[2] * 255.0 + 0.5); -} - -/** - * clutter_color_to_pixel: - * @color: a #ClutterColor - * - * Converts @color into a packed 32 bit integer, containing - * all the four 8 bit channels used by #ClutterColor. - * - * Return value: a packed color - */ -guint32 -clutter_color_to_pixel (const ClutterColor *color) -{ - g_return_val_if_fail (color != NULL, 0); - - return (color->alpha | - color->blue << 8 | - color->green << 16 | - color->red << 24); -} - -/** - * clutter_color_from_pixel: - * @color: (out caller-allocates): return location for a #ClutterColor - * @pixel: a 32 bit packed integer containing a color - * - * Converts @pixel from the packed representation of a four 8 bit channel - * color to a #ClutterColor. - */ -void -clutter_color_from_pixel (ClutterColor *color, - guint32 pixel) -{ - g_return_if_fail (color != NULL); - - color->red = pixel >> 24; - color->green = (pixel >> 16) & 0xff; - color->blue = (pixel >> 8) & 0xff; - color->alpha = pixel & 0xff; -} - -static inline void -skip_whitespace (gchar **str) -{ - while (g_ascii_isspace (**str)) - *str += 1; -} - -static inline void -parse_rgb_value (gchar *str, - guint8 *color, - gchar **endp) -{ - gdouble number; - gchar *p; - - skip_whitespace (&str); - - number = g_ascii_strtod (str, endp); - - p = *endp; - - skip_whitespace (&p); - - if (*p == '%') - { - *endp = (gchar *) (p + 1); - - *color = CLAMP (number / 100.0, 0.0, 1.0) * 255; - } - else - *color = CLAMP (number, 0, 255); -} - -static gboolean -parse_rgba (ClutterColor *color, - gchar *str, - gboolean has_alpha) -{ - skip_whitespace (&str); - - if (*str != '(') - return FALSE; - - str += 1; - - /* red */ - parse_rgb_value (str, &color->red, &str); - skip_whitespace (&str); - if (*str != ',') - return FALSE; - - str += 1; - - /* green */ - parse_rgb_value (str, &color->green, &str); - skip_whitespace (&str); - if (*str != ',') - return FALSE; - - str += 1; - - /* blue */ - parse_rgb_value (str, &color->blue, &str); - skip_whitespace (&str); - - /* alpha (optional); since the alpha channel value can only - * be between 0 and 1 we don't use the parse_rgb_value() - * function - */ - if (has_alpha) - { - gdouble number; - - if (*str != ',') - return FALSE; - - str += 1; - - skip_whitespace (&str); - number = g_ascii_strtod (str, &str); - - color->alpha = CLAMP (number * 255.0, 0, 255); - } - else - color->alpha = 255; - - skip_whitespace (&str); - if (*str != ')') - return FALSE; - - return TRUE; -} - -static gboolean -parse_hsla (ClutterColor *color, - gchar *str, - gboolean has_alpha) -{ - gdouble number; - gdouble h, l, s; - - skip_whitespace (&str); - - if (*str != '(') - return FALSE; - - str += 1; - - /* hue */ - skip_whitespace (&str); - /* we don't do any angle normalization here because - * clutter_color_from_hls() will do it for us - */ - number = g_ascii_strtod (str, &str); - skip_whitespace (&str); - if (*str != ',') - return FALSE; - - h = number; - - str += 1; - - /* saturation */ - skip_whitespace (&str); - number = g_ascii_strtod (str, &str); - skip_whitespace (&str); - if (*str != '%') - return FALSE; - - str += 1; - - s = CLAMP (number / 100.0, 0.0, 1.0); - skip_whitespace (&str); - if (*str != ',') - return FALSE; - - str += 1; - - /* luminance */ - skip_whitespace (&str); - number = g_ascii_strtod (str, &str); - skip_whitespace (&str); - if (*str != '%') - return FALSE; - - str += 1; - - l = CLAMP (number / 100.0, 0.0, 1.0); - skip_whitespace (&str); - - /* alpha (optional); since the alpha channel value can only - * be between 0 and 1 we don't use the parse_rgb_value() - * function - */ - if (has_alpha) - { - if (*str != ',') - return FALSE; - - str += 1; - - skip_whitespace (&str); - number = g_ascii_strtod (str, &str); - - color->alpha = CLAMP (number * 255.0, 0, 255); - } - else - color->alpha = 255; - - skip_whitespace (&str); - if (*str != ')') - return FALSE; - - clutter_color_from_hls (color, h, l, s); - - return TRUE; -} - -/** - * clutter_color_from_string: - * @color: (out caller-allocates): return location for a #ClutterColor - * @str: a string specifying a color - * - * Parses a string definition of a color, filling the #ClutterColor.red, - * #ClutterColor.green, #ClutterColor.blue and #ClutterColor.alpha fields - * of @color. - * - * The @color is not allocated. - * - * The format of @str can be either one of: - * - * - a standard name (as taken from the X11 rgb.txt file) - * - an hexadecimal value in the form: `#rgb`, `#rrggbb`, `#rgba`, or `#rrggbbaa` - * - a RGB color in the form: `rgb(r, g, b)` - * - a RGB color in the form: `rgba(r, g, b, a)` - * - a HSL color in the form: `hsl(h, s, l)` - * -a HSL color in the form: `hsla(h, s, l, a)` - * - * where 'r', 'g', 'b' and 'a' are (respectively) the red, green, blue color - * intensities and the opacity. The 'h', 's' and 'l' are (respectively) the - * hue, saturation and luminance values. - * - * In the rgb() and rgba() formats, the 'r', 'g', and 'b' values are either - * integers between 0 and 255, or percentage values in the range between 0% - * and 100%; the percentages require the '%' character. The 'a' value, if - * specified, can only be a floating point value between 0.0 and 1.0. - * - * In the hls() and hlsa() formats, the 'h' value (hue) is an angle between - * 0 and 360.0 degrees; the 'l' and 's' values (luminance and saturation) are - * percentage values in the range between 0% and 100%. The 'a' value, if specified, - * can only be a floating point value between 0.0 and 1.0. - * - * Whitespace inside the definitions is ignored; no leading whitespace - * is allowed. - * - * If the alpha component is not specified then it is assumed to be set to - * be fully opaque. - * - * Return value: %TRUE if parsing succeeded, and %FALSE otherwise - */ -gboolean -clutter_color_from_string (ClutterColor *color, - const gchar *str) -{ - PangoColor pango_color = { 0, }; - - g_return_val_if_fail (color != NULL, FALSE); - g_return_val_if_fail (str != NULL, FALSE); - - if (strncmp (str, "rgb", 3) == 0) - { - gchar *s = (gchar *) str; - gboolean res; - - if (strncmp (str, "rgba", 4) == 0) - res = parse_rgba (color, s + 4, TRUE); - else - res = parse_rgba (color, s + 3, FALSE); - - return res; - } - - if (strncmp (str, "hsl", 3) == 0) - { - gchar *s = (gchar *) str; - gboolean res; - - if (strncmp (str, "hsla", 4) == 0) - res = parse_hsla (color, s + 4, TRUE); - else - res = parse_hsla (color, s + 3, FALSE); - - return res; - } - - /* if the string contains a color encoded using the hexadecimal - * notations (#rrggbbaa or #rgba) we attempt a rough pass at - * parsing the color ourselves, as we need the alpha channel that - * Pango can't retrieve. - */ - if (str[0] == '#' && str[1] != '\0') - { - gsize length = strlen (str + 1); - gint32 result; - - if (sscanf (str + 1, "%x", &result) == 1) - { - switch (length) - { - case 8: /* rrggbbaa */ - color->red = (result >> 24) & 0xff; - color->green = (result >> 16) & 0xff; - color->blue = (result >> 8) & 0xff; - - color->alpha = result & 0xff; - - return TRUE; - - case 6: /* #rrggbb */ - color->red = (result >> 16) & 0xff; - color->green = (result >> 8) & 0xff; - color->blue = result & 0xff; - - color->alpha = 0xff; - - return TRUE; - - case 4: /* #rgba */ - color->red = ((result >> 12) & 0xf); - color->green = ((result >> 8) & 0xf); - color->blue = ((result >> 4) & 0xf); - color->alpha = result & 0xf; - - color->red = (color->red << 4) | color->red; - color->green = (color->green << 4) | color->green; - color->blue = (color->blue << 4) | color->blue; - color->alpha = (color->alpha << 4) | color->alpha; - - return TRUE; - - case 3: /* #rgb */ - color->red = ((result >> 8) & 0xf); - color->green = ((result >> 4) & 0xf); - color->blue = result & 0xf; - - color->red = (color->red << 4) | color->red; - color->green = (color->green << 4) | color->green; - color->blue = (color->blue << 4) | color->blue; - - color->alpha = 0xff; - - return TRUE; - - default: - return FALSE; - } - } - } - - /* fall back to pango for X11-style named colors; see: - * - * http://en.wikipedia.org/wiki/X11_color_names - * - * for a list. at some point we might even ship with our own list generated - * from X11/rgb.txt, like we generate the key symbols. - */ - if (pango_color_parse (&pango_color, str)) - { - color->red = pango_color.red; - color->green = pango_color.green; - color->blue = pango_color.blue; - - color->alpha = 0xff; - - return TRUE; - } - - return FALSE; -} - -/** - * clutter_color_to_string: - * @color: a #ClutterColor - * - * Returns a textual specification of @color in the hexadecimal form - * `#rrggbbaa`, where `r`, `g`, `b` and `a` are - * hexadecimal digits representing the red, green, blue and alpha components - * respectively. - * - * Return value: (transfer full): a newly-allocated text string - */ -gchar * -clutter_color_to_string (const ClutterColor *color) -{ - g_return_val_if_fail (color != NULL, NULL); - - return g_strdup_printf ("#%02x%02x%02x%02x", - color->red, - color->green, - color->blue, - color->alpha); -} - -/** - * clutter_color_equal: - * @v1: (type Clutter.Color): a #ClutterColor - * @v2: (type Clutter.Color): a #ClutterColor - * - * Compares two `ClutterColor`s and checks if they are the same. - * - * This function can be passed to g_hash_table_new() as the @key_equal_func - * parameter, when using `ClutterColor`s as keys in a #GHashTable. - * - * Return value: %TRUE if the two colors are the same. - */ -gboolean -clutter_color_equal (gconstpointer v1, - gconstpointer v2) -{ - const ClutterColor *a, *b; - - g_return_val_if_fail (v1 != NULL, FALSE); - g_return_val_if_fail (v2 != NULL, FALSE); - - if (v1 == v2) - return TRUE; - - a = v1; - b = v2; - - return (a->red == b->red && - a->green == b->green && - a->blue == b->blue && - a->alpha == b->alpha); -} - -/** - * clutter_color_hash: - * @v: (type Clutter.Color): a #ClutterColor - * - * Converts a #ClutterColor to a hash value. - * - * This function can be passed to g_hash_table_new() as the @hash_func - * parameter, when using `ClutterColor`s as keys in a #GHashTable. - * - * Return value: a hash value corresponding to the color - */ -guint -clutter_color_hash (gconstpointer v) -{ - return clutter_color_to_pixel ((const ClutterColor *) v); -} - -/** - * clutter_color_interpolate: - * @initial: the initial #ClutterColor - * @final: the final #ClutterColor - * @progress: the interpolation progress - * @result: (out): return location for the interpolation - * - * Interpolates between @initial and @final `ClutterColor`s - * using @progress - */ -void -clutter_color_interpolate (const ClutterColor *initial, - const ClutterColor *final, - gdouble progress, - ClutterColor *result) -{ - g_return_if_fail (initial != NULL); - g_return_if_fail (final != NULL); - g_return_if_fail (result != NULL); - - result->red = initial->red + (final->red - initial->red) * progress; - result->green = initial->green + (final->green - initial->green) * progress; - result->blue = initial->blue + (final->blue - initial->blue) * progress; - result->alpha = initial->alpha + (final->alpha - initial->alpha) * progress; -} - -static gboolean -clutter_color_progress (const GValue *a, - const GValue *b, - gdouble progress, - GValue *retval) -{ - const ClutterColor *a_color = clutter_value_get_color (a); - const ClutterColor *b_color = clutter_value_get_color (b); - ClutterColor res = { 0, }; - - clutter_color_interpolate (a_color, b_color, progress, &res); - clutter_value_set_color (retval, &res); - - return TRUE; -} - -/** - * clutter_color_copy: - * @color: a #ClutterColor - * - * Makes a copy of the color structure. The result must be - * freed using [method@Clutter.Color.free]. - * - * Return value: (transfer full): an allocated copy of @color. - */ -ClutterColor * -clutter_color_copy (const ClutterColor *color) -{ - if (G_LIKELY (color != NULL)) - return g_memdup2 (color, sizeof (ClutterColor)); - - return NULL; -} - -/** - * clutter_color_free: - * @color: a #ClutterColor - * - * Frees a color structure created with [method@Clutter.Color.copy]. - */ -void -clutter_color_free (ClutterColor *color) -{ - if (G_LIKELY (color != NULL)) - g_free (color); -} - -/** - * clutter_color_new: - * @red: red component of the color, between 0 and 255 - * @green: green component of the color, between 0 and 255 - * @blue: blue component of the color, between 0 and 255 - * @alpha: alpha component of the color, between 0 and 255 - * - * Creates a new #ClutterColor with the given values. - * - * This function is the equivalent of: - * - * ```c - * clutter_color_init (clutter_color_alloc (), red, green, blue, alpha); - * ``` - * - * Return value: (transfer full): the newly allocated color. - * Use [method@Clutter.Color.free] when done - */ -ClutterColor * -clutter_color_new (guint8 red, - guint8 green, - guint8 blue, - guint8 alpha) -{ - return clutter_color_init (clutter_color_alloc (), - red, - green, - blue, - alpha); -} - -/** - * clutter_color_alloc: (constructor) - * - * Allocates a new, transparent black #ClutterColor. - * - * Return value: (transfer full): the newly allocated #ClutterColor; use - * [method@Clutter.Color.free] to free its resources - */ -ClutterColor * -clutter_color_alloc (void) -{ - return g_new0 (ClutterColor, 1); -} - -/** - * clutter_color_init: - * @color: a #ClutterColor - * @red: red component of the color, between 0 and 255 - * @green: green component of the color, between 0 and 255 - * @blue: blue component of the color, between 0 and 255 - * @alpha: alpha component of the color, between 0 and 255 - * - * Initializes @color with the given values. - * - * Return value: (transfer none): the initialized #ClutterColor - */ -ClutterColor * -clutter_color_init (ClutterColor *color, - guint8 red, - guint8 green, - guint8 blue, - guint8 alpha) -{ - g_return_val_if_fail (color != NULL, NULL); - - color->red = red; - color->green = green; - color->blue = blue; - color->alpha = alpha; - - return color; -} - -static void -clutter_value_transform_color_string (const GValue *src, - GValue *dest) -{ - const ClutterColor *color = g_value_get_boxed (src); - - if (color) - { - gchar *string = clutter_color_to_string (color); - - g_value_take_string (dest, string); - } - else - g_value_set_string (dest, NULL); -} - -static void -clutter_value_transform_string_color (const GValue *src, - GValue *dest) -{ - const char *str = g_value_get_string (src); - - if (str) - { - ClutterColor color = { 0, }; - - clutter_color_from_string (&color, str); - - clutter_value_set_color (dest, &color); - } - else - clutter_value_set_color (dest, NULL); -} - -G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterColor, clutter_color, - clutter_color_copy, - clutter_color_free, - CLUTTER_REGISTER_VALUE_TRANSFORM_TO (G_TYPE_STRING, clutter_value_transform_color_string) - CLUTTER_REGISTER_VALUE_TRANSFORM_FROM (G_TYPE_STRING, clutter_value_transform_string_color) - CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_color_progress)); - -/** - * clutter_value_set_color: - * @value: a #GValue initialized to #CLUTTER_TYPE_COLOR - * @color: the color to set - * - * Sets @value to @color. - */ -void -clutter_value_set_color (GValue *value, - const ClutterColor *color) -{ - g_return_if_fail (CLUTTER_VALUE_HOLDS_COLOR (value)); - - g_value_set_boxed (value, color); -} - -/** - * clutter_value_get_color: - * @value: a #GValue initialized to #CLUTTER_TYPE_COLOR - * - * Gets the #ClutterColor contained in @value. - * - * Return value: (transfer none): the color inside the passed #GValue - */ -const ClutterColor * -clutter_value_get_color (const GValue *value) -{ - g_return_val_if_fail (CLUTTER_VALUE_HOLDS_COLOR (value), NULL); - - return g_value_get_boxed (value); -} - -static void -param_color_init (GParamSpec *pspec) -{ - ClutterParamSpecColor *cspec = CLUTTER_PARAM_SPEC_COLOR (pspec); - - cspec->default_value = NULL; -} - -static void -param_color_finalize (GParamSpec *pspec) -{ - ClutterParamSpecColor *cspec = CLUTTER_PARAM_SPEC_COLOR (pspec); - - clutter_color_free (cspec->default_value); -} - -static void -param_color_set_default (GParamSpec *pspec, - GValue *value) -{ - const ClutterColor *default_value = - CLUTTER_PARAM_SPEC_COLOR (pspec)->default_value; - clutter_value_set_color (value, default_value); -} - -static gint -param_color_values_cmp (GParamSpec *pspec, - const GValue *value1, - const GValue *value2) -{ - const ClutterColor *color1 = g_value_get_boxed (value1); - const ClutterColor *color2 = g_value_get_boxed (value2); - int pixel1, pixel2; - - if (color1 == NULL) - return color2 == NULL ? 0 : -1; - - pixel1 = clutter_color_to_pixel (color1); - pixel2 = clutter_color_to_pixel (color2); - - if (pixel1 < pixel2) - return -1; - else if (pixel1 == pixel2) - return 0; - else - return 1; -} - -GType -clutter_param_color_get_type (void) -{ - static GType pspec_type = 0; - - if (G_UNLIKELY (pspec_type == 0)) - { - const GParamSpecTypeInfo pspec_info = { - sizeof (ClutterParamSpecColor), - 16, - param_color_init, - CLUTTER_TYPE_COLOR, - param_color_finalize, - param_color_set_default, - NULL, - param_color_values_cmp, - }; - - pspec_type = g_param_type_register_static (I_("ClutterParamSpecColor"), - &pspec_info); - } - - return pspec_type; -} - -/** - * clutter_param_spec_color: (skip) - * @name: name of the property - * @nick: short name - * @blurb: description (can be translatable) - * @default_value: default value - * @flags: flags for the param spec - * - * Creates a #GParamSpec for properties using #ClutterColor. - * - * Return value: the newly created #GParamSpec - */ -GParamSpec * -clutter_param_spec_color (const gchar *name, - const gchar *nick, - const gchar *blurb, - const ClutterColor *default_value, - GParamFlags flags) -{ - ClutterParamSpecColor *cspec; - - cspec = g_param_spec_internal (CLUTTER_TYPE_PARAM_COLOR, - name, nick, blurb, flags); - - cspec->default_value = clutter_color_copy (default_value); - - return G_PARAM_SPEC (cspec); -} diff --git a/mutter/clutter/clutter/clutter-color.h b/mutter/clutter/clutter/clutter-color.h deleted file mode 100644 index 3414354..0000000 --- a/mutter/clutter/clutter/clutter-color.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By: Matthew Allum - * Emmanuele Bassi - * - * Copyright (C) 2006, 2007, 2008 OpenedHand - * Copyright (C) 2009 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_COLOR (clutter_color_get_type ()) - -/** - * ClutterColor: - * @red: red component, between 0 and 255 - * @green: green component, between 0 and 255 - * @blue: blue component, between 0 and 255 - * @alpha: alpha component, between 0 and 255 - * - * A simple type for representing colors. - * - * A #ClutterColor is expressed as a 4-tuple of values ranging from - * zero to 255, one for each color channel plus one for the alpha. - * - * The alpha channel is fully opaque at 255 and fully transparent at 0. - */ -struct _ClutterColor -{ - /*< public >*/ - guint8 red; - guint8 green; - guint8 blue; - - guint8 alpha; -}; - -/** - * CLUTTER_COLOR_INIT: - * @r: value for the red channel, between 0 and 255 - * @g: value for the green channel, between 0 and 255 - * @b: value for the blue channel, between 0 and 255 - * @a: value for the alpha channel, between 0 and 255 - * - * A macro that initializes a #ClutterColor, to be used when declaring it. - */ -#define CLUTTER_COLOR_INIT(_r, _g, _b, _a) \ - (ClutterColor) { \ - .red = (_r), \ - .green = (_g), \ - .blue = (_b), \ - .alpha = (_a) \ - } - -CLUTTER_EXPORT -GType clutter_color_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterColor *clutter_color_new (guint8 red, - guint8 green, - guint8 blue, - guint8 alpha); -CLUTTER_EXPORT -ClutterColor *clutter_color_alloc (void); -CLUTTER_EXPORT -ClutterColor *clutter_color_init (ClutterColor *color, - guint8 red, - guint8 green, - guint8 blue, - guint8 alpha); -CLUTTER_EXPORT -ClutterColor *clutter_color_copy (const ClutterColor *color); -CLUTTER_EXPORT -void clutter_color_free (ClutterColor *color); - -CLUTTER_EXPORT -gchar * clutter_color_to_string (const ClutterColor *color); -CLUTTER_EXPORT -gboolean clutter_color_from_string (ClutterColor *color, - const gchar *str); - -CLUTTER_EXPORT -void clutter_color_to_hls (const ClutterColor *color, - gfloat *hue, - gfloat *luminance, - gfloat *saturation); -CLUTTER_EXPORT -void clutter_color_from_hls (ClutterColor *color, - gfloat hue, - gfloat luminance, - gfloat saturation); - -CLUTTER_EXPORT -guint32 clutter_color_to_pixel (const ClutterColor *color); -CLUTTER_EXPORT -void clutter_color_from_pixel (ClutterColor *color, - guint32 pixel); - -CLUTTER_EXPORT -guint clutter_color_hash (gconstpointer v); -CLUTTER_EXPORT -gboolean clutter_color_equal (gconstpointer v1, - gconstpointer v2); - -CLUTTER_EXPORT -void clutter_color_interpolate (const ClutterColor *initial, - const ClutterColor *final, - gdouble progress, - ClutterColor *result); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColor, clutter_color_free) - -#define CLUTTER_TYPE_PARAM_COLOR (clutter_param_color_get_type ()) -#define CLUTTER_PARAM_SPEC_COLOR(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), CLUTTER_TYPE_PARAM_COLOR, ClutterParamSpecColor)) -#define CLUTTER_IS_PARAM_SPEC_COLOR(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), CLUTTER_TYPE_PARAM_COLOR)) - -/** - * CLUTTER_VALUE_HOLDS_COLOR: - * @x: a #GValue - * - * Evaluates to %TRUE if @x holds a `ClutterColor`. - */ -#define CLUTTER_VALUE_HOLDS_COLOR(x) (G_VALUE_HOLDS ((x), CLUTTER_TYPE_COLOR)) - -typedef struct _ClutterParamSpecColor ClutterParamSpecColor; - -/** - * ClutterParamSpecColor: (skip) - * @default_value: default color value - * - * A #GParamSpec subclass for defining properties holding - * a #ClutterColor. - */ -struct _ClutterParamSpecColor -{ - /*< private >*/ - GParamSpec parent_instance; - - /*< public >*/ - ClutterColor *default_value; -}; - -CLUTTER_EXPORT -void clutter_value_set_color (GValue *value, - const ClutterColor *color); -CLUTTER_EXPORT -const ClutterColor * clutter_value_get_color (const GValue *value); - -CLUTTER_EXPORT -GType clutter_param_color_get_type (void) G_GNUC_CONST; -CLUTTER_EXPORT -GParamSpec * clutter_param_spec_color (const gchar *name, - const gchar *nick, - const gchar *blurb, - const ClutterColor *default_value, - GParamFlags flags); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-colorize-effect.c b/mutter/clutter/clutter/clutter-colorize-effect.c deleted file mode 100644 index 3d64314..0000000 --- a/mutter/clutter/clutter/clutter-colorize-effect.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterColorizeEffect: - * - * A colorization effect - * - * #ClutterColorizeEffect is a sub-class of #ClutterEffect that - * colorizes an actor with the given tint. - */ - -#include "config.h" - -#include "clutter/clutter-colorize-effect.h" - -#include "cogl/cogl.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-private.h" - -typedef struct _ClutterColorizeEffectPrivate -{ - ClutterOffscreenEffect parent_instance; - - /* the tint of the colorization */ - ClutterColor tint; - - gint tint_uniform; - - CoglPipeline *pipeline; -} ClutterColorizeEffectPrivate; - -/* the magic gray vec3 has been taken from the NTSC conversion weights - * as defined by: - * - * "OpenGL Superbible, 4th Edition" - * -- Richard S. Wright Jr, Benjamin Lipchak, Nicholas Haemel - * Addison-Wesley - */ -static const gchar *colorize_glsl_declarations = -"uniform vec3 tint;\n"; - -static const gchar *colorize_glsl_source = -"float gray = dot (cogl_color_out.rgb, vec3 (0.299, 0.587, 0.114));\n" -"cogl_color_out.rgb = gray * tint;\n"; - -/* a lame sepia */ -static const ClutterColor default_tint = { 255, 204, 153, 255 }; - -enum -{ - PROP_0, - - PROP_TINT, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterColorizeEffect, - clutter_colorize_effect, - CLUTTER_TYPE_OFFSCREEN_EFFECT); - -static CoglPipeline * -clutter_colorize_effect_create_pipeline (ClutterOffscreenEffect *effect, - CoglTexture *texture) -{ - ClutterColorizeEffect *colorize_effect = CLUTTER_COLORIZE_EFFECT (effect); - ClutterColorizeEffectPrivate *priv = - clutter_colorize_effect_get_instance_private (colorize_effect); - - cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture); - - return g_object_ref (priv->pipeline); -} - -static void -clutter_colorize_effect_dispose (GObject *gobject) -{ - ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (gobject); - ClutterColorizeEffectPrivate *priv = - clutter_colorize_effect_get_instance_private (self); - - g_clear_object (&priv->pipeline); - - G_OBJECT_CLASS (clutter_colorize_effect_parent_class)->dispose (gobject); -} - -static void -clutter_colorize_effect_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterColorizeEffect *effect = CLUTTER_COLORIZE_EFFECT (gobject); - - switch (prop_id) - { - case PROP_TINT: - clutter_colorize_effect_set_tint (effect, - clutter_value_get_color (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_colorize_effect_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterColorizeEffect *effect = CLUTTER_COLORIZE_EFFECT (gobject); - ClutterColorizeEffectPrivate *priv = - clutter_colorize_effect_get_instance_private (effect); - - switch (prop_id) - { - case PROP_TINT: - clutter_value_set_color (value, &priv->tint); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_colorize_effect_class_init (ClutterColorizeEffectClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterOffscreenEffectClass *offscreen_class; - - offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); - offscreen_class->create_pipeline = clutter_colorize_effect_create_pipeline; - - gobject_class->set_property = clutter_colorize_effect_set_property; - gobject_class->get_property = clutter_colorize_effect_get_property; - gobject_class->dispose = clutter_colorize_effect_dispose; - - /** - * ClutterColorizeEffect:tint: - * - * The tint to apply to the actor - */ - obj_props[PROP_TINT] = - clutter_param_spec_color ("tint", NULL, NULL, - &default_tint, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); -} - -static void -update_tint_uniform (ClutterColorizeEffect *self) -{ - ClutterColorizeEffectPrivate *priv = - clutter_colorize_effect_get_instance_private (self); - if (priv->tint_uniform > -1) - { - float tint[3] = { - priv->tint.red / 255.0, - priv->tint.green / 255.0, - priv->tint.blue / 255.0 - }; - - cogl_pipeline_set_uniform_float (priv->pipeline, - priv->tint_uniform, - 3, /* n_components */ - 1, /* count */ - tint); - } -} - -static void -clutter_colorize_effect_init (ClutterColorizeEffect *self) -{ - ClutterColorizeEffectClass *klass = CLUTTER_COLORIZE_EFFECT_GET_CLASS (self); - ClutterColorizeEffectPrivate *priv = - clutter_colorize_effect_get_instance_private (self); - if (G_UNLIKELY (klass->base_pipeline == NULL)) - { - CoglSnippet *snippet; - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - - klass->base_pipeline = cogl_pipeline_new (ctx); - - snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, - colorize_glsl_declarations, - colorize_glsl_source); - cogl_pipeline_add_snippet (klass->base_pipeline, snippet); - g_object_unref (snippet); - - cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0); - } - - priv->pipeline = cogl_pipeline_copy (klass->base_pipeline); - - priv->tint_uniform = - cogl_pipeline_get_uniform_location (priv->pipeline, "tint"); - - priv->tint = default_tint; - - update_tint_uniform (self); -} - -/** - * clutter_colorize_effect_new: - * @tint: the color to be used - * - * Creates a new #ClutterColorizeEffect to be used with - * [method@Clutter.Actor.add_effect] - * - * Return value: the newly created #ClutterColorizeEffect or %NULL - */ -ClutterEffect * -clutter_colorize_effect_new (const ClutterColor *tint) -{ - return g_object_new (CLUTTER_TYPE_COLORIZE_EFFECT, - "tint", tint, - NULL); -} - -/** - * clutter_colorize_effect_set_tint: - * @effect: a #ClutterColorizeEffect - * @tint: the color to be used - * - * Sets the tint to be used when colorizing - */ -void -clutter_colorize_effect_set_tint (ClutterColorizeEffect *effect, - const ClutterColor *tint) -{ - ClutterColorizeEffectPrivate *priv; - - g_return_if_fail (CLUTTER_IS_COLORIZE_EFFECT (effect)); - - priv = clutter_colorize_effect_get_instance_private (effect); - priv->tint = *tint; - - update_tint_uniform (effect); - - clutter_effect_queue_repaint (CLUTTER_EFFECT (effect)); - - g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_TINT]); -} - -/** - * clutter_colorize_effect_get_tint: - * @effect: a #ClutterColorizeEffect - * @tint: (out caller-allocates): return location for the color used - * - * Retrieves the tint used by @effect - */ -void -clutter_colorize_effect_get_tint (ClutterColorizeEffect *effect, - ClutterColor *tint) -{ - ClutterColorizeEffectPrivate *priv; - - g_return_if_fail (CLUTTER_IS_COLORIZE_EFFECT (effect)); - g_return_if_fail (tint != NULL); - - priv = clutter_colorize_effect_get_instance_private (effect); - *tint = priv->tint; -} diff --git a/mutter/clutter/clutter/clutter-colorize-effect.h b/mutter/clutter/clutter/clutter-colorize-effect.h deleted file mode 100644 index 5f5f46a..0000000 --- a/mutter/clutter/clutter/clutter-colorize-effect.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-color.h" -#include "clutter/clutter-effect.h" -#include "clutter/clutter-offscreen-effect.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_COLORIZE_EFFECT (clutter_colorize_effect_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterColorizeEffect, - clutter_colorize_effect, - CLUTTER, COLORIZE_EFFECT, - ClutterOffscreenEffect) - -struct _ClutterColorizeEffectClass -{ - ClutterOffscreenEffectClass parent_class; - - CoglPipeline *base_pipeline; -}; - -CLUTTER_EXPORT -ClutterEffect *clutter_colorize_effect_new (const ClutterColor *tint); - -CLUTTER_EXPORT -void clutter_colorize_effect_set_tint (ClutterColorizeEffect *effect, - const ClutterColor *tint); -CLUTTER_EXPORT -void clutter_colorize_effect_get_tint (ClutterColorizeEffect *effect, - ClutterColor *tint); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-constraint-private.h b/mutter/clutter/clutter/clutter-constraint-private.h deleted file mode 100644 index c533e7f..0000000 --- a/mutter/clutter/clutter/clutter-constraint-private.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#include "clutter/clutter-constraint.h" - -G_BEGIN_DECLS - -gboolean clutter_constraint_update_allocation (ClutterConstraint *constraint, - ClutterActor *actor, - ClutterActorBox *allocation); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-constraint.c b/mutter/clutter/clutter/clutter-constraint.c deleted file mode 100644 index 237d1a3..0000000 --- a/mutter/clutter/clutter/clutter-constraint.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterConstraint: - * - * Abstract class for constraints on position or size - * - * #ClutterConstraint is a base abstract class for modifiers of a #ClutterActor - * position or size. - * - * A #ClutterConstraint sub-class should contain the logic for modifying - * the position or size of the #ClutterActor to which it is applied, by - * updating the actor's allocation. Each #ClutterConstraint can change the - * allocation of the actor to which they are applied by overriding the - * [vfunc@Clutter.Constraint.update_allocation] virtual function. - * - * ## Using Constraints - * - * Constraints can be used with fixed layout managers, like - * #ClutterFixedLayout, or with actors implicitly using a fixed layout - * manager, like #ClutterGroup and #ClutterStage. - * - * Constraints provide a way to build user interfaces by using - * relations between #ClutterActors, without explicit fixed - * positioning and sizing, similarly to how fluid layout managers like - * #ClutterBoxLayout lay out their children. - * - * Constraints are attached to a #ClutterActor, and are available - * for inspection using [method@Clutter.Actor.get_constraints]. - * - * Clutter provides different implementation of the #ClutterConstraint - * abstract class, for instance: - * - * - #ClutterAlignConstraint, a constraint that can be used to align - * an actor to another one on either the horizontal or the vertical - * axis, using a normalized value between 0 and 1. - * - #ClutterBindConstraint, a constraint binds the X, Y, width or height - * of an actor to the corresponding position or size of a source actor, - * with or without an offset. - * - #ClutterSnapConstraint, a constraint that "snaps" together the edges - * of two #ClutterActors; if an actor uses two constraints on both its - * horizontal or vertical edges then it can also expand to fit the empty - * space. - * - * It is important to note that Clutter does not avoid loops or - * competing constraints; if two or more #ClutterConstraints - * are operating on the same positional or dimensional attributes of an - * actor, or if the constraints on two different actors depend on each - * other, then the behavior is undefined. - * - * ## Implementing a ClutterConstraint - * - * Creating a sub-class of #ClutterConstraint requires the - * implementation of the [vfunc@Clutter.Constraint.update_allocation] - * virtual function. - * - * The `update_allocation()` virtual function is called during the - * allocation sequence of a #ClutterActor, and allows any #ClutterConstraint - * attached to that actor to modify the allocation before it is passed to - * the actor's #ClutterActorClass.allocate() implementation. - * - * The #ClutterActorBox passed to the `update_allocation()` implementation - * contains the original allocation of the #ClutterActor, plus the eventual - * modifications applied by the other #ClutterConstraints, in the same order - * the constraints have been applied to the actor. - * - * It is not necessary for a #ClutterConstraint sub-class to chain - * up to the parent's implementation. - * - * If a #ClutterConstraint is parametrized - i.e. if it contains - * properties that affect the way the constraint is implemented - it should - * call clutter_actor_queue_relayout() on the actor to which it is attached - * to whenever any parameter is changed. The actor to which it is attached - * can be recovered at any point using clutter_actor_meta_get_actor(). - */ - -#include "config.h" - -#include - -#include "clutter/clutter-constraint-private.h" - -#include "clutter/clutter-actor.h" -#include "clutter/clutter-actor-meta-private.h" -#include "clutter/clutter-private.h" - -G_DEFINE_ABSTRACT_TYPE (ClutterConstraint, - clutter_constraint, - CLUTTER_TYPE_ACTOR_META); - -static void -constraint_update_allocation (ClutterConstraint *constraint, - ClutterActor *actor, - ClutterActorBox *allocation) -{ -} - -static void -constraint_update_preferred_size (ClutterConstraint *constraint, - ClutterActor *actor, - ClutterOrientation direction, - float for_size, - float *minimum_size, - float *natural_size) -{ -} - -static void -clutter_constraint_set_enabled (ClutterActorMeta *meta, - gboolean is_enabled) -{ - ClutterActorMetaClass *parent_class = - CLUTTER_ACTOR_META_CLASS (clutter_constraint_parent_class); - ClutterActor *actor; - - actor = clutter_actor_meta_get_actor (meta); - if (actor) - clutter_actor_queue_relayout (actor); - - parent_class->set_enabled (meta, is_enabled); -} - -static void -clutter_constraint_class_init (ClutterConstraintClass *klass) -{ - ClutterActorMetaClass *actor_meta_class = CLUTTER_ACTOR_META_CLASS (klass); - - actor_meta_class->set_enabled = clutter_constraint_set_enabled; - - klass->update_allocation = constraint_update_allocation; - klass->update_preferred_size = constraint_update_preferred_size; -} - -static void -clutter_constraint_init (ClutterConstraint *self) -{ -} - -/*< private > - * clutter_constraint_update_allocation: - * @constraint: a #ClutterConstraint - * @actor: a #ClutterActor - * @allocation: (inout): the allocation to modify - * - * Asks the @constraint to update the @allocation of a #ClutterActor. - * - * Returns: %TRUE if the allocation was updated - */ -gboolean -clutter_constraint_update_allocation (ClutterConstraint *constraint, - ClutterActor *actor, - ClutterActorBox *allocation) -{ - ClutterActorBox old_alloc; - - g_return_val_if_fail (CLUTTER_IS_CONSTRAINT (constraint), FALSE); - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE); - g_return_val_if_fail (allocation != NULL, FALSE); - - old_alloc = *allocation; - - CLUTTER_CONSTRAINT_GET_CLASS (constraint)->update_allocation (constraint, - actor, - allocation); - - return !clutter_actor_box_equal (allocation, &old_alloc); -} - -/** - * clutter_constraint_update_preferred_size: - * @constraint: a #ClutterConstraint - * @actor: a #ClutterActor - * @direction: a #ClutterOrientation - * @for_size: the size in the opposite direction - * @minimum_size: (inout): the minimum size to modify - * @natural_size: (inout): the natural size to modify - * - * Asks the @constraint to update the size request of a #ClutterActor. - */ -void -clutter_constraint_update_preferred_size (ClutterConstraint *constraint, - ClutterActor *actor, - ClutterOrientation direction, - float for_size, - float *minimum_size, - float *natural_size) -{ - g_return_if_fail (CLUTTER_IS_CONSTRAINT (constraint)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - CLUTTER_CONSTRAINT_GET_CLASS (constraint)->update_preferred_size (constraint, actor, - direction, - for_size, - minimum_size, - natural_size); -} diff --git a/mutter/clutter/clutter/clutter-constraint.h b/mutter/clutter/clutter/clutter-constraint.h deleted file mode 100644 index dbe1ace..0000000 --- a/mutter/clutter/clutter/clutter-constraint.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-actor-meta.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_CONSTRAINT (clutter_constraint_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterConstraint, - clutter_constraint, - CLUTTER, - CONSTRAINT, - ClutterActorMeta) - -/** - * ClutterConstraintClass: - * @update_allocation: virtual function used to update the allocation - * of the #ClutterActor using the #ClutterConstraint - * @update_preferred_size: virtual function used to update the preferred - * size of the #ClutterActor using the #ClutterConstraint; optional, - * since 1.22 - * - * The #ClutterConstraintClass structure contains - * only private data - */ -struct _ClutterConstraintClass -{ - /*< private >*/ - ClutterActorMetaClass parent_class; - - /*< public >*/ - void (* update_allocation) (ClutterConstraint *constraint, - ClutterActor *actor, - ClutterActorBox *allocation); - - void (* update_preferred_size) (ClutterConstraint *constraint, - ClutterActor *actor, - ClutterOrientation direction, - float for_size, - float *minimum_size, - float *natural_size); -}; - -CLUTTER_EXPORT -void clutter_constraint_update_preferred_size (ClutterConstraint *constraint, - ClutterActor *actor, - ClutterOrientation direction, - float for_size, - float *minimum_size, - float *natural_size); - -/* ClutterActor API */ -CLUTTER_EXPORT -void clutter_actor_add_constraint (ClutterActor *self, - ClutterConstraint *constraint); -CLUTTER_EXPORT -void clutter_actor_add_constraint_with_name (ClutterActor *self, - const gchar *name, - ClutterConstraint *constraint); -CLUTTER_EXPORT -void clutter_actor_remove_constraint (ClutterActor *self, - ClutterConstraint *constraint); -CLUTTER_EXPORT -void clutter_actor_remove_constraint_by_name (ClutterActor *self, - const gchar *name); -CLUTTER_EXPORT -GList * clutter_actor_get_constraints (ClutterActor *self); -CLUTTER_EXPORT -ClutterConstraint *clutter_actor_get_constraint (ClutterActor *self, - const gchar *name); -CLUTTER_EXPORT -void clutter_actor_clear_constraints (ClutterActor *self); - -CLUTTER_EXPORT -gboolean clutter_actor_has_constraints (ClutterActor *self); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-content-private.h b/mutter/clutter/clutter/clutter-content-private.h deleted file mode 100644 index 2950da9..0000000 --- a/mutter/clutter/clutter/clutter-content-private.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#include "clutter/clutter-content.h" - -G_BEGIN_DECLS - -void _clutter_content_attached (ClutterContent *content, - ClutterActor *actor); -void _clutter_content_detached (ClutterContent *content, - ClutterActor *actor); - -void _clutter_content_paint_content (ClutterContent *content, - ClutterActor *actor, - ClutterPaintNode *node, - ClutterPaintContext *paint_context); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-content.c b/mutter/clutter/clutter/clutter-content.c deleted file mode 100644 index 8fda7e0..0000000 --- a/mutter/clutter/clutter/clutter-content.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterContent: - * - * Delegate for painting the content of an actor - * - * #ClutterContent is an interface to implement types responsible for - * painting the content of a [class@Actor]. - * - * Multiple actors can use the same #ClutterContent instance, in order - * to share the resources associated with painting the same content.. - */ - -#include "config.h" - -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-content-private.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-private.h" - -enum -{ - ATTACHED, - DETACHED, - - LAST_SIGNAL -}; - -static GQuark quark_content_actors = 0; - -static guint content_signals[LAST_SIGNAL] = { 0, }; - -G_DEFINE_INTERFACE (ClutterContent, clutter_content, G_TYPE_OBJECT) - -static gboolean -clutter_content_real_get_preferred_size (ClutterContent *content, - gfloat *width, - gfloat *height) -{ - if (width != NULL) - *width = 0.f; - - if (height != NULL) - *height = 0.f; - - return FALSE; -} - -static void -clutter_content_real_attached (ClutterContent *content, - ClutterActor *actor) -{ -} - -static void -clutter_content_real_detached (ClutterContent *content, - ClutterActor *actor) -{ -} - -static void -clutter_content_real_invalidate (ClutterContent *content) -{ -} - -static void -clutter_content_real_invalidate_size (ClutterContent *content) -{ -} - -static void -clutter_content_real_paint_content (ClutterContent *content, - ClutterActor *actor, - ClutterPaintNode *context, - ClutterPaintContext *paint_context) -{ -} - -static void -clutter_content_default_init (ClutterContentInterface *iface) -{ - quark_content_actors = g_quark_from_static_string ("-clutter-content-actors"); - - iface->get_preferred_size = clutter_content_real_get_preferred_size; - iface->paint_content = clutter_content_real_paint_content; - iface->attached = clutter_content_real_attached; - iface->detached = clutter_content_real_detached; - iface->invalidate = clutter_content_real_invalidate; - iface->invalidate_size = clutter_content_real_invalidate_size; - - /** - * ClutterContent::attached: - * @content: the object that emitted the signal - * @actor: a #ClutterActor - * - * This signal is emitted each time a #ClutterContent implementation is - * assigned to a #ClutterActor. - */ - content_signals[ATTACHED] = - g_signal_new (I_("attached"), - G_TYPE_FROM_INTERFACE (iface), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterContentInterface, attached), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_ACTOR); - - /** - * ClutterContent::detached: - * @content: the object that emitted the signal - * @actor: a #ClutterActor - * - * This signal is emitted each time a #ClutterContent implementation is - * removed from a #ClutterActor. - */ - content_signals[DETACHED] = - g_signal_new (I_("detached"), - G_TYPE_FROM_INTERFACE (iface), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterContentInterface, detached), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_ACTOR); -} - -/** - * clutter_content_invalidate: - * @content: a #ClutterContent - * - * Invalidates a #ClutterContent. - * - * This function should be called by #ClutterContent implementations when - * they change the way a the content should be painted regardless of the - * actor state. - */ -void -clutter_content_invalidate (ClutterContent *content) -{ - GHashTable *actors; - GHashTableIter iter; - gpointer key_p, value_p; - - g_return_if_fail (CLUTTER_IS_CONTENT (content)); - - CLUTTER_CONTENT_GET_IFACE (content)->invalidate (content); - - actors = g_object_get_qdata (G_OBJECT (content), quark_content_actors); - if (actors == NULL) - return; - - g_hash_table_iter_init (&iter, actors); - while (g_hash_table_iter_next (&iter, &key_p, &value_p)) - { - ClutterActor *actor = key_p; - - g_assert (actor != NULL); - - clutter_actor_queue_redraw (actor); - } -} - -/** - * clutter_content_invalidate_size: - * @content: a #ClutterContent - * - * Signals that @content's size changed. Attached actors with request mode - * set to %CLUTTER_REQUEST_CONTENT_SIZE will have a relayout queued. - * - * Attached actors with other request modes are not redrawn. To redraw them - * too, use [method@Clutter.Content.invalidate]. - */ -void -clutter_content_invalidate_size (ClutterContent *content) -{ - ClutterActor *actor; - GHashTable *actors; - GHashTableIter iter; - - g_return_if_fail (CLUTTER_IS_CONTENT (content)); - - CLUTTER_CONTENT_GET_IFACE (content)->invalidate_size (content); - - actors = g_object_get_qdata (G_OBJECT (content), quark_content_actors); - if (actors == NULL) - return; - - g_hash_table_iter_init (&iter, actors); - while (g_hash_table_iter_next (&iter, (gpointer *) &actor, NULL)) - { - ClutterRequestMode request_mode; - - g_assert (actor != NULL); - - request_mode = clutter_actor_get_request_mode (actor); - - if (request_mode == CLUTTER_REQUEST_CONTENT_SIZE) - _clutter_actor_queue_only_relayout (actor); - } -} - -/*< private > - * _clutter_content_attached: - * @content: a #ClutterContent - * @actor: a #ClutterActor - * - * Attaches @actor to the @content. - * - * This function should be used internally every time a #ClutterActor - * is associated to a #ClutterContent, to set up a backpointer from - * the @content to the @actor. - * - * This function will invoke the [vfunc@Clutter.Content.attached] virtual - * function. - */ -void -_clutter_content_attached (ClutterContent *content, - ClutterActor *actor) -{ - GObject *obj = G_OBJECT (content); - GHashTable *actors; - - actors = g_object_get_qdata (obj, quark_content_actors); - if (actors == NULL) - { - actors = g_hash_table_new (NULL, NULL); - g_object_set_qdata_full (obj, quark_content_actors, - actors, - (GDestroyNotify) g_hash_table_unref); - } - - g_hash_table_insert (actors, actor, actor); - - g_signal_emit (content, content_signals[ATTACHED], 0, actor); -} - -/*< private > - * _clutter_content_detached: - * @content: a #ClutterContent - * @actor: a #ClutterActor - * - * Detaches @actor from @content. - * - * This function should be used internally every time a #ClutterActor - * removes the association with a #ClutterContent. - * - * This function will invoke the [vfunc@Clutter.Content.detached] virtual - * function. - */ -void -_clutter_content_detached (ClutterContent *content, - ClutterActor *actor) -{ - GObject *obj = G_OBJECT (content); - GHashTable *actors; - - actors = g_object_get_qdata (obj, quark_content_actors); - g_assert (actors != NULL); - - g_hash_table_remove (actors, actor); - - if (g_hash_table_size (actors) == 0) - g_object_set_qdata (obj, quark_content_actors, NULL); - - g_signal_emit (content, content_signals[DETACHED], 0, actor); -} - -/*< private > - * _clutter_content_paint_content: - * @content: a #ClutterContent - * @actor: a #ClutterActor - * @node: a #ClutterPaintNode - * @paint_context: a #ClutterPaintContext - * - * Creates the render tree for the @content and @actor. - * - * This function will invoke the [vfunc@Clutter.Content.paint_content] - * virtual function. - */ -void -_clutter_content_paint_content (ClutterContent *content, - ClutterActor *actor, - ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - CLUTTER_CONTENT_GET_IFACE (content)->paint_content (content, actor, node, - paint_context); -} - -/** - * clutter_content_get_preferred_size: - * @content: a #ClutterContent - * @width: (out) (optional): return location for the natural width of the content - * @height: (out) (optional): return location for the natural height of the content - * - * Retrieves the natural size of the @content, if any. - * - * The natural size of a #ClutterContent is defined as the size the content - * would have regardless of the allocation of the actor that is painting it, - * for instance the size of an image data. - * - * Return value: %TRUE if the content has a preferred size, and %FALSE - * otherwise - */ -gboolean -clutter_content_get_preferred_size (ClutterContent *content, - gfloat *width, - gfloat *height) -{ - g_return_val_if_fail (CLUTTER_IS_CONTENT (content), FALSE); - - return CLUTTER_CONTENT_GET_IFACE (content)->get_preferred_size (content, - width, - height); -} diff --git a/mutter/clutter/clutter/clutter-content.h b/mutter/clutter/clutter/clutter-content.h deleted file mode 100644 index 1880f1f..0000000 --- a/mutter/clutter/clutter/clutter-content.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_CONTENT (clutter_content_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_INTERFACE (ClutterContent, clutter_content, CLUTTER, CONTENT, GObject) - -/** - * ClutterContentInterface: - * @get_preferred_size: virtual function; should be overridden by subclasses - * of #ClutterContent that have a natural size - * @paint_content: virtual function; called each time the content needs to - * paint itself - * @attached: virtual function; called each time a #ClutterContent is attached - * to a #ClutterActor. - * @detached: virtual function; called each time a #ClutterContent is detached - * from a #ClutterActor. - * @invalidate: virtual function; called each time a #ClutterContent state - * is changed. - * - * The #ClutterContentInterface structure contains only - * private data. - */ -struct _ClutterContentInterface -{ - /*< private >*/ - GTypeInterface g_iface; - - /*< public >*/ - gboolean (* get_preferred_size) (ClutterContent *content, - gfloat *width, - gfloat *height); - void (* paint_content) (ClutterContent *content, - ClutterActor *actor, - ClutterPaintNode *node, - ClutterPaintContext *paint_context); - - void (* attached) (ClutterContent *content, - ClutterActor *actor); - void (* detached) (ClutterContent *content, - ClutterActor *actor); - - void (* invalidate) (ClutterContent *content); - - void (* invalidate_size) (ClutterContent *content); -}; - -CLUTTER_EXPORT -gboolean clutter_content_get_preferred_size (ClutterContent *content, - gfloat *width, - gfloat *height); -CLUTTER_EXPORT -void clutter_content_invalidate (ClutterContent *content); - -CLUTTER_EXPORT -void clutter_content_invalidate_size (ClutterContent *content); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-context-private.h b/mutter/clutter/clutter/clutter-context-private.h deleted file mode 100644 index dc81d7f..0000000 --- a/mutter/clutter/clutter/clutter-context-private.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2006 OpenedHand - * Copyright (C) 2023 Red Hat - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - */ - -#pragma once - -#include "clutter/clutter-context.h" - -struct _ClutterContext -{ - GObject parent; - - ClutterBackend *backend; - ClutterStageManager *stage_manager; - - GAsyncQueue *events_queue; - - /* the event filters added via clutter_event_add_filter. these are - * ordered from least recently added to most recently added */ - GList *event_filters; - - CoglPangoFontMap *font_map; - - GSList *current_event; - - GList *repaint_funcs; - guint last_repaint_id; - - ClutterSettings *settings; - - gboolean is_initialized; - gboolean show_fps; -}; diff --git a/mutter/clutter/clutter/clutter-context.c b/mutter/clutter/clutter/clutter-context.c deleted file mode 100644 index 1108bf6..0000000 --- a/mutter/clutter/clutter/clutter-context.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - */ - -#include "config.h" - -#include "clutter/clutter-context-private.h" - -#include - -#include "cally/cally.h" -#include "clutter/clutter-backend-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-graphene.h" -#include "clutter/clutter-main.h" -#include "clutter/clutter-paint-node-private.h" -#include "clutter/clutter-settings-private.h" - -static gboolean clutter_disable_mipmap_text = FALSE; -static gboolean clutter_show_fps = FALSE; - -#ifdef CLUTTER_ENABLE_DEBUG -static const GDebugKey clutter_debug_keys[] = { - { "misc", CLUTTER_DEBUG_MISC }, - { "actor", CLUTTER_DEBUG_ACTOR }, - { "texture", CLUTTER_DEBUG_TEXTURE }, - { "event", CLUTTER_DEBUG_EVENT }, - { "paint", CLUTTER_DEBUG_PAINT }, - { "pick", CLUTTER_DEBUG_PICK }, - { "pango", CLUTTER_DEBUG_PANGO }, - { "backend", CLUTTER_DEBUG_BACKEND }, - { "scheduler", CLUTTER_DEBUG_SCHEDULER }, - { "script", CLUTTER_DEBUG_SCRIPT }, - { "shader", CLUTTER_DEBUG_SHADER }, - { "animation", CLUTTER_DEBUG_ANIMATION }, - { "layout", CLUTTER_DEBUG_LAYOUT }, - { "clipping", CLUTTER_DEBUG_CLIPPING }, - { "oob-transforms", CLUTTER_DEBUG_OOB_TRANSFORMS }, - { "frame-timings", CLUTTER_DEBUG_FRAME_TIMINGS }, - { "detailed-trace", CLUTTER_DEBUG_DETAILED_TRACE }, - { "grabs", CLUTTER_DEBUG_GRABS }, - { "frame-clock", CLUTTER_DEBUG_FRAME_CLOCK }, - { "gestures", CLUTTER_DEBUG_GESTURES }, -}; -#endif /* CLUTTER_ENABLE_DEBUG */ - -static const GDebugKey clutter_pick_debug_keys[] = { - { "nop-picking", CLUTTER_DEBUG_NOP_PICKING }, -}; - -static const GDebugKey clutter_paint_debug_keys[] = { - { "disable-swap-events", CLUTTER_DEBUG_DISABLE_SWAP_EVENTS }, - { "disable-clipped-redraws", CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS }, - { "redraws", CLUTTER_DEBUG_REDRAWS }, - { "paint-volumes", CLUTTER_DEBUG_PAINT_VOLUMES }, - { "disable-culling", CLUTTER_DEBUG_DISABLE_CULLING }, - { "disable-offscreen-redirect", CLUTTER_DEBUG_DISABLE_OFFSCREEN_REDIRECT }, - { "continuous-redraw", CLUTTER_DEBUG_CONTINUOUS_REDRAW }, - { "paint-deform-tiles", CLUTTER_DEBUG_PAINT_DEFORM_TILES }, - { "damage-region", CLUTTER_DEBUG_PAINT_DAMAGE_REGION }, - { "disable-dynamic-max-render-time", CLUTTER_DEBUG_DISABLE_DYNAMIC_MAX_RENDER_TIME }, - { "max-render-time", CLUTTER_DEBUG_PAINT_MAX_RENDER_TIME }, -}; - -typedef struct _ClutterContextPrivate -{ - ClutterTextDirection text_direction; -} ClutterContextPrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterContext, clutter_context, G_TYPE_OBJECT) - -static void -clutter_context_dispose (GObject *object) -{ - ClutterContext *context = CLUTTER_CONTEXT (object); - - g_clear_pointer (&context->events_queue, g_async_queue_unref); - g_clear_pointer (&context->backend, clutter_backend_destroy); - - G_OBJECT_CLASS (clutter_context_parent_class)->dispose (object); -} - -static void -clutter_context_class_init (ClutterContextClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = clutter_context_dispose; - - clutter_graphene_init (); -} - -static void -clutter_context_init (ClutterContext *context) -{ - ClutterContextPrivate *priv = clutter_context_get_instance_private (context); - - priv->text_direction = CLUTTER_TEXT_DIRECTION_LTR; -} - -ClutterTextDirection -clutter_get_text_direction (void) -{ - ClutterTextDirection dir = CLUTTER_TEXT_DIRECTION_LTR; - const gchar *direction; - - direction = g_getenv ("CLUTTER_TEXT_DIRECTION"); - if (direction && *direction != '\0') - { - if (strcmp (direction, "rtl") == 0) - dir = CLUTTER_TEXT_DIRECTION_RTL; - else if (strcmp (direction, "ltr") == 0) - dir = CLUTTER_TEXT_DIRECTION_LTR; - } - else - { - PangoLanguage *language; - const PangoScript *scripts; - int n_scripts, i; - - language = pango_language_get_default (); - scripts = pango_language_get_scripts (language, &n_scripts); - - for (i = 0; i < n_scripts; i++) - { - hb_script_t script; - hb_direction_t text_dir; - - script = hb_glib_script_to_script ((GUnicodeScript) scripts[i]); - text_dir = hb_script_get_horizontal_direction (script); - - if (text_dir == HB_DIRECTION_LTR) - dir = CLUTTER_TEXT_DIRECTION_LTR; - else if (text_dir == HB_DIRECTION_RTL) - dir = CLUTTER_TEXT_DIRECTION_RTL; - else - continue; - } - } - - CLUTTER_NOTE (MISC, "Text direction: %s", - dir == CLUTTER_TEXT_DIRECTION_RTL ? "rtl" : "ltr"); - - return dir; -} - -static gboolean -clutter_context_init_real (ClutterContext *context, - ClutterContextFlags flags, - GError **error) -{ - ClutterContextPrivate *priv = clutter_context_get_instance_private (context); - - /* If we are displaying the regions that would get redrawn with clipped - * redraws enabled we actually have to disable the clipped redrawing - * because otherwise we end up with nasty trails of rectangles everywhere. - */ - if (clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS) - clutter_paint_debug_flags |= CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS; - - /* The same is true when drawing the outlines of paint volumes... */ - if (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_VOLUMES) - { - clutter_paint_debug_flags |= - CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS | CLUTTER_DEBUG_DISABLE_CULLING; - } - - if (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION) - g_message ("Enabling damaged region"); - - if (!_clutter_backend_create_context (context->backend, error)) - return FALSE; - - priv->text_direction = clutter_get_text_direction (); - - context->is_initialized = TRUE; - - /* Initialize a11y */ - if (!(flags & CLUTTER_CONTEXT_FLAG_NO_A11Y)) - cally_accessibility_init (); - - /* Initialize types required for paint nodes */ - clutter_paint_node_init_types (context->backend); - - return TRUE; -} - -static void -init_clutter_debug (ClutterContext *context) -{ - const char *env_string; - -#ifdef CLUTTER_ENABLE_DEBUG - env_string = g_getenv ("CLUTTER_DEBUG"); - if (env_string != NULL) - { - clutter_debug_flags = - g_parse_debug_string (env_string, - clutter_debug_keys, - G_N_ELEMENTS (clutter_debug_keys)); - env_string = NULL; - } -#endif /* CLUTTER_ENABLE_DEBUG */ - - env_string = g_getenv ("CLUTTER_PICK"); - if (env_string != NULL) - { - clutter_pick_debug_flags = - g_parse_debug_string (env_string, - clutter_pick_debug_keys, - G_N_ELEMENTS (clutter_pick_debug_keys)); - env_string = NULL; - } - - env_string = g_getenv ("CLUTTER_PAINT"); - if (env_string != NULL) - { - clutter_paint_debug_flags = - g_parse_debug_string (env_string, - clutter_paint_debug_keys, - G_N_ELEMENTS (clutter_paint_debug_keys)); - env_string = NULL; - } - - env_string = g_getenv ("CLUTTER_SHOW_FPS"); - if (env_string) - clutter_show_fps = TRUE; - - env_string = g_getenv ("CLUTTER_DISABLE_MIPMAPPED_TEXT"); - if (env_string) - clutter_disable_mipmap_text = TRUE; -} - -ClutterContext * -clutter_context_new (ClutterContextFlags flags, - ClutterBackendConstructor backend_constructor, - gpointer user_data, - GError **error) -{ - ClutterContext *context; - - context = g_object_new (CLUTTER_TYPE_CONTEXT, NULL); - - init_clutter_debug (context); - context->show_fps = clutter_show_fps; - context->is_initialized = FALSE; - - context->backend = backend_constructor (user_data); - context->settings = clutter_settings_get_default (); - _clutter_settings_set_backend (context->settings, - context->backend); - - context->events_queue = - g_async_queue_new_full ((GDestroyNotify) clutter_event_free); - context->last_repaint_id = 1; - - if (!clutter_context_init_real (context, flags, error)) - return NULL; - - return context; -} - -void -clutter_context_destroy (ClutterContext *context) -{ - g_object_run_dispose (G_OBJECT (context)); - g_object_unref (context); -} - -ClutterBackend * -clutter_context_get_backend (ClutterContext *context) -{ - return context->backend; -} - -CoglPangoFontMap * -clutter_context_get_pango_fontmap (ClutterContext *context) -{ - CoglPangoFontMap *font_map; - gdouble resolution; - gboolean use_mipmapping; - - if (G_LIKELY (context->font_map != NULL)) - return context->font_map; - - font_map = COGL_PANGO_FONT_MAP (cogl_pango_font_map_new ()); - - resolution = clutter_backend_get_resolution (context->backend); - cogl_pango_font_map_set_resolution (font_map, resolution); - - use_mipmapping = !clutter_disable_mipmap_text; - cogl_pango_font_map_set_use_mipmapping (font_map, use_mipmapping); - - context->font_map = font_map; - - return context->font_map; -} - -ClutterTextDirection -clutter_context_get_text_direction (ClutterContext *context) -{ - ClutterContextPrivate *priv = clutter_context_get_instance_private (context); - - return priv->text_direction; -} diff --git a/mutter/clutter/clutter/clutter-context.h b/mutter/clutter/clutter/clutter-context.h deleted file mode 100644 index 8bc2aa7..0000000 --- a/mutter/clutter/clutter/clutter-context.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2006 OpenedHand - * Copyright (C) 2023 Red Hat - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - */ - -#pragma once - -#include "clutter-backend.h" -#include "clutter-stage-manager.h" -#include "clutter-settings.h" -#include "cogl-pango/cogl-pango.h" - -typedef enum _ClutterContextFlags -{ - CLUTTER_CONTEXT_FLAG_NONE = 0, - CLUTTER_CONTEXT_FLAG_NO_A11Y = 1 << 0, -} ClutterContextFlags; - -typedef ClutterBackend * (* ClutterBackendConstructor) (gpointer user_data); - -#define CLUTTER_TYPE_CONTEXT (clutter_context_get_type ()) -CLUTTER_EXPORT -G_DECLARE_FINAL_TYPE (ClutterContext, clutter_context, - CLUTTER, CONTEXT, GObject) - -/** - * clutter_context_new: (skip) - */ -ClutterContext * clutter_context_new (ClutterContextFlags flags, - ClutterBackendConstructor backend_constructor, - gpointer user_data, - GError **error); - -/** - * clutter_context_destroy: (skip) - */ -CLUTTER_EXPORT -void clutter_context_destroy (ClutterContext *context); - -/** - * clutter_context_get_backend: - * - * Returns: (transfer none): The %ClutterBackend - */ -CLUTTER_EXPORT -ClutterBackend * clutter_context_get_backend (ClutterContext *context); - -/** - * clutter_context_get_pango_fontmap: (skip) - */ -CoglPangoFontMap * clutter_context_get_pango_fontmap (ClutterContext *context); - -ClutterTextDirection clutter_context_get_text_direction (ClutterContext *context); diff --git a/mutter/clutter/clutter/clutter-damage-history.c b/mutter/clutter/clutter/clutter-damage-history.c deleted file mode 100644 index f2c8b23..0000000 --- a/mutter/clutter/clutter/clutter-damage-history.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2010,2011 Intel Corporation. - * Copyright (C) 2020 Red Hat Inc - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include "config.h" - -#include "clutter/clutter-damage-history.h" - -#define DAMAGE_HISTORY_LENGTH 0x10 - -struct _ClutterDamageHistory -{ - MtkRegion *damages[DAMAGE_HISTORY_LENGTH]; - int index; -}; - -ClutterDamageHistory * -clutter_damage_history_new (void) -{ - ClutterDamageHistory *history; - - history = g_new0 (ClutterDamageHistory, 1); - - return history; -} - -void -clutter_damage_history_free (ClutterDamageHistory *history) -{ - int i; - - for (i = 0; i < G_N_ELEMENTS (history->damages); i++) - g_clear_pointer (&history->damages[i], mtk_region_unref); - - g_free (history); -} - -gboolean -clutter_damage_history_is_age_valid (ClutterDamageHistory *history, - int age) -{ - if (age >= DAMAGE_HISTORY_LENGTH || - age < 1) - return FALSE; - - if (!clutter_damage_history_lookup (history, age)) - return FALSE; - - return TRUE; -} - -void -clutter_damage_history_record (ClutterDamageHistory *history, - const MtkRegion *damage) -{ - g_clear_pointer (&history->damages[history->index], mtk_region_unref); - history->damages[history->index] = mtk_region_copy (damage); -} - -static inline int -step_damage_index (int current, - int diff) -{ - return (current + diff) & (DAMAGE_HISTORY_LENGTH - 1); -} - -void -clutter_damage_history_step (ClutterDamageHistory *history) -{ - history->index = step_damage_index (history->index, 1); -} - -const MtkRegion * -clutter_damage_history_lookup (ClutterDamageHistory *history, - int age) -{ - return history->damages[step_damage_index (history->index, -age)]; -} diff --git a/mutter/clutter/clutter/clutter-damage-history.h b/mutter/clutter/clutter/clutter-damage-history.h deleted file mode 100644 index 7328ac7..0000000 --- a/mutter/clutter/clutter/clutter-damage-history.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2010,2011 Intel Corporation. - * Copyright (C) 2020 Red Hat Inc - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#include - -#include "clutter/clutter-macros.h" -#include "mtk/mtk.h" - -typedef struct _ClutterDamageHistory ClutterDamageHistory; - -CLUTTER_EXPORT -ClutterDamageHistory * clutter_damage_history_new (void); - -CLUTTER_EXPORT -void clutter_damage_history_free (ClutterDamageHistory *history); - -CLUTTER_EXPORT -gboolean clutter_damage_history_is_age_valid (ClutterDamageHistory *history, - int age); - -CLUTTER_EXPORT -void clutter_damage_history_record (ClutterDamageHistory *history, - const MtkRegion *damage); - -CLUTTER_EXPORT -void clutter_damage_history_step (ClutterDamageHistory *history); - -CLUTTER_EXPORT -const MtkRegion * clutter_damage_history_lookup (ClutterDamageHistory *history, - int age); diff --git a/mutter/clutter/clutter/clutter-debug.h b/mutter/clutter/clutter/clutter-debug.h deleted file mode 100644 index f41e783..0000000 --- a/mutter/clutter/clutter/clutter-debug.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include - -#include "clutter/clutter-main.h" - -G_BEGIN_DECLS - -#ifdef CLUTTER_ENABLE_DEBUG - -#define CLUTTER_HAS_DEBUG(type) ((clutter_debug_flags & CLUTTER_DEBUG_##type) != FALSE) - -#ifdef __GNUC__ - -/* Try the GCC extension for valists in macros */ -#define CLUTTER_NOTE(type,x,a...) G_STMT_START { \ - if (G_UNLIKELY (CLUTTER_HAS_DEBUG (type))) { \ - _clutter_debug_message ("[" #type "]: " x, ##a); \ - } } G_STMT_END - -#else /* !__GNUC__ */ -/* Try the C99 version; unfortunately, this does not allow us to pass - * empty arguments to the macro, which means we have to - * do an intemediate printf. - */ -#define CLUTTER_NOTE(type,...) G_STMT_START { \ - if (G_UNLIKELY (CLUTTER_HAS_DEBUG (type))) { \ - gchar *_fmt = g_strdup_printf (__VA_ARGS__); \ - _clutter_debug_message ("[" #type "]: %s", _fmt); \ - g_free (_fmt); \ - } } G_STMT_END -#endif - -#else /* !CLUTTER_ENABLE_DEBUG */ - -#define CLUTTER_NOTE(type,...) G_STMT_START { } G_STMT_END -#define CLUTTER_HAS_DEBUG(type) FALSE - -#endif /* CLUTTER_ENABLE_DEBUG */ - -extern guint clutter_debug_flags; -extern guint clutter_pick_debug_flags; -extern guint clutter_paint_debug_flags; -extern int clutter_max_render_time_constant_us; - -void _clutter_debug_messagev (const char *format, - va_list var_args) G_GNUC_PRINTF (1, 0); -void _clutter_debug_message (const char *format, - ...) G_GNUC_PRINTF (1, 2); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-deform-effect.c b/mutter/clutter/clutter/clutter-deform-effect.c deleted file mode 100644 index 5f4be0e..0000000 --- a/mutter/clutter/clutter/clutter-deform-effect.c +++ /dev/null @@ -1,804 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - * - * Based on the MxDeformTexture class, written by: - * Chris Lord - */ - -/** - * ClutterDeformEffect: - * - * A base class for effects deforming the geometry of an actor - * - * #ClutterDeformEffect is an abstract class providing all the plumbing - * for creating effects that result in the deformation of an actor's - * geometry. - * - * #ClutterDeformEffect uses offscreen buffers to render the contents of - * a #ClutterActor and then the Cogl vertex buffers API to submit the - * geometry to the GPU. - * - * ## Implementing ClutterDeformEffect - * - * Sub-classes of #ClutterDeformEffect should override the - * [vfunc@Clutter.DeformEffect.deform_vertex] virtual function; this function - * is called on every vertex that needs to be deformed by the effect. - * Each passed vertex is an in-out parameter that initially contains the - * position of the vertex and should be modified according to a specific - * deformation algorithm. - */ - -#include "config.h" - -#include "cogl/cogl.h" - -#include "clutter/clutter-deform-effect.h" -#include "clutter/clutter-color.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-paint-node.h" -#include "clutter/clutter-paint-nodes.h" -#include "clutter/clutter-private.h" - -#define DEFAULT_N_TILES 32 - -typedef struct _ClutterDeformEffectPrivate -{ - CoglPipeline *back_pipeline; - - gint x_tiles; - gint y_tiles; - - CoglAttributeBuffer *buffer; - - CoglPrimitive *primitive; - - CoglPrimitive *lines_primitive; - - gint n_vertices; - - gulong allocation_id; - - guint is_dirty : 1; -} ClutterDeformEffectPrivate; - -enum -{ - PROP_0, - - PROP_X_TILES, - PROP_Y_TILES, - - PROP_BACK_MATERIAL, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterDeformEffect, - clutter_deform_effect, - CLUTTER_TYPE_OFFSCREEN_EFFECT) - -static void -clutter_deform_effect_real_deform_vertex (ClutterDeformEffect *effect, - gfloat width, - gfloat height, - CoglTextureVertex *vertex) -{ - g_warning ("%s: Deformation effect of type '%s' does not implement " - "the required ClutterDeformEffect::deform_vertex virtual " - "function.", - G_STRLOC, - G_OBJECT_TYPE_NAME (effect)); -} - -static void -clutter_deform_effect_deform_vertex (ClutterDeformEffect *effect, - gfloat width, - gfloat height, - CoglTextureVertex *vertex) -{ - CLUTTER_DEFORM_EFFECT_GET_CLASS (effect)->deform_vertex (effect, - width, height, - vertex); -} - -static void -vbo_invalidate (ClutterActor *actor, - GParamSpec *pspec, - ClutterDeformEffect *effect) -{ - ClutterDeformEffectPrivate *priv = - clutter_deform_effect_get_instance_private (effect); - - priv->is_dirty = TRUE; -} - -static void -clutter_deform_effect_set_actor (ClutterActorMeta *meta, - ClutterActor *actor) -{ - ClutterDeformEffect *effect = CLUTTER_DEFORM_EFFECT (meta); - ClutterDeformEffectPrivate *priv = - clutter_deform_effect_get_instance_private (effect); - - if (priv->allocation_id != 0) - { - ClutterActor *old_actor = clutter_actor_meta_get_actor (meta); - - if (old_actor != NULL) - g_clear_signal_handler (&priv->allocation_id, old_actor); - - priv->allocation_id = 0; - } - - /* we need to invalidate the VBO whenever the allocation of the actor - * changes - */ - if (actor != NULL) - priv->allocation_id = g_signal_connect (actor, "notify::allocation", - G_CALLBACK (vbo_invalidate), - meta); - - priv->is_dirty = TRUE; - - CLUTTER_ACTOR_META_CLASS (clutter_deform_effect_parent_class)->set_actor (meta, actor); -} - -static void -clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterDeformEffect *self = CLUTTER_DEFORM_EFFECT (effect); - ClutterDeformEffectPrivate *priv = - clutter_deform_effect_get_instance_private (self); - CoglPipeline *pipeline; - CoglDepthState depth_state; - - if (priv->is_dirty) - { - gboolean mapped_buffer; - CoglVertexP3T2C4 *verts; - ClutterActor *actor; - gfloat width, height; - guint opacity; - gint i, j; - - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); - opacity = clutter_actor_get_paint_opacity (actor); - - /* if we don't have a target size, fall back to the actor's - * allocation, though wrong it might be - */ - if (!clutter_offscreen_effect_get_target_size (effect, &width, &height)) - clutter_actor_get_size (actor, &width, &height); - - /* XXX ideally, the sub-classes should tell us what they - * changed in the texture vertices; we then would be able to - * avoid resubmitting the same data, if it did not change. for - * the time being, we resubmit everything - */ - verts = cogl_buffer_map (COGL_BUFFER (priv->buffer), - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD); - - /* If the map failed then we'll resort to allocating a temporary - buffer */ - if (verts == NULL) - { - mapped_buffer = FALSE; - verts = g_malloc (sizeof (*verts) * priv->n_vertices); - } - else - mapped_buffer = TRUE; - - for (i = 0; i < priv->y_tiles + 1; i++) - { - for (j = 0; j < priv->x_tiles + 1; j++) - { - CoglVertexP3T2C4 *vertex_out; - CoglTextureVertex vertex; - - /* CoglTextureVertex isn't an ideal structure to use for - this because it contains a CoglColor. The internal - layout of CoglColor is mean to be private so Clutter - can not pass a pointer to it as a vertex - attribute. Also it contains padding so we end up - storing more data in the vertex buffer than we need - to. Instead we let the application modify a dummy - vertex and then copy the details back out to a more - well-defined struct */ - - vertex.tx = (float) j / priv->x_tiles; - vertex.ty = (float) i / priv->y_tiles; - - vertex.x = width * vertex.tx; - vertex.y = height * vertex.ty; - vertex.z = 0.0f; - - cogl_color_init_from_4f (&vertex.color, 1.0, 1.0, 1.0, opacity / 255.0); - - clutter_deform_effect_deform_vertex (self, - width, height, - &vertex); - - vertex_out = verts + i * (priv->x_tiles + 1) + j; - - vertex_out->x = vertex.x; - vertex_out->y = vertex.y; - vertex_out->z = vertex.z; - vertex_out->s = vertex.tx; - vertex_out->t = vertex.ty; - vertex_out->r = cogl_color_get_red (&vertex.color) * 255.0; - vertex_out->g = cogl_color_get_green (&vertex.color) * 255.0; - vertex_out->b = cogl_color_get_blue (&vertex.color) * 255.0; - vertex_out->a = cogl_color_get_alpha (&vertex.color) * 255.0; - } - } - - if (mapped_buffer) - cogl_buffer_unmap (COGL_BUFFER (priv->buffer)); - else - { - cogl_buffer_set_data (COGL_BUFFER (priv->buffer), - 0, /* offset */ - verts, - sizeof (*verts) * priv->n_vertices); - g_free (verts); - } - - priv->is_dirty = FALSE; - } - - pipeline = clutter_offscreen_effect_get_pipeline (effect); - - /* enable depth testing */ - cogl_depth_state_init (&depth_state); - cogl_depth_state_set_test_enabled (&depth_state, TRUE); - cogl_depth_state_set_test_function (&depth_state, COGL_DEPTH_TEST_FUNCTION_LEQUAL); - cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL); - - /* enable backface culling if we have a back material */ - if (priv->back_pipeline != NULL) - cogl_pipeline_set_cull_face_mode (pipeline, - COGL_PIPELINE_CULL_FACE_MODE_BACK); - - /* draw the front */ - if (pipeline != NULL) - { - ClutterPaintNode *front_node; - - front_node = clutter_pipeline_node_new (pipeline); - clutter_paint_node_set_static_name (front_node, - "ClutterDeformEffect (front)"); - clutter_paint_node_add_child (node, front_node); - clutter_paint_node_add_primitive (front_node, priv->primitive); - clutter_paint_node_unref (front_node); - } - - /* draw the back */ - if (priv->back_pipeline != NULL) - { - ClutterPaintNode *back_node; - CoglPipeline *back_pipeline; - - /* We probably shouldn't be modifying the user's material so - instead we make a temporary copy */ - back_pipeline = cogl_pipeline_copy (priv->back_pipeline); - cogl_pipeline_set_depth_state (back_pipeline, &depth_state, NULL); - cogl_pipeline_set_cull_face_mode (back_pipeline, - COGL_PIPELINE_CULL_FACE_MODE_FRONT); - - - back_node = clutter_pipeline_node_new (back_pipeline); - clutter_paint_node_set_static_name (back_node, - "ClutterDeformEffect (back)"); - clutter_paint_node_add_child (node, back_node); - clutter_paint_node_add_primitive (back_node, priv->primitive); - - clutter_paint_node_unref (back_node); - g_object_unref (back_pipeline); - } - - if (G_UNLIKELY (priv->lines_primitive != NULL)) - { - static ClutterColor red = CLUTTER_COLOR_INIT (255, 0, 0, 255); - ClutterPaintNode *lines_node; - - lines_node = clutter_color_node_new (&red); - clutter_paint_node_set_static_name (lines_node, - "ClutterDeformEffect (lines)"); - clutter_paint_node_add_child (node, lines_node); - clutter_paint_node_add_primitive (lines_node, priv->lines_primitive); - clutter_paint_node_unref (lines_node); - } -} - -static inline void -clutter_deform_effect_free_arrays (ClutterDeformEffect *self) -{ - ClutterDeformEffectPrivate *priv = - clutter_deform_effect_get_instance_private (self); - - g_clear_object (&priv->buffer); - g_clear_object (&priv->primitive); - g_clear_object (&priv->lines_primitive); -} - -static void -clutter_deform_effect_init_arrays (ClutterDeformEffect *self) -{ - ClutterDeformEffectPrivate *priv = - clutter_deform_effect_get_instance_private (self); - gint x, y, direction, n_indices; - CoglAttribute *attributes[3]; - guint16 *static_indices; - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - CoglIndices *indices; - guint16 *idx; - int i; - - clutter_deform_effect_free_arrays (self); - - n_indices = ((2 + 2 * priv->x_tiles) - * priv->y_tiles - + (priv->y_tiles - 1)); - - static_indices = g_new (guint16, n_indices); - -#define MESH_INDEX(x,y) ((y) * (priv->x_tiles + 1) + (x)) - - /* compute all the triangles from the various tiles */ - direction = 1; - - idx = static_indices; - idx[0] = MESH_INDEX (0, 0); - idx[1] = MESH_INDEX (0, 1); - idx += 2; - - for (y = 0; y < priv->y_tiles; y++) - { - for (x = 0; x < priv->x_tiles; x++) - { - if (direction) - { - idx[0] = MESH_INDEX (x + 1, y); - idx[1] = MESH_INDEX (x + 1, y + 1); - } - else - { - idx[0] = MESH_INDEX (priv->x_tiles - x - 1, y); - idx[1] = MESH_INDEX (priv->x_tiles - x - 1, y + 1); - } - - idx += 2; - } - - if (y == (priv->y_tiles - 1)) - break; - - if (direction) - { - idx[0] = MESH_INDEX (priv->x_tiles, y + 1); - idx[1] = MESH_INDEX (priv->x_tiles, y + 1); - idx[2] = MESH_INDEX (priv->x_tiles, y + 2); - } - else - { - idx[0] = MESH_INDEX (0, y + 1); - idx[1] = MESH_INDEX (0, y + 1); - idx[2] = MESH_INDEX (0, y + 2); - } - - idx += 3; - - direction = !direction; - } - -#undef MESH_INDEX - - indices = cogl_indices_new (ctx, - COGL_INDICES_TYPE_UNSIGNED_SHORT, - static_indices, - n_indices); - - g_free (static_indices); - - priv->n_vertices = (priv->x_tiles + 1) * (priv->y_tiles + 1); - - priv->buffer = - cogl_attribute_buffer_new (ctx, - sizeof (CoglVertexP3T2C4) * - priv->n_vertices, - NULL); - - /* The application is expected to continuously modify the vertices - so we should give a hint to Cogl about that */ - cogl_buffer_set_update_hint (COGL_BUFFER (priv->buffer), - COGL_BUFFER_UPDATE_HINT_DYNAMIC); - - attributes[0] = cogl_attribute_new (priv->buffer, - "cogl_position_in", - sizeof (CoglVertexP3T2C4), - G_STRUCT_OFFSET (CoglVertexP3T2C4, x), - 3, /* n_components */ - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (priv->buffer, - "cogl_tex_coord0_in", - sizeof (CoglVertexP3T2C4), - G_STRUCT_OFFSET (CoglVertexP3T2C4, s), - 2, /* n_components */ - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[2] = cogl_attribute_new (priv->buffer, - "cogl_color_in", - sizeof (CoglVertexP3T2C4), - G_STRUCT_OFFSET (CoglVertexP3T2C4, r), - 4, /* n_components */ - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - - priv->primitive = - cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLE_STRIP, - priv->n_vertices, - attributes, - 3 /* n_attributes */); - cogl_primitive_set_indices (priv->primitive, - indices, - n_indices); - - if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DEFORM_TILES)) - { - priv->lines_primitive = - cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_LINE_STRIP, - priv->n_vertices, - attributes, - 2 /* n_attributes */); - cogl_primitive_set_indices (priv->lines_primitive, - indices, - n_indices); - } - - g_object_unref (indices); - - for (i = 0; i < 3; i++) - g_object_unref (attributes[i]); - - priv->is_dirty = TRUE; -} - -static inline void -clutter_deform_effect_free_back_pipeline (ClutterDeformEffect *self) -{ - ClutterDeformEffectPrivate *priv = - clutter_deform_effect_get_instance_private (self); - - g_clear_object (&priv->back_pipeline); -} - -static void -clutter_deform_effect_finalize (GObject *gobject) -{ - ClutterDeformEffect *self = CLUTTER_DEFORM_EFFECT (gobject); - - clutter_deform_effect_free_arrays (self); - clutter_deform_effect_free_back_pipeline (self); - - G_OBJECT_CLASS (clutter_deform_effect_parent_class)->finalize (gobject); -} - -static void -clutter_deform_effect_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterDeformEffect *self = CLUTTER_DEFORM_EFFECT (gobject); - ClutterDeformEffectPrivate *priv = - clutter_deform_effect_get_instance_private (self); - - switch (prop_id) - { - case PROP_X_TILES: - clutter_deform_effect_set_n_tiles (self, g_value_get_uint (value), - priv->y_tiles); - break; - - case PROP_Y_TILES: - clutter_deform_effect_set_n_tiles (self, priv->x_tiles, - g_value_get_uint (value)); - break; - - case PROP_BACK_MATERIAL: - clutter_deform_effect_set_back_material (self, g_value_get_object (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_deform_effect_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterDeformEffect *effect = CLUTTER_DEFORM_EFFECT (gobject); - ClutterDeformEffectPrivate *priv = - clutter_deform_effect_get_instance_private (effect); - - switch (prop_id) - { - case PROP_X_TILES: - g_value_set_uint (value, priv->x_tiles); - break; - - case PROP_Y_TILES: - g_value_set_uint (value, priv->y_tiles); - break; - - case PROP_BACK_MATERIAL: - g_value_set_object (value, priv->back_pipeline); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_deform_effect_class_init (ClutterDeformEffectClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); - ClutterOffscreenEffectClass *offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); - - klass->deform_vertex = clutter_deform_effect_real_deform_vertex; - - /** - * ClutterDeformEffect:x-tiles: - * - * The number of horizontal tiles. The bigger the number, the - * smaller the tiles - */ - obj_props[PROP_X_TILES] = - g_param_spec_uint ("x-tiles", NULL, NULL, - 1, G_MAXUINT, - DEFAULT_N_TILES, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterDeformEffect:y-tiles: - * - * The number of vertical tiles. The bigger the number, the - * smaller the tiles - */ - obj_props[PROP_Y_TILES] = - g_param_spec_uint ("y-tiles", NULL, NULL, - 1, G_MAXUINT, - DEFAULT_N_TILES, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterDeformEffect:back-material: - * - * A material to be used when painting the back of the actor - * to which this effect has been applied - * - * By default, no material will be used - */ - obj_props[PROP_BACK_MATERIAL] = - g_param_spec_object ("back-material", NULL, NULL, - COGL_TYPE_PIPELINE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - gobject_class->finalize = clutter_deform_effect_finalize; - gobject_class->set_property = clutter_deform_effect_set_property; - gobject_class->get_property = clutter_deform_effect_get_property; - g_object_class_install_properties (gobject_class, - PROP_LAST, - obj_props); - - meta_class->set_actor = clutter_deform_effect_set_actor; - - offscreen_class->paint_target = clutter_deform_effect_paint_target; -} - -static void -clutter_deform_effect_init (ClutterDeformEffect *self) -{ - ClutterDeformEffectPrivate *priv = - clutter_deform_effect_get_instance_private (self); - - priv->x_tiles = priv->y_tiles = DEFAULT_N_TILES; - priv->back_pipeline = NULL; - - clutter_deform_effect_init_arrays (self); -} - -/** - * clutter_deform_effect_set_back_material: - * @effect: a #ClutterDeformEffect - * @material: (allow-none): a handle to a Cogl material - * - * Sets the material that should be used when drawing the back face - * of the actor during a deformation - * - * The #ClutterDeformEffect will take a reference on the material's - * handle - */ -void -clutter_deform_effect_set_back_material (ClutterDeformEffect *effect, - CoglPipeline *pipeline) -{ - ClutterDeformEffectPrivate *priv; - - g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect)); - g_return_if_fail (pipeline == NULL || COGL_IS_PIPELINE (pipeline)); - - priv = clutter_deform_effect_get_instance_private (effect); - - clutter_deform_effect_free_back_pipeline (effect); - - priv->back_pipeline = pipeline; - if (priv->back_pipeline != NULL) - g_object_ref (priv->back_pipeline); - - clutter_deform_effect_invalidate (effect); -} - -/** - * clutter_deform_effect_get_back_material: - * @effect: a #ClutterDeformEffect - * - * Retrieves the handle to the back face material used by @effect - * - * Return value: (transfer none): a handle for the material, or %NULL. - * The returned material is owned by the #ClutterDeformEffect and it - * should not be freed directly - */ -CoglPipeline* -clutter_deform_effect_get_back_material (ClutterDeformEffect *effect) -{ - ClutterDeformEffectPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect), NULL); - - priv = clutter_deform_effect_get_instance_private (effect); - return priv->back_pipeline; -} - -/** - * clutter_deform_effect_set_n_tiles: - * @effect: a #ClutterDeformEffect - * @x_tiles: number of horizontal tiles - * @y_tiles: number of vertical tiles - * - * Sets the number of horizontal and vertical tiles to be used - * when applying the effect - * - * More tiles allow a finer grained deformation at the expenses - * of computation - */ -void -clutter_deform_effect_set_n_tiles (ClutterDeformEffect *effect, - guint x_tiles, - guint y_tiles) -{ - ClutterDeformEffectPrivate *priv; - gboolean tiles_changed = FALSE; - - g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect)); - g_return_if_fail (x_tiles > 0 && y_tiles > 0); - - priv = clutter_deform_effect_get_instance_private (effect); - - g_object_freeze_notify (G_OBJECT (effect)); - - if (priv->x_tiles != x_tiles) - { - priv->x_tiles = x_tiles; - - g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_X_TILES]); - - tiles_changed = TRUE; - } - - if (priv->y_tiles != y_tiles) - { - priv->y_tiles = y_tiles; - - g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_Y_TILES]); - - tiles_changed = TRUE; - } - - if (tiles_changed) - { - clutter_deform_effect_init_arrays (effect); - clutter_deform_effect_invalidate (effect); - } - - g_object_thaw_notify (G_OBJECT (effect)); -} - -/** - * clutter_deform_effect_get_n_tiles: - * @effect: a #ClutterDeformEffect - * @x_tiles: (out): return location for the number of horizontal tiles, - * or %NULL - * @y_tiles: (out): return location for the number of vertical tiles, - * or %NULL - * - * Retrieves the number of horizontal and vertical tiles used to sub-divide - * the actor's geometry during the effect - */ -void -clutter_deform_effect_get_n_tiles (ClutterDeformEffect *effect, - guint *x_tiles, - guint *y_tiles) -{ - ClutterDeformEffectPrivate *priv; - - g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect)); - - priv = clutter_deform_effect_get_instance_private (effect); - if (x_tiles != NULL) - *x_tiles = priv->x_tiles; - - if (y_tiles != NULL) - *y_tiles = priv->y_tiles; -} - -/** - * clutter_deform_effect_invalidate: - * @effect: a #ClutterDeformEffect - * - * Invalidates the `effect`'s vertices and, if it is associated - * to an actor, it will queue a redraw - */ -void -clutter_deform_effect_invalidate (ClutterDeformEffect *effect) -{ - ClutterActor *actor; - ClutterDeformEffectPrivate *priv; - - g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect)); - - priv = clutter_deform_effect_get_instance_private (effect); - if (priv->is_dirty) - return; - - priv->is_dirty = TRUE; - - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); - if (actor != NULL) - clutter_effect_queue_repaint (CLUTTER_EFFECT (effect)); -} diff --git a/mutter/clutter/clutter/clutter-deform-effect.h b/mutter/clutter/clutter/clutter-deform-effect.h deleted file mode 100644 index 74771fe..0000000 --- a/mutter/clutter/clutter/clutter-deform-effect.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl.h" -#include "clutter/clutter-offscreen-effect.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_DEFORM_EFFECT (clutter_deform_effect_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterDeformEffect, - clutter_deform_effect, - CLUTTER, - DEFORM_EFFECT, - ClutterOffscreenEffect) - -/** - * ClutterDeformEffectClass: - * @deform_vertex: virtual function; sub-classes should override this - * function to compute the deformation of each vertex - * - * The #ClutterDeformEffectClass structure contains - * only private data - */ -struct _ClutterDeformEffectClass -{ - /*< private >*/ - ClutterOffscreenEffectClass parent_class; - - /*< public >*/ - void (* deform_vertex) (ClutterDeformEffect *effect, - gfloat width, - gfloat height, - CoglTextureVertex *vertex); -}; - -CLUTTER_EXPORT -void clutter_deform_effect_set_back_material (ClutterDeformEffect *effect, - CoglPipeline *material); -CLUTTER_EXPORT -CoglPipeline* clutter_deform_effect_get_back_material (ClutterDeformEffect *effect); -CLUTTER_EXPORT -void clutter_deform_effect_set_n_tiles (ClutterDeformEffect *effect, - guint x_tiles, - guint y_tiles); -CLUTTER_EXPORT -void clutter_deform_effect_get_n_tiles (ClutterDeformEffect *effect, - guint *x_tiles, - guint *y_tiles); - -CLUTTER_EXPORT -void clutter_deform_effect_invalidate (ClutterDeformEffect *effect); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-desaturate-effect.c b/mutter/clutter/clutter/clutter-desaturate-effect.c deleted file mode 100644 index 805eb54..0000000 --- a/mutter/clutter/clutter/clutter-desaturate-effect.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterDesaturateEffect: - * - * A desaturation effect - * - * #ClutterDesaturateEffect is a sub-class of #ClutterEffect that - * desaturates the color of an actor and its contents. The strength - * of the desaturation effect is controllable and animatable through - * the #ClutterDesaturateEffect:factor property. - */ - -#include "config.h" - -#include - -#include "clutter/clutter-desaturate-effect.h" - -#include "cogl/cogl.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-private.h" - -typedef struct _ClutterDesaturateEffectPrivate -{ - /* the desaturation factor, also known as "strength" */ - gdouble factor; - - gint factor_uniform; - - gint tex_width; - gint tex_height; - - CoglPipeline *pipeline; -} ClutterDesaturateEffectPrivate; - - -/* the magic gray vec3 has been taken from the NTSC conversion weights - * as defined by: - * - * "OpenGL Superbible, 4th edition" - * -- Richard S. Wright Jr, Benjamin Lipchak, Nicholas Haemel - * Addison-Wesley - */ -static const gchar *desaturate_glsl_declarations = - "uniform float factor;\n" - "\n" - "vec3 desaturate (const vec3 color, const float desaturation)\n" - "{\n" - " const vec3 gray_conv = vec3 (0.299, 0.587, 0.114);\n" - " vec3 gray = vec3 (dot (gray_conv, color));\n" - " return vec3 (mix (color.rgb, gray, desaturation));\n" - "}\n"; - -static const gchar *desaturate_glsl_source = - " cogl_color_out.rgb = desaturate (cogl_color_out.rgb, factor);\n"; - -enum -{ - PROP_0, - - PROP_FACTOR, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterDesaturateEffect, - clutter_desaturate_effect, - CLUTTER_TYPE_OFFSCREEN_EFFECT); - -static CoglPipeline * -clutter_desaturate_effect_create_pipeline (ClutterOffscreenEffect *effect, - CoglTexture *texture) -{ - ClutterDesaturateEffect *desaturate_effect = - CLUTTER_DESATURATE_EFFECT (effect); - ClutterDesaturateEffectPrivate *priv = - clutter_desaturate_effect_get_instance_private (desaturate_effect); - - cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture); - - return g_object_ref (priv->pipeline); -} - -static void -clutter_desaturate_effect_dispose (GObject *gobject) -{ - ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (gobject); - ClutterDesaturateEffectPrivate *priv = - clutter_desaturate_effect_get_instance_private (self); - - g_clear_object (&priv->pipeline); - - G_OBJECT_CLASS (clutter_desaturate_effect_parent_class)->dispose (gobject); -} - -static void -clutter_desaturate_effect_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterDesaturateEffect *effect = CLUTTER_DESATURATE_EFFECT (gobject); - - switch (prop_id) - { - case PROP_FACTOR: - clutter_desaturate_effect_set_factor (effect, - g_value_get_double (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_desaturate_effect_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterDesaturateEffect *effect = CLUTTER_DESATURATE_EFFECT (gobject); - ClutterDesaturateEffectPrivate *priv = - clutter_desaturate_effect_get_instance_private (effect); - - switch (prop_id) - { - case PROP_FACTOR: - g_value_set_double (value, priv->factor); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -update_factor_uniform (ClutterDesaturateEffect *self) -{ - ClutterDesaturateEffectPrivate *priv = - clutter_desaturate_effect_get_instance_private (self); - - if (priv->factor_uniform > -1) - cogl_pipeline_set_uniform_1f (priv->pipeline, - priv->factor_uniform, - priv->factor); -} - -static void -clutter_desaturate_effect_class_init (ClutterDesaturateEffectClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterOffscreenEffectClass *offscreen_class; - - offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); - offscreen_class->create_pipeline = clutter_desaturate_effect_create_pipeline; - - /** - * ClutterDesaturateEffect:factor: - * - * The desaturation factor, between 0.0 (no desaturation) and 1.0 (full - * desaturation). - */ - obj_props[PROP_FACTOR] = - g_param_spec_double ("factor", NULL, NULL, - 0.0, 1.0, - 1.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - gobject_class->dispose = clutter_desaturate_effect_dispose; - gobject_class->set_property = clutter_desaturate_effect_set_property; - gobject_class->get_property = clutter_desaturate_effect_get_property; - - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); -} - -static void -clutter_desaturate_effect_init (ClutterDesaturateEffect *self) -{ - ClutterDesaturateEffectClass *klass = CLUTTER_DESATURATE_EFFECT_GET_CLASS (self); - ClutterDesaturateEffectPrivate *priv = - clutter_desaturate_effect_get_instance_private (self); - - if (G_UNLIKELY (klass->base_pipeline == NULL)) - { - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - CoglSnippet *snippet; - - klass->base_pipeline = cogl_pipeline_new (ctx); - - snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, - desaturate_glsl_declarations, - desaturate_glsl_source); - cogl_pipeline_add_snippet (klass->base_pipeline, snippet); - g_object_unref (snippet); - - cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0); - } - - priv->pipeline = cogl_pipeline_copy (klass->base_pipeline); - - priv->factor_uniform = - cogl_pipeline_get_uniform_location (priv->pipeline, "factor"); - - priv->factor = 1.0; - - update_factor_uniform (self); -} - -/** - * clutter_desaturate_effect_new: - * @factor: the desaturation factor, between 0.0 and 1.0 - * - * Creates a new #ClutterDesaturateEffect to be used with - * [method@Clutter.Actor.add_effect] - * - * Return value: the newly created #ClutterDesaturateEffect or %NULL - */ -ClutterEffect * -clutter_desaturate_effect_new (gdouble factor) -{ - g_return_val_if_fail (factor >= 0.0 && factor <= 1.0, NULL); - - return g_object_new (CLUTTER_TYPE_DESATURATE_EFFECT, - "factor", factor, - NULL); -} - -/** - * clutter_desaturate_effect_set_factor: - * @effect: a #ClutterDesaturateEffect - * @factor: the desaturation factor, between 0.0 and 1.0 - * - * Sets the desaturation factor for @effect, with 0.0 being "do not desaturate" - * and 1.0 being "fully desaturate" - */ -void -clutter_desaturate_effect_set_factor (ClutterDesaturateEffect *effect, - double factor) -{ - ClutterDesaturateEffectPrivate *priv; - - g_return_if_fail (CLUTTER_IS_DESATURATE_EFFECT (effect)); - g_return_if_fail (factor >= 0.0 && factor <= 1.0); - - priv = clutter_desaturate_effect_get_instance_private (effect); - if (fabs (priv->factor - factor) >= 0.00001) - { - priv->factor = factor; - update_factor_uniform (effect); - - clutter_effect_queue_repaint (CLUTTER_EFFECT (effect)); - - g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_FACTOR]); - } -} - -/** - * clutter_desaturate_effect_get_factor: - * @effect: a #ClutterDesaturateEffect - * - * Retrieves the desaturation factor of @effect - * - * Return value: the desaturation factor - */ -gdouble -clutter_desaturate_effect_get_factor (ClutterDesaturateEffect *effect) -{ - ClutterDesaturateEffectPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_DESATURATE_EFFECT (effect), 0.0); - - priv = clutter_desaturate_effect_get_instance_private (effect); - return priv->factor; -} diff --git a/mutter/clutter/clutter/clutter-desaturate-effect.h b/mutter/clutter/clutter/clutter-desaturate-effect.h deleted file mode 100644 index bd6c429..0000000 --- a/mutter/clutter/clutter/clutter-desaturate-effect.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-effect.h" -#include "clutter/clutter-offscreen-effect.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_DESATURATE_EFFECT (clutter_desaturate_effect_get_type ()) - -struct _ClutterDesaturateEffectClass -{ - ClutterOffscreenEffectClass parent_class; - - CoglPipeline *base_pipeline; -}; - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterDesaturateEffect, - clutter_desaturate_effect, - CLUTTER, DESATURATE_EFFECT, - ClutterOffscreenEffect) - -CLUTTER_EXPORT -ClutterEffect *clutter_desaturate_effect_new (gdouble factor); - -CLUTTER_EXPORT -void clutter_desaturate_effect_set_factor (ClutterDesaturateEffect *effect, - gdouble factor); -CLUTTER_EXPORT -gdouble clutter_desaturate_effect_get_factor (ClutterDesaturateEffect *effect); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-easing.c b/mutter/clutter/clutter/clutter-easing.c deleted file mode 100644 index 635c7f4..0000000 --- a/mutter/clutter/clutter/clutter-easing.c +++ /dev/null @@ -1,555 +0,0 @@ -#include "config.h" - -#include "clutter/clutter-easing.h" - -#include - -double -clutter_linear (double t, - double d) -{ - return t / d; -} - -double -clutter_ease_in_quad (double t, - double d) -{ - double p = t / d; - - return p * p; -} - -double -clutter_ease_out_quad (double t, - double d) -{ - double p = t / d; - - return -1.0 * p * (p - 2); -} - -double -clutter_ease_in_out_quad (double t, - double d) -{ - double p = t / (d / 2); - - if (p < 1) - return 0.5 * p * p; - - p -= 1; - - return -0.5 * (p * (p - 2) - 1); -} - -double -clutter_ease_in_cubic (double t, - double d) -{ - double p = t / d; - - return p * p * p; -} - -double -clutter_ease_out_cubic (double t, - double d) -{ - double p = t / d - 1; - - return p * p * p + 1; -} - -double -clutter_ease_in_out_cubic (double t, - double d) -{ - double p = t / (d / 2); - - if (p < 1) - return 0.5 * p * p * p; - - p -= 2; - - return 0.5 * (p * p * p + 2); -} - -double -clutter_ease_in_quart (double t, - double d) -{ - double p = t / d; - - return p * p * p * p; -} - -double -clutter_ease_out_quart (double t, - double d) -{ - double p = t / d - 1; - - return -1.0 * (p * p * p * p - 1); -} - -double -clutter_ease_in_out_quart (double t, - double d) -{ - double p = t / (d / 2); - - if (p < 1) - return 0.5 * p * p * p * p; - - p -= 2; - - return -0.5 * (p * p * p * p - 2); -} - -double -clutter_ease_in_quint (double t, - double d) - { - double p = t / d; - - return p * p * p * p * p; -} - -double -clutter_ease_out_quint (double t, - double d) -{ - double p = t / d - 1; - - return p * p * p * p * p + 1; -} - -double -clutter_ease_in_out_quint (double t, - double d) -{ - double p = t / (d / 2); - - if (p < 1) - return 0.5 * p * p * p * p * p; - - p -= 2; - - return 0.5 * (p * p * p * p * p + 2); -} - -double -clutter_ease_in_sine (double t, - double d) -{ - return -1.0 * cos (t / d * G_PI_2) + 1.0; -} - -double -clutter_ease_out_sine (double t, - double d) -{ - return sin (t / d * G_PI_2); -} - -double -clutter_ease_in_out_sine (double t, - double d) -{ - return -0.5 * (cos (G_PI * t / d) - 1); -} - -double -clutter_ease_in_expo (double t, - double d) -{ - return (t == 0) ? 0.0 : pow (2, 10 * (t / d - 1)); -} - -double -clutter_ease_out_expo (double t, - double d) -{ - return (t == d) ? 1.0 : -pow (2, -10 * t / d) + 1; -} - -double -clutter_ease_in_out_expo (double t, - double d) -{ - double p; - - if (t == 0) - return 0.0; - - if (t == d) - return 1.0; - - p = t / (d / 2); - - if (p < 1) - return 0.5 * pow (2, 10 * (p - 1)); - - p -= 1; - - return 0.5 * (-pow (2, -10 * p) + 2); -} - -double -clutter_ease_in_circ (double t, - double d) -{ - double p = t / d; - - return -1.0 * (sqrt (1 - p * p) - 1); -} - -double -clutter_ease_out_circ (double t, - double d) -{ - double p = t / d - 1; - - return sqrt (1 - p * p); -} - -double -clutter_ease_in_out_circ (double t, - double d) -{ - double p = t / (d / 2); - - if (p < 1) - return -0.5 * (sqrt (1 - p * p) - 1); - - p -= 2; - - return 0.5 * (sqrt (1 - p * p) + 1); -} - -double -clutter_ease_in_elastic (double t, - double d) -{ - double p = d * .3; - double s = p / 4; - double q = t / d; - - if (q == 1) - return 1.0; - - q -= 1; - - return -(pow (2, 10 * q) * sin ((q * d - s) * (2 * G_PI) / p)); -} - -double -clutter_ease_out_elastic (double t, - double d) -{ - double p = d * .3; - double s = p / 4; - double q = t / d; - - if (q == 1) - return 1.0; - - return pow (2, -10 * q) * sin ((q * d - s) * (2 * G_PI) / p) + 1.0; -} - -double -clutter_ease_in_out_elastic (double t, - double d) -{ - double p = d * (.3 * 1.5); - double s = p / 4; - double q = t / (d / 2); - - if (q == 2) - return 1.0; - - if (q < 1) - { - q -= 1; - - return -.5 * (pow (2, 10 * q) * sin ((q * d - s) * (2 * G_PI) / p)); - } - else - { - q -= 1; - - return pow (2, -10 * q) - * sin ((q * d - s) * (2 * G_PI) / p) - * .5 + 1.0; - } -} - -double -clutter_ease_in_back (double t, - double d) -{ - double p = t / d; - - return p * p * ((1.70158 + 1) * p - 1.70158); -} - -double -clutter_ease_out_back (double t, - double d) -{ - double p = t / d - 1; - - return p * p * ((1.70158 + 1) * p + 1.70158) + 1; -} - -double -clutter_ease_in_out_back (double t, - double d) -{ - double p = t / (d / 2); - double s = 1.70158 * 1.525; - - if (p < 1) - return 0.5 * (p * p * ((s + 1) * p - s)); - - p -= 2; - - return 0.5 * (p * p * ((s + 1) * p + s) + 2); -} - -static inline double -ease_out_bounce_internal (double t, - double d) -{ - double p = t / d; - - if (p < (1 / 2.75)) - { - return 7.5625 * p * p; - } - else if (p < (2 / 2.75)) - { - p -= (1.5 / 2.75); - - return 7.5625 * p * p + .75; - } - else if (p < (2.5 / 2.75)) - { - p -= (2.25 / 2.75); - - return 7.5625 * p * p + .9375; - } - else - { - p -= (2.625 / 2.75); - - return 7.5625 * p * p + .984375; - } -} - -static inline double -ease_in_bounce_internal (double t, - double d) -{ - return 1.0 - ease_out_bounce_internal (d - t, d); -} - -double -clutter_ease_in_bounce (double t, - double d) -{ - return ease_in_bounce_internal (t, d); -} - -double -clutter_ease_out_bounce (double t, - double d) -{ - return ease_out_bounce_internal (t, d); -} - -double -clutter_ease_in_out_bounce (double t, - double d) -{ - if (t < d / 2) - return ease_in_bounce_internal (t * 2, d) * 0.5; - else - return ease_out_bounce_internal (t * 2 - d, d) * 0.5 + 1.0 * 0.5; -} - -static inline double -ease_steps_end (double p, - int n_steps) -{ - return floor (p * (double) n_steps) / (double) n_steps; -} - -double -clutter_ease_steps_start (double t, - double d, - int n_steps) -{ - return 1.0 - ease_steps_end (1.0 - (t / d), n_steps); -} - -double -clutter_ease_steps_end (double t, - double d, - int n_steps) -{ - return ease_steps_end ((t / d), n_steps); -} - -static inline double -x_for_t (double t, - double x_1, - double x_2) -{ - double omt = 1.0 - t; - - return 3.0 * omt * omt * t * x_1 - + 3.0 * omt * t * t * x_2 - + t * t * t; -} - -static inline double -y_for_t (double t, - double y_1, - double y_2) -{ - double omt = 1.0 - t; - - return 3.0 * omt * omt * t * y_1 - + 3.0 * omt * t * t * y_2 - + t * t * t; -} - -static inline double -t_for_x (double x, - double x_1, - double x_2) -{ - double min_t = 0, max_t = 1; - int i; - - for (i = 0; i < 30; ++i) - { - double guess_t = (min_t + max_t) / 2.0; - double guess_x = x_for_t (guess_t, x_1, x_2); - - if (x < guess_x) - max_t = guess_t; - else - min_t = guess_t; - } - - return (min_t + max_t) / 2.0; -} - -double -clutter_ease_cubic_bezier (double t, - double d, - double x_1, - double y_1, - double x_2, - double y_2) -{ - double p = t / d; - - if (p == 0.0) - return 0.0; - - if (p == 1.0) - return 1.0; - - return y_for_t (t_for_x (p, x_1, x_2), y_1, y_2); -} - -/*< private > - * _clutter_animation_modes: - * - * A mapping of animation modes and easing functions. - */ -static const struct { - ClutterAnimationMode mode; - ClutterEasingFunc func; - const char *name; -} _clutter_animation_modes[] = { - { CLUTTER_CUSTOM_MODE, NULL, "custom" }, - - { CLUTTER_LINEAR, clutter_linear, "linear" }, - { CLUTTER_EASE_IN_QUAD, clutter_ease_in_quad, "easeInQuad" }, - { CLUTTER_EASE_OUT_QUAD, clutter_ease_out_quad, "easeOutQuad" }, - { CLUTTER_EASE_IN_OUT_QUAD, clutter_ease_in_out_quad, "easeInOutQuad" }, - { CLUTTER_EASE_IN_CUBIC, clutter_ease_in_cubic, "easeInCubic" }, - { CLUTTER_EASE_OUT_CUBIC, clutter_ease_out_cubic, "easeOutCubic" }, - { CLUTTER_EASE_IN_OUT_CUBIC, clutter_ease_in_out_cubic, "easeInOutCubic" }, - { CLUTTER_EASE_IN_QUART, clutter_ease_in_quart, "easeInQuart" }, - { CLUTTER_EASE_OUT_QUART, clutter_ease_out_quart, "easeOutQuart" }, - { CLUTTER_EASE_IN_OUT_QUART, clutter_ease_in_out_quart, "easeInOutQuart" }, - { CLUTTER_EASE_IN_QUINT, clutter_ease_in_quint, "easeInQuint" }, - { CLUTTER_EASE_OUT_QUINT, clutter_ease_out_quint, "easeOutQuint" }, - { CLUTTER_EASE_IN_OUT_QUINT, clutter_ease_in_out_quint, "easeInOutQuint" }, - { CLUTTER_EASE_IN_SINE, clutter_ease_in_sine, "easeInSine" }, - { CLUTTER_EASE_OUT_SINE, clutter_ease_out_sine, "easeOutSine" }, - { CLUTTER_EASE_IN_OUT_SINE, clutter_ease_in_out_sine, "easeInOutSine" }, - { CLUTTER_EASE_IN_EXPO, clutter_ease_in_expo, "easeInExpo" }, - { CLUTTER_EASE_OUT_EXPO, clutter_ease_out_expo, "easeOutExpo" }, - { CLUTTER_EASE_IN_OUT_EXPO, clutter_ease_in_out_expo, "easeInOutExpo" }, - { CLUTTER_EASE_IN_CIRC, clutter_ease_in_circ, "easeInCirc" }, - { CLUTTER_EASE_OUT_CIRC, clutter_ease_out_circ, "easeOutCirc" }, - { CLUTTER_EASE_IN_OUT_CIRC, clutter_ease_in_out_circ, "easeInOutCirc" }, - { CLUTTER_EASE_IN_ELASTIC, clutter_ease_in_elastic, "easeInElastic" }, - { CLUTTER_EASE_OUT_ELASTIC, clutter_ease_out_elastic, "easeOutElastic" }, - { CLUTTER_EASE_IN_OUT_ELASTIC, clutter_ease_in_out_elastic, "easeInOutElastic" }, - { CLUTTER_EASE_IN_BACK, clutter_ease_in_back, "easeInBack" }, - { CLUTTER_EASE_OUT_BACK, clutter_ease_out_back, "easeOutBack" }, - { CLUTTER_EASE_IN_OUT_BACK, clutter_ease_in_out_back, "easeInOutBack" }, - { CLUTTER_EASE_IN_BOUNCE, clutter_ease_in_bounce, "easeInBounce" }, - { CLUTTER_EASE_OUT_BOUNCE, clutter_ease_out_bounce, "easeOutBounce" }, - { CLUTTER_EASE_IN_OUT_BOUNCE, clutter_ease_in_out_bounce, "easeInOutBounce" }, - - /* the parametrized functions need a cast */ - { CLUTTER_STEPS, (ClutterEasingFunc) clutter_ease_steps_end, "steps" }, - { CLUTTER_STEP_START, (ClutterEasingFunc) clutter_ease_steps_start, "stepStart" }, - { CLUTTER_STEP_END, (ClutterEasingFunc) clutter_ease_steps_end, "stepEnd" }, - - { CLUTTER_CUBIC_BEZIER, (ClutterEasingFunc) clutter_ease_cubic_bezier, "cubicBezier" }, - { CLUTTER_EASE, (ClutterEasingFunc) clutter_ease_cubic_bezier, "ease" }, - { CLUTTER_EASE_IN, (ClutterEasingFunc) clutter_ease_cubic_bezier, "easeIn" }, - { CLUTTER_EASE_OUT, (ClutterEasingFunc) clutter_ease_cubic_bezier, "easeOut" }, - { CLUTTER_EASE_IN_OUT, (ClutterEasingFunc) clutter_ease_cubic_bezier, "easeInOut" }, - - { CLUTTER_ANIMATION_LAST, NULL, "sentinel" }, -}; - -ClutterEasingFunc -clutter_get_easing_func_for_mode (ClutterAnimationMode mode) -{ - g_assert (_clutter_animation_modes[mode].mode == mode); - g_assert (_clutter_animation_modes[mode].func != NULL); - - return _clutter_animation_modes[mode].func; -} - -const char * -clutter_get_easing_name_for_mode (ClutterAnimationMode mode) -{ - g_assert (_clutter_animation_modes[mode].mode == mode); - g_assert (_clutter_animation_modes[mode].func != NULL); - - return _clutter_animation_modes[mode].name; -} - -double -clutter_easing_for_mode (ClutterAnimationMode mode, - double t, - double d) -{ - g_assert (_clutter_animation_modes[mode].mode == mode); - g_assert (_clutter_animation_modes[mode].func != NULL); - - return _clutter_animation_modes[mode].func (t, d); -} diff --git a/mutter/clutter/clutter/clutter-easing.h b/mutter/clutter/clutter/clutter-easing.h deleted file mode 100644 index ff64646..0000000 --- a/mutter/clutter/clutter/clutter-easing.h +++ /dev/null @@ -1,139 +0,0 @@ -#pragma once - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -/*< private > - * ClutterEasingFunc: - * @t: elapsed time - * @d: total duration - * - * Internal type for the easing functions used by Clutter. - * - * Return value: the interpolated value, between -1.0 and 2.0 - */ -typedef double (* ClutterEasingFunc) (double t, double d); - -G_GNUC_INTERNAL -ClutterEasingFunc clutter_get_easing_func_for_mode (ClutterAnimationMode mode); - -G_GNUC_INTERNAL -const char * clutter_get_easing_name_for_mode (ClutterAnimationMode mode); - -G_GNUC_INTERNAL -double clutter_easing_for_mode (ClutterAnimationMode mode, - double t, - double d); - -G_GNUC_INTERNAL -double clutter_linear (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_quad (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_out_quad (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_out_quad (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_cubic (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_out_cubic (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_out_cubic (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_quart (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_out_quart (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_out_quart (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_quint (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_out_quint (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_out_quint (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_sine (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_out_sine (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_out_sine (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_expo (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_out_expo (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_out_expo (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_circ (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_out_circ (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_out_circ (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_elastic (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_out_elastic (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_out_elastic (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_back (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_out_back (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_out_back (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_bounce (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_out_bounce (double t, - double d); -G_GNUC_INTERNAL -double clutter_ease_in_out_bounce (double t, - double d); - -G_GNUC_INTERNAL -double clutter_ease_steps_start (double t, - double d, - int steps); -G_GNUC_INTERNAL -double clutter_ease_steps_end (double t, - double d, - int steps); -G_GNUC_INTERNAL -double clutter_ease_cubic_bezier (double t, - double d, - double x_1, - double y_1, - double x_2, - double y_2); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-effect-private.h b/mutter/clutter/clutter/clutter-effect-private.h deleted file mode 100644 index c99d424..0000000 --- a/mutter/clutter/clutter/clutter-effect-private.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "clutter/clutter-effect.h" - -G_BEGIN_DECLS - -gboolean _clutter_effect_modify_paint_volume (ClutterEffect *effect, - ClutterPaintVolume *volume); -gboolean _clutter_effect_has_custom_paint_volume (ClutterEffect *effect); -void _clutter_effect_paint (ClutterEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context, - ClutterEffectPaintFlags flags); -void _clutter_effect_pick (ClutterEffect *effect, - ClutterPickContext *pick_context); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-effect.c b/mutter/clutter/clutter/clutter-effect.c deleted file mode 100644 index 29c39a1..0000000 --- a/mutter/clutter/clutter/clutter-effect.c +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterEffect: - * - * Base class for actor effects - * - * The #ClutterEffect class provides a default type and API for creating - * effects for generic actors. - * - * Effects are a #ClutterActorMeta sub-class that modify the way an actor - * is painted in a way that is not part of the actor's implementation. - * - * Effects should be the preferred way to affect the paint sequence of an - * actor without sub-classing the actor itself and overriding the - * [vfunc@Clutter.Actor.paint] virtual function. - * - * ## Implementing a ClutterEffect - * - * Creating a sub-class of #ClutterEffect requires overriding the - * [vfunc@Clutter.Effect.paint] method. The implementation of the function should look - * something like this: - * - * ```c - * void effect_paint (ClutterEffect *effect, ClutterEffectPaintFlags flags) - * { - * // Set up initialisation of the paint such as binding a - * // CoglOffscreen or other operations - * - * // Chain to the next item in the paint sequence. This will either call - * // ‘paint’ on the next effect or just paint the actor if this is - * // the last effect. - * ClutterActor *actor = - * clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); - * - * clutter_actor_continue_paint (actor); - * - * // perform any cleanup of state, such as popping the CoglOffscreen - * } - * ``` - * - * The effect can optionally avoid calling clutter_actor_continue_paint() to skip any - * further stages of the paint sequence. This is useful for example if the effect - * contains a cached image of the actor. In that case it can optimise painting by - * avoiding the actor paint and instead painting the cached image. - * - * The %CLUTTER_EFFECT_PAINT_ACTOR_DIRTY flag is useful in this case. Clutter will set - * this flag when a redraw has been queued on the actor since it was last painted. The - * effect can use this information to decide if the cached image is still valid. - * - * ## A simple ClutterEffect implementation - * - * The example below creates two rectangles: one will be painted "behind" the actor, - * while another will be painted "on top" of the actor. - * - * The #ClutterActorMetaClass.set_actor() implementation will create the two materials - * used for the two different rectangles; the #ClutterEffectClass.paint() implementation - * will paint the first material using cogl_rectangle(), before continuing and then it - * will paint paint the second material after. - * - * ```c - * typedef struct { - * ClutterEffect parent_instance; - * - * CoglPipeline *rect_1; - * CoglPipeline *rect_2; - * } MyEffect; - * - * typedef struct _ClutterEffectClass MyEffectClass; - * - * G_DEFINE_TYPE (MyEffect, my_effect, CLUTTER_TYPE_EFFECT); - * - * static void - * my_effect_set_actor (ClutterActorMeta *meta, - * ClutterActor *actor) - * { - * MyEffect *self = MY_EFFECT (meta); - * CoglColor color; - * - * // Clear the previous state // - * if (self->rect_1) - * { - * g_object_unref (self->rect_1); - * self->rect_1 = NULL; - * } - * - * if (self->rect_2) - * { - * g_object_unref (self->rect_2); - * self->rect_2 = NULL; - * } - * - * // Maintain a pointer to the actor - * self->actor = actor; - * - * // If we've been detached by the actor then we should just bail out here - * if (self->actor == NULL) - * return; - * - * // Create a red material - * self->rect_1 = cogl_pipeline_new (); - * cogl_color_init_from_4f (&color, 1.0, 1.0, 1.0, 1.0); - * cogl_pipeline_set_color (self->rect_1, &color); - * - * // Create a green material - * self->rect_2 = cogl_pipeline_new (); - * cogl_color_init_from_4f (&color, 0.0, 1.0, 0.0, 1.0); - * cogl_pipeline_set_color (self->rect_2, &color); - * } - * - * static gboolean - * my_effect_paint (ClutterEffect *effect) - * { - * MyEffect *self = MY_EFFECT (effect); - * gfloat width, height; - * - * clutter_actor_get_size (self->actor, &width, &height); - * - * // Paint the first rectangle in the upper left quadrant - * cogl_set_source (self->rect_1); - * cogl_rectangle (0, 0, width / 2, height / 2); - * - * // Continue to the rest of the paint sequence - * clutter_actor_continue_paint (self->actor); - * - * // Paint the second rectangle in the lower right quadrant - * cogl_set_source (self->rect_2); - * cogl_rectangle (width / 2, height / 2, width, height); - * } - * - * static void - * my_effect_class_init (MyEffectClass *klass) - * { - * ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); - * - * meta_class->set_actor = my_effect_set_actor; - * - * klass->paint = my_effect_paint; - * } - * ``` - */ - -#include "config.h" - -#include "clutter/clutter-effect.h" - -#include "clutter/clutter-actor-meta-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-effect-private.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-paint-node-private.h" -#include "clutter/clutter-paint-nodes.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-actor-private.h" - -G_DEFINE_ABSTRACT_TYPE (ClutterEffect, - clutter_effect, - CLUTTER_TYPE_ACTOR_META); - -static gboolean -clutter_effect_real_pre_paint (ClutterEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - return TRUE; -} - -static void -clutter_effect_real_post_paint (ClutterEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ -} - -static gboolean -clutter_effect_real_modify_paint_volume (ClutterEffect *effect, - ClutterPaintVolume *volume) -{ - return TRUE; -} - -static void -add_actor_node (ClutterEffect *effect, - ClutterPaintNode *node) -{ - ClutterPaintNode *actor_node; - ClutterActor *actor; - - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); - - actor_node = clutter_actor_node_new (actor, -1); - clutter_paint_node_add_child (node, actor_node); - clutter_paint_node_unref (actor_node); -} - -static void -clutter_effect_real_paint_node (ClutterEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context, - ClutterEffectPaintFlags flags) -{ - add_actor_node (effect, node); -} - -static void -clutter_effect_real_paint (ClutterEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context, - ClutterEffectPaintFlags flags) -{ - ClutterEffectClass *effect_class = CLUTTER_EFFECT_GET_CLASS (effect); - gboolean pre_paint_succeeded; - - /* The default implementation provides a compatibility wrapper for - effects that haven't migrated to use the 'paint' virtual yet. This - just calls the old pre and post virtuals before chaining on */ - - pre_paint_succeeded = effect_class->pre_paint (effect, node,paint_context); - - if (pre_paint_succeeded) - { - effect_class->paint_node (effect, node, paint_context, flags); - effect_class->post_paint (effect, node, paint_context); - } - else - { - /* Just paint the actor as fallback */ - add_actor_node (effect, node); - } -} - -static void -clutter_effect_real_pick (ClutterEffect *effect, - ClutterPickContext *pick_context) -{ - ClutterActorMeta *actor_meta = CLUTTER_ACTOR_META (effect); - ClutterActor *actor; - - actor = clutter_actor_meta_get_actor (actor_meta); - clutter_actor_continue_pick (actor, pick_context); -} - -static void -clutter_effect_set_enabled (ClutterActorMeta *meta, - gboolean is_enabled) -{ - ClutterActorMetaClass *parent_class = - CLUTTER_ACTOR_META_CLASS (clutter_effect_parent_class); - ClutterActor *actor; - - actor = clutter_actor_meta_get_actor (meta); - if (actor) - clutter_actor_queue_redraw (actor); - - parent_class->set_enabled (meta, is_enabled); -} - -static void -clutter_effect_class_init (ClutterEffectClass *klass) -{ - ClutterActorMetaClass *actor_meta_class = CLUTTER_ACTOR_META_CLASS (klass); - - actor_meta_class->set_enabled = clutter_effect_set_enabled; - - klass->pre_paint = clutter_effect_real_pre_paint; - klass->post_paint = clutter_effect_real_post_paint; - klass->modify_paint_volume = clutter_effect_real_modify_paint_volume; - klass->paint = clutter_effect_real_paint; - klass->paint_node = clutter_effect_real_paint_node; - klass->pick = clutter_effect_real_pick; -} - -static void -clutter_effect_init (ClutterEffect *self) -{ -} - -void -_clutter_effect_paint (ClutterEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context, - ClutterEffectPaintFlags flags) -{ - g_return_if_fail (CLUTTER_IS_EFFECT (effect)); - - CLUTTER_EFFECT_GET_CLASS (effect)->paint (effect, - node, - paint_context, - flags); -} - -void -_clutter_effect_pick (ClutterEffect *effect, - ClutterPickContext *pick_context) -{ - g_return_if_fail (CLUTTER_IS_EFFECT (effect)); - - CLUTTER_EFFECT_GET_CLASS (effect)->pick (effect, pick_context); -} - -gboolean -_clutter_effect_modify_paint_volume (ClutterEffect *effect, - ClutterPaintVolume *volume) -{ - g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE); - g_return_val_if_fail (volume != NULL, FALSE); - - return CLUTTER_EFFECT_GET_CLASS (effect)->modify_paint_volume (effect, - volume); -} - -gboolean -_clutter_effect_has_custom_paint_volume (ClutterEffect *effect) -{ - g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE); - - return CLUTTER_EFFECT_GET_CLASS (effect)->modify_paint_volume != clutter_effect_real_modify_paint_volume; -} - -/** - * clutter_effect_queue_repaint: - * @effect: A #ClutterEffect which needs redrawing - * - * Queues a repaint of the effect. The effect can detect when the ‘paint’ - * method is called as a result of this function because it will not - * have the %CLUTTER_EFFECT_PAINT_ACTOR_DIRTY flag set. In that case the - * effect is free to assume that the actor has not changed its - * appearance since the last time it was painted so it doesn't need to - * call clutter_actor_continue_paint() if it can draw a cached - * image. This is mostly intended for effects that are using a - * %CoglOffscreen to redirect the actor (such as - * %ClutterOffscreenEffect). In that case the effect can save a bit of - * rendering time by painting the cached texture without causing the - * entire actor to be painted. - * - * This function can be used by effects that have their own animatable - * parameters. For example, an effect which adds a varying degree of a - * red tint to an actor by redirecting it through a CoglOffscreen - * might have a property to specify the level of tint. When this value - * changes, the underlying actor doesn't need to be redrawn so the - * effect can call clutter_effect_queue_repaint() to make sure the - * effect is repainted. - * - * Note however that modifying the position of the parent of an actor - * may change the appearance of the actor because its transformation - * matrix would change. In this case a redraw wouldn't be queued on - * the actor itself so the %CLUTTER_EFFECT_PAINT_ACTOR_DIRTY would still - * not be set. The effect can detect this case by keeping track of the - * last modelview matrix that was used to render the actor and - * verifying that it remains the same in the next paint. - * - * Any other effects that are layered on top of the passed in effect - * will still be passed the %CLUTTER_EFFECT_PAINT_ACTOR_DIRTY flag. If - * anything queues a redraw on the actor without specifying an effect - * or with an effect that is lower in the chain of effects than this - * one then that will override this call. In that case this effect - * will instead be called with the %CLUTTER_EFFECT_PAINT_ACTOR_DIRTY - * flag set. - */ -void -clutter_effect_queue_repaint (ClutterEffect *effect) -{ - ClutterActor *actor; - - g_return_if_fail (CLUTTER_IS_EFFECT (effect)); - - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); - - /* If the effect has no actor then nothing needs to be done */ - if (actor != NULL) - _clutter_actor_queue_redraw_full (actor, - NULL, /* clip volume */ - effect /* effect */); -} diff --git a/mutter/clutter/clutter/clutter-effect.h b/mutter/clutter/clutter/clutter-effect.h deleted file mode 100644 index ff24d21..0000000 --- a/mutter/clutter/clutter/clutter-effect.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-actor-meta.h" -#include "clutter/clutter-paint-context.h" -#include "clutter/clutter-pick-context.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_EFFECT (clutter_effect_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterEffect, - clutter_effect, - CLUTTER, - EFFECT, - ClutterActorMeta) - -/** - * ClutterEffectClass: - * @pre_paint: virtual function - * @post_paint: virtual function - * @modify_paint_volume: virtual function - * @paint: virtual function - * @pick: virtual function - * - * The #ClutterEffectClass structure contains only private data - */ -struct _ClutterEffectClass -{ - /*< private >*/ - ClutterActorMetaClass parent_class; - - /*< public >*/ - gboolean (* pre_paint) (ClutterEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context); - void (* post_paint) (ClutterEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context); - - gboolean (* modify_paint_volume) (ClutterEffect *effect, - ClutterPaintVolume *volume); - - void (* paint) (ClutterEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context, - ClutterEffectPaintFlags flags); - void (* paint_node) (ClutterEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context, - ClutterEffectPaintFlags flags); - void (* pick) (ClutterEffect *effect, - ClutterPickContext *pick_context); -}; - -CLUTTER_EXPORT -void clutter_effect_queue_repaint (ClutterEffect *effect); - -/* - * ClutterActor API - */ - -CLUTTER_EXPORT -void clutter_actor_add_effect (ClutterActor *self, - ClutterEffect *effect); -CLUTTER_EXPORT -void clutter_actor_add_effect_with_name (ClutterActor *self, - const gchar *name, - ClutterEffect *effect); -CLUTTER_EXPORT -void clutter_actor_remove_effect (ClutterActor *self, - ClutterEffect *effect); -CLUTTER_EXPORT -void clutter_actor_remove_effect_by_name (ClutterActor *self, - const gchar *name); -CLUTTER_EXPORT -GList * clutter_actor_get_effects (ClutterActor *self); -CLUTTER_EXPORT -ClutterEffect *clutter_actor_get_effect (ClutterActor *self, - const gchar *name); -CLUTTER_EXPORT -void clutter_actor_clear_effects (ClutterActor *self); - -CLUTTER_EXPORT -gboolean clutter_actor_has_effects (ClutterActor *self); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-enum-types.c.in b/mutter/clutter/clutter/clutter-enum-types.c.in deleted file mode 100644 index d940283..0000000 --- a/mutter/clutter/clutter/clutter-enum-types.c.in +++ /dev/null @@ -1,40 +0,0 @@ -/*** BEGIN file-header ***/ -#include "config.h" -#include "clutter/clutter-enum-types.h" -/*** END file-header ***/ - -/*** BEGIN file-production ***/ - -/* enumerations from "@filename@" */ -#include "@filename@" - -/*** END file-production ***/ - -/*** BEGIN value-header ***/ -GType -@enum_name@_get_type (void) -{ - static size_t g_enum_type_id = 0; - - if (g_once_init_enter (&g_enum_type_id)) - { - static const G@Type@Value values[] = { -/*** END value-header ***/ - -/*** BEGIN value-production ***/ - { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, -/*** END value-production ***/ - -/*** BEGIN value-tail ***/ - { 0, NULL, NULL } - }; - GType id; - - id = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); - - g_once_init_leave (&g_enum_type_id, id); - } - - return g_enum_type_id; -} -/*** END value-tail ***/ diff --git a/mutter/clutter/clutter/clutter-enum-types.h.in b/mutter/clutter/clutter/clutter-enum-types.h.in deleted file mode 100644 index 2272a05..0000000 --- a/mutter/clutter/clutter/clutter-enum-types.h.in +++ /dev/null @@ -1,27 +0,0 @@ -/*** BEGIN file-header ***/ -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -/*** END file-header ***/ - -/*** BEGIN file-production ***/ -/* enumerations from "@basename@" */ -/*** END file-production ***/ - -/*** BEGIN value-header ***/ -CLUTTER_EXPORT GType @enum_name@_get_type (void) G_GNUC_CONST; -#define CLUTTER_TYPE_@ENUMSHORT@ (@enum_name@_get_type()) - -/*** END value-header ***/ - -/*** BEGIN file-tail ***/ -G_END_DECLS - -/*** END file-tail ***/ diff --git a/mutter/clutter/clutter/clutter-enums.h b/mutter/clutter/clutter/clutter-enums.h deleted file mode 100644 index 45956bf..0000000 --- a/mutter/clutter/clutter/clutter-enums.h +++ /dev/null @@ -1,1244 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2011 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -G_BEGIN_DECLS - -/** - * ClutterRotateAxis: - * @CLUTTER_X_AXIS: Rotate around the X axis - * @CLUTTER_Y_AXIS: Rotate around the Y axis - * @CLUTTER_Z_AXIS: Rotate around the Z axis - * - * Axis of a rotation. - */ -typedef enum /*< prefix=CLUTTER >*/ -{ - CLUTTER_X_AXIS, - CLUTTER_Y_AXIS, - CLUTTER_Z_AXIS -} ClutterRotateAxis; - -/** - * ClutterRequestMode: - * @CLUTTER_REQUEST_HEIGHT_FOR_WIDTH: Height for width requests - * @CLUTTER_REQUEST_WIDTH_FOR_HEIGHT: Width for height requests - * @CLUTTER_REQUEST_CONTENT_SIZE: Use the preferred size of the - * #ClutterContent, if it has any (available since 1.22) - * - * Specifies the type of requests for a #ClutterActor. - */ -typedef enum /*< prefix=CLUTTER_REQUEST >*/ -{ - CLUTTER_REQUEST_HEIGHT_FOR_WIDTH, - CLUTTER_REQUEST_WIDTH_FOR_HEIGHT, - CLUTTER_REQUEST_CONTENT_SIZE -} ClutterRequestMode; - -/** - * ClutterAnimationMode: - * @CLUTTER_CUSTOM_MODE: custom progress function - * @CLUTTER_LINEAR: linear tweening - * @CLUTTER_EASE_IN_QUAD: quadratic tweening - * @CLUTTER_EASE_OUT_QUAD: quadratic tweening, inverse of - * %CLUTTER_EASE_IN_QUAD - * @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_IN_CUBIC - * @CLUTTER_EASE_IN_OUT_CUBIC: cubic tweening, combining - * %CLUTTER_EASE_IN_CUBIC and %CLUTTER_EASE_OUT_CUBIC - * @CLUTTER_EASE_IN_QUART: quartic tweening - * @CLUTTER_EASE_OUT_QUART: quartic tweening, inverse of - * %CLUTTER_EASE_IN_QUART - * @CLUTTER_EASE_IN_OUT_QUART: quartic tweening, combining - * %CLUTTER_EASE_IN_QUART and %CLUTTER_EASE_OUT_QUART - * @CLUTTER_EASE_IN_QUINT: quintic tweening - * @CLUTTER_EASE_OUT_QUINT: quintic tweening, inverse of - * %CLUTTER_EASE_IN_QUINT - * @CLUTTER_EASE_IN_OUT_QUINT: fifth power tweening, combining - * %CLUTTER_EASE_IN_QUINT and %CLUTTER_EASE_OUT_QUINT - * @CLUTTER_EASE_IN_SINE: sinusoidal tweening - * @CLUTTER_EASE_OUT_SINE: sinusoidal tweening, inverse of - * %CLUTTER_EASE_IN_SINE - * @CLUTTER_EASE_IN_OUT_SINE: sine wave tweening, combining - * %CLUTTER_EASE_IN_SINE and %CLUTTER_EASE_OUT_SINE - * @CLUTTER_EASE_IN_EXPO: exponential tweening - * @CLUTTER_EASE_OUT_EXPO: exponential tweening, inverse of - * %CLUTTER_EASE_IN_EXPO - * @CLUTTER_EASE_IN_OUT_EXPO: exponential tweening, combining - * %CLUTTER_EASE_IN_EXPO and %CLUTTER_EASE_OUT_EXPO - * @CLUTTER_EASE_IN_CIRC: circular tweening - * @CLUTTER_EASE_OUT_CIRC: circular tweening, inverse of - * %CLUTTER_EASE_IN_CIRC - * @CLUTTER_EASE_IN_OUT_CIRC: circular tweening, combining - * %CLUTTER_EASE_IN_CIRC and %CLUTTER_EASE_OUT_CIRC - * @CLUTTER_EASE_IN_ELASTIC: elastic tweening, with offshoot on start - * @CLUTTER_EASE_OUT_ELASTIC: elastic tweening, with offshoot on end - * @CLUTTER_EASE_IN_OUT_ELASTIC: elastic tweening with offshoot on both ends - * @CLUTTER_EASE_IN_BACK: overshooting cubic tweening, with - * backtracking on start - * @CLUTTER_EASE_OUT_BACK: overshooting cubic tweening, with - * backtracking on end - * @CLUTTER_EASE_IN_OUT_BACK: overshooting cubic tweening, with - * backtracking on both ends - * @CLUTTER_EASE_IN_BOUNCE: exponentially decaying parabolic (bounce) - * tweening, with bounce on start - * @CLUTTER_EASE_OUT_BOUNCE: exponentially decaying parabolic (bounce) - * tweening, with bounce on end - * @CLUTTER_EASE_IN_OUT_BOUNCE: exponentially decaying parabolic (bounce) - * tweening, with bounce on both ends - * @CLUTTER_STEPS: parametrized step function; see clutter_timeline_set_step_progress() - * for further details. (Since 1.12) - * @CLUTTER_STEP_START: equivalent to %CLUTTER_STEPS with a number of steps - * equal to 1, and a step mode of %CLUTTER_STEP_MODE_START. (Since 1.12) - * @CLUTTER_STEP_END: equivalent to %CLUTTER_STEPS with a number of steps - * equal to 1, and a step mode of %CLUTTER_STEP_MODE_END. (Since 1.12) - * @CLUTTER_CUBIC_BEZIER: cubic bezier between (0, 0) and (1, 1) with two - * control points; see clutter_timeline_set_cubic_bezier_progress(). (Since 1.12) - * @CLUTTER_EASE: equivalent to %CLUTTER_CUBIC_BEZIER with control points - * in (0.25, 0.1) and (0.25, 1.0). (Since 1.12) - * @CLUTTER_EASE_IN: equivalent to %CLUTTER_CUBIC_BEZIER with control points - * in (0.42, 0) and (1.0, 1.0). (Since 1.12) - * @CLUTTER_EASE_OUT: equivalent to %CLUTTER_CUBIC_BEZIER with control points - * in (0, 0) and (0.58, 1.0). (Since 1.12) - * @CLUTTER_EASE_IN_OUT: equivalent to %CLUTTER_CUBIC_BEZIER with control points - * in (0.42, 0) and (0.58, 1.0). (Since 1.12) - * @CLUTTER_ANIMATION_LAST: last animation mode, used as a guard for - * registered global alpha functions - * - * The animation modes used by [iface@Animatable]. - * - * This enumeration can be expanded in later versions of Clutter. - * - *
- * Easing modes provided by Clutter - * - *
- * - * Every global alpha function registered using clutter_alpha_register_func() - * or clutter_alpha_register_closure() will have a logical id greater than - * %CLUTTER_ANIMATION_LAST. - */ -typedef enum -{ - CLUTTER_CUSTOM_MODE = 0, - - /* linear */ - CLUTTER_LINEAR, - - /* quadratic */ - CLUTTER_EASE_IN_QUAD, - CLUTTER_EASE_OUT_QUAD, - CLUTTER_EASE_IN_OUT_QUAD, - - /* cubic */ - CLUTTER_EASE_IN_CUBIC, - CLUTTER_EASE_OUT_CUBIC, - CLUTTER_EASE_IN_OUT_CUBIC, - - /* quartic */ - CLUTTER_EASE_IN_QUART, - CLUTTER_EASE_OUT_QUART, - CLUTTER_EASE_IN_OUT_QUART, - - /* quintic */ - CLUTTER_EASE_IN_QUINT, - CLUTTER_EASE_OUT_QUINT, - CLUTTER_EASE_IN_OUT_QUINT, - - /* sinusoidal */ - CLUTTER_EASE_IN_SINE, - CLUTTER_EASE_OUT_SINE, - CLUTTER_EASE_IN_OUT_SINE, - - /* exponential */ - CLUTTER_EASE_IN_EXPO, - CLUTTER_EASE_OUT_EXPO, - CLUTTER_EASE_IN_OUT_EXPO, - - /* circular */ - CLUTTER_EASE_IN_CIRC, - CLUTTER_EASE_OUT_CIRC, - CLUTTER_EASE_IN_OUT_CIRC, - - /* elastic */ - CLUTTER_EASE_IN_ELASTIC, - CLUTTER_EASE_OUT_ELASTIC, - CLUTTER_EASE_IN_OUT_ELASTIC, - - /* overshooting cubic */ - CLUTTER_EASE_IN_BACK, - CLUTTER_EASE_OUT_BACK, - CLUTTER_EASE_IN_OUT_BACK, - - /* exponentially decaying parabolic */ - CLUTTER_EASE_IN_BOUNCE, - CLUTTER_EASE_OUT_BOUNCE, - CLUTTER_EASE_IN_OUT_BOUNCE, - - /* step functions (see css3-transitions) */ - CLUTTER_STEPS, - CLUTTER_STEP_START, /* steps(1, start) */ - CLUTTER_STEP_END, /* steps(1, end) */ - - /* cubic bezier (see css3-transitions) */ - CLUTTER_CUBIC_BEZIER, - CLUTTER_EASE, - CLUTTER_EASE_IN, - CLUTTER_EASE_OUT, - CLUTTER_EASE_IN_OUT, - - /* guard, before registered alpha functions */ - CLUTTER_ANIMATION_LAST -} ClutterAnimationMode; - -/** - * ClutterTextDirection: - * @CLUTTER_TEXT_DIRECTION_DEFAULT: Use the default setting, as returned - * by clutter_get_default_text_direction() - * @CLUTTER_TEXT_DIRECTION_LTR: Use left-to-right text direction - * @CLUTTER_TEXT_DIRECTION_RTL: Use right-to-left text direction - * - * The text direction to be used by [class@Actor]s - */ -typedef enum -{ - CLUTTER_TEXT_DIRECTION_DEFAULT, - CLUTTER_TEXT_DIRECTION_LTR, - CLUTTER_TEXT_DIRECTION_RTL -} ClutterTextDirection; - -/** - * ClutterShaderType: - * @CLUTTER_VERTEX_SHADER: a vertex shader - * @CLUTTER_FRAGMENT_SHADER: a fragment shader - * - * The type of GLSL shader program - */ -typedef enum -{ - CLUTTER_VERTEX_SHADER, - CLUTTER_FRAGMENT_SHADER -} ClutterShaderType; - -/** - * ClutterModifierType: - * @CLUTTER_SHIFT_MASK: Mask applied by the Shift key - * @CLUTTER_LOCK_MASK: Mask applied by the Caps Lock key - * @CLUTTER_CONTROL_MASK: Mask applied by the Control key - * @CLUTTER_MOD1_MASK: Mask applied by the first Mod key - * @CLUTTER_MOD2_MASK: Mask applied by the second Mod key - * @CLUTTER_MOD3_MASK: Mask applied by the third Mod key - * @CLUTTER_MOD4_MASK: Mask applied by the fourth Mod key - * @CLUTTER_MOD5_MASK: Mask applied by the fifth Mod key - * @CLUTTER_BUTTON1_MASK: Mask applied by the first pointer button - * @CLUTTER_BUTTON2_MASK: Mask applied by the second pointer button - * @CLUTTER_BUTTON3_MASK: Mask applied by the third pointer button - * @CLUTTER_BUTTON4_MASK: Mask applied by the fourth pointer button - * @CLUTTER_BUTTON5_MASK: Mask applied by the fifth pointer button - * @CLUTTER_SUPER_MASK: Mask applied by the Super key - * @CLUTTER_HYPER_MASK: Mask applied by the Hyper key - * @CLUTTER_META_MASK: Mask applied by the Meta key - * @CLUTTER_RELEASE_MASK: Mask applied during release - * @CLUTTER_MODIFIER_MASK: A mask covering all modifier types - * - * Masks applied to a #ClutterEvent by modifiers. - * - * Note that Clutter may add internal values to events which include - * reserved values such as %CLUTTER_MODIFIER_RESERVED_13_MASK. Your code - * should preserve and ignore them. You can use %CLUTTER_MODIFIER_MASK to - * remove all reserved values. - */ -typedef enum -{ - CLUTTER_SHIFT_MASK = 1 << 0, - CLUTTER_LOCK_MASK = 1 << 1, - CLUTTER_CONTROL_MASK = 1 << 2, - CLUTTER_MOD1_MASK = 1 << 3, - CLUTTER_MOD2_MASK = 1 << 4, - CLUTTER_MOD3_MASK = 1 << 5, - CLUTTER_MOD4_MASK = 1 << 6, - CLUTTER_MOD5_MASK = 1 << 7, - CLUTTER_BUTTON1_MASK = 1 << 8, - CLUTTER_BUTTON2_MASK = 1 << 9, - CLUTTER_BUTTON3_MASK = 1 << 10, - CLUTTER_BUTTON4_MASK = 1 << 11, - CLUTTER_BUTTON5_MASK = 1 << 12, - -#ifndef __GTK_DOC_IGNORE__ - CLUTTER_MODIFIER_RESERVED_13_MASK = 1 << 13, - CLUTTER_MODIFIER_RESERVED_14_MASK = 1 << 14, - CLUTTER_MODIFIER_RESERVED_15_MASK = 1 << 15, - CLUTTER_MODIFIER_RESERVED_16_MASK = 1 << 16, - CLUTTER_MODIFIER_RESERVED_17_MASK = 1 << 17, - CLUTTER_MODIFIER_RESERVED_18_MASK = 1 << 18, - CLUTTER_MODIFIER_RESERVED_19_MASK = 1 << 19, - CLUTTER_MODIFIER_RESERVED_20_MASK = 1 << 20, - CLUTTER_MODIFIER_RESERVED_21_MASK = 1 << 21, - CLUTTER_MODIFIER_RESERVED_22_MASK = 1 << 22, - CLUTTER_MODIFIER_RESERVED_23_MASK = 1 << 23, - CLUTTER_MODIFIER_RESERVED_24_MASK = 1 << 24, - CLUTTER_MODIFIER_RESERVED_25_MASK = 1 << 25, -#endif - - CLUTTER_SUPER_MASK = 1 << 26, - CLUTTER_HYPER_MASK = 1 << 27, - CLUTTER_META_MASK = 1 << 28, - -#ifndef __GTK_DOC_IGNORE__ - CLUTTER_MODIFIER_RESERVED_29_MASK = 1 << 29, -#endif - - CLUTTER_RELEASE_MASK = 1 << 30, - - /* Combination of CLUTTER_SHIFT_MASK..CLUTTER_BUTTON5_MASK + CLUTTER_SUPER_MASK - + CLUTTER_HYPER_MASK + CLUTTER_META_MASK + CLUTTER_RELEASE_MASK */ - CLUTTER_MODIFIER_MASK = 0x5c001fff -} ClutterModifierType; - -/** - * ClutterPointerA11yFlags: - * @CLUTTER_A11Y_POINTER_ENABLED: - * @CLUTTER_A11Y_SECONDARY_CLICK_ENABLED: - * @CLUTTER_A11Y_DWELL_ENABLED: - * - * Pointer accessibility features applied to a ClutterInputDevice pointer. - * - */ -typedef enum { - CLUTTER_A11Y_SECONDARY_CLICK_ENABLED = 1 << 0, - CLUTTER_A11Y_DWELL_ENABLED = 1 << 1, -} ClutterPointerA11yFlags; - -/** - * ClutterPointerA11yDwellClickType: - * @CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE: Internal use only - * @CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY: - * @CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY: - * @CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE: - * @CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE: - * @CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG: - * - * Dwell click types. - * - */ -typedef enum { - CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE, - CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY, - CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY, - CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE, - CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE, - CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG, -} ClutterPointerA11yDwellClickType; - -/** - * ClutterPointerA11yDwellDirection: - * @CLUTTER_A11Y_DWELL_DIRECTION_NONE: - * @CLUTTER_A11Y_DWELL_DIRECTION_LEFT: - * @CLUTTER_A11Y_DWELL_DIRECTION_RIGHT: - * @CLUTTER_A11Y_DWELL_DIRECTION_UP: - * @CLUTTER_A11Y_DWELL_DIRECTION_DOWN: - * - * Dwell gesture directions. - * - */ -typedef enum { - CLUTTER_A11Y_DWELL_DIRECTION_NONE, - CLUTTER_A11Y_DWELL_DIRECTION_LEFT, - CLUTTER_A11Y_DWELL_DIRECTION_RIGHT, - CLUTTER_A11Y_DWELL_DIRECTION_UP, - CLUTTER_A11Y_DWELL_DIRECTION_DOWN, -} ClutterPointerA11yDwellDirection; - -/** - * ClutterPointerA11yDwellMode: - * @CLUTTER_A11Y_DWELL_MODE_WINDOW: - * @CLUTTER_A11Y_DWELL_MODE_GESTURE: - * - * Dwell mode. - * - */ -typedef enum { - CLUTTER_A11Y_DWELL_MODE_WINDOW, - CLUTTER_A11Y_DWELL_MODE_GESTURE, -} ClutterPointerA11yDwellMode; - -/** - * ClutterPointerA11yTimeoutType: - * @CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK: - * @CLUTTER_A11Y_TIMEOUT_TYPE_DWELL: - * @CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE: - * - * Pointer accessibility timeout type. - * - */ -typedef enum { - CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK, - CLUTTER_A11Y_TIMEOUT_TYPE_DWELL, - CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE, -} ClutterPointerA11yTimeoutType; - -/** - * ClutterActorFlags: - * @CLUTTER_ACTOR_MAPPED: the actor will be painted (is visible, and inside - * a toplevel, and all parents visible) - * @CLUTTER_ACTOR_REALIZED: the resources associated to the actor have been - * allocated - * @CLUTTER_ACTOR_REACTIVE: the actor 'reacts' to mouse events emitting event - * signals - * @CLUTTER_ACTOR_VISIBLE: the actor has been shown by the application program - * @CLUTTER_ACTOR_NO_LAYOUT: the actor provides an explicit layout management - * policy for its children; this flag will prevent Clutter from automatic - * queueing of relayout and will defer all layouting to the actor itself - * - * Flags used to signal the state of an actor. - */ -typedef enum /*< prefix=CLUTTER_ACTOR >*/ -{ - CLUTTER_ACTOR_MAPPED = 1 << 1, - CLUTTER_ACTOR_REALIZED = 1 << 2, - CLUTTER_ACTOR_REACTIVE = 1 << 3, - CLUTTER_ACTOR_VISIBLE = 1 << 4, - CLUTTER_ACTOR_NO_LAYOUT = 1 << 5 -} ClutterActorFlags; - -/** - * ClutterOffscreenRedirect: - * @CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY: Only redirect - * the actor if it is semi-transparent and its has_overlaps() - * virtual returns %TRUE. - * @CLUTTER_OFFSCREEN_REDIRECT_ALWAYS: Always redirect the actor to an - * offscreen buffer even if it is fully opaque. - * @CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE: Only redirect the actor if it is the - * most efficient thing to do based on its recent repaint behaviour. That - * means when its contents are changing less frequently than it's being used - * on stage. - * - * Possible flags to pass to clutter_actor_set_offscreen_redirect(). - */ -typedef enum /*< prefix=CLUTTER_OFFSCREEN_REDIRECT >*/ -{ - CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY = 1 << 0, - CLUTTER_OFFSCREEN_REDIRECT_ALWAYS = 1 << 1, - CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE = 1 << 2 -} ClutterOffscreenRedirect; - -/** - * ClutterAlignAxis: - * @CLUTTER_ALIGN_X_AXIS: Maintain the alignment on the X axis - * @CLUTTER_ALIGN_Y_AXIS: Maintain the alignment on the Y axis - * @CLUTTER_ALIGN_BOTH: Maintain the alignment on both the X and Y axis - * - * Specifies the axis on which #ClutterAlignConstraint should maintain - * the alignment. - */ -typedef enum /*< prefix=CLUTTER_ALIGN >*/ -{ - CLUTTER_ALIGN_X_AXIS, - CLUTTER_ALIGN_Y_AXIS, - CLUTTER_ALIGN_BOTH -} ClutterAlignAxis; - -/** - * ClutterBindCoordinate: - * @CLUTTER_BIND_X: Bind the X coordinate - * @CLUTTER_BIND_Y: Bind the Y coordinate - * @CLUTTER_BIND_WIDTH: Bind the width - * @CLUTTER_BIND_HEIGHT: Bind the height - * @CLUTTER_BIND_POSITION: Equivalent to to %CLUTTER_BIND_X and - * %CLUTTER_BIND_Y - * @CLUTTER_BIND_SIZE: Equivalent to %CLUTTER_BIND_WIDTH and - * %CLUTTER_BIND_HEIGHT - * @CLUTTER_BIND_ALL: Equivalent to %CLUTTER_BIND_POSITION and - * %CLUTTER_BIND_SIZE - * - * Specifies which property should be used in a binding - */ -typedef enum /*< prefix=CLUTTER_BIND >*/ -{ - CLUTTER_BIND_X, - CLUTTER_BIND_Y, - CLUTTER_BIND_WIDTH, - CLUTTER_BIND_HEIGHT, - CLUTTER_BIND_POSITION, - CLUTTER_BIND_SIZE, - CLUTTER_BIND_ALL -} ClutterBindCoordinate; - -/** - * ClutterEffectPaintFlags: - * @CLUTTER_EFFECT_PAINT_ACTOR_DIRTY: The actor or one of its children - * has queued a redraw before this paint. This implies that the effect - * should call clutter_actor_continue_paint() to chain to the next - * effect and can not cache any results from a previous paint. - * @CLUTTER_EFFECT_PAINT_BYPASS_EFFECT: The effect should not be used - * on this frame, but it will be asked to paint the actor still. - * - * Flags passed to the ‘paint’ or ‘pick’ method of #ClutterEffect. - */ -typedef enum /*< prefix=CLUTTER_EFFECT_PAINT >*/ -{ - CLUTTER_EFFECT_PAINT_ACTOR_DIRTY = (1 << 0), - CLUTTER_EFFECT_PAINT_BYPASS_EFFECT = (1 << 1) -} ClutterEffectPaintFlags; - - -/** - * ClutterLongPressState: - * @CLUTTER_LONG_PRESS_QUERY: Queries the action whether it supports - * long presses - * @CLUTTER_LONG_PRESS_ACTIVATE: Activates the action on a long press - * @CLUTTER_LONG_PRESS_CANCEL: The long press was cancelled - * - * The states for the #ClutterClickAction::long-press signal. - */ -typedef enum /*< prefix=CLUTTER_LONG_PRESS >*/ -{ - CLUTTER_LONG_PRESS_QUERY, - CLUTTER_LONG_PRESS_ACTIVATE, - CLUTTER_LONG_PRESS_CANCEL -} ClutterLongPressState; - -/** - * ClutterEventFlags: - * @CLUTTER_EVENT_NONE: No flag set - * @CLUTTER_EVENT_FLAG_SYNTHETIC: Synthetic event - * @CLUTTER_EVENT_FLAG_REPEATED: Auto-repeated event - * - * Flags for the #ClutterEvent - */ -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_GRAB_NOTIFY = 1 << 4, - CLUTTER_EVENT_FLAG_POINTER_EMULATED = 1 << 5, -} ClutterEventFlags; - -/** - * ClutterEventType: - * @CLUTTER_NOTHING: Empty event - * @CLUTTER_KEY_PRESS: Key press event - * @CLUTTER_KEY_RELEASE: Key release event - * @CLUTTER_MOTION: Pointer motion event - * @CLUTTER_ENTER: Actor enter event - * @CLUTTER_LEAVE: Actor leave event - * @CLUTTER_BUTTON_PRESS: Pointer button press event - * @CLUTTER_BUTTON_RELEASE: Pointer button release event - * @CLUTTER_SCROLL: Pointer scroll event - * @CLUTTER_TOUCH_BEGIN: A new touch event sequence has started; - * @CLUTTER_TOUCH_UPDATE: A touch event sequence has been updated; - * @CLUTTER_TOUCH_END: A touch event sequence has finished; - * @CLUTTER_TOUCH_CANCEL: A touch event sequence has been canceled; - * @CLUTTER_TOUCHPAD_PINCH: A pinch gesture event, the current state is - * determined by its phase field; - * @CLUTTER_TOUCHPAD_SWIPE: A swipe gesture event, the current state is - * determined by its phase field; - * @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. - * @CLUTTER_PROXIMITY_IN: A tool entered in proximity to a tablet; - * @CLUTTER_PROXIMITY_OUT: A tool left from the proximity area of a tablet; - * @CLUTTER_EVENT_LAST: Marks the end of the #ClutterEventType enumeration; - * - * Types of events. - */ -typedef enum /*< prefix=CLUTTER >*/ -{ - CLUTTER_NOTHING = 0, - CLUTTER_KEY_PRESS, - CLUTTER_KEY_RELEASE, - CLUTTER_MOTION, - CLUTTER_ENTER, - CLUTTER_LEAVE, - CLUTTER_BUTTON_PRESS, - CLUTTER_BUTTON_RELEASE, - CLUTTER_SCROLL, - 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; - -/** - * ClutterScrollDirection: - * @CLUTTER_SCROLL_UP: Scroll up - * @CLUTTER_SCROLL_DOWN: Scroll down - * @CLUTTER_SCROLL_LEFT: Scroll left - * @CLUTTER_SCROLL_RIGHT: Scroll right - * @CLUTTER_SCROLL_SMOOTH: Precise scrolling delta (available in 1.10) - * - * Direction of a pointer scroll event. - * - * The %CLUTTER_SCROLL_SMOOTH value implies that the #ClutterScrollEvent - * has precise scrolling delta information. - */ -typedef enum /*< prefix=CLUTTER_SCROLL >*/ -{ - CLUTTER_SCROLL_UP, - CLUTTER_SCROLL_DOWN, - CLUTTER_SCROLL_LEFT, - CLUTTER_SCROLL_RIGHT, - CLUTTER_SCROLL_SMOOTH -} ClutterScrollDirection; - -/** - * ClutterInputDeviceCapabilities: - * @CLUTTER_INPUT_CAPABILITY_NONE: No capabilities - * @CLUTTER_INPUT_CAPABILITY_POINTER: Pointer capability - * @CLUTTER_INPUT_CAPABILITY_KEYBOARD: Keyboard capability - * @CLUTTER_INPUT_CAPABILITY_TOUCHPAD: Touchpad gesture and scroll capability - * @CLUTTER_INPUT_CAPABILITY_TOUCH: Touch capability - * @CLUTTER_INPUT_CAPABILITY_TABLET_TOOL: Tablet tool capability - * @CLUTTER_INPUT_CAPABILITY_TABLET_PAD: Tablet pad capability - * - * Describes the capabilities of an input device. - **/ -typedef enum /*< prefix=CLUTTER_INPUT_CAPABILITY >*/ -{ - CLUTTER_INPUT_CAPABILITY_NONE = 0, - CLUTTER_INPUT_CAPABILITY_POINTER = 1 << 0, - CLUTTER_INPUT_CAPABILITY_KEYBOARD = 1 << 1, - CLUTTER_INPUT_CAPABILITY_TOUCHPAD = 1 << 2, - CLUTTER_INPUT_CAPABILITY_TOUCH = 1 << 3, - CLUTTER_INPUT_CAPABILITY_TABLET_TOOL = 1 << 4, - CLUTTER_INPUT_CAPABILITY_TABLET_PAD = 1 << 5, - CLUTTER_INPUT_CAPABILITY_TRACKBALL = 1 << 6, - CLUTTER_INPUT_CAPABILITY_TRACKPOINT = 1 << 7, -} ClutterInputCapabilities; - -/** - * ClutterInputDeviceType: - * @CLUTTER_POINTER_DEVICE: A pointer device - * @CLUTTER_KEYBOARD_DEVICE: A keyboard device - * @CLUTTER_EXTENSION_DEVICE: A generic extension device - * @CLUTTER_JOYSTICK_DEVICE: A joystick device - * @CLUTTER_TABLET_DEVICE: A tablet device - * @CLUTTER_TOUCHPAD_DEVICE: A touchpad device - * @CLUTTER_TOUCHSCREEN_DEVICE: A touch screen device - * @CLUTTER_PEN_DEVICE: A pen device - * @CLUTTER_ERASER_DEVICE: An eraser device - * @CLUTTER_CURSOR_DEVICE: A cursor device - * @CLUTTER_PAD_DEVICE: A tablet pad - * @CLUTTER_N_DEVICE_TYPES: The number of device types - * - * The types of input devices available. - * - * The #ClutterInputDeviceType enumeration can be extended at later - * date; not every platform supports every input device type. - */ -typedef enum -{ - CLUTTER_POINTER_DEVICE, - CLUTTER_KEYBOARD_DEVICE, - CLUTTER_EXTENSION_DEVICE, - CLUTTER_JOYSTICK_DEVICE, - CLUTTER_TABLET_DEVICE, - CLUTTER_TOUCHPAD_DEVICE, - CLUTTER_TOUCHSCREEN_DEVICE, - CLUTTER_PEN_DEVICE, - CLUTTER_ERASER_DEVICE, - CLUTTER_CURSOR_DEVICE, - CLUTTER_PAD_DEVICE, - - CLUTTER_N_DEVICE_TYPES -} ClutterInputDeviceType; - -/** - * 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 - * - * The mode for input devices available. - */ -typedef enum -{ - CLUTTER_INPUT_MODE_LOGICAL, - CLUTTER_INPUT_MODE_PHYSICAL, - CLUTTER_INPUT_MODE_FLOATING -} ClutterInputMode; - -/** - * ClutterInputAxis: - * @CLUTTER_INPUT_AXIS_IGNORE: Unused axis - * @CLUTTER_INPUT_AXIS_X: The position on the X axis - * @CLUTTER_INPUT_AXIS_Y: The position of the Y axis - * @CLUTTER_INPUT_AXIS_PRESSURE: The pressure information - * @CLUTTER_INPUT_AXIS_XTILT: The tilt on the X axis - * @CLUTTER_INPUT_AXIS_YTILT: The tile on the Y axis - * @CLUTTER_INPUT_AXIS_WHEEL: A wheel - * @CLUTTER_INPUT_AXIS_DISTANCE: Distance (Since 1.12) - * @CLUTTER_INPUT_AXIS_ROTATION: Rotation along the z-axis (Since 1.28) - * @CLUTTER_INPUT_AXIS_SLIDER: A slider (Since 1.28) - * @CLUTTER_INPUT_AXIS_LAST: Last value of the enumeration; this value is - * useful when iterating over the enumeration values (Since 1.12) - * - * The type of axes Clutter recognizes on a #ClutterInputDevice - */ -typedef enum -{ - CLUTTER_INPUT_AXIS_IGNORE, - - CLUTTER_INPUT_AXIS_X, - CLUTTER_INPUT_AXIS_Y, - CLUTTER_INPUT_AXIS_PRESSURE, - CLUTTER_INPUT_AXIS_XTILT, - CLUTTER_INPUT_AXIS_YTILT, - CLUTTER_INPUT_AXIS_WHEEL, - CLUTTER_INPUT_AXIS_DISTANCE, - CLUTTER_INPUT_AXIS_ROTATION, - CLUTTER_INPUT_AXIS_SLIDER, - - 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 - * @CLUTTER_SNAP_EDGE_RIGHT: the right edge - * @CLUTTER_SNAP_EDGE_BOTTOM: the bottom edge - * @CLUTTER_SNAP_EDGE_LEFT: the left edge - * - * The edge to snap - */ -typedef enum -{ - CLUTTER_SNAP_EDGE_TOP, - CLUTTER_SNAP_EDGE_RIGHT, - CLUTTER_SNAP_EDGE_BOTTOM, - CLUTTER_SNAP_EDGE_LEFT -} ClutterSnapEdge; - -/** - * ClutterPickMode: - * @CLUTTER_PICK_NONE: Do not paint any actor - * @CLUTTER_PICK_REACTIVE: Paint only the reactive actors - * @CLUTTER_PICK_ALL: Paint all actors - * - * Controls the paint cycle of the scene graph when in pick mode - */ -typedef enum -{ - CLUTTER_PICK_NONE = 0, - CLUTTER_PICK_REACTIVE, - CLUTTER_PICK_ALL -} ClutterPickMode; - -/** - * ClutterSwipeDirection: - * @CLUTTER_SWIPE_DIRECTION_UP: Upwards swipe gesture - * @CLUTTER_SWIPE_DIRECTION_DOWN: Downwards swipe gesture - * @CLUTTER_SWIPE_DIRECTION_LEFT: Leftwards swipe gesture - * @CLUTTER_SWIPE_DIRECTION_RIGHT: Rightwards swipe gesture - * - * The main direction of the swipe gesture - */ -typedef enum /*< prefix=CLUTTER_SWIPE_DIRECTION >*/ -{ - CLUTTER_SWIPE_DIRECTION_UP = 1 << 0, - CLUTTER_SWIPE_DIRECTION_DOWN = 1 << 1, - CLUTTER_SWIPE_DIRECTION_LEFT = 1 << 2, - CLUTTER_SWIPE_DIRECTION_RIGHT = 1 << 3 -} ClutterSwipeDirection; - -/** - * ClutterPanAxis: - * @CLUTTER_PAN_AXIS_NONE: No constraint - * @CLUTTER_PAN_X_AXIS: Set a constraint on the X axis - * @CLUTTER_PAN_Y_AXIS: Set a constraint on the Y axis - * @CLUTTER_PAN_AXIS_AUTO: Constrain panning automatically based on initial - * movement (available since 1.24) - * - * The axis of the constraint that should be applied on the - * panning action - */ -typedef enum /*< prefix=CLUTTER_PAN >*/ -{ - CLUTTER_PAN_AXIS_NONE = 0, - - CLUTTER_PAN_X_AXIS, - CLUTTER_PAN_Y_AXIS, - - CLUTTER_PAN_AXIS_AUTO -} ClutterPanAxis; - -/** - * ClutterTimelineDirection: - * @CLUTTER_TIMELINE_FORWARD: forward direction for a timeline - * @CLUTTER_TIMELINE_BACKWARD: backward direction for a timeline - * - * The direction of a #ClutterTimeline - */ -typedef enum -{ - CLUTTER_TIMELINE_FORWARD, - CLUTTER_TIMELINE_BACKWARD -} ClutterTimelineDirection; - -/** - * ClutterActorAlign: - * @CLUTTER_ACTOR_ALIGN_FILL: Stretch to cover the whole allocated space - * @CLUTTER_ACTOR_ALIGN_START: Snap to left or top side, leaving space - * to the right or bottom. For horizontal layouts, in right-to-left - * locales this should be reversed. - * @CLUTTER_ACTOR_ALIGN_CENTER: Center the actor inside the allocation - * @CLUTTER_ACTOR_ALIGN_END: Snap to right or bottom side, leaving space - * to the left or top. For horizontal layouts, in right-to-left locales - * this should be reversed. - * - * Controls how a #ClutterActor should align itself inside the extra space - * assigned to it during the allocation. - * - * Alignment only matters if the allocated space given to an actor is - * bigger than its natural size; for example, when - * the [property@Clutter.Actor:x-expand] or the [property@Clutter.Actor:y-expand] - * properties of #ClutterActor are set to %TRUE. - */ -typedef enum -{ - CLUTTER_ACTOR_ALIGN_FILL, - CLUTTER_ACTOR_ALIGN_START, - CLUTTER_ACTOR_ALIGN_CENTER, - CLUTTER_ACTOR_ALIGN_END -} ClutterActorAlign; - -/** - * ClutterRepaintFlags: - * @CLUTTER_REPAINT_FLAGS_PRE_PAINT: Run the repaint function prior to - * painting the stages - * @CLUTTER_REPAINT_FLAGS_POST_PAINT: Run the repaint function after - * painting the stages - * - * Flags to pass to clutter_threads_add_repaint_func_full(). - */ -typedef enum -{ - CLUTTER_REPAINT_FLAGS_PRE_PAINT = 1 << 0, - CLUTTER_REPAINT_FLAGS_POST_PAINT = 1 << 1, -} ClutterRepaintFlags; - -/** - * ClutterContentGravity: - * @CLUTTER_CONTENT_GRAVITY_TOP_LEFT: Align the content to the top left corner - * @CLUTTER_CONTENT_GRAVITY_TOP: Align the content to the top edge - * @CLUTTER_CONTENT_GRAVITY_TOP_RIGHT: Align the content to the top right corner - * @CLUTTER_CONTENT_GRAVITY_LEFT: Align the content to the left edge - * @CLUTTER_CONTENT_GRAVITY_CENTER: Align the content to the center - * @CLUTTER_CONTENT_GRAVITY_RIGHT: Align the content to the right edge - * @CLUTTER_CONTENT_GRAVITY_BOTTOM_LEFT: Align the content to the bottom left corner - * @CLUTTER_CONTENT_GRAVITY_BOTTOM: Align the content to the bottom edge - * @CLUTTER_CONTENT_GRAVITY_BOTTOM_RIGHT: Align the content to the bottom right corner - * @CLUTTER_CONTENT_GRAVITY_RESIZE_FILL: Resize the content to fill the allocation - * @CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT: Resize the content to remain within the - * allocation, while maintaining the aspect ratio - * - * Controls the alignment of the #ClutterContent inside a #ClutterActor. - */ -typedef enum -{ - CLUTTER_CONTENT_GRAVITY_TOP_LEFT, - CLUTTER_CONTENT_GRAVITY_TOP, - CLUTTER_CONTENT_GRAVITY_TOP_RIGHT, - - CLUTTER_CONTENT_GRAVITY_LEFT, - CLUTTER_CONTENT_GRAVITY_CENTER, - CLUTTER_CONTENT_GRAVITY_RIGHT, - - CLUTTER_CONTENT_GRAVITY_BOTTOM_LEFT, - CLUTTER_CONTENT_GRAVITY_BOTTOM, - CLUTTER_CONTENT_GRAVITY_BOTTOM_RIGHT, - - CLUTTER_CONTENT_GRAVITY_RESIZE_FILL, - CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT -} ClutterContentGravity; - -/** - * ClutterScalingFilter: - * @CLUTTER_SCALING_FILTER_LINEAR: Linear interpolation filter - * @CLUTTER_SCALING_FILTER_NEAREST: Nearest neighbor interpolation filter - * @CLUTTER_SCALING_FILTER_TRILINEAR: Trilinear minification filter, with - * mipmap generation; this filter linearly interpolates on every axis, - * as well as between mipmap levels. - * - * The scaling filters to be used with the [property@Actor:minification-filter] - * and [property@Actor:magnification-filter] properties. - */ -typedef enum -{ - CLUTTER_SCALING_FILTER_LINEAR, - CLUTTER_SCALING_FILTER_NEAREST, - CLUTTER_SCALING_FILTER_TRILINEAR -} ClutterScalingFilter; - -/** - * ClutterOrientation: - * @CLUTTER_ORIENTATION_HORIZONTAL: An horizontal orientation - * @CLUTTER_ORIENTATION_VERTICAL: A vertical orientation - * - * Represents the orientation of actors or layout managers. - */ -typedef enum -{ - CLUTTER_ORIENTATION_HORIZONTAL, - CLUTTER_ORIENTATION_VERTICAL -} ClutterOrientation; - -/** - * ClutterScrollMode: - * @CLUTTER_SCROLL_NONE: Ignore scrolling - * @CLUTTER_SCROLL_HORIZONTALLY: Scroll only horizontally - * @CLUTTER_SCROLL_VERTICALLY: Scroll only vertically - * @CLUTTER_SCROLL_BOTH: Scroll in both directions - * - * Scroll modes. - */ -typedef enum /*< prefix=CLUTTER_SCROLL >*/ -{ - CLUTTER_SCROLL_NONE = 0, - - CLUTTER_SCROLL_HORIZONTALLY = 1 << 0, - CLUTTER_SCROLL_VERTICALLY = 1 << 1, - - CLUTTER_SCROLL_BOTH = CLUTTER_SCROLL_HORIZONTALLY | CLUTTER_SCROLL_VERTICALLY -} ClutterScrollMode; - -/** - * ClutterGridPosition: - * @CLUTTER_GRID_POSITION_LEFT: left position - * @CLUTTER_GRID_POSITION_RIGHT: right position - * @CLUTTER_GRID_POSITION_TOP: top position - * @CLUTTER_GRID_POSITION_BOTTOM: bottom position - * - * Grid position modes. - */ -typedef enum -{ - CLUTTER_GRID_POSITION_LEFT, - CLUTTER_GRID_POSITION_RIGHT, - CLUTTER_GRID_POSITION_TOP, - CLUTTER_GRID_POSITION_BOTTOM -} ClutterGridPosition; - -/** - * ClutterContentRepeat: - * @CLUTTER_REPEAT_NONE: No repeat - * @CLUTTER_REPEAT_X_AXIS: Repeat the content on the X axis - * @CLUTTER_REPEAT_Y_AXIS: Repeat the content on the Y axis - * @CLUTTER_REPEAT_BOTH: Repeat the content on both axis - * - * Content repeat modes. - */ -typedef enum -{ - CLUTTER_REPEAT_NONE = 0, - CLUTTER_REPEAT_X_AXIS = 1 << 0, - CLUTTER_REPEAT_Y_AXIS = 1 << 1, - CLUTTER_REPEAT_BOTH = CLUTTER_REPEAT_X_AXIS | CLUTTER_REPEAT_Y_AXIS -} ClutterContentRepeat; - -/** - * ClutterColorspace: - * @CLUTTER_COLORSPACE_UNKNOWN: Unknown colorspace - * @CLUTTER_COLORSPACE_SRGB: Default sRGB colorspace - * @CLUTTER_COLORSPACE_BT2020: BT2020 colorspace - * - * Colorspace information. - */ -typedef enum -{ - CLUTTER_COLORSPACE_UNKNOWN, - CLUTTER_COLORSPACE_SRGB, - CLUTTER_COLORSPACE_BT2020, -} ClutterColorspace; - -/** - * ClutterStepMode: - * @CLUTTER_STEP_MODE_START: The change in the value of a - * %CLUTTER_STEP progress mode should occur at the start of - * the transition - * @CLUTTER_STEP_MODE_END: The change in the value of a - * %CLUTTER_STEP progress mode should occur at the end of - * the transition - * - * Change the value transition of a step function. - * - * See clutter_timeline_set_step_progress(). - */ -typedef enum -{ - CLUTTER_STEP_MODE_START, - CLUTTER_STEP_MODE_END -} ClutterStepMode; - -/** - * ClutterGestureTriggerEdge: - * @CLUTTER_GESTURE_TRIGGER_EDGE_NONE: Tell #ClutterGestureAction that - * the gesture must begin immediately and there's no drag limit that - * will cause its cancellation; - * @CLUTTER_GESTURE_TRIGGER_EDGE_AFTER: Tell #ClutterGestureAction that - * it needs to wait until the drag threshold has been exceeded before - * considering that the gesture has begun; - * @CLUTTER_GESTURE_TRIGGER_EDGE_BEFORE: Tell #ClutterGestureAction that - * the gesture must begin immediately and that it must be cancelled - * once the drag exceed the configured threshold. - * - * Enum passed to the [method@GestureAction.set_threshold_trigger_edge] - * function. - */ -typedef enum -{ - CLUTTER_GESTURE_TRIGGER_EDGE_NONE = 0, - CLUTTER_GESTURE_TRIGGER_EDGE_AFTER, - CLUTTER_GESTURE_TRIGGER_EDGE_BEFORE -} ClutterGestureTriggerEdge; - -/** - * ClutterTouchpadGesturePhase: - * @CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN: The gesture has begun. - * @CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE: The gesture has been updated. - * @CLUTTER_TOUCHPAD_GESTURE_PHASE_END: The gesture was finished, changes - * should be permanently applied. - * @CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL: The gesture was cancelled, all - * changes should be undone. - * - * The phase of a touchpad gesture event. - * - * All gestures are guaranteed to begin with an event of type - * %CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN, followed by a number - * of %CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE (possibly 0). - * - * A finished gesture may have 2 possible outcomes, an event with phase - * %CLUTTER_TOUCHPAD_GESTURE_PHASE_END will be emitted when the gesture is - * considered successful, this should be used as the hint to perform any - * permanent changes. - - * Cancelled gestures may be so for a variety of reasons, due to hardware, - * or due to the gesture recognition layers hinting the gesture did not - * finish resolutely (eg. a 3rd finger being added during a pinch gesture). - * In these cases, the last event with report the phase - * %CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL, this should be used as a hint - * to undo any visible/permanent changes that were done throughout the - * progress of the gesture. - * - * See also #ClutterTouchpadPinchEvent and #ClutterTouchpadPinchEvent.4 - */ -typedef enum -{ - CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN, - CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE, - CLUTTER_TOUCHPAD_GESTURE_PHASE_END, - CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL -} ClutterTouchpadGesturePhase; - -/** - * ClutterScrollSource: - * @CLUTTER_SCROLL_SOURCE_UNKNOWN: Source of scroll events is unknown. - * @CLUTTER_SCROLL_SOURCE_WHEEL: The scroll event is originated by a mouse wheel. - * @CLUTTER_SCROLL_SOURCE_FINGER: The scroll event is originated by one or more - * fingers on the device (eg. touchpads). - * @CLUTTER_SCROLL_SOURCE_CONTINUOUS: The scroll event is originated by the - * motion of some device (eg. a scroll button is set). - * - * The scroll source determines the source of the scroll event. - * - * Keep in mind that the source device #ClutterInputDeviceType is not enough - * to infer the scroll source.6 - */ -typedef enum -{ - CLUTTER_SCROLL_SOURCE_UNKNOWN, - CLUTTER_SCROLL_SOURCE_WHEEL, - CLUTTER_SCROLL_SOURCE_FINGER, - CLUTTER_SCROLL_SOURCE_CONTINUOUS -} ClutterScrollSource; - -/** - * ClutterScrollFinishFlags: - * @CLUTTER_SCROLL_FINISHED_NONE: no axis was stopped. - * @CLUTTER_SCROLL_FINISHED_HORIZONTAL: The horizontal axis stopped. - * @CLUTTER_SCROLL_FINISHED_VERTICAL: The vertical axis stopped. - * - * Flags used to notify the axes that were stopped in a #ClutterScrollEvent. - * - * These can be used to trigger post-scroll effects like kinetic scrolling.6 - */ -typedef enum -{ - CLUTTER_SCROLL_FINISHED_NONE = 0, - CLUTTER_SCROLL_FINISHED_HORIZONTAL = 1 << 0, - CLUTTER_SCROLL_FINISHED_VERTICAL = 1 << 1 -} ClutterScrollFinishFlags; - -/** - * ClutterInputDeviceToolType: - * @CLUTTER_INPUT_DEVICE_TOOL_NONE: No tool - * @CLUTTER_INPUT_DEVICE_TOOL_PEN: The tool is a pen - * @CLUTTER_INPUT_DEVICE_TOOL_ERASER: The tool is an eraser - * @CLUTTER_INPUT_DEVICE_TOOL_BRUSH: The tool is a brush - * @CLUTTER_INPUT_DEVICE_TOOL_PENCIL: The tool is a pencil - * @CLUTTER_INPUT_DEVICE_TOOL_AIRBRUSH: The tool is an airbrush - * @CLUTTER_INPUT_DEVICE_TOOL_MOUSE: The tool is a mouse - * @CLUTTER_INPUT_DEVICE_TOOL_LENS: The tool is a lens - * - * Defines the type of tool that a #ClutterInputDeviceTool represents.8 - */ -typedef enum -{ - CLUTTER_INPUT_DEVICE_TOOL_NONE, - CLUTTER_INPUT_DEVICE_TOOL_PEN, - CLUTTER_INPUT_DEVICE_TOOL_ERASER, - CLUTTER_INPUT_DEVICE_TOOL_BRUSH, - CLUTTER_INPUT_DEVICE_TOOL_PENCIL, - CLUTTER_INPUT_DEVICE_TOOL_AIRBRUSH, - CLUTTER_INPUT_DEVICE_TOOL_MOUSE, - CLUTTER_INPUT_DEVICE_TOOL_LENS -} ClutterInputDeviceToolType; - -typedef enum -{ - CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN, - CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER, -} ClutterInputDevicePadSource; - -typedef enum -{ - CLUTTER_PAD_FEATURE_BUTTON, - CLUTTER_PAD_FEATURE_RING, - CLUTTER_PAD_FEATURE_STRIP, -} ClutterInputDevicePadFeature; - -typedef enum -{ - CLUTTER_INPUT_CONTENT_HINT_COMPLETION = 1 << 0, - CLUTTER_INPUT_CONTENT_HINT_SPELLCHECK = 1 << 1, - CLUTTER_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION = 1 << 2, - CLUTTER_INPUT_CONTENT_HINT_LOWERCASE = 1 << 3, - CLUTTER_INPUT_CONTENT_HINT_UPPERCASE = 1 << 4, - CLUTTER_INPUT_CONTENT_HINT_TITLECASE = 1 << 5, - CLUTTER_INPUT_CONTENT_HINT_HIDDEN_TEXT = 1 << 6, - CLUTTER_INPUT_CONTENT_HINT_SENSITIVE_DATA = 1 << 7, - CLUTTER_INPUT_CONTENT_HINT_LATIN = 1 << 8, - CLUTTER_INPUT_CONTENT_HINT_MULTILINE = 1 << 9, -} ClutterInputContentHintFlags; - -typedef enum -{ - CLUTTER_INPUT_CONTENT_PURPOSE_NORMAL, - CLUTTER_INPUT_CONTENT_PURPOSE_ALPHA, - CLUTTER_INPUT_CONTENT_PURPOSE_DIGITS, - CLUTTER_INPUT_CONTENT_PURPOSE_NUMBER, - CLUTTER_INPUT_CONTENT_PURPOSE_PHONE, - CLUTTER_INPUT_CONTENT_PURPOSE_URL, - CLUTTER_INPUT_CONTENT_PURPOSE_EMAIL, - CLUTTER_INPUT_CONTENT_PURPOSE_NAME, - CLUTTER_INPUT_CONTENT_PURPOSE_PASSWORD, - CLUTTER_INPUT_CONTENT_PURPOSE_DATE, - CLUTTER_INPUT_CONTENT_PURPOSE_TIME, - CLUTTER_INPUT_CONTENT_PURPOSE_DATETIME, - CLUTTER_INPUT_CONTENT_PURPOSE_TERMINAL, -} ClutterInputContentPurpose; - -typedef enum -{ - CLUTTER_INPUT_PANEL_STATE_OFF, - CLUTTER_INPUT_PANEL_STATE_ON, - 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; - -typedef enum -{ - CLUTTER_GRAB_STATE_NONE = 0, - CLUTTER_GRAB_STATE_POINTER = 1 << 0, - CLUTTER_GRAB_STATE_KEYBOARD = 1 << 1, - CLUTTER_GRAB_STATE_ALL = (CLUTTER_GRAB_STATE_POINTER | - CLUTTER_GRAB_STATE_KEYBOARD), -} ClutterGrabState; - -typedef enum /*< prefix=CLUTTER_GESTURE_STATE >*/ -{ - CLUTTER_GESTURE_STATE_WAITING, - CLUTTER_GESTURE_STATE_POSSIBLE, - CLUTTER_GESTURE_STATE_RECOGNIZING, - CLUTTER_GESTURE_STATE_COMPLETED, - CLUTTER_GESTURE_STATE_CANCELLED, - - CLUTTER_N_GESTURE_STATES -} ClutterGestureState; - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-event-private.h b/mutter/clutter/clutter/clutter-event-private.h deleted file mode 100644 index 52c4516..0000000 --- a/mutter/clutter/clutter/clutter-event-private.h +++ /dev/null @@ -1,188 +0,0 @@ -#pragma once - -#include "clutter/clutter-event.h" - -G_BEGIN_DECLS - -typedef struct _ClutterModifierSet ClutterModifierSet; - -struct _ClutterModifierSet -{ - ClutterModifierType pressed; - ClutterModifierType latched; - ClutterModifierType locked; -}; - -CLUTTER_EXPORT -ClutterEvent * clutter_event_key_new (ClutterEventType type, - ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterModifierSet raw_modifiers, - ClutterModifierType modifiers, - uint32_t keyval, - uint32_t evcode, - uint32_t keycode, - gunichar unicode_value); - -CLUTTER_EXPORT -ClutterEvent * clutter_event_button_new (ClutterEventType type, - ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterInputDeviceTool *tool, - ClutterModifierType modifiers, - graphene_point_t coords, - int button, - uint32_t evcode, - double *axes); -CLUTTER_EXPORT -ClutterEvent * clutter_event_motion_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterInputDeviceTool *tool, - ClutterModifierType modifiers, - graphene_point_t coords, - graphene_point_t delta, - graphene_point_t delta_unaccel, - graphene_point_t delta_constrained, - double *axes); -CLUTTER_EXPORT -ClutterEvent * clutter_event_scroll_smooth_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterInputDeviceTool *tool, - ClutterModifierType modifiers, - graphene_point_t coords, - graphene_point_t delta, - ClutterScrollSource scroll_source, - ClutterScrollFinishFlags finish_flags); -CLUTTER_EXPORT -ClutterEvent * clutter_event_scroll_discrete_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterInputDeviceTool *tool, - ClutterModifierType modifiers, - graphene_point_t coords, - ClutterScrollSource scroll_source, - ClutterScrollDirection direction); -CLUTTER_EXPORT -ClutterEvent * clutter_event_crossing_new (ClutterEventType type, - ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - graphene_point_t coords, - ClutterActor *source, - ClutterActor *related); -CLUTTER_EXPORT -ClutterEvent * clutter_event_touch_new (ClutterEventType type, - ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterEventSequence *sequence, - ClutterModifierType modifiers, - graphene_point_t coords); -CLUTTER_EXPORT -ClutterEvent * clutter_event_touch_cancel_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterEventSequence *sequence); -CLUTTER_EXPORT -ClutterEvent * clutter_event_proximity_new (ClutterEventType type, - ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterInputDeviceTool *tool); -CLUTTER_EXPORT -ClutterEvent * clutter_event_touchpad_pinch_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterTouchpadGesturePhase phase, - uint32_t fingers, - graphene_point_t coords, - graphene_point_t delta, - graphene_point_t delta_unaccel, - float angle, - float scale); -CLUTTER_EXPORT -ClutterEvent * clutter_event_touchpad_swipe_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterTouchpadGesturePhase phase, - uint32_t fingers, - graphene_point_t coords, - graphene_point_t delta, - graphene_point_t delta_unaccel); -CLUTTER_EXPORT -ClutterEvent * clutter_event_touchpad_hold_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterTouchpadGesturePhase phase, - uint32_t fingers, - graphene_point_t coords); -CLUTTER_EXPORT -ClutterEvent * clutter_event_pad_button_new (ClutterEventType type, - ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - uint32_t button, - uint32_t group, - uint32_t mode); -CLUTTER_EXPORT -ClutterEvent * clutter_event_pad_strip_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterInputDevicePadSource strip_source, - uint32_t strip, - uint32_t group, - double value, - uint32_t mode); -CLUTTER_EXPORT -ClutterEvent * clutter_event_pad_ring_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterInputDevicePadSource ring_source, - uint32_t ring, - uint32_t group, - double angle, - uint32_t mode); -CLUTTER_EXPORT -ClutterEvent * clutter_event_device_notify_new (ClutterEventType type, - ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device); -CLUTTER_EXPORT -ClutterEvent * clutter_event_im_new (ClutterEventType type, - ClutterEventFlags flags, - int64_t timestamp_us, - ClutterSeat *seat, - const char *text, - int32_t offset, - int32_t anchor, - uint32_t len, - ClutterPreeditResetMode mode); - -/* Reinjecting queued events for processing */ -CLUTTER_EXPORT -void clutter_stage_process_event (ClutterStage *stage, - ClutterEvent *event); - -CLUTTER_EXPORT -gboolean _clutter_event_process_filters (ClutterEvent *event, - ClutterActor *event_actor); - -/* clears the event queue inside the main context */ -void _clutter_clear_events_queue (void); - -CLUTTER_EXPORT -void _clutter_event_push (const ClutterEvent *event, - gboolean do_copy); - -CLUTTER_EXPORT -const char * clutter_event_get_name (const ClutterEvent *event); - -CLUTTER_EXPORT -char * clutter_event_describe (const ClutterEvent *event); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-event.c b/mutter/clutter/clutter/clutter-event.c deleted file mode 100644 index bcda1bb..0000000 --- a/mutter/clutter/clutter/clutter-event.c +++ /dev/null @@ -1,2729 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * 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 . - * - * - */ - -#include "config.h" - -#include "clutter/clutter-backend-private.h" -#include "clutter/clutter-context-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-event-private.h" -#include "clutter/clutter-keysyms.h" -#include "clutter/clutter-input-device-tool.h" -#include "clutter/clutter-private.h" - -#include - -struct _ClutterAnyEvent -{ - ClutterEventType type; - int64_t time_us; - ClutterEventFlags flags; - ClutterInputDevice *device; - ClutterInputDevice *source_device; -}; - -struct _ClutterKeyEvent -{ - ClutterEventType type; - int64_t time_us; - ClutterEventFlags flags; - ClutterInputDevice *device; - ClutterInputDevice *source_device; - - ClutterModifierSet raw_modifiers; - ClutterModifierType modifier_state; - uint32_t keyval; - uint16_t hardware_keycode; - gunichar unicode_value; - uint32_t evdev_code; -}; - -struct _ClutterButtonEvent -{ - ClutterEventType type; - int64_t time_us; - ClutterEventFlags flags; - ClutterInputDevice *device; - ClutterInputDevice *source_device; - - float x; - float y; - ClutterModifierType modifier_state; - uint32_t button; - double *axes; - ClutterInputDeviceTool *tool; - uint32_t evdev_code; -}; - -struct _ClutterProximityEvent -{ - ClutterEventType type; - int64_t time_us; - ClutterEventFlags flags; - ClutterInputDevice *device; - ClutterInputDevice *source_device; - ClutterInputDeviceTool *tool; -}; - -struct _ClutterCrossingEvent -{ - ClutterEventType type; - int64_t time_us; - ClutterEventFlags flags; - ClutterInputDevice *device; - ClutterInputDevice *source_device; - - float x; - float y; - ClutterEventSequence *sequence; - ClutterActor *source; - ClutterActor *related; -}; - -struct _ClutterMotionEvent -{ - ClutterEventType type; - int64_t time_us; - ClutterEventFlags flags; - ClutterInputDevice *device; - ClutterInputDevice *source_device; - - float x; - float y; - ClutterModifierType modifier_state; - double *axes; - ClutterInputDeviceTool *tool; - - double dx; - double dy; - double dx_unaccel; - double dy_unaccel; - double dx_constrained; - double dy_constrained; -}; - -struct _ClutterScrollEvent -{ - ClutterEventType type; - int64_t time_us; - ClutterEventFlags flags; - ClutterInputDevice *device; - ClutterInputDevice *source_device; - - float x; - float y; - double delta_x; - double delta_y; - ClutterScrollDirection direction; - ClutterModifierType modifier_state; - double *axes; - ClutterInputDeviceTool *tool; - ClutterScrollSource scroll_source; - ClutterScrollFinishFlags finish_flags; -}; - -struct _ClutterTouchEvent -{ - ClutterEventType type; - int64_t time_us; - ClutterEventFlags flags; - ClutterInputDevice *device; - ClutterInputDevice *source_device; - - float x; - float y; - ClutterEventSequence *sequence; - ClutterModifierType modifier_state; - double *axes; /* reserved */ -}; - -struct _ClutterTouchpadPinchEvent -{ - ClutterEventType type; - int64_t time_us; - ClutterEventFlags flags; - ClutterInputDevice *device; - ClutterInputDevice *source_device; - - ClutterTouchpadGesturePhase phase; - float x; - float y; - float dx; - float dy; - float dx_unaccel; - float dy_unaccel; - float angle_delta; - float scale; - uint32_t n_fingers; -}; - -struct _ClutterTouchpadSwipeEvent -{ - ClutterEventType type; - int64_t time_us; - ClutterEventFlags flags; - ClutterInputDevice *device; - ClutterInputDevice *source_device; - - ClutterTouchpadGesturePhase phase; - uint32_t n_fingers; - float x; - float y; - float dx; - float dy; - float dx_unaccel; - float dy_unaccel; -}; - -struct _ClutterTouchpadHoldEvent -{ - ClutterEventType type; - int64_t time_us; - ClutterEventFlags flags; - ClutterInputDevice *device; - ClutterInputDevice *source_device; - - ClutterTouchpadGesturePhase phase; - uint32_t n_fingers; - float x; - float y; -}; - -struct _ClutterPadButtonEvent -{ - ClutterEventType type; - int64_t time_us; - ClutterEventFlags flags; - ClutterInputDevice *device; - ClutterInputDevice *source_device; - - uint32_t button; - uint32_t group; - uint32_t mode; -}; - -struct _ClutterPadStripEvent -{ - ClutterEventType type; - int64_t time_us; - ClutterEventFlags flags; - ClutterInputDevice *device; - ClutterInputDevice *source_device; - - ClutterInputDevicePadSource strip_source; - uint32_t strip_number; - uint32_t group; - double value; - uint32_t mode; -}; - -struct _ClutterPadRingEvent -{ - ClutterEventType type; - int64_t time_us; - ClutterEventFlags flags; - ClutterInputDevice *device; - ClutterInputDevice *source_device; - - ClutterInputDevicePadSource ring_source; - uint32_t ring_number; - uint32_t group; - double angle; - uint32_t mode; -}; - -struct _ClutterDeviceEvent -{ - ClutterEventType type; - int64_t time_us; - ClutterEventFlags flags; - ClutterInputDevice *device; - ClutterInputDevice *source_device; -}; - -struct _ClutterIMEvent -{ - ClutterEventType type; - int64_t time_us; - ClutterEventFlags flags; - ClutterInputDevice *device; - ClutterInputDevice *source_device; - - char *text; - int32_t offset; - int32_t anchor; - uint32_t len; - ClutterPreeditResetMode mode; -}; - -union _ClutterEvent -{ - /*< private >*/ - ClutterEventType type; - - ClutterAnyEvent any; - ClutterButtonEvent button; - ClutterKeyEvent key; - ClutterMotionEvent motion; - ClutterScrollEvent scroll; - 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; -}; - -typedef struct _ClutterEventFilter { - int id; - - ClutterStage *stage; - ClutterEventFilterFunc func; - GDestroyNotify notify; - gpointer user_data; -} ClutterEventFilter; - -G_DEFINE_BOXED_TYPE (ClutterEvent, clutter_event, - clutter_event_copy, - clutter_event_free); - -static ClutterEventSequence * -clutter_event_sequence_copy (ClutterEventSequence *sequence) -{ - /* Nothing to copy here */ - return sequence; -} - -static void -clutter_event_sequence_free (ClutterEventSequence *sequence) -{ - /* Nothing to free here */ -} - -G_DEFINE_BOXED_TYPE (ClutterEventSequence, clutter_event_sequence, - clutter_event_sequence_copy, - clutter_event_sequence_free); - -/** - * clutter_event_type: - * @event: a #ClutterEvent - * - * Retrieves the type of the event. - * - * Return value: a #ClutterEventType - */ -ClutterEventType -clutter_event_type (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, CLUTTER_NOTHING); - - return event->type; -} - -/** - * clutter_event_get_time: - * @event: a #ClutterEvent - * - * Retrieves the time of the event. - * - * Return value: the time of the event, or %CLUTTER_CURRENT_TIME - */ -guint32 -clutter_event_get_time (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, CLUTTER_CURRENT_TIME); - - return us2ms (event->any.time_us); -} - -/** - * clutter_event_get_state: - * @event: a #ClutterEvent - * - * Retrieves the modifier state of the event. In case the window system - * supports reporting latched and locked modifiers, this function returns - * the effective state. - * - * Return value: the modifier state parameter, or 0 - */ -ClutterModifierType -clutter_event_get_state (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, 0); - - switch (event->type) - { - case CLUTTER_KEY_PRESS: - case CLUTTER_KEY_RELEASE: - return event->key.modifier_state; - - case CLUTTER_BUTTON_PRESS: - case CLUTTER_BUTTON_RELEASE: - return event->button.modifier_state; - - case CLUTTER_TOUCH_BEGIN: - case CLUTTER_TOUCH_UPDATE: - case CLUTTER_TOUCH_END: - case CLUTTER_TOUCH_CANCEL: - return event->touch.modifier_state; - - case CLUTTER_MOTION: - return event->motion.modifier_state; - - case CLUTTER_SCROLL: - return event->scroll.modifier_state; - - default: - break; - } - - return 0; -} - -/** - * clutter_event_get_coords: - * @event: a #ClutterEvent - * @x: (out): return location for the X coordinate, or %NULL - * @y: (out): return location for the Y coordinate, or %NULL - * - * Retrieves the coordinates of @event and puts them into @x and @y. - */ -void -clutter_event_get_coords (const ClutterEvent *event, - gfloat *x, - gfloat *y) -{ - graphene_point_t coords; - - g_return_if_fail (event != NULL); - - clutter_event_get_position (event, &coords); - - if (x != NULL) - *x = coords.x; - - if (y != NULL) - *y = coords.y; -} - -/** - * clutter_event_get_position: - * @event: a #ClutterEvent - * @position: a #graphene_point_t - * - * Retrieves the event coordinates as a #graphene_point_t. - */ -void -clutter_event_get_position (const ClutterEvent *event, - graphene_point_t *position) -{ - g_return_if_fail (event != NULL); - g_return_if_fail (position != NULL); - - switch (event->type) - { - case CLUTTER_NOTHING: - case CLUTTER_KEY_PRESS: - case CLUTTER_KEY_RELEASE: - case CLUTTER_EVENT_LAST: - case CLUTTER_PROXIMITY_IN: - case CLUTTER_PROXIMITY_OUT: - case CLUTTER_PAD_BUTTON_PRESS: - 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; - - case CLUTTER_ENTER: - case CLUTTER_LEAVE: - graphene_point_init (position, event->crossing.x, event->crossing.y); - break; - - case CLUTTER_BUTTON_PRESS: - case CLUTTER_BUTTON_RELEASE: - graphene_point_init (position, event->button.x, event->button.y); - break; - - case CLUTTER_MOTION: - graphene_point_init (position, event->motion.x, event->motion.y); - break; - - case CLUTTER_TOUCH_BEGIN: - case CLUTTER_TOUCH_UPDATE: - case CLUTTER_TOUCH_END: - case CLUTTER_TOUCH_CANCEL: - graphene_point_init (position, event->touch.x, event->touch.y); - break; - - case CLUTTER_SCROLL: - graphene_point_init (position, event->scroll.x, event->scroll.y); - break; - - case CLUTTER_TOUCHPAD_PINCH: - graphene_point_init (position, event->touchpad_pinch.x, - event->touchpad_pinch.y); - break; - - case CLUTTER_TOUCHPAD_SWIPE: - 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; - } - -} - -/** - * clutter_event_get_source: - * @event: a #ClutterEvent - * - * Retrieves the source #ClutterActor the event originated from, or - * NULL if the event has no source. - * - * Return value: (transfer none): a #ClutterActor - */ -ClutterActor * -clutter_event_get_source (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, NULL); - - if (event->type == CLUTTER_ENTER || - event->type == CLUTTER_LEAVE) - return event->crossing.source; - - return NULL; -} - -/** - * clutter_event_get_flags: - * @event: a #ClutterEvent - * - * Retrieves the #ClutterEventFlags of @event - * - * Return value: the event flags - */ -ClutterEventFlags -clutter_event_get_flags (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, CLUTTER_EVENT_NONE); - - return event->any.flags; -} - -/** - * clutter_event_get_related: - * @event: a #ClutterEvent of type %CLUTTER_ENTER or of - * type %CLUTTER_LEAVE - * - * Retrieves the related actor of a crossing event. - * - * Return value: (transfer none): the related #ClutterActor, or %NULL - */ -ClutterActor * -clutter_event_get_related (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, NULL); - g_return_val_if_fail (event->type == CLUTTER_ENTER || - event->type == CLUTTER_LEAVE, NULL); - - return event->crossing.related; -} - -/** - * clutter_event_get_scroll_delta: - * @event: a #ClutterEvent of type %CLUTTER_SCROLL - * @dx: (out): return location for the delta on the horizontal axis - * @dy: (out): return location for the delta on the vertical axis - * - * Retrieves the precise scrolling information of @event. - * - * The @event has to have a #ClutterScrollEvent.direction value - * of %CLUTTER_SCROLL_SMOOTH. - */ -void -clutter_event_get_scroll_delta (const ClutterEvent *event, - gdouble *dx, - gdouble *dy) -{ - g_return_if_fail (event != NULL); - g_return_if_fail (event->type == CLUTTER_SCROLL); - g_return_if_fail (event->scroll.direction == CLUTTER_SCROLL_SMOOTH); - - if (dx != NULL) - *dx = event->scroll.delta_x; - - if (dy != NULL) - *dy = event->scroll.delta_y; -} - -/** - * clutter_event_get_scroll_direction: - * @event: a #ClutterEvent of type %CLUTTER_SCROLL - * - * Retrieves the direction of the scrolling of @event - * - * Return value: the scrolling direction - */ -ClutterScrollDirection -clutter_event_get_scroll_direction (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, CLUTTER_SCROLL_UP); - g_return_val_if_fail (event->type == CLUTTER_SCROLL, CLUTTER_SCROLL_UP); - - return event->scroll.direction; -} - -/** - * clutter_event_get_button: - * @event: a #ClutterEvent of type %CLUTTER_BUTTON_PRESS or - * of type %CLUTTER_BUTTON_RELEASE - * - * Retrieves the button number of @event - * - * Return value: the button number - */ -guint32 -clutter_event_get_button (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 || - event->type == CLUTTER_PAD_BUTTON_PRESS || - event->type == CLUTTER_PAD_BUTTON_RELEASE, 0); - - if (event->type == CLUTTER_BUTTON_PRESS || - event->type == CLUTTER_BUTTON_RELEASE) - return event->button.button; - else - return event->pad_button.button; -} - -/* keys */ - -/** - * clutter_event_get_key_symbol: - * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS or - * of type %CLUTTER_KEY_RELEASE - * - * Retrieves the key symbol of @event - * - * Return value: the key symbol representing the key - */ -guint -clutter_event_get_key_symbol (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, 0); - g_return_val_if_fail (event->type == CLUTTER_KEY_PRESS || - event->type == CLUTTER_KEY_RELEASE, 0); - - return event->key.keyval; -} - -/** - * clutter_event_get_key_code: - * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS or - * of type %CLUTTER_KEY_RELEASE - * - * Retrieves the keycode of the key that caused @event - * - * Return value: The keycode representing the key - */ -guint16 -clutter_event_get_key_code (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, 0); - g_return_val_if_fail (event->type == CLUTTER_KEY_PRESS || - event->type == CLUTTER_KEY_RELEASE, 0); - - return event->key.hardware_keycode; -} - -/** - * clutter_event_get_key_unicode: - * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS - * or %CLUTTER_KEY_RELEASE - * - * Retrieves the unicode value for the key that caused @keyev. - * - * Return value: The unicode value representing the key - */ -gunichar -clutter_event_get_key_unicode (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, 0); - g_return_val_if_fail (event->type == CLUTTER_KEY_PRESS || - event->type == CLUTTER_KEY_RELEASE, 0); - - if (event->key.unicode_value) - return event->key.unicode_value; - else - return clutter_keysym_to_unicode (event->key.keyval); -} - -/** - * clutter_event_get_key_state: - * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS - * or %CLUTTER_KEY_RELEASE - * @pressed: (out): Return location for pressed modifiers - * @latched: (out): Return location for latched modifiers - * @locked: (out): Return location for locked modifiers - * - * Returns the modifier state decomposed into independent - * pressed/latched/locked states. The effective state is a - * composition of these 3 states, see [method@Clutter.Event.get_state]. - **/ -void -clutter_event_get_key_state (const ClutterEvent *event, - ClutterModifierType *pressed, - ClutterModifierType *latched, - ClutterModifierType *locked) -{ - g_return_if_fail (event != NULL); - g_return_if_fail (event->type == CLUTTER_KEY_PRESS || - event->type == CLUTTER_KEY_RELEASE); - - if (pressed) - *pressed = event->key.raw_modifiers.pressed; - if (latched) - *latched = event->key.raw_modifiers.latched; - if (locked) - *locked = event->key.raw_modifiers.locked; -} - -/** - * clutter_event_get_event_sequence: - * @event: a #ClutterEvent of type %CLUTTER_TOUCH_BEGIN, - * %CLUTTER_TOUCH_UPDATE, %CLUTTER_TOUCH_END, or - * %CLUTTER_TOUCH_CANCEL - * - * Retrieves the #ClutterEventSequence of @event. - * - * Return value: (transfer none): the event sequence, or %NULL - */ -ClutterEventSequence * -clutter_event_get_event_sequence (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, NULL); - - if (event->type == CLUTTER_TOUCH_BEGIN || - event->type == CLUTTER_TOUCH_UPDATE || - event->type == CLUTTER_TOUCH_END || - event->type == CLUTTER_TOUCH_CANCEL) - return event->touch.sequence; - else if (event->type == CLUTTER_ENTER || - event->type == CLUTTER_LEAVE) - return event->crossing.sequence; - - return NULL; -} - -/** - * clutter_event_get_device_type: - * @event: a #ClutterEvent - * - * Retrieves the type of the device for @event - * - * Return value: the #ClutterInputDeviceType for the device, if - * any is set - */ -ClutterInputDeviceType -clutter_event_get_device_type (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_type (device); - - return CLUTTER_POINTER_DEVICE; -} - -/** - * clutter_event_get_device: - * @event: a #ClutterEvent - * - * Retrieves the #ClutterInputDevice for the event. - * If you want the physical device the event originated from, use - * [method@Clutter.Event.get_source_device]. - * - * The #ClutterInputDevice structure is completely opaque and should - * be cast to the platform-specific implementation. - * - * Return value: (transfer none): the #ClutterInputDevice or %NULL. The - * returned device is owned by the #ClutterEvent and it should not - * be unreferenced - */ -ClutterInputDevice * -clutter_event_get_device (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, NULL); - - return event->any.device; -} - -/** - * clutter_event_get_device_tool: - * @event: a #ClutterEvent - * - * Returns the device tool that originated this event - * - * Returns: (transfer none): The tool of this event8 - **/ -ClutterInputDeviceTool * -clutter_event_get_device_tool (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, NULL); - - switch (event->any.type) - { - case CLUTTER_BUTTON_PRESS: - case CLUTTER_BUTTON_RELEASE: - return event->button.tool; - case CLUTTER_MOTION: - return event->motion.tool; - case CLUTTER_SCROLL: - return event->scroll.tool; - case CLUTTER_PROXIMITY_IN: - case CLUTTER_PROXIMITY_OUT: - return event->proximity.tool; - default: - return NULL; - } -} - -static ClutterEvent * -clutter_event_new (ClutterEventType type) -{ - ClutterEvent *new_event; - - new_event = g_new0 (ClutterEvent, 1); - new_event->any.type = type; - - return new_event; -} - -/** - * clutter_event_copy: - * @event: A #ClutterEvent. - * - * Copies @event. - * - * Return value: (transfer full): A newly allocated #ClutterEvent - */ -ClutterEvent * -clutter_event_copy (const ClutterEvent *event) -{ - ClutterEvent *new_event; - - g_return_val_if_fail (event != NULL, NULL); - - new_event = clutter_event_new (CLUTTER_NOTHING); - - g_set_object (&new_event->any.device, event->any.device); - g_set_object (&new_event->any.source_device, event->any.source_device); - *new_event = *event; - - 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); - } - break; - - case CLUTTER_SCROLL: - if (event->scroll.axes != NULL) - { - new_event->scroll.axes = - g_memdup2 (event->scroll.axes, - sizeof (double) * CLUTTER_INPUT_AXIS_LAST); - } - break; - - case CLUTTER_MOTION: - if (event->motion.axes != NULL) - { - new_event->motion.axes = - g_memdup2 (event->motion.axes, - sizeof (double) * CLUTTER_INPUT_AXIS_LAST); - } - break; - - case CLUTTER_TOUCH_BEGIN: - case CLUTTER_TOUCH_UPDATE: - 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_IM_COMMIT: - case CLUTTER_IM_PREEDIT: - new_event->im.text = g_strdup (event->im.text); - break; - - default: - break; - } - - return new_event; -} - -/** - * clutter_event_free: - * @event: A #ClutterEvent. - * - * Frees all resources used by @event. - */ -void -clutter_event_free (ClutterEvent *event) -{ - if (G_LIKELY (event != NULL)) - { - g_clear_object (&event->any.device); - g_clear_object (&event->any.source_device); - - switch (event->type) - { - case CLUTTER_BUTTON_PRESS: - case CLUTTER_BUTTON_RELEASE: - g_free (event->button.axes); - break; - - case CLUTTER_MOTION: - g_free (event->motion.axes); - break; - - case CLUTTER_SCROLL: - g_free (event->scroll.axes); - break; - - case CLUTTER_TOUCH_BEGIN: - case CLUTTER_TOUCH_UPDATE: - case CLUTTER_TOUCH_END: - case CLUTTER_TOUCH_CANCEL: - g_free (event->touch.axes); - break; - - case CLUTTER_IM_COMMIT: - case CLUTTER_IM_PREEDIT: - g_free (event->im.text); - break; - - default: - break; - } - - g_free (event); - } -} - -/** - * clutter_event_get: - * - * Pops an event off the event queue. Applications should not need to call - * this. - * - * Return value: A #ClutterEvent or NULL if queue empty - */ -ClutterEvent * -clutter_event_get (void) -{ - ClutterContext *context = _clutter_context_get_default (); - ClutterEvent *event; - - event = g_async_queue_try_pop (context->events_queue); - - return event; -} - -void -_clutter_event_push (const ClutterEvent *event, - gboolean do_copy) -{ - ClutterContext *context = _clutter_context_get_default (); - - g_assert (context != NULL); - - if (do_copy) - { - ClutterEvent *copy; - - copy = clutter_event_copy (event); - event = copy; - } - - g_async_queue_push (context->events_queue, (gpointer) event); - g_main_context_wakeup (NULL); -} - -/** - * clutter_event_put: - * @event: a #ClutterEvent - * - * Puts a copy of the event on the back of the event queue. The event will - * have the %CLUTTER_EVENT_FLAG_SYNTHETIC flag set. If the source is set - * event signals will be emitted for this source and capture/bubbling for - * its ancestors. If the source is not set it will be generated by picking - * or use the actor that currently has keyboard focus - */ -void -clutter_event_put (const ClutterEvent *event) -{ - _clutter_event_push (event, TRUE); -} - -/** - * clutter_events_pending: - * - * Checks if events are pending in the event queue. - * - * Return value: TRUE if there are pending events, FALSE otherwise. - */ -gboolean -clutter_events_pending (void) -{ - ClutterContext *context = _clutter_context_get_default (); - - g_return_val_if_fail (context != NULL, FALSE); - - return g_async_queue_length (context->events_queue) > 0; -} - -/** - * clutter_get_current_event_time: - * - * Retrieves the timestamp of the last event, if there is an - * event or if the event has a timestamp. - * - * Return value: the event timestamp, or %CLUTTER_CURRENT_TIME - */ -guint32 -clutter_get_current_event_time (void) -{ - const ClutterEvent* event; - - event = clutter_get_current_event (); - - if (event != NULL) - return clutter_event_get_time (event); - - return CLUTTER_CURRENT_TIME; -} - -/** - * clutter_get_current_event: - * - * If an event is currently being processed, return that event. - * This function is intended to be used to access event state - * that might not be exposed by higher-level widgets. For - * example, to get the key modifier state from a Button 'clicked' - * event. - * - * Return value: (transfer none): The current ClutterEvent, or %NULL if none - */ -const ClutterEvent * -clutter_get_current_event (void) -{ - ClutterContext *context = _clutter_context_get_default (); - - g_return_val_if_fail (context != NULL, NULL); - - return context->current_event != NULL ? context->current_event->data : NULL; -} - -/** - * clutter_event_get_source_device: - * @event: a #ClutterEvent - * - * Retrieves the hardware device that originated the event. - * - * If you need the virtual device, use [method@Clutter.Event.get_device]. - * - * If no hardware device originated this event, this function will - * return the same device as [method@Clutter.Event.get_device]. - * - * Return value: (transfer none): a pointer to a #ClutterInputDevice - * or %NULL - */ -ClutterInputDevice * -clutter_event_get_source_device (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, NULL); - - if (event->any.source_device) - return event->any.source_device; - else - return clutter_event_get_device (event); -} - -/** - * clutter_event_get_axes: - * @event: a #ClutterEvent - * @n_axes: (out): return location for the number of axes returned - * - * Retrieves the array of axes values attached to the event. - * - * Return value: (transfer none): an array of axis values - */ -gdouble * -clutter_event_get_axes (const ClutterEvent *event, - guint *n_axes) -{ - gdouble *retval = NULL; - - switch (event->type) - { - case CLUTTER_NOTHING: - case CLUTTER_ENTER: - case CLUTTER_LEAVE: - case CLUTTER_KEY_PRESS: - case CLUTTER_KEY_RELEASE: - case CLUTTER_EVENT_LAST: - case CLUTTER_PROXIMITY_IN: - case CLUTTER_PROXIMITY_OUT: - case CLUTTER_DEVICE_ADDED: - case CLUTTER_DEVICE_REMOVED: - break; - - case CLUTTER_SCROLL: - retval = event->scroll.axes; - break; - - case CLUTTER_BUTTON_PRESS: - case CLUTTER_BUTTON_RELEASE: - retval = event->button.axes; - break; - - case CLUTTER_TOUCH_BEGIN: - case CLUTTER_TOUCH_UPDATE: - case CLUTTER_TOUCH_END: - case CLUTTER_TOUCH_CANCEL: - retval = event->touch.axes; - break; - - case CLUTTER_MOTION: - retval = event->motion.axes; - break; - - 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 (n_axes) - *n_axes = CLUTTER_INPUT_AXIS_LAST; - - return retval; -} - -/** - * clutter_event_get_distance: - * @source: a #ClutterEvent - * @target: a #ClutterEvent - * - * Retrieves the distance between two events, a @source and a @target. - * - * Return value: the distance between two #ClutterEvent - */ -float -clutter_event_get_distance (const ClutterEvent *source, - const ClutterEvent *target) -{ - graphene_point_t p0, p1; - - clutter_event_get_position (source, &p0); - clutter_event_get_position (source, &p1); - - return graphene_point_distance (&p0, &p1, NULL, NULL); -} - -/** - * clutter_event_get_angle: - * @source: a #ClutterEvent - * @target: a #ClutterEvent - * - * Retrieves the angle relative from @source to @target. - * - * The direction of the angle is from the position X axis towards - * the positive Y axis. - * - * Return value: the angle between two #ClutterEvent - */ -double -clutter_event_get_angle (const ClutterEvent *source, - const ClutterEvent *target) -{ - graphene_point_t p0, p1; - float x_distance, y_distance; - double angle; - - clutter_event_get_position (source, &p0); - clutter_event_get_position (target, &p1); - - if (graphene_point_equal (&p0, &p1)) - return 0; - - graphene_point_distance (&p0, &p1, &x_distance, &y_distance); - - angle = atan2 (x_distance, y_distance); - - /* invert the angle, and shift it by 90 degrees */ - angle = (2.0 * G_PI) - angle; - angle += G_PI / 2.0; - - /* keep the angle within the [ 0, 360 ] interval */ - angle = fmod (angle, 2.0 * G_PI); - - return angle; -} - -/** - * clutter_event_has_shift_modifier: - * @event: a #ClutterEvent - * - * Checks whether @event has the Shift modifier mask set. - * - * Return value: %TRUE if the event has the Shift modifier mask set - */ -gboolean -clutter_event_has_shift_modifier (const ClutterEvent *event) -{ - return (clutter_event_get_state (event) & CLUTTER_SHIFT_MASK) != FALSE; -} - -/** - * clutter_event_has_control_modifier: - * @event: a #ClutterEvent - * - * Checks whether @event has the Control modifier mask set. - * - * Return value: %TRUE if the event has the Control modifier mask set - */ -gboolean -clutter_event_has_control_modifier (const ClutterEvent *event) -{ - return (clutter_event_get_state (event) & CLUTTER_CONTROL_MASK) != FALSE; -} - -/** - * clutter_event_is_pointer_emulated: - * @event: a #ClutterEvent - * - * Checks whether a pointer @event has been generated by the windowing - * system. The returned value can be used to distinguish between events - * synthesized by the windowing system itself (as opposed by Clutter). - * - * Return value: %TRUE if the event is pointer emulated - */ -gboolean -clutter_event_is_pointer_emulated (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, FALSE); - - return !!(event->any.flags & CLUTTER_EVENT_FLAG_POINTER_EMULATED); -} - -gboolean -_clutter_event_process_filters (ClutterEvent *event, - ClutterActor *event_actor) -{ - ClutterContext *context = _clutter_context_get_default (); - GList *l, *next; - - /* Event filters are handled in order from least recently added to - * most recently added */ - - for (l = context->event_filters; l; l = next) - { - ClutterEventFilter *event_filter = l->data; - - next = l->next; - - if (event_filter->stage && - event_filter->stage != CLUTTER_STAGE (clutter_actor_get_stage (event_actor))) - continue; - - if (event_filter->func (event, event_actor, event_filter->user_data) == CLUTTER_EVENT_STOP) - return CLUTTER_EVENT_STOP; - } - - return CLUTTER_EVENT_PROPAGATE; -} - -/** - * clutter_event_add_filter: - * @stage: (allow-none): The #ClutterStage to capture events for - * @func: The callback function which will be passed all events. - * @notify: A #GDestroyNotify - * @user_data: A data pointer to pass to the function. - * - * Adds a function which will be called for all events that Clutter - * processes. The function will be called before any signals are - * emitted for the event and it will take precedence over any grabs. - * - * Return value: an identifier for the event filter, to be used - * with [func@Clutter.Event.remove_filter]. - */ -guint -clutter_event_add_filter (ClutterStage *stage, - ClutterEventFilterFunc func, - GDestroyNotify notify, - gpointer user_data) -{ - ClutterContext *context = _clutter_context_get_default (); - ClutterEventFilter *event_filter = g_new0 (ClutterEventFilter, 1); - static guint event_filter_id = 0; - - event_filter->stage = stage; - event_filter->id = ++event_filter_id; - event_filter->func = func; - event_filter->notify = notify; - event_filter->user_data = user_data; - - /* The event filters are kept in order from least recently added to - * most recently added so we must add it to the end */ - context->event_filters = g_list_append (context->event_filters, event_filter); - - return event_filter->id; -} - -/** - * clutter_event_remove_filter: - * @id: The ID of the event filter, as returned from [func@Clutter.Event.add_filter] - * - * Removes an event filter that was previously added with - * [func@Clutter.Event.add_filter]. - */ -void -clutter_event_remove_filter (guint id) -{ - ClutterContext *context = _clutter_context_get_default (); - GList *l; - - for (l = context->event_filters; l; l = l->next) - { - ClutterEventFilter *event_filter = l->data; - - if (event_filter->id == id) - { - if (event_filter->notify) - event_filter->notify (event_filter->user_data); - - context->event_filters = g_list_delete_link (context->event_filters, l); - g_free (event_filter); - return; - } - } - - g_warning ("No event filter found for id: %d\n", id); -} - -/** - * clutter_event_get_touchpad_gesture_finger_count: - * @event: a touchpad swipe/pinch event - * - * Returns the number of fingers that is triggering the touchpad gesture. - * - * Returns: the number of fingers in the gesture.4 - **/ -guint -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); - - 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; -} - -/** - * clutter_event_get_gesture_pinch_angle_delta: - * @event: a touchpad pinch event - * - * Returns the angle delta reported by this specific event. - * - * Returns: The angle delta relative to the previous event.4 - **/ -gdouble -clutter_event_get_gesture_pinch_angle_delta (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, 0); - g_return_val_if_fail (event->type == CLUTTER_TOUCHPAD_PINCH, 0); - - return event->touchpad_pinch.angle_delta; -} - -/** - * clutter_event_get_gesture_pinch_scale: - * @event: a touchpad pinch event - * - * Returns the current scale as reported by @event, 1.0 being the original - * distance at the time the corresponding event with phase - * %CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN is received. - * is received. - * - * Returns: the current pinch gesture scale4 - **/ -gdouble -clutter_event_get_gesture_pinch_scale (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, 0); - g_return_val_if_fail (event->type == CLUTTER_TOUCHPAD_PINCH, 0); - - return event->touchpad_pinch.scale; -} - -/** - * clutter_event_get_gesture_phase: - * @event: a touchpad gesture event - * - * Returns the phase of the event, See #ClutterTouchpadGesturePhase. - * - * Returns: the phase of the gesture event. - **/ -ClutterTouchpadGesturePhase -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); - - 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; -}; - -/** - * clutter_event_get_gesture_motion_delta: - * @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 gesture motion deltas relative to the current pointer - * position.4 - **/ -void -clutter_event_get_gesture_motion_delta (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; - if (dy) - *dy = event->touchpad_pinch.dy; - } - else if (event->type == CLUTTER_TOUCHPAD_SWIPE) - { - if (dx) - *dx = event->touchpad_swipe.dx; - 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 [method@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 - * - * Returns the #ClutterScrollSource that applies to an scroll event. - * - * Returns: The source of scroll events6 - **/ -ClutterScrollSource -clutter_event_get_scroll_source (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, CLUTTER_SCROLL_SOURCE_UNKNOWN); - g_return_val_if_fail (event->type == CLUTTER_SCROLL, - CLUTTER_SCROLL_SOURCE_UNKNOWN); - - return event->scroll.scroll_source; -} - -/** - * clutter_event_get_scroll_finish_flags: - * @event: an scroll event - * - * Returns the #ClutterScrollFinishFlags of an scroll event. Those - * can be used to determine whether post-scroll effects like kinetic - * scrolling should be applied. - * - * Returns: The scroll finish flags6 - **/ -ClutterScrollFinishFlags -clutter_event_get_scroll_finish_flags (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, CLUTTER_SCROLL_FINISHED_NONE); - g_return_val_if_fail (event->type == CLUTTER_SCROLL, - CLUTTER_SCROLL_FINISHED_NONE); - - return event->scroll.finish_flags; -} - -guint -clutter_event_get_mode_group (const ClutterEvent *event) -{ - g_return_val_if_fail (event->type == CLUTTER_PAD_BUTTON_PRESS || - event->type == CLUTTER_PAD_BUTTON_RELEASE || - event->type == CLUTTER_PAD_RING || - event->type == CLUTTER_PAD_STRIP, 0); - switch (event->type) - { - case CLUTTER_PAD_BUTTON_PRESS: - case CLUTTER_PAD_BUTTON_RELEASE: - return event->pad_button.group; - case CLUTTER_PAD_RING: - return event->pad_ring.group; - case CLUTTER_PAD_STRIP: - return event->pad_strip.group; - default: - return 0; - } -} - -/** - * clutter_event_get_pad_details: - * @event: a pad event - * @number: (out) (optional): ring/strip/button number - * @mode: (out) (optional): pad mode as per the event - * @source: (out) (optional): source of the event - * @value: (out) (optional): event axis value - * - * Returns the details of a pad event. - * - * Returns: #TRUE if event details could be obtained - **/ -gboolean -clutter_event_get_pad_details (const ClutterEvent *event, - guint *number, - guint *mode, - ClutterInputDevicePadSource *source, - gdouble *value) -{ - ClutterInputDevicePadSource s; - guint n, m; - gdouble v; - - g_return_val_if_fail (event != NULL, FALSE); - g_return_val_if_fail (event->type == CLUTTER_PAD_BUTTON_PRESS || - event->type == CLUTTER_PAD_BUTTON_RELEASE || - event->type == CLUTTER_PAD_RING || - event->type == CLUTTER_PAD_STRIP, FALSE); - - switch (event->type) - { - case CLUTTER_PAD_BUTTON_PRESS: - case CLUTTER_PAD_BUTTON_RELEASE: - n = event->pad_button.button; - m = event->pad_button.mode; - s = CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN; - v = 0.0; - break; - case CLUTTER_PAD_RING: - n = event->pad_ring.ring_number; - m = event->pad_ring.mode; - s = event->pad_ring.ring_source; - v = event->pad_ring.angle; - break; - case CLUTTER_PAD_STRIP: - n = event->pad_strip.strip_number; - m = event->pad_strip.mode; - s = event->pad_strip.strip_source; - v = event->pad_strip.value; - break; - default: - return FALSE; - } - - if (number) - *number = n; - if (mode) - *mode = m; - if (source) - *source = s; - if (value) - *value = v; - - 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) -{ - return event->any.time_us; -} - -gboolean -clutter_event_get_relative_motion (const ClutterEvent *event, - double *dx, - double *dy, - double *dx_unaccel, - double *dy_unaccel, - double *dx_constrained, - double *dy_constrained) -{ - 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; - if (dx_constrained) - *dx_constrained = event->motion.dx_constrained; - if (dy_constrained) - *dy_constrained = event->motion.dy_constrained; - - return TRUE; - } - else - return FALSE; -} - -const char * -clutter_event_get_im_text (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, NULL); - g_return_val_if_fail (event->type == CLUTTER_IM_COMMIT || - event->type == CLUTTER_IM_PREEDIT, NULL); - - return event->im.text; -} - -gboolean -clutter_event_get_im_location (const ClutterEvent *event, - int32_t *offset, - int32_t *anchor) -{ - g_return_val_if_fail (event != NULL, FALSE); - g_return_val_if_fail (event->type == CLUTTER_IM_DELETE || - event->type == CLUTTER_IM_PREEDIT, FALSE); - - if (offset) - *offset = event->im.offset; - if (anchor) - *anchor = event->im.anchor; - - return TRUE; -} - -uint32_t -clutter_event_get_im_delete_length (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, 0); - g_return_val_if_fail (event->type == CLUTTER_IM_DELETE, 0); - - return event->im.len; -} - -ClutterPreeditResetMode -clutter_event_get_im_preedit_reset_mode (const ClutterEvent *event) -{ - g_return_val_if_fail (event != NULL, CLUTTER_PREEDIT_RESET_CLEAR); - g_return_val_if_fail (event->type == CLUTTER_IM_COMMIT || - event->type == CLUTTER_IM_PREEDIT, - CLUTTER_PREEDIT_RESET_CLEAR); - - return event->im.mode; -} - -const char * -clutter_event_get_name (const ClutterEvent *event) -{ - switch (event->type) - { - case CLUTTER_KEY_PRESS: - return "key-press"; - case CLUTTER_KEY_RELEASE: - return "key-release"; - case CLUTTER_MOTION: - return "motion"; - case CLUTTER_ENTER: - return "enter"; - case CLUTTER_LEAVE: - return "leave"; - case CLUTTER_BUTTON_PRESS: - return "button-press"; - case CLUTTER_BUTTON_RELEASE: - return "button-release"; - case CLUTTER_SCROLL: - return "scroll"; - case CLUTTER_TOUCH_BEGIN: - return "touch-begin"; - case CLUTTER_TOUCH_UPDATE: - return "touch-update"; - case CLUTTER_TOUCH_END: - return "touch-end"; - case CLUTTER_TOUCH_CANCEL: - return "touch-cancel"; - case CLUTTER_TOUCHPAD_PINCH: - return "touchpad-pinch"; - case CLUTTER_TOUCHPAD_SWIPE: - return "touchpad-swipe"; - case CLUTTER_TOUCHPAD_HOLD: - return "touchpad-hold"; - case CLUTTER_PROXIMITY_IN: - return "proximity-in"; - case CLUTTER_PROXIMITY_OUT: - return "proximity-out"; - case CLUTTER_PAD_BUTTON_PRESS: - return "pad-button-press"; - case CLUTTER_PAD_BUTTON_RELEASE: - return "pad-button-release"; - case CLUTTER_PAD_STRIP: - return "pad-strip"; - case CLUTTER_PAD_RING: - return "pad-ring"; - case CLUTTER_DEVICE_ADDED: - return "device-added"; - case CLUTTER_DEVICE_REMOVED: - return "device-removed"; - case CLUTTER_IM_COMMIT: - return "im-commit"; - case CLUTTER_IM_DELETE: - return "im-delete"; - case CLUTTER_IM_PREEDIT: - return "im-preedit"; - case CLUTTER_NOTHING: - case CLUTTER_EVENT_LAST: - break; - } - g_assert_not_reached (); -} - -ClutterEvent * -clutter_event_key_new (ClutterEventType type, - ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterModifierSet raw_modifiers, - ClutterModifierType modifiers, - uint32_t keyval, - uint32_t evcode, - uint32_t keycode, - gunichar unicode_value) -{ - ClutterEvent *event; - ClutterSeat *seat; - - g_return_val_if_fail (type == CLUTTER_KEY_PRESS || - type == CLUTTER_KEY_RELEASE, NULL); - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (source_device), NULL); - - seat = clutter_input_device_get_seat (source_device); - - event = clutter_event_new (type); - - event->key.time_us = timestamp_us; - event->key.flags = flags; - event->key.raw_modifiers = raw_modifiers; - event->key.modifier_state = modifiers; - event->key.keyval = keyval; - event->key.hardware_keycode = keycode; - event->key.unicode_value = unicode_value; - event->key.evdev_code = evcode; - g_set_object (&event->key.device, clutter_seat_get_keyboard (seat)); - g_set_object (&event->key.source_device, source_device); - - return event; -} - -ClutterEvent * -clutter_event_button_new (ClutterEventType type, - ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterInputDeviceTool *tool, - ClutterModifierType modifiers, - graphene_point_t coords, - int button, - uint32_t evcode, - double *axes) -{ - ClutterEvent *event; - - g_return_val_if_fail (type == CLUTTER_BUTTON_PRESS || - type == CLUTTER_BUTTON_RELEASE, NULL); - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (source_device), NULL); - g_return_val_if_fail (!tool || CLUTTER_IS_INPUT_DEVICE_TOOL (tool), NULL); - - event = clutter_event_new (type); - - event->button.time_us = timestamp_us; - event->button.flags = flags; - event->button.x = coords.x; - event->button.y = coords.y; - event->button.modifier_state = modifiers; - event->button.button = button; - event->button.axes = axes; - event->button.evdev_code = evcode; - event->button.tool = tool; - - g_set_object (&event->button.source_device, source_device); - - if (clutter_input_device_get_device_mode (source_device) == - CLUTTER_INPUT_MODE_FLOATING) - { - g_set_object (&event->button.device, source_device); - } - else - { - ClutterSeat *seat; - - seat = clutter_input_device_get_seat (source_device); - g_set_object (&event->button.device, clutter_seat_get_pointer (seat)); - } - - return event; -} - -ClutterEvent * -clutter_event_motion_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterInputDeviceTool *tool, - ClutterModifierType modifiers, - graphene_point_t coords, - graphene_point_t delta, - graphene_point_t delta_unaccel, - graphene_point_t delta_constrained, - double *axes) -{ - ClutterEvent *event; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (source_device), NULL); - g_return_val_if_fail (!tool || CLUTTER_IS_INPUT_DEVICE_TOOL (tool), NULL); - - event = clutter_event_new (CLUTTER_MOTION); - - event->motion.time_us = timestamp_us; - event->motion.flags = flags; - event->motion.x = coords.x; - event->motion.y = coords.y; - event->motion.modifier_state = modifiers; - event->motion.axes = axes; - event->motion.dx = delta.x; - event->motion.dy = delta.y; - event->motion.dx_unaccel = delta_unaccel.x; - event->motion.dy_unaccel = delta_unaccel.y; - event->motion.dx_constrained = delta_constrained.x; - event->motion.dy_constrained = delta_constrained.y; - event->motion.tool = tool; - - g_set_object (&event->motion.source_device, source_device); - - if (clutter_input_device_get_device_mode (source_device) == - CLUTTER_INPUT_MODE_FLOATING) - { - g_set_object (&event->motion.device, source_device); - } - else - { - ClutterSeat *seat; - - seat = clutter_input_device_get_seat (source_device); - g_set_object (&event->motion.device, clutter_seat_get_pointer (seat)); - } - - return event; -} - -ClutterEvent * -clutter_event_scroll_smooth_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterInputDeviceTool *tool, - ClutterModifierType modifiers, - graphene_point_t coords, - graphene_point_t delta, - ClutterScrollSource scroll_source, - ClutterScrollFinishFlags finish_flags) -{ - ClutterEvent *event; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (source_device), NULL); - g_return_val_if_fail (!tool || CLUTTER_IS_INPUT_DEVICE_TOOL (tool), NULL); - - event = clutter_event_new (CLUTTER_SCROLL); - - event->scroll.time_us = timestamp_us; - event->scroll.flags = flags; - event->scroll.x = coords.x; - event->scroll.y = coords.y; - event->scroll.delta_x = delta.x; - event->scroll.delta_y = delta.y; - event->scroll.direction = CLUTTER_SCROLL_SMOOTH; - event->scroll.modifier_state = modifiers; - event->scroll.scroll_source = scroll_source; - event->scroll.finish_flags = finish_flags; - event->scroll.tool = tool; - - g_set_object (&event->scroll.source_device, source_device); - - if (clutter_input_device_get_device_mode (source_device) == - CLUTTER_INPUT_MODE_FLOATING) - { - g_set_object (&event->scroll.device, source_device); - } - else - { - ClutterSeat *seat; - - seat = clutter_input_device_get_seat (source_device); - g_set_object (&event->scroll.device, clutter_seat_get_pointer (seat)); - } - - return event; -} - -ClutterEvent * -clutter_event_scroll_discrete_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterInputDeviceTool *tool, - ClutterModifierType modifiers, - graphene_point_t coords, - ClutterScrollSource scroll_source, - ClutterScrollDirection direction) -{ - ClutterEvent *event; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (source_device), NULL); - g_return_val_if_fail (!tool || CLUTTER_IS_INPUT_DEVICE_TOOL (tool), NULL); - - event = clutter_event_new (CLUTTER_SCROLL); - - event->scroll.time_us = timestamp_us; - event->scroll.flags = flags; - event->scroll.x = coords.x; - event->scroll.y = coords.y; - event->scroll.direction = direction; - event->scroll.scroll_source = scroll_source; - event->scroll.modifier_state = modifiers; - event->scroll.tool = tool; - - g_set_object (&event->scroll.source_device, source_device); - - if (clutter_input_device_get_device_mode (source_device) == - CLUTTER_INPUT_MODE_FLOATING) - { - g_set_object (&event->scroll.device, source_device); - } - else - { - ClutterSeat *seat; - - seat = clutter_input_device_get_seat (source_device); - g_set_object (&event->scroll.device, clutter_seat_get_pointer (seat)); - } - - return event; -} - -ClutterEvent * -clutter_event_crossing_new (ClutterEventType type, - ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterEventSequence *sequence, - graphene_point_t coords, - ClutterActor *source, - ClutterActor *related) -{ - ClutterInputDevice *device; - ClutterEvent *event; - - g_return_val_if_fail (type == CLUTTER_ENTER || - type == CLUTTER_LEAVE, NULL); - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (source_device), NULL); - - if (clutter_input_device_get_device_mode (source_device) == - CLUTTER_INPUT_MODE_FLOATING) - { - device = source_device; - } - else - { - ClutterSeat *seat; - - seat = clutter_input_device_get_seat (source_device); - device = clutter_seat_get_pointer (seat); - } - - event = clutter_event_new (type); - - event->crossing.time_us = timestamp_us; - event->crossing.flags = flags; - event->crossing.x = coords.x; - event->crossing.y = coords.y; - event->crossing.sequence = sequence; - event->crossing.source = source; - event->crossing.related = related; - g_set_object (&event->crossing.device, device); - g_set_object (&event->crossing.source_device, source_device); - - return event; -} - -ClutterEvent * -clutter_event_touch_new (ClutterEventType type, - ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterEventSequence *sequence, - ClutterModifierType modifiers, - graphene_point_t coords) -{ - ClutterEvent *event; - ClutterSeat *seat; - - g_return_val_if_fail (type == CLUTTER_TOUCH_BEGIN || - type == CLUTTER_TOUCH_UPDATE || - type == CLUTTER_TOUCH_END, NULL); - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (source_device), NULL); - g_return_val_if_fail (sequence != NULL, NULL); - - seat = clutter_input_device_get_seat (source_device); - - event = clutter_event_new (type); - - event->touch.time_us = timestamp_us; - event->touch.flags = flags; - event->touch.x = coords.x; - event->touch.y = coords.y; - event->touch.modifier_state = modifiers; - event->touch.sequence = sequence; - - /* This has traditionally been the virtual pointer device */ - g_set_object (&event->touch.device, clutter_seat_get_pointer (seat)); - g_set_object (&event->touch.source_device, source_device); - - return event; -} - -ClutterEvent * -clutter_event_touch_cancel_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterEventSequence *sequence) -{ - ClutterEvent *event; - ClutterSeat *seat; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (source_device), NULL); - g_return_val_if_fail (sequence != NULL, NULL); - - seat = clutter_input_device_get_seat (source_device); - - event = clutter_event_new (CLUTTER_TOUCH_CANCEL); - - event->touch.time_us = timestamp_us; - event->touch.flags = flags; - event->touch.sequence = sequence; - - /* This has traditionally been the virtual pointer device */ - g_set_object (&event->touch.device, clutter_seat_get_pointer (seat)); - g_set_object (&event->touch.source_device, source_device); - - return event; -} - -ClutterEvent * -clutter_event_proximity_new (ClutterEventType type, - ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterInputDeviceTool *tool) -{ - ClutterEvent *event; - - g_return_val_if_fail (type == CLUTTER_PROXIMITY_IN || - type == CLUTTER_PROXIMITY_OUT, NULL); - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (source_device), NULL); - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL (tool), NULL); - - event = clutter_event_new (type); - - event->proximity.time_us = timestamp_us; - event->proximity.flags = flags; - event->proximity.tool = tool; - - g_set_object (&event->proximity.device, source_device); - g_set_object (&event->proximity.source_device, source_device); - - return event; -} - -ClutterEvent * -clutter_event_touchpad_pinch_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterTouchpadGesturePhase phase, - uint32_t fingers, - graphene_point_t coords, - graphene_point_t delta, - graphene_point_t delta_unaccel, - float angle, - float scale) -{ - ClutterEvent *event; - ClutterSeat *seat; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (source_device), NULL); - - seat = clutter_input_device_get_seat (source_device); - - event = clutter_event_new (CLUTTER_TOUCHPAD_PINCH); - - event->touchpad_pinch.time_us = timestamp_us; - event->touchpad_pinch.flags = flags; - event->touchpad_pinch.phase = phase; - event->touchpad_pinch.x = coords.x; - event->touchpad_pinch.y = coords.y; - event->touchpad_pinch.dx = delta.x; - event->touchpad_pinch.dy = delta.y; - event->touchpad_pinch.dx_unaccel = delta_unaccel.x; - event->touchpad_pinch.dy_unaccel = delta_unaccel.y; - event->touchpad_pinch.angle_delta = angle; - event->touchpad_pinch.scale = scale; - event->touchpad_pinch.n_fingers = fingers; - - g_set_object (&event->touchpad_pinch.device, clutter_seat_get_pointer (seat)); - g_set_object (&event->touchpad_pinch.source_device, source_device); - - return event; -} - -ClutterEvent * -clutter_event_touchpad_swipe_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterTouchpadGesturePhase phase, - uint32_t fingers, - graphene_point_t coords, - graphene_point_t delta, - graphene_point_t delta_unaccel) -{ - ClutterEvent *event; - ClutterSeat *seat; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (source_device), NULL); - - seat = clutter_input_device_get_seat (source_device); - - event = clutter_event_new (CLUTTER_TOUCHPAD_SWIPE); - - event->touchpad_swipe.time_us = timestamp_us; - event->touchpad_swipe.flags = flags; - event->touchpad_swipe.phase = phase; - event->touchpad_swipe.x = coords.x; - event->touchpad_swipe.y = coords.y; - event->touchpad_swipe.dx = delta.x; - event->touchpad_swipe.dy = delta.y; - event->touchpad_swipe.dx_unaccel = delta_unaccel.x; - event->touchpad_swipe.dy_unaccel = delta_unaccel.y; - event->touchpad_swipe.n_fingers = fingers; - - g_set_object (&event->touchpad_swipe.device, clutter_seat_get_pointer (seat)); - g_set_object (&event->touchpad_swipe.source_device, source_device); - - return event; -} - -ClutterEvent * -clutter_event_touchpad_hold_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterTouchpadGesturePhase phase, - uint32_t fingers, - graphene_point_t coords) -{ - ClutterEvent *event; - ClutterSeat *seat; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (source_device), NULL); - - seat = clutter_input_device_get_seat (source_device); - - event = clutter_event_new (CLUTTER_TOUCHPAD_HOLD); - - event->touchpad_hold.time_us = timestamp_us; - event->touchpad_hold.flags = flags; - event->touchpad_hold.phase = phase; - event->touchpad_hold.x = coords.x; - event->touchpad_hold.y = coords.y; - event->touchpad_hold.n_fingers = fingers; - - g_set_object (&event->touchpad_hold.device, clutter_seat_get_pointer (seat)); - g_set_object (&event->touchpad_hold.source_device, source_device); - - return event; -} - -ClutterEvent * -clutter_event_pad_button_new (ClutterEventType type, - ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - uint32_t button, - uint32_t group, - uint32_t mode) -{ - ClutterEvent *event; - - g_return_val_if_fail (type == CLUTTER_PAD_BUTTON_PRESS || - type == CLUTTER_PAD_BUTTON_RELEASE, NULL); - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (source_device), NULL); - - event = clutter_event_new (type); - - event->pad_button.time_us = timestamp_us; - event->pad_button.flags = flags; - event->pad_button.button = button; - event->pad_button.group = group; - event->pad_button.mode = mode; - - g_set_object (&event->pad_button.device, source_device); - g_set_object (&event->pad_button.source_device, source_device); - - return event; -} - -ClutterEvent * -clutter_event_pad_strip_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterInputDevicePadSource strip_source, - uint32_t strip, - uint32_t group, - double value, - uint32_t mode) -{ - ClutterEvent *event; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (source_device), NULL); - - event = clutter_event_new (CLUTTER_PAD_STRIP); - - event->pad_strip.time_us = timestamp_us; - event->pad_strip.flags = flags; - event->pad_strip.strip_source = strip_source; - event->pad_strip.strip_number = strip; - event->pad_strip.group = group; - event->pad_strip.value = value; - event->pad_strip.mode = mode; - - g_set_object (&event->pad_strip.device, source_device); - g_set_object (&event->pad_strip.source_device, source_device); - - return event; -} - -ClutterEvent * -clutter_event_pad_ring_new (ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device, - ClutterInputDevicePadSource ring_source, - uint32_t ring, - uint32_t group, - double angle, - uint32_t mode) -{ - ClutterEvent *event; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (source_device), NULL); - - event = clutter_event_new (CLUTTER_PAD_RING); - - event->pad_ring.time_us = timestamp_us; - event->pad_ring.flags = flags; - event->pad_ring.ring_source = ring_source; - event->pad_ring.ring_number = ring; - event->pad_ring.group = group; - event->pad_ring.angle = angle; - event->pad_ring.mode = mode; - - g_set_object (&event->pad_ring.device, source_device); - g_set_object (&event->pad_ring.source_device, source_device); - - return event; -} - -ClutterEvent * -clutter_event_device_notify_new (ClutterEventType type, - ClutterEventFlags flags, - int64_t timestamp_us, - ClutterInputDevice *source_device) -{ - ClutterEvent *event; - - g_return_val_if_fail (type == CLUTTER_DEVICE_ADDED || - type == CLUTTER_DEVICE_REMOVED, NULL); - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (source_device), NULL); - - event = clutter_event_new (type); - - event->device.time_us = timestamp_us; - event->device.flags = flags; - - g_set_object (&event->device.device, source_device); - - return event; -} - -ClutterEvent * -clutter_event_im_new (ClutterEventType type, - ClutterEventFlags flags, - int64_t timestamp_us, - ClutterSeat *seat, - const char *text, - int32_t offset, - int32_t anchor, - uint32_t len, - ClutterPreeditResetMode mode) -{ - ClutterEvent *event; - - g_return_val_if_fail (type == CLUTTER_IM_COMMIT || - type == CLUTTER_IM_DELETE || - type == CLUTTER_IM_PREEDIT, NULL); - - event = clutter_event_new (type); - - event->im.time_us = timestamp_us; - event->im.flags = flags; - event->im.text = g_strdup (text); - event->im.offset = offset; - event->im.anchor = anchor; - event->im.len = len; - event->im.mode = mode; - - g_set_object (&event->im.device, clutter_seat_get_keyboard (seat)); - - return event; -} - -static const char * -scroll_source_to_string (ClutterScrollSource scroll_source) -{ - switch (scroll_source) - { - case CLUTTER_SCROLL_SOURCE_UNKNOWN: - return "unknown"; - case CLUTTER_SCROLL_SOURCE_WHEEL: - return "wheel"; - case CLUTTER_SCROLL_SOURCE_FINGER: - return "finger"; - case CLUTTER_SCROLL_SOURCE_CONTINUOUS: - return "continuous"; - } - g_return_val_if_reached (""); -} - -static const char * -touchpad_gesture_phase_to_string (ClutterTouchpadGesturePhase phase) -{ - switch (phase) - { - case CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN: - return "begin"; - case CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE: - return "update"; - case CLUTTER_TOUCHPAD_GESTURE_PHASE_END: - return "end"; - case CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL: - return "cancel"; - } - g_return_val_if_reached (""); -} - -static const char * -pad_source_to_string (ClutterInputDevicePadSource pad_source) -{ - switch (pad_source) - { - case CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN: - return "unknown"; - case CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER: - return "finger"; - } - g_return_val_if_reached (""); -} - -static const char * -scroll_direction_to_string (ClutterScrollDirection scroll_direction) -{ - switch (scroll_direction) - { - case CLUTTER_SCROLL_SMOOTH: - g_warn_if_reached (); - return ""; - case CLUTTER_SCROLL_LEFT: - return "left"; - case CLUTTER_SCROLL_RIGHT: - return "right"; - case CLUTTER_SCROLL_UP: - return "up"; - case CLUTTER_SCROLL_DOWN: - return "down"; - } - g_return_val_if_reached (""); -} - -static char * -generate_event_description (const ClutterEvent *event) -{ - switch (event->type) - { - case CLUTTER_KEY_PRESS: - case CLUTTER_KEY_RELEASE: - if (g_strcmp0 (g_getenv ("MUTTER_DEBUG_LOG_KEYCODES"), "1") == 0) - { - char unicode[7] = {}; - - if (event->key.unicode_value) - g_unichar_to_utf8 (event->key.unicode_value, unicode); - return g_strdup_printf ("keycode=%u, evdev=%u, " - "keysym=%u, unicode='%s'", - event->key.hardware_keycode, - event->key.evdev_code, - event->key.keyval, - event->key.unicode_value ? unicode : "N\\A"); - } - else - { - return g_strdup ("(hidden)"); - } - case CLUTTER_MOTION: - return g_strdup_printf ("abs=(%f, %f), rel=(%f, %f), unaccel-rel=(%f, %f)", - event->motion.x, - event->motion.y, - event->motion.dx, - event->motion.dy, - event->motion.dx_unaccel, - event->motion.dy_unaccel); - case CLUTTER_BUTTON_PRESS: - case CLUTTER_BUTTON_RELEASE: - return g_strdup_printf ("button=%u, evdev=%u", - event->button.button, - event->button.evdev_code); - case CLUTTER_SCROLL: - if (event->scroll.direction == CLUTTER_SCROLL_SMOOTH) - { - double dx, dy; - ClutterScrollSource scroll_source; - - clutter_event_get_scroll_delta (event, &dx, &dy); - scroll_source = event->scroll.scroll_source; - return g_strdup_printf ("source=%s, rel: (%f, %f)", - scroll_source_to_string (scroll_source), - dx, dy); - } - else - { - ClutterScrollDirection direction = event->scroll.direction; - - return g_strdup_printf ("direction=%s", - scroll_direction_to_string (direction)); - } - case CLUTTER_TOUCH_BEGIN: - case CLUTTER_TOUCH_UPDATE: - case CLUTTER_TOUCH_END: - case CLUTTER_TOUCH_CANCEL: - return g_strdup_printf ("slot=%d, abs=(%f, %f)", - GPOINTER_TO_INT (event->touch.sequence), - event->touch.x, - event->touch.y); - case CLUTTER_TOUCHPAD_PINCH: - return g_strdup_printf ("phase=%s, rel=(%f, %f), unaccel-rel=(%f, %f), " - "angle-delta=%f, scale=%f, n-fingers=%d", - touchpad_gesture_phase_to_string (event->touchpad_pinch.phase), - event->touchpad_pinch.dx, - event->touchpad_pinch.dy, - event->touchpad_pinch.dx_unaccel, - event->touchpad_pinch.dy_unaccel, - event->touchpad_pinch.angle_delta, - event->touchpad_pinch.scale, - event->touchpad_pinch.n_fingers); - case CLUTTER_TOUCHPAD_SWIPE: - return g_strdup_printf ("phase=%s, rel=(%f, %f), unaccel-rel=(%f, %f), " - "n-fingers=%d", - touchpad_gesture_phase_to_string (event->touchpad_pinch.phase), - event->touchpad_swipe.dx, - event->touchpad_swipe.dy, - event->touchpad_swipe.dx_unaccel, - event->touchpad_swipe.dy_unaccel, - event->touchpad_swipe.n_fingers); - case CLUTTER_TOUCHPAD_HOLD: - return g_strdup_printf ("phase=%s, n-fingers=%d", - touchpad_gesture_phase_to_string (event->touchpad_pinch.phase), - event->touchpad_hold.n_fingers); - case CLUTTER_PROXIMITY_IN: - case CLUTTER_PROXIMITY_OUT: - return g_strdup (""); - case CLUTTER_PAD_BUTTON_PRESS: - case CLUTTER_PAD_BUTTON_RELEASE: - return g_strdup_printf ("button=%u, group=%u, mode=%u", - event->pad_button.button, - event->pad_button.group, - event->pad_button.mode); - case CLUTTER_PAD_STRIP: - return g_strdup_printf ("source=%s (%d), value=%f, group=%u, mode=%u", - pad_source_to_string (event->pad_strip.strip_source), - event->pad_strip.strip_number, - event->pad_strip.value, - event->pad_strip.group, - event->pad_strip.mode); - case CLUTTER_PAD_RING: - return g_strdup_printf ("source=%s (%d), angle=%f, group=%u, mode=%u", - pad_source_to_string (event->pad_ring.ring_source), - event->pad_ring.ring_number, - event->pad_ring.angle, - event->pad_ring.group, - event->pad_ring.mode); - case CLUTTER_DEVICE_ADDED: - case CLUTTER_DEVICE_REMOVED: - { - ClutterInputDevice *device; - - device = clutter_event_get_device (event); - return g_strdup_printf ("%s (%s)", - clutter_input_device_get_device_name (device), - clutter_input_device_get_device_node (device)); - } - default: - g_warn_if_reached (); - return g_strdup (""); - } -} - -static char * -generate_modifiers_description (const ClutterEvent *event) -{ - ClutterModifierType modifiers; - GString *str; - - modifiers = clutter_event_get_state (event); - - if (modifiers == 0) - return g_strdup ("none"); - - str = g_string_new (NULL); - - if (modifiers & CLUTTER_SHIFT_MASK) - g_string_append (str, "shift "); - if (modifiers & CLUTTER_LOCK_MASK) - g_string_append (str, "lock "); - if (modifiers & CLUTTER_CONTROL_MASK) - g_string_append (str, "control "); - if (modifiers & CLUTTER_MOD1_MASK) - g_string_append (str, "mod1 "); - if (modifiers & CLUTTER_MOD2_MASK) - g_string_append (str, "mod2 "); - if (modifiers & CLUTTER_MOD3_MASK) - g_string_append (str, "mod3 "); - if (modifiers & CLUTTER_MOD4_MASK) - g_string_append (str, "mod4 "); - if (modifiers & CLUTTER_MOD5_MASK) - g_string_append (str, "mod5 "); - if (modifiers & CLUTTER_BUTTON1_MASK) - g_string_append (str, "button1 "); - if (modifiers & CLUTTER_BUTTON2_MASK) - g_string_append (str, "button2 "); - if (modifiers & CLUTTER_BUTTON3_MASK) - g_string_append (str, "button3 "); - if (modifiers & CLUTTER_BUTTON4_MASK) - g_string_append (str, "button4 "); - if (modifiers & CLUTTER_BUTTON5_MASK) - g_string_append (str, "button5 "); - if (modifiers & CLUTTER_SUPER_MASK) - g_string_append (str, "super "); - if (modifiers & CLUTTER_HYPER_MASK) - g_string_append (str, "hyper "); - if (modifiers & CLUTTER_META_MASK) - g_string_append (str, "meta "); - if (modifiers & CLUTTER_RELEASE_MASK) - g_string_append (str, "release "); - - /* Delete trailing space */ - g_string_erase (str, str->len - 1, 1); - - return g_string_free_and_steal (str); -} - -char * -clutter_event_describe (const ClutterEvent *event) -{ - g_autofree char *event_description = NULL; - g_autofree char *modifiers_description = NULL; - ClutterInputDevice *source_device; - - source_device = clutter_event_get_source_device (event); - event_description = generate_event_description (event); - modifiers_description = generate_modifiers_description (event); - - return g_strdup_printf ("'%s'%s%s, time=%" G_GINT64_FORMAT " us, modifiers=%s, %s", - clutter_event_get_name (event), - source_device ? " from " : "", - source_device ? - clutter_input_device_get_device_node (source_device) : - "", - event->any.time_us, - modifiers_description, - event_description); -} diff --git a/mutter/clutter/clutter/clutter-event.h b/mutter/clutter/clutter/clutter-event.h deleted file mode 100644 index 62f244c..0000000 --- a/mutter/clutter/clutter/clutter-event.h +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * 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 . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" -#include "clutter/clutter-input-device.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_EVENT (clutter_event_get_type ()) -#define CLUTTER_TYPE_EVENT_SEQUENCE (clutter_event_sequence_get_type ()) - -/** - * CLUTTER_PRIORITY_EVENTS: - * - * Priority for event handling. - */ -#define CLUTTER_PRIORITY_EVENTS (G_PRIORITY_DEFAULT) - -/** - * CLUTTER_CURRENT_TIME: - * - * Default value for "now". - */ -#define CLUTTER_CURRENT_TIME (0L) - -/** - * CLUTTER_EVENT_PROPAGATE: - * - * Continues the propagation of an event; this macro should be - * used in event-related signals. - */ -#define CLUTTER_EVENT_PROPAGATE (FALSE) - -/** - * CLUTTER_EVENT_STOP: - * - * Stops the propagation of an event; this macro should be used - * in event-related signals. - */ -#define CLUTTER_EVENT_STOP (TRUE) - -/** - * CLUTTER_BUTTON_PRIMARY: - * - * The primary button of a pointer device. - * - * This is typically the left mouse button in a right-handed - * mouse configuration. - */ -#define CLUTTER_BUTTON_PRIMARY (1) - -/** - * CLUTTER_BUTTON_MIDDLE: - * - * The middle button of a pointer device. - */ -#define CLUTTER_BUTTON_MIDDLE (2) - -/** - * CLUTTER_BUTTON_SECONDARY: - * - * The secondary button of a pointer device. - * - * This is typically the right mouse button in a right-handed - * mouse configuration. - */ -#define CLUTTER_BUTTON_SECONDARY (3) - -typedef struct _ClutterAnyEvent ClutterAnyEvent; -typedef struct _ClutterButtonEvent ClutterButtonEvent; -typedef struct _ClutterKeyEvent ClutterKeyEvent; -typedef struct _ClutterMotionEvent ClutterMotionEvent; -typedef struct _ClutterScrollEvent ClutterScrollEvent; -typedef struct _ClutterCrossingEvent ClutterCrossingEvent; -typedef struct _ClutterTouchEvent ClutterTouchEvent; -typedef struct _ClutterTouchpadPinchEvent ClutterTouchpadPinchEvent; -typedef struct _ClutterTouchpadSwipeEvent ClutterTouchpadSwipeEvent; -typedef struct _ClutterTouchpadHoldEvent ClutterTouchpadHoldEvent; -typedef struct _ClutterProximityEvent ClutterProximityEvent; -typedef struct _ClutterPadButtonEvent ClutterPadButtonEvent; -typedef struct _ClutterPadStripEvent ClutterPadStripEvent; -typedef struct _ClutterPadRingEvent ClutterPadRingEvent; -typedef struct _ClutterDeviceEvent ClutterDeviceEvent; -typedef struct _ClutterIMEvent ClutterIMEvent; - -/** - * ClutterEventFilterFunc: - * @event: the event that is going to be emitted - * @event_actor: the current device actor of the events device - * @user_data: the data pointer passed to [func@Clutter.Event.add_filter] - * - * A function pointer type used by event filters that are added with - * [func@Clutter.Event.add_filter]. - * - * Return value: %CLUTTER_EVENT_STOP to indicate that the event - * has been handled or %CLUTTER_EVENT_PROPAGATE otherwise. - * Returning %CLUTTER_EVENT_STOP skips any further filter - * functions and prevents the signal emission for the event. - */ -typedef gboolean (* ClutterEventFilterFunc) (const ClutterEvent *event, - ClutterActor *event_actor, - gpointer user_data); - -CLUTTER_EXPORT -GType clutter_event_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -GType clutter_event_sequence_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -gboolean clutter_events_pending (void); -CLUTTER_EXPORT -ClutterEvent * clutter_event_get (void); -CLUTTER_EXPORT -void clutter_event_put (const ClutterEvent *event); - -CLUTTER_EXPORT -guint clutter_event_add_filter (ClutterStage *stage, - ClutterEventFilterFunc func, - GDestroyNotify notify, - gpointer user_data); -CLUTTER_EXPORT -void clutter_event_remove_filter (guint id); - -CLUTTER_EXPORT -ClutterEvent * clutter_event_copy (const ClutterEvent *event); -CLUTTER_EXPORT -void clutter_event_free (ClutterEvent *event); - -CLUTTER_EXPORT -ClutterEventType clutter_event_type (const ClutterEvent *event); -CLUTTER_EXPORT -ClutterEventFlags clutter_event_get_flags (const ClutterEvent *event); -CLUTTER_EXPORT -guint32 clutter_event_get_time (const ClutterEvent *event); -CLUTTER_EXPORT -ClutterModifierType clutter_event_get_state (const ClutterEvent *event); -CLUTTER_EXPORT -ClutterInputDevice * clutter_event_get_device (const ClutterEvent *event); - -CLUTTER_EXPORT -ClutterInputDevice * clutter_event_get_source_device (const ClutterEvent *event); - -CLUTTER_EXPORT -ClutterInputDeviceTool *clutter_event_get_device_tool (const ClutterEvent *event); - -CLUTTER_EXPORT -ClutterActor * clutter_event_get_source (const ClutterEvent *event); -CLUTTER_EXPORT -ClutterInputDeviceType clutter_event_get_device_type (const ClutterEvent *event); -CLUTTER_EXPORT -void clutter_event_get_coords (const ClutterEvent *event, - gfloat *x, - gfloat *y); -CLUTTER_EXPORT -void clutter_event_get_position (const ClutterEvent *event, - graphene_point_t *position); -CLUTTER_EXPORT -float clutter_event_get_distance (const ClutterEvent *source, - const ClutterEvent *target); -CLUTTER_EXPORT -double clutter_event_get_angle (const ClutterEvent *source, - const ClutterEvent *target); -CLUTTER_EXPORT -gdouble * clutter_event_get_axes (const ClutterEvent *event, - guint *n_axes); -CLUTTER_EXPORT -gboolean clutter_event_has_shift_modifier (const ClutterEvent *event); -CLUTTER_EXPORT -gboolean clutter_event_has_control_modifier (const ClutterEvent *event); -CLUTTER_EXPORT -gboolean clutter_event_is_pointer_emulated (const ClutterEvent *event); -CLUTTER_EXPORT -guint clutter_event_get_key_symbol (const ClutterEvent *event); -CLUTTER_EXPORT -guint16 clutter_event_get_key_code (const ClutterEvent *event); -CLUTTER_EXPORT -gunichar clutter_event_get_key_unicode (const ClutterEvent *event); -CLUTTER_EXPORT -void clutter_event_get_key_state (const ClutterEvent *event, - ClutterModifierType *pressed, - ClutterModifierType *latched, - ClutterModifierType *locked); -CLUTTER_EXPORT -guint32 clutter_event_get_button (const ClutterEvent *event); -CLUTTER_EXPORT -ClutterActor * clutter_event_get_related (const ClutterEvent *event); -CLUTTER_EXPORT -ClutterScrollDirection clutter_event_get_scroll_direction (const ClutterEvent *event); -CLUTTER_EXPORT -void clutter_event_get_scroll_delta (const ClutterEvent *event, - gdouble *dx, - gdouble *dy); - -CLUTTER_EXPORT -ClutterEventSequence * clutter_event_get_event_sequence (const ClutterEvent *event); - -CLUTTER_EXPORT -guint32 clutter_keysym_to_unicode (guint keyval); -CLUTTER_EXPORT -guint clutter_unicode_to_keysym (guint32 wc); - -CLUTTER_EXPORT -guint32 clutter_get_current_event_time (void); -CLUTTER_EXPORT -const ClutterEvent * clutter_get_current_event (void); - -CLUTTER_EXPORT -guint clutter_event_get_touchpad_gesture_finger_count (const ClutterEvent *event); - -CLUTTER_EXPORT -gdouble clutter_event_get_gesture_pinch_angle_delta (const ClutterEvent *event); - -CLUTTER_EXPORT -gdouble clutter_event_get_gesture_pinch_scale (const ClutterEvent *event); - -CLUTTER_EXPORT -ClutterTouchpadGesturePhase clutter_event_get_gesture_phase (const ClutterEvent *event); - -CLUTTER_EXPORT -void clutter_event_get_gesture_motion_delta (const ClutterEvent *event, - gdouble *dx, - gdouble *dy); - -CLUTTER_EXPORT -void clutter_event_get_gesture_motion_delta_unaccelerated (const ClutterEvent *event, - gdouble *dx, - gdouble *dy); - -CLUTTER_EXPORT -ClutterScrollSource clutter_event_get_scroll_source (const ClutterEvent *event); - -CLUTTER_EXPORT -ClutterScrollFinishFlags clutter_event_get_scroll_finish_flags (const ClutterEvent *event); - -CLUTTER_EXPORT -guint clutter_event_get_mode_group (const ClutterEvent *event); - -CLUTTER_EXPORT -gboolean clutter_event_get_pad_details (const ClutterEvent *event, - guint *number, - guint *mode, - ClutterInputDevicePadSource *source, - gdouble *value); -CLUTTER_EXPORT -uint32_t clutter_event_get_event_code (const ClutterEvent *event); - -CLUTTER_EXPORT -int32_t clutter_event_sequence_get_slot (const ClutterEventSequence *sequence); - -CLUTTER_EXPORT -int64_t clutter_event_get_time_us (const ClutterEvent *event); -CLUTTER_EXPORT -gboolean clutter_event_get_relative_motion (const ClutterEvent *event, - double *dx, - double *dy, - double *dx_unaccel, - double *dy_unaccel, - double *dx_constrained, - double *dy_constrained); - -CLUTTER_EXPORT -const char * clutter_event_get_im_text (const ClutterEvent *event); -CLUTTER_EXPORT -gboolean clutter_event_get_im_location (const ClutterEvent *event, - int32_t *offset, - int32_t *anchor); -CLUTTER_EXPORT -uint32_t clutter_event_get_im_delete_length (const ClutterEvent *event); -CLUTTER_EXPORT -ClutterPreeditResetMode clutter_event_get_im_preedit_reset_mode (const ClutterEvent *event); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-feature.c b/mutter/clutter/clutter/clutter-feature.c deleted file mode 100644 index 2294cc2..0000000 --- a/mutter/clutter/clutter/clutter-feature.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * 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 . - * - * - */ - -/** - * Run-time detection of Clutter features - * - * Parts of Clutter depend on the underlying platform, including the - * capabilities of the backend used and the OpenGL features exposed through the - * Clutter and COGL API. - * - * It is possible to ask whether Clutter has support for specific features at - * run-time. - */ - -#include "config.h" - -#include -#include -#include - -#include "clutter/clutter-backend-private.h" -#include "clutter/clutter-feature.h" -#include "clutter/clutter-main.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-debug.h" - -#include "cogl/cogl.h" - -typedef struct ClutterFeatures -{ - ClutterFeatureFlags flags; - guint features_set : 1; -} ClutterFeatures; - -static ClutterFeatures* __features = NULL; - -static ClutterFeatureFlags -clutter_features_from_cogl (void) -{ - ClutterFeatureFlags clutter_flags = 0; - - clutter_flags |= CLUTTER_FEATURE_SHADERS_GLSL; - - return clutter_flags; -} - -gboolean -clutter_feature_init (ClutterMainContext *context, - GError **error) -{ - CLUTTER_NOTE (MISC, "checking features"); - - if (!__features) - { - CLUTTER_NOTE (MISC, "allocating features data"); - __features = g_new0 (ClutterFeatures, 1); - __features->features_set = FALSE; /* don't rely on zero-ing */ - } - - if (__features->features_set) - return TRUE; - - /* 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->features_set = TRUE; - - CLUTTER_NOTE (MISC, "features checked"); - - return TRUE; -} - -/** - * clutter_feature_available: - * @feature: a #ClutterFeatureFlags - * - * Checks whether @feature is available. @feature can be a logical - * OR of #ClutterFeatureFlags. - * - * Return value: %TRUE if a feature is available - */ -gboolean -clutter_feature_available (ClutterFeatureFlags feature) -{ - if (G_UNLIKELY (!__features)) - { - g_critical ("Unable to check features. Have you initialized Clutter?"); - return FALSE; - } - - return (__features->flags & feature); -} - -/** - * clutter_feature_get_all: - * - * Returns all the supported features. - * - * Return value: a logical OR of all the supported features. - */ -ClutterFeatureFlags -clutter_feature_get_all (void) -{ - if (G_UNLIKELY (!__features)) - { - g_critical ("Unable to check features. Have you initialized Clutter?"); - return FALSE; - } - - return __features->flags; -} - diff --git a/mutter/clutter/clutter/clutter-fixed-layout.c b/mutter/clutter/clutter/clutter-fixed-layout.c deleted file mode 100644 index 2fed3d5..0000000 --- a/mutter/clutter/clutter/clutter-fixed-layout.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - * - * Based on the fixed layout code inside clutter-group.c - */ - -/** - * ClutterFixedLayout: - * - * A fixed layout manager - * - * #ClutterFixedLayout is a layout manager implementing the same - * layout policies as #ClutterGroup. - */ - -#include "config.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-fixed-layout.h" -#include "clutter/clutter-private.h" - -G_DEFINE_TYPE (ClutterFixedLayout, - clutter_fixed_layout, - CLUTTER_TYPE_LAYOUT_MANAGER); - -static void -clutter_fixed_layout_get_preferred_width (ClutterLayoutManager *manager, - ClutterActor *container, - gfloat for_height, - gfloat *min_width_p, - gfloat *nat_width_p) -{ - ClutterActor *actor, *child; - gdouble min_right; - gdouble natural_right; - - min_right = 0; - natural_right = 0; - - actor = CLUTTER_ACTOR (container); - - for (child = clutter_actor_get_first_child (actor); - child != NULL; - child = clutter_actor_get_next_sibling (child)) - { - gfloat child_x, child_min, child_natural; - - if (!clutter_actor_is_visible (child)) - continue; - - child_x = clutter_actor_get_x (child); - - clutter_actor_get_preferred_size (child, - &child_min, NULL, - &child_natural, NULL); - - if (child_x + child_min > min_right) - min_right = child_x + child_min; - - if (child_x + child_natural > natural_right) - natural_right = child_x + child_natural; - } - - if (min_width_p) - *min_width_p = min_right; - - if (nat_width_p) - *nat_width_p = natural_right; -} - -static void -clutter_fixed_layout_get_preferred_height (ClutterLayoutManager *manager, - ClutterActor *container, - gfloat for_width, - gfloat *min_height_p, - gfloat *nat_height_p) -{ - ClutterActor *actor, *child; - gdouble min_bottom; - gdouble natural_bottom; - - min_bottom = 0; - natural_bottom = 0; - - actor = CLUTTER_ACTOR (container); - - for (child = clutter_actor_get_first_child (actor); - child != NULL; - child = clutter_actor_get_next_sibling (child)) - { - gfloat child_y, child_min, child_natural; - - if (!clutter_actor_is_visible (child)) - continue; - - child_y = clutter_actor_get_y (child); - - clutter_actor_get_preferred_size (child, - NULL, &child_min, - NULL, &child_natural); - - if (child_y + child_min > min_bottom) - min_bottom = child_y + child_min; - - if (child_y + child_natural > natural_bottom) - natural_bottom = child_y + child_natural; - } - - if (min_height_p) - *min_height_p = min_bottom; - - if (nat_height_p) - *nat_height_p = natural_bottom; -} - -static void -clutter_fixed_layout_allocate (ClutterLayoutManager *manager, - ClutterActor *container, - const ClutterActorBox *allocation) -{ - ClutterActor *child; - - for (child = clutter_actor_get_first_child (CLUTTER_ACTOR (container)); - child != NULL; - child = clutter_actor_get_next_sibling (child)) - { - float x = 0.f; - float y = 0.f; - - clutter_actor_get_fixed_position (child, &x, &y); - clutter_actor_allocate_preferred_size (child, x, y); - } -} - -static void -clutter_fixed_layout_class_init (ClutterFixedLayoutClass *klass) -{ - ClutterLayoutManagerClass *manager_class = - CLUTTER_LAYOUT_MANAGER_CLASS (klass); - - manager_class->get_preferred_width = - clutter_fixed_layout_get_preferred_width; - manager_class->get_preferred_height = - clutter_fixed_layout_get_preferred_height; - manager_class->allocate = clutter_fixed_layout_allocate; -} - -static void -clutter_fixed_layout_init (ClutterFixedLayout *self) -{ -} - -/** - * clutter_fixed_layout_new: - * - * Creates a new #ClutterFixedLayout - * - * Return value: the newly created #ClutterFixedLayout - */ -ClutterLayoutManager * -clutter_fixed_layout_new (void) -{ - return g_object_new (CLUTTER_TYPE_FIXED_LAYOUT, NULL); -} diff --git a/mutter/clutter/clutter/clutter-fixed-layout.h b/mutter/clutter/clutter/clutter-fixed-layout.h deleted file mode 100644 index 92c19b8..0000000 --- a/mutter/clutter/clutter/clutter-fixed-layout.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-layout-manager.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_FIXED_LAYOUT (clutter_fixed_layout_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterFixedLayout, - clutter_fixed_layout, - CLUTTER, FIXED_LAYOUT, - ClutterLayoutManager) - -struct _ClutterFixedLayoutClass -{ - /*< private >*/ - ClutterLayoutManagerClass parent_class; -}; - -CLUTTER_EXPORT -ClutterLayoutManager *clutter_fixed_layout_new (void); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-flatten-effect.c b/mutter/clutter/clutter/clutter-flatten-effect.c deleted file mode 100644 index 4d24b09..0000000 --- a/mutter/clutter/clutter/clutter-flatten-effect.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Authors: - * Neil Roberts - */ - -/* This is an internal-only effect used to implement the - 'offscreen-redirect' property of ClutterActor. It doesn't actually - need to do anything on top of the ClutterOffscreenEffect class so - it only exists because that class is abstract */ - -#include "config.h" - -#include "clutter/clutter-flatten-effect.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-actor-private.h" - -struct _ClutterFlattenEffect -{ - ClutterOffscreenEffect parent; -}; - -G_DEFINE_TYPE (ClutterFlattenEffect, - _clutter_flatten_effect, - CLUTTER_TYPE_OFFSCREEN_EFFECT); - -static void -_clutter_flatten_effect_class_init (ClutterFlattenEffectClass *klass) -{ -} - -static void -_clutter_flatten_effect_init (ClutterFlattenEffect *self) -{ -} - -ClutterEffect * -_clutter_flatten_effect_new (void) -{ - return g_object_new (CLUTTER_TYPE_FLATTEN_EFFECT, NULL); -} diff --git a/mutter/clutter/clutter/clutter-flatten-effect.h b/mutter/clutter/clutter/clutter-flatten-effect.h deleted file mode 100644 index 2f63cdf..0000000 --- a/mutter/clutter/clutter/clutter-flatten-effect.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Authors: - * Neil Roberts - */ - -#pragma once - -#include "clutter/clutter-offscreen-effect.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_FLATTEN_EFFECT (_clutter_flatten_effect_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_FINAL_TYPE (ClutterFlattenEffect, - _clutter_flatten_effect, - CLUTTER, - FLATTEN_EFFECT, - ClutterOffscreenEffect) - - -ClutterEffect *_clutter_flatten_effect_new (void); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-flow-layout.c b/mutter/clutter/clutter/clutter-flow-layout.c deleted file mode 100644 index 6d00dab..0000000 --- a/mutter/clutter/clutter/clutter-flow-layout.c +++ /dev/null @@ -1,1438 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterFlowLayout: - * - * A reflowing layout manager - * - * #ClutterFlowLayout is a layout manager which implements the following - * policy: - * - * - the preferred natural size depends on the value - * of the #ClutterFlowLayout:orientation property; the layout will try - * to maintain all its children on a single row or - * column; - * - if either the width or the height allocated are - * smaller than the preferred ones, the layout will wrap; in this case, - * the preferred height or width, respectively, will take into account - * the amount of columns and rows; - * - each line (either column or row) in reflowing will - * have the size of the biggest cell on that line; if the - * #ClutterFlowLayout:homogeneous property is set to %FALSE the actor - * will be allocated within that area, and if set to %TRUE instead the - * actor will be given exactly that area; - * - the size of the columns or rows can be controlled - * for both minimum and maximum; the spacing can also be controlled - * in both columns and rows. - */ - -#include "config.h" - -#include - -#include "clutter/clutter-actor.h" -#include "clutter/clutter-animatable.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-flow-layout.h" -#include "clutter/clutter-layout-meta.h" -#include "clutter/clutter-private.h" - -struct _ClutterFlowLayout -{ - ClutterLayoutManager parent_instance; - - ClutterActor *container; - - ClutterOrientation orientation; - - gfloat col_spacing; - gfloat row_spacing; - - gfloat min_col_width; - gfloat max_col_width; - gfloat col_width; - - gfloat min_row_height; - gfloat max_row_height; - gfloat row_height; - - /* per-line size */ - GArray *line_min; - GArray *line_natural; - gfloat req_width; - gfloat req_height; - - guint line_count; - - guint is_homogeneous : 1; - guint snap_to_grid : 1; -}; - -enum -{ - PROP_0, - - PROP_ORIENTATION, - - PROP_HOMOGENEOUS, - - PROP_COLUMN_SPACING, - PROP_ROW_SPACING, - - PROP_MIN_COLUMN_WIDTH, - PROP_MAX_COLUMN_WIDTH, - PROP_MIN_ROW_HEGHT, - PROP_MAX_ROW_HEIGHT, - - PROP_SNAP_TO_GRID, - - N_PROPERTIES -}; - -static GParamSpec *flow_properties[N_PROPERTIES] = { NULL, }; - -G_DEFINE_FINAL_TYPE (ClutterFlowLayout, - clutter_flow_layout, - CLUTTER_TYPE_LAYOUT_MANAGER) - -static gint -get_columns (ClutterFlowLayout *self, - gfloat for_width) -{ - gint n_columns; - - if (for_width < 0) - return 1; - - if (self->col_width == 0) - return 1; - - n_columns = (gint) (for_width + self->col_spacing) - / (self->col_width + self->col_spacing); - - if (n_columns == 0) - return 1; - - return n_columns; -} - -static gint -get_rows (ClutterFlowLayout *self, - gfloat for_height) -{ - gint n_rows; - - if (for_height < 0) - return 1; - - if (self->row_height == 0) - return 1; - - n_rows = (gint) (for_height + self->row_spacing) - / (self->row_height + self->row_spacing); - - if (n_rows == 0) - return 1; - - return n_rows; -} - -static gint -compute_lines (ClutterFlowLayout *self, - gfloat avail_width, - gfloat avail_height) -{ - if (self->orientation == CLUTTER_ORIENTATION_HORIZONTAL) - return get_columns (self, avail_width); - else - return get_rows (self, avail_height); -} - -static void -clutter_flow_layout_get_preferred_width (ClutterLayoutManager *manager, - ClutterActor *container, - gfloat for_height, - gfloat *min_width_p, - gfloat *nat_width_p) -{ - ClutterFlowLayout *self = CLUTTER_FLOW_LAYOUT (manager); - gint n_rows, line_item_count, line_count; - gfloat total_min_width, total_natural_width; - gfloat line_min_width, line_natural_width; - gfloat max_min_width, max_natural_width; - ClutterActor *actor, *child; - ClutterActorIter iter; - gfloat item_y; - - n_rows = get_rows (CLUTTER_FLOW_LAYOUT (manager), for_height); - - total_min_width = 0; - total_natural_width = 0; - - line_min_width = 0; - line_natural_width = 0; - - line_item_count = 0; - line_count = 0; - - item_y = 0; - - actor = CLUTTER_ACTOR (container); - - /* clear the line width arrays */ - if (self->line_min != NULL) - g_array_free (self->line_min, TRUE); - - if (self->line_natural != NULL) - g_array_free (self->line_natural, TRUE); - - self->line_min = g_array_sized_new (FALSE, FALSE, - sizeof (gfloat), - 16); - self->line_natural = g_array_sized_new (FALSE, FALSE, - sizeof (gfloat), - 16); - - if (clutter_actor_get_n_children (actor) != 0) - line_count = 1; - - max_min_width = max_natural_width = 0; - - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) - { - gfloat child_min, child_natural; - gfloat new_y, item_height; - - if (!clutter_actor_is_visible (child)) - continue; - - if (self->orientation == CLUTTER_ORIENTATION_VERTICAL && for_height > 0) - { - clutter_actor_get_preferred_height (child, -1, - &child_min, - &child_natural); - - if ((self->snap_to_grid && line_item_count == n_rows) || - (!self->snap_to_grid && item_y + child_natural > for_height)) - { - total_min_width += line_min_width; - total_natural_width += line_natural_width; - - g_array_append_val (self->line_min, - line_min_width); - g_array_append_val (self->line_natural, - line_natural_width); - - line_min_width = line_natural_width = 0; - - line_item_count = 0; - line_count += 1; - item_y = 0; - } - - if (self->snap_to_grid) - { - new_y = ((line_item_count + 1) * (for_height + self->row_spacing)) - / n_rows; - item_height = new_y - item_y - self->row_spacing; - } - else - { - new_y = item_y + child_natural + self->row_spacing; - item_height = child_natural; - } - - clutter_actor_get_preferred_width (child, item_height, - &child_min, - &child_natural); - - line_min_width = MAX (line_min_width, child_min); - line_natural_width = MAX (line_natural_width, child_natural); - - item_y = new_y; - line_item_count += 1; - - max_min_width = MAX (max_min_width, line_min_width); - max_natural_width = MAX (max_natural_width, line_natural_width); - } - else - { - clutter_actor_get_preferred_width (child, for_height, - &child_min, - &child_natural); - - max_min_width = MAX (max_min_width, child_min); - max_natural_width = MAX (max_natural_width, child_natural); - - total_min_width += max_min_width; - total_natural_width += max_natural_width; - line_count += 1; - } - } - - self->col_width = max_natural_width; - - if (self->max_col_width > 0 && self->col_width > self->max_col_width) - self->col_width = MAX (self->max_col_width, max_min_width); - - if (self->col_width < self->min_col_width) - self->col_width = self->min_col_width; - - if (self->orientation == CLUTTER_ORIENTATION_VERTICAL && for_height > 0) - { - /* if we have a non-full row we need to add it */ - if (line_item_count > 0) - { - total_min_width += line_min_width; - total_natural_width += line_natural_width; - - g_array_append_val (self->line_min, - line_min_width); - g_array_append_val (self->line_natural, - line_natural_width); - } - - self->line_count = line_count; - - if (self->line_count > 0) - { - gfloat total_spacing; - - total_spacing = self->col_spacing * (self->line_count - 1); - - total_min_width += total_spacing; - total_natural_width += total_spacing; - } - } - else - { - g_array_append_val (self->line_min, line_min_width); - g_array_append_val (self->line_natural, line_natural_width); - - self->line_count = line_count; - - if (self->line_count > 0) - { - gfloat total_spacing; - - total_spacing = self->col_spacing * (self->line_count - 1); - - total_min_width += total_spacing; - total_natural_width += total_spacing; - } - } - - CLUTTER_NOTE (LAYOUT, - "Flow[w]: %d lines (%d per line): w [ %.2f, %.2f ] for h %.2f", - n_rows, self->line_count, - total_min_width, - total_natural_width, - for_height); - - self->req_height = for_height; - - if (min_width_p) - *min_width_p = max_min_width; - - if (nat_width_p) - *nat_width_p = total_natural_width; -} - -static void -clutter_flow_layout_get_preferred_height (ClutterLayoutManager *manager, - ClutterActor *container, - gfloat for_width, - gfloat *min_height_p, - gfloat *nat_height_p) -{ - ClutterFlowLayout *self = CLUTTER_FLOW_LAYOUT (manager); - gint n_columns, line_item_count, line_count; - gfloat total_min_height, total_natural_height; - gfloat line_min_height, line_natural_height; - gfloat max_min_height, max_natural_height; - ClutterActor *actor, *child; - ClutterActorIter iter; - gfloat item_x; - - n_columns = get_columns (CLUTTER_FLOW_LAYOUT (manager), for_width); - - total_min_height = 0; - total_natural_height = 0; - - line_min_height = 0; - line_natural_height = 0; - - line_item_count = 0; - line_count = 0; - - item_x = 0; - - actor = CLUTTER_ACTOR (container); - - /* clear the line height arrays */ - if (self->line_min != NULL) - g_array_free (self->line_min, TRUE); - - if (self->line_natural != NULL) - g_array_free (self->line_natural, TRUE); - - self->line_min = g_array_sized_new (FALSE, FALSE, - sizeof (gfloat), - 16); - self->line_natural = g_array_sized_new (FALSE, FALSE, - sizeof (gfloat), - 16); - - if (clutter_actor_get_n_children (actor) != 0) - line_count = 1; - - max_min_height = max_natural_height = 0; - - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) - { - gfloat child_min, child_natural; - gfloat new_x, item_width; - - if (!clutter_actor_is_visible (child)) - continue; - - if (self->orientation == CLUTTER_ORIENTATION_HORIZONTAL && for_width > 0) - { - clutter_actor_get_preferred_width (child, -1, - &child_min, - &child_natural); - - if ((self->snap_to_grid && line_item_count == n_columns) || - (!self->snap_to_grid && item_x + child_natural > for_width)) - { - total_min_height += line_min_height; - total_natural_height += line_natural_height; - - g_array_append_val (self->line_min, - line_min_height); - g_array_append_val (self->line_natural, - line_natural_height); - - line_min_height = line_natural_height = 0; - - line_item_count = 0; - line_count += 1; - item_x = 0; - } - - if (self->snap_to_grid) - { - new_x = ((line_item_count + 1) * (for_width + self->col_spacing)) - / n_columns; - item_width = new_x - item_x - self->col_spacing; - } - else - { - new_x = item_x + child_natural + self->col_spacing; - item_width = child_natural; - } - - clutter_actor_get_preferred_height (child, item_width, - &child_min, - &child_natural); - - line_min_height = MAX (line_min_height, child_min); - line_natural_height = MAX (line_natural_height, child_natural); - - item_x = new_x; - line_item_count += 1; - - max_min_height = MAX (max_min_height, line_min_height); - max_natural_height = MAX (max_natural_height, line_natural_height); - } - else - { - clutter_actor_get_preferred_height (child, for_width, - &child_min, - &child_natural); - - max_min_height = MAX (max_min_height, child_min); - max_natural_height = MAX (max_natural_height, child_natural); - - total_min_height += max_min_height; - total_natural_height += max_natural_height; - - line_count += 1; - } - } - - self->row_height = max_natural_height; - - if (self->max_row_height > 0 && self->row_height > self->max_row_height) - self->row_height = MAX (self->max_row_height, max_min_height); - - if (self->row_height < self->min_row_height) - self->row_height = self->min_row_height; - - if (self->orientation == CLUTTER_ORIENTATION_HORIZONTAL && for_width > 0) - { - /* if we have a non-full row we need to add it */ - if (line_item_count > 0) - { - total_min_height += line_min_height; - total_natural_height += line_natural_height; - - g_array_append_val (self->line_min, - line_min_height); - g_array_append_val (self->line_natural, - line_natural_height); - } - - self->line_count = line_count; - if (self->line_count > 0) - { - gfloat total_spacing; - - total_spacing = self->row_spacing * (self->line_count - 1); - - total_min_height += total_spacing; - total_natural_height += total_spacing; - } - } - else - { - g_array_append_val (self->line_min, line_min_height); - g_array_append_val (self->line_natural, line_natural_height); - - self->line_count = line_count; - - if (self->line_count > 0) - { - gfloat total_spacing; - - total_spacing = self->col_spacing * self->line_count; - - total_min_height += total_spacing; - total_natural_height += total_spacing; - } - } - - CLUTTER_NOTE (LAYOUT, - "Flow[h]: %d lines (%d per line): w [ %.2f, %.2f ] for h %.2f", - n_columns, self->line_count, - total_min_height, - total_natural_height, - for_width); - - self->req_width = for_width; - - if (min_height_p) - *min_height_p = max_min_height; - - if (nat_height_p) - *nat_height_p = total_natural_height; -} - -static void -clutter_flow_layout_allocate (ClutterLayoutManager *manager, - ClutterActor *container, - const ClutterActorBox *allocation) -{ - ClutterFlowLayout *self = CLUTTER_FLOW_LAYOUT (manager); - ClutterActor *actor, *child; - ClutterActorIter iter; - gfloat x_off, y_off; - gfloat avail_width, avail_height; - gfloat item_x, item_y; - gint line_item_count; - gint items_per_line; - gint line_index; - - actor = CLUTTER_ACTOR (container); - if (clutter_actor_get_n_children (actor) == 0) - return; - - clutter_actor_box_get_origin (allocation, &x_off, &y_off); - clutter_actor_box_get_size (allocation, &avail_width, &avail_height); - - /* blow the cached preferred size and re-compute with the given - * available size in case the FlowLayout wasn't given the exact - * size it requested - */ - if ((self->req_width >= 0 && avail_width != self->req_width) || - (self->req_height >= 0 && avail_height != self->req_height)) - { - clutter_flow_layout_get_preferred_width (manager, container, - avail_height, - NULL, NULL); - clutter_flow_layout_get_preferred_height (manager, container, - avail_width, - NULL, NULL); - } - - items_per_line = compute_lines (CLUTTER_FLOW_LAYOUT (manager), - avail_width, avail_height); - - item_x = x_off; - item_y = y_off; - - line_item_count = 0; - line_index = 0; - - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) - { - ClutterActorBox child_alloc; - gfloat item_width, item_height; - gfloat new_x, new_y; - gfloat child_min, child_natural; - - if (!clutter_actor_is_visible (child)) - continue; - - new_x = new_y = 0; - - if (!self->snap_to_grid) - clutter_actor_get_preferred_size (child, - NULL, NULL, - &item_width, - &item_height); - - if (self->orientation == CLUTTER_ORIENTATION_HORIZONTAL) - { - if ((self->snap_to_grid && - line_item_count == items_per_line && line_item_count > 0) || - (!self->snap_to_grid && item_x + item_width > avail_width)) - { - item_y += g_array_index (self->line_natural, - gfloat, - line_index); - - if (line_index >= 0) - item_y += self->row_spacing; - - line_item_count = 0; - line_index += 1; - - item_x = x_off; - } - - if (self->snap_to_grid) - { - new_x = x_off + ((line_item_count + 1) * (avail_width + self->col_spacing)) - / items_per_line; - item_width = new_x - item_x - self->col_spacing; - } - else - { - new_x = item_x + item_width + self->col_spacing; - } - - item_height = g_array_index (self->line_natural, - gfloat, - line_index); - - } - else - { - if ((self->snap_to_grid && - line_item_count == items_per_line && line_item_count > 0) || - (!self->snap_to_grid && item_y + item_height > avail_height)) - { - item_x += g_array_index (self->line_natural, - gfloat, - line_index); - - if (line_index >= 0) - item_x += self->col_spacing; - - line_item_count = 0; - line_index += 1; - - item_y = y_off; - } - - if (self->snap_to_grid) - { - new_y = y_off + ((line_item_count + 1) * (avail_height + self->row_spacing)) - / items_per_line; - item_height = new_y - item_y - self->row_spacing; - } - else - { - new_y = item_y + item_height + self->row_spacing; - } - - item_width = g_array_index (self->line_natural, - gfloat, - line_index); - } - - if (!self->is_homogeneous && - !clutter_actor_needs_expand (child, - CLUTTER_ORIENTATION_HORIZONTAL)) - { - clutter_actor_get_preferred_width (child, item_height, - &child_min, - &child_natural); - item_width = MIN (item_width, child_natural); - } - - if (!self->is_homogeneous && - !clutter_actor_needs_expand (child, - CLUTTER_ORIENTATION_VERTICAL)) - { - clutter_actor_get_preferred_height (child, item_width, - &child_min, - &child_natural); - item_height = MIN (item_height, child_natural); - } - - CLUTTER_NOTE (LAYOUT, - "flow[line:%d, item:%d/%d] =" - "{ %.2f, %.2f, %.2f, %.2f }", - line_index, line_item_count + 1, items_per_line, - item_x, item_y, item_width, item_height); - - child_alloc.x1 = ceil (item_x); - child_alloc.y1 = ceil (item_y); - child_alloc.x2 = ceil (child_alloc.x1 + item_width); - child_alloc.y2 = ceil (child_alloc.y1 + item_height); - clutter_actor_allocate (child, &child_alloc); - - if (self->orientation == CLUTTER_ORIENTATION_HORIZONTAL) - item_x = new_x; - else - item_y = new_y; - - line_item_count += 1; - } -} - -static void -clutter_flow_layout_set_container (ClutterLayoutManager *manager, - ClutterActor *container) -{ - ClutterFlowLayout *self = CLUTTER_FLOW_LAYOUT (manager); - ClutterLayoutManagerClass *parent_class; - - self->container = container; - - if (self->container != NULL) - { - ClutterRequestMode request_mode; - - /* we need to change the :request-mode of the container - * to match the orientation - */ - request_mode = (self->orientation == CLUTTER_ORIENTATION_HORIZONTAL) - ? CLUTTER_REQUEST_HEIGHT_FOR_WIDTH - : CLUTTER_REQUEST_WIDTH_FOR_HEIGHT; - clutter_actor_set_request_mode (CLUTTER_ACTOR (self->container), - request_mode); - } - - parent_class = CLUTTER_LAYOUT_MANAGER_CLASS (clutter_flow_layout_parent_class); - parent_class->set_container (manager, container); -} - -static void -clutter_flow_layout_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterFlowLayout *self = CLUTTER_FLOW_LAYOUT (gobject); - - switch (prop_id) - { - case PROP_ORIENTATION: - clutter_flow_layout_set_orientation (self, g_value_get_enum (value)); - break; - - case PROP_HOMOGENEOUS: - clutter_flow_layout_set_homogeneous (self, g_value_get_boolean (value)); - break; - - case PROP_COLUMN_SPACING: - clutter_flow_layout_set_column_spacing (self, g_value_get_float (value)); - break; - - case PROP_ROW_SPACING: - clutter_flow_layout_set_row_spacing (self, g_value_get_float (value)); - break; - - case PROP_MIN_COLUMN_WIDTH: - clutter_flow_layout_set_column_width (self, - g_value_get_float (value), - self->max_col_width); - break; - - case PROP_MAX_COLUMN_WIDTH: - clutter_flow_layout_set_column_width (self, - self->min_col_width, - g_value_get_float (value)); - break; - - case PROP_MIN_ROW_HEGHT: - clutter_flow_layout_set_row_height (self, - g_value_get_float (value), - self->max_row_height); - break; - - case PROP_MAX_ROW_HEIGHT: - clutter_flow_layout_set_row_height (self, - self->min_row_height, - g_value_get_float (value)); - break; - - case PROP_SNAP_TO_GRID: - clutter_flow_layout_set_snap_to_grid (self, - g_value_get_boolean (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_flow_layout_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterFlowLayout *self = CLUTTER_FLOW_LAYOUT (gobject); - - switch (prop_id) - { - case PROP_ORIENTATION: - g_value_set_enum (value, self->orientation); - break; - - case PROP_HOMOGENEOUS: - g_value_set_boolean (value, self->is_homogeneous); - break; - - case PROP_COLUMN_SPACING: - g_value_set_float (value, self->col_spacing); - break; - - case PROP_ROW_SPACING: - g_value_set_float (value, self->row_spacing); - break; - - case PROP_MIN_COLUMN_WIDTH: - g_value_set_float (value, self->min_col_width); - break; - - case PROP_MAX_COLUMN_WIDTH: - g_value_set_float (value, self->max_col_width); - break; - - case PROP_MIN_ROW_HEGHT: - g_value_set_float (value, self->min_row_height); - break; - - case PROP_MAX_ROW_HEIGHT: - g_value_set_float (value, self->max_row_height); - break; - - case PROP_SNAP_TO_GRID: - g_value_set_boolean (value, self->snap_to_grid); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_flow_layout_finalize (GObject *gobject) -{ - ClutterFlowLayout *self = CLUTTER_FLOW_LAYOUT (gobject); - - if (self->line_min != NULL) - g_array_free (self->line_min, TRUE); - - if (self->line_natural != NULL) - g_array_free (self->line_natural, TRUE); - - G_OBJECT_CLASS (clutter_flow_layout_parent_class)->finalize (gobject); -} - -static void -clutter_flow_layout_class_init (ClutterFlowLayoutClass *klass) -{ - GObjectClass *gobject_class; - ClutterLayoutManagerClass *layout_class; - - gobject_class = G_OBJECT_CLASS (klass); - layout_class = CLUTTER_LAYOUT_MANAGER_CLASS (klass); - - layout_class->get_preferred_width = - clutter_flow_layout_get_preferred_width; - layout_class->get_preferred_height = - clutter_flow_layout_get_preferred_height; - layout_class->allocate = clutter_flow_layout_allocate; - layout_class->set_container = clutter_flow_layout_set_container; - - /** - * ClutterFlowLayout:orientation: - * - * The orientation of the #ClutterFlowLayout. The children - * of the layout will be laid out following the orientation. - * - * This property also controls the overflowing directions - */ - flow_properties[PROP_ORIENTATION] = - g_param_spec_enum ("orientation", NULL, NULL, - CLUTTER_TYPE_ORIENTATION, - CLUTTER_ORIENTATION_HORIZONTAL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT); - - /** - * ClutterFlowLayout:homogeneous: - * - * Whether each child inside the #ClutterFlowLayout should receive - * the same allocation - */ - flow_properties[PROP_HOMOGENEOUS] = - g_param_spec_boolean ("homogeneous", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterFlowLayout:column-spacing: - * - * The spacing between columns, in pixels; the value of this - * property is honoured by horizontal non-overflowing layouts - * and by vertical overflowing layouts - */ - flow_properties[PROP_COLUMN_SPACING] = - g_param_spec_float ("column-spacing", NULL, NULL, - 0.0, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterFlowLayout:row-spacing: - * - * The spacing between rows, in pixels; the value of this - * property is honoured by vertical non-overflowing layouts and - * by horizontal overflowing layouts - */ - flow_properties[PROP_ROW_SPACING] = - g_param_spec_float ("row-spacing", NULL, NULL, - 0.0, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterFlowLayout:min-column-width: - * - * Minimum width for each column in the layout, in pixels - */ - flow_properties[PROP_MIN_COLUMN_WIDTH] = - g_param_spec_float ("min-column-width", NULL, NULL, - 0.0, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterFlowLayout:max-column-width: - * - * Maximum width for each column in the layout, in pixels. If - * set to -1 the width will be the maximum child width - */ - flow_properties[PROP_MAX_COLUMN_WIDTH] = - g_param_spec_float ("max-column-width", NULL, NULL, - -1.0, G_MAXFLOAT, - -1.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterFlowLayout:min-row-height: - * - * Minimum height for each row in the layout, in pixels - */ - flow_properties[PROP_MIN_ROW_HEGHT] = - g_param_spec_float ("min-row-height", NULL, NULL, - 0.0, G_MAXFLOAT, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterFlowLayout:max-row-height: - * - * Maximum height for each row in the layout, in pixels. If - * set to -1 the width will be the maximum child height - */ - flow_properties[PROP_MAX_ROW_HEIGHT] = - g_param_spec_float ("max-row-height", NULL, NULL, - -1.0, G_MAXFLOAT, - -1.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterFlowLayout:snap-to-grid: - * - * Whether the #ClutterFlowLayout should arrange its children - * on a grid - */ - flow_properties[PROP_SNAP_TO_GRID] = - g_param_spec_boolean ("snap-to-grid", NULL, NULL, - TRUE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - gobject_class->finalize = clutter_flow_layout_finalize; - gobject_class->set_property = clutter_flow_layout_set_property; - gobject_class->get_property = clutter_flow_layout_get_property; - g_object_class_install_properties (gobject_class, - N_PROPERTIES, - flow_properties); -} - -static void -clutter_flow_layout_init (ClutterFlowLayout *self) -{ - self->orientation = CLUTTER_ORIENTATION_HORIZONTAL; - - self->col_spacing = 0; - self->row_spacing = 0; - - self->min_col_width = self->min_row_height = 0; - self->max_col_width = self->max_row_height = -1; - - self->line_min = NULL; - self->line_natural = NULL; - self->snap_to_grid = TRUE; -} - -/** - * clutter_flow_layout_new: - * @orientation: the orientation of the flow layout - * - * Creates a new #ClutterFlowLayout with the given @orientation - * - * Return value: the newly created #ClutterFlowLayout - */ -ClutterLayoutManager * -clutter_flow_layout_new (ClutterOrientation orientation) -{ - return g_object_new (CLUTTER_TYPE_FLOW_LAYOUT, - "orientation", orientation, - NULL); -} - -/** - * clutter_flow_layout_set_orientation: - * @layout: a #ClutterFlowLayout - * @orientation: the orientation of the layout - * - * Sets the orientation of the flow layout - * - * The orientation controls the direction used to allocate - * the children: either horizontally or vertically. The - * orientation also controls the direction of the overflowing - */ -void -clutter_flow_layout_set_orientation (ClutterFlowLayout *layout, - ClutterOrientation orientation) -{ - g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout)); - - if (layout->orientation != orientation) - { - ClutterLayoutManager *manager; - - layout->orientation = orientation; - - if (layout->container != NULL) - { - ClutterRequestMode request_mode; - - /* we need to change the :request-mode of the container - * to match the orientation - */ - request_mode = (layout->orientation == CLUTTER_ORIENTATION_HORIZONTAL) - ? CLUTTER_REQUEST_HEIGHT_FOR_WIDTH - : CLUTTER_REQUEST_WIDTH_FOR_HEIGHT; - clutter_actor_set_request_mode (CLUTTER_ACTOR (layout->container), - request_mode); - } - - manager = CLUTTER_LAYOUT_MANAGER (layout); - clutter_layout_manager_layout_changed (manager); - - g_object_notify_by_pspec (G_OBJECT (layout), - flow_properties[PROP_ORIENTATION]); - } -} - -/** - * clutter_flow_layout_get_orientation: - * @layout: a #ClutterFlowLayout - * - * Retrieves the orientation of the @layout - * - * Return value: the orientation of the #ClutterFlowLayout - */ -ClutterOrientation -clutter_flow_layout_get_orientation (ClutterFlowLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout), - CLUTTER_ORIENTATION_HORIZONTAL); - - return layout->orientation; -} - -/** - * clutter_flow_layout_set_homogeneous: - * @layout: a #ClutterFlowLayout - * @homogeneous: whether the layout should be homogeneous or not - * - * Sets whether the @layout should allocate the same space for - * each child - */ -void -clutter_flow_layout_set_homogeneous (ClutterFlowLayout *layout, - gboolean homogeneous) -{ - g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout)); - - if (layout->is_homogeneous != homogeneous) - { - ClutterLayoutManager *manager; - - layout->is_homogeneous = homogeneous; - - manager = CLUTTER_LAYOUT_MANAGER (layout); - clutter_layout_manager_layout_changed (manager); - - g_object_notify_by_pspec (G_OBJECT (layout), - flow_properties[PROP_HOMOGENEOUS]); - } -} - -/** - * clutter_flow_layout_get_homogeneous: - * @layout: a #ClutterFlowLayout - * - * Retrieves whether the @layout is homogeneous - * - * Return value: %TRUE if the #ClutterFlowLayout is homogeneous - */ -gboolean -clutter_flow_layout_get_homogeneous (ClutterFlowLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout), FALSE); - - return layout->is_homogeneous; -} - -/** - * clutter_flow_layout_set_column_spacing: - * @layout: a #ClutterFlowLayout - * @spacing: the space between columns - * - * Sets the space between columns, in pixels - */ -void -clutter_flow_layout_set_column_spacing (ClutterFlowLayout *layout, - gfloat spacing) -{ - g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout)); - - if (layout->col_spacing != spacing) - { - ClutterLayoutManager *manager; - - layout->col_spacing = spacing; - - manager = CLUTTER_LAYOUT_MANAGER (layout); - clutter_layout_manager_layout_changed (manager); - - g_object_notify_by_pspec (G_OBJECT (layout), - flow_properties[PROP_COLUMN_SPACING]); - } -} - -/** - * clutter_flow_layout_get_column_spacing: - * @layout: a #ClutterFlowLayout - * - * Retrieves the spacing between columns - * - * Return value: the spacing between columns of the #ClutterFlowLayout, - * in pixels - */ -gfloat -clutter_flow_layout_get_column_spacing (ClutterFlowLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout), 0.0); - - return layout->col_spacing; -} - -/** - * clutter_flow_layout_set_row_spacing: - * @layout: a #ClutterFlowLayout - * @spacing: the space between rows - * - * Sets the spacing between rows, in pixels - */ -void -clutter_flow_layout_set_row_spacing (ClutterFlowLayout *layout, - gfloat spacing) -{ - g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout)); - - if (layout->row_spacing != spacing) - { - ClutterLayoutManager *manager; - - layout->row_spacing = spacing; - - manager = CLUTTER_LAYOUT_MANAGER (layout); - clutter_layout_manager_layout_changed (manager); - - g_object_notify_by_pspec (G_OBJECT (layout), - flow_properties[PROP_ROW_SPACING]); - } -} - -/** - * clutter_flow_layout_get_row_spacing: - * @layout: a #ClutterFlowLayout - * - * Retrieves the spacing between rows - * - * Return value: the spacing between rows of the #ClutterFlowLayout, - * in pixels - */ -gfloat -clutter_flow_layout_get_row_spacing (ClutterFlowLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout), 0.0); - - return layout->row_spacing; -} - -/** - * clutter_flow_layout_set_column_width: - * @layout: a #ClutterFlowLayout - * @min_width: minimum width of a column - * @max_width: maximum width of a column - * - * Sets the minimum and maximum widths that a column can have - */ -void -clutter_flow_layout_set_column_width (ClutterFlowLayout *layout, - gfloat min_width, - gfloat max_width) -{ - gboolean notify_min = FALSE, notify_max = FALSE; - - g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout)); - - if (layout->min_col_width != min_width) - { - layout->min_col_width = min_width; - - notify_min = TRUE; - } - - if (layout->max_col_width != max_width) - { - layout->max_col_width = max_width; - - notify_max = TRUE; - } - - g_object_freeze_notify (G_OBJECT (layout)); - - if (notify_min || notify_max) - { - ClutterLayoutManager *manager = CLUTTER_LAYOUT_MANAGER (layout); - - clutter_layout_manager_layout_changed (manager); - } - - if (notify_min) - g_object_notify_by_pspec (G_OBJECT (layout), - flow_properties[PROP_MIN_COLUMN_WIDTH]); - - if (notify_max) - g_object_notify_by_pspec (G_OBJECT (layout), - flow_properties[PROP_MAX_COLUMN_WIDTH]); - - g_object_thaw_notify (G_OBJECT (layout)); -} - -/** - * clutter_flow_layout_get_column_width: - * @layout: a #ClutterFlowLayout - * @min_width: (out): return location for the minimum column width, or %NULL - * @max_width: (out): return location for the maximum column width, or %NULL - * - * Retrieves the minimum and maximum column widths - */ -void -clutter_flow_layout_get_column_width (ClutterFlowLayout *layout, - gfloat *min_width, - gfloat *max_width) -{ - g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout)); - - if (min_width) - *min_width = layout->min_col_width; - - if (max_width) - *max_width = layout->max_col_width; -} - -/** - * clutter_flow_layout_set_row_height: - * @layout: a #ClutterFlowLayout - * @min_height: the minimum height of a row - * @max_height: the maximum height of a row - * - * Sets the minimum and maximum heights that a row can have - */ -void -clutter_flow_layout_set_row_height (ClutterFlowLayout *layout, - gfloat min_height, - gfloat max_height) -{ - gboolean notify_min = FALSE, notify_max = FALSE; - - g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout)); - - if (layout->min_row_height != min_height) - { - layout->min_row_height = min_height; - - notify_min = TRUE; - } - - if (layout->max_row_height != max_height) - { - layout->max_row_height = max_height; - - notify_max = TRUE; - } - - g_object_freeze_notify (G_OBJECT (layout)); - - if (notify_min || notify_max) - { - ClutterLayoutManager *manager = CLUTTER_LAYOUT_MANAGER (layout); - - clutter_layout_manager_layout_changed (manager); - } - - if (notify_min) - g_object_notify_by_pspec (G_OBJECT (layout), - flow_properties[PROP_MIN_ROW_HEGHT]); - - if (notify_max) - g_object_notify_by_pspec (G_OBJECT (layout), - flow_properties[PROP_MAX_ROW_HEIGHT]); - - g_object_thaw_notify (G_OBJECT (layout)); -} - -/** - * clutter_flow_layout_get_row_height: - * @layout: a #ClutterFlowLayout - * @min_height: (out): return location for the minimum row height, or %NULL - * @max_height: (out): return location for the maximum row height, or %NULL - * - * Retrieves the minimum and maximum row heights - */ -void -clutter_flow_layout_get_row_height (ClutterFlowLayout *layout, - gfloat *min_height, - gfloat *max_height) -{ - g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout)); - - if (min_height) - *min_height = layout->min_row_height; - - if (max_height) - *max_height = layout->max_row_height; -} - -/** - * clutter_flow_layout_set_snap_to_grid: - * @layout: a #ClutterFlowLayout - * @snap_to_grid: %TRUE if @layout should place its children on a grid - * - * Whether the @layout should place its children on a grid. - */ -void -clutter_flow_layout_set_snap_to_grid (ClutterFlowLayout *layout, - gboolean snap_to_grid) -{ - g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout)); - - if (layout->snap_to_grid != snap_to_grid) - { - layout->snap_to_grid = snap_to_grid; - - clutter_layout_manager_layout_changed (CLUTTER_LAYOUT_MANAGER (layout)); - - g_object_notify_by_pspec (G_OBJECT (layout), - flow_properties[PROP_SNAP_TO_GRID]); - } -} - -/** - * clutter_flow_layout_get_snap_to_grid: - * @layout: a #ClutterFlowLayout - * - * Retrieves the value of #ClutterFlowLayout:snap-to-grid property - * - * Return value: %TRUE if the @layout is placing its children on a grid - */ -gboolean -clutter_flow_layout_get_snap_to_grid (ClutterFlowLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout), FALSE); - - return layout->snap_to_grid; -} diff --git a/mutter/clutter/clutter/clutter-flow-layout.h b/mutter/clutter/clutter/clutter-flow-layout.h deleted file mode 100644 index 22b6e62..0000000 --- a/mutter/clutter/clutter/clutter-flow-layout.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-layout-manager.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_FLOW_LAYOUT (clutter_flow_layout_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_FINAL_TYPE (ClutterFlowLayout, - clutter_flow_layout, - CLUTTER, FLOW_LAYOUT, - ClutterLayoutManager) - -CLUTTER_EXPORT -ClutterLayoutManager * clutter_flow_layout_new (ClutterOrientation orientation); - -CLUTTER_EXPORT -void clutter_flow_layout_set_orientation (ClutterFlowLayout *layout, - ClutterOrientation orientation); -CLUTTER_EXPORT -ClutterOrientation clutter_flow_layout_get_orientation (ClutterFlowLayout *layout); -CLUTTER_EXPORT -void clutter_flow_layout_set_homogeneous (ClutterFlowLayout *layout, - gboolean homogeneous); -CLUTTER_EXPORT -gboolean clutter_flow_layout_get_homogeneous (ClutterFlowLayout *layout); - -CLUTTER_EXPORT -void clutter_flow_layout_set_column_spacing (ClutterFlowLayout *layout, - gfloat spacing); -CLUTTER_EXPORT -gfloat clutter_flow_layout_get_column_spacing (ClutterFlowLayout *layout); -CLUTTER_EXPORT -void clutter_flow_layout_set_row_spacing (ClutterFlowLayout *layout, - gfloat spacing); -CLUTTER_EXPORT -gfloat clutter_flow_layout_get_row_spacing (ClutterFlowLayout *layout); - -CLUTTER_EXPORT -void clutter_flow_layout_set_column_width (ClutterFlowLayout *layout, - gfloat min_width, - gfloat max_width); -CLUTTER_EXPORT -void clutter_flow_layout_get_column_width (ClutterFlowLayout *layout, - gfloat *min_width, - gfloat *max_width); -CLUTTER_EXPORT -void clutter_flow_layout_set_row_height (ClutterFlowLayout *layout, - gfloat min_height, - gfloat max_height); -CLUTTER_EXPORT -void clutter_flow_layout_get_row_height (ClutterFlowLayout *layout, - gfloat *min_height, - gfloat *max_height); -CLUTTER_EXPORT -void clutter_flow_layout_set_snap_to_grid (ClutterFlowLayout *layout, - gboolean snap_to_grid); -CLUTTER_EXPORT -gboolean clutter_flow_layout_get_snap_to_grid (ClutterFlowLayout *layout); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-frame-clock.c b/mutter/clutter/clutter/clutter-frame-clock.c deleted file mode 100644 index 30a319f..0000000 --- a/mutter/clutter/clutter/clutter-frame-clock.c +++ /dev/null @@ -1,1255 +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 . - */ - -#include "config.h" - -#include "clutter/clutter-frame-clock.h" - -#include - -#ifdef HAVE_TIMERFD -#include -#include -#endif - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-frame-private.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]; - -#define SYNC_DELAY_FALLBACK_FRACTION 0.875 - -#define MINIMUM_REFRESH_RATE 30.f - -typedef struct _ClutterFrameListener -{ - const ClutterFrameListenerIface *iface; - gpointer user_data; -} ClutterFrameListener; - -typedef struct _ClutterClockSource -{ - GSource source; - - ClutterFrameClock *frame_clock; - -#ifdef HAVE_TIMERFD - int tfd; - struct itimerspec tfd_spec; -#endif -} ClutterClockSource; - -typedef enum _ClutterFrameClockState -{ - CLUTTER_FRAME_CLOCK_STATE_INIT, - CLUTTER_FRAME_CLOCK_STATE_IDLE, - CLUTTER_FRAME_CLOCK_STATE_SCHEDULED, - CLUTTER_FRAME_CLOCK_STATE_SCHEDULED_NOW, - CLUTTER_FRAME_CLOCK_STATE_DISPATCHING, - CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED, -} ClutterFrameClockState; - -struct _ClutterFrameClock -{ - GObject parent; - - float refresh_rate; - int64_t refresh_interval_us; - int64_t minimum_refresh_interval_us; - - ClutterFrameListener listener; - - GSource *source; - - int64_t frame_count; - - ClutterFrameClockState state; - ClutterFrameClockMode mode; - - int64_t last_dispatch_time_us; - int64_t last_dispatch_lateness_us; - int64_t last_presentation_time_us; - int64_t next_update_time_us; - - ClutterFrameInfoFlag last_presentation_flags; - - gboolean is_next_presentation_time_valid; - int64_t next_presentation_time_us; - - gboolean has_next_frame_deadline; - int64_t next_frame_deadline_us; - - gboolean has_last_next_presentation_time; - int64_t last_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 time we promoted short-term maximum to long-term one */ - int64_t longterm_promotion_us; - /* Long-term maximum update duration */ - int64_t longterm_max_update_duration_us; - /* Short-term maximum update duration */ - int64_t shortterm_max_update_duration_us; - - /* If we got new measurements last frame. */ - gboolean got_measurements_last_frame; - gboolean ever_got_measurements; - - gboolean pending_reschedule; - gboolean pending_reschedule_now; - - int inhibit_count; - - GList *timelines; - - int n_missed_frames; - int64_t missed_frame_report_time_us; - - int64_t last_dispatch_interval_us; - - char *output_name; -}; - -G_DEFINE_TYPE (ClutterFrameClock, clutter_frame_clock, - G_TYPE_OBJECT) - -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); - } - } -} - -static void -maybe_update_longterm_max_duration_us (ClutterFrameClock *frame_clock, - ClutterFrameInfo *frame_info) -{ - /* Do not update long-term max if there has been no measurement */ - if (!frame_clock->shortterm_max_update_duration_us) - return; - - if ((frame_info->presentation_time - frame_clock->longterm_promotion_us) < - G_USEC_PER_SEC) - return; - - if (frame_clock->longterm_max_update_duration_us > - frame_clock->shortterm_max_update_duration_us) - { - /* Exponential drop-off toward the short-term max */ - frame_clock->longterm_max_update_duration_us -= - (frame_clock->longterm_max_update_duration_us - - frame_clock->shortterm_max_update_duration_us) / 2; - } - else - { - frame_clock->longterm_max_update_duration_us = - frame_clock->shortterm_max_update_duration_us; - } - - frame_clock->shortterm_max_update_duration_us = 0; - frame_clock->longterm_promotion_us = frame_info->presentation_time; -} - -void -clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock, - ClutterFrameInfo *frame_info) -{ - COGL_TRACE_BEGIN_SCOPED (ClutterFrameClockNotifyPresented, - "Clutter::FrameClock::presented()"); - COGL_TRACE_DESCRIBE (ClutterFrameClockNotifyPresented, - frame_clock->output_name); - - frame_clock->last_next_presentation_time_us = - frame_clock->next_presentation_time_us; - frame_clock->has_last_next_presentation_time = - frame_clock->is_next_presentation_time_valid; - - if (G_UNLIKELY (CLUTTER_HAS_DEBUG (FRAME_CLOCK))) - { - int64_t now_us; - - if (frame_clock->has_last_next_presentation_time && - frame_info->presentation_time != 0) - { - int64_t diff_us; - int n_missed_frames; - - diff_us = llabs (frame_info->presentation_time - - frame_clock->last_next_presentation_time_us); - n_missed_frames = - (int) roundf ((float) diff_us / - (float) frame_clock->refresh_interval_us); - - frame_clock->n_missed_frames = n_missed_frames; - } - - now_us = g_get_monotonic_time (); - if ((now_us - frame_clock->missed_frame_report_time_us) > G_USEC_PER_SEC) - { - if (frame_clock->n_missed_frames > 0) - { - CLUTTER_NOTE (FRAME_CLOCK, "Missed %d frames the last second", - frame_clock->n_missed_frames); - } - frame_clock->n_missed_frames = 0; - frame_clock->missed_frame_report_time_us = now_us; - } - } - -#ifdef HAVE_PROFILER - if (G_UNLIKELY (cogl_is_tracing_enabled ())) - { - int64_t current_time_us; - g_autoptr (GString) description = NULL; - - current_time_us = g_get_monotonic_time (); - description = g_string_new (NULL); - - if (frame_info->presentation_time != 0) - { - if (frame_info->presentation_time <= current_time_us) - { - g_string_append_printf (description, - "presentation was %ld µs earlier", - current_time_us - frame_info->presentation_time); - } - else - { - g_string_append_printf (description, - "presentation will be %ld µs later", - frame_info->presentation_time - current_time_us); - } - } - - if (frame_info->gpu_rendering_duration_ns != 0) - { - if (description->len > 0) - g_string_append (description, ", "); - - g_string_append_printf (description, - "buffer swap to GPU done: %ld µs", - ns2us (frame_info->gpu_rendering_duration_ns)); - } - - COGL_TRACE_DESCRIBE (ClutterFrameClockNotifyPresented, description->str); - } -#endif - - if (frame_info->presentation_time > 0) - { - frame_clock->last_presentation_time_us = frame_info->presentation_time; - frame_clock->last_presentation_flags = frame_info->flags; - } - - frame_clock->got_measurements_last_frame = FALSE; - - if (frame_info->cpu_time_before_buffer_swap_us != 0 && - frame_info->has_valid_gpu_rendering_duration) - { - 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, - "update2dispatch %ld µs, dispatch2swap %ld µs, swap2render %ld µs, swap2flip %ld µs", - frame_clock->last_dispatch_lateness_us, - dispatch_to_swap_us, - swap_to_rendering_done_us, - swap_to_flip_us); - - frame_clock->shortterm_max_update_duration_us = - CLAMP (frame_clock->last_dispatch_lateness_us + dispatch_to_swap_us + - MAX (swap_to_rendering_done_us, swap_to_flip_us), - frame_clock->shortterm_max_update_duration_us, - frame_clock->refresh_interval_us); - - maybe_update_longterm_max_duration_us (frame_clock, frame_info); - - frame_clock->got_measurements_last_frame = TRUE; - frame_clock->ever_got_measurements = TRUE; - } - else - { - CLUTTER_NOTE (FRAME_TIMINGS, "update2dispatch %ld µs", - frame_clock->last_dispatch_lateness_us); - } - - if (frame_info->refresh_rate > 1.0) - { - 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: - case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED_NOW: - 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) -{ - COGL_TRACE_BEGIN_SCOPED (ClutterFrameClockNotifyReady, "Clutter::FrameClock::ready()"); - COGL_TRACE_DESCRIBE (ClutterFrameClockNotifyReady, frame_clock->output_name); - - switch (frame_clock->state) - { - case CLUTTER_FRAME_CLOCK_STATE_INIT: - case CLUTTER_FRAME_CLOCK_STATE_IDLE: - case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED: - case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED_NOW: - 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_render_time_us; - - refresh_interval_us = frame_clock->refresh_interval_us; - - if (!frame_clock->ever_got_measurements || - G_UNLIKELY (clutter_paint_debug_flags & - CLUTTER_DEBUG_DISABLE_DYNAMIC_MAX_RENDER_TIME)) - return refresh_interval_us * SYNC_DELAY_FALLBACK_FRACTION; - - /* Max render time shows how early the frame clock needs to be dispatched - * to make it to the predicted next presentation time. It is an estimate of - * the total update duration, which is composed of: - * - Dispatch start lateness. - * - The duration from dispatch start to buffer swap. - * - The maximum 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. - * - The duration of vertical blank. - * - A constant to account for variations in the above estimates. - */ - max_render_time_us = - MAX (frame_clock->longterm_max_update_duration_us, - frame_clock->shortterm_max_update_duration_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 *out_next_frame_deadline_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 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; - *out_next_frame_deadline_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 current_phase_us; - - /* - * Let's say we're just past next_presentation_time_us. - * - * First, we calculate current_phase_us, corresponding to the time since - * the last integer multiple of the refresh interval passed after the last - * presentation time. Subtracting this phase from now_us and adding a - * refresh interval gets us the next possible presentation time after - * now_us. - * - * last_presentation_time_us - * / next_presentation_time_us - * / / now_us - * / / / new next_presentation_time_us - * |-------|---o---|-------|--> possible presentation times - * \_/ \_____/ - * / \ - * current_phase_us refresh_interval_us - */ - - current_phase_us = (now_us - last_presentation_time_us) % refresh_interval_us; - next_presentation_time_us = now_us - current_phase_us + refresh_interval_us; - } - - if (frame_clock->has_last_next_presentation_time) - { - int64_t time_since_last_next_presentation_time_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 - * - */ - time_since_last_next_presentation_time_us = - next_presentation_time_us - frame_clock->last_next_presentation_time_us; - if (time_since_last_next_presentation_time_us > 0 && - time_since_last_next_presentation_time_us < (refresh_interval_us / 2)) - { - next_presentation_time_us = - frame_clock->next_presentation_time_us + refresh_interval_us; - } - } - - if (frame_clock->last_presentation_flags & CLUTTER_FRAME_INFO_FLAG_VSYNC && - next_presentation_time_us != last_presentation_time_us + refresh_interval_us) - { - /* There was an idle period since the last presentation, so there seems - * be no constantly updating actor. In this case it's best to start - * working on the next update ASAP, this results in lowest average latency - * for sporadic user input. - */ - next_update_time_us = now_us; - min_render_time_allowed_us = 0; - } - else - { - while (next_presentation_time_us - min_render_time_allowed_us < now_us) - next_presentation_time_us += refresh_interval_us; - - next_update_time_us = next_presentation_time_us - max_render_time_allowed_us; - if (next_update_time_us < now_us) - next_update_time_us = now_us; - } - - *out_next_update_time_us = next_update_time_us; - *out_next_presentation_time_us = next_presentation_time_us; - *out_next_frame_deadline_us = next_presentation_time_us - min_render_time_allowed_us; -} - -static void -calculate_next_variable_update_time_us (ClutterFrameClock *frame_clock, - int64_t *out_next_update_time_us, - int64_t *out_next_presentation_time_us, - int64_t *out_next_frame_deadline_us) -{ - int64_t last_presentation_time_us; - int64_t now_us; - int64_t refresh_interval_us; - int64_t max_render_time_allowed_us; - int64_t next_presentation_time_us; - int64_t next_update_time_us; - int64_t next_frame_deadline_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; - *out_next_frame_deadline_us = 0; - return; - } - - max_render_time_allowed_us = - clutter_frame_clock_compute_max_render_time_us (frame_clock); - - last_presentation_time_us = frame_clock->last_presentation_time_us; - next_presentation_time_us = last_presentation_time_us + refresh_interval_us; - - next_update_time_us = next_presentation_time_us - max_render_time_allowed_us; - if (next_update_time_us < now_us) - next_update_time_us = now_us; - - if (next_presentation_time_us < next_update_time_us) - next_presentation_time_us = 0; - - next_frame_deadline_us = next_update_time_us; - if (next_frame_deadline_us == now_us) - next_frame_deadline_us += refresh_interval_us; - - *out_next_update_time_us = next_update_time_us; - *out_next_presentation_time_us = next_presentation_time_us; - *out_next_frame_deadline_us = next_frame_deadline_us; -} - -static void -calculate_next_variable_update_timeout_us (ClutterFrameClock *frame_clock, - int64_t *out_next_update_time_us) -{ - int64_t now_us; - int64_t last_presentation_time_us; - int64_t next_presentation_time_us; - int64_t timeout_interval_us; - - now_us = g_get_monotonic_time (); - - last_presentation_time_us = frame_clock->last_presentation_time_us; - - timeout_interval_us = frame_clock->minimum_refresh_interval_us; - - if (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) + timeout_interval_us) : - now_us; - return; - } - - next_presentation_time_us = last_presentation_time_us + timeout_interval_us; - - while (next_presentation_time_us < now_us) - next_presentation_time_us += timeout_interval_us; - - *out_next_update_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_SCHEDULED_NOW: - frame_clock->pending_reschedule = TRUE; - frame_clock->pending_reschedule_now = 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: - case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED: - break; - case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED_NOW: - 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; - } - - switch (frame_clock->mode) - { - case CLUTTER_FRAME_CLOCK_MODE_FIXED: - next_update_time_us = g_get_monotonic_time (); - frame_clock->is_next_presentation_time_valid = FALSE; - frame_clock->has_next_frame_deadline = FALSE; - break; - case CLUTTER_FRAME_CLOCK_MODE_VARIABLE: - calculate_next_variable_update_time_us (frame_clock, - &next_update_time_us, - &frame_clock->next_presentation_time_us, - &frame_clock->next_frame_deadline_us); - frame_clock->is_next_presentation_time_valid = - (frame_clock->next_presentation_time_us != 0); - frame_clock->has_next_frame_deadline = - (frame_clock->next_frame_deadline_us != 0); - break; - } - - g_warn_if_fail (next_update_time_us != -1); - - frame_clock->next_update_time_us = next_update_time_us; - g_source_set_ready_time (frame_clock->source, next_update_time_us); - frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_SCHEDULED_NOW; -} - -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 (); - g_source_set_ready_time (frame_clock->source, next_update_time_us); - frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_SCHEDULED; - return; - case CLUTTER_FRAME_CLOCK_STATE_IDLE: - break; - case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED: - case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED_NOW: - return; - case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING: - case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED: - frame_clock->pending_reschedule = TRUE; - return; - } - - switch (frame_clock->mode) - { - case CLUTTER_FRAME_CLOCK_MODE_FIXED: - calculate_next_update_time_us (frame_clock, - &next_update_time_us, - &frame_clock->next_presentation_time_us, - &frame_clock->next_frame_deadline_us); - frame_clock->is_next_presentation_time_valid = - (frame_clock->next_presentation_time_us != 0); - frame_clock->has_next_frame_deadline = - (frame_clock->next_frame_deadline_us != 0); - break; - case CLUTTER_FRAME_CLOCK_MODE_VARIABLE: - calculate_next_variable_update_timeout_us (frame_clock, - &next_update_time_us); - frame_clock->is_next_presentation_time_valid = FALSE; - frame_clock->has_next_frame_deadline = FALSE; - break; - } - - g_warn_if_fail (next_update_time_us != -1); - - frame_clock->next_update_time_us = next_update_time_us; - g_source_set_ready_time (frame_clock->source, next_update_time_us); - frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_SCHEDULED; -} - -void -clutter_frame_clock_set_mode (ClutterFrameClock *frame_clock, - ClutterFrameClockMode mode) -{ - if (frame_clock->mode == mode) - return; - - frame_clock->mode = mode; - - 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_SCHEDULED_NOW: - frame_clock->pending_reschedule = TRUE; - frame_clock->pending_reschedule_now = TRUE; - frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE; - break; - case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING: - case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED: - break; - } - - maybe_reschedule_update (frame_clock); -} - -static void -clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock, - int64_t time_us) -{ - const ClutterFrameListenerIface *iface = frame_clock->listener.iface; - g_autoptr (ClutterFrame) frame = NULL; - int64_t frame_count; - ClutterFrameResult result; - int64_t ideal_dispatch_time_us, lateness_us; - -#ifdef HAVE_PROFILER - int64_t this_dispatch_ready_time_us; - int64_t this_dispatch_time_us; - - COGL_TRACE_BEGIN_SCOPED (ClutterFrameClockDispatch, "Clutter::FrameClock::dispatch()"); - COGL_TRACE_DESCRIBE (ClutterFrameClockDispatch, frame_clock->output_name); - - this_dispatch_ready_time_us = g_source_get_ready_time (frame_clock->source); - this_dispatch_time_us = time_us; -#endif - - ideal_dispatch_time_us = frame_clock->next_update_time_us; - - if (ideal_dispatch_time_us <= 0) - 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; - -#ifdef CLUTTER_ENABLE_DEBUG - if (G_UNLIKELY (CLUTTER_HAS_DEBUG (FRAME_TIMINGS))) - { - int64_t dispatch_interval_us, jitter_us; - - dispatch_interval_us = time_us - frame_clock->last_dispatch_time_us; - jitter_us = llabs (dispatch_interval_us - - frame_clock->last_dispatch_interval_us) % - frame_clock->refresh_interval_us; - frame_clock->last_dispatch_interval_us = dispatch_interval_us; - CLUTTER_NOTE (FRAME_TIMINGS, "dispatch jitter %5ldµs (%3ld%%)", - jitter_us, - jitter_us * 100 / frame_clock->refresh_interval_us); - } -#endif - - 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++; - - if (iface->new_frame) - frame = iface->new_frame (frame_clock, frame_clock->listener.user_data); - if (!frame) - frame = clutter_frame_new (ClutterFrame, NULL); - - frame->frame_count = frame_count; - frame->has_target_presentation_time = frame_clock->is_next_presentation_time_valid; - frame->target_presentation_time_us = frame_clock->next_presentation_time_us; - - frame->has_frame_deadline = frame_clock->has_next_frame_deadline; - frame->frame_deadline_us = frame_clock->next_frame_deadline_us; - - COGL_TRACE_BEGIN_SCOPED (ClutterFrameClockEvents, "Clutter::FrameListener::before_frame()"); - if (iface->before_frame) - iface->before_frame (frame_clock, frame, frame_clock->listener.user_data); - COGL_TRACE_END (ClutterFrameClockEvents); - - COGL_TRACE_BEGIN_SCOPED (ClutterFrameClockTimelines, "Clutter::FrameClock::advance_timelines()"); - if (frame_clock->is_next_presentation_time_valid) - time_us = frame_clock->next_presentation_time_us; - advance_timelines (frame_clock, time_us); - COGL_TRACE_END (ClutterFrameClockTimelines); - - COGL_TRACE_BEGIN_SCOPED (ClutterFrameClockFrame, "Clutter::FrameListener::frame()"); - result = iface->frame (frame_clock, frame, 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: - case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED_NOW: - 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; - } - -#ifdef HAVE_PROFILER - if (this_dispatch_ready_time_us != -1 && - G_UNLIKELY (cogl_is_tracing_enabled ())) - { - g_autofree char *description = NULL; - description = g_strdup_printf ("dispatched %ld µs late", - this_dispatch_time_us - this_dispatch_ready_time_us); - COGL_TRACE_DESCRIBE (ClutterFrameClockDispatch, description); - } -#endif -} - -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_update_duration_us; - 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)"); - - max_update_duration_us = - MAX (frame_clock->longterm_max_update_duration_us, - frame_clock->shortterm_max_update_duration_us); - - g_string_append_printf (string, "\nVblank duration: %ld µs +", - frame_clock->vblank_duration_us); - g_string_append_printf (string, "\nUpdate duration: %ld µs +", - max_update_duration_us); - g_string_append_printf (string, "\nConstant: %d µs", - clutter_max_render_time_constant_us); - - return string; -} - -static gboolean -frame_clock_source_prepare (GSource *source, - int *timeout) -{ - G_GNUC_UNUSED ClutterClockSource *clock_source = (ClutterClockSource *)source; - - *timeout = -1; - -#ifdef HAVE_TIMERFD - /* The cycle for GMainContext is: - * - * - prepare(): where we update our timerfd deadline - * - poll(): internal to GMainContext/GPollFunc - * - check(): where GLib will check POLLIN and make ready - * - dispatch(): where we actually process the pending work - * - * If we have a ready_time >= 0 then we need to set our deadline - * in nanoseconds for the timerfd. The timerfd will receive POLLIN - * after that point and poll() will return. - * - * If we have a ready_time of -1, then we need to disable our - * timerfd by setting tv_sec and tv_nsec to 0. - * - * In both cases, the POLLIN bit will be reset. - */ - if (clock_source->tfd > -1) - { - int64_t ready_time = g_source_get_ready_time (source); - struct itimerspec tfd_spec; - - tfd_spec.it_interval.tv_sec = 0; - tfd_spec.it_interval.tv_nsec = 0; - - if (ready_time > -1) - { - tfd_spec.it_value.tv_sec = ready_time / G_USEC_PER_SEC; - tfd_spec.it_value.tv_nsec = (ready_time % G_USEC_PER_SEC) * 1000L; - } - else - { - tfd_spec.it_value.tv_sec = 0; - tfd_spec.it_value.tv_nsec = 0; - } - - /* Avoid extraneous calls timerfd_settime() */ - if (memcmp (&tfd_spec, &clock_source->tfd_spec, sizeof tfd_spec) != 0) - { - clock_source->tfd_spec = tfd_spec; - - timerfd_settime (clock_source->tfd, - TFD_TIMER_ABSTIME, - &clock_source->tfd_spec, - NULL); - } - } -#endif - - return FALSE; -} - -static void -frame_clock_source_finalize (GSource *source) -{ -#ifdef HAVE_TIMERFD - ClutterClockSource *clock_source = (ClutterClockSource *)source; - - g_clear_fd (&clock_source->tfd, NULL); -#endif -} - -static GSourceFuncs frame_clock_source_funcs = { - frame_clock_source_prepare, - NULL, - frame_clock_source_dispatch, - frame_clock_source_finalize, -}; - -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; - -#ifdef HAVE_TIMERFD - clock_source->tfd = timerfd_create (CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); - - if (clock_source->tfd > -1) - g_source_add_unix_fd (source, clock_source->tfd, G_IO_IN); -#endif - - name = g_strdup_printf ("[mutter] 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 char *output_name, - 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->minimum_refresh_interval_us = - (int64_t) (0.5 + G_USEC_PER_SEC / MINIMUM_REFRESH_RATE); - - frame_clock->vblank_duration_us = vblank_duration_us; - - frame_clock->output_name = g_strdup (output_name); - - 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); - - g_warn_if_fail (frame_clock->state != CLUTTER_FRAME_CLOCK_STATE_DISPATCHING); - - 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_clear_pointer (&frame_clock->output_name, g_free); - - 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; - frame_clock->mode = CLUTTER_FRAME_CLOCK_MODE_FIXED; -} - -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); -} diff --git a/mutter/clutter/clutter/clutter-frame-clock.h b/mutter/clutter/clutter/clutter-frame-clock.h deleted file mode 100644 index a7be5ef..0000000 --- a/mutter/clutter/clutter/clutter-frame-clock.h +++ /dev/null @@ -1,108 +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 . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include -#include -#include - -#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, - ClutterFrame *frame, - gpointer user_data); - ClutterFrameResult (* frame) (ClutterFrameClock *frame_clock, - ClutterFrame *frame, - gpointer user_data); - ClutterFrame * (* new_frame) (ClutterFrameClock *frame_clock, - gpointer user_data); -} ClutterFrameListenerIface; - -typedef enum _ClutterFrameClockMode -{ - CLUTTER_FRAME_CLOCK_MODE_FIXED, - CLUTTER_FRAME_CLOCK_MODE_VARIABLE, -} ClutterFrameClockMode; - -CLUTTER_EXPORT -ClutterFrameClock * clutter_frame_clock_new (float refresh_rate, - int64_t vblank_duration_us, - const char *name, - const ClutterFrameListenerIface *iface, - gpointer user_data); - -CLUTTER_EXPORT -void clutter_frame_clock_destroy (ClutterFrameClock *frame_clock); - -CLUTTER_EXPORT -void clutter_frame_clock_set_mode (ClutterFrameClock *frame_clock, - ClutterFrameClockMode mode); - -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); diff --git a/mutter/clutter/clutter/clutter-frame-private.h b/mutter/clutter/clutter/clutter-frame-private.h deleted file mode 100644 index ef66b87..0000000 --- a/mutter/clutter/clutter/clutter-frame-private.h +++ /dev/null @@ -1,49 +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 . - */ - -#pragma once - -#include "clutter/clutter-frame.h" - -typedef void (* ClutterFrameRelease) (ClutterFrame *frame); - -struct _ClutterFrame -{ - grefcount ref_count; - ClutterFrameRelease release; - - int64_t frame_count; - - gboolean has_target_presentation_time; - int64_t target_presentation_time_us; - - gboolean has_frame_deadline; - int64_t frame_deadline_us; - - gboolean has_result; - ClutterFrameResult result; -}; - -CLUTTER_EXPORT -gpointer clutter_frame_new (size_t size, - ClutterFrameRelease release); - -#define clutter_frame_new(FrameType, release) \ - ((FrameType *) (clutter_frame_new (sizeof (FrameType), release))) - -CLUTTER_EXPORT -ClutterFrameResult clutter_frame_get_result (ClutterFrame *frame); diff --git a/mutter/clutter/clutter/clutter-frame.c b/mutter/clutter/clutter/clutter-frame.c deleted file mode 100644 index 7436f9f..0000000 --- a/mutter/clutter/clutter/clutter-frame.c +++ /dev/null @@ -1,117 +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 . - */ - -#include "config.h" - -#include "clutter/clutter-frame-private.h" - -G_DEFINE_BOXED_TYPE (ClutterFrame, clutter_frame, - clutter_frame_ref, - clutter_frame_unref) - -ClutterFrame * -clutter_frame_ref (ClutterFrame *frame) -{ - g_ref_count_inc (&frame->ref_count); - return frame; -} - -void -clutter_frame_unref (ClutterFrame *frame) -{ - if (g_ref_count_dec (&frame->ref_count)) - { - if (frame->release) - frame->release (frame); - g_free (frame); - } -} - -gpointer -(clutter_frame_new) (size_t size, - ClutterFrameRelease release) -{ - ClutterFrame *frame; - - g_assert (size >= sizeof (ClutterFrame)); - - frame = g_malloc0 (size); - g_ref_count_init (&frame->ref_count); - frame->release = release; - - return frame; -} - -int64_t -clutter_frame_get_count (ClutterFrame *frame) -{ - return frame->frame_count; -} - -gboolean -clutter_frame_get_target_presentation_time (ClutterFrame *frame, - int64_t *target_presentation_time_us) -{ - if (frame->has_target_presentation_time) - { - *target_presentation_time_us = frame->target_presentation_time_us; - return TRUE; - } - else - { - return FALSE; - } -} - -gboolean -clutter_frame_get_frame_deadline (ClutterFrame *frame, - int64_t *frame_deadline_us) -{ - if (frame->has_frame_deadline) - { - *frame_deadline_us = frame->frame_deadline_us; - return TRUE; - } - else - { - return FALSE; - } -} - -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; -} diff --git a/mutter/clutter/clutter/clutter-frame.h b/mutter/clutter/clutter/clutter-frame.h deleted file mode 100644 index 34f0770..0000000 --- a/mutter/clutter/clutter/clutter-frame.h +++ /dev/null @@ -1,57 +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 . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-frame-clock.h" - -typedef struct _ClutterFrame ClutterFrame; - -#define CLUTTER_TYPE_FRAME (clutter_frame_get_type ()) - -CLUTTER_EXPORT -GType clutter_frame_get_type (void); - -CLUTTER_EXPORT -ClutterFrame * clutter_frame_ref (ClutterFrame *frame); - -CLUTTER_EXPORT -void clutter_frame_unref (ClutterFrame *frame); - -CLUTTER_EXPORT -int64_t clutter_frame_get_count (ClutterFrame *frame); - -CLUTTER_EXPORT -gboolean clutter_frame_get_target_presentation_time (ClutterFrame *frame, - int64_t *target_presentation_time_us); - -CLUTTER_EXPORT -gboolean clutter_frame_get_frame_deadline (ClutterFrame *frame, - int64_t *frame_deadline_us); - -CLUTTER_EXPORT -void clutter_frame_set_result (ClutterFrame *frame, - ClutterFrameResult result); - -CLUTTER_EXPORT -gboolean clutter_frame_has_result (ClutterFrame *frame); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFrame, clutter_frame_unref) diff --git a/mutter/clutter/clutter/clutter-gesture-action.c b/mutter/clutter/clutter/clutter-gesture-action.c deleted file mode 100644 index e9c083b..0000000 --- a/mutter/clutter/clutter/clutter-gesture-action.c +++ /dev/null @@ -1,1357 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * Copyright (C) 2011 Robert Bosch Car Multimedia GmbH. - * Copyright (C) 2012 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Tomeu Vizoso - */ - -/** - * ClutterGestureAction: - * - * Action for gesture gestures - * - * #ClutterGestureAction is a sub-class of [class@Action] that implements - * the logic for recognizing gesture gestures. It listens for low level - * [struct@Event] events on the stage to raise - * the [signal@GestureAction::gesture-begin], [signal@GestureAction::gesture-progress], - * and [signal@GestureAction::gesture-end] signals. - * - * To use #ClutterGestureAction you just need to apply it to a [class@Actor] - * using [method@Actor.add_action] and connect to the signals: - * - * ```c - * ClutterAction *action = clutter_gesture_action_new (); - * - * clutter_actor_add_action (actor, action); - * - * g_signal_connect (action, "gesture-begin", G_CALLBACK (on_gesture_begin), NULL); - * g_signal_connect (action, "gesture-progress", G_CALLBACK (on_gesture_progress), NULL); - * g_signal_connect (action, "gesture-end", G_CALLBACK (on_gesture_end), NULL); - * ``` - * - * ## Creating Gesture actions - * - * A #ClutterGestureAction provides four separate states that can be - * used to recognize or ignore gestures when writing a new action class: - * - * - Prepare -> Cancel - * - Prepare -> Begin -> Cancel - * - Prepare -> Begin -> End - * - Prepare -> Begin -> Progress -> Cancel - * - Prepare -> Begin -> Progress -> End - * - * Each #ClutterGestureAction starts in the "prepare" state, and calls - * the [vfunc@GestureAction.gesture_prepare] virtual function; this - * state can be used to reset the internal state of a #ClutterGestureAction - * subclass, but it can also immediately cancel a gesture without going - * through the rest of the states. - * - * The "begin" state follows the "prepare" state, and calls the - * [vfunc@GestureAction.gesture_begin] virtual function. This state - * signals the start of a gesture recognizing process. From the "begin" state - * the gesture recognition process can successfully end, by going to the - * "end" state; it can continue in the "progress" state, in case of a - * continuous gesture; or it can be terminated, by moving to the "cancel" - * state. - * - * In case of continuous gestures, the #ClutterGestureAction will use - * the "progress" state, calling the [vfunc@GestureAction.gesture_progress] - * virtual function; the "progress" state will continue until the end of the - * gesture, in which case the "end" state will be reached, or until the - * gesture is cancelled, in which case the "cancel" gesture will be used - * instead. - */ - -#include "config.h" - - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-gesture-action.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-private.h" - -#include - -#define MAX_GESTURE_POINTS (10) -#define FLOAT_EPSILON (1e-15) - -typedef struct -{ - ClutterInputDevice *device; - ClutterEventSequence *sequence; - ClutterEvent *last_event; - - gfloat press_x, press_y; - gint64 last_motion_time; - gfloat last_motion_x, last_motion_y; - gint64 last_delta_time; - gfloat last_delta_x, last_delta_y; - gfloat release_x, release_y; -} GesturePoint; - -struct _ClutterGestureActionPrivate -{ - ClutterActor *stage; - - gint requested_nb_points; - GArray *points; - - ClutterGestureTriggerEdge edge; - float distance_x, distance_y; - - guint in_gesture : 1; -}; - -enum -{ - PROP_0, - - PROP_N_TOUCH_POINTS, - PROP_THRESHOLD_TRIGGER_EDGE, - PROP_THRESHOLD_TRIGGER_DISTANCE_X, - PROP_THRESHOLD_TRIGGER_DISTANCE_Y, - - PROP_LAST -}; - -enum -{ - GESTURE_BEGIN, - GESTURE_PROGRESS, - GESTURE_END, - GESTURE_CANCEL, - - LAST_SIGNAL -}; - -static GParamSpec *gesture_props[PROP_LAST]; -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) -{ - ClutterGestureActionPrivate *priv = - clutter_gesture_action_get_instance_private (action); - GesturePoint *point = NULL; - - if (priv->points->len >= MAX_GESTURE_POINTS) - return NULL; - - g_array_set_size (priv->points, priv->points->len + 1); - point = &g_array_index (priv->points, GesturePoint, priv->points->len - 1); - - point->last_event = clutter_event_copy (event); - point->device = clutter_event_get_device (event); - - clutter_event_get_coords (event, &point->press_x, &point->press_y); - point->last_motion_x = point->press_x; - point->last_motion_y = point->press_y; - point->last_motion_time = clutter_event_get_time (event); - - point->last_delta_x = point->last_delta_y = 0; - point->last_delta_time = 0; - - if (clutter_event_type (event) != CLUTTER_BUTTON_PRESS) - point->sequence = clutter_event_get_event_sequence (event); - else - point->sequence = NULL; - - return point; -} - -static GesturePoint * -gesture_find_point (ClutterGestureAction *action, - const ClutterEvent *event, - int *position) -{ - ClutterGestureActionPrivate *priv = - clutter_gesture_action_get_instance_private (action); - GesturePoint *point = NULL; - ClutterEventType type = clutter_event_type (event); - ClutterInputDevice *device = clutter_event_get_device (event); - ClutterEventSequence *sequence = NULL; - gint i; - - if ((type != CLUTTER_BUTTON_PRESS) && - (type != CLUTTER_BUTTON_RELEASE) && - (type != CLUTTER_MOTION)) - sequence = clutter_event_get_event_sequence (event); - - for (i = 0; i < priv->points->len; i++) - { - if ((g_array_index (priv->points, GesturePoint, i).device == device) && - (g_array_index (priv->points, GesturePoint, i).sequence == sequence)) - { - if (position != NULL) - *position = i; - point = &g_array_index (priv->points, GesturePoint, i); - break; - } - } - - return point; -} - -static void -gesture_unregister_point (ClutterGestureAction *action, gint position) -{ - ClutterGestureActionPrivate *priv = - clutter_gesture_action_get_instance_private (action); - - if (priv->points->len == 0) - return; - - g_array_remove_index (priv->points, position); -} - -static void -gesture_update_motion_point (GesturePoint *point, - const ClutterEvent *event) -{ - gfloat motion_x, motion_y; - gint64 _time; - - clutter_event_get_coords (event, &motion_x, &motion_y); - - clutter_event_free (point->last_event); - point->last_event = clutter_event_copy (event); - - point->last_delta_x = motion_x - point->last_motion_x; - point->last_delta_y = motion_y - point->last_motion_y; - point->last_motion_x = motion_x; - point->last_motion_y = motion_y; - - _time = clutter_event_get_time (event); - point->last_delta_time = _time - point->last_motion_time; - point->last_motion_time = _time; -} - -static void -gesture_update_release_point (GesturePoint *point, - const ClutterEvent *event) -{ - gint64 _time; - - clutter_event_get_coords (event, &point->release_x, &point->release_y); - - clutter_event_free (point->last_event); - point->last_event = clutter_event_copy (event); - - /* Treat the release event as the continuation of the last motion, - * in case the user keeps the pointer still for a while before - * releasing it. */ - _time = clutter_event_get_time (event); - point->last_delta_time += _time - point->last_motion_time; -} - -static gint -gesture_get_default_threshold (void) -{ - gint threshold; - ClutterSettings *settings = clutter_settings_get_default (); - g_object_get (settings, "dnd-drag-threshold", &threshold, NULL); - return threshold; -} - -static gboolean -gesture_point_pass_threshold (ClutterGestureAction *action, - GesturePoint *point, - const ClutterEvent *event) -{ - float threshold_x, threshold_y; - gfloat motion_x, motion_y; - - clutter_event_get_coords (event, &motion_x, &motion_y); - clutter_gesture_action_get_threshold_trigger_distance (action, &threshold_x, &threshold_y); - - if ((fabsf (point->press_y - motion_y) < threshold_y) && - (fabsf (point->press_x - motion_x) < threshold_x)) - return TRUE; - return FALSE; -} - -static void -gesture_point_unset (GesturePoint *point) -{ - clutter_event_free (point->last_event); -} - -static void -cancel_gesture (ClutterGestureAction *action) -{ - ClutterGestureActionPrivate *priv = - clutter_gesture_action_get_instance_private (action); - ClutterActor *actor; - - priv->in_gesture = FALSE; - - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); - g_signal_emit (action, gesture_signals[GESTURE_CANCEL], 0, actor); - - g_array_set_size (priv->points, 0); -} - -static gboolean -begin_gesture (ClutterGestureAction *action, - ClutterActor *actor) -{ - ClutterGestureActionPrivate *priv = - clutter_gesture_action_get_instance_private (action); - gboolean return_value; - - priv->in_gesture = TRUE; - - if (!CLUTTER_GESTURE_ACTION_GET_CLASS (action)->gesture_prepare (action, actor)) - { - cancel_gesture (action); - return FALSE; - } - - /* clutter_gesture_action_cancel() may have been called during - * gesture_prepare(), check that the gesture is still active. */ - if (!priv->in_gesture) - return FALSE; - - g_signal_emit (action, gesture_signals[GESTURE_BEGIN], 0, actor, - &return_value); - - if (!return_value) - { - cancel_gesture (action); - return FALSE; - } - - return TRUE; -} - -static gboolean -clutter_gesture_action_handle_event (ClutterAction *action, - const ClutterEvent *event) -{ - 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)); - 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))) - return CLUTTER_EVENT_PROPAGATE; - - event_type = clutter_event_type (event); - - 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; - } - - switch (clutter_event_type (event)) - { - case CLUTTER_ENTER: - case CLUTTER_LEAVE: - return CLUTTER_EVENT_PROPAGATE; - - 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); - - /* we might miss a button-release event in case of grabs, - * so we need to check whether the button is still down - * during a motion event - */ - if (!(mods & CLUTTER_BUTTON1_MASK)) - { - cancel_gesture (gesture_action); - return CLUTTER_EVENT_PROPAGATE; - } - } - G_GNUC_FALLTHROUGH; - - case CLUTTER_TOUCH_UPDATE: - if (!priv->in_gesture) - { - if (priv->points->len < priv->requested_nb_points) - { - gesture_update_motion_point (point, event); - return CLUTTER_EVENT_PROPAGATE; - } - - /* 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_update_motion_point (point, event); - return CLUTTER_EVENT_PROPAGATE; - } - - gesture_update_motion_point (point, event); - - if (!begin_gesture (gesture_action, actor)) - return CLUTTER_EVENT_PROPAGATE; - - if ((point = gesture_find_point (gesture_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, - &return_value); - if (!return_value) - { - cancel_gesture (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); - 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); - return CLUTTER_EVENT_PROPAGATE; - } - break; - - case CLUTTER_BUTTON_RELEASE: - case CLUTTER_TOUCH_END: - { - gesture_update_release_point (point, event); - - if (priv->in_gesture && - ((priv->points->len - 1) < priv->requested_nb_points)) - { - priv->in_gesture = FALSE; - g_signal_emit (gesture_action, gesture_signals[GESTURE_END], 0, actor); - } - - gesture_unregister_point (gesture_action, position); - } - break; - - case CLUTTER_TOUCH_CANCEL: - { - gesture_update_release_point (point, event); - - if (priv->in_gesture) - { - priv->in_gesture = FALSE; - cancel_gesture (gesture_action); - } - - gesture_unregister_point (gesture_action, position); - } - break; - - default: - break; - } - - return priv->in_gesture ? - CLUTTER_EVENT_STOP : - CLUTTER_EVENT_PROPAGATE; -} - -static void -clutter_gesture_action_sequence_cancelled (ClutterAction *action, - ClutterInputDevice *device, - ClutterEventSequence *sequence) -{ - ClutterGestureAction *self = CLUTTER_GESTURE_ACTION (action); - ClutterGestureActionPrivate *priv = - clutter_gesture_action_get_instance_private (self); - int i, position = -1; - - for (i = 0; i < priv->points->len; i++) - { - if ((g_array_index (priv->points, GesturePoint, i).device == device) && - (g_array_index (priv->points, GesturePoint, i).sequence == sequence)) - { - position = i; - break; - } - } - - if (position == -1) - return; - - if (priv->in_gesture) - { - priv->in_gesture = FALSE; - cancel_gesture (self); - } - - gesture_unregister_point (self, position); -} - -static void -clutter_gesture_action_set_enabled (ClutterActorMeta *meta, - gboolean is_enabled) -{ - ClutterActorMetaClass *meta_class = - CLUTTER_ACTOR_META_CLASS (clutter_gesture_action_parent_class); - ClutterGestureAction *gesture_action = CLUTTER_GESTURE_ACTION (meta); - ClutterGestureActionPrivate *priv = - clutter_gesture_action_get_instance_private (gesture_action); - - if (!is_enabled) - { - if (priv->in_gesture) - cancel_gesture (gesture_action); - else - g_array_set_size (priv->points, 0); - } - - meta_class->set_enabled (meta, is_enabled); -} - -static gboolean -default_event_handler (ClutterGestureAction *action, - ClutterActor *actor) -{ - return TRUE; -} - -static void -clutter_gesture_action_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterGestureAction *self = CLUTTER_GESTURE_ACTION (gobject); - ClutterGestureActionPrivate *priv = - clutter_gesture_action_get_instance_private (self); - - switch (prop_id) - { - case PROP_N_TOUCH_POINTS: - clutter_gesture_action_set_n_touch_points (self, g_value_get_int (value)); - break; - - case PROP_THRESHOLD_TRIGGER_EDGE: - clutter_gesture_action_set_threshold_trigger_edge (self, g_value_get_enum (value)); - break; - - case PROP_THRESHOLD_TRIGGER_DISTANCE_X: - clutter_gesture_action_set_threshold_trigger_distance (self, - g_value_get_float (value), - priv->distance_y); - break; - - case PROP_THRESHOLD_TRIGGER_DISTANCE_Y: - clutter_gesture_action_set_threshold_trigger_distance (self, - priv->distance_x, - g_value_get_float (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_gesture_action_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterGestureActionPrivate *priv = - clutter_gesture_action_get_instance_private (CLUTTER_GESTURE_ACTION (gobject)); - - switch (prop_id) - { - case PROP_N_TOUCH_POINTS: - g_value_set_int (value, priv->requested_nb_points); - break; - - case PROP_THRESHOLD_TRIGGER_EDGE: - g_value_set_enum (value, priv->edge); - break; - - case PROP_THRESHOLD_TRIGGER_DISTANCE_X: - if (priv->distance_x > 0.0) - g_value_set_float (value, priv->distance_x); - else - g_value_set_float (value, gesture_get_default_threshold ()); - break; - - case PROP_THRESHOLD_TRIGGER_DISTANCE_Y: - if (priv->distance_y > 0.0) - g_value_set_float (value, priv->distance_y); - else - g_value_set_float (value, gesture_get_default_threshold ()); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_gesture_action_finalize (GObject *gobject) -{ - ClutterGestureActionPrivate *priv = - clutter_gesture_action_get_instance_private (CLUTTER_GESTURE_ACTION (gobject)); - - g_array_unref (priv->points); - - G_OBJECT_CLASS (clutter_gesture_action_parent_class)->finalize (gobject); -} - -static void -clutter_gesture_action_class_init (ClutterGestureActionClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); - ClutterActionClass *action_class = CLUTTER_ACTION_CLASS (klass); - - gobject_class->finalize = clutter_gesture_action_finalize; - gobject_class->set_property = clutter_gesture_action_set_property; - gobject_class->get_property = clutter_gesture_action_get_property; - - meta_class->set_enabled = clutter_gesture_action_set_enabled; - - action_class->handle_event = clutter_gesture_action_handle_event; - action_class->sequence_cancelled = clutter_gesture_action_sequence_cancelled; - - klass->gesture_begin = default_event_handler; - klass->gesture_progress = default_event_handler; - klass->gesture_prepare = default_event_handler; - - /** - * ClutterGestureAction:n-touch-points: - * - * Number of touch points to trigger a gesture action. - */ - gesture_props[PROP_N_TOUCH_POINTS] = - g_param_spec_int ("n-touch-points", NULL, NULL, - 1, G_MAXINT, 1, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterGestureAction:threshold-trigger-edge: - * - * The trigger edge to be used by the action to either emit the - * [signal@GestureAction::gesture-begin] signal or to emit the - * [signal@GestureAction::gesture-cancel] signal. - */ - gesture_props[PROP_THRESHOLD_TRIGGER_EDGE] = - g_param_spec_enum ("threshold-trigger-edge", NULL, NULL, - CLUTTER_TYPE_GESTURE_TRIGGER_EDGE, - CLUTTER_GESTURE_TRIGGER_EDGE_NONE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - /** - * ClutterGestureAction:threshold-trigger-distance-x: - * - * The horizontal trigger distance to be used by the action to either - * emit the [signal@GestureAction::gesture-begin] signal or to emit - * the [signal@GestureAction::gesture-cancel] signal. - * - * A negative value will be interpreted as the default drag threshold. - */ - gesture_props[PROP_THRESHOLD_TRIGGER_DISTANCE_X] = - g_param_spec_float ("threshold-trigger-distance-x", NULL, NULL, - -1.0, G_MAXFLOAT, -1.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - /** - * ClutterGestureAction:threshold-trigger-distance-y: - * - * The vertical trigger distance to be used by the action to either - * emit the [signal@GestureAction::gesture-begin] signal or to emit - * the [signal@GestureAction::gesture-cancel] signal. - * - * A negative value will be interpreted as the default drag threshold. - */ - gesture_props[PROP_THRESHOLD_TRIGGER_DISTANCE_Y] = - g_param_spec_float ("threshold-trigger-distance-y", NULL, NULL, - -1.0, G_MAXFLOAT, -1.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - g_object_class_install_properties (gobject_class, - PROP_LAST, - gesture_props); - - /** - * ClutterGestureAction::gesture-begin: - * @action: the #ClutterGestureAction that emitted the signal - * @actor: the #ClutterActor attached to the @action - * - * The signal is emitted when the [class@Actor] to which - * a #ClutterGestureAction has been applied starts receiving a gesture. - * - * Return value: %TRUE if the gesture should start, and %FALSE if - * the gesture should be ignored. - */ - gesture_signals[GESTURE_BEGIN] = - g_signal_new (I_("gesture-begin"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterGestureActionClass, gesture_begin), - _clutter_boolean_continue_accumulator, NULL, - _clutter_marshal_BOOLEAN__OBJECT, - G_TYPE_BOOLEAN, 1, - CLUTTER_TYPE_ACTOR); - - /** - * ClutterGestureAction::gesture-progress: - * @action: the #ClutterGestureAction that emitted the signal - * @actor: the #ClutterActor attached to the @action - * - * The signal is emitted for each motion event after - * the [signal@GestureAction::gesture-begin] signal has been emitted. - * - * Return value: %TRUE if the gesture should continue, and %FALSE if - * the gesture should be cancelled. - */ - gesture_signals[GESTURE_PROGRESS] = - g_signal_new (I_("gesture-progress"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterGestureActionClass, gesture_progress), - _clutter_boolean_continue_accumulator, NULL, - _clutter_marshal_BOOLEAN__OBJECT, - G_TYPE_BOOLEAN, 1, - CLUTTER_TYPE_ACTOR); - - /** - * ClutterGestureAction::gesture-end: - * @action: the #ClutterGestureAction that emitted the signal - * @actor: the #ClutterActor attached to the @action - * - * The signal is emitted at the end of the gesture gesture, - * when the pointer's button is released - * - * This signal is emitted if and only if the [signal@GestureAction::gesture-begin] - * signal has been emitted first. - */ - gesture_signals[GESTURE_END] = - g_signal_new (I_("gesture-end"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterGestureActionClass, gesture_end), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_ACTOR); - - /** - * ClutterGestureAction::gesture-cancel: - * @action: the #ClutterGestureAction that emitted the signal - * @actor: the #ClutterActor attached to the @action - * - * The signal is emitted when the ongoing gesture gets - * cancelled from the [signal@GestureAction::gesture-progress] signal handler. - * - * This signal is emitted if and only if the [signal@GestureAction::gesture-begin] - * signal has been emitted first. - */ - gesture_signals[GESTURE_CANCEL] = - g_signal_new (I_("gesture-cancel"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterGestureActionClass, gesture_cancel), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_ACTOR); -} - -static void -clutter_gesture_action_init (ClutterGestureAction *self) -{ - ClutterGestureActionPrivate *priv = - clutter_gesture_action_get_instance_private (self); - - priv->points = g_array_sized_new (FALSE, TRUE, sizeof (GesturePoint), 3); - g_array_set_clear_func (priv->points, (GDestroyNotify) gesture_point_unset); - - priv->requested_nb_points = 1; - priv->edge = CLUTTER_GESTURE_TRIGGER_EDGE_NONE; -} - -/** - * clutter_gesture_action_new: - * - * Creates a new #ClutterGestureAction instance. - * - * Return value: the newly created #ClutterGestureAction - */ -ClutterAction * -clutter_gesture_action_new (void) -{ - return g_object_new (CLUTTER_TYPE_GESTURE_ACTION, NULL); -} - -/** - * clutter_gesture_action_get_press_coords: - * @action: a #ClutterGestureAction - * @point: the touch point index, with 0 being the first touch - * point received by the action - * @press_x: (out) (allow-none): return location for the press - * event's X coordinate - * @press_y: (out) (allow-none): return location for the press - * event's Y coordinate - * - * Retrieves the coordinates, in stage space, of the press event - * that started the dragging for a specific touch point. - */ -void -clutter_gesture_action_get_press_coords (ClutterGestureAction *action, - guint point, - gfloat *press_x, - gfloat *press_y) -{ - ClutterGestureActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action)); - - priv = clutter_gesture_action_get_instance_private (action); - - g_return_if_fail (priv->points->len > point); - - if (press_x) - *press_x = g_array_index (priv->points, - GesturePoint, - point).press_x; - - if (press_y) - *press_y = g_array_index (priv->points, - GesturePoint, - point).press_y; -} - -/** - * clutter_gesture_action_get_motion_coords: - * @action: a #ClutterGestureAction - * @point: the touch point index, with 0 being the first touch - * point received by the action - * @motion_x: (out) (allow-none): return location for the latest motion - * event's X coordinate - * @motion_y: (out) (allow-none): return location for the latest motion - * event's Y coordinate - * - * Retrieves the coordinates, in stage space, of the latest motion - * event during the dragging. - */ -void -clutter_gesture_action_get_motion_coords (ClutterGestureAction *action, - guint point, - gfloat *motion_x, - gfloat *motion_y) -{ - ClutterGestureActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action)); - - priv = clutter_gesture_action_get_instance_private (action); - - g_return_if_fail (priv->points->len > point); - - if (motion_x) - *motion_x = g_array_index (priv->points, - GesturePoint, - point).last_motion_x; - - if (motion_y) - *motion_y = g_array_index (priv->points, - GesturePoint, - point).last_motion_y; -} - -/** - * clutter_gesture_action_get_motion_delta: - * @action: a #ClutterGestureAction - * @point: the touch point index, with 0 being the first touch - * point received by the action - * @delta_x: (out) (allow-none): return location for the X axis - * component of the incremental motion delta - * @delta_y: (out) (allow-none): return location for the Y axis - * component of the incremental motion delta - * - * Retrieves the incremental delta since the last motion event - * during the dragging. - * - * Return value: the distance since last motion event - */ -gfloat -clutter_gesture_action_get_motion_delta (ClutterGestureAction *action, - guint point, - gfloat *delta_x, - gfloat *delta_y) -{ - ClutterGestureActionPrivate *priv; - gfloat d_x, d_y; - - g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0); - - priv = clutter_gesture_action_get_instance_private (action); - - g_return_val_if_fail (priv->points->len > point, 0); - - d_x = g_array_index (priv->points, - GesturePoint, - point).last_delta_x; - d_y = g_array_index (priv->points, - GesturePoint, - point).last_delta_y; - - if (delta_x) - *delta_x = d_x; - - if (delta_y) - *delta_y = d_y; - - return sqrt ((d_x * d_x) + (d_y * d_y)); -} - -/** - * clutter_gesture_action_get_release_coords: - * @action: a #ClutterGestureAction - * @point: the touch point index, with 0 being the first touch - * point received by the action - * @release_x: (out) (allow-none): return location for the X coordinate of - * the last release - * @release_y: (out) (allow-none): return location for the Y coordinate of - * the last release - * - * Retrieves the coordinates, in stage space, where the touch point was - * last released. - */ -void -clutter_gesture_action_get_release_coords (ClutterGestureAction *action, - guint point, - gfloat *release_x, - gfloat *release_y) -{ - ClutterGestureActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action)); - - priv = clutter_gesture_action_get_instance_private (action); - - g_return_if_fail (priv->points->len > point); - - if (release_x) - *release_x = g_array_index (priv->points, - GesturePoint, - point).release_x; - - if (release_y) - *release_y = g_array_index (priv->points, - GesturePoint, - point).release_y; -} - -/** - * clutter_gesture_action_get_velocity: - * @action: a #ClutterGestureAction - * @point: the touch point index, with 0 being the first touch - * point received by the action - * @velocity_x: (out) (allow-none): return location for the latest motion - * event's X velocity - * @velocity_y: (out) (allow-none): return location for the latest motion - * event's Y velocity - * - * Retrieves the velocity, in stage pixels per millisecond, of the - * latest motion event during the dragging. - */ -gfloat -clutter_gesture_action_get_velocity (ClutterGestureAction *action, - guint point, - gfloat *velocity_x, - gfloat *velocity_y) -{ - ClutterGestureActionPrivate *priv; - gfloat d_x, d_y, distance, velocity; - gint64 d_t; - - g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0); - - priv = clutter_gesture_action_get_instance_private (action); - - g_return_val_if_fail (priv->points->len > point, 0); - - distance = clutter_gesture_action_get_motion_delta (action, point, - &d_x, &d_y); - - d_t = g_array_index (priv->points, - GesturePoint, - point).last_delta_time; - - if (velocity_x) - *velocity_x = d_t > FLOAT_EPSILON ? d_x / d_t : 0; - - if (velocity_y) - *velocity_y = d_t > FLOAT_EPSILON ? d_y / d_t : 0; - - velocity = d_t > FLOAT_EPSILON ? distance / d_t : 0; - return velocity; -} - -/** - * clutter_gesture_action_get_n_touch_points: - * @action: a #ClutterGestureAction - * - * Retrieves the number of requested points to trigger the gesture. - * - * Return value: the number of points to trigger the gesture. - */ -gint -clutter_gesture_action_get_n_touch_points (ClutterGestureAction *action) -{ - ClutterGestureActionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0); - - priv = clutter_gesture_action_get_instance_private (action); - - return priv->requested_nb_points; -} - -/** - * clutter_gesture_action_set_n_touch_points: - * @action: a #ClutterGestureAction - * @nb_points: a number of points - * - * Sets the number of points needed to trigger the gesture. - */ -void -clutter_gesture_action_set_n_touch_points (ClutterGestureAction *action, - gint nb_points) -{ - ClutterGestureActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action)); - g_return_if_fail (nb_points >= 1); - - priv = clutter_gesture_action_get_instance_private (action); - - if (priv->requested_nb_points == nb_points) - return; - - priv->requested_nb_points = nb_points; - - if (priv->in_gesture) - { - if (priv->points->len < priv->requested_nb_points) - cancel_gesture (action); - } - else if (priv->edge == CLUTTER_GESTURE_TRIGGER_EDGE_AFTER) - { - if (priv->points->len >= priv->requested_nb_points) - { - ClutterActor *actor = - clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); - gint i; - float threshold_x, threshold_y; - - clutter_gesture_action_get_threshold_trigger_distance (action, &threshold_x, &threshold_y); - - for (i = 0; i < priv->points->len; i++) - { - GesturePoint *point = &g_array_index (priv->points, GesturePoint, i); - - if ((fabsf (point->press_y - point->last_motion_y) >= threshold_y) || - (fabsf (point->press_x - point->last_motion_x) >= threshold_x)) - { - begin_gesture (action, actor); - break; - } - } - } - } - - g_object_notify_by_pspec (G_OBJECT (action), - gesture_props[PROP_N_TOUCH_POINTS]); -} - -/** - * clutter_gesture_action_get_n_current_points: - * @action: a #ClutterGestureAction - * - * Retrieves the number of points currently active. - * - * Return value: the number of points currently active. - */ -guint -clutter_gesture_action_get_n_current_points (ClutterGestureAction *action) -{ - ClutterGestureActionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0); - - priv = clutter_gesture_action_get_instance_private (action); - - return priv->points->len; -} - -/** - * clutter_gesture_action_get_sequence: - * @action: a #ClutterGestureAction - * @point: index of a point currently active - * - * Retrieves the #ClutterEventSequence of a touch point. - * - * Return value: (transfer none): the #ClutterEventSequence of a touch point. - */ -ClutterEventSequence * -clutter_gesture_action_get_sequence (ClutterGestureAction *action, - guint point) -{ - ClutterGestureActionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), NULL); - - priv = clutter_gesture_action_get_instance_private (action); - - g_return_val_if_fail (priv->points->len > point, NULL); - - return g_array_index (priv->points, GesturePoint, point).sequence; -} - -/** - * clutter_gesture_action_get_device: - * @action: a #ClutterGestureAction - * @point: the touch point index, with 0 being the first touch - * point received by the action - * - * Retrieves the #ClutterInputDevice of a touch point. - * - * Return value: (transfer none): the #ClutterInputDevice of a touch point. - */ -ClutterInputDevice * -clutter_gesture_action_get_device (ClutterGestureAction *action, - guint point) -{ - ClutterGestureActionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), NULL); - - priv = clutter_gesture_action_get_instance_private (action); - - g_return_val_if_fail (priv->points->len > point, NULL); - - return g_array_index (priv->points, GesturePoint, point).device; -} - -/** - * clutter_gesture_action_get_last_event: - * @action: a #ClutterGestureAction - * @point: index of a point currently active - * - * Retrieves a reference to the last #ClutterEvent for a touch point. Call - * [method@Event.copy] if you need to store the reference somewhere. - * - * Return value: (transfer none): the last #ClutterEvent for a touch point. - */ -const ClutterEvent * -clutter_gesture_action_get_last_event (ClutterGestureAction *action, - guint point) -{ - GesturePoint *gesture_point; - ClutterGestureActionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), NULL); - - priv = clutter_gesture_action_get_instance_private (action); - - g_return_val_if_fail (priv->points->len > point, NULL); - - gesture_point = &g_array_index (priv->points, GesturePoint, point); - - return gesture_point->last_event; -} - -/** - * clutter_gesture_action_cancel: - * @action: a #ClutterGestureAction - * - * Cancel a #ClutterGestureAction before it begins - */ -void -clutter_gesture_action_cancel (ClutterGestureAction *action) -{ - g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action)); - - cancel_gesture (action); -} - -/** - * clutter_gesture_action_set_threshold_trigger_edge: - * @action: a #ClutterGestureAction - * @edge: the %ClutterGestureTriggerEdge - * - * Sets the edge trigger for the gesture drag threshold, if any. - * - * This function should only be called by sub-classes of - * #ClutterGestureAction during their construction phase. - */ -void -clutter_gesture_action_set_threshold_trigger_edge (ClutterGestureAction *action, - ClutterGestureTriggerEdge edge) -{ - ClutterGestureActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action)); - - priv = clutter_gesture_action_get_instance_private (action); - - if (priv->edge == edge) - return; - - priv->edge = edge; - - g_object_notify_by_pspec (G_OBJECT (action), gesture_props[PROP_THRESHOLD_TRIGGER_EDGE]); -} - -/** - * clutter_gesture_action_get_threshold_trigger_edge: - * @action: a #ClutterGestureAction - * - * Retrieves the edge trigger of the gesture @action, as set using - * [method@GestureAction.set_threshold_trigger_edge]. - * - * Return value: the edge trigger0 - */ -ClutterGestureTriggerEdge -clutter_gesture_action_get_threshold_trigger_edge (ClutterGestureAction *action) -{ - ClutterGestureActionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), - CLUTTER_GESTURE_TRIGGER_EDGE_NONE); - - priv = clutter_gesture_action_get_instance_private (action); - - return priv->edge; -} - -/** - * clutter_gesture_action_set_threshold_trigger_distance: - * @action: a #ClutterGestureAction - * @x: the distance on the horizontal axis - * @y: the distance on the vertical axis - * - * Sets the threshold trigger distance for the gesture drag threshold, if any. - * - * This function should only be called by sub-classes of - * #ClutterGestureAction during their construction phase. - */ -void -clutter_gesture_action_set_threshold_trigger_distance (ClutterGestureAction *action, - float x, - float y) -{ - ClutterGestureActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action)); - - priv = clutter_gesture_action_get_instance_private (action); - - if (fabsf (x - priv->distance_x) > FLOAT_EPSILON) - { - priv->distance_x = x; - g_object_notify_by_pspec (G_OBJECT (action), gesture_props[PROP_THRESHOLD_TRIGGER_DISTANCE_X]); - } - - if (fabsf (y - priv->distance_y) > FLOAT_EPSILON) - { - priv->distance_y = y; - g_object_notify_by_pspec (G_OBJECT (action), gesture_props[PROP_THRESHOLD_TRIGGER_DISTANCE_Y]); - } -} - -/** - * clutter_gesture_action_get_threshold_trigger_distance: - * @action: a #ClutterGestureAction - * @x: (out) (allow-none): The return location for the horizontal distance, or %NULL - * @y: (out) (allow-none): The return location for the vertical distance, or %NULL - * - * Retrieves the threshold trigger distance of the gesture @action, - * as set using [method@GestureAction.set_threshold_trigger_distance]. - */ -void -clutter_gesture_action_get_threshold_trigger_distance (ClutterGestureAction *action, - float *x, - float *y) -{ - ClutterGestureActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action)); - - priv = clutter_gesture_action_get_instance_private (action); - - if (x != NULL) - { - if (priv->distance_x > 0.0) - *x = priv->distance_x; - else - *x = gesture_get_default_threshold (); - } - if (y != NULL) - { - if (priv->distance_y > 0.0) - *y = priv->distance_y; - else - *y = gesture_get_default_threshold (); - } -} diff --git a/mutter/clutter/clutter/clutter-gesture-action.h b/mutter/clutter/clutter/clutter-gesture-action.h deleted file mode 100644 index db27af5..0000000 --- a/mutter/clutter/clutter/clutter-gesture-action.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * Copyright (C) 2011 Robert Bosch Car Multimedia GmbH. - * - * 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 . - * - * Author: - * Tomeu Vizoso - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-action.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_GESTURE_ACTION (clutter_gesture_action_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterGestureAction, clutter_gesture_action, - CLUTTER, GESTURE_ACTION, ClutterAction); - -typedef struct _ClutterGestureActionPrivate ClutterGestureActionPrivate; - -/** - * ClutterGestureActionClass: - * @gesture_begin: class handler for the #ClutterGestureAction::gesture-begin signal - * @gesture_progress: class handler for the #ClutterGestureAction::gesture-progress signal - * @gesture_end: class handler for the #ClutterGestureAction::gesture-end signal - * @gesture_cancel: class handler for the #ClutterGestureAction::gesture-cancel signal - * @gesture_prepare: virtual function called before emitting the - * #ClutterGestureAction::gesture-cancel signal - * - * The #ClutterGestureClass structure contains only - * private data. - */ -struct _ClutterGestureActionClass -{ - /*< private >*/ - ClutterActionClass parent_class; - - /*< public >*/ - gboolean (* gesture_begin) (ClutterGestureAction *action, - ClutterActor *actor); - gboolean (* gesture_progress) (ClutterGestureAction *action, - ClutterActor *actor); - void (* gesture_end) (ClutterGestureAction *action, - ClutterActor *actor); - void (* gesture_cancel) (ClutterGestureAction *action, - ClutterActor *actor); - gboolean (* gesture_prepare) (ClutterGestureAction *action, - ClutterActor *actor); -}; - -CLUTTER_EXPORT -ClutterAction * clutter_gesture_action_new (void); - -CLUTTER_EXPORT -gint clutter_gesture_action_get_n_touch_points (ClutterGestureAction *action); -CLUTTER_EXPORT -void clutter_gesture_action_set_n_touch_points (ClutterGestureAction *action, - gint nb_points); -CLUTTER_EXPORT -void clutter_gesture_action_get_press_coords (ClutterGestureAction *action, - guint point, - gfloat *press_x, - gfloat *press_y); -CLUTTER_EXPORT -void clutter_gesture_action_get_motion_coords (ClutterGestureAction *action, - guint point, - gfloat *motion_x, - gfloat *motion_y); -CLUTTER_EXPORT -gfloat clutter_gesture_action_get_motion_delta (ClutterGestureAction *action, - guint point, - gfloat *delta_x, - gfloat *delta_y); -CLUTTER_EXPORT -void clutter_gesture_action_get_release_coords (ClutterGestureAction *action, - guint point, - gfloat *release_x, - gfloat *release_y); -CLUTTER_EXPORT -gfloat clutter_gesture_action_get_velocity (ClutterGestureAction *action, - guint point, - gfloat *velocity_x, - gfloat *velocity_y); - -CLUTTER_EXPORT -guint clutter_gesture_action_get_n_current_points (ClutterGestureAction *action); - -CLUTTER_EXPORT -ClutterEventSequence * clutter_gesture_action_get_sequence (ClutterGestureAction *action, - guint point); - -CLUTTER_EXPORT -ClutterInputDevice * clutter_gesture_action_get_device (ClutterGestureAction *action, - guint point); - -CLUTTER_EXPORT -const ClutterEvent * clutter_gesture_action_get_last_event (ClutterGestureAction *action, - guint point); - -CLUTTER_EXPORT -void clutter_gesture_action_cancel (ClutterGestureAction *action); - -CLUTTER_EXPORT -void clutter_gesture_action_set_threshold_trigger_edge (ClutterGestureAction *action, - ClutterGestureTriggerEdge edge); - -CLUTTER_EXPORT -ClutterGestureTriggerEdge clutter_gesture_action_get_threshold_trigger_edge (ClutterGestureAction *action); - -CLUTTER_EXPORT -void clutter_gesture_action_set_threshold_trigger_distance (ClutterGestureAction *action, - float x, - float y); - -CLUTTER_EXPORT -void clutter_gesture_action_get_threshold_trigger_distance (ClutterGestureAction *action, - float *x, - float *y); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-gesture.c b/mutter/clutter/clutter/clutter-gesture.c deleted file mode 100644 index ea095f8..0000000 --- a/mutter/clutter/clutter/clutter-gesture.c +++ /dev/null @@ -1,1825 +0,0 @@ -/* - * Copyright (C) 2023 Jonas Dreßler - * - * 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 . - */ - -/** - * ClutterGesture: - * - * A #ClutterAction for recognizing gestures - * - * #ClutterGesture is a sub-class of #ClutterAction and an abstract base class - * for implementing the logic to recognize various input gestures. - * - * Implementing a #ClutterGesture is done by subclassing #ClutterGesture, - * connecting to the should_handle_sequence(), point_began()/moved()/ended() - * and sequences_cancelled() vfuncs, and then moving the gesture through the - * #ClutterGestureState state machine using clutter_gesture_set_state(). - * - * ## Recognizing new gestures - * - * #ClutterGesture uses five separate states to differentiate between the - * phases of gesture recognition. Those states also define whether to block or - * allow event delivery: - * - * - WAITING: The gesture will be starting out in this state if no points - * are available. When points are added, the state automatically moves - * to POSSIBLE before the point_began() vfunc gets called. - * - * - POSSIBLE: This is the state the gesture will be in when point_began() - * gets called the first time. As soon as the implementation is reasonably - * sure that the sequence of events is the gesture, it should set the state - * to RECOGNIZING. - * - * - RECOGNIZING: A continuous gesture is being recognized. In this state - * the implementation usually triggers UI changes as feedback to the user. - * - * - COMPLETED: The gesture was sucessfully recognized and has been completed. - * The gesture will automatically move to state WAITING after all the - * remaining points have ended. - * - * - CANCELLED: The gesture was either not started at all because preconditions - * were not fulfilled or it was cancelled by the implementation. - * The gesture will automatically move to state WAITING after all the - * remaining points have ended. - * - * Each #ClutterGesture starts out in the WAITING state and automatically - * moves to POSSIBLE when #ClutterGestureClass.should_handle_sequence() returns - * true for the first event of an event sequence. Events of this sequence must - * then be handled using the point_began(), point_moved(), point_ended() and - * sequences_cancelled() vfuncs. From these events, the implementation moves - * the gesture through the #ClutterGestureState state-machine. - * - * Note that point_ended() and sequences_cancelled() both have a default - * implementation which automatically moves the state of the gesture to - * CANCELLED. - * - * Note that it's not guaranteed that clutter_gesture_set_state() will always - * (and immediately) enter the requested state. To deal with this, never - * assume the state has changed after calling clutter_gesture_set_state(), - * and react to state changes by implementing the state_changed() vfunc. - * - * ## Relationships of gestures - * - * By default, when multiple gestures try to recognize while sharing one or - * more points, the first gesture to move to RECOGNIZING wins, and implicitly - * moves all conflicting gestures to state CANCELLED. This behavior can be - * prohibited by using the clutter_gesture_can_not_cancel() API or by - * implementing the should_influence() or should_be_influenced_by() vfuncs - * in your #ClutterGesture subclass. - */ - -#include "config.h" - -#include "clutter-gesture.h" - -#include "clutter-debug.h" -#include "clutter-enum-types.h" -#include "clutter-marshal.h" -#include "clutter-private.h" -#include "clutter-stage-private.h" - -#include - -static const char * state_to_string[] = { - "WAITING", - "POSSIBLE", - "RECOGNIZING", - "COMPLETED", - "CANCELLED", -}; -G_STATIC_ASSERT (sizeof (state_to_string) / sizeof (state_to_string[0]) == CLUTTER_N_GESTURE_STATES); - -typedef struct -{ - ClutterInputDevice *device; - ClutterEventSequence *sequence; - - ClutterEvent *begin_event; - ClutterEvent *previous_event; - ClutterEvent *latest_event; - - unsigned int n_buttons_pressed; - gboolean seen; - gboolean ended; -} GestureSequenceData; - -typedef struct _ClutterGesturePrivate ClutterGesturePrivate; - -struct _ClutterGesturePrivate -{ - GArray *sequences; - GPtrArray *stage_all_active_gestures; - - unsigned int latest_index; - - ClutterGestureState state; - - GHashTable *in_relationship_with; - - GPtrArray *cancel_on_recognizing; - - GHashTable *can_not_cancel; -}; - -enum -{ - PROP_0, - - PROP_STATE, - - PROP_LAST -}; - -enum -{ - SHOULD_HANDLE_SEQUENCE, - MAY_RECOGNIZE, - RECOGNIZE, - END, - CANCEL, - - LAST_SIGNAL -}; - -static GParamSpec *obj_props[PROP_LAST]; -static guint obj_signals[LAST_SIGNAL] = { 0, }; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterGesture, - clutter_gesture, - CLUTTER_TYPE_ACTION) - -static inline void -debug_message (ClutterGesture *self, - const char *format, - ...) G_GNUC_PRINTF (2, 3); - -static void -maybe_move_to_waiting (ClutterGesture *self); - -static void -set_state_authoritative (ClutterGesture *self, - ClutterGestureState new_state); - -inline void -debug_message (ClutterGesture *self, - const char *format, - ...) -{ - if (G_UNLIKELY (clutter_debug_flags & CLUTTER_DEBUG_GESTURES)) - { - va_list args; - char *str; - const char *name; - - va_start (args, format); - - str = g_strdup_vprintf (format, args); - name = clutter_actor_meta_get_name (CLUTTER_ACTOR_META (self)); - - CLUTTER_NOTE (GESTURES, - "<%s> [%p] %s", - name ? name : G_OBJECT_TYPE_NAME (self), - self, str); - - g_free (str); - va_end (args); - } -} - -static GestureSequenceData * -get_sequence_data (ClutterGesture *self, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - unsigned int *index) -{ - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - unsigned int i; - - for (i = 0; i < priv->sequences->len; i++) - { - GestureSequenceData *iter = &g_array_index (priv->sequences, GestureSequenceData, i); - - if (!iter->ended && iter->device == device && iter->sequence == sequence) - { - if (index != NULL) - *index = i; - return iter; - } - } - - return NULL; -} - -static void -register_sequence (ClutterGesture *self, - const ClutterEvent *event) -{ - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - GestureSequenceData *seq_data; - ClutterInputDevice *device = clutter_event_get_device (event); - ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); - - g_array_set_size (priv->sequences, priv->sequences->len + 1); - seq_data = &g_array_index (priv->sequences, GestureSequenceData, priv->sequences->len - 1); - - seq_data->device = device; - seq_data->sequence = sequence; - seq_data->n_buttons_pressed = 0; - seq_data->seen = FALSE; - seq_data->ended = FALSE; - seq_data->begin_event = clutter_event_copy (event); - - debug_message (self, - "[d=%p s=%p] Registered new sequence, n total sequences now: %u", - device, sequence, priv->sequences->len); -} - -static void -free_sequence_data (GestureSequenceData *seq_data) -{ - if (seq_data->latest_event) - clutter_event_free (seq_data->latest_event); - - if (seq_data->previous_event) - clutter_event_free (seq_data->previous_event); - - if (seq_data->begin_event) - clutter_event_free (seq_data->begin_event); -} - -static void -cancel_sequence (ClutterGesture *self, - unsigned int seq_index) -{ - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - ClutterGestureClass *gesture_class = CLUTTER_GESTURE_GET_CLASS (self); - GestureSequenceData *seq_data = - &g_array_index (priv->sequences, GestureSequenceData, seq_index); - - if (priv->state == CLUTTER_GESTURE_STATE_CANCELLED || - priv->state == CLUTTER_GESTURE_STATE_COMPLETED) - goto out; - - g_assert (priv->state == CLUTTER_GESTURE_STATE_POSSIBLE || - priv->state == CLUTTER_GESTURE_STATE_RECOGNIZING); - - /* If all sequences are cancelled, it's as if this sequence had never existed - * and therefore the gesture should never have moved into POSSIBLE. This - * means there's no reason to emit a sequences_cancelled() to the gesture - * implementation, and we can just cancel the gesture right away and move - * back into WAITING state. - * - * Note that this check is a bit sloppy and doesn't handle any sequences - * that ended or got cancelled before. In the case where sequences ended - * (as in: didn't get cancelled) before, we can not apply this shortcut and - * must leave the decision to the implementation. In the case where all - * sequences before were also cancelled, we should theoretically always - * cancel here too, but we're skipping that for simplicity reasons. - */ - if (priv->sequences->len == 1) - { - set_state_authoritative (self, CLUTTER_GESTURE_STATE_CANCELLED); - goto out; - } - - if (!seq_data->seen) - goto out; - - g_assert (!seq_data->ended); - - if (gesture_class->sequences_cancelled) - gesture_class->sequences_cancelled (self, &seq_index, 1); - -out: - seq_data->ended = TRUE; - - maybe_move_to_waiting (self); -} - -static void -cancel_point (ClutterGesture *self, - ClutterInputDevice *device, - ClutterEventSequence *sequence) -{ - unsigned int seq_index; - - if (!get_sequence_data (self, device, sequence, &seq_index)) - return; - - debug_message (self, "[d=%p s=%p] Cancelling point", device, sequence); - - cancel_sequence (self, seq_index); -} - -static void -cancel_all_points (ClutterGesture *self) -{ - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - g_autoptr (GArray) emission_points = NULL; - unsigned int i; - unsigned int n_ended; - ClutterGestureClass *gesture_class = CLUTTER_GESTURE_GET_CLASS (self); - - if (priv->state == CLUTTER_GESTURE_STATE_CANCELLED || - priv->state == CLUTTER_GESTURE_STATE_COMPLETED) - goto out; - - g_assert (priv->state == CLUTTER_GESTURE_STATE_POSSIBLE || - priv->state == CLUTTER_GESTURE_STATE_RECOGNIZING); - - emission_points = - g_array_sized_new (FALSE, TRUE, sizeof (unsigned int), priv->sequences->len); - - n_ended = 0; - - for (i = 0; i < priv->sequences->len; i++) - { - GestureSequenceData *seq_data = - &g_array_index (priv->sequences, GestureSequenceData, i); - - if (seq_data->ended) - n_ended++; - - if (seq_data->seen && !seq_data->ended) - g_array_append_val (emission_points, i); - } - - /* Just like in cancel_sequence(), force-cancel the gesture in case all sequences - * got cancelled, and none of them ended before. Also similar to cancel_sequence(), - * cheap out on the check a bit and ignore the case where sequences have - * already been cancelled before. - */ - if (n_ended == 0) - { - set_state_authoritative (self, CLUTTER_GESTURE_STATE_CANCELLED); - goto out; - } - - if (emission_points->len == 0) - goto out; - - if (gesture_class->sequences_cancelled) - { - gesture_class->sequences_cancelled (self, - (unsigned int *) emission_points->data, - emission_points->len); - } - -out: - for (i = 0; i < priv->sequences->len; i++) - { - GestureSequenceData *seq_data = - &g_array_index (priv->sequences, GestureSequenceData, i); - - seq_data->ended = TRUE; - } - - maybe_move_to_waiting (self); -} - -static gboolean -other_gesture_allowed_to_start (ClutterGesture *self, - ClutterGesture *other_gesture) -{ - /* Only a single gesture can be recognizing globally at a time */ - return FALSE; -} - -static gboolean -new_gesture_allowed_to_start (ClutterGesture *self) -{ - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - unsigned int i; - - for (i = 0; i < priv->stage_all_active_gestures->len; i++) - { - ClutterGesture *existing_gesture = - g_ptr_array_index (priv->stage_all_active_gestures, i); - ClutterGesturePrivate *other_priv = - clutter_gesture_get_instance_private (existing_gesture); - - if (existing_gesture == self) - continue; - - /* For gestures in relationship we have different APIs */ - if (g_hash_table_contains (other_priv->in_relationship_with, self)) - continue; - - if (other_priv->state == CLUTTER_GESTURE_STATE_RECOGNIZING) - { - if (!other_gesture_allowed_to_start (existing_gesture, self)) - return FALSE; - } - } - - return TRUE; -} - -static gboolean -gesture_may_start (ClutterGesture *self) -{ - gboolean may_recognize; - - if (!new_gesture_allowed_to_start (self)) - { - debug_message (self, - "gesture may not recognize, another gesture is already running"); - return FALSE; - } - - g_signal_emit (self, obj_signals[MAY_RECOGNIZE], 0, &may_recognize); - if (!may_recognize) - { - debug_message (self, - "::may-recognize prevented gesture from recognizing"); - return FALSE; - } - - return TRUE; -} - -static void -maybe_cancel_independent_gestures (ClutterGesture *self) -{ - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - int i; - - g_assert (priv->stage_all_active_gestures != NULL); - - for (i = priv->stage_all_active_gestures->len - 1; i >= 0; i--) - { - if (i >= priv->stage_all_active_gestures->len) - continue; - - ClutterGesture *other_gesture = - g_ptr_array_index (priv->stage_all_active_gestures, i); - ClutterGesturePrivate *other_priv = - clutter_gesture_get_instance_private (other_gesture); - - if (other_gesture == self) - continue; - - /* For gestures in relationship we have different APIs */ - if (g_hash_table_contains (priv->in_relationship_with, other_gesture)) - continue; - - if (other_priv->state == CLUTTER_GESTURE_STATE_POSSIBLE && - !other_gesture_allowed_to_start (self, other_gesture)) - { - debug_message (self, "Cancelling independent gesture in POSSIBLE on recognize"); - set_state_authoritative (other_gesture, CLUTTER_GESTURE_STATE_CANCELLED); - } - } -} - -static void -set_state (ClutterGesture *self, - ClutterGestureState new_state) -{ - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - ClutterGestureState old_state; - ClutterGestureClass *gesture_class = CLUTTER_GESTURE_GET_CLASS (self); - - if (priv->state == new_state) - { - debug_message (self, "Skipping state change %s -> %s", - state_to_string[priv->state], state_to_string[new_state]); - return; - } - - switch (priv->state) - { - case CLUTTER_GESTURE_STATE_WAITING: - g_assert (new_state == CLUTTER_GESTURE_STATE_POSSIBLE); - break; - case CLUTTER_GESTURE_STATE_POSSIBLE: - g_assert (new_state == CLUTTER_GESTURE_STATE_RECOGNIZING || - new_state == CLUTTER_GESTURE_STATE_COMPLETED || - new_state == CLUTTER_GESTURE_STATE_CANCELLED); - break; - case CLUTTER_GESTURE_STATE_RECOGNIZING: - g_assert (new_state == CLUTTER_GESTURE_STATE_COMPLETED || - new_state == CLUTTER_GESTURE_STATE_CANCELLED); - break; - case CLUTTER_GESTURE_STATE_COMPLETED: - g_assert (new_state == CLUTTER_GESTURE_STATE_WAITING); - break; - case CLUTTER_GESTURE_STATE_CANCELLED: - g_assert (new_state == CLUTTER_GESTURE_STATE_WAITING); - break; - case CLUTTER_N_GESTURE_STATES: - g_assert_not_reached (); - break; - } - - if (priv->state == CLUTTER_GESTURE_STATE_WAITING) - { - if (new_state == CLUTTER_GESTURE_STATE_POSSIBLE) - { - if (!priv->stage_all_active_gestures) - { - ClutterActor *actor; - ClutterStage *stage; - - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self)); - g_assert (actor); - - stage = CLUTTER_STAGE (clutter_actor_get_stage (actor)); - g_assert (stage); - - priv->stage_all_active_gestures = - clutter_stage_get_active_gestures_array (stage); - } - - g_ptr_array_add (priv->stage_all_active_gestures, self); - } - } - - if (priv->state == CLUTTER_GESTURE_STATE_POSSIBLE) - { - if (new_state == CLUTTER_GESTURE_STATE_RECOGNIZING || - new_state == CLUTTER_GESTURE_STATE_COMPLETED) - { - if (!gesture_may_start (self)) - { - set_state_authoritative (self, CLUTTER_GESTURE_STATE_CANCELLED); - return; - } - } - } - - old_state = priv->state; - - if (new_state == CLUTTER_GESTURE_STATE_RECOGNIZING || - (old_state != CLUTTER_GESTURE_STATE_RECOGNIZING && - new_state == CLUTTER_GESTURE_STATE_COMPLETED)) - { - ClutterActor *actor; - ClutterStage *stage; - unsigned int i; - - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self)); - g_assert (actor); - - stage = CLUTTER_STAGE (clutter_actor_get_stage (actor)); - g_assert (stage); - - for (i = 0; i < priv->sequences->len; i++) - { - GestureSequenceData *seq_data = - &g_array_index (priv->sequences, GestureSequenceData, i); - - if (seq_data->ended) - continue; - - clutter_stage_notify_action_implicit_grab (stage, - seq_data->device, - seq_data->sequence); - } - - /* Cancel gestures that are independent of ours and still in POSSIBLE: - * That's to prevent subtle UI bugs like a click gesture preemptively - * applying "pressed" style to a widget even though it most likely won't - * recognize anyway. - */ - maybe_cancel_independent_gestures (self); - } - - if (new_state == CLUTTER_GESTURE_STATE_WAITING) - { - gboolean removed; - GHashTableIter iter; - ClutterGesture *other_gesture; - - removed = g_ptr_array_remove (priv->stage_all_active_gestures, self); - g_assert (removed); - - g_array_set_size (priv->sequences, 0); - - g_hash_table_iter_init (&iter, priv->in_relationship_with); - while (g_hash_table_iter_next (&iter, (gpointer *) &other_gesture, NULL)) - { - ClutterGesturePrivate *other_priv = - clutter_gesture_get_instance_private (other_gesture); - - removed = g_hash_table_remove (other_priv->in_relationship_with, self); - g_assert (removed); - - g_hash_table_iter_remove (&iter); - } - - g_ptr_array_set_size (priv->cancel_on_recognizing, 0); - } - - priv->state = new_state; - - debug_message (self, "State change (%s -> %s)", - state_to_string[old_state], state_to_string[new_state]); - - if (new_state == CLUTTER_GESTURE_STATE_RECOGNIZING || - (old_state != CLUTTER_GESTURE_STATE_RECOGNIZING && - new_state == CLUTTER_GESTURE_STATE_COMPLETED)) - g_signal_emit (self, obj_signals[RECOGNIZE], 0); - - if (old_state == CLUTTER_GESTURE_STATE_RECOGNIZING && - new_state == CLUTTER_GESTURE_STATE_COMPLETED) - g_signal_emit (self, obj_signals[END], 0); - - if (old_state == CLUTTER_GESTURE_STATE_RECOGNIZING && - new_state == CLUTTER_GESTURE_STATE_CANCELLED) - g_signal_emit (self, obj_signals[CANCEL], 0); - - if (gesture_class->state_changed) - gesture_class->state_changed (self, old_state, new_state); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_STATE]); -} - -void -maybe_move_to_waiting (ClutterGesture *self) -{ - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - unsigned int i; - - if (priv->state != CLUTTER_GESTURE_STATE_COMPLETED && - priv->state != CLUTTER_GESTURE_STATE_CANCELLED) - return; - - for (i = 0; i < priv->sequences->len; i++) - { - GestureSequenceData *seq_data = &g_array_index (priv->sequences, GestureSequenceData, i); - - if (!seq_data->ended) - return; - } - - set_state (self, CLUTTER_GESTURE_STATE_WAITING); -} - -static void -maybe_influence_other_gestures (ClutterGesture *self) -{ - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - - if (priv->state == CLUTTER_GESTURE_STATE_RECOGNIZING || - priv->state == CLUTTER_GESTURE_STATE_COMPLETED) - { - unsigned int i; - - for (i = 0; i < priv->cancel_on_recognizing->len; i++) - { - ClutterGesture *other_gesture = priv->cancel_on_recognizing->pdata[i]; - ClutterGesturePrivate *other_priv = - clutter_gesture_get_instance_private (other_gesture); - - if (!g_hash_table_contains (priv->in_relationship_with, other_gesture)) - continue; - - g_assert (other_priv->state != CLUTTER_GESTURE_STATE_WAITING); - - if (other_priv->state == CLUTTER_GESTURE_STATE_CANCELLED || - other_priv->state == CLUTTER_GESTURE_STATE_COMPLETED) - continue; - - set_state (other_gesture, CLUTTER_GESTURE_STATE_CANCELLED); - maybe_move_to_waiting (other_gesture); - } - } -} - -void -set_state_authoritative (ClutterGesture *self, - ClutterGestureState new_state) -{ - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - ClutterGestureState old_state = priv->state; - - set_state (self, new_state); - - if (priv->state == CLUTTER_GESTURE_STATE_RECOGNIZING || - (old_state != CLUTTER_GESTURE_STATE_RECOGNIZING && - priv->state == CLUTTER_GESTURE_STATE_COMPLETED)) - maybe_influence_other_gestures (self); - maybe_move_to_waiting (self); -} - -static gboolean -clutter_gesture_real_should_handle_sequence (ClutterGesture *self, - const ClutterEvent *sequence_begin_event) -{ - /* We expect the actual gesture implementation to implement - * should_handle_sequence() vfunc and to tell us whether it's able to - * handle this kind of event. - */ - g_warning ("gesture <%s> [<%s>:%p]: should_handle_sequence() not implemented", - clutter_actor_meta_get_name (CLUTTER_ACTOR_META (self)), - G_OBJECT_TYPE_NAME (self), self); - - return FALSE; -} - -static gboolean -clutter_gesture_real_may_recognize (ClutterGesture *self) -{ - return TRUE; -} - -static void -clutter_gesture_real_point_ended (ClutterGesture *self, - unsigned int point_index) -{ - /* As convenience for implementations, if this is the last point, move - * to CANCELLED. - */ - if (clutter_gesture_get_n_points (self) == 1) - set_state_authoritative (self, CLUTTER_GESTURE_STATE_CANCELLED); -} - -static void -clutter_gesture_real_sequences_cancelled (ClutterGesture *self, - unsigned int *sequences, - unsigned int n_sequences) -{ - set_state_authoritative (self, CLUTTER_GESTURE_STATE_CANCELLED); -} - -static void -handle_pointer_event (ClutterGesture *self, - unsigned int seq_index, - const ClutterEvent *event) -{ - ClutterGestureClass *gesture_class = CLUTTER_GESTURE_GET_CLASS (self); - - switch (clutter_event_type (event)) - { - case CLUTTER_BUTTON_PRESS: - case CLUTTER_TOUCH_BEGIN: - if (gesture_class->point_began) - gesture_class->point_began (self, seq_index); - break; - - case CLUTTER_MOTION: - case CLUTTER_TOUCH_UPDATE: - if (gesture_class->point_moved) - gesture_class->point_moved (self, seq_index); - break; - - case CLUTTER_BUTTON_RELEASE: - case CLUTTER_TOUCH_END: - if (gesture_class->point_ended) - gesture_class->point_ended (self, seq_index); - break; - - case CLUTTER_TOUCH_CANCEL: - cancel_sequence (self, seq_index); - break; - - default: - g_assert_not_reached (); - break; - } -} - -static gboolean -is_sequence_end_event (const ClutterEvent *event) -{ - switch (clutter_event_type (event)) - { - case CLUTTER_BUTTON_PRESS: - case CLUTTER_MOTION: - case CLUTTER_TOUCH_BEGIN: - case CLUTTER_TOUCH_UPDATE: - return FALSE; - - case CLUTTER_BUTTON_RELEASE: - case CLUTTER_TOUCH_END: - case CLUTTER_TOUCH_CANCEL: - return TRUE; - - case CLUTTER_ENTER: - case CLUTTER_LEAVE: - return FALSE; - - default: - g_assert_not_reached (); - break; - } -} - -static gboolean -clutter_gesture_handle_event (ClutterAction *action, - const ClutterEvent *event) -{ - ClutterGesture *self = CLUTTER_GESTURE (action); - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - ClutterGestureClass *gesture_class = CLUTTER_GESTURE_GET_CLASS (self); - ClutterInputDevice *device = clutter_event_get_device (event); - ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); - ClutterEventType event_type = clutter_event_type (event); - GestureSequenceData *seq_data; - unsigned int seq_index; - gboolean is_first_event; - gboolean should_emit; - gboolean may_remove_point = TRUE; - ClutterGestureState old_state = priv->state; - - if (clutter_event_get_flags (event) & CLUTTER_EVENT_FLAG_SYNTHETIC) - return CLUTTER_EVENT_PROPAGATE; - - if ((seq_data = get_sequence_data (self, device, sequence, &seq_index)) == NULL) - return CLUTTER_EVENT_PROPAGATE; - - if (event_type == CLUTTER_ENTER || event_type == CLUTTER_LEAVE) - { - if (gesture_class->crossing_event) - { - gesture_class->crossing_event (self, - seq_index, - event_type, - clutter_event_get_time (event), - clutter_event_get_flags (event), - clutter_event_get_source (event), - clutter_event_get_related (event)); - } - - return CLUTTER_EVENT_PROPAGATE; - } - - g_assert (priv->state != CLUTTER_GESTURE_STATE_WAITING); - - is_first_event = !seq_data->seen; - - should_emit = - priv->state == CLUTTER_GESTURE_STATE_POSSIBLE || - priv->state == CLUTTER_GESTURE_STATE_RECOGNIZING; - - if (event_type == CLUTTER_BUTTON_PRESS) - { - seq_data->n_buttons_pressed++; - if (seq_data->n_buttons_pressed >= 2) - should_emit = FALSE; - } - else if (event_type == CLUTTER_BUTTON_RELEASE) - { - seq_data->n_buttons_pressed--; - if (seq_data->n_buttons_pressed >= 1) - may_remove_point = should_emit = FALSE; - } - - if (priv->state == CLUTTER_GESTURE_STATE_POSSIBLE && - priv->sequences->len == 1 && is_first_event) - { - /* We cancel independent gestures that are in POSSIBLE when a gesture is - * moving to RECOGNIZING, see maybe_cancel_independent_gestures(). - * - * The other half of this behavior is implemented here: Bailing out - * on the first event and moving to CANCELLED when an independent one - * is already RECOGNIZING. - * - * Note that we could also return FALSE in register_sequence(), but this - * would mean we could't track the sequence and remain in CANCELLED until - * the sequence ends. We could also move to CANCELLED in register_sequence() - * while still returning TRUE, but then we'd be moving to CANCELLED before - * the influencing is fully set-up. So we do in the handle_event() stage - * instead. - */ - if (!new_gesture_allowed_to_start (self)) - { - debug_message (self, - "Cancelling gesture on first event, another gesture is " - "already running"); - - set_state_authoritative (self, CLUTTER_GESTURE_STATE_CANCELLED); - return CLUTTER_EVENT_PROPAGATE; - } - } - - if (should_emit) - { - if (seq_data->previous_event) - clutter_event_free (seq_data->previous_event); - seq_data->previous_event = seq_data->latest_event; - seq_data->latest_event = clutter_event_copy (event); - - priv->latest_index = seq_index; - - seq_data->seen = TRUE; - - switch (event_type) - { - case CLUTTER_BUTTON_PRESS: - case CLUTTER_MOTION: - case CLUTTER_BUTTON_RELEASE: - case CLUTTER_TOUCH_BEGIN: - case CLUTTER_TOUCH_UPDATE: - case CLUTTER_TOUCH_END: - case CLUTTER_TOUCH_CANCEL: - handle_pointer_event (self, seq_index, event); - break; - - default: - g_assert_not_reached (); - break; - } - } - - if (may_remove_point && is_sequence_end_event (event)) - { - seq_data->ended = TRUE; - - maybe_move_to_waiting (self); - } - - /* If we were already RECOGNIZING, a new point was added and the gesture - * wasn't cancelled, we'll interpret this as a hint to claim the new - * point, too. - * - * Note that we check for !seq_data->ended here because the sequence might - * have been cancelled as an effect of the points_began() implementation, eg. - * in case the gesture implementation unmapped our actor. - */ - if (is_first_event && !seq_data->ended && - old_state == CLUTTER_GESTURE_STATE_RECOGNIZING && - priv->state == CLUTTER_GESTURE_STATE_RECOGNIZING) - { - ClutterActor *actor; - - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self)); - if (actor) - { - ClutterStage *stage = CLUTTER_STAGE (clutter_actor_get_stage (actor)); - - if (stage) - clutter_stage_notify_action_implicit_grab (stage, device, sequence); - } - - debug_message (self, - "Cancelling other gestures on newly added point automatically"); - - maybe_influence_other_gestures (self); - } - - return CLUTTER_EVENT_PROPAGATE; -} - -static void -clutter_gesture_sequence_cancelled (ClutterAction *action, - ClutterInputDevice *device, - ClutterEventSequence *sequence) -{ - cancel_point (CLUTTER_GESTURE (action), device, sequence); -} - -static gboolean -clutter_gesture_register_sequence (ClutterAction *action, - const ClutterEvent *sequence_begin_event) -{ - ClutterGesture *self = CLUTTER_GESTURE (action); - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - ClutterInputDevice *source_device = clutter_event_get_source_device (sequence_begin_event); - gboolean retval; - - if (priv->state == CLUTTER_GESTURE_STATE_CANCELLED || - priv->state == CLUTTER_GESTURE_STATE_COMPLETED) - return FALSE; - - if (priv->sequences->len > 0) - { - unsigned int i; - - for (i = 0; i < priv->sequences->len; i++) - { - GestureSequenceData *iter = &g_array_index (priv->sequences, GestureSequenceData, i); - ClutterInputDevice *iter_source_device; - - if (iter->ended) - continue; - - iter_source_device = clutter_event_get_source_device (iter->begin_event); - - if (iter_source_device != source_device) - return FALSE; - - break; - } - } - - g_signal_emit (self, obj_signals[SHOULD_HANDLE_SEQUENCE], 0, - sequence_begin_event, &retval); - if (!retval) - return FALSE; - - if (priv->state == CLUTTER_GESTURE_STATE_WAITING) - { - set_state_authoritative (self, CLUTTER_GESTURE_STATE_POSSIBLE); - g_assert (priv->state == CLUTTER_GESTURE_STATE_POSSIBLE); - } - - register_sequence (self, sequence_begin_event); - - return TRUE; -} - -static void -setup_influence_on_other_gesture (ClutterGesture *self, - ClutterGesture *other_gesture, - gboolean *cancel_other_gesture_on_recognizing) -{ - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - ClutterGestureClass *gesture_class = CLUTTER_GESTURE_GET_CLASS (self); - ClutterGestureClass *other_gesture_class = CLUTTER_GESTURE_GET_CLASS (other_gesture); - - /* The default: We cancel other gestures when we recognize */ - gboolean cancel = TRUE; - - /* First check with the implementation specific APIs */ - if (gesture_class->should_influence) - gesture_class->should_influence (self, other_gesture, &cancel); - - if (other_gesture_class->should_be_influenced_by) - other_gesture_class->should_be_influenced_by (other_gesture, self, &cancel); - - /* Then apply overrides made using the public methods */ - if (priv->can_not_cancel && - g_hash_table_contains (priv->can_not_cancel, other_gesture)) - cancel = FALSE; - - *cancel_other_gesture_on_recognizing = cancel; -} - -static int -clutter_gesture_setup_sequence_relationship (ClutterAction *action_1, - ClutterAction *action_2, - ClutterInputDevice *device, - ClutterEventSequence *sequence) -{ - if (!CLUTTER_IS_GESTURE (action_1) || !CLUTTER_IS_GESTURE (action_2)) - return 0; - - ClutterGesture *gesture_1 = CLUTTER_GESTURE (action_1); - ClutterGesture *gesture_2 = CLUTTER_GESTURE (action_2); - ClutterGesturePrivate *priv_1 = clutter_gesture_get_instance_private (gesture_1); - ClutterGesturePrivate *priv_2 = clutter_gesture_get_instance_private (gesture_2); - gboolean cancel_1_on_recognizing; - gboolean cancel_2_on_recognizing; - - /* When CANCELLED or COMPLETED, we refuse to accept new points in - * register_sequence(). Also when WAITING it's impossible to have points, - * that leaves only two states, POSSIBLE and RECOGNIZING. - */ - g_assert (priv_1->state == CLUTTER_GESTURE_STATE_POSSIBLE || - priv_1->state == CLUTTER_GESTURE_STATE_RECOGNIZING); - g_assert (priv_2->state == CLUTTER_GESTURE_STATE_POSSIBLE || - priv_2->state == CLUTTER_GESTURE_STATE_RECOGNIZING); - - g_assert (get_sequence_data (gesture_1, device, sequence, NULL) != NULL && - get_sequence_data (gesture_2, device, sequence, NULL) != NULL); - - /* If gesture 1 knows gesture 2 (this implies vice-versa), everything's - * figured out already, we won't negotiate again for any new shared sequences! - */ - if (g_hash_table_contains (priv_1->in_relationship_with, gesture_2)) - { - cancel_1_on_recognizing = g_ptr_array_find (priv_2->cancel_on_recognizing, gesture_1, NULL); - cancel_2_on_recognizing = g_ptr_array_find (priv_1->cancel_on_recognizing, gesture_2, NULL); - } - else - { - setup_influence_on_other_gesture (gesture_1, gesture_2, - &cancel_2_on_recognizing); - - setup_influence_on_other_gesture (gesture_2, gesture_1, - &cancel_1_on_recognizing); - - CLUTTER_NOTE (GESTURES, - "Setting up relation between \"<%s> [<%s>:%p]\" (cancel: %d) " - "and \"<%s> [<%s>:%p]\" (cancel: %d)", - clutter_actor_meta_get_name (CLUTTER_ACTOR_META (gesture_1)), - G_OBJECT_TYPE_NAME (gesture_1), gesture_1, - cancel_1_on_recognizing, - clutter_actor_meta_get_name (CLUTTER_ACTOR_META (gesture_2)), - G_OBJECT_TYPE_NAME (gesture_2), gesture_2, - cancel_2_on_recognizing); - - g_hash_table_add (priv_1->in_relationship_with, g_object_ref (gesture_2)); - g_hash_table_add (priv_2->in_relationship_with, g_object_ref (gesture_1)); - - if (cancel_2_on_recognizing) - g_ptr_array_add (priv_1->cancel_on_recognizing, gesture_2); - - if (cancel_1_on_recognizing) - g_ptr_array_add (priv_2->cancel_on_recognizing, gesture_1); - } - - if (cancel_2_on_recognizing && !cancel_1_on_recognizing) - return -1; - - if (!cancel_2_on_recognizing && cancel_1_on_recognizing) - return 1; - - return 0; -} - -static void -clutter_gesture_set_actor (ClutterActorMeta *meta, - ClutterActor *actor) -{ - ClutterGesture *self = CLUTTER_GESTURE (meta); - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - - if (priv->sequences->len) - { - debug_message (self, - "Detaching from actor while gesture has points, cancelling " - "all points"); - - cancel_all_points (self); - } - - if (!actor) - priv->stage_all_active_gestures = NULL; - - CLUTTER_ACTOR_META_CLASS (clutter_gesture_parent_class)->set_actor (meta, actor); -} - -static void -clutter_gesture_set_enabled (ClutterActorMeta *meta, - gboolean is_enabled) -{ - ClutterGesture *self = CLUTTER_GESTURE (meta); - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - - if (!is_enabled && priv->sequences->len) - { - debug_message (self, - "Disabling gesture while it has points, cancelling all points"); - - cancel_all_points (self); - } - - CLUTTER_ACTOR_META_CLASS (clutter_gesture_parent_class)->set_enabled (meta, is_enabled); -} - -static void -clutter_gesture_get_property (GObject *gobject, - unsigned int prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterGesture *self = CLUTTER_GESTURE (gobject); - - switch (prop_id) - { - case PROP_STATE: - g_value_set_enum (value, clutter_gesture_get_state (self)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -other_gesture_disposed (gpointer user_data, - GObject *finalized_gesture) -{ - GHashTable *hashtable = user_data; - - g_hash_table_remove (hashtable, finalized_gesture); -} - -static void -destroy_weak_ref_hashtable (GHashTable *hashtable) -{ - GHashTableIter iter; - GObject *key; - - g_hash_table_iter_init (&iter, hashtable); - while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL)) - g_object_weak_unref (key, other_gesture_disposed, hashtable); - - g_hash_table_destroy (hashtable); -} - -static void -clutter_gesture_finalize (GObject *gobject) -{ - ClutterGesture *self = CLUTTER_GESTURE (gobject); - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - - g_assert (priv->state != CLUTTER_GESTURE_STATE_COMPLETED && - priv->state != CLUTTER_GESTURE_STATE_CANCELLED); - - if (priv->state != CLUTTER_GESTURE_STATE_WAITING) - { - gboolean removed; - - g_warning ("gesture <%s> [<%s>:%p]: Finalizing while in active state (%s), " - "implementation didn't move the gesture to an end state.", - clutter_actor_meta_get_name (CLUTTER_ACTOR_META (self)), - G_OBJECT_TYPE_NAME (self), self, - state_to_string[priv->state]); - - removed = g_ptr_array_remove (priv->stage_all_active_gestures, self); - g_assert (removed); - } - - g_array_unref (priv->sequences); - - g_assert (g_hash_table_size (priv->in_relationship_with) == 0); - g_hash_table_destroy (priv->in_relationship_with); - - g_assert (priv->cancel_on_recognizing->len == 0); - g_ptr_array_free (priv->cancel_on_recognizing, TRUE); - - if (priv->can_not_cancel) - destroy_weak_ref_hashtable (priv->can_not_cancel); - - G_OBJECT_CLASS (clutter_gesture_parent_class)->finalize (gobject); -} - -static void -clutter_gesture_class_init (ClutterGestureClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); - ClutterActionClass *action_class = CLUTTER_ACTION_CLASS (klass); - - klass->should_handle_sequence = clutter_gesture_real_should_handle_sequence; - klass->may_recognize = clutter_gesture_real_may_recognize; - klass->point_ended = clutter_gesture_real_point_ended; - klass->sequences_cancelled = clutter_gesture_real_sequences_cancelled; - - action_class->handle_event = clutter_gesture_handle_event; - action_class->sequence_cancelled = clutter_gesture_sequence_cancelled; - action_class->register_sequence = clutter_gesture_register_sequence; - action_class->setup_sequence_relationship = clutter_gesture_setup_sequence_relationship; - - meta_class->set_actor = clutter_gesture_set_actor; - meta_class->set_enabled = clutter_gesture_set_enabled; - - gobject_class->get_property = clutter_gesture_get_property; - gobject_class->finalize = clutter_gesture_finalize; - - /** - * ClutterGesture:state: - * - * The current state of the gesture. - */ - obj_props[PROP_STATE] = - g_param_spec_enum ("state", - "state", - "state", - CLUTTER_TYPE_GESTURE_STATE, - CLUTTER_GESTURE_STATE_WAITING, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - g_object_class_install_properties (gobject_class, - PROP_LAST, - obj_props); - - /** - * ClutterGesture::should-handle-sequence: - * @gesture: the #ClutterGesture that emitted the signal - * @sequence_begin_event: the #ClutterEvent beginning the sequence - * - * The ::should-handle-sequence signal is emitted when a sequence gets added - * to the gesture. Return %FALSE to make the gesture ignore the sequence of - * events. - * - * Returns: %TRUE if the gesture may handle the sequence, %FALSE if it may not. - */ - obj_signals[SHOULD_HANDLE_SEQUENCE] = - g_signal_new (I_("should-handle-sequence"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterGestureClass, should_handle_sequence), - _clutter_boolean_continue_accumulator, - NULL, _clutter_marshal_BOOLEAN__BOXED, - G_TYPE_BOOLEAN, 1, - CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - g_signal_set_va_marshaller (obj_signals[SHOULD_HANDLE_SEQUENCE], - G_TYPE_FROM_CLASS (gobject_class), - _clutter_marshal_BOOLEAN__BOXEDv); - - /** - * ClutterGesture::may-recognize: - * @gesture: the #ClutterGesture that emitted the signal - * - * The ::may-recognize signal is emitted if the gesture might become - * active and move to RECOGNIZING. Its purpose is to allow the - * implementation or a user of a gesture to prohibit the gesture - * from starting when needed. - * - * Returns: %TRUE if the gesture may recognize, %FALSE if it may not. - */ - obj_signals[MAY_RECOGNIZE] = - g_signal_new (I_("may-recognize"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterGestureClass, may_recognize), - _clutter_boolean_continue_accumulator, - NULL, NULL, - G_TYPE_BOOLEAN, 0, - G_TYPE_NONE); - - /** - * ClutterGesture::recognize: - * @gesture: the #ClutterGesture that emitted the signal - * - * The ::recognize signal is emitted when the gesture recognizes. - * - * This is the signal gesture users are supposed to use for implementing - * actions on gesture recognize. - */ - obj_signals[RECOGNIZE] = - g_signal_new (I_("recognize"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0, - G_TYPE_NONE); - - g_signal_set_va_marshaller (obj_signals[RECOGNIZE], - G_TYPE_FROM_CLASS (gobject_class), - _clutter_marshal_VOID__VOIDv); - - /** - * ClutterGesture::end: - * @gesture: the #ClutterGesture that emitted the signal - * - * The ::end signal is emitted when a continuous gesture ends. - */ - obj_signals[END] = - g_signal_new (I_("end"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0, - G_TYPE_NONE); - - g_signal_set_va_marshaller (obj_signals[END], - G_TYPE_FROM_CLASS (gobject_class), - _clutter_marshal_VOID__VOIDv); - - /** - * ClutterGesture::cancel: - * @gesture: the #ClutterGesture that emitted the signal - * - * The ::cancel signal is emitted when a continuous gesture got cancelled. - */ - obj_signals[CANCEL] = - g_signal_new (I_("cancel"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0, - G_TYPE_NONE); - - g_signal_set_va_marshaller (obj_signals[CANCEL], - G_TYPE_FROM_CLASS (gobject_class), - _clutter_marshal_VOID__VOIDv); -} - -static void -clutter_gesture_init (ClutterGesture *self) -{ - ClutterGesturePrivate *priv = clutter_gesture_get_instance_private (self); - - priv->sequences = g_array_sized_new (FALSE, TRUE, sizeof (GestureSequenceData), 3); - g_array_set_clear_func (priv->sequences, (GDestroyNotify) free_sequence_data); - - priv->latest_index = 0; - - priv->state = CLUTTER_GESTURE_STATE_WAITING; - - priv->in_relationship_with = g_hash_table_new_full (NULL, NULL, (GDestroyNotify) g_object_unref, NULL); - - priv->cancel_on_recognizing = g_ptr_array_new (); - - priv->can_not_cancel = NULL; -} - -/** - * clutter_gesture_set_state: (skip) - * - * Sets the state of the gesture. This method is private to gesture - * implementations. - * - * Allowed state transitions are: - * - * - From POSSIBLE into RECOGNIZING, COMPLETED or CANCELLED. - * - From RECOGNIZING into COMPLETED or CANCELLED. - */ -void -clutter_gesture_set_state (ClutterGesture *self, - ClutterGestureState state) -{ - ClutterGesturePrivate *priv; - - g_return_if_fail (CLUTTER_IS_GESTURE (self)); - - priv = clutter_gesture_get_instance_private (self); - - debug_message (self, "State change requested: %s -> %s", - state_to_string[priv->state], state_to_string[state]); - - if ((priv->state == CLUTTER_GESTURE_STATE_POSSIBLE && - (state == CLUTTER_GESTURE_STATE_RECOGNIZING || - state == CLUTTER_GESTURE_STATE_COMPLETED || - state == CLUTTER_GESTURE_STATE_CANCELLED)) || - (priv->state == CLUTTER_GESTURE_STATE_RECOGNIZING && - (state == CLUTTER_GESTURE_STATE_COMPLETED || - state == CLUTTER_GESTURE_STATE_CANCELLED))) - { - set_state_authoritative (self, state); - } - else - { - /* For sake of simplicity, never complain about unnecessary tries to cancel */ - if (state == CLUTTER_GESTURE_STATE_CANCELLED) - return; - - g_warning ("gesture <%s> [<%s>:%p]: Requested invalid state change: %s -> %s", - clutter_actor_meta_get_name (CLUTTER_ACTOR_META (self)), - G_OBJECT_TYPE_NAME (self), self, - state_to_string[priv->state], state_to_string[state]); - } -} - -/** - * clutter_gesture_cancel: - * @self: a #ClutterGesture - * - * Cancels the gesture by setting its state to CANCELLED. - */ -void -clutter_gesture_cancel (ClutterGesture *self) -{ - clutter_gesture_set_state (self, CLUTTER_GESTURE_STATE_CANCELLED); -} - -/** - * clutter_gesture_reset_state_machine: (skip) - */ -void -clutter_gesture_reset_state_machine (ClutterGesture *self) -{ - ClutterGesturePrivate *priv; - - g_return_if_fail (CLUTTER_IS_GESTURE (self)); - - priv = clutter_gesture_get_instance_private (self); - - if (priv->state == CLUTTER_GESTURE_STATE_CANCELLED || - priv->state == CLUTTER_GESTURE_STATE_COMPLETED) - set_state_authoritative (self, CLUTTER_GESTURE_STATE_WAITING); -} - -/** - * clutter_gesture_get_state: - * @self: a #ClutterGesture - * - * Gets the current state of the gesture. - * - * Returns: the #ClutterGestureState - */ -ClutterGestureState -clutter_gesture_get_state (ClutterGesture *self) -{ - ClutterGesturePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_GESTURE (self), CLUTTER_GESTURE_STATE_WAITING); - - priv = clutter_gesture_get_instance_private (self); - - return priv->state; -} - -/** - * clutter_gesture_get_n_points: - * @self: a #ClutterGesture - * - * Retrieves the number of active points the gesture currently has. - * - * Returns: the number of active points - */ -unsigned int -clutter_gesture_get_n_points (ClutterGesture *self) -{ - ClutterGesturePrivate *priv; - unsigned int i, n_points = 0; - - g_return_val_if_fail (CLUTTER_IS_GESTURE (self), 0); - - priv = clutter_gesture_get_instance_private (self); - - for (i = 0; i < priv->sequences->len; i++) - { - GestureSequenceData *seq_data = &g_array_index (priv->sequences, GestureSequenceData, i); - - if (seq_data->seen && !seq_data->ended) - n_points++; - } - - return n_points; -} - -/** - * clutter_gesture_get_points: - * @self: a #ClutterGesture - * @n_points: (out) (optional): number of points - * - * Retrieves an array of the currently active points of the gesture, the array is - * ordered in the order the points were added in (newest to oldest). - * - * Returns: (array length=n_points): array with active points of the gesture - */ -unsigned int * -clutter_gesture_get_points (ClutterGesture *self, - size_t *n_points) -{ - ClutterGesturePrivate *priv; - GArray *points = NULL; - unsigned int i; - - g_return_val_if_fail (CLUTTER_IS_GESTURE (self), 0); - - priv = clutter_gesture_get_instance_private (self); - - points = g_array_sized_new (TRUE, TRUE, sizeof (unsigned int), 1); - - for (i = 0; i < priv->sequences->len; i++) - { - GestureSequenceData *seq_data = - &g_array_index (priv->sequences, GestureSequenceData, i); - - if (seq_data->seen && !seq_data->ended) - g_array_append_val (points, i); - } - - return (unsigned int *) g_array_steal (points, n_points); -} - -/** - * clutter_gesture_get_point_coords: - * @self: a #ClutterGesture - * @point_index: index of the point - * @coords_out: (out): a #graphene_point_t - * - * Retrieves the latest coordinates of the point with index @point_index. - */ -void -clutter_gesture_get_point_coords (ClutterGesture *self, - int point_index, - graphene_point_t *coords_out) -{ - ClutterGesturePrivate *priv; - GestureSequenceData *seq_data; - ClutterActor *action_actor; - - g_return_if_fail (CLUTTER_IS_GESTURE (self)); - g_return_if_fail (coords_out != NULL); - - priv = clutter_gesture_get_instance_private (self); - seq_data = - &g_array_index (priv->sequences, GestureSequenceData, - point_index == -1 ? priv->latest_index : point_index); - - clutter_event_get_position (seq_data->latest_event, coords_out); - - action_actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self)); - if (action_actor) - { - clutter_actor_transform_stage_point (action_actor, - coords_out->x, coords_out->y, - &coords_out->x, &coords_out->y); - } -} - -/** - * clutter_gesture_get_point_coords_abs: (skip) - */ -void -clutter_gesture_get_point_coords_abs (ClutterGesture *self, - int point_index, - graphene_point_t *coords_out) -{ - ClutterGesturePrivate *priv; - GestureSequenceData *seq_data; - - g_return_if_fail (CLUTTER_IS_GESTURE (self)); - g_return_if_fail (coords_out != NULL); - - priv = clutter_gesture_get_instance_private (self); - seq_data = - &g_array_index (priv->sequences, GestureSequenceData, - point_index == -1 ? priv->latest_index : point_index); - - clutter_event_get_position (seq_data->latest_event, coords_out); -} - -/** - * clutter_gesture_get_point_begin_coords: - * @self: a #ClutterGesture - * @point_index: index of the point - * @coords_out: (out): a #graphene_point_t - * - * Retrieves the begin coordinates of the point with index @point_index. - */ -void -clutter_gesture_get_point_begin_coords (ClutterGesture *self, - int point_index, - graphene_point_t *coords_out) -{ - ClutterGesturePrivate *priv; - GestureSequenceData *seq_data; - ClutterActor *action_actor; - - g_return_if_fail (CLUTTER_IS_GESTURE (self)); - g_return_if_fail (coords_out != NULL); - - priv = clutter_gesture_get_instance_private (self); - seq_data = - &g_array_index (priv->sequences, GestureSequenceData, - point_index == -1 ? priv->latest_index : point_index); - - clutter_event_get_position (seq_data->begin_event, coords_out); - - action_actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self)); - if (action_actor) - { - clutter_actor_transform_stage_point (action_actor, - coords_out->x, coords_out->y, - &coords_out->x, &coords_out->y); - } -} - -/** - * clutter_gesture_get_point_begin_coords_abs: (skip) - */ -void -clutter_gesture_get_point_begin_coords_abs (ClutterGesture *self, - int point_index, - graphene_point_t *coords_out) -{ - ClutterGesturePrivate *priv; - GestureSequenceData *seq_data; - - g_return_if_fail (CLUTTER_IS_GESTURE (self)); - g_return_if_fail (coords_out != NULL); - - priv = clutter_gesture_get_instance_private (self); - seq_data = - &g_array_index (priv->sequences, GestureSequenceData, - point_index == -1 ? priv->latest_index : point_index); - - clutter_event_get_position (seq_data->begin_event, coords_out); -} - -/** - * clutter_gesture_get_point_previous_coords: - * @self: a #ClutterGesture - * @point_index: index of the point - * @coords_out: (out): a #graphene_point_t - * - * Retrieves the previous coordinates of the point with index @point_index. - */ -void -clutter_gesture_get_point_previous_coords (ClutterGesture *self, - int point_index, - graphene_point_t *coords_out) -{ - ClutterGesturePrivate *priv; - GestureSequenceData *seq_data; - ClutterActor *action_actor; - - g_return_if_fail (CLUTTER_IS_GESTURE (self)); - g_return_if_fail (coords_out != NULL); - - priv = clutter_gesture_get_instance_private (self); - seq_data = - &g_array_index (priv->sequences, GestureSequenceData, - point_index == -1 ? priv->latest_index : point_index); - - clutter_event_get_position (seq_data->previous_event, coords_out); - - action_actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self)); - if (action_actor) - { - clutter_actor_transform_stage_point (action_actor, - coords_out->x, coords_out->y, - &coords_out->x, &coords_out->y); - } -} - -/** - * clutter_gesture_get_point_previous_coords_abs: (skip) - */ -void -clutter_gesture_get_point_previous_coords_abs (ClutterGesture *self, - int point_index, - graphene_point_t *coords_out) -{ - ClutterGesturePrivate *priv; - GestureSequenceData *seq_data; - - g_return_if_fail (CLUTTER_IS_GESTURE (self)); - g_return_if_fail (coords_out != NULL); - - priv = clutter_gesture_get_instance_private (self); - seq_data = - &g_array_index (priv->sequences, GestureSequenceData, - point_index == -1 ? priv->latest_index : point_index); - - clutter_event_get_position (seq_data->previous_event, coords_out); -} - -/** - * clutter_gesture_get_point_event: - * @self: a #ClutterGesture - * @point_index: index of the point - * - * Retrieves the the latest event of the point with index @point_index. - * - * Returns: The #ClutterEvent - */ -const ClutterEvent * -clutter_gesture_get_point_event (ClutterGesture *self, - int point_index) -{ - ClutterGesturePrivate *priv; - GestureSequenceData *seq_data; - - g_return_val_if_fail (CLUTTER_IS_GESTURE (self), NULL); - - priv = clutter_gesture_get_instance_private (self); - - g_return_val_if_fail (point_index < (int) priv->sequences->len, NULL); - g_return_val_if_fail (priv->latest_index < priv->sequences->len, NULL); - - seq_data = - &g_array_index (priv->sequences, GestureSequenceData, - point_index < 0 ? priv->latest_index : point_index); - - return seq_data->latest_event; -} - -/** - * clutter_gesture_can_not_cancel: - * @self: a #ClutterGesture - * @other_gesture: the other #ClutterGesture - * - * In case @self and @other_gesture are operating on the same points, calling - * this function will make sure that @self does not cancel @other_gesture - * when @self moves to state RECOGNIZING. - * - * To allow two gestures to recognize simultaneously using the same set of - * points (for example a zoom and a rotate gesture on the same actor), call - * clutter_gesture_can_not_cancel() twice, so that both gestures can not - * cancel each other. - */ -void -clutter_gesture_can_not_cancel (ClutterGesture *self, - ClutterGesture *other_gesture) -{ - ClutterGesturePrivate *priv; - - g_return_if_fail (CLUTTER_IS_GESTURE (self)); - g_return_if_fail (CLUTTER_IS_GESTURE (other_gesture)); - - priv = clutter_gesture_get_instance_private (self); - - if (!priv->can_not_cancel) - priv->can_not_cancel = g_hash_table_new (NULL, NULL); - - if (!g_hash_table_add (priv->can_not_cancel, other_gesture)) - return; - - g_object_weak_ref (G_OBJECT (other_gesture), - (GWeakNotify) other_gesture_disposed, - priv->can_not_cancel); -} diff --git a/mutter/clutter/clutter/clutter-gesture.h b/mutter/clutter/clutter/clutter-gesture.h deleted file mode 100644 index f461ce8..0000000 --- a/mutter/clutter/clutter/clutter-gesture.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2023 Jonas Dreßler - * - * 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 . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_GESTURE (clutter_gesture_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterGesture, clutter_gesture, - CLUTTER, GESTURE, ClutterAction) - -struct _ClutterGestureClass -{ - ClutterActionClass parent_class; - - /** - * ClutterGestureClass::should_handle_sequence: (skip) - */ - gboolean (* should_handle_sequence) (ClutterGesture *self, - const ClutterEvent *sequence_begin_event); - - /** - * ClutterGestureClass::point_began: (skip) - */ - void (* point_began) (ClutterGesture *self, - unsigned int sequence_index); - - /** - * ClutterGestureClass::point_moved: (skip) - */ - void (* point_moved) (ClutterGesture *self, - unsigned int sequence_index); - - /** - * ClutterGestureClass::point_ended: (skip) - */ - void (* point_ended) (ClutterGesture *self, - unsigned int sequence_index); - - /** - * ClutterGestureClass::sequences_cancelled: (skip) - */ - void (* sequences_cancelled) (ClutterGesture *self, - unsigned int *sequences, - unsigned int n_sequences); - - /** - * ClutterGestureClass::state_changed: (skip) - */ - void (* state_changed) (ClutterGesture *self, - ClutterGestureState old_state, - ClutterGestureState new_state); - - /** - * ClutterGestureClass::crossing_event: (skip) - */ - void (* crossing_event) (ClutterGesture *self, - unsigned int sequence_index, - ClutterEventType type, - uint32_t time, - ClutterEventFlags flags, - ClutterActor *source_actor, - ClutterActor *related_actor); - - /** - * ClutterGestureClass::may_recognize: (skip) - */ - gboolean (* may_recognize) (ClutterGesture *self); - - /** - * ClutterGestureClass::should_influence: (skip) - */ - void (* should_influence) (ClutterGesture *self, - ClutterGesture *other_gesture, - gboolean *cancel_on_recognizing); - - /** - * ClutterGestureClass::should_be_influenced_by: (skip) - */ - void (* should_be_influenced_by) (ClutterGesture *self, - ClutterGesture *other_gesture, - gboolean *cancelled_on_recognizing); -}; - -CLUTTER_EXPORT -void clutter_gesture_set_state (ClutterGesture *self, - ClutterGestureState state); - -CLUTTER_EXPORT -ClutterGestureState clutter_gesture_get_state (ClutterGesture *self); - -CLUTTER_EXPORT -void clutter_gesture_cancel (ClutterGesture *self); - -CLUTTER_EXPORT -void clutter_gesture_reset_state_machine (ClutterGesture *self); - -CLUTTER_EXPORT -unsigned int clutter_gesture_get_n_points (ClutterGesture *self); - -CLUTTER_EXPORT -unsigned int * clutter_gesture_get_points (ClutterGesture *self, - size_t *n_points); - -CLUTTER_EXPORT -void clutter_gesture_get_point_coords (ClutterGesture *self, - int point_index, - graphene_point_t *coords_out); - -CLUTTER_EXPORT -void clutter_gesture_get_point_coords_abs (ClutterGesture *self, - int point_index, - graphene_point_t *coords_out); - -CLUTTER_EXPORT -void clutter_gesture_get_point_begin_coords (ClutterGesture *self, - int point_index, - graphene_point_t *coords_out); - -CLUTTER_EXPORT -void clutter_gesture_get_point_begin_coords_abs (ClutterGesture *self, - int point_index, - graphene_point_t *coords_out); - -CLUTTER_EXPORT -void clutter_gesture_get_point_previous_coords (ClutterGesture *self, - int point_index, - graphene_point_t *coords_out); - -CLUTTER_EXPORT -void clutter_gesture_get_point_previous_coords_abs (ClutterGesture *self, - int point_index, - graphene_point_t *coords_out); - -CLUTTER_EXPORT -const ClutterEvent * clutter_gesture_get_point_event (ClutterGesture *self, - int point_index); - -CLUTTER_EXPORT -void clutter_gesture_can_not_cancel (ClutterGesture *self, - ClutterGesture *other_gesture); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-grab-private.h b/mutter/clutter/clutter/clutter-grab-private.h deleted file mode 100644 index bc9a79c..0000000 --- a/mutter/clutter/clutter/clutter-grab-private.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Clutter. - * - * Copyright (C) 2023 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 . - * - * Author: Carlos Garnacho - */ - -#pragma once - -#include "clutter-grab.h" -#include "clutter-stage.h" - -G_BEGIN_DECLS - -struct _ClutterGrab -{ - GObject parent_instance; - ClutterStage *stage; - - ClutterActor *actor; - gboolean owns_actor; - - ClutterGrab *prev; - ClutterGrab *next; -}; - -ClutterGrab * clutter_grab_new (ClutterStage *stage, - ClutterActor *actor, - gboolean owns_actor); - -void clutter_grab_notify (ClutterGrab *grab); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-grab.c b/mutter/clutter/clutter/clutter-grab.c deleted file mode 100644 index bdd2d43..0000000 --- a/mutter/clutter/clutter/clutter-grab.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Clutter. - * - * Copyright (C) 2023 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 . - * - * Author: Carlos Garnacho - */ - -#include "config.h" - -#include "clutter-grab-private.h" - -#include "clutter-private.h" - -enum -{ - PROP_0, - PROP_REVOKED, - N_PROPS, -}; - -static GParamSpec *props[N_PROPS] = { 0, }; - -G_DEFINE_FINAL_TYPE (ClutterGrab, clutter_grab, G_TYPE_OBJECT) - -static void -clutter_grab_dispose (GObject *object) -{ - clutter_grab_dismiss (CLUTTER_GRAB (object)); - G_OBJECT_CLASS (clutter_grab_parent_class)->dispose (object); -} - -static void -clutter_grab_finalize (GObject *object) -{ - ClutterGrab *grab = CLUTTER_GRAB (object); - - if (grab->owns_actor) - g_clear_pointer (&grab->actor, clutter_actor_destroy); - - G_OBJECT_CLASS (clutter_grab_parent_class)->finalize (object); -} - -static void -clutter_grab_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterGrab *grab = CLUTTER_GRAB (object); - - switch (prop_id) - { - case PROP_REVOKED: - g_value_set_boolean (value, clutter_grab_is_revoked (grab)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_grab_class_init (ClutterGrabClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = clutter_grab_dispose; - object_class->finalize = clutter_grab_finalize; - object_class->get_property = clutter_grab_get_property; - - props[PROP_REVOKED] = - g_param_spec_boolean ("revoked", NULL, NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - g_object_class_install_properties (object_class, N_PROPS, props); -} - -static void -clutter_grab_init (ClutterGrab *grab) -{ -} - -ClutterGrab * -clutter_grab_new (ClutterStage *stage, - ClutterActor *actor, - gboolean owns_actor) -{ - ClutterGrab *grab; - - grab = g_object_new (CLUTTER_TYPE_GRAB, NULL); - grab->stage = stage; - - grab->actor = actor; - if (owns_actor) - grab->owns_actor = TRUE; - - return grab; -} - -void -clutter_grab_notify (ClutterGrab *grab) -{ - g_object_notify (G_OBJECT (grab), "revoked"); -} - -gboolean -clutter_grab_is_revoked (ClutterGrab *grab) -{ - g_return_val_if_fail (CLUTTER_IS_GRAB (grab), FALSE); - - return grab->prev != NULL; -} diff --git a/mutter/clutter/clutter/clutter-grab.h b/mutter/clutter/clutter/clutter-grab.h deleted file mode 100644 index 36199ac..0000000 --- a/mutter/clutter/clutter/clutter-grab.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2021 Red Hat Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Carlos Garnacho - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -#include "clutter-macros.h" -#include "clutter-enums.h" - -#define CLUTTER_TYPE_GRAB (clutter_grab_get_type ()) -CLUTTER_EXPORT -G_DECLARE_FINAL_TYPE (ClutterGrab, clutter_grab, CLUTTER, GRAB, GObject) - -CLUTTER_EXPORT -void clutter_grab_dismiss (ClutterGrab *grab); - -CLUTTER_EXPORT -ClutterGrabState clutter_grab_get_seat_state (ClutterGrab *grab); - -CLUTTER_EXPORT -gboolean clutter_grab_is_revoked (ClutterGrab *grab); diff --git a/mutter/clutter/clutter/clutter-graphene.c b/mutter/clutter/clutter/clutter-graphene.c deleted file mode 100644 index d77be0e..0000000 --- a/mutter/clutter/clutter/clutter-graphene.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Georges Basile Stavracas Neto - * - * Copyright (C) 2019 Endless, Inc - * Copyright (C) 2009, 2010 Intel Corp - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include "config.h" - -#include "clutter/clutter-graphene.h" - -#include "clutter/clutter-private.h" -#include "clutter/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, - double progress, - GValue *retval) -{ - const graphene_point_t *ap = g_value_get_boxed (a); - const graphene_point_t *bp = g_value_get_boxed (b); - graphene_point_t res; - - graphene_point_interpolate (ap, bp, progress, &res); - - g_value_set_boxed (retval, &res); - - return TRUE; -} - -static gboolean -graphene_point3d_progress (const GValue *a, - const GValue *b, - double progress, - GValue *retval) -{ - const graphene_point3d_t *av = g_value_get_boxed (a); - const graphene_point3d_t *bv = g_value_get_boxed (b); - graphene_point3d_t res; - - graphene_point3d_interpolate (av, bv, progress, &res); - - g_value_set_boxed (retval, &res); - - return TRUE; -} - -static gboolean -graphene_rect_progress (const GValue *a, - const GValue *b, - double progress, - GValue *retval) -{ - const graphene_rect_t *rect_a = g_value_get_boxed (a); - const graphene_rect_t *rect_b = g_value_get_boxed (b); - graphene_rect_t res; - - graphene_rect_interpolate (rect_a, rect_b, progress, &res); - - g_value_set_boxed (retval, &res); - - return TRUE; -} - -static gboolean -graphene_size_progress (const GValue *a, - const GValue *b, - double progress, - GValue *retval) -{ - const graphene_size_t *as = g_value_get_boxed (a); - const graphene_size_t *bs = g_value_get_boxed (b); - graphene_size_t res; - - graphene_size_interpolate (as, bs, progress, &res); - - g_value_set_boxed (retval, &res); - - return TRUE; -} - -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, - graphene_point3d_progress); - clutter_interval_register_progress_func (GRAPHENE_TYPE_RECT, - graphene_rect_progress); - clutter_interval_register_progress_func (GRAPHENE_TYPE_SIZE, - graphene_size_progress); -} diff --git a/mutter/clutter/clutter/clutter-graphene.h b/mutter/clutter/clutter/clutter-graphene.h deleted file mode 100644 index b4ee29d..0000000 --- a/mutter/clutter/clutter/clutter-graphene.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Georges Basile Stavracas Neto - * - * Copyright (C) 2019 Endless, Inc - * Copyright (C) 2009, 2010 Intel Corp - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -void clutter_graphene_init (void); diff --git a/mutter/clutter/clutter/clutter-grid-layout.c b/mutter/clutter/clutter/clutter-grid-layout.c deleted file mode 100644 index 2b49515..0000000 --- a/mutter/clutter/clutter/clutter-grid-layout.c +++ /dev/null @@ -1,2083 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Red Hat, Inc. - * Copyright (C) 2012 Bastian Winkler - * - * 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 . - * - * Author: - * Bastian Winkler - * - * Based on GtkGrid widget by: - * Matthias Clasen - */ - -#include "config.h" - -#include -#include - -#include "clutter/clutter-grid-layout.h" - -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-layout-meta.h" -#include "clutter/clutter-private.h" - -/** - * ClutterGridLayout: - * - * A layout manager for a grid of actors - * - * #ClutterGridLayout is a layout manager which arranges its child widgets in - * rows and columns. It is a very similar to [class@Clutter.BoxLayout], but it - * consistently uses [class@Clutter.Actor]'s alignment and expansion flags instead of - * custom child properties. - * - * Children are added using [method@Clutter.GridLayout.attach]. They can span - * multiple rows or columns. It is also possible to add a child next to an - * existing child, using [method@Clutter.GridLayout.attach_next_to]. The behaviour of - * #ClutterGridLayout when several children occupy the same grid cell is undefined. - * - * #ClutterGridLayout can be used like a #ClutterBoxLayout by just using - * [method@Clutter.Actor.add_child], which will place children next to each other in - * the direction determined by the [property@Clutter.GridLayout:orientation] property. - */ - -#define CLUTTER_TYPE_GRID_CHILD (clutter_grid_child_get_type ()) - -G_DECLARE_FINAL_TYPE (ClutterGridChild, - clutter_grid_child, - CLUTTER, GRID_CHILD, - ClutterLayoutMeta) - -typedef struct _ClutterGridAttach ClutterGridAttach; -typedef struct _ClutterGridLine ClutterGridLine; -typedef struct _ClutterGridLines ClutterGridLines; -typedef struct _ClutterGridLineData ClutterGridLineData; -typedef struct _ClutterGridRequest ClutterGridRequest; - - -struct _ClutterGridAttach -{ - gint pos; - gint span; -}; - -struct _ClutterGridChild -{ - ClutterLayoutMeta parent_instance; - - ClutterGridAttach attach[2]; -}; - -#define CHILD_LEFT(child) ((child)->attach[CLUTTER_ORIENTATION_HORIZONTAL].pos) -#define CHILD_WIDTH(child) ((child)->attach[CLUTTER_ORIENTATION_HORIZONTAL].span) -#define CHILD_TOP(child) ((child)->attach[CLUTTER_ORIENTATION_VERTICAL].pos) -#define CHILD_HEIGHT(child) ((child)->attach[CLUTTER_ORIENTATION_VERTICAL].span) - -/* A ClutterGridLineData struct contains row/column specific parts - * of the grid. - */ -struct _ClutterGridLineData -{ - gfloat spacing; - guint homogeneous : 1; -}; - -struct _ClutterGridLayout -{ - ClutterLayoutManager parent_instance; - - ClutterActor *container; - ClutterOrientation orientation; - - ClutterGridLineData linedata[2]; -}; - -#define ROWS(priv) (&(priv)->linedata[CLUTTER_ORIENTATION_HORIZONTAL]) -#define COLUMNS(priv) (&(priv)->linedata[CLUTTER_ORIENTATION_VERTICAL]) - -/* A ClutterGridLine struct represents a single row or column - * during size requests - */ -struct _ClutterGridLine -{ - gfloat minimum; - gfloat natural; - gfloat position; - gfloat allocation; - - guint need_expand : 1; - guint expand : 1; - guint empty : 1; -}; - -struct _ClutterGridLines -{ - ClutterGridLine *lines; - gint min, max; -}; - -struct _ClutterGridRequest -{ - ClutterGridLayout *grid; - ClutterGridLines lines[2]; -}; - -enum -{ - PROP_0, - - PROP_ORIENTATION, - PROP_ROW_SPACING, - PROP_COLUMN_SPACING, - PROP_ROW_HOMOGENEOUS, - PROP_COLUMN_HOMOGENEOUS, - - PROP_LAST -}; -static GParamSpec *obj_props[PROP_LAST]; - -enum -{ - PROP_CHILD_0, - - PROP_CHILD_LEFT_ATTACH, - PROP_CHILD_TOP_ATTACH, - PROP_CHILD_WIDTH, - PROP_CHILD_HEIGHT, - - PROP_CHILD_LAST -}; -static GParamSpec *child_props[PROP_CHILD_LAST]; - -G_DEFINE_FINAL_TYPE (ClutterGridChild, clutter_grid_child, - CLUTTER_TYPE_LAYOUT_META) - -G_DEFINE_FINAL_TYPE (ClutterGridLayout, clutter_grid_layout, - CLUTTER_TYPE_LAYOUT_MANAGER) - - -#define GET_GRID_CHILD(grid, child) \ - (CLUTTER_GRID_CHILD(clutter_layout_manager_get_child_meta \ - (CLUTTER_LAYOUT_MANAGER((grid)),\ - CLUTTER_GRID_LAYOUT((grid))->container,(child)))) - -static void -grid_attach (ClutterGridLayout *self, - ClutterActor *actor, - gint left, - gint top, - gint width, - gint height) -{ - ClutterGridChild *grid_child; - - grid_child = GET_GRID_CHILD (self, actor); - - CHILD_LEFT (grid_child) = left; - CHILD_TOP (grid_child) = top; - CHILD_WIDTH (grid_child) = width; - CHILD_HEIGHT (grid_child) = height; -} - -/* Find the position 'touching' existing - * children. @orientation and @max determine - * from which direction to approach (horizontal - * + max = right, vertical + !max = top, etc). - * @op_pos, @op_span determine the rows/columns - * in which the touching has to happen. - */ -static gint -find_attach_position (ClutterGridLayout *self, - ClutterOrientation orientation, - gint op_pos, - gint op_span, - gboolean max) -{ - ClutterGridChild *grid_child; - ClutterGridAttach *attach; - ClutterGridAttach *opposite; - ClutterActorIter iter; - ClutterActor *child; - gint pos; - gboolean hit; - - if (max) - pos = -G_MAXINT; - else - pos = G_MAXINT; - - hit = FALSE; - - if (!self->container) - return -1; - - clutter_actor_iter_init (&iter, CLUTTER_ACTOR (self->container)); - while (clutter_actor_iter_next (&iter, &child)) - { - grid_child = GET_GRID_CHILD (self, child); - - attach = &grid_child->attach[orientation]; - opposite = &grid_child->attach[1 - orientation]; - - /* check if the ranges overlap */ - if (opposite->pos <= op_pos + op_span && op_pos <= opposite->pos + opposite->span) - { - hit = TRUE; - - if (max) - pos = MAX (pos, attach->pos + attach->span); - else - pos = MIN (pos, attach->pos); - } - } - - if (!hit) - pos = 0; - - return pos; -} -static void -grid_attach_next_to (ClutterGridLayout *layout, - ClutterActor *child, - ClutterActor *sibling, - ClutterGridPosition side, - gint width, - gint height) -{ - ClutterGridChild *grid_sibling; - gint left, top; - - if (sibling) - { - grid_sibling = GET_GRID_CHILD (layout, sibling); - - switch (side) - { - case CLUTTER_GRID_POSITION_LEFT: - left = CHILD_LEFT (grid_sibling) - width; - top = CHILD_TOP (grid_sibling); - break; - - case CLUTTER_GRID_POSITION_RIGHT: - left = CHILD_LEFT (grid_sibling) + CHILD_WIDTH (grid_sibling); - top = CHILD_TOP (grid_sibling); - break; - - case CLUTTER_GRID_POSITION_TOP: - left = CHILD_LEFT (grid_sibling); - top = CHILD_TOP (grid_sibling) - height; - break; - - case CLUTTER_GRID_POSITION_BOTTOM: - left = CHILD_LEFT (grid_sibling); - top = CHILD_TOP (grid_sibling) + CHILD_HEIGHT (grid_sibling); - break; - - default: - g_assert_not_reached (); - } - } - else - { - switch (side) - { - case CLUTTER_GRID_POSITION_LEFT: - left = find_attach_position (layout, CLUTTER_ORIENTATION_HORIZONTAL, - 0, height, FALSE); - left -= width; - top = 0; - break; - - case CLUTTER_GRID_POSITION_RIGHT: - left = find_attach_position (layout, CLUTTER_ORIENTATION_HORIZONTAL, - 0, height, TRUE); - top = 0; - break; - - case CLUTTER_GRID_POSITION_TOP: - left = 0; - top = find_attach_position (layout, CLUTTER_ORIENTATION_VERTICAL, - 0, width, FALSE); - top -= height; - break; - - case CLUTTER_GRID_POSITION_BOTTOM: - left = 0; - top = find_attach_position (layout, CLUTTER_ORIENTATION_VERTICAL, - 0, width, TRUE); - break; - - default: - g_assert_not_reached (); - } - } - - grid_attach (layout, child, left, top, width, height); -} - -static void -clutter_grid_request_update_child_attach (ClutterGridRequest *request, - ClutterActor *actor) -{ - ClutterGridLayout *grid = request->grid; - ClutterGridChild *grid_child; - - grid_child = GET_GRID_CHILD (grid, actor); - - if (CHILD_LEFT (grid_child) == -1 || CHILD_TOP (grid_child) == -1) - { - ClutterGridPosition side; - ClutterActor *sibling; - - if (grid->orientation == CLUTTER_ORIENTATION_HORIZONTAL) - { - ClutterTextDirection td; - gboolean rtl; - ClutterActor *container = CLUTTER_ACTOR (grid->container); - - td = clutter_actor_get_text_direction (container); - rtl = (td == CLUTTER_TEXT_DIRECTION_RTL) ? TRUE : FALSE; - side = rtl ? CLUTTER_GRID_POSITION_LEFT : CLUTTER_GRID_POSITION_RIGHT; - } - else - { - /* XXX: maybe we should also add a :pack-start property to modify - * this */ - side = CLUTTER_GRID_POSITION_BOTTOM; - } - - sibling = clutter_actor_get_previous_sibling (actor); - if (sibling) - clutter_grid_layout_insert_next_to (grid, sibling, side); - grid_attach_next_to (grid, actor, sibling, side, - CHILD_WIDTH (grid_child), - CHILD_HEIGHT (grid_child)); - } -} - -static void -clutter_grid_request_update_attach (ClutterGridRequest *request) -{ - ClutterGridLayout *grid = request->grid; - ClutterActorIter iter; - ClutterActor *child; - - clutter_actor_iter_init (&iter, CLUTTER_ACTOR (grid->container)); - while (clutter_actor_iter_next (&iter, &child)) - clutter_grid_request_update_child_attach (request, child); -} - -/* Calculates the min and max numbers for both orientations. - */ -static void -clutter_grid_request_count_lines (ClutterGridRequest *request) -{ - ClutterGridLayout *grid = request->grid; - ClutterGridChild *grid_child; - ClutterGridAttach *attach; - ClutterActorIter iter; - ClutterActor *child; - gint min[2]; - gint max[2]; - - min[0] = min[1] = G_MAXINT; - max[0] = max[1] = G_MININT; - - clutter_actor_iter_init (&iter, CLUTTER_ACTOR (grid->container)); - while (clutter_actor_iter_next (&iter, &child)) - { - grid_child = GET_GRID_CHILD (request->grid, child); - attach = grid_child->attach; - - min[0] = MIN (min[0], attach[0].pos); - max[0] = MAX (max[0], attach[0].pos + attach[0].span); - min[1] = MIN (min[1], attach[1].pos); - max[1] = MAX (max[1], attach[1].pos + attach[1].span); - } - - request->lines[0].min = min[0]; - request->lines[0].max = max[0]; - request->lines[1].min = min[1]; - request->lines[1].max = max[1]; -} - -/* Sets line sizes to 0 and marks lines as expand - * if they have a non-spanning expanding child. - */ -static void -clutter_grid_request_init (ClutterGridRequest *request, - ClutterOrientation orientation) -{ - ClutterGridLayout *grid = request->grid; - ClutterGridChild *grid_child; - ClutterGridAttach *attach; - ClutterGridLines *lines; - ClutterActorIter iter; - ClutterActor *child; - gint i; - - lines = &request->lines[orientation]; - - for (i = 0; i < lines->max - lines->min; i++) - { - lines->lines[i].minimum = 0; - lines->lines[i].natural = 0; - lines->lines[i].expand = FALSE; - } - - clutter_actor_iter_init (&iter, CLUTTER_ACTOR (grid->container)); - while (clutter_actor_iter_next (&iter, &child)) - { - grid_child = GET_GRID_CHILD (request->grid, child); - attach = &grid_child->attach[orientation]; - if (attach->span == 1 && clutter_actor_needs_expand (child, orientation)) - lines->lines[attach->pos - lines->min].expand = TRUE; - } -} - -/* Sums allocations for lines spanned by child and their spacing. - */ -static gfloat -compute_allocation_for_child (ClutterGridRequest *request, - ClutterActor *child, - ClutterOrientation orientation) -{ - ClutterGridLayout *grid = request->grid; - ClutterGridChild *grid_child; - ClutterGridLineData *linedata; - ClutterGridLines *lines; - ClutterGridLine *line; - ClutterGridAttach *attach; - gfloat size; - gint i; - - grid_child = GET_GRID_CHILD (request->grid, child); - linedata = &grid->linedata[orientation]; - lines = &request->lines[orientation]; - attach = &grid_child->attach[orientation]; - - size = (attach->span - 1) * linedata->spacing; - for (i = 0; i < attach->span; i++) - { - line = &lines->lines[attach->pos - lines->min + i]; - size += line->allocation; - } - - return size; -} - -static void -compute_request_for_child (ClutterGridRequest *request, - ClutterActor *child, - ClutterOrientation orientation, - gboolean contextual, - gfloat *minimum, - gfloat *natural) -{ - if (contextual) - { - gfloat size; - - size = compute_allocation_for_child (request, child, 1 - orientation); - if (orientation == CLUTTER_ORIENTATION_HORIZONTAL) - clutter_actor_get_preferred_width (child, size, minimum, natural); - else - clutter_actor_get_preferred_height (child, size, minimum, natural); - } - else - { - if (orientation == CLUTTER_ORIENTATION_HORIZONTAL) - clutter_actor_get_preferred_width (child, -1, minimum, natural); - else - clutter_actor_get_preferred_height (child, -1, minimum, natural); - } -} - -/* Sets requisition to max. of non-spanning children. - * If contextual is TRUE, requires allocations of - * lines in the opposite orientation to be set. - */ -static void -clutter_grid_request_non_spanning (ClutterGridRequest *request, - ClutterOrientation orientation, - gboolean contextual) -{ - ClutterGridLayout *grid = request->grid; - ClutterGridChild *grid_child; - ClutterGridAttach *attach; - ClutterGridLines *lines; - ClutterGridLine *line; - ClutterActorIter iter; - ClutterActor *child; - gfloat minimum; - gfloat natural; - - lines = &request->lines[orientation]; - - clutter_actor_iter_init (&iter, CLUTTER_ACTOR (grid->container)); - while (clutter_actor_iter_next (&iter, &child)) - { - if (!clutter_actor_is_visible (child)) - continue; - - grid_child = GET_GRID_CHILD (request->grid, child); - - attach = &grid_child->attach[orientation]; - if (attach->span != 1) - continue; - - compute_request_for_child (request, child, orientation, contextual, &minimum, &natural); - - line = &lines->lines[attach->pos - lines->min]; - line->minimum = MAX (line->minimum, minimum); - line->natural = MAX (line->natural, natural); - } -} - -/* Enforce homogeneous sizes. - */ -static void -clutter_grid_request_homogeneous (ClutterGridRequest *request, - ClutterOrientation orientation) -{ - ClutterGridLayout *grid = request->grid; - ClutterGridLineData *linedata; - ClutterGridLines *lines; - gfloat minimum, natural; - gint i; - - linedata = &grid->linedata[orientation]; - lines = &request->lines[orientation]; - - if (!linedata->homogeneous) - return; - - minimum = 0.0f; - natural = 0.0f; - - for (i = 0; i < lines->max - lines->min; i++) - { - minimum = MAX (minimum, lines->lines[i].minimum); - natural = MAX (natural, lines->lines[i].natural); - } - - for (i = 0; i < lines->max - lines->min; i++) - { - lines->lines[i].minimum = minimum; - lines->lines[i].natural = natural; - } -} - -/* Deals with spanning children. - * Requires expand fields of lines to be set for - * non-spanning children. - */ -static void -clutter_grid_request_spanning (ClutterGridRequest *request, - ClutterOrientation orientation, - gboolean contextual) -{ - ClutterGridLayout *grid = request->grid; - ClutterGridChild *grid_child; - ClutterActor *child; - ClutterActorIter iter; - ClutterGridAttach *attach; - ClutterGridLineData *linedata; - ClutterGridLines *lines; - ClutterGridLine *line; - gfloat minimum; - gfloat natural; - gint span_minimum; - gint span_natural; - gint span_expand; - gboolean force_expand; - gint extra; - gint expand; - gint line_extra; - gint i; - - linedata = &grid->linedata[orientation]; - lines = &request->lines[orientation]; - - clutter_actor_iter_init (&iter, CLUTTER_ACTOR (grid->container)); - while (clutter_actor_iter_next (&iter, &child)) - { - if (!clutter_actor_is_visible (child)) - continue; - - grid_child = GET_GRID_CHILD (request->grid, child); - - attach = &grid_child->attach[orientation]; - if (attach->span == 1) - continue; - - compute_request_for_child (request, child, orientation, contextual, - &minimum, &natural); - - span_minimum = (attach->span - 1) * linedata->spacing; - span_natural = (attach->span - 1) * linedata->spacing; - span_expand = 0; - force_expand = FALSE; - for (i = 0; i < attach->span; i++) - { - line = &lines->lines[attach->pos - lines->min + i]; - span_minimum += line->minimum; - span_natural += line->natural; - if (line->expand) - span_expand += 1; - } - if (span_expand == 0) - { - span_expand = attach->span; - force_expand = TRUE; - } - - /* If we need to request more space for this child to fill - * its requisition, then divide up the needed space amongst the - * lines it spans, favoring expandable lines if any. - * - * When doing homogeneous allocation though, try to keep the - * line allocations even, since we're going to force them to - * be the same anyway, and we don't want to introduce unnecessary - * extra space. - */ - if (span_minimum < minimum) - { - if (linedata->homogeneous) - { - gint total, m; - - total = minimum - (attach->span - 1) * linedata->spacing; - m = total / attach->span + (total % attach->span ? 1 : 0); - for (i = 0; i < attach->span; i++) - { - line = &lines->lines[attach->pos - lines->min + i]; - line->minimum = MAX(line->minimum, m); - } - } - else - { - extra = minimum - span_minimum; - expand = span_expand; - for (i = 0; i < attach->span; i++) - { - line = &lines->lines[attach->pos - lines->min + i]; - if (force_expand || line->expand) - { - line_extra = extra / expand; - line->minimum += line_extra; - extra -= line_extra; - expand -= 1; - } - } - } - } - - if (span_natural < natural) - { - if (linedata->homogeneous) - { - gint total, n; - - total = natural - (attach->span - 1) * linedata->spacing; - n = total / attach->span + (total % attach->span ? 1 : 0); - for (i = 0; i < attach->span; i++) - { - line = &lines->lines[attach->pos - lines->min + i]; - line->natural = MAX(line->natural, n); - } - } - else - { - extra = natural - span_natural; - expand = span_expand; - for (i = 0; i < attach->span; i++) - { - line = &lines->lines[attach->pos - lines->min + i]; - if (force_expand || line->expand) - { - line_extra = extra / expand; - line->natural += line_extra; - extra -= line_extra; - expand -= 1; - } - } - } - } - } -} - -/* Marks empty and expanding lines and counts them. - */ -static void -clutter_grid_request_compute_expand (ClutterGridRequest *request, - ClutterOrientation orientation, - gint *nonempty_lines, - gint *expand_lines) -{ - ClutterGridLayout *grid = request->grid; - ClutterGridChild *grid_child; - ClutterGridAttach *attach; - ClutterActorIter iter; - ClutterActor *child; - gint i; - ClutterGridLines *lines; - ClutterGridLine *line; - gboolean has_expand; - gint expand; - gint empty; - - lines = &request->lines[orientation]; - - for (i = 0; i < lines->max - lines->min; i++) - { - lines->lines[i].need_expand = FALSE; - lines->lines[i].expand = FALSE; - lines->lines[i].empty = TRUE; - } - - clutter_actor_iter_init (&iter, CLUTTER_ACTOR (grid->container)); - while (clutter_actor_iter_next (&iter, &child)) - { - if (!clutter_actor_is_visible (child)) - continue; - - grid_child = GET_GRID_CHILD (request->grid, child); - - attach = &grid_child->attach[orientation]; - if (attach->span != 1) - continue; - - line = &lines->lines[attach->pos - lines->min]; - line->empty = FALSE; - if (clutter_actor_needs_expand (child, orientation)) - line->expand = TRUE; - } - - - clutter_actor_iter_init (&iter, CLUTTER_ACTOR (grid->container)); - while (clutter_actor_iter_next (&iter, &child)) - { - if (!clutter_actor_is_visible (child)) - continue; - - grid_child = GET_GRID_CHILD (request->grid, child); - - attach = &grid_child->attach[orientation]; - if (attach->span == 1) - continue; - - has_expand = FALSE; - for (i = 0; i < attach->span; i++) - { - line = &lines->lines[attach->pos - lines->min + i]; - line->empty = FALSE; - if (line->expand) - has_expand = TRUE; - } - - if (!has_expand && clutter_actor_needs_expand (child, orientation)) - { - for (i = 0; i < attach->span; i++) - { - line = &lines->lines[attach->pos - lines->min + i]; - line->need_expand = TRUE; - } - } - } - - empty = 0; - expand = 0; - for (i = 0; i < lines->max - lines->min; i++) - { - line = &lines->lines[i]; - - if (line->need_expand) - line->expand = TRUE; - - if (line->empty) - empty += 1; - - if (line->expand) - expand += 1; - } - - if (nonempty_lines) - *nonempty_lines = lines->max - lines->min - empty; - - if (expand_lines) - *expand_lines = expand; -} - -/* Sums the minimum and natural fields of lines and their spacing. - */ -static void -clutter_grid_request_sum (ClutterGridRequest *request, - ClutterOrientation orientation, - gfloat *minimum, - gfloat *natural) -{ - ClutterGridLayout *grid = request->grid; - ClutterGridLineData *linedata; - ClutterGridLines *lines; - gint i; - gfloat min, nat; - gint nonempty; - - clutter_grid_request_compute_expand (request, orientation, &nonempty, NULL); - - linedata = &grid->linedata[orientation]; - lines = &request->lines[orientation]; - - min = 0; - nat = 0; - if (nonempty > 0) - { - min = (nonempty - 1) * linedata->spacing; - nat = (nonempty - 1) * linedata->spacing; - } - - for (i = 0; i < lines->max - lines->min; i++) - { - min += lines->lines[i].minimum; - nat += lines->lines[i].natural; - } - - if (minimum) - *minimum = min; - - if (natural) - *natural = nat; -} - -/* Computes minimum and natural fields of lines. - * When contextual is TRUE, requires allocation of - * lines in the opposite orientation to be set. - */ -static void -clutter_grid_request_run (ClutterGridRequest *request, - ClutterOrientation orientation, - gboolean contextual) -{ - clutter_grid_request_init (request, orientation); - clutter_grid_request_non_spanning (request, orientation, contextual); - clutter_grid_request_homogeneous (request, orientation); - clutter_grid_request_spanning (request, orientation, contextual); - clutter_grid_request_homogeneous (request, orientation); -} - -typedef struct _RequestedSize -{ - gpointer data; - - gfloat minimum_size; - gfloat natural_size; -} RequestedSize; - - -/* Pulled from gtksizerequest.c from Gtk+ */ -static gint -compare_gap (gconstpointer p1, - gconstpointer p2, - gpointer data) -{ - RequestedSize *sizes = data; - const guint *c1 = p1; - const guint *c2 = p2; - - const gint d1 = MAX (sizes[*c1].natural_size - - sizes[*c1].minimum_size, - 0); - const gint d2 = MAX (sizes[*c2].natural_size - - sizes[*c2].minimum_size, - 0); - - gint delta = (d2 - d1); - - if (0 == delta) - delta = (*c2 - *c1); - - return delta; -} - -/* - * distribute_natural_allocation: - * @extra_space: Extra space to redistribute among children after subtracting - * minimum sizes and any child padding from the overall allocation - * @n_requested_sizes: Number of requests to fit into the allocation - * @sizes: An array of structs with a client pointer and a minimum/natural size - * in the orientation of the allocation. - * - * Distributes @extra_space to child @sizes by bringing smaller - * children up to natural size first. - * - * The remaining space will be added to the @minimum_size member of the - * RequestedSize struct. If all sizes reach their natural size then - * the remaining space is returned. - * - * Returns: The remainder of @extra_space after redistributing space - * to @sizes. - * - * Pulled from gtksizerequest.c from Gtk+ - */ -static gint -distribute_natural_allocation (gint extra_space, - guint n_requested_sizes, - RequestedSize *sizes) -{ - guint *spreading; - gint i; - - g_return_val_if_fail (extra_space >= 0, 0); - - spreading = g_newa (guint, n_requested_sizes); - - for (i = 0; i < n_requested_sizes; i++) - spreading[i] = i; - - /* Distribute the container's extra space c_gap. We want to assign - * this space such that the sum of extra space assigned to children - * (c^i_gap) is equal to c_cap. The case that there's not enough - * space for all children to take their natural size needs some - * attention. The goals we want to achieve are: - * - * a) Maximize number of children taking their natural size. - * b) The allocated size of children should be a continuous - * function of c_gap. That is, increasing the container size by - * one pixel should never make drastic changes in the distribution. - * c) If child i takes its natural size and child j doesn't, - * child j should have received at least as much gap as child i. - * - * The following code distributes the additional space by following - * these rules. - */ - - /* Sort descending by gap and position. */ - g_qsort_with_data (spreading, - n_requested_sizes, sizeof (guint), - compare_gap, sizes); - - /* Distribute available space. - * This master piece of a loop was conceived by Behdad Esfahbod. - */ - for (i = n_requested_sizes - 1; extra_space > 0 && i >= 0; --i) - { - /* Divide remaining space by number of remaining children. - * Sort order and reducing remaining space by assigned space - * ensures that space is distributed equally. - */ - gint glue = (extra_space + i) / (i + 1); - gint gap = sizes[(spreading[i])].natural_size - - sizes[(spreading[i])].minimum_size; - - gint extra = MIN (glue, gap); - - sizes[spreading[i]].minimum_size += extra; - - extra_space -= extra; - } - - return extra_space; -} - -/* Requires that the minimum and natural fields of lines - * have been set, computes the allocation field of lines - * by distributing total_size among lines. - */ -static void -clutter_grid_request_allocate (ClutterGridRequest *request, - ClutterOrientation orientation, - gfloat total_size) -{ - ClutterGridLayout *grid = request->grid; - ClutterGridLineData *linedata; - ClutterGridLines *lines; - ClutterGridLine *line; - gint nonempty; - gint expand; - gint i, j; - RequestedSize *sizes; - gint extra; - gint rest; - gint size; - - clutter_grid_request_compute_expand (request, orientation, &nonempty, &expand); - - if (nonempty == 0) - return; - - linedata = &grid->linedata[orientation]; - lines = &request->lines[orientation]; - - size = total_size - (nonempty - 1) * linedata->spacing; - - if (linedata->homogeneous) - { - extra = size / nonempty; - rest = size % nonempty; - - for (i = 0; i < lines->max - lines->min; i++) - { - line = &lines->lines[i]; - if (line->empty) - continue; - - line->allocation = extra; - if (rest > 0) - { - line->allocation += 1; - rest -= 1; - } - } - } - else - { - sizes = g_newa (RequestedSize, nonempty); - - j = 0; - for (i = 0; i < lines->max - lines->min; i++) - { - line = &lines->lines[i]; - if (line->empty) - continue; - - size -= line->minimum; - - sizes[j].minimum_size = line->minimum; - sizes[j].natural_size = line->natural; - sizes[j].data = line; - j++; - } - - size = distribute_natural_allocation (MAX (0, size), nonempty, sizes); - - if (expand > 0) - { - extra = size / expand; - rest = size % expand; - } - else - { - extra = 0; - rest = 0; - } - - j = 0; - for (i = 0; i < lines->max - lines->min; i++) - { - line = &lines->lines[i]; - if (line->empty) - continue; - - g_assert (line == sizes[j].data); - - line->allocation = sizes[j].minimum_size; - if (line->expand) - { - line->allocation += extra; - if (rest > 0) - { - line->allocation += 1; - rest -= 1; - } - } - - j++; - } - } -} - -/* Computes the position fields from allocation and spacing. - */ -static void -clutter_grid_request_position (ClutterGridRequest *request, - ClutterOrientation orientation) -{ - ClutterGridLayout *grid = request->grid; - ClutterGridLineData *linedata; - ClutterGridLines *lines; - ClutterGridLine *line; - gfloat position; - gint i; - - linedata = &grid->linedata[orientation]; - lines = &request->lines[orientation]; - - position = 0.f; - for (i = 0; i < lines->max - lines->min; i++) - { - line = &lines->lines[i]; - if (!line->empty) - { - line->position = position; - position += line->allocation + linedata->spacing; - } - } -} - -static void -clutter_grid_child_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterGridChild *grid_child = CLUTTER_GRID_CHILD (gobject); - ClutterLayoutManager *manager; - - manager = clutter_layout_meta_get_manager (CLUTTER_LAYOUT_META (gobject)); - - switch (prop_id) - { - case PROP_CHILD_LEFT_ATTACH: - CHILD_LEFT (grid_child) = g_value_get_int (value); - clutter_layout_manager_layout_changed (manager); - break; - - case PROP_CHILD_TOP_ATTACH: - CHILD_TOP (grid_child) = g_value_get_int (value); - clutter_layout_manager_layout_changed (manager); - break; - - case PROP_CHILD_WIDTH: - CHILD_WIDTH (grid_child) = g_value_get_int (value); - clutter_layout_manager_layout_changed (manager); - break; - - case PROP_CHILD_HEIGHT: - CHILD_HEIGHT (grid_child) = g_value_get_int (value); - clutter_layout_manager_layout_changed (manager); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_grid_child_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterGridChild *grid_child = CLUTTER_GRID_CHILD (gobject); - - switch (prop_id) - { - case PROP_CHILD_LEFT_ATTACH: - g_value_set_int (value, CHILD_LEFT (grid_child)); - break; - - case PROP_CHILD_TOP_ATTACH: - g_value_set_int (value, CHILD_TOP (grid_child)); - break; - - case PROP_CHILD_WIDTH: - g_value_set_int (value, CHILD_WIDTH (grid_child)); - break; - - case PROP_CHILD_HEIGHT: - g_value_set_int (value, CHILD_HEIGHT (grid_child)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_grid_child_class_init (ClutterGridChildClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->set_property = clutter_grid_child_set_property; - gobject_class->get_property = clutter_grid_child_get_property; - - child_props[PROP_CHILD_LEFT_ATTACH] = - g_param_spec_int ("left-attach", NULL, NULL, - -G_MAXINT, G_MAXINT, 0, - G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE); - - child_props[PROP_CHILD_TOP_ATTACH] = - g_param_spec_int ("top-attach", NULL, NULL, - -G_MAXINT, G_MAXINT, 0, - G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE); - - child_props[PROP_CHILD_WIDTH] = - g_param_spec_int ("width", NULL, NULL, - -G_MAXINT, G_MAXINT, 1, - G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE); - - child_props[PROP_CHILD_HEIGHT] = - g_param_spec_int ("height", NULL, NULL, - -G_MAXINT, G_MAXINT, 1, - G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE); - - g_object_class_install_properties (gobject_class, PROP_CHILD_LAST, - child_props); -} - -static void -clutter_grid_child_init (ClutterGridChild *self) -{ - CHILD_LEFT (self) = -1; - CHILD_TOP (self) = -1; - CHILD_WIDTH (self) = 1; - CHILD_HEIGHT (self) = 1; -} - -static void -clutter_grid_layout_set_container (ClutterLayoutManager *self, - ClutterActor *container) -{ - ClutterGridLayout *grid = CLUTTER_GRID_LAYOUT (self); - ClutterLayoutManagerClass *parent_class; - - grid->container = container; - - if (grid->container != NULL) - { - ClutterRequestMode request_mode; - - /* we need to change the :request-mode of the container - * to match the orientation - */ - request_mode = grid->orientation == CLUTTER_ORIENTATION_VERTICAL - ? CLUTTER_REQUEST_HEIGHT_FOR_WIDTH - : CLUTTER_REQUEST_WIDTH_FOR_HEIGHT; - clutter_actor_set_request_mode (CLUTTER_ACTOR (grid->container), - request_mode); - } - - parent_class = CLUTTER_LAYOUT_MANAGER_CLASS (clutter_grid_layout_parent_class); - parent_class->set_container (self, container); -} - -static void -clutter_grid_layout_get_size_for_size (ClutterGridLayout *self, - ClutterOrientation orientation, - float size, - float *minimum, - float *natural) -{ - ClutterGridRequest request; - ClutterGridLines *lines; - float min_size, nat_size; - - request.grid = self; - clutter_grid_request_update_attach (&request); - clutter_grid_request_count_lines (&request); - - lines = &request.lines[0]; - lines->lines = g_newa (ClutterGridLine, lines->max - lines->min); - memset (lines->lines, 0, (lines->max - lines->min) * sizeof (ClutterGridLine)); - - lines = &request.lines[1]; - lines->lines = g_newa (ClutterGridLine, lines->max - lines->min); - memset (lines->lines, 0, (lines->max - lines->min) * sizeof (ClutterGridLine)); - - clutter_grid_request_run (&request, 1 - orientation, FALSE); - clutter_grid_request_sum (&request, 1 - orientation, &min_size, &nat_size); - clutter_grid_request_allocate (&request, 1 - orientation, MAX (size, nat_size)); - - clutter_grid_request_run (&request, orientation, TRUE); - clutter_grid_request_sum (&request, orientation, minimum, natural); -} - -static void -clutter_grid_layout_get_preferred_width (ClutterLayoutManager *manager, - ClutterActor *container, - gfloat for_height, - gfloat *min_width_p, - gfloat *nat_width_p) -{ - ClutterGridLayout *self = CLUTTER_GRID_LAYOUT (manager); - - if (min_width_p) - *min_width_p = 0.0f; - if (nat_width_p) - *nat_width_p = 0.0f; - - clutter_grid_layout_get_size_for_size (self, CLUTTER_ORIENTATION_HORIZONTAL, - for_height, - min_width_p, nat_width_p); -} - -static void -clutter_grid_layout_get_preferred_height (ClutterLayoutManager *manager, - ClutterActor *container, - gfloat for_width, - gfloat *min_height_p, - gfloat *nat_height_p) -{ - ClutterGridLayout *self = CLUTTER_GRID_LAYOUT (manager); - - if (min_height_p) - *min_height_p = 0.0f; - if (nat_height_p) - *nat_height_p = 0.0f; - - clutter_grid_layout_get_size_for_size (self, CLUTTER_ORIENTATION_VERTICAL, - for_width, - min_height_p, nat_height_p); -} - -static void -allocate_child (ClutterGridRequest *request, - ClutterOrientation orientation, - ClutterGridChild *child, - gfloat *position, - gfloat *size) -{ - ClutterGridLayout *grid = request->grid; - ClutterGridLineData *linedata; - ClutterGridLines *lines; - ClutterGridLine *line; - ClutterGridAttach *attach; - gint i; - - linedata = &grid->linedata[orientation]; - lines = &request->lines[orientation]; - attach = &child->attach[orientation]; - - *position = lines->lines[attach->pos - lines->min].position; - - *size = (attach->span - 1) * linedata->spacing; - for (i = 0; i < attach->span; i++) - { - line = &lines->lines[attach->pos - lines->min + i]; - *size += line->allocation; - } -} - -#define GET_SIZE(allocation, orientation) \ - (orientation == CLUTTER_ORIENTATION_HORIZONTAL \ - ? clutter_actor_box_get_width ((allocation)) \ - : clutter_actor_box_get_height ((allocation))) - -static void -clutter_grid_layout_allocate (ClutterLayoutManager *layout, - ClutterActor *container, - const ClutterActorBox *allocation) -{ - ClutterGridLayout *self = CLUTTER_GRID_LAYOUT (layout); - ClutterOrientation orientation; - ClutterGridRequest request; - ClutterGridLines *lines; - ClutterActorIter iter; - ClutterActor *child; - - request.grid = self; - - clutter_grid_request_update_attach (&request); - clutter_grid_request_count_lines (&request); - lines = &request.lines[0]; - lines->lines = g_newa (ClutterGridLine, lines->max - lines->min); - memset (lines->lines, 0, (lines->max - lines->min) * sizeof (ClutterGridLine)); - lines = &request.lines[1]; - lines->lines = g_newa (ClutterGridLine, lines->max - lines->min); - memset (lines->lines, 0, (lines->max - lines->min) * sizeof (ClutterGridLine)); - - if (clutter_actor_get_request_mode (CLUTTER_ACTOR (container)) == CLUTTER_REQUEST_WIDTH_FOR_HEIGHT) - orientation = CLUTTER_ORIENTATION_HORIZONTAL; - else - orientation = CLUTTER_ORIENTATION_VERTICAL; - - clutter_grid_request_run (&request, 1 - orientation, FALSE); - clutter_grid_request_allocate (&request, 1 - orientation, GET_SIZE (allocation, 1 - orientation)); - clutter_grid_request_run (&request, orientation, TRUE); - - clutter_grid_request_allocate (&request, orientation, GET_SIZE (allocation, orientation)); - - clutter_grid_request_position (&request, 0); - clutter_grid_request_position (&request, 1); - - clutter_actor_iter_init (&iter, CLUTTER_ACTOR (container)); - while (clutter_actor_iter_next (&iter, &child)) - { - ClutterActorBox child_allocation; - gfloat x, y, width, height; - ClutterGridChild *grid_child; - - if (!clutter_actor_is_visible (child)) - continue; - - grid_child = GET_GRID_CHILD (self, child); - allocate_child (&request, CLUTTER_ORIENTATION_HORIZONTAL, grid_child, - &x, &width); - allocate_child (&request, CLUTTER_ORIENTATION_VERTICAL, grid_child, - &y, &height); - x += allocation->x1; - y += allocation->y1; - - CLUTTER_NOTE (LAYOUT, "Allocation for %s { %.2f, %.2f - %.2f x %.2f }", - _clutter_actor_get_debug_name (child), - x, y, width, height); - - child_allocation.x1 = x; - child_allocation.y1 = y; - child_allocation.x2 = child_allocation.x1 + width; - child_allocation.y2 = child_allocation.y1 + height; - - clutter_actor_allocate (child, &child_allocation); - } -} - -static GType -clutter_grid_layout_get_child_meta_type (ClutterLayoutManager *self) -{ - return CLUTTER_TYPE_GRID_CHILD; -} - -static void -clutter_grid_layout_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterGridLayout *self = CLUTTER_GRID_LAYOUT (gobject); - - switch (prop_id) - { - case PROP_ORIENTATION: - clutter_grid_layout_set_orientation (self, g_value_get_enum (value)); - break; - - case PROP_ROW_SPACING: - clutter_grid_layout_set_row_spacing (self, g_value_get_uint (value)); - break; - - case PROP_COLUMN_SPACING: - clutter_grid_layout_set_column_spacing (self, g_value_get_uint (value)); - break; - - case PROP_ROW_HOMOGENEOUS: - clutter_grid_layout_set_row_homogeneous (self, - g_value_get_boolean (value)); - break; - - case PROP_COLUMN_HOMOGENEOUS: - clutter_grid_layout_set_column_homogeneous (self, - g_value_get_boolean (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_grid_layout_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterGridLayout *self = CLUTTER_GRID_LAYOUT (gobject); - - switch (prop_id) - { - case PROP_ORIENTATION: - g_value_set_enum (value, self->orientation); - break; - - case PROP_ROW_SPACING: - g_value_set_uint (value, COLUMNS (self)->spacing); - break; - - case PROP_COLUMN_SPACING: - g_value_set_uint (value, ROWS (self)->spacing); - break; - - case PROP_ROW_HOMOGENEOUS: - g_value_set_boolean (value, COLUMNS (self)->homogeneous); - break; - - case PROP_COLUMN_HOMOGENEOUS: - g_value_set_boolean (value, ROWS (self)->homogeneous); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_grid_layout_class_init (ClutterGridLayoutClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - ClutterLayoutManagerClass *layout_class; - - layout_class = CLUTTER_LAYOUT_MANAGER_CLASS (klass); - - object_class->set_property = clutter_grid_layout_set_property; - object_class->get_property = clutter_grid_layout_get_property; - - layout_class->set_container = clutter_grid_layout_set_container; - layout_class->get_preferred_width = clutter_grid_layout_get_preferred_width; - layout_class->get_preferred_height = clutter_grid_layout_get_preferred_height; - layout_class->allocate = clutter_grid_layout_allocate; - layout_class->get_child_meta_type = clutter_grid_layout_get_child_meta_type; - - /** - * ClutterGridLayout:orientation: - * - * The orientation of the layout, either horizontal or vertical - */ - obj_props[PROP_ORIENTATION] = - g_param_spec_enum ("orientation", NULL, NULL, - CLUTTER_TYPE_ORIENTATION, - CLUTTER_ORIENTATION_HORIZONTAL, - G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE); - - /** - * ClutterGridLayout:row-spacing: - * - * The amount of space in pixels between two consecutive rows - */ - obj_props[PROP_ROW_SPACING] = - g_param_spec_uint ("row-spacing", NULL, NULL, - 0, G_MAXUINT, 0, - G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE); - - /** - * ClutterGridLayout:column-spacing: - * - * The amount of space in pixels between two consecutive columns - */ - obj_props[PROP_COLUMN_SPACING] = - g_param_spec_uint ("column-spacing", NULL, NULL, - 0, G_MAXUINT, 0, - G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE); - - /** - * ClutterGridLayout:row-homogeneous: - * - * Whether all rows of the layout should have the same height - */ - obj_props[PROP_ROW_HOMOGENEOUS] = - g_param_spec_boolean ("row-homogeneous", NULL, NULL, - FALSE, - G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE); - - /** - * ClutterGridLayout:column-homogeneous: - * - * Whether all columns of the layout should have the same width - */ - obj_props[PROP_COLUMN_HOMOGENEOUS] = - g_param_spec_boolean ("column-homogeneous", NULL, NULL, - FALSE, - G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE); - - g_object_class_install_properties (object_class, PROP_LAST, obj_props); -} - -static void -clutter_grid_layout_init (ClutterGridLayout *self) -{ - self->orientation = CLUTTER_ORIENTATION_HORIZONTAL; - - self->linedata[0].spacing = 0; - self->linedata[1].spacing = 0; - - self->linedata[0].homogeneous = FALSE; - self->linedata[1].homogeneous = FALSE; -} - -/** - * clutter_grid_layout_new: - * - * Creates a new #ClutterGridLayout - * - * Return value: the new #ClutterGridLayout - */ -ClutterLayoutManager * -clutter_grid_layout_new (void) -{ - return g_object_new (CLUTTER_TYPE_GRID_LAYOUT, NULL); -} - -/** - * clutter_grid_layout_attach: - * @layout: a #ClutterGridLayout - * @child: the #ClutterActor to add - * @left: the column number to attach the left side of @child to - * @top: the row number to attach the top side of @child to - * @width: the number of columns that @child will span - * @height: the number of rows that @child will span - * - * Adds a widget to the grid. - * - * The position of @child is determined by @left and @top. The - * number of 'cells' that @child will occupy is determined by - * @width and @height. - */ -void -clutter_grid_layout_attach (ClutterGridLayout *layout, - ClutterActor *child, - gint left, - gint top, - gint width, - gint height) -{ - g_return_if_fail (CLUTTER_IS_GRID_LAYOUT (layout)); - - if (!layout->container) - return; - - grid_attach (layout, child, left, top, width, height); - clutter_actor_add_child (CLUTTER_ACTOR (layout->container), child); -} - -/** - * clutter_grid_layout_attach_next_to: - * @layout: a #ClutterGridLayout - * @child: the actor to add - * @sibling: (allow-none): the child of @layout that @child will be placed - * next to, or %NULL to place @child at the beginning or end - * @side: the side of @sibling that @child is positioned next to - * @width: the number of columns that @child will span - * @height: the number of rows that @child will span - * - * Adds a actor to the grid. - * - * The actor is placed next to @sibling, on the side determined by - * @side. When @sibling is %NULL, the actor is placed in row (for - * left or right placement) or column 0 (for top or bottom placement), - * at the end indicated by @side. - * - * Attaching widgets labeled [1], [2], [3] with @sibling == %NULL and - * @side == %CLUTTER_GRID_POSITION_LEFT yields a layout of [3][2][1]. - */ -void -clutter_grid_layout_attach_next_to (ClutterGridLayout *layout, - ClutterActor *child, - ClutterActor *sibling, - ClutterGridPosition side, - gint width, - gint height) -{ - g_return_if_fail (CLUTTER_IS_GRID_LAYOUT (layout)); - g_return_if_fail (CLUTTER_IS_ACTOR (child)); - g_return_if_fail (clutter_actor_get_parent (child) == NULL); - g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling)); - g_return_if_fail (width > 0); - g_return_if_fail (height > 0); - - if (!layout->container) - return; - - grid_attach_next_to (layout, child, sibling, side, width, height); - clutter_actor_add_child (CLUTTER_ACTOR (layout->container), child); -} - -/** - * clutter_grid_layout_set_orientation: - * @layout: a #ClutterGridLayout - * @orientation: the orientation of the #ClutterGridLayout - * - * Sets the orientation of the @layout. - * - * #ClutterGridLayout uses the orientation as a hint when adding - * children to the #ClutterActor using it as a layout manager via - * [method@Clutter.Actor.add_child]; changing this value will not have - * any effect on children that are already part of the layout. - */ -void -clutter_grid_layout_set_orientation (ClutterGridLayout *layout, - ClutterOrientation orientation) -{ - g_return_if_fail (CLUTTER_IS_GRID_LAYOUT (layout)); - - if (layout->orientation != orientation) - { - layout->orientation = orientation; - - clutter_layout_manager_layout_changed (CLUTTER_LAYOUT_MANAGER (layout)); - g_object_notify_by_pspec (G_OBJECT (layout), obj_props[PROP_ORIENTATION]); - } -} - -/** - * clutter_grid_layout_get_child_at: - * @layout: a #ClutterGridLayout - * @left: the left edge of the cell - * @top: the top edge of the cell - * - * Gets the child of @layout whose area covers the grid - * cell whose upper left corner is at @left, @top. - * - * Returns: (transfer none): the child at the given position, or %NULL - */ -ClutterActor * -clutter_grid_layout_get_child_at (ClutterGridLayout *layout, - gint left, - gint top) -{ - ClutterGridChild *grid_child; - ClutterActorIter iter; - ClutterActor *child; - - g_return_val_if_fail (CLUTTER_IS_GRID_LAYOUT (layout), NULL); - - if (!layout->container) - return NULL; - - clutter_actor_iter_init (&iter, CLUTTER_ACTOR (layout->container)); - while (clutter_actor_iter_next (&iter, &child)) - { - grid_child = GET_GRID_CHILD (layout, child); - - if (CHILD_LEFT (grid_child) <= left && - CHILD_LEFT (grid_child) + CHILD_WIDTH (grid_child) > left && - CHILD_TOP (grid_child) <= top && - CHILD_TOP (grid_child) + CHILD_HEIGHT (grid_child) > top) - return child; - } - - return NULL; -} - -/** - * clutter_grid_layout_insert_row: - * @layout: a #ClutterGridLayout - * @position: the position to insert the row at - * - * Inserts a row at the specified position. - * - * Children which are attached at or below this position - * are moved one row down. Children which span across this - * position are grown to span the new row. - */ -void -clutter_grid_layout_insert_row (ClutterGridLayout *layout, - gint position) -{ - ClutterGridChild *grid_child; - ClutterActorIter iter; - ClutterActor *child; - gint top, height; - - g_return_if_fail (CLUTTER_IS_GRID_LAYOUT (layout)); - - if (!layout->container) - return; - - clutter_actor_iter_init (&iter, CLUTTER_ACTOR (layout->container)); - while (clutter_actor_iter_next (&iter, &child)) - { - grid_child = GET_GRID_CHILD (layout, child); - - top = CHILD_TOP (grid_child); - height = CHILD_HEIGHT (grid_child); - - if (top >= position) - { - CHILD_TOP (grid_child) = top + 1; - g_object_notify_by_pspec (G_OBJECT (grid_child), - child_props[PROP_CHILD_TOP_ATTACH]); - } - else if (top + height > position) - { - CHILD_HEIGHT (grid_child) = height + 1; - g_object_notify_by_pspec (G_OBJECT (grid_child), - child_props[PROP_CHILD_HEIGHT]); - } - } - clutter_layout_manager_layout_changed (CLUTTER_LAYOUT_MANAGER (layout)); -} - -/** - * clutter_grid_layout_insert_column: - * @layout: a #ClutterGridLayout - * @position: the position to insert the column at - * - * Inserts a column at the specified position. - * - * Children which are attached at or to the right of this position - * are moved one column to the right. Children which span across this - * position are grown to span the new column. - */ -void -clutter_grid_layout_insert_column (ClutterGridLayout *layout, - gint position) -{ - ClutterGridChild *grid_child; - ClutterActorIter iter; - ClutterActor *child; - gint left, width; - - g_return_if_fail (CLUTTER_IS_GRID_LAYOUT (layout)); - - if (!layout->container) - return; - - clutter_actor_iter_init (&iter, CLUTTER_ACTOR (layout->container)); - while (clutter_actor_iter_next (&iter, &child)) - { - grid_child = GET_GRID_CHILD (layout, child); - - left = CHILD_LEFT (grid_child); - width = CHILD_WIDTH (grid_child); - - if (left >= position) - { - CHILD_LEFT (grid_child) = left + 1; - g_object_notify_by_pspec (G_OBJECT (grid_child), - child_props[PROP_CHILD_LEFT_ATTACH]); - } - else if (left + width > position) - { - CHILD_WIDTH (grid_child) = width + 1; - g_object_notify_by_pspec (G_OBJECT (grid_child), - child_props[PROP_CHILD_WIDTH]); - } - } - clutter_layout_manager_layout_changed (CLUTTER_LAYOUT_MANAGER (layout)); -} - -/** - * clutter_grid_layout_insert_next_to: - * @layout: a #ClutterGridLayout - * @sibling: the child of @layout that the new row or column will be - * placed next to - * @side: the side of @sibling that @child is positioned next to - * - * Inserts a row or column at the specified position. - * - * The new row or column is placed next to @sibling, on the side - * determined by @side. If @side is %CLUTTER_GRID_POSITION_LEFT or - * %CLUTTER_GRID_POSITION_BOTTOM, a row is inserted. If @side is - * %CLUTTER_GRID_POSITION_LEFT of %CLUTTER_GRID_POSITION_RIGHT, - * a column is inserted. - */ -void -clutter_grid_layout_insert_next_to (ClutterGridLayout *layout, - ClutterActor *sibling, - ClutterGridPosition side) -{ - ClutterGridChild *grid_child; - - g_return_if_fail (CLUTTER_IS_GRID_LAYOUT (layout)); - g_return_if_fail (CLUTTER_IS_ACTOR (sibling)); - - grid_child = GET_GRID_CHILD (layout, sibling); - - switch (side) - { - case CLUTTER_GRID_POSITION_LEFT: - clutter_grid_layout_insert_column (layout, CHILD_LEFT (grid_child)); - break; - - case CLUTTER_GRID_POSITION_RIGHT: - clutter_grid_layout_insert_column (layout, CHILD_LEFT (grid_child) + - CHILD_WIDTH (grid_child)); - break; - - case CLUTTER_GRID_POSITION_TOP: - clutter_grid_layout_insert_row (layout, CHILD_TOP (grid_child)); - break; - - case CLUTTER_GRID_POSITION_BOTTOM: - clutter_grid_layout_insert_row (layout, CHILD_TOP (grid_child) + - CHILD_HEIGHT (grid_child)); - break; - - default: - g_assert_not_reached (); - } -} - -/** - * clutter_grid_layout_get_orientation: - * @layout: a #ClutterGridLayout - * - * Retrieves the orientation of the @layout. - * - * Return value: the orientation of the layout - */ -ClutterOrientation -clutter_grid_layout_get_orientation (ClutterGridLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_GRID_LAYOUT (layout), - CLUTTER_ORIENTATION_HORIZONTAL); - - return layout->orientation; -} - -/** - * clutter_grid_layout_set_row_spacing: - * @layout: a #ClutterGridLayout - * @spacing: the spacing between rows of the layout, in pixels - * - * Sets the spacing between rows of @layout - */ -void -clutter_grid_layout_set_row_spacing (ClutterGridLayout *layout, - guint spacing) -{ - g_return_if_fail (CLUTTER_IS_GRID_LAYOUT (layout)); - - if (COLUMNS (layout)->spacing != spacing) - { - COLUMNS (layout)->spacing = spacing; - - clutter_layout_manager_layout_changed (CLUTTER_LAYOUT_MANAGER (layout)); - g_object_notify_by_pspec (G_OBJECT (layout), - obj_props[PROP_ROW_SPACING]); - } -} - -/** - * clutter_grid_layout_get_row_spacing: - * @layout: a #ClutterGridLayout - * - * Retrieves the spacing set using [method@Clutter.GridLayout.set_row_spacing] - * - * Return value: the spacing between rows of @layout - */ -guint -clutter_grid_layout_get_row_spacing (ClutterGridLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_GRID_LAYOUT (layout), 0); - - return COLUMNS (layout)->spacing; -} - -/** - * clutter_grid_layout_set_column_spacing: - * @layout: a #ClutterGridLayout - * @spacing: the spacing between columns of the layout, in pixels - * - * Sets the spacing between columns of @layout - */ -void -clutter_grid_layout_set_column_spacing (ClutterGridLayout *layout, - guint spacing) -{ - g_return_if_fail (CLUTTER_IS_GRID_LAYOUT (layout)); - - if (ROWS (layout)->spacing != spacing) - { - ROWS (layout)->spacing = spacing; - - clutter_layout_manager_layout_changed (CLUTTER_LAYOUT_MANAGER (layout)); - g_object_notify_by_pspec (G_OBJECT (layout), - obj_props[PROP_COLUMN_SPACING]); - } -} - -/** - * clutter_grid_layout_get_column_spacing: - * @layout: a #ClutterGridLayout - * - * Retrieves the spacing set using [method@Clutter.GridLayout.set_column_spacing] - * - * Return value: the spacing between coluns of @layout - */ -guint -clutter_grid_layout_get_column_spacing (ClutterGridLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_GRID_LAYOUT (layout), 0); - - return ROWS (layout)->spacing; -} - -/** - * clutter_grid_layout_set_column_homogeneous: - * @layout: a #ClutterGridLayout - * @homogeneous: %TRUE to make columns homogeneous - * - * Sets whether all columns of @layout will have the same width. - */ -void -clutter_grid_layout_set_column_homogeneous (ClutterGridLayout *layout, - gboolean homogeneous) -{ - g_return_if_fail (CLUTTER_IS_GRID_LAYOUT (layout)); - - if (ROWS (layout)->homogeneous != homogeneous) - { - ROWS (layout)->homogeneous = homogeneous; - - clutter_layout_manager_layout_changed (CLUTTER_LAYOUT_MANAGER (layout)); - g_object_notify_by_pspec (G_OBJECT (layout), - obj_props[PROP_COLUMN_HOMOGENEOUS]); - } -} - -/** - * clutter_grid_layout_get_column_homogeneous: - * @layout: a #ClutterGridLayout - * - * Returns whether all columns of @layout have the same width. - * - * Returns: whether all columns of @layout have the same width. - */ -gboolean -clutter_grid_layout_get_column_homogeneous (ClutterGridLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_GRID_LAYOUT (layout), FALSE); - - return ROWS (layout)->homogeneous; -} - -/** - * clutter_grid_layout_set_row_homogeneous: - * @layout: a #ClutterGridLayout - * @homogeneous: %TRUE to make rows homogeneous - * - * Sets whether all rows of @layout will have the same height. - */ -void -clutter_grid_layout_set_row_homogeneous (ClutterGridLayout *layout, - gboolean homogeneous) -{ - g_return_if_fail (CLUTTER_IS_GRID_LAYOUT (layout)); - - if (COLUMNS (layout)->homogeneous != homogeneous) - { - COLUMNS (layout)->homogeneous = homogeneous; - - clutter_layout_manager_layout_changed (CLUTTER_LAYOUT_MANAGER (layout)); - g_object_notify_by_pspec (G_OBJECT (layout), - obj_props[PROP_ROW_HOMOGENEOUS]); - } -} - -/** - * clutter_grid_layout_get_row_homogeneous: - * @layout: a #ClutterGridLayout - * - * Returns whether all rows of @layout have the same height. - * - * Returns: whether all rows of @layout have the same height. - */ -gboolean -clutter_grid_layout_get_row_homogeneous (ClutterGridLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_GRID_LAYOUT (layout), FALSE); - - return COLUMNS (layout)->homogeneous; -} diff --git a/mutter/clutter/clutter/clutter-grid-layout.h b/mutter/clutter/clutter/clutter-grid-layout.h deleted file mode 100644 index 79832c3..0000000 --- a/mutter/clutter/clutter/clutter-grid-layout.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Red Hat, Inc. - * Copyright (C) 2012 Bastian Winkler - * - * 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 . - * - * Author: - * Bastian Winkler - * - * Based on GtkGrid widget by: - * Matthias Clasen - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-layout-manager.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_GRID_LAYOUT (clutter_grid_layout_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_FINAL_TYPE (ClutterGridLayout, - clutter_grid_layout, - CLUTTER, GRID_LAYOUT, - ClutterLayoutManager) - -CLUTTER_EXPORT -ClutterLayoutManager * clutter_grid_layout_new (void); - -CLUTTER_EXPORT -void clutter_grid_layout_attach (ClutterGridLayout *layout, - ClutterActor *child, - gint left, - gint top, - gint width, - gint height); - -CLUTTER_EXPORT -void clutter_grid_layout_attach_next_to (ClutterGridLayout *layout, - ClutterActor *child, - ClutterActor *sibling, - ClutterGridPosition side, - gint width, - gint height); - -CLUTTER_EXPORT -ClutterActor * clutter_grid_layout_get_child_at (ClutterGridLayout *layout, - gint left, - gint top); - -CLUTTER_EXPORT -void clutter_grid_layout_insert_row (ClutterGridLayout *layout, - gint position); - -CLUTTER_EXPORT -void clutter_grid_layout_insert_column (ClutterGridLayout *layout, - gint position); - -CLUTTER_EXPORT -void clutter_grid_layout_insert_next_to (ClutterGridLayout *layout, - ClutterActor *sibling, - ClutterGridPosition side); - -CLUTTER_EXPORT -void clutter_grid_layout_set_orientation (ClutterGridLayout *layout, - ClutterOrientation orientation); - -CLUTTER_EXPORT -ClutterOrientation clutter_grid_layout_get_orientation (ClutterGridLayout *layout); - -CLUTTER_EXPORT -void clutter_grid_layout_set_column_spacing (ClutterGridLayout *layout, - guint spacing); - -CLUTTER_EXPORT -guint clutter_grid_layout_get_column_spacing (ClutterGridLayout *layout); - -CLUTTER_EXPORT -void clutter_grid_layout_set_row_spacing (ClutterGridLayout *layout, - guint spacing); - -CLUTTER_EXPORT -guint clutter_grid_layout_get_row_spacing (ClutterGridLayout *layout); - -CLUTTER_EXPORT -void clutter_grid_layout_set_column_homogeneous (ClutterGridLayout *layout, - gboolean homogeneous); - -CLUTTER_EXPORT -gboolean clutter_grid_layout_get_column_homogeneous (ClutterGridLayout *layout); - - -CLUTTER_EXPORT -void clutter_grid_layout_set_row_homogeneous (ClutterGridLayout *layout, - gboolean homogeneous); - -CLUTTER_EXPORT -gboolean clutter_grid_layout_get_row_homogeneous (ClutterGridLayout *layout); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-image.c b/mutter/clutter/clutter/clutter-image.c deleted file mode 100644 index 7e9f9bc..0000000 --- a/mutter/clutter/clutter/clutter-image.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive image' library. - * - * Copyright (C) 2012 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterImage: - * - * Image data content - * - * #ClutterImage is a #ClutterContent implementation that displays - * image data inside a [class@Actor]. - */ - -#include "config.h" - -#include "clutter/clutter-image.h" - -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-color.h" -#include "clutter/clutter-content-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-paint-node.h" -#include "clutter/clutter-paint-nodes.h" -#include "clutter/clutter-private.h" - -typedef struct -{ - CoglTexture *texture; - gint width; - gint height; -} ClutterImagePrivate; - -static void clutter_content_iface_init (ClutterContentInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (ClutterImage, clutter_image, G_TYPE_OBJECT, - G_ADD_PRIVATE (ClutterImage) - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT, - clutter_content_iface_init)) - -static CoglTexture * -create_texture_from_data (unsigned int width, - unsigned int height, - CoglPixelFormat pixel_format, - unsigned int row_stride, - const uint8_t *data, - GError **error) -{ - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - CoglTexture *texture_2d; - - texture_2d = cogl_texture_2d_new_from_data (ctx, - width, - height, - pixel_format, - row_stride, - data, - error); - - return texture_2d; -} - -static void -update_image_size (ClutterImage *self) -{ - ClutterImagePrivate *priv = clutter_image_get_instance_private (self); - gint width, height; - - if (priv->texture == NULL) - return; - - width = cogl_texture_get_width (priv->texture); - height = cogl_texture_get_height (priv->texture); - - if (priv->width == width && - priv->height == height) - return; - - priv->width = width; - priv->height = height; - - clutter_content_invalidate_size (CLUTTER_CONTENT (self)); -} - -static void -clutter_image_finalize (GObject *gobject) -{ - ClutterImage *image = CLUTTER_IMAGE (gobject); - ClutterImagePrivate *priv = clutter_image_get_instance_private (image); - - g_clear_object (&priv->texture); - - G_OBJECT_CLASS (clutter_image_parent_class)->finalize (gobject); -} - -static void -clutter_image_class_init (ClutterImageClass *klass) -{ - G_OBJECT_CLASS (klass)->finalize = clutter_image_finalize; -} - -static void -clutter_image_init (ClutterImage *self) -{ -} - -static void -clutter_image_paint_content (ClutterContent *content, - ClutterActor *actor, - ClutterPaintNode *root, - ClutterPaintContext *paint_context) -{ - ClutterImage *image = CLUTTER_IMAGE (content); - ClutterImagePrivate *priv = clutter_image_get_instance_private (image); - ClutterPaintNode *node; - - if (priv->texture == NULL) - return; - - node = clutter_actor_create_texture_paint_node (actor, priv->texture); - clutter_paint_node_set_static_name (node, "Image Content"); - clutter_paint_node_add_child (root, node); - clutter_paint_node_unref (node); -} - -static gboolean -clutter_image_get_preferred_size (ClutterContent *content, - gfloat *width, - gfloat *height) -{ - ClutterImage *image = CLUTTER_IMAGE (content); - ClutterImagePrivate *priv = clutter_image_get_instance_private (image); - - if (priv->texture == NULL) - return FALSE; - - if (width != NULL) - *width = cogl_texture_get_width (priv->texture); - - if (height != NULL) - *height = cogl_texture_get_height (priv->texture); - - return TRUE; -} - -static void -clutter_content_iface_init (ClutterContentInterface *iface) -{ - iface->get_preferred_size = clutter_image_get_preferred_size; - iface->paint_content = clutter_image_paint_content; -} - -/** - * clutter_image_new: - * - * Creates a new #ClutterImage instance. - * - * Return value: (transfer full): the newly created #ClutterImage instance. - * Use g_object_unref() when done. - */ -ClutterContent * -clutter_image_new (void) -{ - return g_object_new (CLUTTER_TYPE_IMAGE, NULL); -} - -/** - * clutter_image_set_data: - * @image: a #ClutterImage - * @data: (array): the image data, as an array of bytes - * @pixel_format: the Cogl pixel format of the image data - * @width: the width of the image data - * @height: the height of the image data - * @row_stride: the length of each row inside @data - * @error: return location for a #GError, or %NULL - * - * Sets the image data to be displayed by @image. - * - * If the image data was successfully loaded, the @image will be invalidated. - * - * In case of error, the @error value will be set, and this function will - * return %FALSE. - * - * The image data is copied in texture memory. - * - * The image data is expected to be a linear array of RGBA or RGB pixel data; - * how to retrieve that data is left to platform specific image loaders. For - * instance, if you use the GdkPixbuf library: - * - * ```c - * ClutterContent *image = clutter_image_new (); - * - * GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (filename, NULL); - * - * clutter_image_set_data (CLUTTER_IMAGE (image), - * gdk_pixbuf_get_pixels (pixbuf), - * gdk_pixbuf_get_has_alpha (pixbuf) - * ? COGL_PIXEL_FORMAT_RGBA_8888 - * : COGL_PIXEL_FORMAT_RGB_888, - * gdk_pixbuf_get_width (pixbuf), - * gdk_pixbuf_get_height (pixbuf), - * gdk_pixbuf_get_rowstride (pixbuf), - * &error); - * - * g_object_unref (pixbuf); - * ``` - * - * Return value: %TRUE if the image data was successfully loaded, - * and %FALSE otherwise. - */ -gboolean -clutter_image_set_data (ClutterImage *image, - const guint8 *data, - CoglPixelFormat pixel_format, - guint width, - guint height, - guint row_stride, - GError **error) -{ - ClutterImagePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_IMAGE (image), FALSE); - g_return_val_if_fail (data != NULL, FALSE); - - priv = clutter_image_get_instance_private (image); - - if (priv->texture != NULL) - g_object_unref (priv->texture); - - priv->texture = create_texture_from_data (width, - height, - pixel_format, - row_stride, - data, - error); - - if (priv->texture == NULL) - return FALSE; - - clutter_content_invalidate (CLUTTER_CONTENT (image)); - update_image_size (image); - - return TRUE; -} - -/** - * clutter_image_set_bytes: - * @image: a #ClutterImage - * @data: the image data, as a #GBytes - * @pixel_format: the Cogl pixel format of the image data - * @width: the width of the image data - * @height: the height of the image data - * @row_stride: the length of each row inside @data - * @error: return location for a #GError, or %NULL - * - * Sets the image data stored inside a #GBytes to be displayed by @image. - * - * If the image data was successfully loaded, the @image will be invalidated. - * - * In case of error, the @error value will be set, and this function will - * return %FALSE. - * - * The image data contained inside the #GBytes is copied in texture memory, - * and no additional reference is acquired on the @data. - * - * Return value: %TRUE if the image data was successfully loaded, - * and %FALSE otherwise. - */ -gboolean -clutter_image_set_bytes (ClutterImage *image, - GBytes *data, - CoglPixelFormat pixel_format, - guint width, - guint height, - guint row_stride, - GError **error) -{ - ClutterImagePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_IMAGE (image), FALSE); - g_return_val_if_fail (data != NULL, FALSE); - - priv = clutter_image_get_instance_private (image); - - if (priv->texture != NULL) - g_object_unref (priv->texture); - - priv->texture = create_texture_from_data (width, - height, - pixel_format, - row_stride, - g_bytes_get_data (data, NULL), - error); - - if (priv->texture == NULL) - return FALSE; - - clutter_content_invalidate (CLUTTER_CONTENT (image)); - update_image_size (image); - - return TRUE; -} - -/** - * clutter_image_set_area: - * @image: a #ClutterImage - * @data: (array): the image data, as an array of bytes - * @pixel_format: the Cogl pixel format of the image data - * @rect: a rectangle indicating the area that should be set - * @row_stride: the length of each row inside @data - * @error: return location for a #GError, or %NULL - * - * Sets the image data to be display by @image, using @rect to indicate - * the position and size of the image data to be set. - * - * If the @image does not have any image data set when this function is - * called, a new texture will be created with the size of the width and - * height of the rectangle, i.e. calling this function on a newly created - * #ClutterImage will be the equivalent of calling [method@Clutter.Image.set_data]. - * - * If the image data was successfully loaded, the @image will be invalidated. - * - * In case of error, the @error value will be set, and this function will - * return %FALSE. - * - * The image data is copied in texture memory. - * - * Return value: %TRUE if the image data was successfully loaded, - * and %FALSE otherwise. - */ -gboolean -clutter_image_set_area (ClutterImage *image, - const guint8 *data, - CoglPixelFormat pixel_format, - const MtkRectangle *area, - guint row_stride, - GError **error) -{ - ClutterImagePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_IMAGE (image), FALSE); - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (area != NULL, FALSE); - - priv = clutter_image_get_instance_private (image); - - if (priv->texture == NULL) - { - priv->texture = create_texture_from_data (area->width, - area->height, - pixel_format, - row_stride, - data, - error); - } - else - { - gboolean res; - - res = cogl_texture_set_region (priv->texture, - 0, 0, - area->x, area->y, - area->width, area->height, - area->width, area->height, - pixel_format, - row_stride, - data); - - if (!res) - { - g_clear_object (&priv->texture); - } - } - - if (priv->texture == NULL) - return FALSE; - - clutter_content_invalidate (CLUTTER_CONTENT (image)); - update_image_size (image); - - return TRUE; -} - -/** - * clutter_image_get_texture: - * @image: a #ClutterImage - * - * Retrieves a pointer to the Cogl texture used by @image. - * - * If you change the contents of the returned Cogl texture you will need - * to manually invalidate the @image with [method@Clutter.Content.invalidate] - * in order to update the actors using @image as their content. - * - * Return value: (transfer none): a pointer to the Cogl texture, or %NULL - */ -CoglTexture * -clutter_image_get_texture (ClutterImage *image) -{ - ClutterImagePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_IMAGE (image), NULL); - - priv = clutter_image_get_instance_private (image); - return priv->texture; -} diff --git a/mutter/clutter/clutter/clutter-image.h b/mutter/clutter/clutter/clutter-image.h deleted file mode 100644 index fcdee35..0000000 --- a/mutter/clutter/clutter/clutter-image.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive image' library. - * - * Copyright (C) 2012 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl.h" -#include "clutter/clutter-types.h" -#include "mtk/mtk.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_IMAGE (clutter_image_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterImage, clutter_image, CLUTTER, IMAGE, GObject) - -/** - * ClutterImageClass: - * - * The #ClutterImageClass structure contains - * private data. - */ -struct _ClutterImageClass -{ - /*< private >*/ - GObjectClass parent_class; -}; - -CLUTTER_EXPORT -ClutterContent * clutter_image_new (void); -CLUTTER_EXPORT -gboolean clutter_image_set_data (ClutterImage *image, - const guint8 *data, - CoglPixelFormat pixel_format, - guint width, - guint height, - guint row_stride, - GError **error); -CLUTTER_EXPORT -gboolean clutter_image_set_area (ClutterImage *image, - const guint8 *data, - CoglPixelFormat pixel_format, - const MtkRectangle *rect, - guint row_stride, - GError **error); -CLUTTER_EXPORT -gboolean clutter_image_set_bytes (ClutterImage *image, - GBytes *data, - CoglPixelFormat pixel_format, - guint width, - guint height, - guint row_stride, - GError **error); - -CLUTTER_EXPORT -CoglTexture * clutter_image_get_texture (ClutterImage *image); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-input-device-private.h b/mutter/clutter/clutter/clutter-input-device-private.h deleted file mode 100644 index d097108..0000000 --- a/mutter/clutter/clutter/clutter-input-device-private.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2009, 2010, 2011 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-input-device.h" - -G_BEGIN_DECLS - -typedef struct _ClutterPtrA11yData -{ - int n_btn_pressed; - float current_x; - float current_y; - - float dwell_x; - float dwell_y; - gboolean dwell_drag_started; - gboolean dwell_gesture_started; - guint dwell_timer; - guint dwell_position_timer; - - guint secondary_click_timer; - gboolean secondary_click_triggered; -} ClutterPtrA11yData; - -struct _ClutterInputDevice -{ - GObject parent_instance; - - /* Accessibility */ - ClutterVirtualInputDevice *accessibility_virtual_device; - ClutterPtrA11yData *ptr_a11y_data; -}; diff --git a/mutter/clutter/clutter/clutter-input-device-tool.c b/mutter/clutter/clutter/clutter-input-device-tool.c deleted file mode 100644 index c4ab055..0000000 --- a/mutter/clutter/clutter/clutter-input-device-tool.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2009, 2010, 2011 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Carlos Garnacho - */ - -#include "config.h" - -#include "clutter/clutter-input-device-tool.h" -#include "clutter/clutter-private.h" - -typedef struct _ClutterInputDeviceToolPrivate -{ - ClutterInputDeviceToolType type; - guint64 serial; - guint64 id; - ClutterInputAxisFlags axes; -} ClutterInputDeviceToolPrivate; - -enum -{ - PROP_0, - PROP_TYPE, - PROP_SERIAL, - PROP_ID, - PROP_AXES, - PROP_LAST -}; - -static GParamSpec *props[PROP_LAST] = { NULL, }; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterInputDeviceTool, clutter_input_device_tool, G_TYPE_OBJECT) - -static void -clutter_input_device_tool_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterInputDeviceTool *tool = CLUTTER_INPUT_DEVICE_TOOL (object); - ClutterInputDeviceToolPrivate *priv; - - priv = clutter_input_device_tool_get_instance_private (tool); - - switch (prop_id) - { - case PROP_TYPE: - priv->type = g_value_get_enum (value); - break; - case PROP_SERIAL: - priv->serial = g_value_get_uint64 (value); - break; - 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); - } -} - -static void -clutter_input_device_tool_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterInputDeviceTool *tool = CLUTTER_INPUT_DEVICE_TOOL (object); - ClutterInputDeviceToolPrivate *priv; - - priv = clutter_input_device_tool_get_instance_private (tool); - - switch (prop_id) - { - case PROP_TYPE: - g_value_set_enum (value, priv->type); - break; - case PROP_SERIAL: - g_value_set_uint64 (value, priv->serial); - break; - 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); - } -} - -static void -clutter_input_device_tool_class_init (ClutterInputDeviceToolClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->set_property = clutter_input_device_tool_set_property; - gobject_class->get_property = clutter_input_device_tool_get_property; - - props[PROP_TYPE] = - g_param_spec_enum ("type", NULL, NULL, - CLUTTER_TYPE_INPUT_DEVICE_TOOL_TYPE, - CLUTTER_INPUT_DEVICE_TOOL_NONE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - props[PROP_SERIAL] = - g_param_spec_uint64 ("serial", NULL, NULL, - 0, G_MAXUINT64, 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - props[PROP_ID] = - g_param_spec_uint64 ("id", NULL, NULL, - 0, G_MAXUINT64, 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - props[PROP_AXES] = - g_param_spec_flags ("axes", NULL, NULL, - CLUTTER_TYPE_INPUT_AXIS_FLAGS, - CLUTTER_INPUT_AXIS_FLAG_NONE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - g_object_class_install_properties (gobject_class, PROP_LAST, props); -} - -static void -clutter_input_device_tool_init (ClutterInputDeviceTool *tool) -{ -} - -/** - * clutter_input_device_tool_get_serial: - * @tool: a #ClutterInputDeviceTool - * - * Gets the serial of this tool, this value can be used to identify a - * physical tool (eg. a tablet pen) across program executions. - * - * Returns: The serial ID for this tool8 - **/ -guint64 -clutter_input_device_tool_get_serial (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->serial; -} - - -/** - * clutter_input_device_tool_get_tool_type: - * @tool: a #ClutterInputDeviceTool - * - * Gets the tool type of this tool. - * - * Returns: The tool type of this tool8 - **/ -ClutterInputDeviceToolType -clutter_input_device_tool_get_tool_type (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->type; -} - -/** - * clutter_input_device_tool_get_id: - * @tool: a #ClutterInputDeviceTool - * - * Gets the ID of this tool, this value can be used to identify a - * physical tool (eg. a tablet pen) across program executions. - * - * Returns: The tool ID for this tool - **/ -guint64 -clutter_input_device_tool_get_id (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->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; -} diff --git a/mutter/clutter/clutter/clutter-input-device-tool.h b/mutter/clutter/clutter/clutter-input-device-tool.h deleted file mode 100644 index b62489a..0000000 --- a/mutter/clutter/clutter/clutter-input-device-tool.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2009, 2010, 2011 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Carlos Garnacho - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" -#include "clutter/clutter-enum-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_INPUT_DEVICE_TOOL (clutter_input_device_tool_get_type ()) - -struct _ClutterInputDeviceToolClass -{ - GObjectClass parent_class; -}; - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterInputDeviceTool, - clutter_input_device_tool, - CLUTTER, INPUT_DEVICE_TOOL, - GObject) - -CLUTTER_EXPORT -guint64 clutter_input_device_tool_get_serial (ClutterInputDeviceTool *tool); - -CLUTTER_EXPORT -ClutterInputDeviceToolType clutter_input_device_tool_get_tool_type (ClutterInputDeviceTool *tool); - -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 diff --git a/mutter/clutter/clutter/clutter-input-device.c b/mutter/clutter/clutter/clutter-input-device.c deleted file mode 100644 index 5959461..0000000 --- a/mutter/clutter/clutter/clutter-input-device.c +++ /dev/null @@ -1,786 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2009, 2010, 2011 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -/** - * ClutterInputDevice: - * - * An input device managed by Clutter - * - * #ClutterInputDevice represents an input device known to Clutter. - * - * The #ClutterInputDevice class holds the state of the device, but - * its contents are usually defined by the Clutter backend in use. - */ - -#include "config.h" - -#include "clutter/clutter-input-device.h" - -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-event-private.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-stage-private.h" -#include "clutter/clutter-input-device-private.h" -#include "clutter/clutter-input-device-tool.h" - -#include - -enum -{ - PROP_0, - - PROP_NAME, - - PROP_DEVICE_TYPE, - PROP_CAPABILITIES, - PROP_SEAT, - PROP_DEVICE_MODE, - - PROP_HAS_CURSOR, - - PROP_VENDOR_ID, - PROP_PRODUCT_ID, - - PROP_N_STRIPS, - PROP_N_RINGS, - PROP_N_MODE_GROUPS, - PROP_N_BUTTONS, - PROP_DEVICE_NODE, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST] = { NULL, }; - -typedef struct _ClutterInputDevicePrivate ClutterInputDevicePrivate; - -struct _ClutterInputDevicePrivate -{ - ClutterInputDeviceType device_type; - ClutterInputCapabilities capabilities; - ClutterInputMode device_mode; - - char *device_name; - - ClutterSeat *seat; - - char *vendor_id; - char *product_id; - char *node_path; - - int n_rings; - int n_strips; - int n_mode_groups; - int n_buttons; - - gboolean has_cursor; -}; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterInputDevice, clutter_input_device, G_TYPE_OBJECT); - -static void -clutter_input_device_constructed (GObject *gobject) -{ - ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (gobject); - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - - if (priv->capabilities == 0) - { - ClutterInputCapabilities capabilities = 0; - - switch (priv->device_type) - { - case CLUTTER_POINTER_DEVICE: - capabilities = CLUTTER_INPUT_CAPABILITY_POINTER; - break; - case CLUTTER_KEYBOARD_DEVICE: - capabilities = CLUTTER_INPUT_CAPABILITY_KEYBOARD; - break; - case CLUTTER_TOUCHPAD_DEVICE: - capabilities = CLUTTER_INPUT_CAPABILITY_POINTER | - CLUTTER_INPUT_CAPABILITY_TOUCHPAD; - break; - case CLUTTER_TOUCHSCREEN_DEVICE: - capabilities = CLUTTER_INPUT_CAPABILITY_TOUCH; - break; - case CLUTTER_TABLET_DEVICE: - case CLUTTER_PEN_DEVICE: - case CLUTTER_ERASER_DEVICE: - case CLUTTER_CURSOR_DEVICE: - capabilities = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL; - break; - case CLUTTER_PAD_DEVICE: - capabilities = CLUTTER_INPUT_CAPABILITY_TABLET_PAD; - break; - case CLUTTER_EXTENSION_DEVICE: - case CLUTTER_JOYSTICK_DEVICE: - break; - case CLUTTER_N_DEVICE_TYPES: - g_assert_not_reached (); - break; - } - - priv->capabilities = capabilities; - } -} - -static void -clutter_input_device_dispose (GObject *gobject) -{ - ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (gobject); - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - - g_clear_pointer (&priv->device_name, g_free); - g_clear_pointer (&priv->vendor_id, g_free); - g_clear_pointer (&priv->product_id, g_free); - g_clear_pointer (&priv->node_path, g_free); - - if (device->accessibility_virtual_device) - g_clear_object (&device->accessibility_virtual_device); - - G_OBJECT_CLASS (clutter_input_device_parent_class)->dispose (gobject); -} - -static void -clutter_input_device_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterInputDevice *self = CLUTTER_INPUT_DEVICE (gobject); - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (self); - - switch (prop_id) - { - case PROP_DEVICE_TYPE: - priv->device_type = g_value_get_enum (value); - break; - - case PROP_CAPABILITIES: - priv->capabilities = g_value_get_flags (value); - break; - - case PROP_SEAT: - priv->seat = g_value_get_object (value); - break; - - case PROP_DEVICE_MODE: - priv->device_mode = g_value_get_enum (value); - break; - - case PROP_NAME: - priv->device_name = g_value_dup_string (value); - break; - - case PROP_HAS_CURSOR: - priv->has_cursor = g_value_get_boolean (value); - break; - - case PROP_VENDOR_ID: - priv->vendor_id = g_value_dup_string (value); - break; - - case PROP_PRODUCT_ID: - priv->product_id = g_value_dup_string (value); - break; - - case PROP_N_RINGS: - priv->n_rings = g_value_get_int (value); - break; - - case PROP_N_STRIPS: - priv->n_strips = g_value_get_int (value); - break; - - case PROP_N_MODE_GROUPS: - priv->n_mode_groups = g_value_get_int (value); - break; - - case PROP_N_BUTTONS: - priv->n_buttons = g_value_get_int (value); - break; - - case PROP_DEVICE_NODE: - priv->node_path = g_value_dup_string (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_input_device_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterInputDevice *self = CLUTTER_INPUT_DEVICE (gobject); - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (self); - - switch (prop_id) - { - case PROP_DEVICE_TYPE: - g_value_set_enum (value, priv->device_type); - break; - - case PROP_CAPABILITIES: - g_value_set_flags (value, priv->capabilities); - break; - - case PROP_SEAT: - g_value_set_object (value, priv->seat); - break; - - case PROP_DEVICE_MODE: - g_value_set_enum (value, priv->device_mode); - break; - - case PROP_NAME: - g_value_set_string (value, priv->device_name); - break; - - case PROP_HAS_CURSOR: - g_value_set_boolean (value, priv->has_cursor); - break; - - case PROP_VENDOR_ID: - g_value_set_string (value, priv->vendor_id); - break; - - case PROP_PRODUCT_ID: - g_value_set_string (value, priv->product_id); - break; - - case PROP_N_RINGS: - g_value_set_int (value, priv->n_rings); - break; - - case PROP_N_STRIPS: - g_value_set_int (value, priv->n_strips); - break; - - case PROP_N_MODE_GROUPS: - g_value_set_int (value, priv->n_mode_groups); - break; - - case PROP_N_BUTTONS: - g_value_set_int (value, priv->n_buttons); - break; - - case PROP_DEVICE_NODE: - g_value_set_string (value, priv->node_path); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_input_device_class_init (ClutterInputDeviceClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - /** - * ClutterInputDevice:name: - * - * The name of the device - */ - obj_props[PROP_NAME] = - g_param_spec_string ("name", NULL, NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - /** - * ClutterInputDevice:device-type: - * - * The type of the device - */ - obj_props[PROP_DEVICE_TYPE] = - g_param_spec_enum ("device-type", NULL, NULL, - CLUTTER_TYPE_INPUT_DEVICE_TYPE, - CLUTTER_POINTER_DEVICE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - /** - * ClutterInputDevice:capabilities: - * - * The capabilities of the device - */ - obj_props[PROP_CAPABILITIES] = - g_param_spec_flags ("capabilities", NULL, NULL, - CLUTTER_TYPE_INPUT_CAPABILITIES, 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - /** - * ClutterInputDevice:seat: - * - * The #ClutterSeat instance which owns the device - */ - obj_props[PROP_SEAT] = - g_param_spec_object ("seat", NULL, NULL, - CLUTTER_TYPE_SEAT, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - /** - * ClutterInputDevice:mode: - * - * The mode of the device. - */ - obj_props[PROP_DEVICE_MODE] = - g_param_spec_enum ("device-mode", NULL, NULL, - CLUTTER_TYPE_INPUT_MODE, - CLUTTER_INPUT_MODE_FLOATING, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - /** - * ClutterInputDevice:has-cursor: - * - * Whether the device has an on screen cursor following its movement. - */ - obj_props[PROP_HAS_CURSOR] = - g_param_spec_boolean ("has-cursor", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - /** - * ClutterInputDevice:vendor-id: - * - * Vendor ID of this device.2 - */ - obj_props[PROP_VENDOR_ID] = - g_param_spec_string ("vendor-id", NULL, NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - /** - * ClutterInputDevice:product-id: - * - * Product ID of this device.2 - */ - obj_props[PROP_PRODUCT_ID] = - g_param_spec_string ("product-id", NULL, NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - obj_props[PROP_N_RINGS] = - g_param_spec_int ("n-rings", NULL, NULL, - 0, G_MAXINT, 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - obj_props[PROP_N_STRIPS] = - g_param_spec_int ("n-strips", NULL, NULL, - 0, G_MAXINT, 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - obj_props[PROP_N_MODE_GROUPS] = - g_param_spec_int ("n-mode-groups", NULL, NULL, - 0, G_MAXINT, 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - obj_props[PROP_N_BUTTONS] = - g_param_spec_int ("n-buttons", NULL, NULL, - 0, G_MAXINT, 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - obj_props[PROP_DEVICE_NODE] = - g_param_spec_string ("device-node", NULL, NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - gobject_class->constructed = clutter_input_device_constructed; - gobject_class->dispose = clutter_input_device_dispose; - gobject_class->set_property = clutter_input_device_set_property; - gobject_class->get_property = clutter_input_device_get_property; - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); -} - -static void -clutter_input_device_init (ClutterInputDevice *self) -{ - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (self); - - priv->device_type = CLUTTER_POINTER_DEVICE; -} - -/** - * clutter_input_device_get_device_type: - * @device: a #ClutterInputDevice - * - * Retrieves the type of @device - * - * Return value: the type of the device - */ -ClutterInputDeviceType -clutter_input_device_get_device_type (ClutterInputDevice *device) -{ - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), - CLUTTER_POINTER_DEVICE); - - return priv->device_type; -} - -/** - * clutter_input_device_get_capabilities: - * @device: a #ClutterInputDevice - * - * Retrieves the capabilities of @device - * - * Return value: the capabilities of the device - */ -ClutterInputCapabilities -clutter_input_device_get_capabilities (ClutterInputDevice *device) -{ - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), 0); - - return priv->capabilities; -} - -/** - * clutter_input_device_get_device_name: - * @device: a #ClutterInputDevice - * - * Retrieves the name of the @device - * - * Return value: the name of the device, or %NULL. The returned string - * is owned by the #ClutterInputDevice and should never be modified - * or freed - */ -const gchar * -clutter_input_device_get_device_name (ClutterInputDevice *device) -{ - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - - return priv->device_name; -} - -/** - * clutter_input_device_get_has_cursor: - * @device: a #ClutterInputDevice - * - * Retrieves whether @device has a pointer that follows the - * device motion. - * - * Return value: %TRUE if the device has a cursor - */ -gboolean -clutter_input_device_get_has_cursor (ClutterInputDevice *device) -{ - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); - - return priv->has_cursor; -} - -/** - * clutter_input_device_get_device_mode: - * @device: a #ClutterInputDevice - * - * Retrieves the #ClutterInputMode of @device. - * - * Return value: the device mode - */ -ClutterInputMode -clutter_input_device_get_device_mode (ClutterInputDevice *device) -{ - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), - CLUTTER_INPUT_MODE_FLOATING); - - return priv->device_mode; -} - -/** - * clutter_input_device_get_vendor_id: - * @device: a physical #ClutterInputDevice - * - * Gets the vendor ID of this device. - * - * Returns: the vendor ID2 - */ -const gchar * -clutter_input_device_get_vendor_id (ClutterInputDevice *device) -{ - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - g_return_val_if_fail (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_LOGICAL, NULL); - - return priv->vendor_id; -} - -/** - * clutter_input_device_get_product_id: - * @device: a physical #ClutterInputDevice - * - * Gets the product ID of this device. - * - * Returns: the product ID2 - */ -const gchar * -clutter_input_device_get_product_id (ClutterInputDevice *device) -{ - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - g_return_val_if_fail (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_LOGICAL, NULL); - - return priv->product_id; -} - -gint -clutter_input_device_get_n_rings (ClutterInputDevice *device) -{ - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), 0); - - return priv->n_rings; -} - -gint -clutter_input_device_get_n_strips (ClutterInputDevice *device) -{ - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), 0); - - return priv->n_strips; -} - -gint -clutter_input_device_get_n_mode_groups (ClutterInputDevice *device) -{ - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), 0); - g_return_val_if_fail (clutter_input_device_get_device_type (device) == - CLUTTER_PAD_DEVICE, 0); - - return priv->n_mode_groups; -} - -gint -clutter_input_device_get_n_buttons (ClutterInputDevice *device) -{ - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), 0); - g_return_val_if_fail (clutter_input_device_get_device_type (device) == - CLUTTER_PAD_DEVICE, 0); - - return priv->n_buttons; -} - -gint -clutter_input_device_get_group_n_modes (ClutterInputDevice *device, - gint group) -{ - ClutterInputDeviceClass *device_class; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), 0); - g_return_val_if_fail (clutter_input_device_get_device_type (device) == - CLUTTER_PAD_DEVICE, 0); - g_return_val_if_fail (group >= 0, 0); - - device_class = CLUTTER_INPUT_DEVICE_GET_CLASS (device); - - if (device_class->get_group_n_modes) - return device_class->get_group_n_modes (device, group); - - return 0; -} - -gboolean -clutter_input_device_is_mode_switch_button (ClutterInputDevice *device, - guint group, - guint button) -{ - ClutterInputDeviceClass *device_class; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); - g_return_val_if_fail (clutter_input_device_get_device_type (device) == - CLUTTER_PAD_DEVICE, FALSE); - - device_class = CLUTTER_INPUT_DEVICE_GET_CLASS (device); - - if (device_class->is_mode_switch_button) - return device_class->is_mode_switch_button (device, group, button); - - return FALSE; -} - -gint -clutter_input_device_get_mode_switch_button_group (ClutterInputDevice *device, - guint button) -{ - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - gint group; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), -1); - g_return_val_if_fail (clutter_input_device_get_device_type (device) == - CLUTTER_PAD_DEVICE, -1); - - for (group = 0; group < priv->n_mode_groups; group++) - { - if (clutter_input_device_is_mode_switch_button (device, group, button)) - return group; - } - - return -1; -} - -int -clutter_input_device_get_pad_feature_group (ClutterInputDevice *device, - ClutterInputDevicePadFeature feature, - int n_feature) -{ - ClutterInputDeviceClass *device_class; - - device_class = CLUTTER_INPUT_DEVICE_GET_CLASS (device); - if (!device_class->get_pad_feature_group) - return 0; - - return CLUTTER_INPUT_DEVICE_GET_CLASS (device)->get_pad_feature_group (device, - feature, - n_feature); -} - -const gchar * -clutter_input_device_get_device_node (ClutterInputDevice *device) -{ - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - - return priv->node_path; -} - -gboolean -clutter_input_device_is_grouped (ClutterInputDevice *device, - ClutterInputDevice *other_device) -{ - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (other_device), FALSE); - - return CLUTTER_INPUT_DEVICE_GET_CLASS (device)->is_grouped (device, other_device); -} - -/** - * clutter_input_device_get_seat: - * @device: a #ClutterInputDevice - * - * Returns the seat the device belongs to - * - * Returns: (transfer none): the device seat - **/ -ClutterSeat * -clutter_input_device_get_seat (ClutterInputDevice *device) -{ - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - - return priv->seat; -} - -/** - * clutter_input_device_get_dimensions: - * @device: a #ClutterInputDevice - * @width: (out): Return location for device width (in millimeters) - * @height: (out): Return location for device height (in millimeters) - * - * Returns: %TRUE if the device reports the physical size of its input area. - **/ -gboolean -clutter_input_device_get_dimensions (ClutterInputDevice *device, - unsigned int *width, - unsigned int *height) -{ - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); - g_return_val_if_fail (width != NULL && height != NULL, FALSE); - - if (!CLUTTER_INPUT_DEVICE_GET_CLASS (device)->get_dimensions) - return FALSE; - - return CLUTTER_INPUT_DEVICE_GET_CLASS (device)->get_dimensions (device, width, height); -} diff --git a/mutter/clutter/clutter/clutter-input-device.h b/mutter/clutter/clutter/clutter-input-device.h deleted file mode 100644 index eb7a3f7..0000000 --- a/mutter/clutter/clutter/clutter-input-device.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2009, 2010, 2011 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-backend.h" -#include "clutter/clutter-types.h" -#include "clutter/clutter-seat.h" - -G_BEGIN_DECLS - -struct _ClutterInputDeviceClass -{ - GObjectClass parent_class; - - gboolean (* is_mode_switch_button) (ClutterInputDevice *device, - guint group, - guint button); - gint (* get_group_n_modes) (ClutterInputDevice *device, - gint group); - - gboolean (* is_grouped) (ClutterInputDevice *device, - ClutterInputDevice *other_device); - - int (* get_pad_feature_group) (ClutterInputDevice *device, - ClutterInputDevicePadFeature feature, - int n_feature); - gboolean (* get_dimensions) (ClutterInputDevice *device, - unsigned int *width, - unsigned int *height); -}; - -#define CLUTTER_TYPE_INPUT_DEVICE (clutter_input_device_get_type ()) -#define CLUTTER_INPUT_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_INPUT_DEVICE, ClutterInputDevice)) -#define CLUTTER_IS_INPUT_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_INPUT_DEVICE)) -#define CLUTTER_INPUT_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_INPUT_DEVICE, ClutterInputDeviceClass)) -#define CLUTTER_IS_INPUT_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_INPUT_DEVICE)) -#define CLUTTER_INPUT_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_INPUT_DEVICE, ClutterInputDeviceClass)) - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterInputDevice, g_object_unref) - -typedef struct _ClutterInputDeviceClass ClutterInputDeviceClass; - -CLUTTER_EXPORT -GType clutter_input_device_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterInputDeviceType clutter_input_device_get_device_type (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 -const gchar * clutter_input_device_get_vendor_id (ClutterInputDevice *device); -CLUTTER_EXPORT -const gchar * clutter_input_device_get_product_id (ClutterInputDevice *device); - -CLUTTER_EXPORT -gint clutter_input_device_get_n_rings (ClutterInputDevice *device); -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, - gint group); - -CLUTTER_EXPORT -gboolean clutter_input_device_is_mode_switch_button (ClutterInputDevice *device, - guint group, - guint button); -CLUTTER_EXPORT -gint clutter_input_device_get_mode_switch_button_group (ClutterInputDevice *device, - guint button); - -CLUTTER_EXPORT -const gchar * clutter_input_device_get_device_node (ClutterInputDevice *device); - -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); - -CLUTTER_EXPORT -ClutterInputCapabilities clutter_input_device_get_capabilities (ClutterInputDevice *device); - -CLUTTER_EXPORT -gboolean clutter_input_device_get_dimensions (ClutterInputDevice *device, - unsigned int *width, - unsigned int *height); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-input-focus-private.h b/mutter/clutter/clutter/clutter-input-focus-private.h deleted file mode 100644 index 69b6985..0000000 --- a/mutter/clutter/clutter/clutter-input-focus-private.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2017,2018 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, see . - * - * Author: Carlos Garnacho - */ - -#pragma once - -void clutter_input_focus_focus_in (ClutterInputFocus *focus, - ClutterInputMethod *method); -void clutter_input_focus_focus_out (ClutterInputFocus *focus); - -void clutter_input_focus_commit (ClutterInputFocus *focus, - const gchar *text); -void clutter_input_focus_request_surrounding (ClutterInputFocus *focus); diff --git a/mutter/clutter/clutter/clutter-input-focus.c b/mutter/clutter/clutter/clutter-input-focus.c deleted file mode 100644 index 9d243b8..0000000 --- a/mutter/clutter/clutter/clutter-input-focus.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (C) 2017,2018 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, see . - * - * Author: Carlos Garnacho - */ - -#include "config.h" - -#include "clutter/clutter-input-focus.h" -#include "clutter/clutter-input-focus-private.h" -#include "clutter/clutter-input-method-private.h" - -typedef struct _ClutterInputFocusPrivate ClutterInputFocusPrivate; - -static void clutter_input_focus_delete_surrounding (ClutterInputFocus *focus, - int offset, - guint len); -static void clutter_input_focus_set_preedit_text (ClutterInputFocus *focus, - const gchar *preedit, - unsigned int cursor, - unsigned int anchor); - -struct _ClutterInputFocusPrivate -{ - ClutterInputMethod *im; - char *preedit; - ClutterPreeditResetMode mode; -}; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterInputFocus, clutter_input_focus, G_TYPE_OBJECT) - -static void -clutter_input_focus_real_focus_in (ClutterInputFocus *focus, - ClutterInputMethod *im) -{ - ClutterInputFocusPrivate *priv; - - priv = clutter_input_focus_get_instance_private (focus); - priv->im = im; -} - -static void -clutter_input_focus_real_focus_out (ClutterInputFocus *focus) -{ - ClutterInputFocusPrivate *priv; - - priv = clutter_input_focus_get_instance_private (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; -} - -static void -clutter_input_focus_init (ClutterInputFocus *focus) -{ -} - -gboolean -clutter_input_focus_is_focused (ClutterInputFocus *focus) -{ - ClutterInputFocusPrivate *priv; - - priv = clutter_input_focus_get_instance_private (focus); - - return !!priv->im; -} - -void -clutter_input_focus_reset (ClutterInputFocus *focus) -{ - ClutterInputFocusPrivate *priv; - - g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus)); - g_return_if_fail (clutter_input_focus_is_focused (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, 0); - g_clear_pointer (&priv->preedit, g_free); - } - - priv->mode = CLUTTER_PREEDIT_RESET_CLEAR; - clutter_input_method_reset (priv->im); -} - -void -clutter_input_focus_set_cursor_location (ClutterInputFocus *focus, - const graphene_rect_t *rect) -{ - ClutterInputFocusPrivate *priv; - - g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus)); - g_return_if_fail (clutter_input_focus_is_focused (focus)); - - priv = clutter_input_focus_get_instance_private (focus); - - clutter_input_method_set_cursor_location (priv->im, rect); -} - -void -clutter_input_focus_set_surrounding (ClutterInputFocus *focus, - const gchar *text, - guint cursor, - guint anchor) -{ - ClutterInputFocusPrivate *priv; - - g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus)); - g_return_if_fail (clutter_input_focus_is_focused (focus)); - - priv = clutter_input_focus_get_instance_private (focus); - - clutter_input_method_set_surrounding (priv->im, text, cursor, anchor); -} - -void -clutter_input_focus_set_content_hints (ClutterInputFocus *focus, - ClutterInputContentHintFlags hints) -{ - ClutterInputFocusPrivate *priv; - - g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus)); - g_return_if_fail (clutter_input_focus_is_focused (focus)); - - priv = clutter_input_focus_get_instance_private (focus); - - clutter_input_method_set_content_hints (priv->im, hints); -} - -void -clutter_input_focus_set_content_purpose (ClutterInputFocus *focus, - ClutterInputContentPurpose purpose) -{ - ClutterInputFocusPrivate *priv; - - g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus)); - g_return_if_fail (clutter_input_focus_is_focused (focus)); - - priv = clutter_input_focus_get_instance_private (focus); - - clutter_input_method_set_content_purpose (priv->im, purpose); -} - -gboolean -clutter_input_focus_filter_event (ClutterInputFocus *focus, - const ClutterEvent *event) -{ - ClutterInputFocusPrivate *priv; - ClutterEventType event_type; - - g_return_val_if_fail (CLUTTER_IS_INPUT_FOCUS (focus), FALSE); - g_return_val_if_fail (clutter_input_focus_is_focused (focus), FALSE); - - priv = clutter_input_focus_get_instance_private (focus); - - event_type = clutter_event_type (event); - - if (event_type == CLUTTER_KEY_PRESS || - event_type == CLUTTER_KEY_RELEASE) - { - return clutter_input_method_filter_key_event (priv->im, (ClutterKeyEvent *) event); - } - - return FALSE; -} - -gboolean -clutter_input_focus_process_event (ClutterInputFocus *focus, - const ClutterEvent *event) -{ - ClutterInputFocusPrivate *priv; - ClutterEventType event_type; - - g_return_val_if_fail (CLUTTER_IS_INPUT_FOCUS (focus), FALSE); - g_return_val_if_fail (clutter_input_focus_is_focused (focus), FALSE); - - priv = clutter_input_focus_get_instance_private (focus); - - event_type = clutter_event_type (event); - - if (event_type == CLUTTER_IM_COMMIT) - { - clutter_input_focus_commit (focus, - clutter_event_get_im_text (event)); - return TRUE; - } - else if (event_type == CLUTTER_IM_DELETE) - { - int32_t offset; - uint32_t len; - - clutter_event_get_im_location (event, &offset, NULL); - len = clutter_event_get_im_delete_length (event); - clutter_input_focus_delete_surrounding (focus, offset, len); - return TRUE; - } - else if (event_type == CLUTTER_IM_PREEDIT) - { - int32_t offset, anchor; - - g_clear_pointer (&priv->preedit, g_free); - priv->preedit = g_strdup (clutter_event_get_im_text (event)); - priv->mode = clutter_event_get_im_preedit_reset_mode (event); - clutter_event_get_im_location (event, &offset, &anchor); - clutter_input_focus_set_preedit_text (focus, - priv->preedit, - offset, anchor); - return TRUE; - } - - return FALSE; -} - -void -clutter_input_focus_set_can_show_preedit (ClutterInputFocus *focus, - gboolean can_show_preedit) -{ - ClutterInputFocusPrivate *priv; - - g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus)); - g_return_if_fail (clutter_input_focus_is_focused (focus)); - - priv = clutter_input_focus_get_instance_private (focus); - - clutter_input_method_set_can_show_preedit (priv->im, can_show_preedit); -} - -void -clutter_input_focus_set_input_panel_state (ClutterInputFocus *focus, - ClutterInputPanelState state) -{ - ClutterInputFocusPrivate *priv; - - g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus)); - g_return_if_fail (clutter_input_focus_is_focused (focus)); - - priv = clutter_input_focus_get_instance_private (focus); - - clutter_input_method_set_input_panel_state (priv->im, state); -} - -void -clutter_input_focus_focus_in (ClutterInputFocus *focus, - ClutterInputMethod *im) -{ - g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus)); - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - - CLUTTER_INPUT_FOCUS_GET_CLASS (focus)->focus_in (focus, im); -} - -void -clutter_input_focus_focus_out (ClutterInputFocus *focus) -{ - g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus)); - - CLUTTER_INPUT_FOCUS_GET_CLASS (focus)->focus_out (focus); -} - -void -clutter_input_focus_commit (ClutterInputFocus *focus, - const gchar *text) -{ - g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus)); - - CLUTTER_INPUT_FOCUS_GET_CLASS (focus)->commit_text (focus, text); -} - -void -clutter_input_focus_delete_surrounding (ClutterInputFocus *focus, - int offset, - guint len) -{ - g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus)); - - CLUTTER_INPUT_FOCUS_GET_CLASS (focus)->delete_surrounding (focus, offset, len); -} - -void -clutter_input_focus_request_surrounding (ClutterInputFocus *focus) -{ - g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus)); - - CLUTTER_INPUT_FOCUS_GET_CLASS (focus)->request_surrounding (focus); -} - -void -clutter_input_focus_set_preedit_text (ClutterInputFocus *focus, - const gchar *preedit, - unsigned int cursor, - unsigned int anchor) -{ - g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus)); - - CLUTTER_INPUT_FOCUS_GET_CLASS (focus)->set_preedit_text (focus, preedit, - cursor, anchor); -} diff --git a/mutter/clutter/clutter/clutter-input-focus.h b/mutter/clutter/clutter/clutter-input-focus.h deleted file mode 100644 index 530e195..0000000 --- a/mutter/clutter/clutter/clutter-input-focus.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2017,2018 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, see . - * - * Author: Carlos Garnacho - */ - -#pragma once - -#include "clutter/clutter.h" - -#define CLUTTER_TYPE_INPUT_FOCUS (clutter_input_focus_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterInputFocus, clutter_input_focus, - CLUTTER, INPUT_FOCUS, GObject) - -struct _ClutterInputFocusClass -{ - GObjectClass parent_class; - GTypeInterface iface; - - void (* focus_in) (ClutterInputFocus *focus, - ClutterInputMethod *input_method); - void (* focus_out) (ClutterInputFocus *focus); - - void (* request_surrounding) (ClutterInputFocus *focus); - void (* delete_surrounding) (ClutterInputFocus *focus, - int offset, - guint len); - void (* commit_text) (ClutterInputFocus *focus, - const gchar *text); - - void (* set_preedit_text) (ClutterInputFocus *focus, - const gchar *preedit, - guint cursor, - guint anchor); -}; - -CLUTTER_EXPORT -gboolean clutter_input_focus_is_focused (ClutterInputFocus *focus); - -CLUTTER_EXPORT -void clutter_input_focus_reset (ClutterInputFocus *focus); -CLUTTER_EXPORT -void clutter_input_focus_set_cursor_location (ClutterInputFocus *focus, - const graphene_rect_t *rect); - -CLUTTER_EXPORT -void clutter_input_focus_set_surrounding (ClutterInputFocus *focus, - const gchar *text, - guint cursor, - guint anchor); -CLUTTER_EXPORT -void clutter_input_focus_set_content_hints (ClutterInputFocus *focus, - ClutterInputContentHintFlags hint); -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); - -CLUTTER_EXPORT -gboolean clutter_input_focus_process_event (ClutterInputFocus *focus, - const ClutterEvent *event); - -CLUTTER_EXPORT -void clutter_input_focus_set_can_show_preedit (ClutterInputFocus *focus, - gboolean can_show_preedit); -CLUTTER_EXPORT -void clutter_input_focus_set_input_panel_state (ClutterInputFocus *focus, - ClutterInputPanelState state); diff --git a/mutter/clutter/clutter/clutter-input-method-private.h b/mutter/clutter/clutter/clutter-input-method-private.h deleted file mode 100644 index e3ba174..0000000 --- a/mutter/clutter/clutter/clutter-input-method-private.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2017,2018 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, see . - * - * Author: Carlos Garnacho - */ - -#pragma once - -void clutter_input_method_reset (ClutterInputMethod *method); - -void clutter_input_method_set_cursor_location (ClutterInputMethod *method, - const graphene_rect_t *rect); -void clutter_input_method_set_surrounding (ClutterInputMethod *method, - const gchar *text, - guint cursor, - guint anchor); -void clutter_input_method_set_content_hints (ClutterInputMethod *method, - ClutterInputContentHintFlags hints); -void clutter_input_method_set_content_purpose (ClutterInputMethod *method, - ClutterInputContentPurpose purpose); -void clutter_input_method_set_can_show_preedit (ClutterInputMethod *method, - gboolean can_show_preedit); -gboolean clutter_input_method_filter_key_event (ClutterInputMethod *method, - const ClutterKeyEvent *key); diff --git a/mutter/clutter/clutter/clutter-input-method.c b/mutter/clutter/clutter/clutter-input-method.c deleted file mode 100644 index b693b61..0000000 --- a/mutter/clutter/clutter/clutter-input-method.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright (C) 2017,2018 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, see . - * - * Author: Carlos Garnacho - */ - -#include "config.h" - -#include "clutter/clutter-event-private.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-input-device-private.h" -#include "clutter/clutter-input-focus.h" -#include "clutter/clutter-input-method.h" -#include "clutter/clutter-input-method-private.h" -#include "clutter/clutter-input-focus-private.h" - -typedef struct _ClutterInputMethodPrivate ClutterInputMethodPrivate; - -struct _ClutterInputMethodPrivate -{ - ClutterInputFocus *focus; - ClutterInputContentHintFlags content_hints; - ClutterInputContentPurpose content_purpose; - gboolean can_show_preedit; -}; - -enum -{ - COMMIT, - DELETE_SURROUNDING, - REQUEST_SURROUNDING, - INPUT_PANEL_STATE, - CURSOR_LOCATION_CHANGED, - N_SIGNALS, -}; - -enum -{ - PROP_0, - PROP_CONTENT_HINTS, - PROP_CONTENT_PURPOSE, - PROP_CAN_SHOW_PREEDIT, - N_PROPS -}; - -static guint signals[N_SIGNALS] = { 0 }; -static GParamSpec *pspecs[N_PROPS] = { 0 }; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterInputMethod, clutter_input_method, G_TYPE_OBJECT) - -static void -clutter_input_method_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterInputMethod *im = CLUTTER_INPUT_METHOD (object); - - switch (prop_id) - { - case PROP_CONTENT_HINTS: - clutter_input_method_set_content_hints (im, - g_value_get_flags (value)); - break; - case PROP_CONTENT_PURPOSE: - clutter_input_method_set_content_purpose (im, - g_value_get_enum (value)); - break; - case PROP_CAN_SHOW_PREEDIT: - clutter_input_method_set_can_show_preedit (im, - g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_input_method_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterInputMethodPrivate *priv; - ClutterInputMethod *im; - - im = CLUTTER_INPUT_METHOD (object); - priv = clutter_input_method_get_instance_private (im); - - switch (prop_id) - { - case PROP_CONTENT_HINTS: - g_value_set_flags (value, priv->content_hints); - break; - case PROP_CONTENT_PURPOSE: - g_value_set_enum (value, priv->content_purpose); - break; - case PROP_CAN_SHOW_PREEDIT: - g_value_set_boolean (value, priv->can_show_preedit); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_input_method_class_init (ClutterInputMethodClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->set_property = clutter_input_method_set_property; - object_class->get_property = clutter_input_method_get_property; - - signals[COMMIT] = - g_signal_new ("commit", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, G_TYPE_STRING); - signals[DELETE_SURROUNDING] = - g_signal_new ("delete-surrounding", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_UINT); - signals[REQUEST_SURROUNDING] = - g_signal_new ("request-surrounding", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); - signals[INPUT_PANEL_STATE] = - g_signal_new ("input-panel-state", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_INPUT_PANEL_STATE); - signals[CURSOR_LOCATION_CHANGED] = - g_signal_new ("cursor-location-changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, GRAPHENE_TYPE_RECT); - - pspecs[PROP_CONTENT_HINTS] = - g_param_spec_flags ("content-hints", NULL, NULL, - CLUTTER_TYPE_INPUT_CONTENT_HINT_FLAGS, 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - pspecs[PROP_CONTENT_PURPOSE] = - g_param_spec_enum ("content-purpose", NULL, NULL, - CLUTTER_TYPE_INPUT_CONTENT_PURPOSE, 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - pspecs[PROP_CAN_SHOW_PREEDIT] = - g_param_spec_boolean ("can-show-preedit", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - g_object_class_install_properties (object_class, N_PROPS, pspecs); -} - -static void -clutter_input_method_init (ClutterInputMethod *im) -{ -} - -void -clutter_input_method_focus_in (ClutterInputMethod *im, - ClutterInputFocus *focus) -{ - ClutterInputMethodPrivate *priv; - ClutterInputMethodClass *klass; - - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus)); - - priv = clutter_input_method_get_instance_private (im); - - if (priv->focus == focus) - return; - - if (priv->focus) - clutter_input_method_focus_out (im); - - g_set_object (&priv->focus, focus); - - if (focus) - { - klass = CLUTTER_INPUT_METHOD_GET_CLASS (im); - klass->focus_in (im, focus); - - clutter_input_focus_focus_in (priv->focus, im); - } -} - -void -clutter_input_method_focus_out (ClutterInputMethod *im) -{ - ClutterInputMethodPrivate *priv; - ClutterInputMethodClass *klass; - - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - - priv = clutter_input_method_get_instance_private (im); - - if (!priv->focus) - return; - - clutter_input_focus_focus_out (priv->focus); - g_clear_object (&priv->focus); - - klass = CLUTTER_INPUT_METHOD_GET_CLASS (im); - klass->focus_out (im); -} - -static void -clutter_input_method_put_im_event (ClutterInputMethod *im, - ClutterEventType event_type, - const char *text, - int32_t offset, - int32_t anchor, - uint32_t len, - ClutterPreeditResetMode mode) -{ - ClutterSeat *seat; - ClutterEvent *event; - - seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); - - event = clutter_event_im_new (event_type, - CLUTTER_EVENT_FLAG_INPUT_METHOD, - CLUTTER_CURRENT_TIME, - seat, - text, - offset, - anchor, - len, - mode); - - clutter_event_put (event); - clutter_event_free (event); -} - -void -clutter_input_method_commit (ClutterInputMethod *im, - const gchar *text) -{ - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - - clutter_input_method_put_im_event (im, CLUTTER_IM_COMMIT, text, 0, 0, 0, - CLUTTER_PREEDIT_RESET_CLEAR); -} - -void -clutter_input_method_delete_surrounding (ClutterInputMethod *im, - int offset, - guint len) -{ - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - - clutter_input_method_put_im_event (im, CLUTTER_IM_DELETE, NULL, - offset, offset, len, - CLUTTER_PREEDIT_RESET_CLEAR); -} - -void -clutter_input_method_request_surrounding (ClutterInputMethod *im) -{ - ClutterInputMethodPrivate *priv; - - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - - priv = clutter_input_method_get_instance_private (im); - if (priv->focus) - clutter_input_focus_request_surrounding (priv->focus); -} - -/** - * clutter_input_method_set_preedit_text: - * @im: a #ClutterInputMethod - * @preedit: (nullable): the preedit text, or %NULL - * @cursor: the cursor - * - * Sets the preedit text on the current input focus. - **/ -void -clutter_input_method_set_preedit_text (ClutterInputMethod *im, - const gchar *preedit, - unsigned int cursor, - unsigned int anchor, - ClutterPreeditResetMode mode) -{ - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - - clutter_input_method_put_im_event (im, CLUTTER_IM_PREEDIT, preedit, - cursor, anchor, 0, mode); -} - -void -clutter_input_method_notify_key_event (ClutterInputMethod *im, - const ClutterEvent *event, - gboolean filtered) -{ - if (!filtered) - { - ClutterModifierSet raw_modifiers; - ClutterEvent *copy; - - clutter_event_get_key_state (event, - &raw_modifiers.pressed, - &raw_modifiers.latched, - &raw_modifiers.locked); - - /* XXX: we rely on the IM implementation to notify back of - * key events in the exact same order they were given. - */ - copy = clutter_event_key_new (clutter_event_type (event), - clutter_event_get_flags (event) | - CLUTTER_EVENT_FLAG_INPUT_METHOD, - clutter_event_get_time_us (event), - clutter_event_get_device (event), - raw_modifiers, - clutter_event_get_state (event), - clutter_event_get_key_symbol (event), - clutter_event_get_event_code (event), - clutter_event_get_key_code (event), - clutter_event_get_key_unicode (event)); - clutter_event_put (copy); - clutter_event_free (copy); - } -} - -void -clutter_input_method_set_input_panel_state (ClutterInputMethod *im, - ClutterInputPanelState state) -{ - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - - g_signal_emit (im, signals[INPUT_PANEL_STATE], 0, state); -} - -void -clutter_input_method_reset (ClutterInputMethod *im) -{ - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - - CLUTTER_INPUT_METHOD_GET_CLASS (im)->reset (im); -} - -void -clutter_input_method_set_cursor_location (ClutterInputMethod *im, - const graphene_rect_t *rect) -{ - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - - CLUTTER_INPUT_METHOD_GET_CLASS (im)->set_cursor_location (im, rect); - - g_signal_emit (im, signals[CURSOR_LOCATION_CHANGED], 0, rect); -} - -void -clutter_input_method_set_surrounding (ClutterInputMethod *im, - const gchar *text, - guint cursor, - guint anchor) -{ - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - - CLUTTER_INPUT_METHOD_GET_CLASS (im)->set_surrounding (im, text, - cursor, anchor); -} - -void -clutter_input_method_set_content_hints (ClutterInputMethod *im, - ClutterInputContentHintFlags hints) -{ - ClutterInputMethodPrivate *priv; - - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - - priv = clutter_input_method_get_instance_private (im); - - if (priv->content_hints == hints) - return; - - priv->content_hints = hints; - CLUTTER_INPUT_METHOD_GET_CLASS (im)->update_content_hints (im, hints); - - g_object_notify_by_pspec (G_OBJECT (im), pspecs[PROP_CONTENT_HINTS]); -} - -void -clutter_input_method_set_content_purpose (ClutterInputMethod *im, - ClutterInputContentPurpose purpose) -{ - ClutterInputMethodPrivate *priv; - - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - - priv = clutter_input_method_get_instance_private (im); - - if (priv->content_purpose == purpose) - return; - - priv->content_purpose = purpose; - CLUTTER_INPUT_METHOD_GET_CLASS (im)->update_content_purpose (im, purpose); - - g_object_notify_by_pspec (G_OBJECT (im), pspecs[PROP_CONTENT_PURPOSE]); -} - -void -clutter_input_method_set_can_show_preedit (ClutterInputMethod *im, - gboolean can_show_preedit) -{ - ClutterInputMethodPrivate *priv; - - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - - priv = clutter_input_method_get_instance_private (im); - - if (priv->can_show_preedit == can_show_preedit) - return; - - priv->can_show_preedit = can_show_preedit; - - g_object_notify_by_pspec (G_OBJECT (im), pspecs[PROP_CAN_SHOW_PREEDIT]); -} - -gboolean -clutter_input_method_filter_key_event (ClutterInputMethod *im, - const ClutterKeyEvent *key) -{ - ClutterInputMethodClass *im_class = CLUTTER_INPUT_METHOD_GET_CLASS (im); - - g_return_val_if_fail (CLUTTER_IS_INPUT_METHOD (im), FALSE); - g_return_val_if_fail (key != NULL, FALSE); - - if (clutter_event_get_flags ((ClutterEvent *) key) & CLUTTER_EVENT_FLAG_INPUT_METHOD) - return FALSE; - if (!im_class->filter_key_event) - return FALSE; - - return im_class->filter_key_event (im, (const ClutterEvent *) key); -} - -void -clutter_input_method_forward_key (ClutterInputMethod *im, - uint32_t keyval, - uint32_t keycode, - uint32_t state, - uint64_t time_, - gboolean press) -{ - ClutterInputMethodPrivate *priv; - ClutterInputDevice *keyboard; - ClutterSeat *seat; - ClutterEvent *event; - - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - - priv = clutter_input_method_get_instance_private (im); - if (!priv->focus) - return; - - seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); - keyboard = clutter_seat_get_keyboard (seat); - - event = clutter_event_key_new (press ? CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE, - CLUTTER_EVENT_FLAG_INPUT_METHOD, - time_, - keyboard, - (ClutterModifierSet) { 0, }, - state, - keyval, - keycode - 8, - keycode, - clutter_keysym_to_unicode (keyval)); - - clutter_event_put (event); - clutter_event_free (event); -} diff --git a/mutter/clutter/clutter/clutter-input-method.h b/mutter/clutter/clutter/clutter-input-method.h deleted file mode 100644 index cce21cd..0000000 --- a/mutter/clutter/clutter/clutter-input-method.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2017,2018 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, see . - * - * Author: Carlos Garnacho - */ - -#pragma once - -#define CLUTTER_TYPE_INPUT_METHOD (clutter_input_method_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterInputMethod, clutter_input_method, - CLUTTER, INPUT_METHOD, GObject) - -typedef struct _ClutterInputMethodClass ClutterInputMethodClass; - -struct _ClutterInputMethodClass -{ - GObjectClass parent_class; - - void (* focus_in) (ClutterInputMethod *im, - ClutterInputFocus *actor); - void (* focus_out) (ClutterInputMethod *im); - - void (* reset) (ClutterInputMethod *im); - - void (* set_cursor_location) (ClutterInputMethod *im, - const graphene_rect_t *rect); - void (* set_surrounding) (ClutterInputMethod *im, - const gchar *text, - guint cursor, - guint anchor); - void (* update_content_hints) (ClutterInputMethod *im, - ClutterInputContentHintFlags hint); - void (* update_content_purpose) (ClutterInputMethod *im, - ClutterInputContentPurpose purpose); - - gboolean (* filter_key_event) (ClutterInputMethod *im, - const ClutterEvent *key); -}; - -CLUTTER_EXPORT -void clutter_input_method_focus_in (ClutterInputMethod *im, - ClutterInputFocus *focus); -CLUTTER_EXPORT -void clutter_input_method_focus_out (ClutterInputMethod *im); - -CLUTTER_EXPORT -void clutter_input_method_commit (ClutterInputMethod *im, - const gchar *text); -CLUTTER_EXPORT -void clutter_input_method_delete_surrounding (ClutterInputMethod *im, - int offset, - guint len); -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, - unsigned int anchor, - ClutterPreeditResetMode mode); - -CLUTTER_EXPORT -void clutter_input_method_notify_key_event (ClutterInputMethod *im, - const ClutterEvent *event, - gboolean filtered); -CLUTTER_EXPORT -void clutter_input_method_set_input_panel_state (ClutterInputMethod *im, - ClutterInputPanelState state); - -CLUTTER_EXPORT -void clutter_input_method_forward_key (ClutterInputMethod *im, - uint32_t keyval, - uint32_t keycode, - uint32_t state, - uint64_t time_, - gboolean press); diff --git a/mutter/clutter/clutter/clutter-input-only-action.c b/mutter/clutter/clutter/clutter-input-only-action.c deleted file mode 100644 index 0af027c..0000000 --- a/mutter/clutter/clutter/clutter-input-only-action.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2022 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 . - */ - -#include "config.h" - -#include "clutter/clutter-input-only-action.h" - -#include "clutter/clutter-action-private.h" -#include "clutter/clutter.h" - -struct _ClutterInputOnlyAction -{ - ClutterAction parent; - - ClutterInputOnlyHandleEvent handle_event; - gpointer user_data; - GDestroyNotify user_data_destroy; -}; - -G_DEFINE_TYPE (ClutterInputOnlyAction, clutter_input_only_action, - CLUTTER_TYPE_ACTION) - -static void -clutter_input_only_action_dispose (GObject *object) -{ - ClutterInputOnlyAction *input_only_action = - CLUTTER_INPUT_ONLY_ACTION (object); - - if (input_only_action->user_data_destroy) - { - g_clear_pointer (&input_only_action->user_data, - input_only_action->user_data_destroy); - } - - G_OBJECT_CLASS (clutter_input_only_action_parent_class)->dispose (object); -} - -static gboolean -clutter_input_only_action_handle_event (ClutterAction *action, - const ClutterEvent *event) -{ - ClutterInputOnlyAction *input_only_action = - CLUTTER_INPUT_ONLY_ACTION (action); - - return input_only_action->handle_event (event, input_only_action->user_data); -} - -static void -clutter_input_only_action_class_init (ClutterInputOnlyActionClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - ClutterActionClass *action_class = CLUTTER_ACTION_CLASS (klass); - - object_class->dispose = clutter_input_only_action_dispose; - - action_class->handle_event = clutter_input_only_action_handle_event; -} - -static void -clutter_input_only_action_init (ClutterInputOnlyAction *input_only_action) -{ -} - -ClutterInputOnlyAction * -clutter_input_only_action_new (ClutterInputOnlyHandleEvent handle_event, - gpointer user_data, - GDestroyNotify user_data_destroy) -{ - ClutterInputOnlyAction *input_only_action; - - input_only_action = g_object_new (CLUTTER_TYPE_INPUT_ONLY_ACTION, NULL); - input_only_action->handle_event = handle_event; - input_only_action->user_data = user_data; - input_only_action->user_data_destroy = user_data_destroy; - clutter_action_set_phase (CLUTTER_ACTION (input_only_action), - CLUTTER_PHASE_CAPTURE); - - return input_only_action; -} diff --git a/mutter/clutter/clutter/clutter-input-only-action.h b/mutter/clutter/clutter/clutter-input-only-action.h deleted file mode 100644 index f86e108..0000000 --- a/mutter/clutter/clutter/clutter-input-only-action.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2022 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 . - */ - -#pragma once - -#include "clutter/clutter.h" - -typedef gboolean (* ClutterInputOnlyHandleEvent) (const ClutterEvent *event, - gpointer user_data); - -#define CLUTTER_TYPE_INPUT_ONLY_ACTION (clutter_input_only_action_get_type ()) -G_DECLARE_FINAL_TYPE (ClutterInputOnlyAction, clutter_input_only_action, - CLUTTER, INPUT_ONLY_ACTION, ClutterAction) - -ClutterInputOnlyAction * clutter_input_only_action_new (ClutterInputOnlyHandleEvent handle_event, - gpointer user_data, - GDestroyNotify destroy); diff --git a/mutter/clutter/clutter/clutter-input-only-actor.c b/mutter/clutter/clutter/clutter-input-only-actor.c deleted file mode 100644 index 7165dcc..0000000 --- a/mutter/clutter/clutter/clutter-input-only-actor.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2022 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 . - */ - -#include "config.h" - -#include "clutter/clutter-input-only-actor.h" - -#include "clutter/clutter-input-only-action.h" - -struct _ClutterInputOnlyActor -{ - ClutterActor parent; -}; - -G_DEFINE_TYPE (ClutterInputOnlyActor, clutter_input_only_actor, - CLUTTER_TYPE_ACTOR) - -static void -clutter_input_only_actor_class_init (ClutterInputOnlyActorClass *klass) -{ -} - -static void -clutter_input_only_actor_init (ClutterInputOnlyActor *input_only_actor) -{ -} - -ClutterInputOnlyActor * -clutter_input_only_actor_new (ClutterInputOnlyHandleEvent handle_event, - gpointer user_data, - GDestroyNotify user_data_destroy) -{ - ClutterInputOnlyAction *input_only_action; - - input_only_action = clutter_input_only_action_new (handle_event, - user_data, - user_data_destroy); - return g_object_new (CLUTTER_TYPE_INPUT_ONLY_ACTOR, - "reactive", TRUE, - "actions", input_only_action, - NULL); -} diff --git a/mutter/clutter/clutter/clutter-input-only-actor.h b/mutter/clutter/clutter/clutter-input-only-actor.h deleted file mode 100644 index 1c45674..0000000 --- a/mutter/clutter/clutter/clutter-input-only-actor.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2022 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 . - */ - -#pragma once - -#include "clutter/clutter.h" -#include "clutter/clutter-stage-private.h" - -#define CLUTTER_TYPE_INPUT_ONLY_ACTOR (clutter_input_only_actor_get_type ()) -G_DECLARE_FINAL_TYPE (ClutterInputOnlyActor, clutter_input_only_actor, - CLUTTER, INPUT_ONLY_ACTOR, ClutterActor) - -ClutterInputOnlyActor * clutter_input_only_actor_new (ClutterEventHandler event_handler, - gpointer user_data, - GDestroyNotify destroy); diff --git a/mutter/clutter/clutter/clutter-input-pointer-a11y-private.h b/mutter/clutter/clutter/clutter-input-pointer-a11y-private.h deleted file mode 100644 index 6e2b688..0000000 --- a/mutter/clutter/clutter/clutter-input-pointer-a11y-private.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2019 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, see . - * - * Author: Olivier Fourdan - */ - -#pragma once - -#include "clutter/clutter-types.h" -#include "clutter/clutter-enum-types.h" - -G_BEGIN_DECLS - -CLUTTER_EXPORT -void _clutter_input_pointer_a11y_add_device (ClutterInputDevice *device); -CLUTTER_EXPORT -void _clutter_input_pointer_a11y_remove_device (ClutterInputDevice *device); -CLUTTER_EXPORT -void _clutter_input_pointer_a11y_on_motion_event (ClutterInputDevice *device, - float x, - float y); -CLUTTER_EXPORT -void _clutter_input_pointer_a11y_on_button_event (ClutterInputDevice *device, - int button, - gboolean pressed); -CLUTTER_EXPORT -gboolean _clutter_is_input_pointer_a11y_enabled (ClutterInputDevice *device); - -CLUTTER_EXPORT -void clutter_input_pointer_a11y_update (ClutterInputDevice *device, - const ClutterEvent *event); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-input-pointer-a11y.c b/mutter/clutter/clutter/clutter-input-pointer-a11y.c deleted file mode 100644 index d5a27e2..0000000 --- a/mutter/clutter/clutter/clutter-input-pointer-a11y.c +++ /dev/null @@ -1,770 +0,0 @@ -/* - * Copyright (C) 2019 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, see . - * - * Author: Olivier Fourdan - * - * This reimplements in Clutter the same behavior as mousetweaks original - * implementation by Gerd Kohlberger - * mousetweaks Copyright (C) 2007-2010 Gerd Kohlberger - */ - -#include "config.h" - -#include "clutter/clutter-backend-private.h" -#include "clutter/clutter-context-private.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-input-device.h" -#include "clutter/clutter-input-device-private.h" -#include "clutter/clutter-input-pointer-a11y-private.h" -#include "clutter/clutter-main.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-virtual-input-device.h" - -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); - - return (settings.controls & CLUTTER_A11Y_SECONDARY_CLICK_ENABLED); -} - -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); - - return (settings.controls & CLUTTER_A11Y_DWELL_ENABLED); -} - -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); - - return settings.secondary_click_delay; -} - -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); - - return settings.dwell_delay; -} - -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); - - return settings.dwell_threshold; -} - -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); - - return settings.dwell_mode; -} - -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); - - return settings.dwell_click_type; -} - -static ClutterPointerA11yDwellClickType -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); - - if (direction == settings.dwell_gesture_single) - return CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY; - else if (direction == settings.dwell_gesture_double) - return CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE; - else if (direction == settings.dwell_gesture_drag) - return CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG; - else if (direction == settings.dwell_gesture_secondary) - return CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY; - - return CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE; -} - -static void -emit_button_press (ClutterInputDevice *device, - gint button) -{ - clutter_virtual_input_device_notify_button (device->accessibility_virtual_device, - g_get_monotonic_time (), - button, - CLUTTER_BUTTON_STATE_PRESSED); -} - -static void -emit_button_release (ClutterInputDevice *device, - gint button) -{ - clutter_virtual_input_device_notify_button (device->accessibility_virtual_device, - g_get_monotonic_time (), - button, - CLUTTER_BUTTON_STATE_RELEASED); -} - -static void -emit_button_click (ClutterInputDevice *device, - gint button) -{ - emit_button_press (device, button); - emit_button_release (device, button); -} - -static void -restore_dwell_position (ClutterInputDevice *device) -{ - clutter_virtual_input_device_notify_absolute_motion (device->accessibility_virtual_device, - g_get_monotonic_time (), - device->ptr_a11y_data->dwell_x, - device->ptr_a11y_data->dwell_y); -} - -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, - "ptr-a11y-timeout-stopped", - device, - CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK, - TRUE); - - return G_SOURCE_REMOVE; -} - -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, - "ptr-a11y-timeout-started", - device, - CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK, - delay); -} - -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, - "ptr-a11y-timeout-stopped", - device, - CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK, - FALSE); - } - device->ptr_a11y_data->secondary_click_triggered = FALSE; -} - -static gboolean -pointer_has_moved (ClutterInputDevice *device) -{ - float dx, dy; - gint threshold; - - dx = device->ptr_a11y_data->dwell_x - device->ptr_a11y_data->current_x; - dy = device->ptr_a11y_data->dwell_y - device->ptr_a11y_data->current_y; - threshold = get_dwell_threshold (device); - - /* Pythagorean theorem */ - return ((dx * dx) + (dy * dy)) > (threshold * threshold); -} - -static gboolean -is_secondary_click_pending (ClutterInputDevice *device) -{ - return device->ptr_a11y_data->secondary_click_timer != 0; -} - -static gboolean -is_secondary_click_triggered (ClutterInputDevice *device) -{ - return device->ptr_a11y_data->secondary_click_triggered; -} - -static gboolean -is_dwell_click_pending (ClutterInputDevice *device) -{ - return device->ptr_a11y_data->dwell_timer != 0; -} - -static gboolean -is_dwell_dragging (ClutterInputDevice *device) -{ - return device->ptr_a11y_data->dwell_drag_started; -} - -static gboolean -is_dwell_gesturing (ClutterInputDevice *device) -{ - return device->ptr_a11y_data->dwell_gesture_started; -} - -static gboolean -has_button_pressed (ClutterInputDevice *device) -{ - return device->ptr_a11y_data->n_btn_pressed > 0; -} - -static gboolean -should_start_secondary_click_timeout (ClutterInputDevice *device) -{ - return !is_dwell_dragging (device); -} - -static gboolean -should_start_dwell (ClutterInputDevice *device) -{ - /* We should trigger a dwell if we've not already started one, and if - * no button is currently pressed or we are in the middle of a dwell - * drag action. - */ - return !is_dwell_click_pending (device) && - (is_dwell_dragging (device) || - !has_button_pressed (device)); -} - -static gboolean -should_stop_dwell (ClutterInputDevice *device) -{ - /* We should stop a dwell if the motion exceeds the threshold, unless - * we've started a gesture, because we want to keep the original dwell - * location to both detect a gesture and restore the original pointer - * location once the gesture is finished. - */ - return pointer_has_moved (device) && - !is_dwell_gesturing (device); -} - - -static gboolean -should_update_dwell_position (ClutterInputDevice *device) -{ - return !is_dwell_gesturing (device) && - !is_dwell_click_pending (device) && - !is_secondary_click_pending (device); -} - -static void -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); - - dwell_click_type = settings.dwell_click_type; - switch (dwell_click_type) - { - case CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE: - case CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY: - case CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE: - dwell_click_type = CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY; - break; - - case CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG: - if (!is_dwell_dragging (device)) - dwell_click_type = CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY; - break; - - case CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY: - case CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE: - default: - break; - } - - if (dwell_click_type != settings.dwell_click_type) - { - settings.dwell_click_type = dwell_click_type; - clutter_seat_set_pointer_a11y_settings (seat, &settings); - - g_signal_emit_by_name (seat, - "ptr-a11y-dwell-click-type-changed", - dwell_click_type); - } -} - -static void -emit_dwell_click (ClutterInputDevice *device, - ClutterPointerA11yDwellClickType dwell_click_type) -{ - switch (dwell_click_type) - { - case CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY: - emit_button_click (device, CLUTTER_BUTTON_PRIMARY); - break; - - case CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE: - emit_button_click (device, CLUTTER_BUTTON_PRIMARY); - emit_button_click (device, CLUTTER_BUTTON_PRIMARY); - break; - - case CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG: - if (is_dwell_dragging (device)) - { - emit_button_release (device, CLUTTER_BUTTON_PRIMARY); - device->ptr_a11y_data->dwell_drag_started = FALSE; - } - else - { - emit_button_press (device, CLUTTER_BUTTON_PRIMARY); - device->ptr_a11y_data->dwell_drag_started = TRUE; - } - break; - - case CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY: - emit_button_click (device, CLUTTER_BUTTON_SECONDARY); - break; - - case CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE: - emit_button_click (device, CLUTTER_BUTTON_MIDDLE); - break; - - case CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE: - default: - break; - } -} - -static ClutterPointerA11yDwellDirection -get_dwell_direction (ClutterInputDevice *device) -{ - float dx, dy; - - dx = ABS (device->ptr_a11y_data->dwell_x - device->ptr_a11y_data->current_x); - dy = ABS (device->ptr_a11y_data->dwell_y - device->ptr_a11y_data->current_y); - - /* The pointer hasn't moved */ - if (!pointer_has_moved (device)) - return CLUTTER_A11Y_DWELL_DIRECTION_NONE; - - if (device->ptr_a11y_data->dwell_x < device->ptr_a11y_data->current_x) - { - if (dx > dy) - return CLUTTER_A11Y_DWELL_DIRECTION_LEFT; - } - else - { - if (dx > dy) - return CLUTTER_A11Y_DWELL_DIRECTION_RIGHT; - } - - if (device->ptr_a11y_data->dwell_y < device->ptr_a11y_data->current_y) - return CLUTTER_A11Y_DWELL_DIRECTION_UP; - - return CLUTTER_A11Y_DWELL_DIRECTION_DOWN; -} - -static gboolean -trigger_clear_dwell_gesture (gpointer data) -{ - ClutterInputDevice *device = data; - - device->ptr_a11y_data->dwell_timer = 0; - device->ptr_a11y_data->dwell_gesture_started = FALSE; - - return G_SOURCE_REMOVE; -} - -static gboolean -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); - emit_dwell_click (device, - get_dwell_click_type_for_direction (device, - direction)); - - /* Do not clear the gesture right away, otherwise we'll start another one */ - device->ptr_a11y_data->dwell_timer = - clutter_threads_add_timeout (delay, trigger_clear_dwell_gesture, device); - - g_signal_emit_by_name (seat, - "ptr-a11y-timeout-stopped", - device, - CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE, - TRUE); - - return G_SOURCE_REMOVE; -} - -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, - "ptr-a11y-timeout-started", - device, - CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE, - delay); -} - -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, - "ptr-a11y-timeout-stopped", - device, - CLUTTER_A11Y_TIMEOUT_TYPE_DWELL, - TRUE); - - if (get_dwell_mode (device) == CLUTTER_A11Y_DWELL_MODE_GESTURE) - { - if (is_dwell_dragging (device)) - emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG); - else - start_dwell_gesture_timeout (device); - } - else - { - emit_dwell_click (device, get_dwell_click_type (device)); - update_dwell_click_type (device); - } - - return G_SOURCE_REMOVE; -} - -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, - "ptr-a11y-timeout-started", - device, - CLUTTER_A11Y_TIMEOUT_TYPE_DWELL, - delay); -} - -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, - "ptr-a11y-timeout-stopped", - device, - CLUTTER_A11Y_TIMEOUT_TYPE_DWELL, - FALSE); - } -} - -static gboolean -trigger_dwell_position_timeout (gpointer data) -{ - ClutterInputDevice *device = data; - - device->ptr_a11y_data->dwell_position_timer = 0; - - if (is_dwell_click_enabled (device)) - { - if (!pointer_has_moved (device)) - start_dwell_timeout (device); - } - - return G_SOURCE_REMOVE; -} - -static void -start_dwell_position_timeout (ClutterInputDevice *device) -{ - device->ptr_a11y_data->dwell_position_timer = - clutter_threads_add_timeout (100, trigger_dwell_position_timeout, device); -} - -static void -stop_dwell_position_timeout (ClutterInputDevice *device) -{ - g_clear_handle_id (&device->ptr_a11y_data->dwell_position_timer, - g_source_remove); -} - -static void -update_dwell_position (ClutterInputDevice *device) -{ - device->ptr_a11y_data->dwell_x = device->ptr_a11y_data->current_x; - device->ptr_a11y_data->dwell_y = device->ptr_a11y_data->current_y; -} - -static void -update_current_position (ClutterInputDevice *device, - float x, - float y) -{ - device->ptr_a11y_data->current_x = x; - device->ptr_a11y_data->current_y = y; -} - -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); - if (core_pointer == NULL) - return FALSE; - - return (core_pointer == 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_POINTER_DEVICE); - - device->ptr_a11y_data = g_new0 (ClutterPtrA11yData, 1); -} - -void -_clutter_input_pointer_a11y_remove_device (ClutterInputDevice *device) -{ - if (!is_device_core_pointer (device)) - return; - - /* Terminate a drag if started */ - if (is_dwell_dragging (device)) - emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG); - - stop_dwell_position_timeout (device); - stop_dwell_timeout (device); - stop_secondary_click_timeout (device); - - g_clear_pointer (&device->ptr_a11y_data, g_free); -} - -void -_clutter_input_pointer_a11y_on_motion_event (ClutterInputDevice *device, - float x, - float y) -{ - if (!is_device_core_pointer (device)) - return; - - if (!_clutter_is_input_pointer_a11y_enabled (device)) - return; - - update_current_position (device, x, y); - - if (is_secondary_click_enabled (device)) - { - if (pointer_has_moved (device)) - stop_secondary_click_timeout (device); - } - - if (is_dwell_click_enabled (device)) - { - stop_dwell_position_timeout (device); - - if (should_stop_dwell (device)) - stop_dwell_timeout (device); - - if (should_start_dwell (device)) - start_dwell_position_timeout (device); - } - - if (should_update_dwell_position (device)) - update_dwell_position (device); -} - -void -_clutter_input_pointer_a11y_on_button_event (ClutterInputDevice *device, - int button, - gboolean pressed) -{ - if (!is_device_core_pointer (device)) - return; - - if (!_clutter_is_input_pointer_a11y_enabled (device)) - return; - - if (pressed) - { - device->ptr_a11y_data->n_btn_pressed++; - - stop_dwell_position_timeout (device); - - if (is_dwell_click_enabled (device)) - stop_dwell_timeout (device); - - if (is_dwell_dragging (device)) - stop_dwell_timeout (device); - - if (is_secondary_click_enabled (device)) - { - if (button == CLUTTER_BUTTON_PRIMARY) - { - if (should_start_secondary_click_timeout (device)) - start_secondary_click_timeout (device); - } - else if (is_secondary_click_pending (device)) - { - stop_secondary_click_timeout (device); - } - } - } - else - { - if (has_button_pressed (device)) - device->ptr_a11y_data->n_btn_pressed--; - - if (is_secondary_click_triggered (device)) - { - emit_button_click (device, CLUTTER_BUTTON_SECONDARY); - stop_secondary_click_timeout (device); - } - - if (is_secondary_click_pending (device)) - stop_secondary_click_timeout (device); - - if (is_dwell_dragging (device)) - emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG); - } -} - -gboolean -_clutter_is_input_pointer_a11y_enabled (ClutterInputDevice *device) -{ - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); - - return (is_secondary_click_enabled (device) || is_dwell_click_enabled (device)); -} - -void -clutter_input_pointer_a11y_update (ClutterInputDevice *device, - const ClutterEvent *event) -{ - - ClutterContext *clutter_context; - ClutterBackend *backend; - ClutterEventType event_type; - - g_return_if_fail (clutter_event_get_device (event) == device); - - if (!_clutter_is_input_pointer_a11y_enabled (device)) - return; - - if ((clutter_event_get_flags (event) & CLUTTER_EVENT_FLAG_SYNTHETIC) != 0) - return; - - clutter_context = _clutter_context_get_default (); - backend = clutter_context->backend; - - if (!clutter_backend_is_display_server (backend)) - return; - - event_type = clutter_event_type (event); - - if (event_type == CLUTTER_MOTION) - { - float x, y; - - clutter_event_get_coords (event, &x, &y); - _clutter_input_pointer_a11y_on_motion_event (device, x, y); - } - else if (event_type == CLUTTER_BUTTON_PRESS || - event_type == CLUTTER_BUTTON_RELEASE) - { - _clutter_input_pointer_a11y_on_button_event (device, - clutter_event_get_button (event), - event_type == CLUTTER_BUTTON_PRESS); - } -} diff --git a/mutter/clutter/clutter/clutter-interval.c b/mutter/clutter/clutter/clutter-interval.c deleted file mode 100644 index fe62ae3..0000000 --- a/mutter/clutter/clutter/clutter-interval.c +++ /dev/null @@ -1,1158 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2008 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterInterval: - * - * An object holding an interval of two values - * - * #ClutterInterval is a simple object that can hold two values - * defining an interval. #ClutterInterval can hold any value that - * can be enclosed inside a #GValue. - * - * Once a #ClutterInterval for a specific #GType has been instantiated - * the #ClutterInterval:value-type property cannot be changed anymore. - * - * #ClutterInterval starts with a floating reference; this means that - * any object taking a reference on a #ClutterInterval instance should - * also take ownership of the interval by using g_object_ref_sink(). - * - * #ClutterInterval can be subclassed to override the validation - * and value computation. - */ - -#include "config.h" - -#include -#include - -#include -#include -#include - -#include "clutter/clutter-color.h" -#include "clutter/clutter-interval.h" -#include "clutter/clutter-private.h" - -enum -{ - PROP_0, - - PROP_VALUE_TYPE, - PROP_INITIAL, - PROP_FINAL, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -enum -{ - INITIAL = 0, - FINAL, - RESULT, - - N_VALUES -}; - -typedef struct _ClutterIntervalPrivate -{ - GType value_type; - - GValue *values; -} ClutterIntervalPrivate; - -G_DEFINE_TYPE_WITH_CODE (ClutterInterval, - clutter_interval, - G_TYPE_INITIALLY_UNOWNED, - G_ADD_PRIVATE (ClutterInterval)); - - -static gboolean -clutter_interval_real_validate (ClutterInterval *interval, - GParamSpec *pspec) -{ - GType pspec_gtype = G_PARAM_SPEC_VALUE_TYPE (pspec); - - /* then check the fundamental types */ - switch (G_TYPE_FUNDAMENTAL (pspec_gtype)) - { - case G_TYPE_INT: - { - GParamSpecInt *pspec_int = G_PARAM_SPEC_INT (pspec); - gint a, b; - - a = b = 0; - clutter_interval_get_interval (interval, &a, &b); - if ((a >= pspec_int->minimum && a <= pspec_int->maximum) && - (b >= pspec_int->minimum && b <= pspec_int->maximum)) - return TRUE; - else - return FALSE; - } - break; - - case G_TYPE_INT64: - { - GParamSpecInt64 *pspec_int = G_PARAM_SPEC_INT64 (pspec); - gint64 a, b; - - a = b = 0; - clutter_interval_get_interval (interval, &a, &b); - if ((a >= pspec_int->minimum && a <= pspec_int->maximum) && - (b >= pspec_int->minimum && b <= pspec_int->maximum)) - return TRUE; - else - return FALSE; - } - break; - - case G_TYPE_UINT: - { - GParamSpecUInt *pspec_uint = G_PARAM_SPEC_UINT (pspec); - guint a, b; - - a = b = 0; - clutter_interval_get_interval (interval, &a, &b); - if ((a >= pspec_uint->minimum && a <= pspec_uint->maximum) && - (b >= pspec_uint->minimum && b <= pspec_uint->maximum)) - return TRUE; - else - return FALSE; - } - break; - - case G_TYPE_UINT64: - { - GParamSpecUInt64 *pspec_int = G_PARAM_SPEC_UINT64 (pspec); - guint64 a, b; - - a = b = 0; - clutter_interval_get_interval (interval, &a, &b); - if ((a >= pspec_int->minimum && a <= pspec_int->maximum) && - (b >= pspec_int->minimum && b <= pspec_int->maximum)) - return TRUE; - else - return FALSE; - } - break; - - case G_TYPE_CHAR: - { - GParamSpecChar *pspec_char = G_PARAM_SPEC_CHAR (pspec); - guchar a, b; - - a = b = 0; - clutter_interval_get_interval (interval, &a, &b); - if ((a >= pspec_char->minimum && a <= pspec_char->maximum) && - (b >= pspec_char->minimum && b <= pspec_char->maximum)) - return TRUE; - else - return FALSE; - } - break; - - case G_TYPE_UCHAR: - { - GParamSpecUChar *pspec_uchar = G_PARAM_SPEC_UCHAR (pspec); - guchar a, b; - - a = b = 0; - clutter_interval_get_interval (interval, &a, &b); - if ((a >= pspec_uchar->minimum && a <= pspec_uchar->maximum) && - (b >= pspec_uchar->minimum && b <= pspec_uchar->maximum)) - return TRUE; - else - return FALSE; - } - break; - - case G_TYPE_FLOAT: - { - GParamSpecFloat *pspec_flt = G_PARAM_SPEC_FLOAT (pspec); - float a, b; - - a = b = 0.f; - clutter_interval_get_interval (interval, &a, &b); - if ((a >= pspec_flt->minimum && a <= pspec_flt->maximum) && - (b >= pspec_flt->minimum && b <= pspec_flt->maximum)) - return TRUE; - else - return FALSE; - } - break; - - case G_TYPE_DOUBLE: - { - GParamSpecDouble *pspec_flt = G_PARAM_SPEC_DOUBLE (pspec); - double a, b; - - a = b = 0; - clutter_interval_get_interval (interval, &a, &b); - if ((a >= pspec_flt->minimum && a <= pspec_flt->maximum) && - (b >= pspec_flt->minimum && b <= pspec_flt->maximum)) - return TRUE; - else - return FALSE; - } - break; - - case G_TYPE_BOOLEAN: - return TRUE; - - default: - break; - } - - return TRUE; -} - -static gboolean -clutter_interval_real_compute_value (ClutterInterval *interval, - gdouble factor, - GValue *value) -{ - GValue *initial, *final; - GType value_type; - gboolean retval = FALSE; - - initial = clutter_interval_peek_initial_value (interval); - final = clutter_interval_peek_final_value (interval); - - value_type = clutter_interval_get_value_type (interval); - - if (_clutter_has_progress_function (value_type)) - { - retval = _clutter_run_progress_function (value_type, - initial, - final, - factor, - value); - if (retval) - return TRUE; - } - - switch (G_TYPE_FUNDAMENTAL (value_type)) - { - case G_TYPE_INT: - { - gint ia, ib, res; - - ia = g_value_get_int (initial); - ib = g_value_get_int (final); - - res = (factor * (ib - ia)) + ia; - - g_value_set_int (value, res); - - retval = TRUE; - } - break; - - case G_TYPE_CHAR: - { - gchar ia, ib, res; - - ia = g_value_get_schar (initial); - ib = g_value_get_schar (final); - - res = (factor * (ib - (gdouble) ia)) + ia; - - g_value_set_schar (value, res); - - retval = TRUE; - } - break; - - case G_TYPE_UINT: - { - guint ia, ib, res; - - ia = g_value_get_uint (initial); - ib = g_value_get_uint (final); - - res = (factor * (ib - (gdouble) ia)) + ia; - - g_value_set_uint (value, res); - - retval = TRUE; - } - break; - - case G_TYPE_UCHAR: - { - guchar ia, ib, res; - - ia = g_value_get_uchar (initial); - ib = g_value_get_uchar (final); - - res = (factor * (ib - (gdouble) ia)) + ia; - - g_value_set_uchar (value, res); - - retval = TRUE; - } - break; - - case G_TYPE_FLOAT: - case G_TYPE_DOUBLE: - { - gdouble ia, ib, res; - - if (value_type == G_TYPE_DOUBLE) - { - ia = g_value_get_double (initial); - ib = g_value_get_double (final); - } - else - { - ia = g_value_get_float (initial); - ib = g_value_get_float (final); - } - - res = (factor * (ib - ia)) + ia; - - if (value_type == G_TYPE_DOUBLE) - g_value_set_double (value, res); - else - g_value_set_float (value, res); - - retval = TRUE; - } - break; - - case G_TYPE_BOOLEAN: - if (factor > 0.5) - g_value_set_boolean (value, TRUE); - else - g_value_set_boolean (value, FALSE); - - retval = TRUE; - break; - - case G_TYPE_BOXED: - break; - - default: - break; - } - - /* We're trying to animate a property without knowing how to do that. Issue - * a warning with a hint to what could be done to fix that */ - if (G_UNLIKELY (retval == FALSE)) - { - g_warning ("%s: Could not compute progress between two %s. You can " - "register a progress function to instruct ClutterInterval " - "how to deal with this GType", - G_STRLOC, - g_type_name (value_type)); - } - - return retval; -} - -static void -clutter_interval_finalize (GObject *gobject) -{ - ClutterIntervalPrivate *priv = - clutter_interval_get_instance_private (CLUTTER_INTERVAL (gobject)); - - if (G_IS_VALUE (&priv->values[INITIAL])) - g_value_unset (&priv->values[INITIAL]); - - if (G_IS_VALUE (&priv->values[FINAL])) - g_value_unset (&priv->values[FINAL]); - - if (G_IS_VALUE (&priv->values[RESULT])) - g_value_unset (&priv->values[RESULT]); - - g_free (priv->values); - - G_OBJECT_CLASS (clutter_interval_parent_class)->finalize (gobject); -} - -static void -clutter_interval_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterInterval *self = CLUTTER_INTERVAL (gobject); - ClutterIntervalPrivate *priv = clutter_interval_get_instance_private (self); - - switch (prop_id) - { - case PROP_VALUE_TYPE: - priv->value_type = g_value_get_gtype (value); - break; - - case PROP_INITIAL: - if (g_value_get_boxed (value) != NULL) - clutter_interval_set_initial_value (self, g_value_get_boxed (value)); - else if (G_IS_VALUE (&priv->values[INITIAL])) - g_value_unset (&priv->values[INITIAL]); - break; - - case PROP_FINAL: - if (g_value_get_boxed (value) != NULL) - clutter_interval_set_final_value (self, g_value_get_boxed (value)); - else if (G_IS_VALUE (&priv->values[FINAL])) - g_value_unset (&priv->values[FINAL]); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_interval_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterIntervalPrivate *priv = - clutter_interval_get_instance_private (CLUTTER_INTERVAL (gobject)); - - switch (prop_id) - { - case PROP_VALUE_TYPE: - g_value_set_gtype (value, priv->value_type); - break; - - case PROP_INITIAL: - if (G_IS_VALUE (&priv->values[INITIAL])) - g_value_set_boxed (value, &priv->values[INITIAL]); - break; - - case PROP_FINAL: - if (G_IS_VALUE (&priv->values[FINAL])) - g_value_set_boxed (value, &priv->values[FINAL]); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_interval_class_init (ClutterIntervalClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - klass->validate = clutter_interval_real_validate; - klass->compute_value = clutter_interval_real_compute_value; - - gobject_class->set_property = clutter_interval_set_property, - gobject_class->get_property = clutter_interval_get_property; - gobject_class->finalize = clutter_interval_finalize; - - /** - * ClutterInterval:value-type: - * - * The type of the values in the interval. - */ - obj_props[PROP_VALUE_TYPE] = - g_param_spec_gtype ("value-type", NULL, NULL, - G_TYPE_NONE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterInterval:initial: - * - * The initial value of the interval. - */ - obj_props[PROP_INITIAL] = - g_param_spec_boxed ("initial", NULL, NULL, - G_TYPE_VALUE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterInterval:final: - * - * The final value of the interval. - */ - obj_props[PROP_FINAL] = - g_param_spec_boxed ("final", NULL, NULL, - G_TYPE_VALUE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); -} - -static void -clutter_interval_init (ClutterInterval *self) -{ - ClutterIntervalPrivate *priv = - clutter_interval_get_instance_private (self); - - priv->value_type = G_TYPE_INVALID; - priv->values = g_malloc0 (sizeof (GValue) * N_VALUES); -} - -static inline void -clutter_interval_set_value_internal (ClutterInterval *interval, - gint index_, - const GValue *value) -{ - ClutterIntervalPrivate *priv = - clutter_interval_get_instance_private (interval); - GType value_type; - - g_assert (index_ >= INITIAL && index_ <= RESULT); - - if (G_IS_VALUE (&priv->values[index_])) - g_value_unset (&priv->values[index_]); - - g_value_init (&priv->values[index_], priv->value_type); - - value_type = G_VALUE_TYPE (value); - if (value_type != priv->value_type || - !g_type_is_a (value_type, priv->value_type)) - { - if (g_value_type_compatible (value_type, priv->value_type)) - { - g_value_copy (value, &priv->values[index_]); - return; - } - - if (g_value_type_transformable (value_type, priv->value_type)) - { - GValue transform = G_VALUE_INIT; - - g_value_init (&transform, priv->value_type); - - if (g_value_transform (value, &transform)) - g_value_copy (&transform, &priv->values[index_]); - else - { - g_warning ("%s: Unable to convert a value of type '%s' into " - "the value type '%s' of the interval.", - G_STRLOC, - g_type_name (value_type), - g_type_name (priv->value_type)); - } - - g_value_unset (&transform); - } - } - else - g_value_copy (value, &priv->values[index_]); -} - -static inline void -clutter_interval_get_value_internal (ClutterInterval *interval, - gint index_, - GValue *value) -{ - ClutterIntervalPrivate *priv = - clutter_interval_get_instance_private (interval); - - g_assert (index_ >= INITIAL && index_ <= RESULT); - - g_value_copy (&priv->values[index_], value); -} - -static gboolean -clutter_interval_set_initial_internal (ClutterInterval *interval, - va_list *args) -{ - ClutterIntervalPrivate *priv = - clutter_interval_get_instance_private (interval); - GType gtype = priv->value_type; - GValue value = G_VALUE_INIT; - gchar *error; - - /* initial value */ - G_VALUE_COLLECT_INIT (&value, gtype, *args, 0, &error); - - if (error) - { - g_warning ("%s: %s", G_STRLOC, error); - - /* we leak the value here as it might not be in a valid state - * given the error and calling g_value_unset() might lead to - * undefined behaviour - */ - g_free (error); - return FALSE; - } - - clutter_interval_set_value_internal (interval, INITIAL, &value); - g_value_unset (&value); - - return TRUE; -} - -static gboolean -clutter_interval_set_final_internal (ClutterInterval *interval, - va_list *args) -{ - ClutterIntervalPrivate *priv = - clutter_interval_get_instance_private (interval); - GType gtype = priv->value_type; - GValue value = G_VALUE_INIT; - gchar *error; - - /* initial value */ - G_VALUE_COLLECT_INIT (&value, gtype, *args, 0, &error); - - if (error) - { - g_warning ("%s: %s", G_STRLOC, error); - - /* we leak the value here as it might not be in a valid state - * given the error and calling g_value_unset() might lead to - * undefined behaviour - */ - g_free (error); - return FALSE; - } - - clutter_interval_set_value_internal (interval, FINAL, &value); - g_value_unset (&value); - - return TRUE; -} - -static void -clutter_interval_get_interval_valist (ClutterInterval *interval, - va_list var_args) -{ - ClutterIntervalPrivate *priv = - clutter_interval_get_instance_private (interval); - GType gtype = priv->value_type; - GValue value = G_VALUE_INIT; - gchar *error; - - /* initial value */ - g_value_init (&value, gtype); - clutter_interval_get_initial_value (interval, &value); - G_VALUE_LCOPY (&value, var_args, 0, &error); - if (error) - { - g_warning ("%s: %s", G_STRLOC, error); - g_free (error); - g_value_unset (&value); - return; - } - - g_value_unset (&value); - - /* final value */ - g_value_init (&value, gtype); - clutter_interval_get_final_value (interval, &value); - G_VALUE_LCOPY (&value, var_args, 0, &error); - if (error) - { - g_warning ("%s: %s", G_STRLOC, error); - g_free (error); - g_value_unset (&value); - return; - } - - g_value_unset (&value); -} - -/** - * clutter_interval_new: - * @gtype: the type of the values in the interval - * @...: the initial value and the final value of the interval - * - * Creates a new #ClutterInterval holding values of type @gtype. - * - * This function avoids using a #GValue for the initial and final values - * of the interval: - * - * ```c - * interval = clutter_interval_new (G_TYPE_FLOAT, 0.0, 1.0); - * interval = clutter_interval_new (G_TYPE_BOOLEAN, FALSE, TRUE); - * interval = clutter_interval_new (G_TYPE_INT, 0, 360); - * ``` - * - * Return value: the newly created #ClutterInterval - */ -ClutterInterval * -clutter_interval_new (GType gtype, - ...) -{ - ClutterInterval *retval; - va_list args; - - g_return_val_if_fail (gtype != G_TYPE_INVALID, NULL); - - retval = g_object_new (CLUTTER_TYPE_INTERVAL, "value-type", gtype, NULL); - - va_start (args, gtype); - - if (!clutter_interval_set_initial_internal (retval, &args)) - goto out; - - clutter_interval_set_final_internal (retval, &args); - -out: - va_end (args); - - return retval; -} - -/** - * clutter_interval_new_with_values: - * @gtype: the type of the values in the interval - * @initial: (allow-none): a #GValue holding the initial value of the interval - * @final: (allow-none): a #GValue holding the final value of the interval - * - * Creates a new #ClutterInterval of type @gtype, between @initial - * and @final. - * - * This function is useful for language bindings. - * - * Return value: the newly created #ClutterInterval - */ -ClutterInterval * -clutter_interval_new_with_values (GType gtype, - const GValue *initial, - const GValue *final) -{ - g_return_val_if_fail (gtype != G_TYPE_INVALID, NULL); - g_return_val_if_fail (initial == NULL || G_VALUE_TYPE (initial) == gtype, NULL); - g_return_val_if_fail (final == NULL || G_VALUE_TYPE (final) == gtype, NULL); - - return g_object_new (CLUTTER_TYPE_INTERVAL, - "value-type", gtype, - "initial", initial, - "final", final, - NULL); -} - -/** - * clutter_interval_clone: - * @interval: a #ClutterInterval - * - * Creates a copy of @interval. - * - * Return value: (transfer full): the newly created #ClutterInterval - */ -ClutterInterval * -clutter_interval_clone (ClutterInterval *interval) -{ - ClutterInterval *retval; - GType gtype; - GValue *tmp; - ClutterIntervalPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), NULL); - priv = clutter_interval_get_instance_private (interval); - g_return_val_if_fail (priv->value_type != G_TYPE_INVALID, NULL); - - gtype = priv->value_type; - retval = g_object_new (CLUTTER_TYPE_INTERVAL, "value-type", gtype, NULL); - - tmp = clutter_interval_peek_initial_value (interval); - clutter_interval_set_initial_value (retval, tmp); - - tmp = clutter_interval_peek_final_value (interval); - clutter_interval_set_final_value (retval, tmp); - - return retval; -} - -/** - * clutter_interval_get_value_type: - * @interval: a #ClutterInterval - * - * Retrieves the #GType of the values inside @interval. - * - * Return value: the type of the value, or G_TYPE_INVALID - */ -GType -clutter_interval_get_value_type (ClutterInterval *interval) -{ - ClutterIntervalPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), G_TYPE_INVALID); - - priv = clutter_interval_get_instance_private (interval); - return priv->value_type; -} - -/** - * clutter_interval_set_initial_value: (rename-to clutter_interval_set_initial) - * @interval: a #ClutterInterval - * @value: a #GValue - * - * Sets the initial value of @interval to @value. The value is copied - * inside the #ClutterInterval. - */ -void -clutter_interval_set_initial_value (ClutterInterval *interval, - const GValue *value) -{ - g_return_if_fail (CLUTTER_IS_INTERVAL (interval)); - g_return_if_fail (value != NULL); - - clutter_interval_set_value_internal (interval, INITIAL, value); -} - -/** - * clutter_interval_set_initial: (skip) - * @interval: a #ClutterInterval - * @...: the initial value of the interval. - * - * Variadic arguments version of [method@Clutter.Interval.set_initial_value]. - * - * This function is meant as a convenience for the C API. - * - * Language bindings should use [method@Clutter.Interval.set_initial_value] - * instead. - */ -void -clutter_interval_set_initial (ClutterInterval *interval, - ...) -{ - va_list args; - - g_return_if_fail (CLUTTER_IS_INTERVAL (interval)); - - va_start (args, interval); - clutter_interval_set_initial_internal (interval, &args); - va_end (args); -} - -/** - * clutter_interval_get_initial_value: - * @interval: a #ClutterInterval - * @value: (out caller-allocates): a #GValue - * - * Retrieves the initial value of @interval and copies - * it into @value. - * - * The passed #GValue must be initialized to the value held by - * the #ClutterInterval. - */ -void -clutter_interval_get_initial_value (ClutterInterval *interval, - GValue *value) -{ - g_return_if_fail (CLUTTER_IS_INTERVAL (interval)); - g_return_if_fail (value != NULL); - - clutter_interval_get_value_internal (interval, INITIAL, value); -} - -/** - * clutter_interval_peek_initial_value: - * @interval: a #ClutterInterval - * - * Gets the pointer to the initial value of @interval - * - * Return value: (transfer none): the initial value of the interval. - * The value is owned by the #ClutterInterval and it should not be - * modified or freed - */ -GValue * -clutter_interval_peek_initial_value (ClutterInterval *interval) -{ - ClutterIntervalPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), NULL); - - priv = clutter_interval_get_instance_private (interval); - return priv->values + INITIAL; -} - -/** - * clutter_interval_set_final_value: (rename-to clutter_interval_set_final) - * @interval: a #ClutterInterval - * @value: a #GValue - * - * Sets the final value of @interval to @value. The value is - * copied inside the #ClutterInterval. - */ -void -clutter_interval_set_final_value (ClutterInterval *interval, - const GValue *value) -{ - g_return_if_fail (CLUTTER_IS_INTERVAL (interval)); - g_return_if_fail (value != NULL); - - clutter_interval_set_value_internal (interval, FINAL, value); -} - -/** - * clutter_interval_get_final_value: - * @interval: a #ClutterInterval - * @value: (out caller-allocates): a #GValue - * - * Retrieves the final value of @interval and copies - * it into @value. - * - * The passed #GValue must be initialized to the value held by - * the #ClutterInterval. - */ -void -clutter_interval_get_final_value (ClutterInterval *interval, - GValue *value) -{ - g_return_if_fail (CLUTTER_IS_INTERVAL (interval)); - g_return_if_fail (value != NULL); - - clutter_interval_get_value_internal (interval, FINAL, value); -} - -/** - * clutter_interval_set_final: (skip) - * @interval: a #ClutterInterval - * @...: the final value of the interval - * - * Variadic arguments version of [method@Clutter.Interval.set_final_value]. - * - * This function is meant as a convenience for the C API. - * - * Language bindings should use [method@Clutter.Interval.set_final_value] instead. - */ -void -clutter_interval_set_final (ClutterInterval *interval, - ...) -{ - va_list args; - - g_return_if_fail (CLUTTER_IS_INTERVAL (interval)); - - va_start (args, interval); - clutter_interval_set_final_internal (interval, &args); - va_end (args); -} - -/** - * clutter_interval_peek_final_value: - * @interval: a #ClutterInterval - * - * Gets the pointer to the final value of @interval - * - * Return value: (transfer none): the final value of the interval. - * The value is owned by the #ClutterInterval and it should not be - * modified or freed - */ -GValue * -clutter_interval_peek_final_value (ClutterInterval *interval) -{ - ClutterIntervalPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), NULL); - - priv = clutter_interval_get_instance_private (interval); - return priv->values + FINAL; -} - -/** - * clutter_interval_set_interval: - * @interval: a #ClutterInterval - * @...: the initial and final values of the interval - * - * Variable arguments wrapper for [method@Clutter.Interval.set_initial_value] - * and [method@Clutter.Interval.set_final_value] that avoids using the - * #GValue arguments: - * - * ```c - * clutter_interval_set_interval (interval, 0, 50); - * clutter_interval_set_interval (interval, 1.0, 0.0); - * clutter_interval_set_interval (interval, FALSE, TRUE); - * ``` - * - * This function is meant for the convenience of the C API; bindings - * should reimplement this function using the #GValue-based API. - */ -void -clutter_interval_set_interval (ClutterInterval *interval, - ...) -{ - ClutterIntervalPrivate *priv; - va_list args; - - g_return_if_fail (CLUTTER_IS_INTERVAL (interval)); - priv = clutter_interval_get_instance_private (interval); - g_return_if_fail (priv->value_type != G_TYPE_INVALID); - - va_start (args, interval); - - if (!clutter_interval_set_initial_internal (interval, &args)) - goto out; - - clutter_interval_set_final_internal (interval, &args); - -out: - va_end (args); -} - -/** - * clutter_interval_get_interval: - * @interval: a #ClutterInterval - * @...: return locations for the initial and final values of - * the interval - * - * Variable arguments wrapper for [method@Clutter.Interval.get_initial_value] - * and [method@Clutter.Interval.get_final_value] that avoids using the - * #GValue arguments: - * - * ```c - * gint a = 0, b = 0; - * clutter_interval_get_interval (interval, &a, &b); - * ``` - * - * This function is meant for the convenience of the C API; bindings - * should reimplement this function using the #GValue-based API. - */ -void -clutter_interval_get_interval (ClutterInterval *interval, - ...) -{ - ClutterIntervalPrivate *priv; - va_list args; - - g_return_if_fail (CLUTTER_IS_INTERVAL (interval)); - priv = clutter_interval_get_instance_private (interval); - g_return_if_fail (priv->value_type != G_TYPE_INVALID); - - va_start (args, interval); - clutter_interval_get_interval_valist (interval, args); - va_end (args); -} - -/** - * clutter_interval_validate: - * @interval: a #ClutterInterval - * @pspec: a #GParamSpec - * - * Validates the initial and final values of @interval against - * a #GParamSpec. - * - * Return value: %TRUE if the #ClutterInterval is valid, %FALSE otherwise - */ -gboolean -clutter_interval_validate (ClutterInterval *interval, - GParamSpec *pspec) -{ - g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), FALSE); - g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE); - - return CLUTTER_INTERVAL_GET_CLASS (interval)->validate (interval, pspec); -} - -/** - * clutter_interval_compute_value: - * @interval: a #ClutterInterval - * @factor: the progress factor, between 0 and 1 - * @value: (out caller-allocates): return location for an initialized #GValue - * - * Computes the value between the @interval boundaries given the - * progress @factor and copies it into @value. - * - * Return value: %TRUE if the operation was successful - */ -gboolean -clutter_interval_compute_value (ClutterInterval *interval, - gdouble factor, - GValue *value) -{ - g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), FALSE); - g_return_val_if_fail (value != NULL, FALSE); - - return CLUTTER_INTERVAL_GET_CLASS (interval)->compute_value (interval, - factor, - value); -} - -/** - * clutter_interval_compute: - * @interval: a #ClutterInterval - * @factor: the progress factor, between 0 and 1 - * - * Computes the value between the @interval boundaries given the - * progress @factor - * - * Unlike [method@Clutter.Interval.compute_value], this function will - * return a const pointer to the computed value - * - * You should use this function if you immediately pass the computed - * value to another function that makes a copy of it, like - * g_object_set_property() - * - * Return value: (transfer none): a pointer to the computed value, - * or %NULL if the computation was not successful - */ -const GValue * -clutter_interval_compute (ClutterInterval *interval, - gdouble factor) -{ - ClutterIntervalPrivate *priv; - GValue *value; - gboolean res; - - g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), NULL); - - priv = clutter_interval_get_instance_private (interval); - value = &(priv->values[RESULT]); - - if (G_VALUE_TYPE (value) == G_TYPE_INVALID) - g_value_init (value, priv->value_type); - - res = CLUTTER_INTERVAL_GET_CLASS (interval)->compute_value (interval, - factor, - value); - - if (res) - return priv->values + RESULT; - - return NULL; -} - -/** - * clutter_interval_is_valid: - * @interval: a #ClutterInterval - * - * Checks if the @interval has a valid initial and final values. - * - * Return value: %TRUE if the #ClutterInterval has an initial and - * final values, and %FALSE otherwise - */ -gboolean -clutter_interval_is_valid (ClutterInterval *interval) -{ - ClutterIntervalPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), FALSE); - - priv = clutter_interval_get_instance_private (interval); - - return G_IS_VALUE (&priv->values[INITIAL]) && - G_IS_VALUE (&priv->values[FINAL]); -} diff --git a/mutter/clutter/clutter/clutter-interval.h b/mutter/clutter/clutter/clutter-interval.h deleted file mode 100644 index e5898f8..0000000 --- a/mutter/clutter/clutter/clutter-interval.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2008 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_INTERVAL (clutter_interval_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterInterval, - clutter_interval, - CLUTTER, - INTERVAL, - GInitiallyUnowned) - -/** - * ClutterIntervalClass: - * @validate: virtual function for validating an interval - * using a #GParamSpec - * @compute_value: virtual function for computing the value - * inside an interval using an adimensional factor between 0 and 1 - * - * The #ClutterIntervalClass contains only private data. - */ -struct _ClutterIntervalClass -{ - /*< private >*/ - GInitiallyUnownedClass parent_class; - - /*< public >*/ - gboolean (* validate) (ClutterInterval *interval, - GParamSpec *pspec); - gboolean (* compute_value) (ClutterInterval *interval, - gdouble factor, - GValue *value); -}; - -CLUTTER_EXPORT -ClutterInterval *clutter_interval_new (GType gtype, - ...); -CLUTTER_EXPORT -ClutterInterval *clutter_interval_new_with_values (GType gtype, - const GValue *initial, - const GValue *final); - -CLUTTER_EXPORT -ClutterInterval *clutter_interval_clone (ClutterInterval *interval); - -CLUTTER_EXPORT -GType clutter_interval_get_value_type (ClutterInterval *interval); - -CLUTTER_EXPORT -void clutter_interval_set_initial (ClutterInterval *interval, - ...); -CLUTTER_EXPORT -void clutter_interval_set_initial_value (ClutterInterval *interval, - const GValue *value); -CLUTTER_EXPORT -void clutter_interval_get_initial_value (ClutterInterval *interval, - GValue *value); -CLUTTER_EXPORT -GValue * clutter_interval_peek_initial_value (ClutterInterval *interval); -CLUTTER_EXPORT -void clutter_interval_set_final (ClutterInterval *interval, - ...); -CLUTTER_EXPORT -void clutter_interval_set_final_value (ClutterInterval *interval, - const GValue *value); -CLUTTER_EXPORT -void clutter_interval_get_final_value (ClutterInterval *interval, - GValue *value); -CLUTTER_EXPORT -GValue * clutter_interval_peek_final_value (ClutterInterval *interval); - -CLUTTER_EXPORT -void clutter_interval_set_interval (ClutterInterval *interval, - ...); -CLUTTER_EXPORT -void clutter_interval_get_interval (ClutterInterval *interval, - ...); - -CLUTTER_EXPORT -gboolean clutter_interval_validate (ClutterInterval *interval, - GParamSpec *pspec); -CLUTTER_EXPORT -gboolean clutter_interval_compute_value (ClutterInterval *interval, - gdouble factor, - GValue *value); - -CLUTTER_EXPORT -const GValue * clutter_interval_compute (ClutterInterval *interval, - gdouble factor); - -CLUTTER_EXPORT -gboolean clutter_interval_is_valid (ClutterInterval *interval); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-keyframe-transition.c b/mutter/clutter/clutter/clutter-keyframe-transition.c deleted file mode 100644 index ebb67cb..0000000 --- a/mutter/clutter/clutter/clutter-keyframe-transition.c +++ /dev/null @@ -1,722 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -/** - * ClutterKeyframeTransition: - * - * Keyframe property transition - * - * #ClutterKeyframeTransition allows animating a property by defining - * "key frames": values at a normalized position on the transition - * duration. - * - * The #ClutterKeyframeTransition interpolates the value of the property - * to which it's bound across these key values. - * - * Setting up a #ClutterKeyframeTransition means providing the times, - * values, and easing modes between these key frames, for instance: - * - * ```c - * ClutterTransition *keyframe; - * - * keyframe = clutter_keyframe_transition_new ("opacity"); - * clutter_transition_set_from (keyframe, G_TYPE_UINT, 255); - * clutter_transition_set_to (keyframe, G_TYPE_UINT, 0); - * clutter_keyframe_transition_set (CLUTTER_KEYFRAME_TRANSITION (keyframe), - * G_TYPE_UINT, - * 1, /* number of key frames */ - * 0.5, 128, CLUTTER_EASE_IN_OUT_CUBIC); - * ``` - * - * The example above sets up a keyframe transition for the [property@Clutter.Actor:opacity] - * property of a #ClutterActor; the transition starts and sets the value of the - * property to fully transparent; between the start of the transition and its mid - * point, it will animate the property to half opacity, using an easy in/easy out - * progress. Once the transition reaches the mid point, it will linearly fade the - * actor out until it reaches the end of the transition. - * - * The #ClutterKeyframeTransition will add an implicit key frame between the last - * and the 1.0 value, to interpolate to the final value of the transition's - * interval.. - */ - -#include "config.h" - -#include "clutter/clutter-keyframe-transition.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-easing.h" -#include "clutter/clutter-interval.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-timeline.h" - -#include -#include - -typedef struct _KeyFrame -{ - double key; - - double start; - double end; - - ClutterAnimationMode mode; - - ClutterInterval *interval; -} KeyFrame; - -typedef struct _ClutterKeyframeTransitionPrivate -{ - GArray *frames; - - gint current_frame; -} ClutterKeyframeTransitionPrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterKeyframeTransition, - clutter_keyframe_transition, - CLUTTER_TYPE_PROPERTY_TRANSITION) - -static void -key_frame_free (gpointer data) -{ - if (data != NULL) - { - KeyFrame *key = data; - - g_object_unref (key->interval); - } -} - -static int -sort_by_key (gconstpointer a, - gconstpointer b) -{ - const KeyFrame *k_a = a; - const KeyFrame *k_b = b; - - if (fabs (k_a->key - k_b->key) < 0.0001) - return 0; - - if (k_a->key > k_b->key) - return 1; - - return -1; -} - -static inline void -clutter_keyframe_transition_sort_frames (ClutterKeyframeTransition *transition) -{ - ClutterKeyframeTransitionPrivate *priv = - clutter_keyframe_transition_get_instance_private (transition); - - if (priv->frames != NULL) - g_array_sort (priv->frames, sort_by_key); -} - -static inline void -clutter_keyframe_transition_init_frames (ClutterKeyframeTransition *transition, - gssize n_key_frames) -{ - ClutterKeyframeTransitionPrivate *priv = - clutter_keyframe_transition_get_instance_private (transition); - guint i; - - priv->frames = g_array_sized_new (FALSE, FALSE, - sizeof (KeyFrame), - n_key_frames); - g_array_set_clear_func (priv->frames, key_frame_free); - - /* we add an implicit key frame that goes to 1.0, so that the - * user doesn't have to do that an can simply add key frames - * in between 0.0 and 1.0 - */ - for (i = 0; i < n_key_frames + 1; i++) - { - KeyFrame frame; - - if (i == n_key_frames) - frame.key = 1.0; - else - frame.key = 0.0; - - frame.mode = CLUTTER_LINEAR; - frame.interval = NULL; - - g_array_insert_val (priv->frames, i, frame); - } -} - -static inline void -clutter_keyframe_transition_update_frames (ClutterKeyframeTransition *transition) -{ - ClutterKeyframeTransitionPrivate *priv = - clutter_keyframe_transition_get_instance_private (transition); - guint i; - - if (priv->frames == NULL) - return; - - for (i = 0; i < priv->frames->len; i++) - { - KeyFrame *cur_frame = &g_array_index (priv->frames, KeyFrame, i); - KeyFrame *prev_frame; - - if (i > 0) - prev_frame = &g_array_index (priv->frames, KeyFrame, i - 1); - else - prev_frame = NULL; - - if (prev_frame != NULL) - { - cur_frame->start = prev_frame->key; - - if (prev_frame->interval != NULL) - { - const GValue *value; - - value = clutter_interval_peek_final_value (prev_frame->interval); - - if (cur_frame->interval != NULL) - clutter_interval_set_initial_value (cur_frame->interval, value); - else - { - cur_frame->interval = - clutter_interval_new_with_values (G_VALUE_TYPE (value), value, NULL); - } - } - } - else - cur_frame->start = 0.0; - - cur_frame->end = cur_frame->key; - } -} - -static void -clutter_keyframe_transition_compute_value (ClutterTransition *transition, - ClutterAnimatable *animatable, - ClutterInterval *interval, - gdouble progress) -{ - ClutterKeyframeTransition *self = CLUTTER_KEYFRAME_TRANSITION (transition); - ClutterTimeline *timeline = CLUTTER_TIMELINE (transition); - ClutterKeyframeTransitionPrivate *priv = - clutter_keyframe_transition_get_instance_private (self); - ClutterTransitionClass *parent_class; - ClutterTimelineDirection direction; - ClutterInterval *real_interval; - gdouble real_progress; - double t, d, p; - KeyFrame *cur_frame = NULL; - - real_interval = interval; - real_progress = progress; - - /* if we don't have any keyframe, we behave like our parent class */ - if (priv->frames == NULL) - goto out; - - direction = clutter_timeline_get_direction (timeline); - - /* we need a normalized linear value */ - t = clutter_timeline_get_elapsed_time (timeline); - d = clutter_timeline_get_duration (timeline); - p = t / d; - - if (priv->current_frame < 0) - { - if (direction == CLUTTER_TIMELINE_FORWARD) - priv->current_frame = 0; - else - priv->current_frame = priv->frames->len - 1; - } - - cur_frame = &g_array_index (priv->frames, KeyFrame, priv->current_frame); - - /* skip to the next key frame, depending on the direction of the timeline */ - if (direction == CLUTTER_TIMELINE_FORWARD) - { - if (p > cur_frame->end) - { - priv->current_frame = MIN (priv->current_frame + 1, - priv->frames->len - 1); - - cur_frame = &g_array_index (priv->frames, KeyFrame, priv->current_frame); - } - } - else - { - if (p < cur_frame->start) - { - priv->current_frame = MAX (priv->current_frame - 1, 0); - - cur_frame = &g_array_index (priv->frames, KeyFrame, priv->current_frame); - } - } - - /* if we are at the boundaries of the transition, use the from and to - * value from the transition - */ - if (priv->current_frame == 0) - { - const GValue *value; - - value = clutter_interval_peek_initial_value (interval); - clutter_interval_set_initial_value (cur_frame->interval, value); - } - else if (priv->current_frame == priv->frames->len - 1) - { - const GValue *value; - - cur_frame->mode = clutter_timeline_get_progress_mode (timeline); - - value = clutter_interval_peek_final_value (interval); - clutter_interval_set_final_value (cur_frame->interval, value); - } - - /* update the interval to be used to interpolate the property */ - real_interval = cur_frame->interval; - - /* normalize the progress and apply the easing mode */ - real_progress = clutter_easing_for_mode ( cur_frame->mode, (p - cur_frame->start), (cur_frame->end - cur_frame->start)); - -#ifdef CLUTTER_ENABLE_DEBUG - if (CLUTTER_HAS_DEBUG (ANIMATION)) - { - char *from, *to; - const GValue *value; - - value = clutter_interval_peek_initial_value (cur_frame->interval); - from = g_strdup_value_contents (value); - - value = clutter_interval_peek_final_value (cur_frame->interval); - to = g_strdup_value_contents (value); - - CLUTTER_NOTE (ANIMATION, - "cur_frame [%d] => { %g, %s, %s %s %s } - " - "progress: %g, sub-progress: %g\n", - priv->current_frame, - cur_frame->key, - clutter_get_easing_name_for_mode (cur_frame->mode), - from, - direction == CLUTTER_TIMELINE_FORWARD ? "->" : "<-", - to, - p, real_progress); - - g_free (from); - g_free (to); - } -#endif /* CLUTTER_ENABLE_DEBUG */ - -out: - parent_class = - CLUTTER_TRANSITION_CLASS (clutter_keyframe_transition_parent_class); - parent_class->compute_value (transition, animatable, real_interval, real_progress); -} - -static void -clutter_keyframe_transition_started (ClutterTimeline *timeline) -{ - ClutterKeyframeTransition *transition; - ClutterKeyframeTransitionPrivate *priv; - - transition = CLUTTER_KEYFRAME_TRANSITION (timeline); - priv = clutter_keyframe_transition_get_instance_private (transition); - - priv->current_frame = -1; - - clutter_keyframe_transition_sort_frames (transition); - clutter_keyframe_transition_update_frames (transition); -} - -static void -clutter_keyframe_transition_completed (ClutterTimeline *timeline) -{ - ClutterKeyframeTransition *transition = CLUTTER_KEYFRAME_TRANSITION (timeline); - ClutterKeyframeTransitionPrivate *priv = - clutter_keyframe_transition_get_instance_private (transition); - - priv->current_frame = -1; -} - -static void -clutter_keyframe_transition_finalize (GObject *gobject) -{ - ClutterKeyframeTransition *transition = CLUTTER_KEYFRAME_TRANSITION (gobject); - ClutterKeyframeTransitionPrivate *priv = - clutter_keyframe_transition_get_instance_private (transition); - - if (priv->frames != NULL) - g_array_unref (priv->frames); - - G_OBJECT_CLASS (clutter_keyframe_transition_parent_class)->finalize (gobject); -} - -static void -clutter_keyframe_transition_class_init (ClutterKeyframeTransitionClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterTimelineClass *timeline_class = CLUTTER_TIMELINE_CLASS (klass); - ClutterTransitionClass *transition_class = CLUTTER_TRANSITION_CLASS (klass); - - gobject_class->finalize = clutter_keyframe_transition_finalize; - - timeline_class->started = clutter_keyframe_transition_started; - timeline_class->completed = clutter_keyframe_transition_completed; - - transition_class->compute_value = clutter_keyframe_transition_compute_value; -} - -static void -clutter_keyframe_transition_init (ClutterKeyframeTransition *self) -{ -} - -/** - * clutter_keyframe_transition_new: - * @property_name: the property to animate - * - * Creates a new #ClutterKeyframeTransition for @property_name. - * - * Return value: (transfer full): the newly allocated - * #ClutterKeyframeTransition instance. Use g_object_unref() when - * done to free its resources. - */ -ClutterTransition * -clutter_keyframe_transition_new (const char *property_name) -{ - return g_object_new (CLUTTER_TYPE_KEYFRAME_TRANSITION, - "property-name", property_name, - NULL); -} - -/** - * clutter_keyframe_transition_set_key_frames: - * @transition: a #ClutterKeyframeTransition - * @n_key_frames: the number of values - * @key_frames: (array length=n_key_frames): an array of keys between 0.0 - * and 1.0, one for each key frame - * - * Sets the keys for each key frame inside @transition. - * - * If @transition does not hold any key frame, @n_key_frames key frames - * will be created; if @transition already has key frames, @key_frames must - * have at least as many elements as the number of key frames. - */ -void -clutter_keyframe_transition_set_key_frames (ClutterKeyframeTransition *transition, - guint n_key_frames, - const double *key_frames) -{ - ClutterKeyframeTransitionPrivate *priv; - guint i; - - g_return_if_fail (CLUTTER_IS_KEYFRAME_TRANSITION (transition)); - g_return_if_fail (n_key_frames > 0); - g_return_if_fail (key_frames != NULL); - - priv = clutter_keyframe_transition_get_instance_private (transition); - - if (priv->frames == NULL) - clutter_keyframe_transition_init_frames (transition, n_key_frames); - else - g_return_if_fail (n_key_frames == priv->frames->len - 1); - - for (i = 0; i < n_key_frames; i++) - { - KeyFrame *frame = &g_array_index (priv->frames, KeyFrame, i); - - frame->key = key_frames[i]; - } -} - -/** - * clutter_keyframe_transition_set_values: - * @transition: a #ClutterKeyframeTransition - * @n_values: the number of values - * @values: (array length=n_values): an array of values, one for each - * key frame - * - * Sets the values for each key frame inside @transition. - * - * If @transition does not hold any key frame, @n_values key frames will - * be created; if @transition already has key frames, @values must have - * at least as many elements as the number of key frames. - */ -void -clutter_keyframe_transition_set_values (ClutterKeyframeTransition *transition, - guint n_values, - const GValue *values) -{ - ClutterKeyframeTransitionPrivate *priv; - guint i; - - g_return_if_fail (CLUTTER_IS_KEYFRAME_TRANSITION (transition)); - g_return_if_fail (n_values > 0); - g_return_if_fail (values != NULL); - - priv = clutter_keyframe_transition_get_instance_private (transition); - - if (priv->frames == NULL) - clutter_keyframe_transition_init_frames (transition, n_values); - else - g_return_if_fail (n_values == priv->frames->len - 1); - - for (i = 0; i < n_values; i++) - { - KeyFrame *frame = &g_array_index (priv->frames, KeyFrame, i); - - if (frame->interval) - clutter_interval_set_final_value (frame->interval, &values[i]); - else - frame->interval = - clutter_interval_new_with_values (G_VALUE_TYPE (&values[i]), NULL, - &values[i]); - } -} - -/** - * clutter_keyframe_transition_set_modes: - * @transition: a #ClutterKeyframeTransition - * @n_modes: the number of easing modes - * @modes: (array length=n_modes): an array of easing modes, one for - * each key frame - * - * Sets the easing modes for each key frame inside @transition. - * - * If @transition does not hold any key frame, @n_modes key frames will - * be created; if @transition already has key frames, @modes must have - * at least as many elements as the number of key frames. - */ -void -clutter_keyframe_transition_set_modes (ClutterKeyframeTransition *transition, - guint n_modes, - const ClutterAnimationMode *modes) -{ - ClutterKeyframeTransitionPrivate *priv; - guint i; - - g_return_if_fail (CLUTTER_IS_KEYFRAME_TRANSITION (transition)); - g_return_if_fail (n_modes > 0); - g_return_if_fail (modes != NULL); - - priv = clutter_keyframe_transition_get_instance_private (transition); - - if (priv->frames == NULL) - clutter_keyframe_transition_init_frames (transition, n_modes); - else - g_return_if_fail (n_modes == priv->frames->len - 1); - - for (i = 0; i < n_modes; i++) - { - KeyFrame *frame = &g_array_index (priv->frames, KeyFrame, i); - - frame->mode = modes[i]; - } -} - -/** - * clutter_keyframe_transition_set: (skip) - * @transition: a #ClutterKeyframeTransition - * @gtype: the type of the values to use for the key frames - * @n_key_frames: the number of key frames between the initial - * and final values - * @...: a list of tuples, containing the key frame index, the value - * at the key frame, and the animation mode - * - * Sets the key frames of the @transition. - * - * This variadic arguments function is a convenience for C developers; - * language bindings should use [method@Clutter.KeyframeTransition.set_key_frames], - * [method@Clutter.KeyframeTransition.set_modes], and - * [method@Clutter.KeyframeTransition.set_values] instead. - */ -void -clutter_keyframe_transition_set (ClutterKeyframeTransition *transition, - GType gtype, - guint n_key_frames, - ...) -{ - ClutterKeyframeTransitionPrivate *priv; - va_list args; - guint i; - - g_return_if_fail (CLUTTER_IS_KEYFRAME_TRANSITION (transition)); - g_return_if_fail (gtype != G_TYPE_INVALID); - g_return_if_fail (n_key_frames > 0); - - priv = clutter_keyframe_transition_get_instance_private (transition); - - if (priv->frames == NULL) - clutter_keyframe_transition_init_frames (transition, n_key_frames); - else - g_return_if_fail (n_key_frames == priv->frames->len - 1); - - va_start (args, n_key_frames); - - for (i = 0; i < n_key_frames; i++) - { - KeyFrame *frame = &g_array_index (priv->frames, KeyFrame, i); - GValue value = G_VALUE_INIT; - char *error = NULL; - - frame->key = va_arg (args, double); - - G_VALUE_COLLECT_INIT (&value, gtype, args, 0, &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRLOC, error); - g_free (error); - break; - } - - frame->mode = va_arg (args, ClutterAnimationMode); - - g_clear_object (&frame->interval); - frame->interval = clutter_interval_new_with_values (gtype, NULL, &value); - - g_value_unset (&value); - } - - va_end (args); -} - -/** - * clutter_keyframe_transition_clear: - * @transition: a #ClutterKeyframeTransition - * - * Removes all key frames from @transition. - */ -void -clutter_keyframe_transition_clear (ClutterKeyframeTransition *transition) -{ - ClutterKeyframeTransitionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_KEYFRAME_TRANSITION (transition)); - - priv = clutter_keyframe_transition_get_instance_private (transition); - if (priv->frames != NULL) - { - g_array_unref (priv->frames); - priv->frames = NULL; - } -} - -/** - * clutter_keyframe_transition_get_n_key_frames: - * @transition: a #ClutterKeyframeTransition - * - * Retrieves the number of key frames inside @transition. - * - * Return value: the number of key frames - */ -guint -clutter_keyframe_transition_get_n_key_frames (ClutterKeyframeTransition *transition) -{ - ClutterKeyframeTransitionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_KEYFRAME_TRANSITION (transition), 0); - - priv = clutter_keyframe_transition_get_instance_private (transition); - if (priv->frames == NULL) - return 0; - - return priv->frames->len - 1; -} - -/** - * clutter_keyframe_transition_set_key_frame: - * @transition: a #ClutterKeyframeTransition - * @index_: the index of the key frame - * @key: the key of the key frame - * @mode: the easing mode of the key frame - * @value: a #GValue containing the value of the key frame - * - * Sets the details of the key frame at @index_ inside @transition. - * - * The @transition must already have a key frame at @index_, and @index_ - * must be smaller than the number of key frames inside @transition. - */ -void -clutter_keyframe_transition_set_key_frame (ClutterKeyframeTransition *transition, - guint index_, - double key, - ClutterAnimationMode mode, - const GValue *value) -{ - ClutterKeyframeTransitionPrivate *priv; - KeyFrame *frame; - - g_return_if_fail (CLUTTER_IS_KEYFRAME_TRANSITION (transition)); - - priv = clutter_keyframe_transition_get_instance_private (transition); - g_return_if_fail (priv->frames != NULL); - g_return_if_fail (index_ < priv->frames->len - 1); - - frame = &g_array_index (priv->frames, KeyFrame, index_); - frame->key = key; - frame->mode = mode; - clutter_interval_set_final_value (frame->interval, value); -} - -/** - * clutter_keyframe_transition_get_key_frame: - * @transition: a #ClutterKeyframeTransition - * @index_: the index of the key frame - * @key: (out) (allow-none): return location for the key, or %NULL - * @mode: (out) (allow-none): return location for the easing mode, or %NULL - * @value: (out caller-allocates): a #GValue initialized with the type of - * the values - * - * Retrieves the details of the key frame at @index_ inside @transition. - * - * The @transition must already have key frames set, and @index_ must be - * smaller than the number of key frames. - */ -void -clutter_keyframe_transition_get_key_frame (ClutterKeyframeTransition *transition, - guint index_, - double *key, - ClutterAnimationMode *mode, - GValue *value) -{ - ClutterKeyframeTransitionPrivate *priv; - const KeyFrame *frame; - - g_return_if_fail (CLUTTER_IS_KEYFRAME_TRANSITION (transition)); - - priv = clutter_keyframe_transition_get_instance_private (transition); - g_return_if_fail (priv->frames != NULL); - g_return_if_fail (index_ < priv->frames->len - 1); - - frame = &g_array_index (priv->frames, KeyFrame, index_); - - if (key != NULL) - *key = frame->key; - - if (mode != NULL) - *mode = frame->mode; - - if (value != NULL) - clutter_interval_get_final_value (frame->interval, value); -} diff --git a/mutter/clutter/clutter/clutter-keyframe-transition.h b/mutter/clutter/clutter/clutter-keyframe-transition.h deleted file mode 100644 index 1a80523..0000000 --- a/mutter/clutter/clutter/clutter-keyframe-transition.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" -#include "clutter/clutter-property-transition.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_KEYFRAME_TRANSITION (clutter_keyframe_transition_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterKeyframeTransition, - clutter_keyframe_transition, - CLUTTER, - KEYFRAME_TRANSITION, - ClutterPropertyTransition) - - -/** - * ClutterKeyframeTransitionClass: - * - * The `ClutterKeyframeTransitionClass` structure contains only - * private data. - */ -struct _ClutterKeyframeTransitionClass -{ - /*< private >*/ - ClutterPropertyTransitionClass parent_class; -}; - -CLUTTER_EXPORT -ClutterTransition * clutter_keyframe_transition_new (const char *property_name); - -CLUTTER_EXPORT -void clutter_keyframe_transition_set_key_frames (ClutterKeyframeTransition *transition, - guint n_key_frames, - const double *key_frames); -CLUTTER_EXPORT -void clutter_keyframe_transition_set_values (ClutterKeyframeTransition *transition, - guint n_values, - const GValue *values); -CLUTTER_EXPORT -void clutter_keyframe_transition_set_modes (ClutterKeyframeTransition *transition, - guint n_modes, - const ClutterAnimationMode *modes); -CLUTTER_EXPORT -void clutter_keyframe_transition_set (ClutterKeyframeTransition *transition, - GType gtype, - guint n_key_frames, - ...); - -CLUTTER_EXPORT -void clutter_keyframe_transition_set_key_frame (ClutterKeyframeTransition *transition, - guint index_, - double key, - ClutterAnimationMode mode, - const GValue *value); -CLUTTER_EXPORT -void clutter_keyframe_transition_get_key_frame (ClutterKeyframeTransition *transition, - guint index_, - double *key, - ClutterAnimationMode *mode, - GValue *value); -CLUTTER_EXPORT -guint clutter_keyframe_transition_get_n_key_frames (ClutterKeyframeTransition *transition); - -CLUTTER_EXPORT -void clutter_keyframe_transition_clear (ClutterKeyframeTransition *transition); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-keymap-private.h b/mutter/clutter/clutter/clutter-keymap-private.h deleted file mode 100644 index 512c5dd..0000000 --- a/mutter/clutter/clutter/clutter-keymap-private.h +++ /dev/null @@ -1,26 +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, see . - * - */ - -#pragma once - -#include "clutter/clutter-keymap.h" - -CLUTTER_EXPORT -void clutter_keymap_set_lock_modifier_state (ClutterKeymap *keymap, - gboolean caps_lock_state, - gboolean num_lock_state); diff --git a/mutter/clutter/clutter/clutter-keymap.c b/mutter/clutter/clutter/clutter-keymap.c deleted file mode 100644 index a18571a..0000000 --- a/mutter/clutter/clutter/clutter-keymap.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2018 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, see . - * - * Author: Carlos Garnacho - */ - -#include "config.h" - -#include "clutter/clutter-keymap-private.h" -#include "clutter/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) - -enum -{ - STATE_CHANGED, - N_SIGNALS -}; - -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", NULL, NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_NUM_LOCK_STATE] = - g_param_spec_boolean ("num-lock-state", NULL, NULL, - 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), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -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; -} - -gboolean -clutter_keymap_get_caps_lock_state (ClutterKeymap *keymap) -{ - ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap); - - return priv->caps_lock_state; -} - -ClutterTextDirection -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); -} diff --git a/mutter/clutter/clutter/clutter-keymap.h b/mutter/clutter/clutter/clutter-keymap.h deleted file mode 100644 index 3601e6f..0000000 --- a/mutter/clutter/clutter/clutter-keymap.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2018 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, see . - * - * Author: Carlos Garnacho - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -#include "clutter/clutter-enums.h" -#include "clutter/clutter-macros.h" - - -typedef struct _ClutterKeymap ClutterKeymap; -typedef struct _ClutterKeymapClass ClutterKeymapClass; - -struct _ClutterKeymapClass -{ - GObjectClass parent_class; - - ClutterTextDirection (* get_direction) (ClutterKeymap *keymap); -}; - -#define CLUTTER_TYPE_KEYMAP (clutter_keymap_get_type ()) -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterKeymap, clutter_keymap, - CLUTTER, KEYMAP, - GObject) - -CLUTTER_EXPORT -gboolean clutter_keymap_get_num_lock_state (ClutterKeymap *keymap); - -CLUTTER_EXPORT -gboolean clutter_keymap_get_caps_lock_state (ClutterKeymap *keymap); - -ClutterTextDirection clutter_keymap_get_direction (ClutterKeymap *keymap); diff --git a/mutter/clutter/clutter/clutter-keyname-table.h b/mutter/clutter/clutter/clutter-keyname-table.h deleted file mode 100644 index 1dd41a6..0000000 --- a/mutter/clutter/clutter/clutter-keyname-table.h +++ /dev/null @@ -1,6827 +0,0 @@ -/* keyname-table.h: Generated by gen-keyname-table.pl from keynames.txt - * - * Date: Mon May 9 13:58:37 2022 - * - * Do not edit. - */ -static const char keynames[] = - "space\0" - "exclam\0" - "quotedbl\0" - "numbersign\0" - "dollar\0" - "percent\0" - "ampersand\0" - "apostrophe\0" - "quoteright\0" - "parenleft\0" - "parenright\0" - "asterisk\0" - "plus\0" - "comma\0" - "minus\0" - "period\0" - "slash\0" - "0\0" - "1\0" - "2\0" - "3\0" - "4\0" - "5\0" - "6\0" - "7\0" - "8\0" - "9\0" - "colon\0" - "semicolon\0" - "less\0" - "equal\0" - "greater\0" - "question\0" - "at\0" - "A\0" - "B\0" - "C\0" - "D\0" - "E\0" - "F\0" - "G\0" - "H\0" - "I\0" - "J\0" - "K\0" - "L\0" - "M\0" - "N\0" - "O\0" - "P\0" - "Q\0" - "R\0" - "S\0" - "T\0" - "U\0" - "V\0" - "W\0" - "X\0" - "Y\0" - "Z\0" - "bracketleft\0" - "backslash\0" - "bracketright\0" - "asciicircum\0" - "underscore\0" - "grave\0" - "quoteleft\0" - "a\0" - "b\0" - "c\0" - "d\0" - "e\0" - "f\0" - "g\0" - "h\0" - "i\0" - "j\0" - "k\0" - "l\0" - "m\0" - "n\0" - "o\0" - "p\0" - "q\0" - "r\0" - "s\0" - "t\0" - "u\0" - "v\0" - "w\0" - "x\0" - "y\0" - "z\0" - "braceleft\0" - "bar\0" - "braceright\0" - "asciitilde\0" - "nobreakspace\0" - "exclamdown\0" - "cent\0" - "sterling\0" - "currency\0" - "yen\0" - "brokenbar\0" - "section\0" - "diaeresis\0" - "copyright\0" - "ordfeminine\0" - "guillemotleft\0" - "notsign\0" - "hyphen\0" - "registered\0" - "macron\0" - "degree\0" - "plusminus\0" - "twosuperior\0" - "threesuperior\0" - "acute\0" - "mu\0" - "paragraph\0" - "periodcentered\0" - "cedilla\0" - "onesuperior\0" - "masculine\0" - "guillemotright\0" - "onequarter\0" - "onehalf\0" - "threequarters\0" - "questiondown\0" - "Agrave\0" - "Aacute\0" - "Acircumflex\0" - "Atilde\0" - "Adiaeresis\0" - "Aring\0" - "AE\0" - "Ccedilla\0" - "Egrave\0" - "Eacute\0" - "Ecircumflex\0" - "Ediaeresis\0" - "Igrave\0" - "Iacute\0" - "Icircumflex\0" - "Idiaeresis\0" - "Eth\0" - "ETH\0" - "Ntilde\0" - "Ograve\0" - "Oacute\0" - "Ocircumflex\0" - "Otilde\0" - "Odiaeresis\0" - "multiply\0" - "Ooblique\0" - "Oslash\0" - "Ugrave\0" - "Uacute\0" - "Ucircumflex\0" - "Udiaeresis\0" - "Yacute\0" - "Thorn\0" - "THORN\0" - "ssharp\0" - "agrave\0" - "aacute\0" - "acircumflex\0" - "atilde\0" - "adiaeresis\0" - "aring\0" - "ae\0" - "ccedilla\0" - "egrave\0" - "eacute\0" - "ecircumflex\0" - "ediaeresis\0" - "igrave\0" - "iacute\0" - "icircumflex\0" - "idiaeresis\0" - "eth\0" - "ntilde\0" - "ograve\0" - "oacute\0" - "ocircumflex\0" - "otilde\0" - "odiaeresis\0" - "division\0" - "ooblique\0" - "oslash\0" - "ugrave\0" - "uacute\0" - "ucircumflex\0" - "udiaeresis\0" - "yacute\0" - "thorn\0" - "ydiaeresis\0" - "Aogonek\0" - "breve\0" - "Lstroke\0" - "Lcaron\0" - "Sacute\0" - "Scaron\0" - "Scedilla\0" - "Tcaron\0" - "Zacute\0" - "Zcaron\0" - "Zabovedot\0" - "aogonek\0" - "ogonek\0" - "lstroke\0" - "lcaron\0" - "sacute\0" - "caron\0" - "scaron\0" - "scedilla\0" - "tcaron\0" - "zacute\0" - "doubleacute\0" - "zcaron\0" - "zabovedot\0" - "Racute\0" - "Abreve\0" - "Lacute\0" - "Cacute\0" - "Ccaron\0" - "Eogonek\0" - "Ecaron\0" - "Dcaron\0" - "Dstroke\0" - "Nacute\0" - "Ncaron\0" - "Odoubleacute\0" - "Rcaron\0" - "Uring\0" - "Udoubleacute\0" - "Tcedilla\0" - "racute\0" - "abreve\0" - "lacute\0" - "cacute\0" - "ccaron\0" - "eogonek\0" - "ecaron\0" - "dcaron\0" - "dstroke\0" - "nacute\0" - "ncaron\0" - "odoubleacute\0" - "rcaron\0" - "uring\0" - "udoubleacute\0" - "tcedilla\0" - "abovedot\0" - "Hstroke\0" - "Hcircumflex\0" - "Iabovedot\0" - "Gbreve\0" - "Jcircumflex\0" - "hstroke\0" - "hcircumflex\0" - "idotless\0" - "gbreve\0" - "jcircumflex\0" - "Cabovedot\0" - "Ccircumflex\0" - "Gabovedot\0" - "Gcircumflex\0" - "Ubreve\0" - "Scircumflex\0" - "cabovedot\0" - "ccircumflex\0" - "gabovedot\0" - "gcircumflex\0" - "ubreve\0" - "scircumflex\0" - "kappa\0" - "kra\0" - "Rcedilla\0" - "Itilde\0" - "Lcedilla\0" - "Emacron\0" - "Gcedilla\0" - "Tslash\0" - "rcedilla\0" - "itilde\0" - "lcedilla\0" - "emacron\0" - "gcedilla\0" - "tslash\0" - "ENG\0" - "eng\0" - "Amacron\0" - "Iogonek\0" - "Eabovedot\0" - "Imacron\0" - "Ncedilla\0" - "Omacron\0" - "Kcedilla\0" - "Uogonek\0" - "Utilde\0" - "Umacron\0" - "amacron\0" - "iogonek\0" - "eabovedot\0" - "imacron\0" - "ncedilla\0" - "omacron\0" - "kcedilla\0" - "uogonek\0" - "utilde\0" - "umacron\0" - "overline\0" - "kana_fullstop\0" - "kana_openingbracket\0" - "kana_closingbracket\0" - "kana_comma\0" - "kana_conjunctive\0" - "kana_middledot\0" - "kana_WO\0" - "kana_a\0" - "kana_i\0" - "kana_u\0" - "kana_e\0" - "kana_o\0" - "kana_ya\0" - "kana_yu\0" - "kana_yo\0" - "kana_tsu\0" - "kana_tu\0" - "prolongedsound\0" - "kana_A\0" - "kana_I\0" - "kana_U\0" - "kana_E\0" - "kana_O\0" - "kana_KA\0" - "kana_KI\0" - "kana_KU\0" - "kana_KE\0" - "kana_KO\0" - "kana_SA\0" - "kana_SHI\0" - "kana_SU\0" - "kana_SE\0" - "kana_SO\0" - "kana_TA\0" - "kana_CHI\0" - "kana_TI\0" - "kana_TSU\0" - "kana_TU\0" - "kana_TE\0" - "kana_TO\0" - "kana_NA\0" - "kana_NI\0" - "kana_NU\0" - "kana_NE\0" - "kana_NO\0" - "kana_HA\0" - "kana_HI\0" - "kana_FU\0" - "kana_HU\0" - "kana_HE\0" - "kana_HO\0" - "kana_MA\0" - "kana_MI\0" - "kana_MU\0" - "kana_ME\0" - "kana_MO\0" - "kana_YA\0" - "kana_YU\0" - "kana_YO\0" - "kana_RA\0" - "kana_RI\0" - "kana_RU\0" - "kana_RE\0" - "kana_RO\0" - "kana_WA\0" - "kana_N\0" - "voicedsound\0" - "semivoicedsound\0" - "Arabic_comma\0" - "Arabic_semicolon\0" - "Arabic_question_mark\0" - "Arabic_hamza\0" - "Arabic_maddaonalef\0" - "Arabic_hamzaonalef\0" - "Arabic_hamzaonwaw\0" - "Arabic_hamzaunderalef\0" - "Arabic_hamzaonyeh\0" - "Arabic_alef\0" - "Arabic_beh\0" - "Arabic_tehmarbuta\0" - "Arabic_teh\0" - "Arabic_theh\0" - "Arabic_jeem\0" - "Arabic_hah\0" - "Arabic_khah\0" - "Arabic_dal\0" - "Arabic_thal\0" - "Arabic_ra\0" - "Arabic_zain\0" - "Arabic_seen\0" - "Arabic_sheen\0" - "Arabic_sad\0" - "Arabic_dad\0" - "Arabic_tah\0" - "Arabic_zah\0" - "Arabic_ain\0" - "Arabic_ghain\0" - "Arabic_tatweel\0" - "Arabic_feh\0" - "Arabic_qaf\0" - "Arabic_kaf\0" - "Arabic_lam\0" - "Arabic_meem\0" - "Arabic_noon\0" - "Arabic_ha\0" - "Arabic_heh\0" - "Arabic_waw\0" - "Arabic_alefmaksura\0" - "Arabic_yeh\0" - "Arabic_fathatan\0" - "Arabic_dammatan\0" - "Arabic_kasratan\0" - "Arabic_fatha\0" - "Arabic_damma\0" - "Arabic_kasra\0" - "Arabic_shadda\0" - "Arabic_sukun\0" - "Serbian_dje\0" - "Macedonia_gje\0" - "Cyrillic_io\0" - "Ukrainian_ie\0" - "Ukranian_je\0" - "Macedonia_dse\0" - "Ukrainian_i\0" - "Ukranian_i\0" - "Ukrainian_yi\0" - "Ukranian_yi\0" - "Cyrillic_je\0" - "Serbian_je\0" - "Cyrillic_lje\0" - "Serbian_lje\0" - "Cyrillic_nje\0" - "Serbian_nje\0" - "Serbian_tshe\0" - "Macedonia_kje\0" - "Ukrainian_ghe_with_upturn\0" - "Byelorussian_shortu\0" - "Cyrillic_dzhe\0" - "Serbian_dze\0" - "numerosign\0" - "Serbian_DJE\0" - "Macedonia_GJE\0" - "Cyrillic_IO\0" - "Ukrainian_IE\0" - "Ukranian_JE\0" - "Macedonia_DSE\0" - "Ukrainian_I\0" - "Ukranian_I\0" - "Ukrainian_YI\0" - "Ukranian_YI\0" - "Cyrillic_JE\0" - "Serbian_JE\0" - "Cyrillic_LJE\0" - "Serbian_LJE\0" - "Cyrillic_NJE\0" - "Serbian_NJE\0" - "Serbian_TSHE\0" - "Macedonia_KJE\0" - "Ukrainian_GHE_WITH_UPTURN\0" - "Byelorussian_SHORTU\0" - "Cyrillic_DZHE\0" - "Serbian_DZE\0" - "Cyrillic_yu\0" - "Cyrillic_a\0" - "Cyrillic_be\0" - "Cyrillic_tse\0" - "Cyrillic_de\0" - "Cyrillic_ie\0" - "Cyrillic_ef\0" - "Cyrillic_ghe\0" - "Cyrillic_ha\0" - "Cyrillic_i\0" - "Cyrillic_shorti\0" - "Cyrillic_ka\0" - "Cyrillic_el\0" - "Cyrillic_em\0" - "Cyrillic_en\0" - "Cyrillic_o\0" - "Cyrillic_pe\0" - "Cyrillic_ya\0" - "Cyrillic_er\0" - "Cyrillic_es\0" - "Cyrillic_te\0" - "Cyrillic_u\0" - "Cyrillic_zhe\0" - "Cyrillic_ve\0" - "Cyrillic_softsign\0" - "Cyrillic_yeru\0" - "Cyrillic_ze\0" - "Cyrillic_sha\0" - "Cyrillic_e\0" - "Cyrillic_shcha\0" - "Cyrillic_che\0" - "Cyrillic_hardsign\0" - "Cyrillic_YU\0" - "Cyrillic_A\0" - "Cyrillic_BE\0" - "Cyrillic_TSE\0" - "Cyrillic_DE\0" - "Cyrillic_IE\0" - "Cyrillic_EF\0" - "Cyrillic_GHE\0" - "Cyrillic_HA\0" - "Cyrillic_I\0" - "Cyrillic_SHORTI\0" - "Cyrillic_KA\0" - "Cyrillic_EL\0" - "Cyrillic_EM\0" - "Cyrillic_EN\0" - "Cyrillic_O\0" - "Cyrillic_PE\0" - "Cyrillic_YA\0" - "Cyrillic_ER\0" - "Cyrillic_ES\0" - "Cyrillic_TE\0" - "Cyrillic_U\0" - "Cyrillic_ZHE\0" - "Cyrillic_VE\0" - "Cyrillic_SOFTSIGN\0" - "Cyrillic_YERU\0" - "Cyrillic_ZE\0" - "Cyrillic_SHA\0" - "Cyrillic_E\0" - "Cyrillic_SHCHA\0" - "Cyrillic_CHE\0" - "Cyrillic_HARDSIGN\0" - "Greek_ALPHAaccent\0" - "Greek_EPSILONaccent\0" - "Greek_ETAaccent\0" - "Greek_IOTAaccent\0" - "Greek_IOTAdiaeresis\0" - "Greek_IOTAdieresis\0" - "Greek_OMICRONaccent\0" - "Greek_UPSILONaccent\0" - "Greek_UPSILONdieresis\0" - "Greek_OMEGAaccent\0" - "Greek_accentdieresis\0" - "Greek_horizbar\0" - "Greek_alphaaccent\0" - "Greek_epsilonaccent\0" - "Greek_etaaccent\0" - "Greek_iotaaccent\0" - "Greek_iotadieresis\0" - "Greek_iotaaccentdieresis\0" - "Greek_omicronaccent\0" - "Greek_upsilonaccent\0" - "Greek_upsilondieresis\0" - "Greek_upsilonaccentdieresis\0" - "Greek_omegaaccent\0" - "Greek_ALPHA\0" - "Greek_BETA\0" - "Greek_GAMMA\0" - "Greek_DELTA\0" - "Greek_EPSILON\0" - "Greek_ZETA\0" - "Greek_ETA\0" - "Greek_THETA\0" - "Greek_IOTA\0" - "Greek_KAPPA\0" - "Greek_LAMBDA\0" - "Greek_LAMDA\0" - "Greek_MU\0" - "Greek_NU\0" - "Greek_XI\0" - "Greek_OMICRON\0" - "Greek_PI\0" - "Greek_RHO\0" - "Greek_SIGMA\0" - "Greek_TAU\0" - "Greek_UPSILON\0" - "Greek_PHI\0" - "Greek_CHI\0" - "Greek_PSI\0" - "Greek_OMEGA\0" - "Greek_alpha\0" - "Greek_beta\0" - "Greek_gamma\0" - "Greek_delta\0" - "Greek_epsilon\0" - "Greek_zeta\0" - "Greek_eta\0" - "Greek_theta\0" - "Greek_iota\0" - "Greek_kappa\0" - "Greek_lambda\0" - "Greek_lamda\0" - "Greek_mu\0" - "Greek_nu\0" - "Greek_xi\0" - "Greek_omicron\0" - "Greek_pi\0" - "Greek_rho\0" - "Greek_sigma\0" - "Greek_finalsmallsigma\0" - "Greek_tau\0" - "Greek_upsilon\0" - "Greek_phi\0" - "Greek_chi\0" - "Greek_psi\0" - "Greek_omega\0" - "leftradical\0" - "topleftradical\0" - "horizconnector\0" - "topintegral\0" - "botintegral\0" - "vertconnector\0" - "topleftsqbracket\0" - "botleftsqbracket\0" - "toprightsqbracket\0" - "botrightsqbracket\0" - "topleftparens\0" - "botleftparens\0" - "toprightparens\0" - "botrightparens\0" - "leftmiddlecurlybrace\0" - "rightmiddlecurlybrace\0" - "topleftsummation\0" - "botleftsummation\0" - "topvertsummationconnector\0" - "botvertsummationconnector\0" - "toprightsummation\0" - "botrightsummation\0" - "rightmiddlesummation\0" - "lessthanequal\0" - "notequal\0" - "greaterthanequal\0" - "integral\0" - "therefore\0" - "variation\0" - "infinity\0" - "nabla\0" - "approximate\0" - "similarequal\0" - "ifonlyif\0" - "implies\0" - "identical\0" - "radical\0" - "includedin\0" - "includes\0" - "intersection\0" - "union\0" - "logicaland\0" - "logicalor\0" - "partialderivative\0" - "function\0" - "leftarrow\0" - "uparrow\0" - "rightarrow\0" - "downarrow\0" - "blank\0" - "soliddiamond\0" - "checkerboard\0" - "ht\0" - "ff\0" - "cr\0" - "lf\0" - "nl\0" - "vt\0" - "lowrightcorner\0" - "uprightcorner\0" - "upleftcorner\0" - "lowleftcorner\0" - "crossinglines\0" - "horizlinescan1\0" - "horizlinescan3\0" - "horizlinescan5\0" - "horizlinescan7\0" - "horizlinescan9\0" - "leftt\0" - "rightt\0" - "bott\0" - "topt\0" - "vertbar\0" - "emspace\0" - "enspace\0" - "em3space\0" - "em4space\0" - "digitspace\0" - "punctspace\0" - "thinspace\0" - "hairspace\0" - "emdash\0" - "endash\0" - "signifblank\0" - "ellipsis\0" - "doubbaselinedot\0" - "onethird\0" - "twothirds\0" - "onefifth\0" - "twofifths\0" - "threefifths\0" - "fourfifths\0" - "onesixth\0" - "fivesixths\0" - "careof\0" - "figdash\0" - "leftanglebracket\0" - "decimalpoint\0" - "rightanglebracket\0" - "marker\0" - "oneeighth\0" - "threeeighths\0" - "fiveeighths\0" - "seveneighths\0" - "trademark\0" - "signaturemark\0" - "trademarkincircle\0" - "leftopentriangle\0" - "rightopentriangle\0" - "emopencircle\0" - "emopenrectangle\0" - "leftsinglequotemark\0" - "rightsinglequotemark\0" - "leftdoublequotemark\0" - "rightdoublequotemark\0" - "prescription\0" - "permille\0" - "minutes\0" - "seconds\0" - "latincross\0" - "hexagram\0" - "filledrectbullet\0" - "filledlefttribullet\0" - "filledrighttribullet\0" - "emfilledcircle\0" - "emfilledrect\0" - "enopencircbullet\0" - "enopensquarebullet\0" - "openrectbullet\0" - "opentribulletup\0" - "opentribulletdown\0" - "openstar\0" - "enfilledcircbullet\0" - "enfilledsqbullet\0" - "filledtribulletup\0" - "filledtribulletdown\0" - "leftpointer\0" - "rightpointer\0" - "club\0" - "diamond\0" - "heart\0" - "maltesecross\0" - "dagger\0" - "doubledagger\0" - "checkmark\0" - "ballotcross\0" - "musicalsharp\0" - "musicalflat\0" - "malesymbol\0" - "femalesymbol\0" - "telephone\0" - "telephonerecorder\0" - "phonographcopyright\0" - "caret\0" - "singlelowquotemark\0" - "doublelowquotemark\0" - "cursor\0" - "leftcaret\0" - "rightcaret\0" - "downcaret\0" - "upcaret\0" - "overbar\0" - "downtack\0" - "upshoe\0" - "downstile\0" - "underbar\0" - "jot\0" - "quad\0" - "uptack\0" - "circle\0" - "upstile\0" - "downshoe\0" - "rightshoe\0" - "leftshoe\0" - "lefttack\0" - "righttack\0" - "hebrew_doublelowline\0" - "hebrew_aleph\0" - "hebrew_bet\0" - "hebrew_beth\0" - "hebrew_gimel\0" - "hebrew_gimmel\0" - "hebrew_dalet\0" - "hebrew_daleth\0" - "hebrew_he\0" - "hebrew_waw\0" - "hebrew_zain\0" - "hebrew_zayin\0" - "hebrew_chet\0" - "hebrew_het\0" - "hebrew_tet\0" - "hebrew_teth\0" - "hebrew_yod\0" - "hebrew_finalkaph\0" - "hebrew_kaph\0" - "hebrew_lamed\0" - "hebrew_finalmem\0" - "hebrew_mem\0" - "hebrew_finalnun\0" - "hebrew_nun\0" - "hebrew_samech\0" - "hebrew_samekh\0" - "hebrew_ayin\0" - "hebrew_finalpe\0" - "hebrew_pe\0" - "hebrew_finalzade\0" - "hebrew_finalzadi\0" - "hebrew_zade\0" - "hebrew_zadi\0" - "hebrew_kuf\0" - "hebrew_qoph\0" - "hebrew_resh\0" - "hebrew_shin\0" - "hebrew_taf\0" - "hebrew_taw\0" - "Thai_kokai\0" - "Thai_khokhai\0" - "Thai_khokhuat\0" - "Thai_khokhwai\0" - "Thai_khokhon\0" - "Thai_khorakhang\0" - "Thai_ngongu\0" - "Thai_chochan\0" - "Thai_choching\0" - "Thai_chochang\0" - "Thai_soso\0" - "Thai_chochoe\0" - "Thai_yoying\0" - "Thai_dochada\0" - "Thai_topatak\0" - "Thai_thothan\0" - "Thai_thonangmontho\0" - "Thai_thophuthao\0" - "Thai_nonen\0" - "Thai_dodek\0" - "Thai_totao\0" - "Thai_thothung\0" - "Thai_thothahan\0" - "Thai_thothong\0" - "Thai_nonu\0" - "Thai_bobaimai\0" - "Thai_popla\0" - "Thai_phophung\0" - "Thai_fofa\0" - "Thai_phophan\0" - "Thai_fofan\0" - "Thai_phosamphao\0" - "Thai_moma\0" - "Thai_yoyak\0" - "Thai_rorua\0" - "Thai_ru\0" - "Thai_loling\0" - "Thai_lu\0" - "Thai_wowaen\0" - "Thai_sosala\0" - "Thai_sorusi\0" - "Thai_sosua\0" - "Thai_hohip\0" - "Thai_lochula\0" - "Thai_oang\0" - "Thai_honokhuk\0" - "Thai_paiyannoi\0" - "Thai_saraa\0" - "Thai_maihanakat\0" - "Thai_saraaa\0" - "Thai_saraam\0" - "Thai_sarai\0" - "Thai_saraii\0" - "Thai_saraue\0" - "Thai_sarauee\0" - "Thai_sarau\0" - "Thai_sarauu\0" - "Thai_phinthu\0" - "Thai_maihanakat_maitho\0" - "Thai_baht\0" - "Thai_sarae\0" - "Thai_saraae\0" - "Thai_sarao\0" - "Thai_saraaimaimuan\0" - "Thai_saraaimaimalai\0" - "Thai_lakkhangyao\0" - "Thai_maiyamok\0" - "Thai_maitaikhu\0" - "Thai_maiek\0" - "Thai_maitho\0" - "Thai_maitri\0" - "Thai_maichattawa\0" - "Thai_thanthakhat\0" - "Thai_nikhahit\0" - "Thai_leksun\0" - "Thai_leknung\0" - "Thai_leksong\0" - "Thai_leksam\0" - "Thai_leksi\0" - "Thai_lekha\0" - "Thai_lekhok\0" - "Thai_lekchet\0" - "Thai_lekpaet\0" - "Thai_lekkao\0" - "Hangul_Kiyeog\0" - "Hangul_SsangKiyeog\0" - "Hangul_KiyeogSios\0" - "Hangul_Nieun\0" - "Hangul_NieunJieuj\0" - "Hangul_NieunHieuh\0" - "Hangul_Dikeud\0" - "Hangul_SsangDikeud\0" - "Hangul_Rieul\0" - "Hangul_RieulKiyeog\0" - "Hangul_RieulMieum\0" - "Hangul_RieulPieub\0" - "Hangul_RieulSios\0" - "Hangul_RieulTieut\0" - "Hangul_RieulPhieuf\0" - "Hangul_RieulHieuh\0" - "Hangul_Mieum\0" - "Hangul_Pieub\0" - "Hangul_SsangPieub\0" - "Hangul_PieubSios\0" - "Hangul_Sios\0" - "Hangul_SsangSios\0" - "Hangul_Ieung\0" - "Hangul_Jieuj\0" - "Hangul_SsangJieuj\0" - "Hangul_Cieuc\0" - "Hangul_Khieuq\0" - "Hangul_Tieut\0" - "Hangul_Phieuf\0" - "Hangul_Hieuh\0" - "Hangul_A\0" - "Hangul_AE\0" - "Hangul_YA\0" - "Hangul_YAE\0" - "Hangul_EO\0" - "Hangul_E\0" - "Hangul_YEO\0" - "Hangul_YE\0" - "Hangul_O\0" - "Hangul_WA\0" - "Hangul_WAE\0" - "Hangul_OE\0" - "Hangul_YO\0" - "Hangul_U\0" - "Hangul_WEO\0" - "Hangul_WE\0" - "Hangul_WI\0" - "Hangul_YU\0" - "Hangul_EU\0" - "Hangul_YI\0" - "Hangul_I\0" - "Hangul_J_Kiyeog\0" - "Hangul_J_SsangKiyeog\0" - "Hangul_J_KiyeogSios\0" - "Hangul_J_Nieun\0" - "Hangul_J_NieunJieuj\0" - "Hangul_J_NieunHieuh\0" - "Hangul_J_Dikeud\0" - "Hangul_J_Rieul\0" - "Hangul_J_RieulKiyeog\0" - "Hangul_J_RieulMieum\0" - "Hangul_J_RieulPieub\0" - "Hangul_J_RieulSios\0" - "Hangul_J_RieulTieut\0" - "Hangul_J_RieulPhieuf\0" - "Hangul_J_RieulHieuh\0" - "Hangul_J_Mieum\0" - "Hangul_J_Pieub\0" - "Hangul_J_PieubSios\0" - "Hangul_J_Sios\0" - "Hangul_J_SsangSios\0" - "Hangul_J_Ieung\0" - "Hangul_J_Jieuj\0" - "Hangul_J_Cieuc\0" - "Hangul_J_Khieuq\0" - "Hangul_J_Tieut\0" - "Hangul_J_Phieuf\0" - "Hangul_J_Hieuh\0" - "Hangul_RieulYeorinHieuh\0" - "Hangul_SunkyeongeumMieum\0" - "Hangul_SunkyeongeumPieub\0" - "Hangul_PanSios\0" - "Hangul_KkogjiDalrinIeung\0" - "Hangul_SunkyeongeumPhieuf\0" - "Hangul_YeorinHieuh\0" - "Hangul_AraeA\0" - "Hangul_AraeAE\0" - "Hangul_J_PanSios\0" - "Hangul_J_KkogjiDalrinIeung\0" - "Hangul_J_YeorinHieuh\0" - "Korean_Won\0" - "OE\0" - "oe\0" - "Ydiaeresis\0" - "EuroSign\0" - "3270_Duplicate\0" - "3270_FieldMark\0" - "3270_Right2\0" - "3270_Left2\0" - "3270_BackTab\0" - "3270_EraseEOF\0" - "3270_EraseInput\0" - "3270_Reset\0" - "3270_Quit\0" - "3270_PA1\0" - "3270_PA2\0" - "3270_PA3\0" - "3270_Test\0" - "3270_Attn\0" - "3270_CursorBlink\0" - "3270_AltCursor\0" - "3270_KeyClick\0" - "3270_Jump\0" - "3270_Ident\0" - "3270_Rule\0" - "3270_Copy\0" - "3270_Play\0" - "3270_Setup\0" - "3270_Record\0" - "3270_ChangeScreen\0" - "3270_DeleteWord\0" - "3270_ExSelect\0" - "3270_CursorSelect\0" - "3270_PrintScreen\0" - "3270_Enter\0" - "ISO_Lock\0" - "ISO_Level2_Latch\0" - "ISO_Level3_Shift\0" - "ISO_Level3_Latch\0" - "ISO_Level3_Lock\0" - "ISO_Group_Latch\0" - "ISO_Group_Lock\0" - "ISO_Next_Group\0" - "ISO_Next_Group_Lock\0" - "ISO_Prev_Group\0" - "ISO_Prev_Group_Lock\0" - "ISO_First_Group\0" - "ISO_First_Group_Lock\0" - "ISO_Last_Group\0" - "ISO_Last_Group_Lock\0" - "ISO_Level5_Shift\0" - "ISO_Level5_Latch\0" - "ISO_Level5_Lock\0" - "ISO_Left_Tab\0" - "ISO_Move_Line_Up\0" - "ISO_Move_Line_Down\0" - "ISO_Partial_Line_Up\0" - "ISO_Partial_Line_Down\0" - "ISO_Partial_Space_Left\0" - "ISO_Partial_Space_Right\0" - "ISO_Set_Margin_Left\0" - "ISO_Set_Margin_Right\0" - "ISO_Release_Margin_Left\0" - "ISO_Release_Margin_Right\0" - "ISO_Release_Both_Margins\0" - "ISO_Fast_Cursor_Left\0" - "ISO_Fast_Cursor_Right\0" - "ISO_Fast_Cursor_Up\0" - "ISO_Fast_Cursor_Down\0" - "ISO_Continuous_Underline\0" - "ISO_Discontinuous_Underline\0" - "ISO_Emphasize\0" - "ISO_Center_Object\0" - "ISO_Enter\0" - "dead_grave\0" - "dead_acute\0" - "dead_circumflex\0" - "dead_perispomeni\0" - "dead_tilde\0" - "dead_macron\0" - "dead_breve\0" - "dead_abovedot\0" - "dead_diaeresis\0" - "dead_abovering\0" - "dead_doubleacute\0" - "dead_caron\0" - "dead_cedilla\0" - "dead_ogonek\0" - "dead_iota\0" - "dead_voiced_sound\0" - "dead_semivoiced_sound\0" - "dead_belowdot\0" - "dead_hook\0" - "dead_horn\0" - "dead_stroke\0" - "dead_abovecomma\0" - "dead_psili\0" - "dead_abovereversedcomma\0" - "dead_dasia\0" - "dead_doublegrave\0" - "dead_belowring\0" - "dead_belowmacron\0" - "dead_belowcircumflex\0" - "dead_belowtilde\0" - "dead_belowbreve\0" - "dead_belowdiaeresis\0" - "dead_invertedbreve\0" - "dead_belowcomma\0" - "dead_currency\0" - "AccessX_Enable\0" - "AccessX_Feedback_Enable\0" - "RepeatKeys_Enable\0" - "SlowKeys_Enable\0" - "BounceKeys_Enable\0" - "StickyKeys_Enable\0" - "MouseKeys_Enable\0" - "MouseKeys_Accel_Enable\0" - "Overlay1_Enable\0" - "Overlay2_Enable\0" - "AudibleBell_Enable\0" - "dead_a\0" - "dead_A\0" - "dead_e\0" - "dead_E\0" - "dead_i\0" - "dead_I\0" - "dead_o\0" - "dead_O\0" - "dead_u\0" - "dead_U\0" - "dead_small_schwa\0" - "dead_capital_schwa\0" - "dead_greek\0" - "ch\0" - "Ch\0" - "CH\0" - "c_h\0" - "C_h\0" - "C_H\0" - "First_Virtual_Screen\0" - "Prev_Virtual_Screen\0" - "Next_Virtual_Screen\0" - "Last_Virtual_Screen\0" - "Terminate_Server\0" - "Pointer_Left\0" - "Pointer_Right\0" - "Pointer_Up\0" - "Pointer_Down\0" - "Pointer_UpLeft\0" - "Pointer_UpRight\0" - "Pointer_DownLeft\0" - "Pointer_DownRight\0" - "Pointer_Button_Dflt\0" - "Pointer_Button1\0" - "Pointer_Button2\0" - "Pointer_Button3\0" - "Pointer_Button4\0" - "Pointer_Button5\0" - "Pointer_DblClick_Dflt\0" - "Pointer_DblClick1\0" - "Pointer_DblClick2\0" - "Pointer_DblClick3\0" - "Pointer_DblClick4\0" - "Pointer_DblClick5\0" - "Pointer_Drag_Dflt\0" - "Pointer_Drag1\0" - "Pointer_Drag2\0" - "Pointer_Drag3\0" - "Pointer_Drag4\0" - "Pointer_EnableKeys\0" - "Pointer_Accelerate\0" - "Pointer_DfltBtnNext\0" - "Pointer_DfltBtnPrev\0" - "Pointer_Drag5\0" - "BackSpace\0" - "Tab\0" - "Linefeed\0" - "Clear\0" - "Return\0" - "Pause\0" - "Scroll_Lock\0" - "Sys_Req\0" - "Escape\0" - "Multi_key\0" - "Kanji\0" - "Muhenkan\0" - "Henkan\0" - "Henkan_Mode\0" - "Romaji\0" - "Hiragana\0" - "Katakana\0" - "Hiragana_Katakana\0" - "Zenkaku\0" - "Hankaku\0" - "Zenkaku_Hankaku\0" - "Touroku\0" - "Massyo\0" - "Kana_Lock\0" - "Kana_Shift\0" - "Eisu_Shift\0" - "Eisu_toggle\0" - "Hangul\0" - "Hangul_Start\0" - "Hangul_End\0" - "Hangul_Hanja\0" - "Hangul_Jamo\0" - "Hangul_Romaja\0" - "Codeinput\0" - "Hangul_Codeinput\0" - "Kanji_Bangou\0" - "Hangul_Jeonja\0" - "Hangul_Banja\0" - "Hangul_PreHanja\0" - "Hangul_PostHanja\0" - "Hangul_SingleCandidate\0" - "SingleCandidate\0" - "Hangul_MultipleCandidate\0" - "MultipleCandidate\0" - "Zen_Koho\0" - "Hangul_PreviousCandidate\0" - "Mae_Koho\0" - "PreviousCandidate\0" - "Hangul_Special\0" - "Home\0" - "Left\0" - "Up\0" - "Right\0" - "Down\0" - "Page_Up\0" - "Prior\0" - "Page_Down\0" - "Next\0" - "End\0" - "Begin\0" - "Select\0" - "Print\0" - "Execute\0" - "Insert\0" - "Undo\0" - "Redo\0" - "Menu\0" - "Find\0" - "Cancel\0" - "Help\0" - "Break\0" - "Arabic_switch\0" - "Greek_switch\0" - "Hangul_switch\0" - "Hebrew_switch\0" - "ISO_Group_Shift\0" - "kana_switch\0" - "Mode_switch\0" - "script_switch\0" - "Num_Lock\0" - "KP_Space\0" - "KP_Tab\0" - "KP_Enter\0" - "KP_F1\0" - "KP_F2\0" - "KP_F3\0" - "KP_F4\0" - "KP_Home\0" - "KP_Left\0" - "KP_Up\0" - "KP_Right\0" - "KP_Down\0" - "KP_Page_Up\0" - "KP_Prior\0" - "KP_Next\0" - "KP_Page_Down\0" - "KP_End\0" - "KP_Begin\0" - "KP_Insert\0" - "KP_Delete\0" - "KP_Multiply\0" - "KP_Add\0" - "KP_Separator\0" - "KP_Subtract\0" - "KP_Decimal\0" - "KP_Divide\0" - "KP_0\0" - "KP_1\0" - "KP_2\0" - "KP_3\0" - "KP_4\0" - "KP_5\0" - "KP_6\0" - "KP_7\0" - "KP_8\0" - "KP_9\0" - "KP_Equal\0" - "F1\0" - "F2\0" - "F3\0" - "F4\0" - "F5\0" - "F6\0" - "F7\0" - "F8\0" - "F9\0" - "F10\0" - "F11\0" - "L1\0" - "F12\0" - "L2\0" - "F13\0" - "L3\0" - "F14\0" - "L4\0" - "F15\0" - "L5\0" - "F16\0" - "L6\0" - "F17\0" - "L7\0" - "F18\0" - "L8\0" - "F19\0" - "L9\0" - "F20\0" - "L10\0" - "F21\0" - "R1\0" - "F22\0" - "R2\0" - "F23\0" - "R3\0" - "F24\0" - "R4\0" - "F25\0" - "R5\0" - "F26\0" - "R6\0" - "F27\0" - "R7\0" - "F28\0" - "R8\0" - "F29\0" - "R9\0" - "F30\0" - "R10\0" - "F31\0" - "R11\0" - "F32\0" - "R12\0" - "F33\0" - "R13\0" - "F34\0" - "R14\0" - "F35\0" - "R15\0" - "Shift_L\0" - "Shift_R\0" - "Control_L\0" - "Control_R\0" - "Caps_Lock\0" - "Shift_Lock\0" - "Meta_L\0" - "Meta_R\0" - "Alt_L\0" - "Alt_R\0" - "Super_L\0" - "Super_R\0" - "Hyper_L\0" - "Hyper_R\0" - "braille_dot_1\0" - "braille_dot_2\0" - "braille_dot_3\0" - "braille_dot_4\0" - "braille_dot_5\0" - "braille_dot_6\0" - "braille_dot_7\0" - "braille_dot_8\0" - "braille_dot_9\0" - "braille_dot_10\0" - "Delete\0" - "Ibreve\0" - "ibreve\0" - "Wcircumflex\0" - "wcircumflex\0" - "Ycircumflex\0" - "ycircumflex\0" - "SCHWA\0" - "Obarred\0" - "Ohorn\0" - "ohorn\0" - "Uhorn\0" - "uhorn\0" - "Zstroke\0" - "zstroke\0" - "EZH\0" - "Ocaron\0" - "ocaron\0" - "Gcaron\0" - "gcaron\0" - "schwa\0" - "obarred\0" - "ezh\0" - "Cyrillic_GHE_bar\0" - "Cyrillic_ghe_bar\0" - "Cyrillic_ZHE_descender\0" - "Cyrillic_zhe_descender\0" - "Cyrillic_KA_descender\0" - "Cyrillic_ka_descender\0" - "Cyrillic_KA_vertstroke\0" - "Cyrillic_ka_vertstroke\0" - "Cyrillic_EN_descender\0" - "Cyrillic_en_descender\0" - "Cyrillic_U_straight\0" - "Cyrillic_u_straight\0" - "Cyrillic_U_straight_bar\0" - "Cyrillic_u_straight_bar\0" - "Cyrillic_HA_descender\0" - "Cyrillic_ha_descender\0" - "Cyrillic_CHE_descender\0" - "Cyrillic_che_descender\0" - "Cyrillic_CHE_vertstroke\0" - "Cyrillic_che_vertstroke\0" - "Cyrillic_SHHA\0" - "Cyrillic_shha\0" - "Cyrillic_SCHWA\0" - "Cyrillic_schwa\0" - "Cyrillic_I_macron\0" - "Cyrillic_i_macron\0" - "Cyrillic_O_bar\0" - "Cyrillic_o_bar\0" - "Cyrillic_U_macron\0" - "Cyrillic_u_macron\0" - "Armenian_AYB\0" - "Armenian_BEN\0" - "Armenian_GIM\0" - "Armenian_DA\0" - "Armenian_YECH\0" - "Armenian_ZA\0" - "Armenian_E\0" - "Armenian_AT\0" - "Armenian_TO\0" - "Armenian_ZHE\0" - "Armenian_INI\0" - "Armenian_LYUN\0" - "Armenian_KHE\0" - "Armenian_TSA\0" - "Armenian_KEN\0" - "Armenian_HO\0" - "Armenian_DZA\0" - "Armenian_GHAT\0" - "Armenian_TCHE\0" - "Armenian_MEN\0" - "Armenian_HI\0" - "Armenian_NU\0" - "Armenian_SHA\0" - "Armenian_VO\0" - "Armenian_CHA\0" - "Armenian_PE\0" - "Armenian_JE\0" - "Armenian_RA\0" - "Armenian_SE\0" - "Armenian_VEV\0" - "Armenian_TYUN\0" - "Armenian_RE\0" - "Armenian_TSO\0" - "Armenian_VYUN\0" - "Armenian_PYUR\0" - "Armenian_KE\0" - "Armenian_O\0" - "Armenian_FE\0" - "Armenian_apostrophe\0" - "Armenian_accent\0" - "Armenian_shesht\0" - "Armenian_amanak\0" - "Armenian_exclam\0" - "Armenian_but\0" - "Armenian_separation_mark\0" - "Armenian_paruyk\0" - "Armenian_question\0" - "Armenian_ayb\0" - "Armenian_ben\0" - "Armenian_gim\0" - "Armenian_da\0" - "Armenian_yech\0" - "Armenian_za\0" - "Armenian_e\0" - "Armenian_at\0" - "Armenian_to\0" - "Armenian_zhe\0" - "Armenian_ini\0" - "Armenian_lyun\0" - "Armenian_khe\0" - "Armenian_tsa\0" - "Armenian_ken\0" - "Armenian_ho\0" - "Armenian_dza\0" - "Armenian_ghat\0" - "Armenian_tche\0" - "Armenian_men\0" - "Armenian_hi\0" - "Armenian_nu\0" - "Armenian_sha\0" - "Armenian_vo\0" - "Armenian_cha\0" - "Armenian_pe\0" - "Armenian_je\0" - "Armenian_ra\0" - "Armenian_se\0" - "Armenian_vev\0" - "Armenian_tyun\0" - "Armenian_re\0" - "Armenian_tso\0" - "Armenian_vyun\0" - "Armenian_pyur\0" - "Armenian_ke\0" - "Armenian_o\0" - "Armenian_fe\0" - "Armenian_ligature_ew\0" - "Armenian_full_stop\0" - "Armenian_verjaket\0" - "Armenian_hyphen\0" - "Armenian_yentamna\0" - "Arabic_madda_above\0" - "Arabic_hamza_above\0" - "Arabic_hamza_below\0" - "Arabic_0\0" - "Arabic_1\0" - "Arabic_2\0" - "Arabic_3\0" - "Arabic_4\0" - "Arabic_5\0" - "Arabic_6\0" - "Arabic_7\0" - "Arabic_8\0" - "Arabic_9\0" - "Arabic_percent\0" - "Arabic_superscript_alef\0" - "Arabic_tteh\0" - "Arabic_peh\0" - "Arabic_tcheh\0" - "Arabic_ddal\0" - "Arabic_rreh\0" - "Arabic_jeh\0" - "Arabic_veh\0" - "Arabic_keheh\0" - "Arabic_gaf\0" - "Arabic_noon_ghunna\0" - "Arabic_heh_doachashmee\0" - "Arabic_heh_goal\0" - "Arabic_farsi_yeh\0" - "Farsi_yeh\0" - "Arabic_yeh_baree\0" - "Arabic_fullstop\0" - "Farsi_0\0" - "Farsi_1\0" - "Farsi_2\0" - "Farsi_3\0" - "Farsi_4\0" - "Farsi_5\0" - "Farsi_6\0" - "Farsi_7\0" - "Farsi_8\0" - "Farsi_9\0" - "Sinh_ng\0" - "Sinh_h2\0" - "Sinh_a\0" - "Sinh_aa\0" - "Sinh_ae\0" - "Sinh_aee\0" - "Sinh_i\0" - "Sinh_ii\0" - "Sinh_u\0" - "Sinh_uu\0" - "Sinh_ri\0" - "Sinh_rii\0" - "Sinh_lu\0" - "Sinh_luu\0" - "Sinh_e\0" - "Sinh_ee\0" - "Sinh_ai\0" - "Sinh_o\0" - "Sinh_oo\0" - "Sinh_au\0" - "Sinh_ka\0" - "Sinh_kha\0" - "Sinh_ga\0" - "Sinh_gha\0" - "Sinh_ng2\0" - "Sinh_nga\0" - "Sinh_ca\0" - "Sinh_cha\0" - "Sinh_ja\0" - "Sinh_jha\0" - "Sinh_nya\0" - "Sinh_jnya\0" - "Sinh_nja\0" - "Sinh_tta\0" - "Sinh_ttha\0" - "Sinh_dda\0" - "Sinh_ddha\0" - "Sinh_nna\0" - "Sinh_ndda\0" - "Sinh_tha\0" - "Sinh_thha\0" - "Sinh_dha\0" - "Sinh_dhha\0" - "Sinh_na\0" - "Sinh_ndha\0" - "Sinh_pa\0" - "Sinh_pha\0" - "Sinh_ba\0" - "Sinh_bha\0" - "Sinh_ma\0" - "Sinh_mba\0" - "Sinh_ya\0" - "Sinh_ra\0" - "Sinh_la\0" - "Sinh_va\0" - "Sinh_sha\0" - "Sinh_ssha\0" - "Sinh_sa\0" - "Sinh_ha\0" - "Sinh_lla\0" - "Sinh_fa\0" - "Sinh_al\0" - "Sinh_aa2\0" - "Sinh_ae2\0" - "Sinh_aee2\0" - "Sinh_i2\0" - "Sinh_ii2\0" - "Sinh_u2\0" - "Sinh_uu2\0" - "Sinh_ru2\0" - "Sinh_e2\0" - "Sinh_ee2\0" - "Sinh_ai2\0" - "Sinh_o2\0" - "Sinh_oo2\0" - "Sinh_au2\0" - "Sinh_lu2\0" - "Sinh_ruu2\0" - "Sinh_luu2\0" - "Sinh_kunddaliya\0" - "Georgian_an\0" - "Georgian_ban\0" - "Georgian_gan\0" - "Georgian_don\0" - "Georgian_en\0" - "Georgian_vin\0" - "Georgian_zen\0" - "Georgian_tan\0" - "Georgian_in\0" - "Georgian_kan\0" - "Georgian_las\0" - "Georgian_man\0" - "Georgian_nar\0" - "Georgian_on\0" - "Georgian_par\0" - "Georgian_zhar\0" - "Georgian_rae\0" - "Georgian_san\0" - "Georgian_tar\0" - "Georgian_un\0" - "Georgian_phar\0" - "Georgian_khar\0" - "Georgian_ghan\0" - "Georgian_qar\0" - "Georgian_shin\0" - "Georgian_chin\0" - "Georgian_can\0" - "Georgian_jil\0" - "Georgian_cil\0" - "Georgian_char\0" - "Georgian_xan\0" - "Georgian_jhan\0" - "Georgian_hae\0" - "Georgian_he\0" - "Georgian_hie\0" - "Georgian_we\0" - "Georgian_har\0" - "Georgian_hoe\0" - "Georgian_fi\0" - "Babovedot\0" - "babovedot\0" - "Dabovedot\0" - "dabovedot\0" - "Fabovedot\0" - "fabovedot\0" - "Lbelowdot\0" - "lbelowdot\0" - "Mabovedot\0" - "mabovedot\0" - "Pabovedot\0" - "pabovedot\0" - "Sabovedot\0" - "sabovedot\0" - "Tabovedot\0" - "tabovedot\0" - "Wgrave\0" - "wgrave\0" - "Wacute\0" - "wacute\0" - "Wdiaeresis\0" - "wdiaeresis\0" - "Xabovedot\0" - "xabovedot\0" - "Abelowdot\0" - "abelowdot\0" - "Ahook\0" - "ahook\0" - "Acircumflexacute\0" - "acircumflexacute\0" - "Acircumflexgrave\0" - "acircumflexgrave\0" - "Acircumflexhook\0" - "acircumflexhook\0" - "Acircumflextilde\0" - "acircumflextilde\0" - "Acircumflexbelowdot\0" - "acircumflexbelowdot\0" - "Abreveacute\0" - "abreveacute\0" - "Abrevegrave\0" - "abrevegrave\0" - "Abrevehook\0" - "abrevehook\0" - "Abrevetilde\0" - "abrevetilde\0" - "Abrevebelowdot\0" - "abrevebelowdot\0" - "Ebelowdot\0" - "ebelowdot\0" - "Ehook\0" - "ehook\0" - "Etilde\0" - "etilde\0" - "Ecircumflexacute\0" - "ecircumflexacute\0" - "Ecircumflexgrave\0" - "ecircumflexgrave\0" - "Ecircumflexhook\0" - "ecircumflexhook\0" - "Ecircumflextilde\0" - "ecircumflextilde\0" - "Ecircumflexbelowdot\0" - "ecircumflexbelowdot\0" - "Ihook\0" - "ihook\0" - "Ibelowdot\0" - "ibelowdot\0" - "Obelowdot\0" - "obelowdot\0" - "Ohook\0" - "ohook\0" - "Ocircumflexacute\0" - "ocircumflexacute\0" - "Ocircumflexgrave\0" - "ocircumflexgrave\0" - "Ocircumflexhook\0" - "ocircumflexhook\0" - "Ocircumflextilde\0" - "ocircumflextilde\0" - "Ocircumflexbelowdot\0" - "ocircumflexbelowdot\0" - "Ohornacute\0" - "ohornacute\0" - "Ohorngrave\0" - "ohorngrave\0" - "Ohornhook\0" - "ohornhook\0" - "Ohorntilde\0" - "ohorntilde\0" - "Ohornbelowdot\0" - "ohornbelowdot\0" - "Ubelowdot\0" - "ubelowdot\0" - "Uhook\0" - "uhook\0" - "Uhornacute\0" - "uhornacute\0" - "Uhorngrave\0" - "uhorngrave\0" - "Uhornhook\0" - "uhornhook\0" - "Uhorntilde\0" - "uhorntilde\0" - "Uhornbelowdot\0" - "uhornbelowdot\0" - "Ygrave\0" - "ygrave\0" - "Ybelowdot\0" - "ybelowdot\0" - "Yhook\0" - "yhook\0" - "Ytilde\0" - "ytilde\0" - "zerosuperior\0" - "foursuperior\0" - "fivesuperior\0" - "sixsuperior\0" - "sevensuperior\0" - "eightsuperior\0" - "ninesuperior\0" - "zerosubscript\0" - "onesubscript\0" - "twosubscript\0" - "threesubscript\0" - "foursubscript\0" - "fivesubscript\0" - "sixsubscript\0" - "sevensubscript\0" - "eightsubscript\0" - "ninesubscript\0" - "EcuSign\0" - "ColonSign\0" - "CruzeiroSign\0" - "FFrancSign\0" - "LiraSign\0" - "MillSign\0" - "NairaSign\0" - "PesetaSign\0" - "RupeeSign\0" - "WonSign\0" - "NewSheqelSign\0" - "DongSign\0" - "partdifferential\0" - "emptyset\0" - "elementof\0" - "notelementof\0" - "containsas\0" - "squareroot\0" - "cuberoot\0" - "fourthroot\0" - "dintegral\0" - "tintegral\0" - "because\0" - "notapproxeq\0" - "approxeq\0" - "notidentical\0" - "stricteq\0" - "braille_blank\0" - "braille_dots_1\0" - "braille_dots_2\0" - "braille_dots_12\0" - "braille_dots_3\0" - "braille_dots_13\0" - "braille_dots_23\0" - "braille_dots_123\0" - "braille_dots_4\0" - "braille_dots_14\0" - "braille_dots_24\0" - "braille_dots_124\0" - "braille_dots_34\0" - "braille_dots_134\0" - "braille_dots_234\0" - "braille_dots_1234\0" - "braille_dots_5\0" - "braille_dots_15\0" - "braille_dots_25\0" - "braille_dots_125\0" - "braille_dots_35\0" - "braille_dots_135\0" - "braille_dots_235\0" - "braille_dots_1235\0" - "braille_dots_45\0" - "braille_dots_145\0" - "braille_dots_245\0" - "braille_dots_1245\0" - "braille_dots_345\0" - "braille_dots_1345\0" - "braille_dots_2345\0" - "braille_dots_12345\0" - "braille_dots_6\0" - "braille_dots_16\0" - "braille_dots_26\0" - "braille_dots_126\0" - "braille_dots_36\0" - "braille_dots_136\0" - "braille_dots_236\0" - "braille_dots_1236\0" - "braille_dots_46\0" - "braille_dots_146\0" - "braille_dots_246\0" - "braille_dots_1246\0" - "braille_dots_346\0" - "braille_dots_1346\0" - "braille_dots_2346\0" - "braille_dots_12346\0" - "braille_dots_56\0" - "braille_dots_156\0" - "braille_dots_256\0" - "braille_dots_1256\0" - "braille_dots_356\0" - "braille_dots_1356\0" - "braille_dots_2356\0" - "braille_dots_12356\0" - "braille_dots_456\0" - "braille_dots_1456\0" - "braille_dots_2456\0" - "braille_dots_12456\0" - "braille_dots_3456\0" - "braille_dots_13456\0" - "braille_dots_23456\0" - "braille_dots_123456\0" - "braille_dots_7\0" - "braille_dots_17\0" - "braille_dots_27\0" - "braille_dots_127\0" - "braille_dots_37\0" - "braille_dots_137\0" - "braille_dots_237\0" - "braille_dots_1237\0" - "braille_dots_47\0" - "braille_dots_147\0" - "braille_dots_247\0" - "braille_dots_1247\0" - "braille_dots_347\0" - "braille_dots_1347\0" - "braille_dots_2347\0" - "braille_dots_12347\0" - "braille_dots_57\0" - "braille_dots_157\0" - "braille_dots_257\0" - "braille_dots_1257\0" - "braille_dots_357\0" - "braille_dots_1357\0" - "braille_dots_2357\0" - "braille_dots_12357\0" - "braille_dots_457\0" - "braille_dots_1457\0" - "braille_dots_2457\0" - "braille_dots_12457\0" - "braille_dots_3457\0" - "braille_dots_13457\0" - "braille_dots_23457\0" - "braille_dots_123457\0" - "braille_dots_67\0" - "braille_dots_167\0" - "braille_dots_267\0" - "braille_dots_1267\0" - "braille_dots_367\0" - "braille_dots_1367\0" - "braille_dots_2367\0" - "braille_dots_12367\0" - "braille_dots_467\0" - "braille_dots_1467\0" - "braille_dots_2467\0" - "braille_dots_12467\0" - "braille_dots_3467\0" - "braille_dots_13467\0" - "braille_dots_23467\0" - "braille_dots_123467\0" - "braille_dots_567\0" - "braille_dots_1567\0" - "braille_dots_2567\0" - "braille_dots_12567\0" - "braille_dots_3567\0" - "braille_dots_13567\0" - "braille_dots_23567\0" - "braille_dots_123567\0" - "braille_dots_4567\0" - "braille_dots_14567\0" - "braille_dots_24567\0" - "braille_dots_124567\0" - "braille_dots_34567\0" - "braille_dots_134567\0" - "braille_dots_234567\0" - "braille_dots_1234567\0" - "braille_dots_8\0" - "braille_dots_18\0" - "braille_dots_28\0" - "braille_dots_128\0" - "braille_dots_38\0" - "braille_dots_138\0" - "braille_dots_238\0" - "braille_dots_1238\0" - "braille_dots_48\0" - "braille_dots_148\0" - "braille_dots_248\0" - "braille_dots_1248\0" - "braille_dots_348\0" - "braille_dots_1348\0" - "braille_dots_2348\0" - "braille_dots_12348\0" - "braille_dots_58\0" - "braille_dots_158\0" - "braille_dots_258\0" - "braille_dots_1258\0" - "braille_dots_358\0" - "braille_dots_1358\0" - "braille_dots_2358\0" - "braille_dots_12358\0" - "braille_dots_458\0" - "braille_dots_1458\0" - "braille_dots_2458\0" - "braille_dots_12458\0" - "braille_dots_3458\0" - "braille_dots_13458\0" - "braille_dots_23458\0" - "braille_dots_123458\0" - "braille_dots_68\0" - "braille_dots_168\0" - "braille_dots_268\0" - "braille_dots_1268\0" - "braille_dots_368\0" - "braille_dots_1368\0" - "braille_dots_2368\0" - "braille_dots_12368\0" - "braille_dots_468\0" - "braille_dots_1468\0" - "braille_dots_2468\0" - "braille_dots_12468\0" - "braille_dots_3468\0" - "braille_dots_13468\0" - "braille_dots_23468\0" - "braille_dots_123468\0" - "braille_dots_568\0" - "braille_dots_1568\0" - "braille_dots_2568\0" - "braille_dots_12568\0" - "braille_dots_3568\0" - "braille_dots_13568\0" - "braille_dots_23568\0" - "braille_dots_123568\0" - "braille_dots_4568\0" - "braille_dots_14568\0" - "braille_dots_24568\0" - "braille_dots_124568\0" - "braille_dots_34568\0" - "braille_dots_134568\0" - "braille_dots_234568\0" - "braille_dots_1234568\0" - "braille_dots_78\0" - "braille_dots_178\0" - "braille_dots_278\0" - "braille_dots_1278\0" - "braille_dots_378\0" - "braille_dots_1378\0" - "braille_dots_2378\0" - "braille_dots_12378\0" - "braille_dots_478\0" - "braille_dots_1478\0" - "braille_dots_2478\0" - "braille_dots_12478\0" - "braille_dots_3478\0" - "braille_dots_13478\0" - "braille_dots_23478\0" - "braille_dots_123478\0" - "braille_dots_578\0" - "braille_dots_1578\0" - "braille_dots_2578\0" - "braille_dots_12578\0" - "braille_dots_3578\0" - "braille_dots_13578\0" - "braille_dots_23578\0" - "braille_dots_123578\0" - "braille_dots_4578\0" - "braille_dots_14578\0" - "braille_dots_24578\0" - "braille_dots_124578\0" - "braille_dots_34578\0" - "braille_dots_134578\0" - "braille_dots_234578\0" - "braille_dots_1234578\0" - "braille_dots_678\0" - "braille_dots_1678\0" - "braille_dots_2678\0" - "braille_dots_12678\0" - "braille_dots_3678\0" - "braille_dots_13678\0" - "braille_dots_23678\0" - "braille_dots_123678\0" - "braille_dots_4678\0" - "braille_dots_14678\0" - "braille_dots_24678\0" - "braille_dots_124678\0" - "braille_dots_34678\0" - "braille_dots_134678\0" - "braille_dots_234678\0" - "braille_dots_1234678\0" - "braille_dots_5678\0" - "braille_dots_15678\0" - "braille_dots_25678\0" - "braille_dots_125678\0" - "braille_dots_35678\0" - "braille_dots_135678\0" - "braille_dots_235678\0" - "braille_dots_1235678\0" - "braille_dots_45678\0" - "braille_dots_145678\0" - "braille_dots_245678\0" - "braille_dots_1245678\0" - "braille_dots_345678\0" - "braille_dots_1345678\0" - "braille_dots_2345678\0" - "braille_dots_12345678\0" - "Switch_VT_1\0" - "Switch_VT_2\0" - "Switch_VT_3\0" - "Switch_VT_4\0" - "Switch_VT_5\0" - "Switch_VT_6\0" - "Switch_VT_7\0" - "Switch_VT_8\0" - "Switch_VT_9\0" - "Switch_VT_10\0" - "Switch_VT_11\0" - "Switch_VT_12\0" - "Ungrab\0" - "ClearGrab\0" - "Next_VMode\0" - "Prev_VMode\0" - "LogWindowTree\0" - "LogGrabInfo\0" - "ModeLock\0" - "MonBrightnessUp\0" - "MonBrightnessDown\0" - "KbdLightOnOff\0" - "KbdBrightnessUp\0" - "KbdBrightnessDown\0" - "Standby\0" - "AudioLowerVolume\0" - "AudioMute\0" - "AudioRaiseVolume\0" - "AudioPlay\0" - "AudioStop\0" - "AudioPrev\0" - "AudioNext\0" - "HomePage\0" - "Mail\0" - "Start\0" - "Search\0" - "AudioRecord\0" - "Calculator\0" - "Memo\0" - "ToDoList\0" - "Calendar\0" - "PowerDown\0" - "ContrastAdjust\0" - "RockerUp\0" - "RockerDown\0" - "RockerEnter\0" - "Back\0" - "Forward\0" - "Stop\0" - "Refresh\0" - "PowerOff\0" - "WakeUp\0" - "Eject\0" - "ScreenSaver\0" - "WWW\0" - "Sleep\0" - "Favorites\0" - "AudioPause\0" - "AudioMedia\0" - "MyComputer\0" - "VendorHome\0" - "LightBulb\0" - "Shop\0" - "History\0" - "OpenURL\0" - "AddFavorite\0" - "HotLinks\0" - "BrightnessAdjust\0" - "Finance\0" - "Community\0" - "AudioRewind\0" - "BackForward\0" - "Launch0\0" - "Launch1\0" - "Launch2\0" - "Launch3\0" - "Launch4\0" - "Launch5\0" - "Launch6\0" - "Launch7\0" - "Launch8\0" - "Launch9\0" - "LaunchA\0" - "LaunchB\0" - "LaunchC\0" - "LaunchD\0" - "LaunchE\0" - "LaunchF\0" - "ApplicationLeft\0" - "ApplicationRight\0" - "Book\0" - "CD\0" - "WindowClear\0" - "Close\0" - "Copy\0" - "Cut\0" - "Display\0" - "DOS\0" - "Documents\0" - "Excel\0" - "Explorer\0" - "Game\0" - "Go\0" - "iTouch\0" - "LogOff\0" - "Market\0" - "Meeting\0" - "MenuKB\0" - "MenuPB\0" - "MySites\0" - "New\0" - "News\0" - "OfficeHome\0" - "Open\0" - "Option\0" - "Paste\0" - "Phone\0" - "Reply\0" - "Reload\0" - "RotateWindows\0" - "RotationPB\0" - "RotationKB\0" - "Save\0" - "ScrollUp\0" - "ScrollDown\0" - "ScrollClick\0" - "Send\0" - "Spell\0" - "SplitScreen\0" - "Support\0" - "TaskPane\0" - "Terminal\0" - "Tools\0" - "Travel\0" - "UserPB\0" - "User1KB\0" - "User2KB\0" - "Video\0" - "WheelButton\0" - "Word\0" - "Xfer\0" - "ZoomIn\0" - "ZoomOut\0" - "Away\0" - "Messenger\0" - "WebCam\0" - "MailForward\0" - "Pictures\0" - "Music\0" - "Battery\0" - "Bluetooth\0" - "WLAN\0" - "UWB\0" - "AudioForward\0" - "AudioRepeat\0" - "AudioRandomPlay\0" - "Subtitle\0" - "AudioCycleTrack\0" - "CycleAngle\0" - "FrameBack\0" - "FrameForward\0" - "Time\0" - "SelectButton\0" - "View\0" - "TopMenu\0" - "Red\0" - "Green\0" - "Yellow\0" - "Blue\0" - "Suspend\0" - "Hibernate\0" - "TouchpadToggle\0" - "TouchpadOn\0" - "TouchpadOff\0" - "AudioMicMute\0" - "VoidSymbol\0"; - -typedef struct { - unsigned int keyval; - unsigned int offset; -} clutter_key; - -static const clutter_key clutter_keys_by_keyval[] = { - { 0x000020, 0 }, - { 0x000021, 6 }, - { 0x000022, 13 }, - { 0x000023, 22 }, - { 0x000024, 33 }, - { 0x000025, 40 }, - { 0x000026, 48 }, - { 0x000027, 58 }, - { 0x000027, 69 }, - { 0x000028, 80 }, - { 0x000029, 90 }, - { 0x00002a, 101 }, - { 0x00002b, 110 }, - { 0x00002c, 115 }, - { 0x00002d, 121 }, - { 0x00002e, 127 }, - { 0x00002f, 134 }, - { 0x000030, 140 }, - { 0x000031, 142 }, - { 0x000032, 144 }, - { 0x000033, 146 }, - { 0x000034, 148 }, - { 0x000035, 150 }, - { 0x000036, 152 }, - { 0x000037, 154 }, - { 0x000038, 156 }, - { 0x000039, 158 }, - { 0x00003a, 160 }, - { 0x00003b, 166 }, - { 0x00003c, 176 }, - { 0x00003d, 181 }, - { 0x00003e, 187 }, - { 0x00003f, 195 }, - { 0x000040, 204 }, - { 0x000041, 207 }, - { 0x000042, 209 }, - { 0x000043, 211 }, - { 0x000044, 213 }, - { 0x000045, 215 }, - { 0x000046, 217 }, - { 0x000047, 219 }, - { 0x000048, 221 }, - { 0x000049, 223 }, - { 0x00004a, 225 }, - { 0x00004b, 227 }, - { 0x00004c, 229 }, - { 0x00004d, 231 }, - { 0x00004e, 233 }, - { 0x00004f, 235 }, - { 0x000050, 237 }, - { 0x000051, 239 }, - { 0x000052, 241 }, - { 0x000053, 243 }, - { 0x000054, 245 }, - { 0x000055, 247 }, - { 0x000056, 249 }, - { 0x000057, 251 }, - { 0x000058, 253 }, - { 0x000059, 255 }, - { 0x00005a, 257 }, - { 0x00005b, 259 }, - { 0x00005c, 271 }, - { 0x00005d, 281 }, - { 0x00005e, 294 }, - { 0x00005f, 306 }, - { 0x000060, 317 }, - { 0x000060, 323 }, - { 0x000061, 333 }, - { 0x000062, 335 }, - { 0x000063, 337 }, - { 0x000064, 339 }, - { 0x000065, 341 }, - { 0x000066, 343 }, - { 0x000067, 345 }, - { 0x000068, 347 }, - { 0x000069, 349 }, - { 0x00006a, 351 }, - { 0x00006b, 353 }, - { 0x00006c, 355 }, - { 0x00006d, 357 }, - { 0x00006e, 359 }, - { 0x00006f, 361 }, - { 0x000070, 363 }, - { 0x000071, 365 }, - { 0x000072, 367 }, - { 0x000073, 369 }, - { 0x000074, 371 }, - { 0x000075, 373 }, - { 0x000076, 375 }, - { 0x000077, 377 }, - { 0x000078, 379 }, - { 0x000079, 381 }, - { 0x00007a, 383 }, - { 0x00007b, 385 }, - { 0x00007c, 395 }, - { 0x00007d, 399 }, - { 0x00007e, 410 }, - { 0x0000a0, 421 }, - { 0x0000a1, 434 }, - { 0x0000a2, 445 }, - { 0x0000a3, 450 }, - { 0x0000a4, 459 }, - { 0x0000a5, 468 }, - { 0x0000a6, 472 }, - { 0x0000a7, 482 }, - { 0x0000a8, 490 }, - { 0x0000a9, 500 }, - { 0x0000aa, 510 }, - { 0x0000ab, 522 }, - { 0x0000ac, 536 }, - { 0x0000ad, 544 }, - { 0x0000ae, 551 }, - { 0x0000af, 562 }, - { 0x0000b0, 569 }, - { 0x0000b1, 576 }, - { 0x0000b2, 586 }, - { 0x0000b3, 598 }, - { 0x0000b4, 612 }, - { 0x0000b5, 618 }, - { 0x0000b6, 621 }, - { 0x0000b7, 631 }, - { 0x0000b8, 646 }, - { 0x0000b9, 654 }, - { 0x0000ba, 666 }, - { 0x0000bb, 676 }, - { 0x0000bc, 691 }, - { 0x0000bd, 702 }, - { 0x0000be, 710 }, - { 0x0000bf, 724 }, - { 0x0000c0, 737 }, - { 0x0000c1, 744 }, - { 0x0000c2, 751 }, - { 0x0000c3, 763 }, - { 0x0000c4, 770 }, - { 0x0000c5, 781 }, - { 0x0000c6, 787 }, - { 0x0000c7, 790 }, - { 0x0000c8, 799 }, - { 0x0000c9, 806 }, - { 0x0000ca, 813 }, - { 0x0000cb, 825 }, - { 0x0000cc, 836 }, - { 0x0000cd, 843 }, - { 0x0000ce, 850 }, - { 0x0000cf, 862 }, - { 0x0000d0, 873 }, - { 0x0000d0, 877 }, - { 0x0000d1, 881 }, - { 0x0000d2, 888 }, - { 0x0000d3, 895 }, - { 0x0000d4, 902 }, - { 0x0000d5, 914 }, - { 0x0000d6, 921 }, - { 0x0000d7, 932 }, - { 0x0000d8, 941 }, - { 0x0000d8, 950 }, - { 0x0000d9, 957 }, - { 0x0000da, 964 }, - { 0x0000db, 971 }, - { 0x0000dc, 983 }, - { 0x0000dd, 994 }, - { 0x0000de, 1001 }, - { 0x0000de, 1007 }, - { 0x0000df, 1013 }, - { 0x0000e0, 1020 }, - { 0x0000e1, 1027 }, - { 0x0000e2, 1034 }, - { 0x0000e3, 1046 }, - { 0x0000e4, 1053 }, - { 0x0000e5, 1064 }, - { 0x0000e6, 1070 }, - { 0x0000e7, 1073 }, - { 0x0000e8, 1082 }, - { 0x0000e9, 1089 }, - { 0x0000ea, 1096 }, - { 0x0000eb, 1108 }, - { 0x0000ec, 1119 }, - { 0x0000ed, 1126 }, - { 0x0000ee, 1133 }, - { 0x0000ef, 1145 }, - { 0x0000f0, 1156 }, - { 0x0000f1, 1160 }, - { 0x0000f2, 1167 }, - { 0x0000f3, 1174 }, - { 0x0000f4, 1181 }, - { 0x0000f5, 1193 }, - { 0x0000f6, 1200 }, - { 0x0000f7, 1211 }, - { 0x0000f8, 1220 }, - { 0x0000f8, 1229 }, - { 0x0000f9, 1236 }, - { 0x0000fa, 1243 }, - { 0x0000fb, 1250 }, - { 0x0000fc, 1262 }, - { 0x0000fd, 1273 }, - { 0x0000fe, 1280 }, - { 0x0000ff, 1286 }, - { 0x0001a1, 1297 }, - { 0x0001a2, 1305 }, - { 0x0001a3, 1311 }, - { 0x0001a5, 1319 }, - { 0x0001a6, 1326 }, - { 0x0001a9, 1333 }, - { 0x0001aa, 1340 }, - { 0x0001ab, 1349 }, - { 0x0001ac, 1356 }, - { 0x0001ae, 1363 }, - { 0x0001af, 1370 }, - { 0x0001b1, 1380 }, - { 0x0001b2, 1388 }, - { 0x0001b3, 1395 }, - { 0x0001b5, 1403 }, - { 0x0001b6, 1410 }, - { 0x0001b7, 1417 }, - { 0x0001b9, 1423 }, - { 0x0001ba, 1430 }, - { 0x0001bb, 1439 }, - { 0x0001bc, 1446 }, - { 0x0001bd, 1453 }, - { 0x0001be, 1465 }, - { 0x0001bf, 1472 }, - { 0x0001c0, 1482 }, - { 0x0001c3, 1489 }, - { 0x0001c5, 1496 }, - { 0x0001c6, 1503 }, - { 0x0001c8, 1510 }, - { 0x0001ca, 1517 }, - { 0x0001cc, 1525 }, - { 0x0001cf, 1532 }, - { 0x0001d0, 1539 }, - { 0x0001d1, 1547 }, - { 0x0001d2, 1554 }, - { 0x0001d5, 1561 }, - { 0x0001d8, 1574 }, - { 0x0001d9, 1581 }, - { 0x0001db, 1587 }, - { 0x0001de, 1600 }, - { 0x0001e0, 1609 }, - { 0x0001e3, 1616 }, - { 0x0001e5, 1623 }, - { 0x0001e6, 1630 }, - { 0x0001e8, 1637 }, - { 0x0001ea, 1644 }, - { 0x0001ec, 1652 }, - { 0x0001ef, 1659 }, - { 0x0001f0, 1666 }, - { 0x0001f1, 1674 }, - { 0x0001f2, 1681 }, - { 0x0001f5, 1688 }, - { 0x0001f8, 1701 }, - { 0x0001f9, 1708 }, - { 0x0001fb, 1714 }, - { 0x0001fe, 1727 }, - { 0x0001ff, 1736 }, - { 0x0002a1, 1745 }, - { 0x0002a6, 1753 }, - { 0x0002a9, 1765 }, - { 0x0002ab, 1775 }, - { 0x0002ac, 1782 }, - { 0x0002b1, 1794 }, - { 0x0002b6, 1802 }, - { 0x0002b9, 1814 }, - { 0x0002bb, 1823 }, - { 0x0002bc, 1830 }, - { 0x0002c5, 1842 }, - { 0x0002c6, 1852 }, - { 0x0002d5, 1864 }, - { 0x0002d8, 1874 }, - { 0x0002dd, 1886 }, - { 0x0002de, 1893 }, - { 0x0002e5, 1905 }, - { 0x0002e6, 1915 }, - { 0x0002f5, 1927 }, - { 0x0002f8, 1937 }, - { 0x0002fd, 1949 }, - { 0x0002fe, 1956 }, - { 0x0003a2, 1968 }, - { 0x0003a2, 1974 }, - { 0x0003a3, 1978 }, - { 0x0003a5, 1987 }, - { 0x0003a6, 1994 }, - { 0x0003aa, 2003 }, - { 0x0003ab, 2011 }, - { 0x0003ac, 2020 }, - { 0x0003b3, 2027 }, - { 0x0003b5, 2036 }, - { 0x0003b6, 2043 }, - { 0x0003ba, 2052 }, - { 0x0003bb, 2060 }, - { 0x0003bc, 2069 }, - { 0x0003bd, 2076 }, - { 0x0003bf, 2080 }, - { 0x0003c0, 2084 }, - { 0x0003c7, 2092 }, - { 0x0003cc, 2100 }, - { 0x0003cf, 2110 }, - { 0x0003d1, 2118 }, - { 0x0003d2, 2127 }, - { 0x0003d3, 2135 }, - { 0x0003d9, 2144 }, - { 0x0003dd, 2152 }, - { 0x0003de, 2159 }, - { 0x0003e0, 2167 }, - { 0x0003e7, 2175 }, - { 0x0003ec, 2183 }, - { 0x0003ef, 2193 }, - { 0x0003f1, 2201 }, - { 0x0003f2, 2210 }, - { 0x0003f3, 2218 }, - { 0x0003f9, 2227 }, - { 0x0003fd, 2235 }, - { 0x0003fe, 2242 }, - { 0x00047e, 2250 }, - { 0x0004a1, 2259 }, - { 0x0004a2, 2273 }, - { 0x0004a3, 2293 }, - { 0x0004a4, 2313 }, - { 0x0004a5, 2324 }, - { 0x0004a5, 2341 }, - { 0x0004a6, 2356 }, - { 0x0004a7, 2364 }, - { 0x0004a8, 2371 }, - { 0x0004a9, 2378 }, - { 0x0004aa, 2385 }, - { 0x0004ab, 2392 }, - { 0x0004ac, 2399 }, - { 0x0004ad, 2407 }, - { 0x0004ae, 2415 }, - { 0x0004af, 2423 }, - { 0x0004af, 2432 }, - { 0x0004b0, 2440 }, - { 0x0004b1, 2455 }, - { 0x0004b2, 2462 }, - { 0x0004b3, 2469 }, - { 0x0004b4, 2476 }, - { 0x0004b5, 2483 }, - { 0x0004b6, 2490 }, - { 0x0004b7, 2498 }, - { 0x0004b8, 2506 }, - { 0x0004b9, 2514 }, - { 0x0004ba, 2522 }, - { 0x0004bb, 2530 }, - { 0x0004bc, 2538 }, - { 0x0004bd, 2547 }, - { 0x0004be, 2555 }, - { 0x0004bf, 2563 }, - { 0x0004c0, 2571 }, - { 0x0004c1, 2579 }, - { 0x0004c1, 2588 }, - { 0x0004c2, 2596 }, - { 0x0004c2, 2605 }, - { 0x0004c3, 2613 }, - { 0x0004c4, 2621 }, - { 0x0004c5, 2629 }, - { 0x0004c6, 2637 }, - { 0x0004c7, 2645 }, - { 0x0004c8, 2653 }, - { 0x0004c9, 2661 }, - { 0x0004ca, 2669 }, - { 0x0004cb, 2677 }, - { 0x0004cc, 2685 }, - { 0x0004cc, 2693 }, - { 0x0004cd, 2701 }, - { 0x0004ce, 2709 }, - { 0x0004cf, 2717 }, - { 0x0004d0, 2725 }, - { 0x0004d1, 2733 }, - { 0x0004d2, 2741 }, - { 0x0004d3, 2749 }, - { 0x0004d4, 2757 }, - { 0x0004d5, 2765 }, - { 0x0004d6, 2773 }, - { 0x0004d7, 2781 }, - { 0x0004d8, 2789 }, - { 0x0004d9, 2797 }, - { 0x0004da, 2805 }, - { 0x0004db, 2813 }, - { 0x0004dc, 2821 }, - { 0x0004dd, 2829 }, - { 0x0004de, 2836 }, - { 0x0004df, 2848 }, - { 0x0005ac, 2864 }, - { 0x0005bb, 2877 }, - { 0x0005bf, 2894 }, - { 0x0005c1, 2915 }, - { 0x0005c2, 2928 }, - { 0x0005c3, 2947 }, - { 0x0005c4, 2966 }, - { 0x0005c5, 2984 }, - { 0x0005c6, 3006 }, - { 0x0005c7, 3024 }, - { 0x0005c8, 3036 }, - { 0x0005c9, 3047 }, - { 0x0005ca, 3065 }, - { 0x0005cb, 3076 }, - { 0x0005cc, 3088 }, - { 0x0005cd, 3100 }, - { 0x0005ce, 3111 }, - { 0x0005cf, 3123 }, - { 0x0005d0, 3134 }, - { 0x0005d1, 3146 }, - { 0x0005d2, 3156 }, - { 0x0005d3, 3168 }, - { 0x0005d4, 3180 }, - { 0x0005d5, 3193 }, - { 0x0005d6, 3204 }, - { 0x0005d7, 3215 }, - { 0x0005d8, 3226 }, - { 0x0005d9, 3237 }, - { 0x0005da, 3248 }, - { 0x0005e0, 3261 }, - { 0x0005e1, 3276 }, - { 0x0005e2, 3287 }, - { 0x0005e3, 3298 }, - { 0x0005e4, 3309 }, - { 0x0005e5, 3320 }, - { 0x0005e6, 3332 }, - { 0x0005e7, 3344 }, - { 0x0005e7, 3354 }, - { 0x0005e8, 3365 }, - { 0x0005e9, 3376 }, - { 0x0005ea, 3395 }, - { 0x0005eb, 3406 }, - { 0x0005ec, 3422 }, - { 0x0005ed, 3438 }, - { 0x0005ee, 3454 }, - { 0x0005ef, 3467 }, - { 0x0005f0, 3480 }, - { 0x0005f1, 3493 }, - { 0x0005f2, 3507 }, - { 0x0006a1, 3520 }, - { 0x0006a2, 3532 }, - { 0x0006a3, 3546 }, - { 0x0006a4, 3558 }, - { 0x0006a4, 3571 }, - { 0x0006a5, 3583 }, - { 0x0006a6, 3597 }, - { 0x0006a6, 3609 }, - { 0x0006a7, 3620 }, - { 0x0006a7, 3633 }, - { 0x0006a8, 3645 }, - { 0x0006a8, 3657 }, - { 0x0006a9, 3668 }, - { 0x0006a9, 3681 }, - { 0x0006aa, 3693 }, - { 0x0006aa, 3706 }, - { 0x0006ab, 3718 }, - { 0x0006ac, 3731 }, - { 0x0006ad, 3745 }, - { 0x0006ae, 3771 }, - { 0x0006af, 3791 }, - { 0x0006af, 3805 }, - { 0x0006b0, 3817 }, - { 0x0006b1, 3828 }, - { 0x0006b2, 3840 }, - { 0x0006b3, 3854 }, - { 0x0006b4, 3866 }, - { 0x0006b4, 3879 }, - { 0x0006b5, 3891 }, - { 0x0006b6, 3905 }, - { 0x0006b6, 3917 }, - { 0x0006b7, 3928 }, - { 0x0006b7, 3941 }, - { 0x0006b8, 3953 }, - { 0x0006b8, 3965 }, - { 0x0006b9, 3976 }, - { 0x0006b9, 3989 }, - { 0x0006ba, 4001 }, - { 0x0006ba, 4014 }, - { 0x0006bb, 4026 }, - { 0x0006bc, 4039 }, - { 0x0006bd, 4053 }, - { 0x0006be, 4079 }, - { 0x0006bf, 4099 }, - { 0x0006bf, 4113 }, - { 0x0006c0, 4125 }, - { 0x0006c1, 4137 }, - { 0x0006c2, 4148 }, - { 0x0006c3, 4160 }, - { 0x0006c4, 4173 }, - { 0x0006c5, 4185 }, - { 0x0006c6, 4197 }, - { 0x0006c7, 4209 }, - { 0x0006c8, 4222 }, - { 0x0006c9, 4234 }, - { 0x0006ca, 4245 }, - { 0x0006cb, 4261 }, - { 0x0006cc, 4273 }, - { 0x0006cd, 4285 }, - { 0x0006ce, 4297 }, - { 0x0006cf, 4309 }, - { 0x0006d0, 4320 }, - { 0x0006d1, 4332 }, - { 0x0006d2, 4344 }, - { 0x0006d3, 4356 }, - { 0x0006d4, 4368 }, - { 0x0006d5, 4380 }, - { 0x0006d6, 4391 }, - { 0x0006d7, 4404 }, - { 0x0006d8, 4416 }, - { 0x0006d9, 4434 }, - { 0x0006da, 4448 }, - { 0x0006db, 4460 }, - { 0x0006dc, 4473 }, - { 0x0006dd, 4484 }, - { 0x0006de, 4499 }, - { 0x0006df, 4512 }, - { 0x0006e0, 4530 }, - { 0x0006e1, 4542 }, - { 0x0006e2, 4553 }, - { 0x0006e3, 4565 }, - { 0x0006e4, 4578 }, - { 0x0006e5, 4590 }, - { 0x0006e6, 4602 }, - { 0x0006e7, 4614 }, - { 0x0006e8, 4627 }, - { 0x0006e9, 4639 }, - { 0x0006ea, 4650 }, - { 0x0006eb, 4666 }, - { 0x0006ec, 4678 }, - { 0x0006ed, 4690 }, - { 0x0006ee, 4702 }, - { 0x0006ef, 4714 }, - { 0x0006f0, 4725 }, - { 0x0006f1, 4737 }, - { 0x0006f2, 4749 }, - { 0x0006f3, 4761 }, - { 0x0006f4, 4773 }, - { 0x0006f5, 4785 }, - { 0x0006f6, 4796 }, - { 0x0006f7, 4809 }, - { 0x0006f8, 4821 }, - { 0x0006f9, 4839 }, - { 0x0006fa, 4853 }, - { 0x0006fb, 4865 }, - { 0x0006fc, 4878 }, - { 0x0006fd, 4889 }, - { 0x0006fe, 4904 }, - { 0x0006ff, 4917 }, - { 0x0007a1, 4935 }, - { 0x0007a2, 4953 }, - { 0x0007a3, 4973 }, - { 0x0007a4, 4989 }, - { 0x0007a5, 5006 }, - { 0x0007a5, 5026 }, - { 0x0007a7, 5045 }, - { 0x0007a8, 5065 }, - { 0x0007a9, 5085 }, - { 0x0007ab, 5107 }, - { 0x0007ae, 5125 }, - { 0x0007af, 5146 }, - { 0x0007b1, 5161 }, - { 0x0007b2, 5179 }, - { 0x0007b3, 5199 }, - { 0x0007b4, 5215 }, - { 0x0007b5, 5232 }, - { 0x0007b6, 5251 }, - { 0x0007b7, 5276 }, - { 0x0007b8, 5296 }, - { 0x0007b9, 5316 }, - { 0x0007ba, 5338 }, - { 0x0007bb, 5366 }, - { 0x0007c1, 5384 }, - { 0x0007c2, 5396 }, - { 0x0007c3, 5407 }, - { 0x0007c4, 5419 }, - { 0x0007c5, 5431 }, - { 0x0007c6, 5445 }, - { 0x0007c7, 5456 }, - { 0x0007c8, 5466 }, - { 0x0007c9, 5478 }, - { 0x0007ca, 5489 }, - { 0x0007cb, 5501 }, - { 0x0007cb, 5514 }, - { 0x0007cc, 5526 }, - { 0x0007cd, 5535 }, - { 0x0007ce, 5544 }, - { 0x0007cf, 5553 }, - { 0x0007d0, 5567 }, - { 0x0007d1, 5576 }, - { 0x0007d2, 5586 }, - { 0x0007d4, 5598 }, - { 0x0007d5, 5608 }, - { 0x0007d6, 5622 }, - { 0x0007d7, 5632 }, - { 0x0007d8, 5642 }, - { 0x0007d9, 5652 }, - { 0x0007e1, 5664 }, - { 0x0007e2, 5676 }, - { 0x0007e3, 5687 }, - { 0x0007e4, 5699 }, - { 0x0007e5, 5711 }, - { 0x0007e6, 5725 }, - { 0x0007e7, 5736 }, - { 0x0007e8, 5746 }, - { 0x0007e9, 5758 }, - { 0x0007ea, 5769 }, - { 0x0007eb, 5781 }, - { 0x0007eb, 5794 }, - { 0x0007ec, 5806 }, - { 0x0007ed, 5815 }, - { 0x0007ee, 5824 }, - { 0x0007ef, 5833 }, - { 0x0007f0, 5847 }, - { 0x0007f1, 5856 }, - { 0x0007f2, 5866 }, - { 0x0007f3, 5878 }, - { 0x0007f4, 5900 }, - { 0x0007f5, 5910 }, - { 0x0007f6, 5924 }, - { 0x0007f7, 5934 }, - { 0x0007f8, 5944 }, - { 0x0007f9, 5954 }, - { 0x0008a1, 5966 }, - { 0x0008a2, 5978 }, - { 0x0008a3, 5993 }, - { 0x0008a4, 6008 }, - { 0x0008a5, 6020 }, - { 0x0008a6, 6032 }, - { 0x0008a7, 6046 }, - { 0x0008a8, 6063 }, - { 0x0008a9, 6080 }, - { 0x0008aa, 6098 }, - { 0x0008ab, 6116 }, - { 0x0008ac, 6130 }, - { 0x0008ad, 6144 }, - { 0x0008ae, 6159 }, - { 0x0008af, 6174 }, - { 0x0008b0, 6195 }, - { 0x0008b1, 6217 }, - { 0x0008b2, 6234 }, - { 0x0008b3, 6251 }, - { 0x0008b4, 6277 }, - { 0x0008b5, 6303 }, - { 0x0008b6, 6321 }, - { 0x0008b7, 6339 }, - { 0x0008bc, 6360 }, - { 0x0008bd, 6374 }, - { 0x0008be, 6383 }, - { 0x0008bf, 6400 }, - { 0x0008c0, 6409 }, - { 0x0008c1, 6419 }, - { 0x0008c2, 6429 }, - { 0x0008c5, 6438 }, - { 0x0008c8, 6444 }, - { 0x0008c9, 6456 }, - { 0x0008cd, 6469 }, - { 0x0008ce, 6478 }, - { 0x0008cf, 6486 }, - { 0x0008d6, 6496 }, - { 0x0008da, 6504 }, - { 0x0008db, 6515 }, - { 0x0008dc, 6524 }, - { 0x0008dd, 6537 }, - { 0x0008de, 6543 }, - { 0x0008df, 6554 }, - { 0x0008ef, 6564 }, - { 0x0008f6, 6582 }, - { 0x0008fb, 6591 }, - { 0x0008fc, 6601 }, - { 0x0008fd, 6609 }, - { 0x0008fe, 6620 }, - { 0x0009df, 6630 }, - { 0x0009e0, 6636 }, - { 0x0009e1, 6649 }, - { 0x0009e2, 6662 }, - { 0x0009e3, 6665 }, - { 0x0009e4, 6668 }, - { 0x0009e5, 6671 }, - { 0x0009e8, 6674 }, - { 0x0009e9, 6677 }, - { 0x0009ea, 6680 }, - { 0x0009eb, 6695 }, - { 0x0009ec, 6709 }, - { 0x0009ed, 6722 }, - { 0x0009ee, 6736 }, - { 0x0009ef, 6750 }, - { 0x0009f0, 6765 }, - { 0x0009f1, 6780 }, - { 0x0009f2, 6795 }, - { 0x0009f3, 6810 }, - { 0x0009f4, 6825 }, - { 0x0009f5, 6831 }, - { 0x0009f6, 6838 }, - { 0x0009f7, 6843 }, - { 0x0009f8, 6848 }, - { 0x000aa1, 6856 }, - { 0x000aa2, 6864 }, - { 0x000aa3, 6872 }, - { 0x000aa4, 6881 }, - { 0x000aa5, 6890 }, - { 0x000aa6, 6901 }, - { 0x000aa7, 6912 }, - { 0x000aa8, 6922 }, - { 0x000aa9, 6932 }, - { 0x000aaa, 6939 }, - { 0x000aac, 6946 }, - { 0x000aae, 6958 }, - { 0x000aaf, 6967 }, - { 0x000ab0, 6983 }, - { 0x000ab1, 6992 }, - { 0x000ab2, 7002 }, - { 0x000ab3, 7011 }, - { 0x000ab4, 7021 }, - { 0x000ab5, 7033 }, - { 0x000ab6, 7044 }, - { 0x000ab7, 7053 }, - { 0x000ab8, 7064 }, - { 0x000abb, 7071 }, - { 0x000abc, 7079 }, - { 0x000abd, 7096 }, - { 0x000abe, 7109 }, - { 0x000abf, 7127 }, - { 0x000ac3, 7134 }, - { 0x000ac4, 7144 }, - { 0x000ac5, 7157 }, - { 0x000ac6, 7169 }, - { 0x000ac9, 7182 }, - { 0x000aca, 7192 }, - { 0x000acb, 7206 }, - { 0x000acc, 7224 }, - { 0x000acd, 7241 }, - { 0x000ace, 7259 }, - { 0x000acf, 7272 }, - { 0x000ad0, 7288 }, - { 0x000ad1, 7308 }, - { 0x000ad2, 7329 }, - { 0x000ad3, 7349 }, - { 0x000ad4, 7370 }, - { 0x000ad5, 7383 }, - { 0x000ad6, 7392 }, - { 0x000ad7, 7400 }, - { 0x000ad9, 7408 }, - { 0x000ada, 7419 }, - { 0x000adb, 7428 }, - { 0x000adc, 7445 }, - { 0x000add, 7465 }, - { 0x000ade, 7486 }, - { 0x000adf, 7501 }, - { 0x000ae0, 7514 }, - { 0x000ae1, 7531 }, - { 0x000ae2, 7550 }, - { 0x000ae3, 7565 }, - { 0x000ae4, 7581 }, - { 0x000ae5, 7599 }, - { 0x000ae6, 7608 }, - { 0x000ae7, 7627 }, - { 0x000ae8, 7644 }, - { 0x000ae9, 7662 }, - { 0x000aea, 7682 }, - { 0x000aeb, 7694 }, - { 0x000aec, 7707 }, - { 0x000aed, 7712 }, - { 0x000aee, 7720 }, - { 0x000af0, 7726 }, - { 0x000af1, 7739 }, - { 0x000af2, 7746 }, - { 0x000af3, 7759 }, - { 0x000af4, 7769 }, - { 0x000af5, 7781 }, - { 0x000af6, 7794 }, - { 0x000af7, 7806 }, - { 0x000af8, 7817 }, - { 0x000af9, 7830 }, - { 0x000afa, 7840 }, - { 0x000afb, 7858 }, - { 0x000afc, 7878 }, - { 0x000afd, 7884 }, - { 0x000afe, 7903 }, - { 0x000aff, 7922 }, - { 0x000ba3, 7929 }, - { 0x000ba6, 7939 }, - { 0x000ba8, 7950 }, - { 0x000ba9, 7960 }, - { 0x000bc0, 7968 }, - { 0x000bc2, 7976 }, - { 0x000bc3, 7985 }, - { 0x000bc4, 7992 }, - { 0x000bc6, 8002 }, - { 0x000bca, 8011 }, - { 0x000bcc, 8015 }, - { 0x000bce, 8020 }, - { 0x000bcf, 8027 }, - { 0x000bd3, 8034 }, - { 0x000bd6, 8042 }, - { 0x000bd8, 8051 }, - { 0x000bda, 8061 }, - { 0x000bdc, 8070 }, - { 0x000bfc, 8079 }, - { 0x000cdf, 8089 }, - { 0x000ce0, 8110 }, - { 0x000ce1, 8123 }, - { 0x000ce1, 8134 }, - { 0x000ce2, 8146 }, - { 0x000ce2, 8159 }, - { 0x000ce3, 8173 }, - { 0x000ce3, 8186 }, - { 0x000ce4, 8200 }, - { 0x000ce5, 8210 }, - { 0x000ce6, 8221 }, - { 0x000ce6, 8233 }, - { 0x000ce7, 8246 }, - { 0x000ce7, 8258 }, - { 0x000ce8, 8269 }, - { 0x000ce8, 8280 }, - { 0x000ce9, 8292 }, - { 0x000cea, 8303 }, - { 0x000ceb, 8320 }, - { 0x000cec, 8332 }, - { 0x000ced, 8345 }, - { 0x000cee, 8361 }, - { 0x000cef, 8372 }, - { 0x000cf0, 8388 }, - { 0x000cf1, 8399 }, - { 0x000cf1, 8413 }, - { 0x000cf2, 8427 }, - { 0x000cf3, 8439 }, - { 0x000cf4, 8454 }, - { 0x000cf5, 8464 }, - { 0x000cf5, 8481 }, - { 0x000cf6, 8498 }, - { 0x000cf6, 8510 }, - { 0x000cf7, 8522 }, - { 0x000cf7, 8533 }, - { 0x000cf8, 8545 }, - { 0x000cf9, 8557 }, - { 0x000cfa, 8569 }, - { 0x000cfa, 8580 }, - { 0x000da1, 8591 }, - { 0x000da2, 8602 }, - { 0x000da3, 8615 }, - { 0x000da4, 8629 }, - { 0x000da5, 8643 }, - { 0x000da6, 8656 }, - { 0x000da7, 8672 }, - { 0x000da8, 8684 }, - { 0x000da9, 8697 }, - { 0x000daa, 8711 }, - { 0x000dab, 8725 }, - { 0x000dac, 8735 }, - { 0x000dad, 8748 }, - { 0x000dae, 8760 }, - { 0x000daf, 8773 }, - { 0x000db0, 8786 }, - { 0x000db1, 8799 }, - { 0x000db2, 8818 }, - { 0x000db3, 8834 }, - { 0x000db4, 8845 }, - { 0x000db5, 8856 }, - { 0x000db6, 8867 }, - { 0x000db7, 8881 }, - { 0x000db8, 8896 }, - { 0x000db9, 8910 }, - { 0x000dba, 8920 }, - { 0x000dbb, 8934 }, - { 0x000dbc, 8945 }, - { 0x000dbd, 8959 }, - { 0x000dbe, 8969 }, - { 0x000dbf, 8982 }, - { 0x000dc0, 8993 }, - { 0x000dc1, 9009 }, - { 0x000dc2, 9019 }, - { 0x000dc3, 9030 }, - { 0x000dc4, 9041 }, - { 0x000dc5, 9049 }, - { 0x000dc6, 9061 }, - { 0x000dc7, 9069 }, - { 0x000dc8, 9081 }, - { 0x000dc9, 9093 }, - { 0x000dca, 9105 }, - { 0x000dcb, 9116 }, - { 0x000dcc, 9127 }, - { 0x000dcd, 9140 }, - { 0x000dce, 9150 }, - { 0x000dcf, 9164 }, - { 0x000dd0, 9179 }, - { 0x000dd1, 9190 }, - { 0x000dd2, 9206 }, - { 0x000dd3, 9218 }, - { 0x000dd4, 9230 }, - { 0x000dd5, 9241 }, - { 0x000dd6, 9253 }, - { 0x000dd7, 9265 }, - { 0x000dd8, 9278 }, - { 0x000dd9, 9289 }, - { 0x000dda, 9301 }, - { 0x000dde, 9314 }, - { 0x000ddf, 9337 }, - { 0x000de0, 9347 }, - { 0x000de1, 9358 }, - { 0x000de2, 9370 }, - { 0x000de3, 9381 }, - { 0x000de4, 9400 }, - { 0x000de5, 9420 }, - { 0x000de6, 9437 }, - { 0x000de7, 9451 }, - { 0x000de8, 9466 }, - { 0x000de9, 9477 }, - { 0x000dea, 9489 }, - { 0x000deb, 9501 }, - { 0x000dec, 9518 }, - { 0x000ded, 9535 }, - { 0x000df0, 9549 }, - { 0x000df1, 9561 }, - { 0x000df2, 9574 }, - { 0x000df3, 9587 }, - { 0x000df4, 9599 }, - { 0x000df5, 9610 }, - { 0x000df6, 9621 }, - { 0x000df7, 9633 }, - { 0x000df8, 9646 }, - { 0x000df9, 9659 }, - { 0x000ea1, 9671 }, - { 0x000ea2, 9685 }, - { 0x000ea3, 9704 }, - { 0x000ea4, 9722 }, - { 0x000ea5, 9735 }, - { 0x000ea6, 9753 }, - { 0x000ea7, 9771 }, - { 0x000ea8, 9785 }, - { 0x000ea9, 9804 }, - { 0x000eaa, 9817 }, - { 0x000eab, 9836 }, - { 0x000eac, 9854 }, - { 0x000ead, 9872 }, - { 0x000eae, 9889 }, - { 0x000eaf, 9907 }, - { 0x000eb0, 9926 }, - { 0x000eb1, 9944 }, - { 0x000eb2, 9957 }, - { 0x000eb3, 9970 }, - { 0x000eb4, 9988 }, - { 0x000eb5, 10005 }, - { 0x000eb6, 10017 }, - { 0x000eb7, 10034 }, - { 0x000eb8, 10047 }, - { 0x000eb9, 10060 }, - { 0x000eba, 10078 }, - { 0x000ebb, 10091 }, - { 0x000ebc, 10105 }, - { 0x000ebd, 10118 }, - { 0x000ebe, 10132 }, - { 0x000ebf, 10145 }, - { 0x000ec0, 10154 }, - { 0x000ec1, 10164 }, - { 0x000ec2, 10174 }, - { 0x000ec3, 10185 }, - { 0x000ec4, 10195 }, - { 0x000ec5, 10204 }, - { 0x000ec6, 10215 }, - { 0x000ec7, 10225 }, - { 0x000ec8, 10234 }, - { 0x000ec9, 10244 }, - { 0x000eca, 10255 }, - { 0x000ecb, 10265 }, - { 0x000ecc, 10275 }, - { 0x000ecd, 10284 }, - { 0x000ece, 10295 }, - { 0x000ecf, 10305 }, - { 0x000ed0, 10315 }, - { 0x000ed1, 10325 }, - { 0x000ed2, 10335 }, - { 0x000ed3, 10345 }, - { 0x000ed4, 10354 }, - { 0x000ed5, 10370 }, - { 0x000ed6, 10391 }, - { 0x000ed7, 10411 }, - { 0x000ed8, 10426 }, - { 0x000ed9, 10446 }, - { 0x000eda, 10466 }, - { 0x000edb, 10482 }, - { 0x000edc, 10497 }, - { 0x000edd, 10518 }, - { 0x000ede, 10538 }, - { 0x000edf, 10558 }, - { 0x000ee0, 10577 }, - { 0x000ee1, 10597 }, - { 0x000ee2, 10618 }, - { 0x000ee3, 10638 }, - { 0x000ee4, 10653 }, - { 0x000ee5, 10668 }, - { 0x000ee6, 10687 }, - { 0x000ee7, 10701 }, - { 0x000ee8, 10720 }, - { 0x000ee9, 10735 }, - { 0x000eea, 10750 }, - { 0x000eeb, 10765 }, - { 0x000eec, 10781 }, - { 0x000eed, 10796 }, - { 0x000eee, 10812 }, - { 0x000eef, 10827 }, - { 0x000ef0, 10851 }, - { 0x000ef1, 10876 }, - { 0x000ef2, 10901 }, - { 0x000ef3, 10916 }, - { 0x000ef4, 10941 }, - { 0x000ef5, 10967 }, - { 0x000ef6, 10986 }, - { 0x000ef7, 10999 }, - { 0x000ef8, 11013 }, - { 0x000ef9, 11030 }, - { 0x000efa, 11057 }, - { 0x000eff, 11078 }, - { 0x0013bc, 11089 }, - { 0x0013bd, 11092 }, - { 0x0013be, 11095 }, - { 0x0020ac, 11106 }, - { 0x00fd01, 11115 }, - { 0x00fd02, 11130 }, - { 0x00fd03, 11145 }, - { 0x00fd04, 11157 }, - { 0x00fd05, 11168 }, - { 0x00fd06, 11181 }, - { 0x00fd07, 11195 }, - { 0x00fd08, 11211 }, - { 0x00fd09, 11222 }, - { 0x00fd0a, 11232 }, - { 0x00fd0b, 11241 }, - { 0x00fd0c, 11250 }, - { 0x00fd0d, 11259 }, - { 0x00fd0e, 11269 }, - { 0x00fd0f, 11279 }, - { 0x00fd10, 11296 }, - { 0x00fd11, 11311 }, - { 0x00fd12, 11325 }, - { 0x00fd13, 11335 }, - { 0x00fd14, 11346 }, - { 0x00fd15, 11356 }, - { 0x00fd16, 11366 }, - { 0x00fd17, 11376 }, - { 0x00fd18, 11387 }, - { 0x00fd19, 11399 }, - { 0x00fd1a, 11417 }, - { 0x00fd1b, 11433 }, - { 0x00fd1c, 11447 }, - { 0x00fd1d, 11465 }, - { 0x00fd1e, 11482 }, - { 0x00fe01, 11493 }, - { 0x00fe02, 11502 }, - { 0x00fe03, 11519 }, - { 0x00fe04, 11536 }, - { 0x00fe05, 11553 }, - { 0x00fe06, 11569 }, - { 0x00fe07, 11585 }, - { 0x00fe08, 11600 }, - { 0x00fe09, 11615 }, - { 0x00fe0a, 11635 }, - { 0x00fe0b, 11650 }, - { 0x00fe0c, 11670 }, - { 0x00fe0d, 11686 }, - { 0x00fe0e, 11707 }, - { 0x00fe0f, 11722 }, - { 0x00fe11, 11742 }, - { 0x00fe12, 11759 }, - { 0x00fe13, 11776 }, - { 0x00fe20, 11792 }, - { 0x00fe21, 11805 }, - { 0x00fe22, 11822 }, - { 0x00fe23, 11841 }, - { 0x00fe24, 11861 }, - { 0x00fe25, 11883 }, - { 0x00fe26, 11906 }, - { 0x00fe27, 11930 }, - { 0x00fe28, 11950 }, - { 0x00fe29, 11971 }, - { 0x00fe2a, 11995 }, - { 0x00fe2b, 12020 }, - { 0x00fe2c, 12045 }, - { 0x00fe2d, 12066 }, - { 0x00fe2e, 12088 }, - { 0x00fe2f, 12107 }, - { 0x00fe30, 12128 }, - { 0x00fe31, 12153 }, - { 0x00fe32, 12181 }, - { 0x00fe33, 12195 }, - { 0x00fe34, 12213 }, - { 0x00fe50, 12223 }, - { 0x00fe51, 12234 }, - { 0x00fe52, 12245 }, - { 0x00fe53, 12261 }, - { 0x00fe53, 12278 }, - { 0x00fe54, 12289 }, - { 0x00fe55, 12301 }, - { 0x00fe56, 12312 }, - { 0x00fe57, 12326 }, - { 0x00fe58, 12341 }, - { 0x00fe59, 12356 }, - { 0x00fe5a, 12373 }, - { 0x00fe5b, 12384 }, - { 0x00fe5c, 12397 }, - { 0x00fe5d, 12409 }, - { 0x00fe5e, 12419 }, - { 0x00fe5f, 12437 }, - { 0x00fe60, 12459 }, - { 0x00fe61, 12473 }, - { 0x00fe62, 12483 }, - { 0x00fe63, 12493 }, - { 0x00fe64, 12505 }, - { 0x00fe64, 12521 }, - { 0x00fe65, 12532 }, - { 0x00fe65, 12556 }, - { 0x00fe66, 12567 }, - { 0x00fe67, 12584 }, - { 0x00fe68, 12599 }, - { 0x00fe69, 12616 }, - { 0x00fe6a, 12637 }, - { 0x00fe6b, 12653 }, - { 0x00fe6c, 12669 }, - { 0x00fe6d, 12689 }, - { 0x00fe6e, 12708 }, - { 0x00fe6f, 12724 }, - { 0x00fe70, 12738 }, - { 0x00fe71, 12753 }, - { 0x00fe72, 12777 }, - { 0x00fe73, 12795 }, - { 0x00fe74, 12811 }, - { 0x00fe75, 12829 }, - { 0x00fe76, 12847 }, - { 0x00fe77, 12864 }, - { 0x00fe78, 12887 }, - { 0x00fe79, 12903 }, - { 0x00fe7a, 12919 }, - { 0x00fe80, 12938 }, - { 0x00fe81, 12945 }, - { 0x00fe82, 12952 }, - { 0x00fe83, 12959 }, - { 0x00fe84, 12966 }, - { 0x00fe85, 12973 }, - { 0x00fe86, 12980 }, - { 0x00fe87, 12987 }, - { 0x00fe88, 12994 }, - { 0x00fe89, 13001 }, - { 0x00fe8a, 13008 }, - { 0x00fe8b, 13025 }, - { 0x00fe8c, 13044 }, - { 0x00fea0, 13055 }, - { 0x00fea1, 13058 }, - { 0x00fea2, 13061 }, - { 0x00fea3, 13064 }, - { 0x00fea4, 13068 }, - { 0x00fea5, 13072 }, - { 0x00fed0, 13076 }, - { 0x00fed1, 13097 }, - { 0x00fed2, 13117 }, - { 0x00fed4, 13137 }, - { 0x00fed5, 13157 }, - { 0x00fee0, 13174 }, - { 0x00fee1, 13187 }, - { 0x00fee2, 13201 }, - { 0x00fee3, 13212 }, - { 0x00fee4, 13225 }, - { 0x00fee5, 13240 }, - { 0x00fee6, 13256 }, - { 0x00fee7, 13273 }, - { 0x00fee8, 13291 }, - { 0x00fee9, 13311 }, - { 0x00feea, 13327 }, - { 0x00feeb, 13343 }, - { 0x00feec, 13359 }, - { 0x00feed, 13375 }, - { 0x00feee, 13391 }, - { 0x00feef, 13413 }, - { 0x00fef0, 13431 }, - { 0x00fef1, 13449 }, - { 0x00fef2, 13467 }, - { 0x00fef3, 13485 }, - { 0x00fef4, 13503 }, - { 0x00fef5, 13521 }, - { 0x00fef6, 13535 }, - { 0x00fef7, 13549 }, - { 0x00fef8, 13563 }, - { 0x00fef9, 13577 }, - { 0x00fefa, 13596 }, - { 0x00fefb, 13615 }, - { 0x00fefc, 13635 }, - { 0x00fefd, 13655 }, - { 0x00ff08, 13669 }, - { 0x00ff09, 13679 }, - { 0x00ff0a, 13683 }, - { 0x00ff0b, 13692 }, - { 0x00ff0d, 13698 }, - { 0x00ff13, 13705 }, - { 0x00ff14, 13711 }, - { 0x00ff15, 13723 }, - { 0x00ff1b, 13731 }, - { 0x00ff20, 13738 }, - { 0x00ff21, 13748 }, - { 0x00ff22, 13754 }, - { 0x00ff23, 13763 }, - { 0x00ff23, 13770 }, - { 0x00ff24, 13782 }, - { 0x00ff25, 13789 }, - { 0x00ff26, 13798 }, - { 0x00ff27, 13807 }, - { 0x00ff28, 13825 }, - { 0x00ff29, 13833 }, - { 0x00ff2a, 13841 }, - { 0x00ff2b, 13857 }, - { 0x00ff2c, 13865 }, - { 0x00ff2d, 13872 }, - { 0x00ff2e, 13882 }, - { 0x00ff2f, 13893 }, - { 0x00ff30, 13904 }, - { 0x00ff31, 13916 }, - { 0x00ff32, 13923 }, - { 0x00ff33, 13936 }, - { 0x00ff34, 13947 }, - { 0x00ff35, 13960 }, - { 0x00ff36, 13972 }, - { 0x00ff37, 13986 }, - { 0x00ff37, 13996 }, - { 0x00ff37, 14013 }, - { 0x00ff38, 14026 }, - { 0x00ff39, 14040 }, - { 0x00ff3a, 14053 }, - { 0x00ff3b, 14069 }, - { 0x00ff3c, 14086 }, - { 0x00ff3c, 14109 }, - { 0x00ff3d, 14125 }, - { 0x00ff3d, 14150 }, - { 0x00ff3d, 14168 }, - { 0x00ff3e, 14177 }, - { 0x00ff3e, 14202 }, - { 0x00ff3e, 14211 }, - { 0x00ff3f, 14229 }, - { 0x00ff50, 14244 }, - { 0x00ff51, 14249 }, - { 0x00ff52, 14254 }, - { 0x00ff53, 14257 }, - { 0x00ff54, 14263 }, - { 0x00ff55, 14268 }, - { 0x00ff55, 14276 }, - { 0x00ff56, 14282 }, - { 0x00ff56, 14292 }, - { 0x00ff57, 14297 }, - { 0x00ff58, 14301 }, - { 0x00ff60, 14307 }, - { 0x00ff61, 14314 }, - { 0x00ff62, 14320 }, - { 0x00ff63, 14328 }, - { 0x00ff65, 14335 }, - { 0x00ff66, 14340 }, - { 0x00ff67, 14345 }, - { 0x00ff68, 14350 }, - { 0x00ff69, 14355 }, - { 0x00ff6a, 14362 }, - { 0x00ff6b, 14367 }, - { 0x00ff7e, 14373 }, - { 0x00ff7e, 14387 }, - { 0x00ff7e, 14400 }, - { 0x00ff7e, 14414 }, - { 0x00ff7e, 14428 }, - { 0x00ff7e, 14444 }, - { 0x00ff7e, 14456 }, - { 0x00ff7e, 14468 }, - { 0x00ff7f, 14482 }, - { 0x00ff80, 14491 }, - { 0x00ff89, 14500 }, - { 0x00ff8d, 14507 }, - { 0x00ff91, 14516 }, - { 0x00ff92, 14522 }, - { 0x00ff93, 14528 }, - { 0x00ff94, 14534 }, - { 0x00ff95, 14540 }, - { 0x00ff96, 14548 }, - { 0x00ff97, 14556 }, - { 0x00ff98, 14562 }, - { 0x00ff99, 14571 }, - { 0x00ff9a, 14579 }, - { 0x00ff9a, 14590 }, - { 0x00ff9b, 14599 }, - { 0x00ff9b, 14607 }, - { 0x00ff9c, 14620 }, - { 0x00ff9d, 14627 }, - { 0x00ff9e, 14636 }, - { 0x00ff9f, 14646 }, - { 0x00ffaa, 14656 }, - { 0x00ffab, 14668 }, - { 0x00ffac, 14675 }, - { 0x00ffad, 14688 }, - { 0x00ffae, 14700 }, - { 0x00ffaf, 14711 }, - { 0x00ffb0, 14721 }, - { 0x00ffb1, 14726 }, - { 0x00ffb2, 14731 }, - { 0x00ffb3, 14736 }, - { 0x00ffb4, 14741 }, - { 0x00ffb5, 14746 }, - { 0x00ffb6, 14751 }, - { 0x00ffb7, 14756 }, - { 0x00ffb8, 14761 }, - { 0x00ffb9, 14766 }, - { 0x00ffbd, 14771 }, - { 0x00ffbe, 14780 }, - { 0x00ffbf, 14783 }, - { 0x00ffc0, 14786 }, - { 0x00ffc1, 14789 }, - { 0x00ffc2, 14792 }, - { 0x00ffc3, 14795 }, - { 0x00ffc4, 14798 }, - { 0x00ffc5, 14801 }, - { 0x00ffc6, 14804 }, - { 0x00ffc7, 14807 }, - { 0x00ffc8, 14811 }, - { 0x00ffc8, 14815 }, - { 0x00ffc9, 14818 }, - { 0x00ffc9, 14822 }, - { 0x00ffca, 14825 }, - { 0x00ffca, 14829 }, - { 0x00ffcb, 14832 }, - { 0x00ffcb, 14836 }, - { 0x00ffcc, 14839 }, - { 0x00ffcc, 14843 }, - { 0x00ffcd, 14846 }, - { 0x00ffcd, 14850 }, - { 0x00ffce, 14853 }, - { 0x00ffce, 14857 }, - { 0x00ffcf, 14860 }, - { 0x00ffcf, 14864 }, - { 0x00ffd0, 14867 }, - { 0x00ffd0, 14871 }, - { 0x00ffd1, 14874 }, - { 0x00ffd1, 14878 }, - { 0x00ffd2, 14882 }, - { 0x00ffd2, 14886 }, - { 0x00ffd3, 14889 }, - { 0x00ffd3, 14893 }, - { 0x00ffd4, 14896 }, - { 0x00ffd4, 14900 }, - { 0x00ffd5, 14903 }, - { 0x00ffd5, 14907 }, - { 0x00ffd6, 14910 }, - { 0x00ffd6, 14914 }, - { 0x00ffd7, 14917 }, - { 0x00ffd7, 14921 }, - { 0x00ffd8, 14924 }, - { 0x00ffd8, 14928 }, - { 0x00ffd9, 14931 }, - { 0x00ffd9, 14935 }, - { 0x00ffda, 14938 }, - { 0x00ffda, 14942 }, - { 0x00ffdb, 14945 }, - { 0x00ffdb, 14949 }, - { 0x00ffdc, 14953 }, - { 0x00ffdc, 14957 }, - { 0x00ffdd, 14961 }, - { 0x00ffdd, 14965 }, - { 0x00ffde, 14969 }, - { 0x00ffde, 14973 }, - { 0x00ffdf, 14977 }, - { 0x00ffdf, 14981 }, - { 0x00ffe0, 14985 }, - { 0x00ffe0, 14989 }, - { 0x00ffe1, 14993 }, - { 0x00ffe2, 15001 }, - { 0x00ffe3, 15009 }, - { 0x00ffe4, 15019 }, - { 0x00ffe5, 15029 }, - { 0x00ffe6, 15039 }, - { 0x00ffe7, 15050 }, - { 0x00ffe8, 15057 }, - { 0x00ffe9, 15064 }, - { 0x00ffea, 15070 }, - { 0x00ffeb, 15076 }, - { 0x00ffec, 15084 }, - { 0x00ffed, 15092 }, - { 0x00ffee, 15100 }, - { 0x00fff1, 15108 }, - { 0x00fff2, 15122 }, - { 0x00fff3, 15136 }, - { 0x00fff4, 15150 }, - { 0x00fff5, 15164 }, - { 0x00fff6, 15178 }, - { 0x00fff7, 15192 }, - { 0x00fff8, 15206 }, - { 0x00fff9, 15220 }, - { 0x00fffa, 15234 }, - { 0x00ffff, 15249 }, - { 0x100012c, 15256 }, - { 0x100012d, 15263 }, - { 0x1000174, 15270 }, - { 0x1000175, 15282 }, - { 0x1000176, 15294 }, - { 0x1000177, 15306 }, - { 0x100018f, 15318 }, - { 0x100019f, 15324 }, - { 0x10001a0, 15332 }, - { 0x10001a1, 15338 }, - { 0x10001af, 15344 }, - { 0x10001b0, 15350 }, - { 0x10001b5, 15356 }, - { 0x10001b6, 15364 }, - { 0x10001b7, 15372 }, - { 0x10001d1, 15376 }, - { 0x10001d2, 15383 }, - { 0x10001e6, 15390 }, - { 0x10001e7, 15397 }, - { 0x1000259, 15404 }, - { 0x1000275, 15410 }, - { 0x1000292, 15418 }, - { 0x1000492, 15422 }, - { 0x1000493, 15439 }, - { 0x1000496, 15456 }, - { 0x1000497, 15479 }, - { 0x100049a, 15502 }, - { 0x100049b, 15524 }, - { 0x100049c, 15546 }, - { 0x100049d, 15569 }, - { 0x10004a2, 15592 }, - { 0x10004a3, 15614 }, - { 0x10004ae, 15636 }, - { 0x10004af, 15656 }, - { 0x10004b0, 15676 }, - { 0x10004b1, 15700 }, - { 0x10004b2, 15724 }, - { 0x10004b3, 15746 }, - { 0x10004b6, 15768 }, - { 0x10004b7, 15791 }, - { 0x10004b8, 15814 }, - { 0x10004b9, 15838 }, - { 0x10004ba, 15862 }, - { 0x10004bb, 15876 }, - { 0x10004d8, 15890 }, - { 0x10004d9, 15905 }, - { 0x10004e2, 15920 }, - { 0x10004e3, 15938 }, - { 0x10004e8, 15956 }, - { 0x10004e9, 15971 }, - { 0x10004ee, 15986 }, - { 0x10004ef, 16004 }, - { 0x1000531, 16022 }, - { 0x1000532, 16035 }, - { 0x1000533, 16048 }, - { 0x1000534, 16061 }, - { 0x1000535, 16073 }, - { 0x1000536, 16087 }, - { 0x1000537, 16099 }, - { 0x1000538, 16110 }, - { 0x1000539, 16122 }, - { 0x100053a, 16134 }, - { 0x100053b, 16147 }, - { 0x100053c, 16160 }, - { 0x100053d, 16174 }, - { 0x100053e, 16187 }, - { 0x100053f, 16200 }, - { 0x1000540, 16213 }, - { 0x1000541, 16225 }, - { 0x1000542, 16238 }, - { 0x1000543, 16252 }, - { 0x1000544, 16266 }, - { 0x1000545, 16279 }, - { 0x1000546, 16291 }, - { 0x1000547, 16303 }, - { 0x1000548, 16316 }, - { 0x1000549, 16328 }, - { 0x100054a, 16341 }, - { 0x100054b, 16353 }, - { 0x100054c, 16365 }, - { 0x100054d, 16377 }, - { 0x100054e, 16389 }, - { 0x100054f, 16402 }, - { 0x1000550, 16416 }, - { 0x1000551, 16428 }, - { 0x1000552, 16441 }, - { 0x1000553, 16455 }, - { 0x1000554, 16469 }, - { 0x1000555, 16481 }, - { 0x1000556, 16492 }, - { 0x100055a, 16504 }, - { 0x100055b, 16524 }, - { 0x100055b, 16540 }, - { 0x100055c, 16556 }, - { 0x100055c, 16572 }, - { 0x100055d, 16588 }, - { 0x100055d, 16601 }, - { 0x100055e, 16626 }, - { 0x100055e, 16642 }, - { 0x1000561, 16660 }, - { 0x1000562, 16673 }, - { 0x1000563, 16686 }, - { 0x1000564, 16699 }, - { 0x1000565, 16711 }, - { 0x1000566, 16725 }, - { 0x1000567, 16737 }, - { 0x1000568, 16748 }, - { 0x1000569, 16760 }, - { 0x100056a, 16772 }, - { 0x100056b, 16785 }, - { 0x100056c, 16798 }, - { 0x100056d, 16812 }, - { 0x100056e, 16825 }, - { 0x100056f, 16838 }, - { 0x1000570, 16851 }, - { 0x1000571, 16863 }, - { 0x1000572, 16876 }, - { 0x1000573, 16890 }, - { 0x1000574, 16904 }, - { 0x1000575, 16917 }, - { 0x1000576, 16929 }, - { 0x1000577, 16941 }, - { 0x1000578, 16954 }, - { 0x1000579, 16966 }, - { 0x100057a, 16979 }, - { 0x100057b, 16991 }, - { 0x100057c, 17003 }, - { 0x100057d, 17015 }, - { 0x100057e, 17027 }, - { 0x100057f, 17040 }, - { 0x1000580, 17054 }, - { 0x1000581, 17066 }, - { 0x1000582, 17079 }, - { 0x1000583, 17093 }, - { 0x1000584, 17107 }, - { 0x1000585, 17119 }, - { 0x1000586, 17130 }, - { 0x1000587, 17142 }, - { 0x1000589, 17163 }, - { 0x1000589, 17182 }, - { 0x100058a, 17200 }, - { 0x100058a, 17216 }, - { 0x1000653, 17234 }, - { 0x1000654, 17253 }, - { 0x1000655, 17272 }, - { 0x1000660, 17291 }, - { 0x1000661, 17300 }, - { 0x1000662, 17309 }, - { 0x1000663, 17318 }, - { 0x1000664, 17327 }, - { 0x1000665, 17336 }, - { 0x1000666, 17345 }, - { 0x1000667, 17354 }, - { 0x1000668, 17363 }, - { 0x1000669, 17372 }, - { 0x100066a, 17381 }, - { 0x1000670, 17396 }, - { 0x1000679, 17420 }, - { 0x100067e, 17432 }, - { 0x1000686, 17443 }, - { 0x1000688, 17456 }, - { 0x1000691, 17468 }, - { 0x1000698, 17480 }, - { 0x10006a4, 17491 }, - { 0x10006a9, 17502 }, - { 0x10006af, 17515 }, - { 0x10006ba, 17526 }, - { 0x10006be, 17545 }, - { 0x10006c1, 17568 }, - { 0x10006cc, 17584 }, - { 0x10006cc, 17601 }, - { 0x10006d2, 17611 }, - { 0x10006d4, 17628 }, - { 0x10006f0, 17644 }, - { 0x10006f1, 17652 }, - { 0x10006f2, 17660 }, - { 0x10006f3, 17668 }, - { 0x10006f4, 17676 }, - { 0x10006f5, 17684 }, - { 0x10006f6, 17692 }, - { 0x10006f7, 17700 }, - { 0x10006f8, 17708 }, - { 0x10006f9, 17716 }, - { 0x1000d82, 17724 }, - { 0x1000d83, 17732 }, - { 0x1000d85, 17740 }, - { 0x1000d86, 17747 }, - { 0x1000d87, 17755 }, - { 0x1000d88, 17763 }, - { 0x1000d89, 17772 }, - { 0x1000d8a, 17779 }, - { 0x1000d8b, 17787 }, - { 0x1000d8c, 17794 }, - { 0x1000d8d, 17802 }, - { 0x1000d8e, 17810 }, - { 0x1000d8f, 17819 }, - { 0x1000d90, 17827 }, - { 0x1000d91, 17836 }, - { 0x1000d92, 17843 }, - { 0x1000d93, 17851 }, - { 0x1000d94, 17859 }, - { 0x1000d95, 17866 }, - { 0x1000d96, 17874 }, - { 0x1000d9a, 17882 }, - { 0x1000d9b, 17890 }, - { 0x1000d9c, 17899 }, - { 0x1000d9d, 17907 }, - { 0x1000d9e, 17916 }, - { 0x1000d9f, 17925 }, - { 0x1000da0, 17934 }, - { 0x1000da1, 17942 }, - { 0x1000da2, 17951 }, - { 0x1000da3, 17959 }, - { 0x1000da4, 17968 }, - { 0x1000da5, 17977 }, - { 0x1000da6, 17987 }, - { 0x1000da7, 17996 }, - { 0x1000da8, 18005 }, - { 0x1000da9, 18015 }, - { 0x1000daa, 18024 }, - { 0x1000dab, 18034 }, - { 0x1000dac, 18043 }, - { 0x1000dad, 18053 }, - { 0x1000dae, 18062 }, - { 0x1000daf, 18072 }, - { 0x1000db0, 18081 }, - { 0x1000db1, 18091 }, - { 0x1000db3, 18099 }, - { 0x1000db4, 18109 }, - { 0x1000db5, 18117 }, - { 0x1000db6, 18126 }, - { 0x1000db7, 18134 }, - { 0x1000db8, 18143 }, - { 0x1000db9, 18151 }, - { 0x1000dba, 18160 }, - { 0x1000dbb, 18168 }, - { 0x1000dbd, 18176 }, - { 0x1000dc0, 18184 }, - { 0x1000dc1, 18192 }, - { 0x1000dc2, 18201 }, - { 0x1000dc3, 18211 }, - { 0x1000dc4, 18219 }, - { 0x1000dc5, 18227 }, - { 0x1000dc6, 18236 }, - { 0x1000dca, 18244 }, - { 0x1000dcf, 18252 }, - { 0x1000dd0, 18261 }, - { 0x1000dd1, 18270 }, - { 0x1000dd2, 18280 }, - { 0x1000dd3, 18288 }, - { 0x1000dd4, 18297 }, - { 0x1000dd6, 18305 }, - { 0x1000dd8, 18314 }, - { 0x1000dd9, 18323 }, - { 0x1000dda, 18331 }, - { 0x1000ddb, 18340 }, - { 0x1000ddc, 18349 }, - { 0x1000ddd, 18357 }, - { 0x1000dde, 18366 }, - { 0x1000ddf, 18375 }, - { 0x1000df2, 18384 }, - { 0x1000df3, 18394 }, - { 0x1000df4, 18404 }, - { 0x10010d0, 18420 }, - { 0x10010d1, 18432 }, - { 0x10010d2, 18445 }, - { 0x10010d3, 18458 }, - { 0x10010d4, 18471 }, - { 0x10010d5, 18483 }, - { 0x10010d6, 18496 }, - { 0x10010d7, 18509 }, - { 0x10010d8, 18522 }, - { 0x10010d9, 18534 }, - { 0x10010da, 18547 }, - { 0x10010db, 18560 }, - { 0x10010dc, 18573 }, - { 0x10010dd, 18586 }, - { 0x10010de, 18598 }, - { 0x10010df, 18611 }, - { 0x10010e0, 18625 }, - { 0x10010e1, 18638 }, - { 0x10010e2, 18651 }, - { 0x10010e3, 18664 }, - { 0x10010e4, 18676 }, - { 0x10010e5, 18690 }, - { 0x10010e6, 18704 }, - { 0x10010e7, 18718 }, - { 0x10010e8, 18731 }, - { 0x10010e9, 18745 }, - { 0x10010ea, 18759 }, - { 0x10010eb, 18772 }, - { 0x10010ec, 18785 }, - { 0x10010ed, 18798 }, - { 0x10010ee, 18812 }, - { 0x10010ef, 18825 }, - { 0x10010f0, 18839 }, - { 0x10010f1, 18852 }, - { 0x10010f2, 18864 }, - { 0x10010f3, 18877 }, - { 0x10010f4, 18889 }, - { 0x10010f5, 18902 }, - { 0x10010f6, 18915 }, - { 0x1001e02, 18927 }, - { 0x1001e03, 18937 }, - { 0x1001e0a, 18947 }, - { 0x1001e0b, 18957 }, - { 0x1001e1e, 18967 }, - { 0x1001e1f, 18977 }, - { 0x1001e36, 18987 }, - { 0x1001e37, 18997 }, - { 0x1001e40, 19007 }, - { 0x1001e41, 19017 }, - { 0x1001e56, 19027 }, - { 0x1001e57, 19037 }, - { 0x1001e60, 19047 }, - { 0x1001e61, 19057 }, - { 0x1001e6a, 19067 }, - { 0x1001e6b, 19077 }, - { 0x1001e80, 19087 }, - { 0x1001e81, 19094 }, - { 0x1001e82, 19101 }, - { 0x1001e83, 19108 }, - { 0x1001e84, 19115 }, - { 0x1001e85, 19126 }, - { 0x1001e8a, 19137 }, - { 0x1001e8b, 19147 }, - { 0x1001ea0, 19157 }, - { 0x1001ea1, 19167 }, - { 0x1001ea2, 19177 }, - { 0x1001ea3, 19183 }, - { 0x1001ea4, 19189 }, - { 0x1001ea5, 19206 }, - { 0x1001ea6, 19223 }, - { 0x1001ea7, 19240 }, - { 0x1001ea8, 19257 }, - { 0x1001ea9, 19273 }, - { 0x1001eaa, 19289 }, - { 0x1001eab, 19306 }, - { 0x1001eac, 19323 }, - { 0x1001ead, 19343 }, - { 0x1001eae, 19363 }, - { 0x1001eaf, 19375 }, - { 0x1001eb0, 19387 }, - { 0x1001eb1, 19399 }, - { 0x1001eb2, 19411 }, - { 0x1001eb3, 19422 }, - { 0x1001eb4, 19433 }, - { 0x1001eb5, 19445 }, - { 0x1001eb6, 19457 }, - { 0x1001eb7, 19472 }, - { 0x1001eb8, 19487 }, - { 0x1001eb9, 19497 }, - { 0x1001eba, 19507 }, - { 0x1001ebb, 19513 }, - { 0x1001ebc, 19519 }, - { 0x1001ebd, 19526 }, - { 0x1001ebe, 19533 }, - { 0x1001ebf, 19550 }, - { 0x1001ec0, 19567 }, - { 0x1001ec1, 19584 }, - { 0x1001ec2, 19601 }, - { 0x1001ec3, 19617 }, - { 0x1001ec4, 19633 }, - { 0x1001ec5, 19650 }, - { 0x1001ec6, 19667 }, - { 0x1001ec7, 19687 }, - { 0x1001ec8, 19707 }, - { 0x1001ec9, 19713 }, - { 0x1001eca, 19719 }, - { 0x1001ecb, 19729 }, - { 0x1001ecc, 19739 }, - { 0x1001ecd, 19749 }, - { 0x1001ece, 19759 }, - { 0x1001ecf, 19765 }, - { 0x1001ed0, 19771 }, - { 0x1001ed1, 19788 }, - { 0x1001ed2, 19805 }, - { 0x1001ed3, 19822 }, - { 0x1001ed4, 19839 }, - { 0x1001ed5, 19855 }, - { 0x1001ed6, 19871 }, - { 0x1001ed7, 19888 }, - { 0x1001ed8, 19905 }, - { 0x1001ed9, 19925 }, - { 0x1001eda, 19945 }, - { 0x1001edb, 19956 }, - { 0x1001edc, 19967 }, - { 0x1001edd, 19978 }, - { 0x1001ede, 19989 }, - { 0x1001edf, 19999 }, - { 0x1001ee0, 20009 }, - { 0x1001ee1, 20020 }, - { 0x1001ee2, 20031 }, - { 0x1001ee3, 20045 }, - { 0x1001ee4, 20059 }, - { 0x1001ee5, 20069 }, - { 0x1001ee6, 20079 }, - { 0x1001ee7, 20085 }, - { 0x1001ee8, 20091 }, - { 0x1001ee9, 20102 }, - { 0x1001eea, 20113 }, - { 0x1001eeb, 20124 }, - { 0x1001eec, 20135 }, - { 0x1001eed, 20145 }, - { 0x1001eee, 20155 }, - { 0x1001eef, 20166 }, - { 0x1001ef0, 20177 }, - { 0x1001ef1, 20191 }, - { 0x1001ef2, 20205 }, - { 0x1001ef3, 20212 }, - { 0x1001ef4, 20219 }, - { 0x1001ef5, 20229 }, - { 0x1001ef6, 20239 }, - { 0x1001ef7, 20245 }, - { 0x1001ef8, 20251 }, - { 0x1001ef9, 20258 }, - { 0x1002070, 20265 }, - { 0x1002074, 20278 }, - { 0x1002075, 20291 }, - { 0x1002076, 20304 }, - { 0x1002077, 20316 }, - { 0x1002078, 20330 }, - { 0x1002079, 20344 }, - { 0x1002080, 20357 }, - { 0x1002081, 20371 }, - { 0x1002082, 20384 }, - { 0x1002083, 20397 }, - { 0x1002084, 20412 }, - { 0x1002085, 20426 }, - { 0x1002086, 20440 }, - { 0x1002087, 20453 }, - { 0x1002088, 20468 }, - { 0x1002089, 20483 }, - { 0x10020a0, 20497 }, - { 0x10020a1, 20505 }, - { 0x10020a2, 20515 }, - { 0x10020a3, 20528 }, - { 0x10020a4, 20539 }, - { 0x10020a5, 20548 }, - { 0x10020a6, 20557 }, - { 0x10020a7, 20567 }, - { 0x10020a8, 20578 }, - { 0x10020a9, 20588 }, - { 0x10020aa, 20596 }, - { 0x10020ab, 20610 }, - { 0x1002202, 20619 }, - { 0x1002205, 20636 }, - { 0x1002208, 20645 }, - { 0x1002209, 20655 }, - { 0x100220b, 20668 }, - { 0x100221a, 20679 }, - { 0x100221b, 20690 }, - { 0x100221c, 20699 }, - { 0x100222c, 20710 }, - { 0x100222d, 20720 }, - { 0x1002235, 20730 }, - { 0x1002247, 20738 }, - { 0x1002248, 20750 }, - { 0x1002262, 20759 }, - { 0x1002263, 20772 }, - { 0x1002800, 20781 }, - { 0x1002801, 20795 }, - { 0x1002802, 20810 }, - { 0x1002803, 20825 }, - { 0x1002804, 20841 }, - { 0x1002805, 20856 }, - { 0x1002806, 20872 }, - { 0x1002807, 20888 }, - { 0x1002808, 20905 }, - { 0x1002809, 20920 }, - { 0x100280a, 20936 }, - { 0x100280b, 20952 }, - { 0x100280c, 20969 }, - { 0x100280d, 20985 }, - { 0x100280e, 21002 }, - { 0x100280f, 21019 }, - { 0x1002810, 21037 }, - { 0x1002811, 21052 }, - { 0x1002812, 21068 }, - { 0x1002813, 21084 }, - { 0x1002814, 21101 }, - { 0x1002815, 21117 }, - { 0x1002816, 21134 }, - { 0x1002817, 21151 }, - { 0x1002818, 21169 }, - { 0x1002819, 21185 }, - { 0x100281a, 21202 }, - { 0x100281b, 21219 }, - { 0x100281c, 21237 }, - { 0x100281d, 21254 }, - { 0x100281e, 21272 }, - { 0x100281f, 21290 }, - { 0x1002820, 21309 }, - { 0x1002821, 21324 }, - { 0x1002822, 21340 }, - { 0x1002823, 21356 }, - { 0x1002824, 21373 }, - { 0x1002825, 21389 }, - { 0x1002826, 21406 }, - { 0x1002827, 21423 }, - { 0x1002828, 21441 }, - { 0x1002829, 21457 }, - { 0x100282a, 21474 }, - { 0x100282b, 21491 }, - { 0x100282c, 21509 }, - { 0x100282d, 21526 }, - { 0x100282e, 21544 }, - { 0x100282f, 21562 }, - { 0x1002830, 21581 }, - { 0x1002831, 21597 }, - { 0x1002832, 21614 }, - { 0x1002833, 21631 }, - { 0x1002834, 21649 }, - { 0x1002835, 21666 }, - { 0x1002836, 21684 }, - { 0x1002837, 21702 }, - { 0x1002838, 21721 }, - { 0x1002839, 21738 }, - { 0x100283a, 21756 }, - { 0x100283b, 21774 }, - { 0x100283c, 21793 }, - { 0x100283d, 21811 }, - { 0x100283e, 21830 }, - { 0x100283f, 21849 }, - { 0x1002840, 21869 }, - { 0x1002841, 21884 }, - { 0x1002842, 21900 }, - { 0x1002843, 21916 }, - { 0x1002844, 21933 }, - { 0x1002845, 21949 }, - { 0x1002846, 21966 }, - { 0x1002847, 21983 }, - { 0x1002848, 22001 }, - { 0x1002849, 22017 }, - { 0x100284a, 22034 }, - { 0x100284b, 22051 }, - { 0x100284c, 22069 }, - { 0x100284d, 22086 }, - { 0x100284e, 22104 }, - { 0x100284f, 22122 }, - { 0x1002850, 22141 }, - { 0x1002851, 22157 }, - { 0x1002852, 22174 }, - { 0x1002853, 22191 }, - { 0x1002854, 22209 }, - { 0x1002855, 22226 }, - { 0x1002856, 22244 }, - { 0x1002857, 22262 }, - { 0x1002858, 22281 }, - { 0x1002859, 22298 }, - { 0x100285a, 22316 }, - { 0x100285b, 22334 }, - { 0x100285c, 22353 }, - { 0x100285d, 22371 }, - { 0x100285e, 22390 }, - { 0x100285f, 22409 }, - { 0x1002860, 22429 }, - { 0x1002861, 22445 }, - { 0x1002862, 22462 }, - { 0x1002863, 22479 }, - { 0x1002864, 22497 }, - { 0x1002865, 22514 }, - { 0x1002866, 22532 }, - { 0x1002867, 22550 }, - { 0x1002868, 22569 }, - { 0x1002869, 22586 }, - { 0x100286a, 22604 }, - { 0x100286b, 22622 }, - { 0x100286c, 22641 }, - { 0x100286d, 22659 }, - { 0x100286e, 22678 }, - { 0x100286f, 22697 }, - { 0x1002870, 22717 }, - { 0x1002871, 22734 }, - { 0x1002872, 22752 }, - { 0x1002873, 22770 }, - { 0x1002874, 22789 }, - { 0x1002875, 22807 }, - { 0x1002876, 22826 }, - { 0x1002877, 22845 }, - { 0x1002878, 22865 }, - { 0x1002879, 22883 }, - { 0x100287a, 22902 }, - { 0x100287b, 22921 }, - { 0x100287c, 22941 }, - { 0x100287d, 22960 }, - { 0x100287e, 22980 }, - { 0x100287f, 23000 }, - { 0x1002880, 23021 }, - { 0x1002881, 23036 }, - { 0x1002882, 23052 }, - { 0x1002883, 23068 }, - { 0x1002884, 23085 }, - { 0x1002885, 23101 }, - { 0x1002886, 23118 }, - { 0x1002887, 23135 }, - { 0x1002888, 23153 }, - { 0x1002889, 23169 }, - { 0x100288a, 23186 }, - { 0x100288b, 23203 }, - { 0x100288c, 23221 }, - { 0x100288d, 23238 }, - { 0x100288e, 23256 }, - { 0x100288f, 23274 }, - { 0x1002890, 23293 }, - { 0x1002891, 23309 }, - { 0x1002892, 23326 }, - { 0x1002893, 23343 }, - { 0x1002894, 23361 }, - { 0x1002895, 23378 }, - { 0x1002896, 23396 }, - { 0x1002897, 23414 }, - { 0x1002898, 23433 }, - { 0x1002899, 23450 }, - { 0x100289a, 23468 }, - { 0x100289b, 23486 }, - { 0x100289c, 23505 }, - { 0x100289d, 23523 }, - { 0x100289e, 23542 }, - { 0x100289f, 23561 }, - { 0x10028a0, 23581 }, - { 0x10028a1, 23597 }, - { 0x10028a2, 23614 }, - { 0x10028a3, 23631 }, - { 0x10028a4, 23649 }, - { 0x10028a5, 23666 }, - { 0x10028a6, 23684 }, - { 0x10028a7, 23702 }, - { 0x10028a8, 23721 }, - { 0x10028a9, 23738 }, - { 0x10028aa, 23756 }, - { 0x10028ab, 23774 }, - { 0x10028ac, 23793 }, - { 0x10028ad, 23811 }, - { 0x10028ae, 23830 }, - { 0x10028af, 23849 }, - { 0x10028b0, 23869 }, - { 0x10028b1, 23886 }, - { 0x10028b2, 23904 }, - { 0x10028b3, 23922 }, - { 0x10028b4, 23941 }, - { 0x10028b5, 23959 }, - { 0x10028b6, 23978 }, - { 0x10028b7, 23997 }, - { 0x10028b8, 24017 }, - { 0x10028b9, 24035 }, - { 0x10028ba, 24054 }, - { 0x10028bb, 24073 }, - { 0x10028bc, 24093 }, - { 0x10028bd, 24112 }, - { 0x10028be, 24132 }, - { 0x10028bf, 24152 }, - { 0x10028c0, 24173 }, - { 0x10028c1, 24189 }, - { 0x10028c2, 24206 }, - { 0x10028c3, 24223 }, - { 0x10028c4, 24241 }, - { 0x10028c5, 24258 }, - { 0x10028c6, 24276 }, - { 0x10028c7, 24294 }, - { 0x10028c8, 24313 }, - { 0x10028c9, 24330 }, - { 0x10028ca, 24348 }, - { 0x10028cb, 24366 }, - { 0x10028cc, 24385 }, - { 0x10028cd, 24403 }, - { 0x10028ce, 24422 }, - { 0x10028cf, 24441 }, - { 0x10028d0, 24461 }, - { 0x10028d1, 24478 }, - { 0x10028d2, 24496 }, - { 0x10028d3, 24514 }, - { 0x10028d4, 24533 }, - { 0x10028d5, 24551 }, - { 0x10028d6, 24570 }, - { 0x10028d7, 24589 }, - { 0x10028d8, 24609 }, - { 0x10028d9, 24627 }, - { 0x10028da, 24646 }, - { 0x10028db, 24665 }, - { 0x10028dc, 24685 }, - { 0x10028dd, 24704 }, - { 0x10028de, 24724 }, - { 0x10028df, 24744 }, - { 0x10028e0, 24765 }, - { 0x10028e1, 24782 }, - { 0x10028e2, 24800 }, - { 0x10028e3, 24818 }, - { 0x10028e4, 24837 }, - { 0x10028e5, 24855 }, - { 0x10028e6, 24874 }, - { 0x10028e7, 24893 }, - { 0x10028e8, 24913 }, - { 0x10028e9, 24931 }, - { 0x10028ea, 24950 }, - { 0x10028eb, 24969 }, - { 0x10028ec, 24989 }, - { 0x10028ed, 25008 }, - { 0x10028ee, 25028 }, - { 0x10028ef, 25048 }, - { 0x10028f0, 25069 }, - { 0x10028f1, 25087 }, - { 0x10028f2, 25106 }, - { 0x10028f3, 25125 }, - { 0x10028f4, 25145 }, - { 0x10028f5, 25164 }, - { 0x10028f6, 25184 }, - { 0x10028f7, 25204 }, - { 0x10028f8, 25225 }, - { 0x10028f9, 25244 }, - { 0x10028fa, 25264 }, - { 0x10028fb, 25284 }, - { 0x10028fc, 25305 }, - { 0x10028fd, 25325 }, - { 0x10028fe, 25346 }, - { 0x10028ff, 25367 }, - { 0x1008fe01, 25389 }, - { 0x1008fe02, 25401 }, - { 0x1008fe03, 25413 }, - { 0x1008fe04, 25425 }, - { 0x1008fe05, 25437 }, - { 0x1008fe06, 25449 }, - { 0x1008fe07, 25461 }, - { 0x1008fe08, 25473 }, - { 0x1008fe09, 25485 }, - { 0x1008fe0a, 25497 }, - { 0x1008fe0b, 25510 }, - { 0x1008fe0c, 25523 }, - { 0x1008fe20, 25536 }, - { 0x1008fe21, 25543 }, - { 0x1008fe22, 25553 }, - { 0x1008fe23, 25564 }, - { 0x1008fe24, 25575 }, - { 0x1008fe25, 25589 }, - { 0x1008ff01, 25601 }, - { 0x1008ff02, 25610 }, - { 0x1008ff03, 25626 }, - { 0x1008ff04, 25644 }, - { 0x1008ff05, 25658 }, - { 0x1008ff06, 25674 }, - { 0x1008ff10, 25692 }, - { 0x1008ff11, 25700 }, - { 0x1008ff12, 25717 }, - { 0x1008ff13, 25727 }, - { 0x1008ff14, 25744 }, - { 0x1008ff15, 25754 }, - { 0x1008ff16, 25764 }, - { 0x1008ff17, 25774 }, - { 0x1008ff18, 25784 }, - { 0x1008ff19, 25793 }, - { 0x1008ff1a, 25798 }, - { 0x1008ff1b, 25804 }, - { 0x1008ff1c, 25811 }, - { 0x1008ff1d, 25823 }, - { 0x1008ff1e, 25834 }, - { 0x1008ff1f, 25839 }, - { 0x1008ff20, 25848 }, - { 0x1008ff21, 25857 }, - { 0x1008ff22, 25867 }, - { 0x1008ff23, 25882 }, - { 0x1008ff24, 25891 }, - { 0x1008ff25, 25902 }, - { 0x1008ff26, 25914 }, - { 0x1008ff27, 25919 }, - { 0x1008ff28, 25927 }, - { 0x1008ff29, 25932 }, - { 0x1008ff2a, 25940 }, - { 0x1008ff2b, 25949 }, - { 0x1008ff2c, 25956 }, - { 0x1008ff2d, 25962 }, - { 0x1008ff2e, 25974 }, - { 0x1008ff2f, 25978 }, - { 0x1008ff30, 25984 }, - { 0x1008ff31, 25994 }, - { 0x1008ff32, 26005 }, - { 0x1008ff33, 26016 }, - { 0x1008ff34, 26027 }, - { 0x1008ff35, 26038 }, - { 0x1008ff36, 26048 }, - { 0x1008ff37, 26053 }, - { 0x1008ff38, 26061 }, - { 0x1008ff39, 26069 }, - { 0x1008ff3a, 26081 }, - { 0x1008ff3b, 26090 }, - { 0x1008ff3c, 26107 }, - { 0x1008ff3d, 26115 }, - { 0x1008ff3e, 26125 }, - { 0x1008ff3f, 26137 }, - { 0x1008ff40, 26149 }, - { 0x1008ff41, 26157 }, - { 0x1008ff42, 26165 }, - { 0x1008ff43, 26173 }, - { 0x1008ff44, 26181 }, - { 0x1008ff45, 26189 }, - { 0x1008ff46, 26197 }, - { 0x1008ff47, 26205 }, - { 0x1008ff48, 26213 }, - { 0x1008ff49, 26221 }, - { 0x1008ff4a, 26229 }, - { 0x1008ff4b, 26237 }, - { 0x1008ff4c, 26245 }, - { 0x1008ff4d, 26253 }, - { 0x1008ff4e, 26261 }, - { 0x1008ff4f, 26269 }, - { 0x1008ff50, 26277 }, - { 0x1008ff51, 26293 }, - { 0x1008ff52, 26310 }, - { 0x1008ff53, 26315 }, - { 0x1008ff55, 26318 }, - { 0x1008ff56, 26330 }, - { 0x1008ff57, 26336 }, - { 0x1008ff58, 26341 }, - { 0x1008ff59, 26345 }, - { 0x1008ff5a, 26353 }, - { 0x1008ff5b, 26357 }, - { 0x1008ff5c, 26367 }, - { 0x1008ff5d, 26373 }, - { 0x1008ff5e, 26382 }, - { 0x1008ff5f, 26387 }, - { 0x1008ff60, 26390 }, - { 0x1008ff61, 26397 }, - { 0x1008ff62, 26404 }, - { 0x1008ff63, 26411 }, - { 0x1008ff65, 26419 }, - { 0x1008ff66, 26426 }, - { 0x1008ff67, 26433 }, - { 0x1008ff68, 26441 }, - { 0x1008ff69, 26445 }, - { 0x1008ff6a, 26450 }, - { 0x1008ff6b, 26461 }, - { 0x1008ff6c, 26466 }, - { 0x1008ff6d, 26473 }, - { 0x1008ff6e, 26479 }, - { 0x1008ff72, 26485 }, - { 0x1008ff73, 26491 }, - { 0x1008ff74, 26498 }, - { 0x1008ff75, 26512 }, - { 0x1008ff76, 26523 }, - { 0x1008ff77, 26534 }, - { 0x1008ff78, 26539 }, - { 0x1008ff79, 26548 }, - { 0x1008ff7a, 26559 }, - { 0x1008ff7b, 26571 }, - { 0x1008ff7c, 26576 }, - { 0x1008ff7d, 26582 }, - { 0x1008ff7e, 26594 }, - { 0x1008ff7f, 26602 }, - { 0x1008ff80, 26611 }, - { 0x1008ff81, 26620 }, - { 0x1008ff82, 26626 }, - { 0x1008ff84, 26633 }, - { 0x1008ff85, 26640 }, - { 0x1008ff86, 26648 }, - { 0x1008ff87, 26656 }, - { 0x1008ff88, 26662 }, - { 0x1008ff89, 26674 }, - { 0x1008ff8a, 26679 }, - { 0x1008ff8b, 26684 }, - { 0x1008ff8c, 26691 }, - { 0x1008ff8d, 26699 }, - { 0x1008ff8e, 26704 }, - { 0x1008ff8f, 26714 }, - { 0x1008ff90, 26721 }, - { 0x1008ff91, 26733 }, - { 0x1008ff92, 26742 }, - { 0x1008ff93, 26748 }, - { 0x1008ff94, 26756 }, - { 0x1008ff95, 26766 }, - { 0x1008ff96, 26771 }, - { 0x1008ff97, 26775 }, - { 0x1008ff98, 26788 }, - { 0x1008ff99, 26800 }, - { 0x1008ff9a, 26816 }, - { 0x1008ff9b, 26825 }, - { 0x1008ff9c, 26841 }, - { 0x1008ff9d, 26852 }, - { 0x1008ff9e, 26862 }, - { 0x1008ff9f, 26875 }, - { 0x1008ffa0, 26880 }, - { 0x1008ffa1, 26893 }, - { 0x1008ffa2, 26898 }, - { 0x1008ffa3, 26906 }, - { 0x1008ffa4, 26910 }, - { 0x1008ffa5, 26916 }, - { 0x1008ffa6, 26923 }, - { 0x1008ffa7, 26928 }, - { 0x1008ffa8, 26936 }, - { 0x1008ffa9, 26946 }, - { 0x1008ffb0, 26961 }, - { 0x1008ffb1, 26972 }, - { 0x1008ffb2, 26984 }, - { 0xffffff, 26997 } -}; - -static const clutter_key clutter_keys_by_name[] = { - { 0x000030, 140 }, - { 0x000031, 142 }, - { 0x000032, 144 }, - { 0x000033, 146 }, - { 0x00fd10, 11296 }, - { 0x00fd0e, 11269 }, - { 0x00fd05, 11168 }, - { 0x00fd19, 11399 }, - { 0x00fd15, 11356 }, - { 0x00fd0f, 11279 }, - { 0x00fd1c, 11447 }, - { 0x00fd1a, 11417 }, - { 0x00fd01, 11115 }, - { 0x00fd1e, 11482 }, - { 0x00fd06, 11181 }, - { 0x00fd07, 11195 }, - { 0x00fd1b, 11433 }, - { 0x00fd02, 11130 }, - { 0x00fd13, 11335 }, - { 0x00fd12, 11325 }, - { 0x00fd11, 11311 }, - { 0x00fd04, 11157 }, - { 0x00fd0a, 11232 }, - { 0x00fd0b, 11241 }, - { 0x00fd0c, 11250 }, - { 0x00fd16, 11366 }, - { 0x00fd1d, 11465 }, - { 0x00fd09, 11222 }, - { 0x00fd18, 11387 }, - { 0x00fd08, 11211 }, - { 0x00fd03, 11145 }, - { 0x00fd14, 11346 }, - { 0x00fd17, 11376 }, - { 0x00fd0d, 11259 }, - { 0x000034, 148 }, - { 0x000035, 150 }, - { 0x000036, 152 }, - { 0x000037, 154 }, - { 0x000038, 156 }, - { 0x000039, 158 }, - { 0x000041, 207 }, - { 0x0000c6, 787 }, - { 0x0000c1, 744 }, - { 0x1001ea0, 19157 }, - { 0x0001c3, 1489 }, - { 0x1001eae, 19363 }, - { 0x1001eb6, 19457 }, - { 0x1001eb0, 19387 }, - { 0x1001eb2, 19411 }, - { 0x1001eb4, 19433 }, - { 0x00fe70, 12738 }, - { 0x00fe71, 12753 }, - { 0x0000c2, 751 }, - { 0x1001ea4, 19189 }, - { 0x1001eac, 19323 }, - { 0x1001ea6, 19223 }, - { 0x1001ea8, 19257 }, - { 0x1001eaa, 19289 }, - { 0x1008ff39, 26069 }, - { 0x0000c4, 770 }, - { 0x0000c0, 737 }, - { 0x1001ea2, 19177 }, - { 0x00ffe9, 15064 }, - { 0x00ffea, 15070 }, - { 0x0003c0, 2084 }, - { 0x0001a1, 1297 }, - { 0x1008ff50, 26277 }, - { 0x1008ff51, 26293 }, - { 0x1000660, 17291 }, - { 0x1000661, 17300 }, - { 0x1000662, 17309 }, - { 0x1000663, 17318 }, - { 0x1000664, 17327 }, - { 0x1000665, 17336 }, - { 0x1000666, 17345 }, - { 0x1000667, 17354 }, - { 0x1000668, 17363 }, - { 0x1000669, 17372 }, - { 0x0005d9, 3237 }, - { 0x0005c7, 3024 }, - { 0x0005e9, 3376 }, - { 0x0005c8, 3036 }, - { 0x0005ac, 2864 }, - { 0x0005d6, 3204 }, - { 0x0005cf, 3123 }, - { 0x0005ef, 3467 }, - { 0x0005ec, 3422 }, - { 0x1000688, 17456 }, - { 0x10006cc, 17584 }, - { 0x0005ee, 3454 }, - { 0x0005eb, 3406 }, - { 0x0005e1, 3276 }, - { 0x10006d4, 17628 }, - { 0x10006af, 17515 }, - { 0x0005da, 3248 }, - { 0x0005e7, 3344 }, - { 0x0005cd, 3100 }, - { 0x0005c1, 2915 }, - { 0x1000654, 17253 }, - { 0x1000655, 17272 }, - { 0x0005c3, 2947 }, - { 0x0005c4, 2966 }, - { 0x0005c6, 3006 }, - { 0x0005c5, 2984 }, - { 0x0005e7, 3354 }, - { 0x10006be, 17545 }, - { 0x10006c1, 17568 }, - { 0x0005cc, 3088 }, - { 0x1000698, 17480 }, - { 0x0005e3, 3298 }, - { 0x0005f0, 3480 }, - { 0x0005ed, 3438 }, - { 0x10006a9, 17502 }, - { 0x0005ce, 3111 }, - { 0x0005e4, 3309 }, - { 0x1000653, 17234 }, - { 0x0005c2, 2928 }, - { 0x0005e5, 3320 }, - { 0x0005e6, 3332 }, - { 0x10006ba, 17526 }, - { 0x100067e, 17432 }, - { 0x100066a, 17381 }, - { 0x0005e2, 3287 }, - { 0x0005bf, 2894 }, - { 0x0005d1, 3146 }, - { 0x1000691, 17468 }, - { 0x0005d5, 3193 }, - { 0x0005d3, 3168 }, - { 0x0005bb, 2877 }, - { 0x0005f1, 3493 }, - { 0x0005d4, 3180 }, - { 0x0005f2, 3507 }, - { 0x1000670, 17396 }, - { 0x00ff7e, 14373 }, - { 0x0005d7, 3215 }, - { 0x0005e0, 3261 }, - { 0x1000686, 17443 }, - { 0x0005ca, 3065 }, - { 0x0005c9, 3047 }, - { 0x0005d0, 3134 }, - { 0x0005cb, 3076 }, - { 0x1000679, 17420 }, - { 0x10006a4, 17491 }, - { 0x0005e8, 3365 }, - { 0x0005ea, 3395 }, - { 0x10006d2, 17611 }, - { 0x0005d8, 3226 }, - { 0x0005d2, 3156 }, - { 0x0000c5, 781 }, - { 0x1000538, 16110 }, - { 0x1000531, 16022 }, - { 0x1000532, 16035 }, - { 0x1000549, 16328 }, - { 0x1000534, 16061 }, - { 0x1000541, 16225 }, - { 0x1000537, 16099 }, - { 0x1000556, 16492 }, - { 0x1000542, 16238 }, - { 0x1000533, 16048 }, - { 0x1000545, 16279 }, - { 0x1000540, 16213 }, - { 0x100053b, 16147 }, - { 0x100054b, 16353 }, - { 0x1000554, 16469 }, - { 0x100053f, 16200 }, - { 0x100053d, 16174 }, - { 0x100053c, 16160 }, - { 0x1000544, 16266 }, - { 0x1000546, 16291 }, - { 0x1000555, 16481 }, - { 0x100054a, 16341 }, - { 0x1000553, 16455 }, - { 0x100054c, 16365 }, - { 0x1000550, 16416 }, - { 0x100054d, 16377 }, - { 0x1000547, 16303 }, - { 0x1000543, 16252 }, - { 0x1000539, 16122 }, - { 0x100053e, 16187 }, - { 0x1000551, 16428 }, - { 0x100054f, 16402 }, - { 0x100054e, 16389 }, - { 0x1000548, 16316 }, - { 0x1000552, 16441 }, - { 0x1000535, 16073 }, - { 0x1000536, 16087 }, - { 0x100053a, 16134 }, - { 0x100055b, 16524 }, - { 0x100055c, 16556 }, - { 0x100055a, 16504 }, - { 0x1000568, 16748 }, - { 0x1000561, 16660 }, - { 0x1000562, 16673 }, - { 0x100055d, 16588 }, - { 0x1000579, 16966 }, - { 0x1000564, 16699 }, - { 0x1000571, 16863 }, - { 0x1000567, 16737 }, - { 0x100055c, 16572 }, - { 0x1000586, 17130 }, - { 0x1000589, 17163 }, - { 0x1000572, 16876 }, - { 0x1000563, 16686 }, - { 0x1000575, 16917 }, - { 0x1000570, 16851 }, - { 0x100058a, 17200 }, - { 0x100056b, 16785 }, - { 0x100057b, 16991 }, - { 0x1000584, 17107 }, - { 0x100056f, 16838 }, - { 0x100056d, 16812 }, - { 0x1000587, 17142 }, - { 0x100056c, 16798 }, - { 0x1000574, 16904 }, - { 0x1000576, 16929 }, - { 0x1000585, 17119 }, - { 0x100055e, 16626 }, - { 0x100057a, 16979 }, - { 0x1000583, 17093 }, - { 0x100055e, 16642 }, - { 0x100057c, 17003 }, - { 0x1000580, 17054 }, - { 0x100057d, 17015 }, - { 0x100055d, 16601 }, - { 0x1000577, 16941 }, - { 0x100055b, 16540 }, - { 0x1000573, 16890 }, - { 0x1000569, 16760 }, - { 0x100056e, 16825 }, - { 0x1000581, 17066 }, - { 0x100057f, 17040 }, - { 0x1000589, 17182 }, - { 0x100057e, 17027 }, - { 0x1000578, 16954 }, - { 0x1000582, 17079 }, - { 0x1000565, 16711 }, - { 0x100058a, 17216 }, - { 0x1000566, 16725 }, - { 0x100056a, 16772 }, - { 0x0000c3, 763 }, - { 0x00fe7a, 12919 }, - { 0x1008ff9b, 26825 }, - { 0x1008ff97, 26775 }, - { 0x1008ff11, 25700 }, - { 0x1008ff32, 26005 }, - { 0x1008ffb2, 26984 }, - { 0x1008ff12, 25717 }, - { 0x1008ff17, 25774 }, - { 0x1008ff31, 25994 }, - { 0x1008ff14, 25744 }, - { 0x1008ff16, 25764 }, - { 0x1008ff13, 25727 }, - { 0x1008ff99, 26800 }, - { 0x1008ff1c, 25811 }, - { 0x1008ff98, 26788 }, - { 0x1008ff3e, 26125 }, - { 0x1008ff15, 25754 }, - { 0x1008ff8d, 26699 }, - { 0x000042, 209 }, - { 0x1001e02, 18927 }, - { 0x1008ff26, 25914 }, - { 0x1008ff3f, 26137 }, - { 0x00ff08, 13669 }, - { 0x1008ff93, 26748 }, - { 0x00ff58, 14301 }, - { 0x1008ffa6, 26923 }, - { 0x1008ff94, 26756 }, - { 0x1008ff52, 26310 }, - { 0x00fe74, 12811 }, - { 0x00ff6b, 14367 }, - { 0x1008ff3b, 26090 }, - { 0x0006be, 4079 }, - { 0x0006ae, 3771 }, - { 0x000043, 211 }, - { 0x1008ff53, 26315 }, - { 0x00fea2, 13061 }, - { 0x00fea5, 13072 }, - { 0x00fea4, 13068 }, - { 0x0002c5, 1842 }, - { 0x0001c6, 1503 }, - { 0x1008ff1d, 25823 }, - { 0x1008ff20, 25848 }, - { 0x00ff69, 14355 }, - { 0x00ffe5, 15029 }, - { 0x0001c8, 1510 }, - { 0x0000c7, 790 }, - { 0x0002c6, 1852 }, - { 0x00fea1, 13058 }, - { 0x00ff0b, 13692 }, - { 0x1008fe21, 25543 }, - { 0x1008ff56, 26330 }, - { 0x00ff37, 13986 }, - { 0x10020a1, 20505 }, - { 0x1008ff3d, 26115 }, - { 0x1008ff22, 25867 }, - { 0x00ffe3, 15009 }, - { 0x00ffe4, 15019 }, - { 0x1008ff57, 26336 }, - { 0x10020a2, 20515 }, - { 0x1008ff58, 26341 }, - { 0x1008ff9c, 26841 }, - { 0x0006e1, 4542 }, - { 0x0006e2, 4553 }, - { 0x0006fe, 4904 }, - { 0x10004b6, 15768 }, - { 0x10004b8, 15814 }, - { 0x0006e4, 4578 }, - { 0x0006bf, 4099 }, - { 0x0006fc, 4878 }, - { 0x0006e6, 4602 }, - { 0x0006ec, 4678 }, - { 0x0006ed, 4690 }, - { 0x0006ee, 4702 }, - { 0x10004a2, 15592 }, - { 0x0006f2, 4749 }, - { 0x0006f3, 4761 }, - { 0x0006e7, 4614 }, - { 0x1000492, 15422 }, - { 0x0006e8, 4627 }, - { 0x0006ff, 4917 }, - { 0x10004b2, 15724 }, - { 0x0006e9, 4639 }, - { 0x0006e5, 4590 }, - { 0x0006b3, 3854 }, - { 0x10004e2, 15920 }, - { 0x0006b8, 3953 }, - { 0x0006eb, 4666 }, - { 0x100049a, 15502 }, - { 0x100049c, 15546 }, - { 0x0006b9, 3976 }, - { 0x0006ba, 4001 }, - { 0x0006ef, 4714 }, - { 0x10004e8, 15956 }, - { 0x0006f0, 4725 }, - { 0x10004d8, 15890 }, - { 0x0006fb, 4865 }, - { 0x0006fd, 4889 }, - { 0x10004ba, 15862 }, - { 0x0006ea, 4650 }, - { 0x0006f8, 4821 }, - { 0x0006f4, 4773 }, - { 0x0006e3, 4565 }, - { 0x0006f5, 4785 }, - { 0x10004ee, 15986 }, - { 0x10004ae, 15636 }, - { 0x10004b0, 15676 }, - { 0x0006f7, 4809 }, - { 0x0006f1, 4737 }, - { 0x0006f9, 4839 }, - { 0x0006e0, 4530 }, - { 0x0006fa, 4853 }, - { 0x0006f6, 4796 }, - { 0x1000496, 15456 }, - { 0x0006c1, 4137 }, - { 0x0006c2, 4148 }, - { 0x0006de, 4499 }, - { 0x10004b7, 15791 }, - { 0x10004b9, 15838 }, - { 0x0006c4, 4173 }, - { 0x0006af, 3791 }, - { 0x0006dc, 4473 }, - { 0x0006c6, 4197 }, - { 0x0006cc, 4273 }, - { 0x0006cd, 4285 }, - { 0x0006ce, 4297 }, - { 0x10004a3, 15614 }, - { 0x0006d2, 4344 }, - { 0x0006d3, 4356 }, - { 0x0006c7, 4209 }, - { 0x1000493, 15439 }, - { 0x0006c8, 4222 }, - { 0x10004b3, 15746 }, - { 0x0006df, 4512 }, - { 0x0006c9, 4234 }, - { 0x10004e3, 15938 }, - { 0x0006c5, 4185 }, - { 0x0006a3, 3546 }, - { 0x0006a8, 3645 }, - { 0x0006cb, 4261 }, - { 0x100049b, 15524 }, - { 0x100049d, 15569 }, - { 0x0006a9, 3668 }, - { 0x0006aa, 3693 }, - { 0x0006cf, 4309 }, - { 0x10004e9, 15971 }, - { 0x0006d0, 4320 }, - { 0x10004d9, 15905 }, - { 0x0006db, 4460 }, - { 0x0006dd, 4484 }, - { 0x10004bb, 15876 }, - { 0x0006ca, 4245 }, - { 0x0006d8, 4416 }, - { 0x0006d4, 4368 }, - { 0x0006c3, 4160 }, - { 0x0006d5, 4380 }, - { 0x10004ef, 16004 }, - { 0x10004af, 15656 }, - { 0x10004b1, 15700 }, - { 0x0006d7, 4404 }, - { 0x0006d1, 4332 }, - { 0x0006d9, 4434 }, - { 0x0006c0, 4125 }, - { 0x0006da, 4448 }, - { 0x0006d6, 4391 }, - { 0x1000497, 15479 }, - { 0x000044, 213 }, - { 0x1008ff5a, 26353 }, - { 0x1001e0a, 18947 }, - { 0x0001cf, 1532 }, - { 0x00ffff, 15249 }, - { 0x1008ff59, 26345 }, - { 0x1008ff5b, 26357 }, - { 0x10020ab, 20610 }, - { 0x00ff54, 14263 }, - { 0x0001d0, 1539 }, - { 0x000045, 215 }, - { 0x0003bd, 2076 }, - { 0x0000d0, 877 }, - { 0x10001b7, 15372 }, - { 0x0003cc, 2100 }, - { 0x0000c9, 806 }, - { 0x1001eb8, 19487 }, - { 0x0001cc, 1525 }, - { 0x0000ca, 813 }, - { 0x1001ebe, 19533 }, - { 0x1001ec6, 19667 }, - { 0x1001ec0, 19567 }, - { 0x1001ec2, 19601 }, - { 0x1001ec4, 19633 }, - { 0x10020a0, 20497 }, - { 0x0000cb, 825 }, - { 0x0000c8, 799 }, - { 0x1001eba, 19507 }, - { 0x00ff2f, 13893 }, - { 0x00ff30, 13904 }, - { 0x1008ff2c, 25956 }, - { 0x0003aa, 2003 }, - { 0x00ff57, 14297 }, - { 0x0001ca, 1517 }, - { 0x00ff1b, 13731 }, - { 0x0000d0, 873 }, - { 0x1001ebc, 19519 }, - { 0x0020ac, 11106 }, - { 0x1008ff5c, 26367 }, - { 0x00ff62, 14320 }, - { 0x1008ff5d, 26373 }, - { 0x000046, 217 }, - { 0x00ffbe, 14780 }, - { 0x00ffc7, 14807 }, - { 0x00ffc8, 14811 }, - { 0x00ffc9, 14818 }, - { 0x00ffca, 14825 }, - { 0x00ffcb, 14832 }, - { 0x00ffcc, 14839 }, - { 0x00ffcd, 14846 }, - { 0x00ffce, 14853 }, - { 0x00ffcf, 14860 }, - { 0x00ffd0, 14867 }, - { 0x00ffbf, 14783 }, - { 0x00ffd1, 14874 }, - { 0x00ffd2, 14882 }, - { 0x00ffd3, 14889 }, - { 0x00ffd4, 14896 }, - { 0x00ffd5, 14903 }, - { 0x00ffd6, 14910 }, - { 0x00ffd7, 14917 }, - { 0x00ffd8, 14924 }, - { 0x00ffd9, 14931 }, - { 0x00ffda, 14938 }, - { 0x00ffc0, 14786 }, - { 0x00ffdb, 14945 }, - { 0x00ffdc, 14953 }, - { 0x00ffdd, 14961 }, - { 0x00ffde, 14969 }, - { 0x00ffdf, 14977 }, - { 0x00ffe0, 14985 }, - { 0x00ffc1, 14789 }, - { 0x00ffc2, 14792 }, - { 0x00ffc3, 14795 }, - { 0x00ffc4, 14798 }, - { 0x00ffc5, 14801 }, - { 0x00ffc6, 14804 }, - { 0x10020a3, 20528 }, - { 0x1001e1e, 18967 }, - { 0x10006f0, 17644 }, - { 0x10006f1, 17652 }, - { 0x10006f2, 17660 }, - { 0x10006f3, 17668 }, - { 0x10006f4, 17676 }, - { 0x10006f5, 17684 }, - { 0x10006f6, 17692 }, - { 0x10006f7, 17700 }, - { 0x10006f8, 17708 }, - { 0x10006f9, 17716 }, - { 0x10006cc, 17601 }, - { 0x1008ff30, 25984 }, - { 0x1008ff3c, 26107 }, - { 0x00ff68, 14350 }, - { 0x00fed0, 13076 }, - { 0x1008ff27, 25919 }, - { 0x1008ff9d, 26852 }, - { 0x1008ff9e, 26862 }, - { 0x000047, 219 }, - { 0x0002d5, 1864 }, - { 0x1008ff5e, 26382 }, - { 0x0002ab, 1775 }, - { 0x10001e6, 15390 }, - { 0x0003ab, 2011 }, - { 0x0002d8, 1874 }, - { 0x10010d0, 18420 }, - { 0x10010d1, 18432 }, - { 0x10010ea, 18759 }, - { 0x10010ed, 18798 }, - { 0x10010e9, 18745 }, - { 0x10010ec, 18785 }, - { 0x10010d3, 18458 }, - { 0x10010d4, 18471 }, - { 0x10010f6, 18915 }, - { 0x10010d2, 18445 }, - { 0x10010e6, 18704 }, - { 0x10010f0, 18839 }, - { 0x10010f4, 18889 }, - { 0x10010f1, 18852 }, - { 0x10010f2, 18864 }, - { 0x10010f5, 18902 }, - { 0x10010d8, 18522 }, - { 0x10010ef, 18825 }, - { 0x10010eb, 18772 }, - { 0x10010d9, 18534 }, - { 0x10010e5, 18690 }, - { 0x10010da, 18547 }, - { 0x10010db, 18560 }, - { 0x10010dc, 18573 }, - { 0x10010dd, 18586 }, - { 0x10010de, 18598 }, - { 0x10010e4, 18676 }, - { 0x10010e7, 18718 }, - { 0x10010e0, 18625 }, - { 0x10010e1, 18638 }, - { 0x10010e8, 18731 }, - { 0x10010d7, 18509 }, - { 0x10010e2, 18651 }, - { 0x10010e3, 18664 }, - { 0x10010d5, 18483 }, - { 0x10010f3, 18877 }, - { 0x10010ee, 18812 }, - { 0x10010d6, 18496 }, - { 0x10010df, 18611 }, - { 0x1008ff5f, 26387 }, - { 0x0007c1, 5384 }, - { 0x0007a1, 4935 }, - { 0x0007c2, 5396 }, - { 0x0007d7, 5632 }, - { 0x0007c4, 5419 }, - { 0x0007c5, 5431 }, - { 0x0007a2, 4953 }, - { 0x0007c7, 5456 }, - { 0x0007a3, 4973 }, - { 0x0007c3, 5407 }, - { 0x0007c9, 5478 }, - { 0x0007a4, 4989 }, - { 0x0007a5, 5006 }, - { 0x0007a5, 5026 }, - { 0x0007ca, 5489 }, - { 0x0007cb, 5501 }, - { 0x0007cb, 5514 }, - { 0x0007cc, 5526 }, - { 0x0007cd, 5535 }, - { 0x0007d9, 5652 }, - { 0x0007ab, 5107 }, - { 0x0007cf, 5553 }, - { 0x0007a7, 5045 }, - { 0x0007d6, 5622 }, - { 0x0007d0, 5567 }, - { 0x0007d8, 5642 }, - { 0x0007d1, 5576 }, - { 0x0007d2, 5586 }, - { 0x0007d4, 5598 }, - { 0x0007c8, 5466 }, - { 0x0007d5, 5608 }, - { 0x0007a8, 5065 }, - { 0x0007a9, 5085 }, - { 0x0007ce, 5544 }, - { 0x0007c6, 5445 }, - { 0x0007ae, 5125 }, - { 0x0007e1, 5664 }, - { 0x0007b1, 5161 }, - { 0x0007e2, 5676 }, - { 0x0007f7, 5934 }, - { 0x0007e4, 5699 }, - { 0x0007e5, 5711 }, - { 0x0007b2, 5179 }, - { 0x0007e7, 5736 }, - { 0x0007b3, 5199 }, - { 0x0007f3, 5878 }, - { 0x0007e3, 5687 }, - { 0x0007af, 5146 }, - { 0x0007e9, 5758 }, - { 0x0007b4, 5215 }, - { 0x0007b6, 5251 }, - { 0x0007b5, 5232 }, - { 0x0007ea, 5769 }, - { 0x0007eb, 5781 }, - { 0x0007eb, 5794 }, - { 0x0007ec, 5806 }, - { 0x0007ed, 5815 }, - { 0x0007f9, 5954 }, - { 0x0007bb, 5366 }, - { 0x0007ef, 5833 }, - { 0x0007b7, 5276 }, - { 0x0007f6, 5924 }, - { 0x0007f0, 5847 }, - { 0x0007f8, 5944 }, - { 0x0007f1, 5856 }, - { 0x0007f2, 5866 }, - { 0x00ff7e, 14387 }, - { 0x0007f4, 5900 }, - { 0x0007e8, 5746 }, - { 0x0007f5, 5910 }, - { 0x0007b8, 5296 }, - { 0x0007ba, 5338 }, - { 0x0007b9, 5316 }, - { 0x0007ee, 5824 }, - { 0x0007e6, 5725 }, - { 0x1008ffa4, 26910 }, - { 0x000048, 221 }, - { 0x00ff31, 13916 }, - { 0x000ebf, 10145 }, - { 0x000ec0, 10154 }, - { 0x000ef6, 10986 }, - { 0x000ef7, 10999 }, - { 0x00ff39, 14040 }, - { 0x000eba, 10078 }, - { 0x00ff37, 13996 }, - { 0x000ea7, 9771 }, - { 0x000ec4, 10195 }, - { 0x000ec3, 10185 }, - { 0x000ed1, 10325 }, - { 0x00ff33, 13936 }, - { 0x00ff34, 13947 }, - { 0x000ebe, 10132 }, - { 0x000ed3, 10345 }, - { 0x000eb7, 10034 }, - { 0x000eea, 10750 }, - { 0x000eda, 10466 }, - { 0x000eee, 10812 }, - { 0x000ee8, 10720 }, - { 0x000ee9, 10735 }, - { 0x000eeb, 10765 }, - { 0x000ed4, 10354 }, - { 0x000ed6, 10391 }, - { 0x000ef9, 11030 }, - { 0x000ee3, 10638 }, - { 0x000ed7, 10411 }, - { 0x000ed9, 10446 }, - { 0x000ed8, 10426 }, - { 0x000ef8, 11013 }, - { 0x000eed, 10796 }, - { 0x000ee4, 10653 }, - { 0x000ee5, 10668 }, - { 0x000edb, 10482 }, - { 0x000ee2, 10618 }, - { 0x000edc, 10497 }, - { 0x000edd, 10518 }, - { 0x000ee1, 10597 }, - { 0x000ede, 10538 }, - { 0x000edf, 10558 }, - { 0x000ee0, 10577 }, - { 0x000ee6, 10687 }, - { 0x000ed5, 10370 }, - { 0x000ee7, 10701 }, - { 0x000eec, 10781 }, - { 0x000efa, 11057 }, - { 0x00ff35, 13960 }, - { 0x00ff38, 14026 }, - { 0x000eb8, 10047 }, - { 0x000ebb, 10091 }, - { 0x000ea1, 9671 }, - { 0x000ea3, 9704 }, - { 0x000ef3, 10916 }, - { 0x000eb1, 9944 }, - { 0x00ff3d, 14125 }, - { 0x000ea4, 9722 }, - { 0x000ea6, 9753 }, - { 0x000ea5, 9735 }, - { 0x000ec7, 10225 }, - { 0x000eca, 10255 }, - { 0x000ef2, 10901 }, - { 0x000ebd, 10118 }, - { 0x000eb2, 9957 }, - { 0x000eb4, 9988 }, - { 0x00ff3b, 14069 }, - { 0x00ff3a, 14053 }, - { 0x00ff3e, 14177 }, - { 0x000ea9, 9804 }, - { 0x000eb0, 9926 }, - { 0x000eaa, 9817 }, - { 0x000eab, 9836 }, - { 0x000eaf, 9907 }, - { 0x000eac, 9854 }, - { 0x000ead, 9872 }, - { 0x000eae, 9889 }, - { 0x000eef, 10827 }, - { 0x00ff36, 13972 }, - { 0x00ff3c, 14086 }, - { 0x000eb5, 10005 }, - { 0x00ff3f, 14229 }, - { 0x000ea8, 9785 }, - { 0x000eb9, 10060 }, - { 0x000ea2, 9685 }, - { 0x000eb3, 9970 }, - { 0x000eb6, 10017 }, - { 0x00ff32, 13923 }, - { 0x000ef0, 10851 }, - { 0x000ef4, 10941 }, - { 0x000ef1, 10876 }, - { 0x000ebc, 10105 }, - { 0x000ecc, 10275 }, - { 0x000ec8, 10234 }, - { 0x000ec9, 10244 }, - { 0x000ece, 10295 }, - { 0x000ecd, 10284 }, - { 0x000ecf, 10305 }, - { 0x000ec1, 10164 }, - { 0x000ec2, 10174 }, - { 0x000ec6, 10215 }, - { 0x000ec5, 10204 }, - { 0x000ed2, 10335 }, - { 0x000ecb, 10265 }, - { 0x000ed0, 10315 }, - { 0x000ef5, 10967 }, - { 0x00ff7e, 14400 }, - { 0x00ff29, 13833 }, - { 0x0002a6, 1753 }, - { 0x00ff7e, 14414 }, - { 0x00ff6a, 14362 }, - { 0x00ff23, 13763 }, - { 0x00ff23, 13770 }, - { 0x1008ffa8, 26936 }, - { 0x00ff25, 13789 }, - { 0x00ff27, 13807 }, - { 0x1008ff37, 26053 }, - { 0x00ff50, 14244 }, - { 0x1008ff18, 25784 }, - { 0x1008ff3a, 26081 }, - { 0x0002a1, 1745 }, - { 0x00ffed, 15092 }, - { 0x00ffee, 15100 }, - { 0x000049, 223 }, - { 0x00fe33, 12195 }, - { 0x00fe30, 12128 }, - { 0x00fe31, 12153 }, - { 0x00fe32, 12181 }, - { 0x00fe34, 12213 }, - { 0x00fe2f, 12107 }, - { 0x00fe2c, 12045 }, - { 0x00fe2d, 12066 }, - { 0x00fe2e, 12088 }, - { 0x00fe0c, 11670 }, - { 0x00fe0d, 11686 }, - { 0x00fe06, 11569 }, - { 0x00fe07, 11585 }, - { 0x00ff7e, 14428 }, - { 0x00fe0e, 11707 }, - { 0x00fe0f, 11722 }, - { 0x00fe20, 11792 }, - { 0x00fe02, 11502 }, - { 0x00fe04, 11536 }, - { 0x00fe05, 11553 }, - { 0x00fe03, 11519 }, - { 0x00fe12, 11759 }, - { 0x00fe13, 11776 }, - { 0x00fe11, 11742 }, - { 0x00fe01, 11493 }, - { 0x00fe22, 11822 }, - { 0x00fe21, 11805 }, - { 0x00fe08, 11600 }, - { 0x00fe09, 11615 }, - { 0x00fe24, 11861 }, - { 0x00fe23, 11841 }, - { 0x00fe25, 11883 }, - { 0x00fe26, 11906 }, - { 0x00fe0a, 11635 }, - { 0x00fe0b, 11650 }, - { 0x00fe2b, 12020 }, - { 0x00fe29, 11971 }, - { 0x00fe2a, 11995 }, - { 0x00fe27, 11930 }, - { 0x00fe28, 11950 }, - { 0x0002a9, 1765 }, - { 0x0000cd, 843 }, - { 0x1001eca, 19719 }, - { 0x100012c, 15256 }, - { 0x0000ce, 850 }, - { 0x0000cf, 862 }, - { 0x0000cc, 836 }, - { 0x1001ec8, 19707 }, - { 0x0003cf, 2110 }, - { 0x00ff63, 14328 }, - { 0x0003c7, 2092 }, - { 0x0003a5, 1987 }, - { 0x00004a, 225 }, - { 0x0002ac, 1782 }, - { 0x00004b, 227 }, - { 0x00ffb0, 14721 }, - { 0x00ffb1, 14726 }, - { 0x00ffb2, 14731 }, - { 0x00ffb3, 14736 }, - { 0x00ffb4, 14741 }, - { 0x00ffb5, 14746 }, - { 0x00ffb6, 14751 }, - { 0x00ffb7, 14756 }, - { 0x00ffb8, 14761 }, - { 0x00ffb9, 14766 }, - { 0x00ffab, 14668 }, - { 0x00ff9d, 14627 }, - { 0x00ffae, 14700 }, - { 0x00ff9f, 14646 }, - { 0x00ffaf, 14711 }, - { 0x00ff99, 14571 }, - { 0x00ff9c, 14620 }, - { 0x00ff8d, 14507 }, - { 0x00ffbd, 14771 }, - { 0x00ff91, 14516 }, - { 0x00ff92, 14522 }, - { 0x00ff93, 14528 }, - { 0x00ff94, 14534 }, - { 0x00ff95, 14540 }, - { 0x00ff9e, 14636 }, - { 0x00ff96, 14548 }, - { 0x00ffaa, 14656 }, - { 0x00ff9b, 14599 }, - { 0x00ff9b, 14607 }, - { 0x00ff9a, 14579 }, - { 0x00ff9a, 14590 }, - { 0x00ff98, 14562 }, - { 0x00ffac, 14675 }, - { 0x00ff80, 14491 }, - { 0x00ffad, 14688 }, - { 0x00ff89, 14500 }, - { 0x00ff97, 14556 }, - { 0x00ff2d, 13872 }, - { 0x00ff2e, 13882 }, - { 0x00ff21, 13748 }, - { 0x00ff37, 14013 }, - { 0x00ff26, 13798 }, - { 0x1008ff06, 25674 }, - { 0x1008ff05, 25658 }, - { 0x1008ff04, 25644 }, - { 0x0003d3, 2135 }, - { 0x000eff, 11078 }, - { 0x00004c, 229 }, - { 0x00ffc8, 14815 }, - { 0x00ffd1, 14878 }, - { 0x00ffc9, 14822 }, - { 0x00ffca, 14829 }, - { 0x00ffcb, 14836 }, - { 0x00ffcc, 14843 }, - { 0x00ffcd, 14850 }, - { 0x00ffce, 14857 }, - { 0x00ffcf, 14864 }, - { 0x00ffd0, 14871 }, - { 0x0001c5, 1496 }, - { 0x00fed4, 13137 }, - { 0x1008ff40, 26149 }, - { 0x1008ff41, 26157 }, - { 0x1008ff42, 26165 }, - { 0x1008ff43, 26173 }, - { 0x1008ff44, 26181 }, - { 0x1008ff45, 26189 }, - { 0x1008ff46, 26197 }, - { 0x1008ff47, 26205 }, - { 0x1008ff48, 26213 }, - { 0x1008ff49, 26221 }, - { 0x1008ff4a, 26229 }, - { 0x1008ff4b, 26237 }, - { 0x1008ff4c, 26245 }, - { 0x1008ff4d, 26253 }, - { 0x1008ff4e, 26261 }, - { 0x1008ff4f, 26269 }, - { 0x1001e36, 18987 }, - { 0x0001a5, 1319 }, - { 0x0003a6, 1994 }, - { 0x00ff51, 14249 }, - { 0x1008ff35, 26038 }, - { 0x00ff0a, 13683 }, - { 0x10020a4, 20539 }, - { 0x1008fe25, 25589 }, - { 0x1008ff61, 26397 }, - { 0x1008fe24, 25575 }, - { 0x0001a3, 1311 }, - { 0x00004d, 231 }, - { 0x1001e40, 19007 }, - { 0x0006b5, 3891 }, - { 0x0006b2, 3840 }, - { 0x0006bc, 4039 }, - { 0x0006a5, 3583 }, - { 0x0006a2, 3532 }, - { 0x0006ac, 3731 }, - { 0x00ff3e, 14202 }, - { 0x1008ff19, 25793 }, - { 0x1008ff90, 26721 }, - { 0x1008ff62, 26404 }, - { 0x00ff2c, 13865 }, - { 0x1008ff63, 26411 }, - { 0x1008ff1e, 25834 }, - { 0x00ff67, 14345 }, - { 0x1008ff65, 26419 }, - { 0x1008ff66, 26426 }, - { 0x1008ff8e, 26704 }, - { 0x00ffe7, 15050 }, - { 0x00ffe8, 15057 }, - { 0x10020a5, 20548 }, - { 0x1008ff01, 25601 }, - { 0x00ff7e, 14456 }, - { 0x1008ff03, 25626 }, - { 0x1008ff02, 25610 }, - { 0x00fe77, 12864 }, - { 0x00fe76, 12847 }, - { 0x00ff22, 13754 }, - { 0x00ff20, 13738 }, - { 0x00ff3d, 14150 }, - { 0x1008ff92, 26742 }, - { 0x1008ff33, 26016 }, - { 0x1008ff67, 26433 }, - { 0x00004e, 233 }, - { 0x0001d1, 1547 }, - { 0x10020a6, 20557 }, - { 0x0001d2, 1554 }, - { 0x0003d1, 2118 }, - { 0x1008ff68, 26441 }, - { 0x10020aa, 20596 }, - { 0x1008ff69, 26445 }, - { 0x00ff56, 14292 }, - { 0x1008fe22, 25553 }, - { 0x00fed2, 13117 }, - { 0x0000d1, 881 }, - { 0x00ff7f, 14482 }, - { 0x00004f, 235 }, - { 0x0013bc, 11089 }, - { 0x0000d3, 895 }, - { 0x100019f, 15324 }, - { 0x1001ecc, 19739 }, - { 0x10001d1, 15376 }, - { 0x0000d4, 902 }, - { 0x1001ed0, 19771 }, - { 0x1001ed8, 19905 }, - { 0x1001ed2, 19805 }, - { 0x1001ed4, 19839 }, - { 0x1001ed6, 19871 }, - { 0x0000d6, 921 }, - { 0x0001d5, 1561 }, - { 0x1008ff6a, 26450 }, - { 0x0000d2, 888 }, - { 0x1001ece, 19759 }, - { 0x10001a0, 15332 }, - { 0x1001eda, 19945 }, - { 0x1001ee2, 20031 }, - { 0x1001edc, 19967 }, - { 0x1001ede, 19989 }, - { 0x1001ee0, 20009 }, - { 0x0003d2, 2127 }, - { 0x0000d8, 941 }, - { 0x1008ff6b, 26461 }, - { 0x1008ff38, 26061 }, - { 0x1008ff6c, 26466 }, - { 0x0000d8, 950 }, - { 0x0000d5, 914 }, - { 0x00fe78, 12887 }, - { 0x00fe79, 12903 }, - { 0x000050, 237 }, - { 0x1001e56, 19027 }, - { 0x00ff56, 14282 }, - { 0x00ff55, 14268 }, - { 0x1008ff6d, 26473 }, - { 0x00ff13, 13705 }, - { 0x10020a7, 20567 }, - { 0x1008ff6e, 26479 }, - { 0x1008ff91, 26733 }, - { 0x00fefa, 13596 }, - { 0x00fee9, 13311 }, - { 0x00feea, 13327 }, - { 0x00feeb, 13343 }, - { 0x00feec, 13359 }, - { 0x00feed, 13375 }, - { 0x00fee8, 13291 }, - { 0x00feef, 13413 }, - { 0x00fef0, 13431 }, - { 0x00fef1, 13449 }, - { 0x00fef2, 13467 }, - { 0x00fef3, 13485 }, - { 0x00feee, 13391 }, - { 0x00fefb, 13615 }, - { 0x00fefc, 13635 }, - { 0x00fee3, 13212 }, - { 0x00fee6, 13256 }, - { 0x00fee7, 13273 }, - { 0x00fef5, 13521 }, - { 0x00fef6, 13535 }, - { 0x00fef7, 13549 }, - { 0x00fef8, 13563 }, - { 0x00fefd, 13655 }, - { 0x00fef4, 13503 }, - { 0x00fef9, 13577 }, - { 0x00fee0, 13174 }, - { 0x00fee1, 13187 }, - { 0x00fee2, 13201 }, - { 0x00fee4, 13225 }, - { 0x00fee5, 13240 }, - { 0x1008ff21, 25857 }, - { 0x1008ff2a, 25940 }, - { 0x1008fe23, 25564 }, - { 0x00fed1, 13097 }, - { 0x00ff3e, 14211 }, - { 0x00ff61, 14314 }, - { 0x00ff55, 14276 }, - { 0x000051, 239 }, - { 0x000052, 241 }, - { 0x00ffd2, 14886 }, - { 0x00ffdb, 14949 }, - { 0x00ffdc, 14957 }, - { 0x00ffdd, 14965 }, - { 0x00ffde, 14973 }, - { 0x00ffdf, 14981 }, - { 0x00ffe0, 14989 }, - { 0x00ffd3, 14893 }, - { 0x00ffd4, 14900 }, - { 0x00ffd5, 14907 }, - { 0x00ffd6, 14914 }, - { 0x00ffd7, 14921 }, - { 0x00ffd8, 14928 }, - { 0x00ffd9, 14935 }, - { 0x00ffda, 14942 }, - { 0x0001c0, 1482 }, - { 0x0001d8, 1574 }, - { 0x0003a3, 1978 }, - { 0x1008ffa3, 26906 }, - { 0x00ff66, 14340 }, - { 0x1008ff29, 25932 }, - { 0x1008ff73, 26491 }, - { 0x00fe72, 12777 }, - { 0x1008ff72, 26485 }, - { 0x00ff0d, 13698 }, - { 0x00ff53, 14257 }, - { 0x1008ff24, 25891 }, - { 0x1008ff25, 25902 }, - { 0x1008ff23, 25882 }, - { 0x00ff24, 13782 }, - { 0x1008ff74, 26498 }, - { 0x1008ff76, 26523 }, - { 0x1008ff75, 26512 }, - { 0x10020a8, 20578 }, - { 0x000053, 243 }, - { 0x100018f, 15318 }, - { 0x1001e60, 19047 }, - { 0x0001a6, 1326 }, - { 0x1008ff77, 26534 }, - { 0x0001a9, 1333 }, - { 0x0001aa, 1340 }, - { 0x0002de, 1893 }, - { 0x1008ff2d, 25962 }, - { 0x1008ff7a, 26559 }, - { 0x1008ff79, 26548 }, - { 0x1008ff78, 26539 }, - { 0x00ff14, 13711 }, - { 0x1008ff1b, 25804 }, - { 0x00ff60, 14307 }, - { 0x1008ffa0, 26880 }, - { 0x1008ff7b, 26571 }, - { 0x0006b1, 3828 }, - { 0x0006bf, 4113 }, - { 0x0006b8, 3965 }, - { 0x0006b9, 3989 }, - { 0x0006ba, 4014 }, - { 0x0006bb, 4026 }, - { 0x0006a1, 3520 }, - { 0x0006af, 3805 }, - { 0x0006a8, 3657 }, - { 0x0006a9, 3681 }, - { 0x0006aa, 3706 }, - { 0x0006ab, 3718 }, - { 0x00ffe1, 14993 }, - { 0x00ffe6, 15039 }, - { 0x00ffe2, 15001 }, - { 0x1008ff36, 26048 }, - { 0x00ff3c, 14109 }, - { 0x1000d85, 17740 }, - { 0x1000d86, 17747 }, - { 0x1000dcf, 18252 }, - { 0x1000d87, 17755 }, - { 0x1000dd0, 18261 }, - { 0x1000d88, 17763 }, - { 0x1000dd1, 18270 }, - { 0x1000d93, 17851 }, - { 0x1000ddb, 18340 }, - { 0x1000dca, 18244 }, - { 0x1000d96, 17874 }, - { 0x1000dde, 18366 }, - { 0x1000db6, 18126 }, - { 0x1000db7, 18134 }, - { 0x1000da0, 17934 }, - { 0x1000da1, 17942 }, - { 0x1000da9, 18015 }, - { 0x1000daa, 18024 }, - { 0x1000daf, 18072 }, - { 0x1000db0, 18081 }, - { 0x1000d91, 17836 }, - { 0x1000dd9, 18323 }, - { 0x1000d92, 17843 }, - { 0x1000dda, 18331 }, - { 0x1000dc6, 18236 }, - { 0x1000d9c, 17899 }, - { 0x1000d9d, 17907 }, - { 0x1000d83, 17732 }, - { 0x1000dc4, 18219 }, - { 0x1000d89, 17772 }, - { 0x1000dd2, 18280 }, - { 0x1000d8a, 17779 }, - { 0x1000dd3, 18288 }, - { 0x1000da2, 17951 }, - { 0x1000da3, 17959 }, - { 0x1000da5, 17977 }, - { 0x1000d9a, 17882 }, - { 0x1000d9b, 17890 }, - { 0x1000df4, 18404 }, - { 0x1000dbd, 18176 }, - { 0x1000dc5, 18227 }, - { 0x1000d8f, 17819 }, - { 0x1000ddf, 18375 }, - { 0x1000d90, 17827 }, - { 0x1000df3, 18394 }, - { 0x1000db8, 18143 }, - { 0x1000db9, 18151 }, - { 0x1000db1, 18091 }, - { 0x1000dac, 18043 }, - { 0x1000db3, 18099 }, - { 0x1000d82, 17724 }, - { 0x1000d9e, 17916 }, - { 0x1000d9f, 17925 }, - { 0x1000da6, 17987 }, - { 0x1000dab, 18034 }, - { 0x1000da4, 17968 }, - { 0x1000d94, 17859 }, - { 0x1000ddc, 18349 }, - { 0x1000d95, 17866 }, - { 0x1000ddd, 18357 }, - { 0x1000db4, 18109 }, - { 0x1000db5, 18117 }, - { 0x1000dbb, 18168 }, - { 0x1000d8d, 17802 }, - { 0x1000d8e, 17810 }, - { 0x1000dd8, 18314 }, - { 0x1000df2, 18384 }, - { 0x1000dc3, 18211 }, - { 0x1000dc1, 18192 }, - { 0x1000dc2, 18201 }, - { 0x1000dad, 18053 }, - { 0x1000dae, 18062 }, - { 0x1000da7, 17996 }, - { 0x1000da8, 18005 }, - { 0x1000d8b, 17787 }, - { 0x1000dd4, 18297 }, - { 0x1000d8c, 17794 }, - { 0x1000dd6, 18305 }, - { 0x1000dc0, 18184 }, - { 0x1000dba, 18160 }, - { 0x1008ff2f, 25978 }, - { 0x00fe73, 12795 }, - { 0x1008ff7c, 26576 }, - { 0x1008ff7d, 26582 }, - { 0x1008ff10, 25692 }, - { 0x1008ff1a, 25798 }, - { 0x00fe75, 12829 }, - { 0x1008ff28, 25927 }, - { 0x1008ff9a, 26816 }, - { 0x00ffeb, 15076 }, - { 0x00ffec, 15084 }, - { 0x1008ff7e, 26594 }, - { 0x1008ffa7, 26928 }, - { 0x1008fe01, 25389 }, - { 0x1008fe0a, 25497 }, - { 0x1008fe0b, 25510 }, - { 0x1008fe0c, 25523 }, - { 0x1008fe02, 25401 }, - { 0x1008fe03, 25413 }, - { 0x1008fe04, 25425 }, - { 0x1008fe05, 25437 }, - { 0x1008fe06, 25449 }, - { 0x1008fe07, 25461 }, - { 0x1008fe08, 25473 }, - { 0x1008fe09, 25485 }, - { 0x00ff15, 13723 }, - { 0x000054, 245 }, - { 0x0000de, 1007 }, - { 0x00ff09, 13679 }, - { 0x1001e6a, 19067 }, - { 0x1008ff7f, 26602 }, - { 0x0001ab, 1349 }, - { 0x0001de, 1600 }, - { 0x1008ff80, 26611 }, - { 0x00fed5, 13157 }, - { 0x000ddf, 9337 }, - { 0x000dba, 8920 }, - { 0x000da8, 8684 }, - { 0x000daa, 8711 }, - { 0x000da9, 8697 }, - { 0x000dac, 8735 }, - { 0x000dae, 8760 }, - { 0x000db4, 8845 }, - { 0x000dbd, 8959 }, - { 0x000dbf, 8982 }, - { 0x000dcb, 9116 }, - { 0x000dce, 9150 }, - { 0x000da2, 8602 }, - { 0x000da5, 8643 }, - { 0x000da3, 8615 }, - { 0x000da4, 8629 }, - { 0x000da6, 8656 }, - { 0x000da1, 8591 }, - { 0x000de5, 9420 }, - { 0x000df7, 9633 }, - { 0x000df5, 9610 }, - { 0x000df6, 9621 }, - { 0x000df9, 9659 }, - { 0x000df1, 9561 }, - { 0x000df8, 9646 }, - { 0x000df3, 9587 }, - { 0x000df4, 9599 }, - { 0x000df2, 9574 }, - { 0x000df0, 9549 }, - { 0x000dcc, 9127 }, - { 0x000dc5, 9049 }, - { 0x000dc6, 9061 }, - { 0x000deb, 9501 }, - { 0x000de8, 9466 }, - { 0x000dd1, 9190 }, - { 0x000dde, 9314 }, - { 0x000de7, 9451 }, - { 0x000de9, 9477 }, - { 0x000dea, 9489 }, - { 0x000de6, 9437 }, - { 0x000dc1, 9009 }, - { 0x000da7, 8672 }, - { 0x000ded, 9535 }, - { 0x000db3, 8834 }, - { 0x000db9, 8910 }, - { 0x000dcd, 9140 }, - { 0x000dcf, 9164 }, - { 0x000dda, 9301 }, - { 0x000dbe, 8969 }, - { 0x000dbc, 8945 }, - { 0x000dc0, 8993 }, - { 0x000dbb, 8934 }, - { 0x000dc3, 9030 }, - { 0x000dc4, 9041 }, - { 0x000dd0, 9179 }, - { 0x000dd2, 9206 }, - { 0x000de1, 9358 }, - { 0x000de4, 9400 }, - { 0x000de3, 9381 }, - { 0x000dd3, 9218 }, - { 0x000de0, 9347 }, - { 0x000dd4, 9230 }, - { 0x000dd5, 9241 }, - { 0x000de2, 9370 }, - { 0x000dd8, 9278 }, - { 0x000dd6, 9253 }, - { 0x000dd7, 9265 }, - { 0x000dd9, 9289 }, - { 0x000dc9, 9093 }, - { 0x000dc8, 9081 }, - { 0x000dab, 8725 }, - { 0x000dca, 9105 }, - { 0x000dec, 9518 }, - { 0x000db1, 8799 }, - { 0x000db2, 8818 }, - { 0x000db7, 8881 }, - { 0x000db0, 8786 }, - { 0x000db8, 8896 }, - { 0x000db6, 8867 }, - { 0x000daf, 8773 }, - { 0x000db5, 8856 }, - { 0x000dc7, 9069 }, - { 0x000dc2, 9019 }, - { 0x000dad, 8748 }, - { 0x0000de, 1001 }, - { 0x1008ff9f, 26875 }, - { 0x1008ff1f, 25839 }, - { 0x1008ff81, 26620 }, - { 0x1008ffa2, 26898 }, - { 0x1008ffb1, 26972 }, - { 0x1008ffb0, 26961 }, - { 0x1008ffa9, 26946 }, - { 0x00ff2b, 13857 }, - { 0x1008ff82, 26626 }, - { 0x0003ac, 2020 }, - { 0x000055, 247 }, - { 0x1008ff96, 26771 }, - { 0x0000da, 964 }, - { 0x1001ee4, 20059 }, - { 0x0002dd, 1886 }, - { 0x0000db, 971 }, - { 0x0000dc, 983 }, - { 0x0001db, 1587 }, - { 0x0000d9, 957 }, - { 0x1001ee6, 20079 }, - { 0x10001af, 15344 }, - { 0x1001ee8, 20091 }, - { 0x1001ef0, 20177 }, - { 0x1001eea, 20113 }, - { 0x1001eec, 20135 }, - { 0x1001eee, 20155 }, - { 0x0006bd, 4053 }, - { 0x0006b6, 3905 }, - { 0x0006b4, 3866 }, - { 0x0006b7, 3928 }, - { 0x0006ad, 3745 }, - { 0x0006a6, 3597 }, - { 0x0006a4, 3558 }, - { 0x0006a7, 3620 }, - { 0x0006b6, 3917 }, - { 0x0006b4, 3879 }, - { 0x0006b7, 3941 }, - { 0x0006a6, 3609 }, - { 0x0006a4, 3571 }, - { 0x0006a7, 3633 }, - { 0x0003de, 2159 }, - { 0x00ff65, 14335 }, - { 0x1008fe20, 25536 }, - { 0x0003d9, 2144 }, - { 0x00ff52, 14254 }, - { 0x0001d9, 1581 }, - { 0x1008ff85, 26640 }, - { 0x1008ff86, 26648 }, - { 0x1008ff84, 26633 }, - { 0x0003dd, 2152 }, - { 0x000056, 249 }, - { 0x1008ff34, 26027 }, - { 0x1008ff87, 26656 }, - { 0x1008ffa1, 26893 }, - { 0xffffff, 26997 }, - { 0x000057, 251 }, - { 0x1008ff95, 26766 }, - { 0x1008ff2e, 25974 }, - { 0x1001e82, 19101 }, - { 0x1008ff2b, 25949 }, - { 0x1000174, 15270 }, - { 0x1001e84, 19115 }, - { 0x1008ff8f, 26714 }, - { 0x1001e80, 19087 }, - { 0x1008ff88, 26662 }, - { 0x1008ff55, 26318 }, - { 0x10020a9, 20588 }, - { 0x1008ff89, 26674 }, - { 0x000058, 253 }, - { 0x1001e8a, 19137 }, - { 0x1008ff8a, 26679 }, - { 0x000059, 255 }, - { 0x0000dd, 994 }, - { 0x1001ef4, 20219 }, - { 0x1000176, 15294 }, - { 0x0013be, 11095 }, - { 0x1008ffa5, 26916 }, - { 0x1001ef2, 20205 }, - { 0x1001ef6, 20239 }, - { 0x1001ef8, 20251 }, - { 0x00005a, 257 }, - { 0x0001af, 1370 }, - { 0x0001ac, 1356 }, - { 0x0001ae, 1363 }, - { 0x00ff3d, 14168 }, - { 0x00ff28, 13825 }, - { 0x00ff2a, 13841 }, - { 0x1008ff8b, 26684 }, - { 0x1008ff8c, 26691 }, - { 0x10001b5, 15356 }, - { 0x000061, 333 }, - { 0x0000e1, 1027 }, - { 0x1001ea1, 19167 }, - { 0x0001ff, 1736 }, - { 0x0001e3, 1616 }, - { 0x1001eaf, 19375 }, - { 0x1001eb7, 19472 }, - { 0x1001eb1, 19399 }, - { 0x1001eb3, 19422 }, - { 0x1001eb5, 19445 }, - { 0x0000e2, 1034 }, - { 0x1001ea5, 19206 }, - { 0x1001ead, 19343 }, - { 0x1001ea7, 19240 }, - { 0x1001ea9, 19273 }, - { 0x1001eab, 19306 }, - { 0x0000b4, 612 }, - { 0x0000e4, 1053 }, - { 0x0000e6, 1070 }, - { 0x0000e0, 1020 }, - { 0x1001ea3, 19183 }, - { 0x0003e0, 2167 }, - { 0x000026, 48 }, - { 0x0001b1, 1380 }, - { 0x000027, 58 }, - { 0x1002248, 20750 }, - { 0x0008c8, 6444 }, - { 0x0000e5, 1064 }, - { 0x00005e, 294 }, - { 0x00007e, 410 }, - { 0x00002a, 101 }, - { 0x000040, 204 }, - { 0x0000e3, 1046 }, - { 0x000062, 335 }, - { 0x1001e03, 18937 }, - { 0x00005c, 271 }, - { 0x000af4, 7769 }, - { 0x00007c, 395 }, - { 0x1002235, 20730 }, - { 0x0009df, 6630 }, - { 0x0008a5, 6020 }, - { 0x0008ac, 6130 }, - { 0x0008a8, 6063 }, - { 0x0008b2, 6234 }, - { 0x0008ae, 6159 }, - { 0x0008aa, 6098 }, - { 0x0008b6, 6321 }, - { 0x0009f6, 6838 }, - { 0x0008b4, 6277 }, - { 0x00007b, 385 }, - { 0x00007d, 399 }, - { 0x00005b, 259 }, - { 0x00005d, 281 }, - { 0x1002800, 20781 }, - { 0x00fff1, 15108 }, - { 0x00fffa, 15234 }, - { 0x00fff2, 15122 }, - { 0x00fff3, 15136 }, - { 0x00fff4, 15150 }, - { 0x00fff5, 15164 }, - { 0x00fff6, 15178 }, - { 0x00fff7, 15192 }, - { 0x00fff8, 15206 }, - { 0x00fff9, 15220 }, - { 0x1002801, 20795 }, - { 0x1002803, 20825 }, - { 0x1002807, 20888 }, - { 0x100280f, 21019 }, - { 0x100281f, 21290 }, - { 0x100283f, 21849 }, - { 0x100287f, 23000 }, - { 0x10028ff, 25367 }, - { 0x10028bf, 24152 }, - { 0x100285f, 22409 }, - { 0x10028df, 24744 }, - { 0x100289f, 23561 }, - { 0x100282f, 21562 }, - { 0x100286f, 22697 }, - { 0x10028ef, 25048 }, - { 0x10028af, 23849 }, - { 0x100284f, 22122 }, - { 0x10028cf, 24441 }, - { 0x100288f, 23274 }, - { 0x1002817, 21151 }, - { 0x1002837, 21702 }, - { 0x1002877, 22845 }, - { 0x10028f7, 25204 }, - { 0x10028b7, 23997 }, - { 0x1002857, 22262 }, - { 0x10028d7, 24589 }, - { 0x1002897, 23414 }, - { 0x1002827, 21423 }, - { 0x1002867, 22550 }, - { 0x10028e7, 24893 }, - { 0x10028a7, 23702 }, - { 0x1002847, 21983 }, - { 0x10028c7, 24294 }, - { 0x1002887, 23135 }, - { 0x100280b, 20952 }, - { 0x100281b, 21219 }, - { 0x100283b, 21774 }, - { 0x100287b, 22921 }, - { 0x10028fb, 25284 }, - { 0x10028bb, 24073 }, - { 0x100285b, 22334 }, - { 0x10028db, 24665 }, - { 0x100289b, 23486 }, - { 0x100282b, 21491 }, - { 0x100286b, 22622 }, - { 0x10028eb, 24969 }, - { 0x10028ab, 23774 }, - { 0x100284b, 22051 }, - { 0x10028cb, 24366 }, - { 0x100288b, 23203 }, - { 0x1002813, 21084 }, - { 0x1002833, 21631 }, - { 0x1002873, 22770 }, - { 0x10028f3, 25125 }, - { 0x10028b3, 23922 }, - { 0x1002853, 22191 }, - { 0x10028d3, 24514 }, - { 0x1002893, 23343 }, - { 0x1002823, 21356 }, - { 0x1002863, 22479 }, - { 0x10028e3, 24818 }, - { 0x10028a3, 23631 }, - { 0x1002843, 21916 }, - { 0x10028c3, 24223 }, - { 0x1002883, 23068 }, - { 0x1002805, 20856 }, - { 0x100280d, 20985 }, - { 0x100281d, 21254 }, - { 0x100283d, 21811 }, - { 0x100287d, 22960 }, - { 0x10028fd, 25325 }, - { 0x10028bd, 24112 }, - { 0x100285d, 22371 }, - { 0x10028dd, 24704 }, - { 0x100289d, 23523 }, - { 0x100282d, 21526 }, - { 0x100286d, 22659 }, - { 0x10028ed, 25008 }, - { 0x10028ad, 23811 }, - { 0x100284d, 22086 }, - { 0x10028cd, 24403 }, - { 0x100288d, 23238 }, - { 0x1002815, 21117 }, - { 0x1002835, 21666 }, - { 0x1002875, 22807 }, - { 0x10028f5, 25164 }, - { 0x10028b5, 23959 }, - { 0x1002855, 22226 }, - { 0x10028d5, 24551 }, - { 0x1002895, 23378 }, - { 0x1002825, 21389 }, - { 0x1002865, 22514 }, - { 0x10028e5, 24855 }, - { 0x10028a5, 23666 }, - { 0x1002845, 21949 }, - { 0x10028c5, 24258 }, - { 0x1002885, 23101 }, - { 0x1002809, 20920 }, - { 0x1002819, 21185 }, - { 0x1002839, 21738 }, - { 0x1002879, 22883 }, - { 0x10028f9, 25244 }, - { 0x10028b9, 24035 }, - { 0x1002859, 22298 }, - { 0x10028d9, 24627 }, - { 0x1002899, 23450 }, - { 0x1002829, 21457 }, - { 0x1002869, 22586 }, - { 0x10028e9, 24931 }, - { 0x10028a9, 23738 }, - { 0x1002849, 22017 }, - { 0x10028c9, 24330 }, - { 0x1002889, 23169 }, - { 0x1002811, 21052 }, - { 0x1002831, 21597 }, - { 0x1002871, 22734 }, - { 0x10028f1, 25087 }, - { 0x10028b1, 23886 }, - { 0x1002851, 22157 }, - { 0x10028d1, 24478 }, - { 0x1002891, 23309 }, - { 0x1002821, 21324 }, - { 0x1002861, 22445 }, - { 0x10028e1, 24782 }, - { 0x10028a1, 23597 }, - { 0x1002841, 21884 }, - { 0x10028c1, 24189 }, - { 0x1002881, 23036 }, - { 0x1002802, 20810 }, - { 0x1002806, 20872 }, - { 0x100280e, 21002 }, - { 0x100281e, 21272 }, - { 0x100283e, 21830 }, - { 0x100287e, 22980 }, - { 0x10028fe, 25346 }, - { 0x10028be, 24132 }, - { 0x100285e, 22390 }, - { 0x10028de, 24724 }, - { 0x100289e, 23542 }, - { 0x100282e, 21544 }, - { 0x100286e, 22678 }, - { 0x10028ee, 25028 }, - { 0x10028ae, 23830 }, - { 0x100284e, 22104 }, - { 0x10028ce, 24422 }, - { 0x100288e, 23256 }, - { 0x1002816, 21134 }, - { 0x1002836, 21684 }, - { 0x1002876, 22826 }, - { 0x10028f6, 25184 }, - { 0x10028b6, 23978 }, - { 0x1002856, 22244 }, - { 0x10028d6, 24570 }, - { 0x1002896, 23396 }, - { 0x1002826, 21406 }, - { 0x1002866, 22532 }, - { 0x10028e6, 24874 }, - { 0x10028a6, 23684 }, - { 0x1002846, 21966 }, - { 0x10028c6, 24276 }, - { 0x1002886, 23118 }, - { 0x100280a, 20936 }, - { 0x100281a, 21202 }, - { 0x100283a, 21756 }, - { 0x100287a, 22902 }, - { 0x10028fa, 25264 }, - { 0x10028ba, 24054 }, - { 0x100285a, 22316 }, - { 0x10028da, 24646 }, - { 0x100289a, 23468 }, - { 0x100282a, 21474 }, - { 0x100286a, 22604 }, - { 0x10028ea, 24950 }, - { 0x10028aa, 23756 }, - { 0x100284a, 22034 }, - { 0x10028ca, 24348 }, - { 0x100288a, 23186 }, - { 0x1002812, 21068 }, - { 0x1002832, 21614 }, - { 0x1002872, 22752 }, - { 0x10028f2, 25106 }, - { 0x10028b2, 23904 }, - { 0x1002852, 22174 }, - { 0x10028d2, 24496 }, - { 0x1002892, 23326 }, - { 0x1002822, 21340 }, - { 0x1002862, 22462 }, - { 0x10028e2, 24800 }, - { 0x10028a2, 23614 }, - { 0x1002842, 21900 }, - { 0x10028c2, 24206 }, - { 0x1002882, 23052 }, - { 0x1002804, 20841 }, - { 0x100280c, 20969 }, - { 0x100281c, 21237 }, - { 0x100283c, 21793 }, - { 0x100287c, 22941 }, - { 0x10028fc, 25305 }, - { 0x10028bc, 24093 }, - { 0x100285c, 22353 }, - { 0x10028dc, 24685 }, - { 0x100289c, 23505 }, - { 0x100282c, 21509 }, - { 0x100286c, 22641 }, - { 0x10028ec, 24989 }, - { 0x10028ac, 23793 }, - { 0x100284c, 22069 }, - { 0x10028cc, 24385 }, - { 0x100288c, 23221 }, - { 0x1002814, 21101 }, - { 0x1002834, 21649 }, - { 0x1002874, 22789 }, - { 0x10028f4, 25145 }, - { 0x10028b4, 23941 }, - { 0x1002854, 22209 }, - { 0x10028d4, 24533 }, - { 0x1002894, 23361 }, - { 0x1002824, 21373 }, - { 0x1002864, 22497 }, - { 0x10028e4, 24837 }, - { 0x10028a4, 23649 }, - { 0x1002844, 21933 }, - { 0x10028c4, 24241 }, - { 0x1002884, 23085 }, - { 0x1002808, 20905 }, - { 0x1002818, 21169 }, - { 0x1002838, 21721 }, - { 0x1002878, 22865 }, - { 0x10028f8, 25225 }, - { 0x10028b8, 24017 }, - { 0x1002858, 22281 }, - { 0x10028d8, 24609 }, - { 0x1002898, 23433 }, - { 0x1002828, 21441 }, - { 0x1002868, 22569 }, - { 0x10028e8, 24913 }, - { 0x10028a8, 23721 }, - { 0x1002848, 22001 }, - { 0x10028c8, 24313 }, - { 0x1002888, 23153 }, - { 0x1002810, 21037 }, - { 0x1002830, 21581 }, - { 0x1002870, 22717 }, - { 0x10028f0, 25069 }, - { 0x10028b0, 23869 }, - { 0x1002850, 22141 }, - { 0x10028d0, 24461 }, - { 0x1002890, 23293 }, - { 0x1002820, 21309 }, - { 0x1002860, 22429 }, - { 0x10028e0, 24765 }, - { 0x10028a0, 23581 }, - { 0x1002840, 21869 }, - { 0x10028c0, 24173 }, - { 0x1002880, 23021 }, - { 0x0001a2, 1305 }, - { 0x0000a6, 472 }, - { 0x000063, 337 }, - { 0x00fea3, 13064 }, - { 0x0002e5, 1905 }, - { 0x0001e6, 1630 }, - { 0x000ab8, 7064 }, - { 0x000afc, 7878 }, - { 0x0001b7, 1417 }, - { 0x0001e8, 1637 }, - { 0x0000e7, 1073 }, - { 0x0002e6, 1915 }, - { 0x0000b8, 646 }, - { 0x0000a2, 445 }, - { 0x00fea0, 13055 }, - { 0x0009e1, 6649 }, - { 0x000af3, 7759 }, - { 0x000bcf, 8027 }, - { 0x000aec, 7707 }, - { 0x00003a, 160 }, - { 0x00002c, 115 }, - { 0x100220b, 20668 }, - { 0x0000a9, 500 }, - { 0x0009e4, 6668 }, - { 0x0009ee, 6736 }, - { 0x100221b, 20690 }, - { 0x0000a4, 459 }, - { 0x000aff, 7922 }, - { 0x000064, 339 }, - { 0x1001e0b, 18957 }, - { 0x000af1, 7739 }, - { 0x0001ef, 1659 }, - { 0x00fe81, 12945 }, - { 0x00fe83, 12959 }, - { 0x00fe85, 12973 }, - { 0x00fe87, 12987 }, - { 0x00fe89, 13001 }, - { 0x00fe80, 12938 }, - { 0x00fe64, 12505 }, - { 0x00fe56, 12312 }, - { 0x00fe65, 12532 }, - { 0x00fe58, 12341 }, - { 0x00fe51, 12234 }, - { 0x00fe6b, 12653 }, - { 0x00fe69, 12616 }, - { 0x00fe6e, 12708 }, - { 0x00fe6c, 12669 }, - { 0x00fe60, 12459 }, - { 0x00fe68, 12599 }, - { 0x00fe67, 12584 }, - { 0x00fe6a, 12637 }, - { 0x00fe55, 12301 }, - { 0x00fe8b, 13025 }, - { 0x00fe5a, 12373 }, - { 0x00fe5b, 12384 }, - { 0x00fe52, 12245 }, - { 0x00fe6f, 12724 }, - { 0x00fe65, 12556 }, - { 0x00fe57, 12326 }, - { 0x00fe59, 12356 }, - { 0x00fe66, 12567 }, - { 0x00fe82, 12952 }, - { 0x00fe50, 12223 }, - { 0x00fe8c, 13044 }, - { 0x00fe61, 12473 }, - { 0x00fe62, 12483 }, - { 0x00fe84, 12966 }, - { 0x00fe6d, 12689 }, - { 0x00fe5d, 12409 }, - { 0x00fe54, 12289 }, - { 0x00fe86, 12980 }, - { 0x00fe5c, 12397 }, - { 0x00fe53, 12261 }, - { 0x00fe64, 12521 }, - { 0x00fe5f, 12437 }, - { 0x00fe8a, 13008 }, - { 0x00fe63, 12493 }, - { 0x00fe53, 12278 }, - { 0x00fe88, 12994 }, - { 0x00fe5e, 12419 }, - { 0x000abd, 7096 }, - { 0x0000b0, 569 }, - { 0x0000a8, 490 }, - { 0x000aed, 7712 }, - { 0x000aa5, 6890 }, - { 0x100222c, 20710 }, - { 0x0000f7, 1211 }, - { 0x000024, 33 }, - { 0x000aaf, 6967 }, - { 0x0001bd, 1453 }, - { 0x000af2, 7746 }, - { 0x000afe, 7903 }, - { 0x0008fe, 6620 }, - { 0x000ba8, 7950 }, - { 0x000bd6, 8042 }, - { 0x000bc4, 7992 }, - { 0x000bc2, 7976 }, - { 0x0001f0, 1666 }, - { 0x000065, 341 }, - { 0x0003ec, 2183 }, - { 0x0000e9, 1089 }, - { 0x1001eb9, 19497 }, - { 0x0001ec, 1652 }, - { 0x0000ea, 1096 }, - { 0x1001ebf, 19550 }, - { 0x1001ec7, 19687 }, - { 0x1001ec1, 19584 }, - { 0x1001ec3, 19617 }, - { 0x1001ec5, 19650 }, - { 0x0000eb, 1108 }, - { 0x0000e8, 1082 }, - { 0x1001ebb, 19513 }, - { 0x1002088, 20468 }, - { 0x1002078, 20330 }, - { 0x1002208, 20645 }, - { 0x000aae, 6958 }, - { 0x000aa3, 6872 }, - { 0x000aa4, 6881 }, - { 0x0003ba, 2052 }, - { 0x000aa9, 6932 }, - { 0x000ade, 7486 }, - { 0x000adf, 7501 }, - { 0x000ace, 7259 }, - { 0x000acf, 7272 }, - { 0x1002205, 20636 }, - { 0x000aa1, 6856 }, - { 0x000aaa, 6939 }, - { 0x000ae6, 7608 }, - { 0x000ae7, 7627 }, - { 0x0003bf, 2080 }, - { 0x000ae0, 7514 }, - { 0x000ae1, 7531 }, - { 0x000aa2, 6864 }, - { 0x0001ea, 1644 }, - { 0x00003d, 181 }, - { 0x0000f0, 1156 }, - { 0x1001ebd, 19526 }, - { 0x000021, 6 }, - { 0x0000a1, 434 }, - { 0x1000292, 15418 }, - { 0x000066, 343 }, - { 0x1001e1f, 18977 }, - { 0x000af8, 7817 }, - { 0x0009e3, 6665 }, - { 0x000abb, 7071 }, - { 0x000adc, 7445 }, - { 0x000adb, 7428 }, - { 0x000add, 7465 }, - { 0x000ae9, 7662 }, - { 0x000ae8, 7644 }, - { 0x000ac5, 7157 }, - { 0x000ab7, 7053 }, - { 0x1002085, 20426 }, - { 0x1002075, 20291 }, - { 0x000ab5, 7033 }, - { 0x1002084, 20412 }, - { 0x1002074, 20278 }, - { 0x100221c, 20699 }, - { 0x0008f6, 6582 }, - { 0x000067, 345 }, - { 0x0002f5, 1927 }, - { 0x0002bb, 1823 }, - { 0x10001e7, 15397 }, - { 0x0003bb, 2060 }, - { 0x0002f8, 1937 }, - { 0x000060, 317 }, - { 0x00003e, 187 }, - { 0x0008be, 6383 }, - { 0x0000ab, 522 }, - { 0x0000bb, 676 }, - { 0x000068, 347 }, - { 0x000aa8, 6922 }, - { 0x0002b6, 1802 }, - { 0x000aee, 7720 }, - { 0x000ce0, 8110 }, - { 0x000cf2, 8427 }, - { 0x000ce1, 8123 }, - { 0x000ce1, 8134 }, - { 0x000ce7, 8246 }, - { 0x000ce3, 8173 }, - { 0x000ce3, 8186 }, - { 0x000cdf, 8089 }, - { 0x000cea, 8303 }, - { 0x000ced, 8345 }, - { 0x000cef, 8372 }, - { 0x000cf3, 8439 }, - { 0x000cf5, 8464 }, - { 0x000cf5, 8481 }, - { 0x000ce2, 8146 }, - { 0x000ce2, 8159 }, - { 0x000ce4, 8200 }, - { 0x000ce7, 8258 }, - { 0x000ceb, 8320 }, - { 0x000cf7, 8522 }, - { 0x000cec, 8332 }, - { 0x000cee, 8361 }, - { 0x000cf0, 8388 }, - { 0x000cf4, 8454 }, - { 0x000cf7, 8533 }, - { 0x000cf8, 8545 }, - { 0x000cf1, 8399 }, - { 0x000cf1, 8413 }, - { 0x000cf9, 8557 }, - { 0x000cfa, 8569 }, - { 0x000cfa, 8580 }, - { 0x000ce8, 8269 }, - { 0x000ce8, 8280 }, - { 0x000ce5, 8210 }, - { 0x000ce9, 8292 }, - { 0x000cf6, 8498 }, - { 0x000cf6, 8510 }, - { 0x000ce6, 8221 }, - { 0x000ce6, 8233 }, - { 0x000ada, 7419 }, - { 0x0008a3, 5993 }, - { 0x0009ef, 6750 }, - { 0x0009f0, 6765 }, - { 0x0009f1, 6780 }, - { 0x0009f2, 6795 }, - { 0x0009f3, 6810 }, - { 0x0002b1, 1794 }, - { 0x0009e2, 6662 }, - { 0x0000ad, 544 }, - { 0x000069, 349 }, - { 0x1008ff60, 26390 }, - { 0x0000ed, 1126 }, - { 0x1001ecb, 19729 }, - { 0x100012d, 15263 }, - { 0x0000ee, 1133 }, - { 0x0008cf, 6486 }, - { 0x0000ef, 1145 }, - { 0x0002b9, 1814 }, - { 0x0008cd, 6469 }, - { 0x0000ec, 1119 }, - { 0x1001ec9, 19713 }, - { 0x0003ef, 2193 }, - { 0x0008ce, 6478 }, - { 0x0008da, 6504 }, - { 0x0008db, 6515 }, - { 0x0008c2, 6429 }, - { 0x0008bf, 6400 }, - { 0x0008dc, 6524 }, - { 0x0003e7, 2175 }, - { 0x0003b5, 2036 }, - { 0x00006a, 351 }, - { 0x0002bc, 1830 }, - { 0x000bca, 8011 }, - { 0x00006b, 353 }, - { 0x0004b1, 2455 }, - { 0x0004c1, 2579 }, - { 0x0004b4, 2476 }, - { 0x0004cc, 2685 }, - { 0x0004ca, 2669 }, - { 0x0004cd, 2701 }, - { 0x0004cb, 2677 }, - { 0x0004ce, 2709 }, - { 0x0004cc, 2693 }, - { 0x0004b2, 2462 }, - { 0x0004b6, 2490 }, - { 0x0004b9, 2514 }, - { 0x0004b7, 2498 }, - { 0x0004ba, 2522 }, - { 0x0004b8, 2506 }, - { 0x0004cf, 2717 }, - { 0x0004d2, 2741 }, - { 0x0004d0, 2725 }, - { 0x0004d3, 2749 }, - { 0x0004d1, 2733 }, - { 0x0004dd, 2829 }, - { 0x0004c5, 2629 }, - { 0x0004c8, 2653 }, - { 0x0004c6, 2637 }, - { 0x0004c9, 2661 }, - { 0x0004c7, 2645 }, - { 0x0004b5, 2483 }, - { 0x0004d7, 2781 }, - { 0x0004da, 2805 }, - { 0x0004d8, 2789 }, - { 0x0004db, 2813 }, - { 0x0004d9, 2797 }, - { 0x0004bb, 2530 }, - { 0x0004be, 2555 }, - { 0x0004bc, 2538 }, - { 0x0004bf, 2563 }, - { 0x0004bd, 2547 }, - { 0x0004c0, 2571 }, - { 0x0004c3, 2613 }, - { 0x0004c1, 2588 }, - { 0x0004c4, 2621 }, - { 0x0004c2, 2596 }, - { 0x0004c2, 2605 }, - { 0x0004b3, 2469 }, - { 0x0004dc, 2821 }, - { 0x0004a6, 2356 }, - { 0x0004d4, 2757 }, - { 0x0004d6, 2773 }, - { 0x0004d5, 2765 }, - { 0x0004a7, 2364 }, - { 0x0004a3, 2293 }, - { 0x0004a4, 2313 }, - { 0x0004a5, 2324 }, - { 0x0004aa, 2385 }, - { 0x0004a1, 2259 }, - { 0x0004a8, 2371 }, - { 0x0004a5, 2341 }, - { 0x0004ab, 2392 }, - { 0x0004a2, 2273 }, - { 0x00ff7e, 14444 }, - { 0x0004af, 2423 }, - { 0x0004af, 2432 }, - { 0x0004a9, 2378 }, - { 0x0004ac, 2399 }, - { 0x0004ae, 2415 }, - { 0x0004ad, 2407 }, - { 0x0003a2, 1968 }, - { 0x0003f3, 2218 }, - { 0x0003a2, 1974 }, - { 0x00006c, 355 }, - { 0x0001e5, 1623 }, - { 0x000ad9, 7408 }, - { 0x1001e37, 18997 }, - { 0x0001b5, 1403 }, - { 0x0003b6, 2043 }, - { 0x000abc, 7079 }, - { 0x0008fb, 6591 }, - { 0x000ba3, 7929 }, - { 0x000ad2, 7329 }, - { 0x0008af, 6174 }, - { 0x000acc, 7224 }, - { 0x000aea, 7682 }, - { 0x0008a1, 5966 }, - { 0x000bda, 8061 }, - { 0x000ad0, 7288 }, - { 0x0009f4, 6825 }, - { 0x000bdc, 8070 }, - { 0x00003c, 176 }, - { 0x0008bc, 6360 }, - { 0x0009e5, 6671 }, - { 0x0008de, 6543 }, - { 0x0008df, 6554 }, - { 0x0009ed, 6722 }, - { 0x0009ea, 6680 }, - { 0x0001b3, 1395 }, - { 0x00006d, 357 }, - { 0x1001e41, 19017 }, - { 0x0000af, 562 }, - { 0x000af7, 7806 }, - { 0x000af0, 7726 }, - { 0x000abf, 7127 }, - { 0x0000ba, 666 }, - { 0x00002d, 121 }, - { 0x000ad6, 7392 }, - { 0x0000b5, 618 }, - { 0x0000d7, 932 }, - { 0x000af6, 7794 }, - { 0x000af5, 7781 }, - { 0x00006e, 359 }, - { 0x0008c5, 6438 }, - { 0x0001f1, 1674 }, - { 0x0001f2, 1681 }, - { 0x0003f1, 2201 }, - { 0x1002089, 20483 }, - { 0x1002079, 20344 }, - { 0x0009e8, 6674 }, - { 0x0000a0, 421 }, - { 0x1002247, 20738 }, - { 0x1002209, 20655 }, - { 0x0008bd, 6374 }, - { 0x1002262, 20759 }, - { 0x0000ac, 536 }, - { 0x0000f1, 1160 }, - { 0x000023, 22 }, - { 0x0006b0, 3817 }, - { 0x00006f, 361 }, - { 0x0000f3, 1174 }, - { 0x1000275, 15410 }, - { 0x1001ecd, 19749 }, - { 0x10001d2, 15383 }, - { 0x0000f4, 1181 }, - { 0x1001ed1, 19788 }, - { 0x1001ed9, 19925 }, - { 0x1001ed3, 19822 }, - { 0x1001ed5, 19855 }, - { 0x1001ed7, 19888 }, - { 0x0000f6, 1200 }, - { 0x0001f5, 1688 }, - { 0x0013bd, 11092 }, - { 0x0001b2, 1388 }, - { 0x0000f2, 1167 }, - { 0x1001ecf, 19765 }, - { 0x10001a1, 15338 }, - { 0x1001edb, 19956 }, - { 0x1001ee3, 20045 }, - { 0x1001edd, 19978 }, - { 0x1001edf, 19999 }, - { 0x1001ee1, 20020 }, - { 0x0003f2, 2210 }, - { 0x000ac3, 7134 }, - { 0x000ab2, 7002 }, - { 0x0000bd, 702 }, - { 0x0000bc, 691 }, - { 0x000ab6, 7044 }, - { 0x1002081, 20371 }, - { 0x0000b9, 654 }, - { 0x000ab0, 6983 }, - { 0x0000f8, 1220 }, - { 0x000ae2, 7550 }, - { 0x000ae5, 7599 }, - { 0x000ae4, 7581 }, - { 0x000ae3, 7565 }, - { 0x0000aa, 510 }, - { 0x0000f8, 1229 }, - { 0x0000f5, 1193 }, - { 0x000bc0, 7968 }, - { 0x00047e, 2250 }, - { 0x000070, 363 }, - { 0x1001e57, 19037 }, - { 0x0000b6, 621 }, - { 0x000028, 80 }, - { 0x000029, 90 }, - { 0x1002202, 20619 }, - { 0x0008ef, 6564 }, - { 0x000025, 40 }, - { 0x00002e, 127 }, - { 0x0000b7, 631 }, - { 0x000ad5, 7383 }, - { 0x000afb, 7858 }, - { 0x00002b, 110 }, - { 0x0000b1, 576 }, - { 0x000ad4, 7370 }, - { 0x0004b0, 2440 }, - { 0x000aa6, 6901 }, - { 0x000071, 365 }, - { 0x000bcc, 8015 }, - { 0x00003f, 195 }, - { 0x0000bf, 724 }, - { 0x000022, 13 }, - { 0x000060, 323 }, - { 0x000027, 69 }, - { 0x000072, 367 }, - { 0x0001e0, 1609 }, - { 0x0008d6, 6496 }, - { 0x0001f8, 1701 }, - { 0x0003b3, 2027 }, - { 0x0000ae, 551 }, - { 0x000abe, 7109 }, - { 0x0008fd, 6609 }, - { 0x000ba6, 7939 }, - { 0x000ad3, 7349 }, - { 0x0008b0, 6195 }, - { 0x0008b7, 6339 }, - { 0x000acd, 7241 }, - { 0x000aeb, 7694 }, - { 0x000bd8, 8051 }, - { 0x000ad1, 7308 }, - { 0x0009f5, 6831 }, - { 0x000bfc, 8079 }, - { 0x000073, 369 }, - { 0x1001e61, 19057 }, - { 0x0001b6, 1410 }, - { 0x0001b9, 1423 }, - { 0x0001ba, 1430 }, - { 0x1000259, 15404 }, - { 0x0002fe, 1956 }, - { 0x00ff7e, 14468 }, - { 0x000ad7, 7400 }, - { 0x0000a7, 482 }, - { 0x00003b, 166 }, - { 0x0004df, 2848 }, - { 0x000ac6, 7169 }, - { 0x1002087, 20453 }, - { 0x1002077, 20316 }, - { 0x000aca, 7192 }, - { 0x000aac, 6946 }, - { 0x0008c9, 6456 }, - { 0x000afd, 7884 }, - { 0x1002086, 20440 }, - { 0x1002076, 20304 }, - { 0x00002f, 134 }, - { 0x0009e0, 6636 }, - { 0x000020, 0 }, - { 0x100221a, 20679 }, - { 0x0000df, 1013 }, - { 0x0000a3, 450 }, - { 0x1002263, 20772 }, - { 0x000074, 371 }, - { 0x1001e6b, 19077 }, - { 0x0001bb, 1439 }, - { 0x0001fe, 1727 }, - { 0x000af9, 7830 }, - { 0x000afa, 7840 }, - { 0x0008c0, 6409 }, - { 0x000aa7, 6912 }, - { 0x0000fe, 1280 }, - { 0x000ac4, 7144 }, - { 0x000ab4, 7021 }, - { 0x0000be, 710 }, - { 0x1002083, 20397 }, - { 0x0000b3, 598 }, - { 0x100222d, 20720 }, - { 0x0008a4, 6008 }, - { 0x0008ab, 6116 }, - { 0x0008a2, 5978 }, - { 0x0008a7, 6046 }, - { 0x0008b1, 6217 }, - { 0x0008ad, 6144 }, - { 0x0008a9, 6080 }, - { 0x0008b5, 6303 }, - { 0x0009f7, 6843 }, - { 0x0008b3, 6251 }, - { 0x000ac9, 7182 }, - { 0x000acb, 7206 }, - { 0x0003bc, 2069 }, - { 0x000ab3, 7011 }, - { 0x1002082, 20384 }, - { 0x0000b2, 586 }, - { 0x000ab1, 6992 }, - { 0x000075, 373 }, - { 0x0000fa, 1243 }, - { 0x1001ee5, 20069 }, - { 0x0002fd, 1949 }, - { 0x0000fb, 1250 }, - { 0x0000fc, 1262 }, - { 0x0001fb, 1714 }, - { 0x0000f9, 1236 }, - { 0x1001ee7, 20085 }, - { 0x10001b0, 15350 }, - { 0x1001ee9, 20102 }, - { 0x1001ef1, 20191 }, - { 0x1001eeb, 20124 }, - { 0x1001eed, 20145 }, - { 0x1001eef, 20166 }, - { 0x0003fe, 2242 }, - { 0x000bc6, 8002 }, - { 0x00005f, 306 }, - { 0x0008dd, 6537 }, - { 0x0003f9, 2227 }, - { 0x0008fc, 6601 }, - { 0x000ba9, 7960 }, - { 0x0009ec, 6709 }, - { 0x0009eb, 6695 }, - { 0x000bc3, 7985 }, - { 0x000bd3, 8034 }, - { 0x000bce, 8020 }, - { 0x0001f9, 1708 }, - { 0x0003fd, 2235 }, - { 0x000076, 375 }, - { 0x0008c1, 6419 }, - { 0x0009f8, 6848 }, - { 0x0008a6, 6032 }, - { 0x0004de, 2836 }, - { 0x0009e9, 6677 }, - { 0x000077, 377 }, - { 0x1001e83, 19108 }, - { 0x1000175, 15282 }, - { 0x1001e85, 19126 }, - { 0x1001e81, 19094 }, - { 0x000078, 379 }, - { 0x1001e8b, 19147 }, - { 0x000079, 381 }, - { 0x0000fd, 1273 }, - { 0x1001ef5, 20229 }, - { 0x1000177, 15306 }, - { 0x0000ff, 1286 }, - { 0x0000a5, 468 }, - { 0x1001ef3, 20212 }, - { 0x1001ef7, 20245 }, - { 0x1001ef9, 20258 }, - { 0x00007a, 383 }, - { 0x0001bf, 1472 }, - { 0x0001bc, 1446 }, - { 0x0001be, 1465 }, - { 0x1002080, 20357 }, - { 0x1002070, 20265 }, - { 0x10001b6, 15364 }}; diff --git a/mutter/clutter/clutter/clutter-keysyms-table.c b/mutter/clutter/clutter/clutter-keysyms-table.c deleted file mode 100644 index 50007f4..0000000 --- a/mutter/clutter/clutter/clutter-keysyms-table.c +++ /dev/null @@ -1,1679 +0,0 @@ -#include "config.h" - -#include - -#include "clutter/clutter-event.h" - -/* Code below from GDK, which contains following comment: - * - * Thanks to Markus G. Kuhn for the ksysym<->Unicode - * mapping functions, from the xterm sources. - */ -static const struct { - unsigned short keysym; - unsigned short ucs; -} clutter_keysym_to_unicode_tab[] = { - { 0x01a1, 0x0104 }, /* Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */ - { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */ - { 0x01a3, 0x0141 }, /* Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE */ - { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ - { 0x01a6, 0x015a }, /* Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE */ - { 0x01a9, 0x0160 }, /* Scaron Š LATIN CAPITAL LETTER S WITH CARON */ - { 0x01aa, 0x015e }, /* Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA */ - { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ - { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ - { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ - { 0x01af, 0x017b }, /* Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE */ - { 0x01b1, 0x0105 }, /* aogonek ą LATIN SMALL LETTER A WITH OGONEK */ - { 0x01b2, 0x02db }, /* ogonek ˛ OGONEK */ - { 0x01b3, 0x0142 }, /* lstroke ł LATIN SMALL LETTER L WITH STROKE */ - { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ - { 0x01b6, 0x015b }, /* sacute ś LATIN SMALL LETTER S WITH ACUTE */ - { 0x01b7, 0x02c7 }, /* caron ˇ CARON */ - { 0x01b9, 0x0161 }, /* scaron š LATIN SMALL LETTER S WITH CARON */ - { 0x01ba, 0x015f }, /* scedilla ş LATIN SMALL LETTER S WITH CEDILLA */ - { 0x01bb, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */ - { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ - { 0x01bd, 0x02dd }, /* doubleacute ˝ DOUBLE ACUTE ACCENT */ - { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ - { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ - { 0x01c0, 0x0154 }, /* Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE */ - { 0x01c3, 0x0102 }, /* Abreve Ă LATIN CAPITAL LETTER A WITH BREVE */ - { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ - { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ - { 0x01c8, 0x010c }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */ - { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ - { 0x01cc, 0x011a }, /* Ecaron Ě LATIN CAPITAL LETTER E WITH CARON */ - { 0x01cf, 0x010e }, /* Dcaron Ď LATIN CAPITAL LETTER D WITH CARON */ - { 0x01d0, 0x0110 }, /* Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE */ - { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ - { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ - { 0x01d5, 0x0150 }, /* Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ - { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ - { 0x01d9, 0x016e }, /* Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE */ - { 0x01db, 0x0170 }, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ - { 0x01de, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */ - { 0x01e0, 0x0155 }, /* racute ŕ LATIN SMALL LETTER R WITH ACUTE */ - { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ - { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ - { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ - { 0x01e8, 0x010d }, /* ccaron č LATIN SMALL LETTER C WITH CARON */ - { 0x01ea, 0x0119 }, /* eogonek ę LATIN SMALL LETTER E WITH OGONEK */ - { 0x01ec, 0x011b }, /* ecaron ě LATIN SMALL LETTER E WITH CARON */ - { 0x01ef, 0x010f }, /* dcaron ď LATIN SMALL LETTER D WITH CARON */ - { 0x01f0, 0x0111 }, /* dstroke đ LATIN SMALL LETTER D WITH STROKE */ - { 0x01f1, 0x0144 }, /* nacute ń LATIN SMALL LETTER N WITH ACUTE */ - { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ - { 0x01f5, 0x0151 }, /* odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE */ - { 0x01f8, 0x0159 }, /* rcaron ř LATIN SMALL LETTER R WITH CARON */ - { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ - { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ - { 0x01fe, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */ - { 0x01ff, 0x02d9 }, /* abovedot ˙ DOT ABOVE */ - { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ - { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ - { 0x02a9, 0x0130 }, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */ - { 0x02ab, 0x011e }, /* Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE */ - { 0x02ac, 0x0134 }, /* Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ - { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ - { 0x02b6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ - { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */ - { 0x02bb, 0x011f }, /* gbreve ğ LATIN SMALL LETTER G WITH BREVE */ - { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ - { 0x02c5, 0x010a }, /* Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE */ - { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ - { 0x02d5, 0x0120 }, /* Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE */ - { 0x02d8, 0x011c }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ - { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ - { 0x02de, 0x015c }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ - { 0x02e5, 0x010b }, /* cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE */ - { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ - { 0x02f5, 0x0121 }, /* gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE */ - { 0x02f8, 0x011d }, /* gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX */ - { 0x02fd, 0x016d }, /* ubreve ŭ LATIN SMALL LETTER U WITH BREVE */ - { 0x02fe, 0x015d }, /* scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX */ - { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */ - { 0x03a3, 0x0156 }, /* Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA */ - { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ - { 0x03a6, 0x013b }, /* Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA */ - { 0x03aa, 0x0112 }, /* Emacron Ē LATIN CAPITAL LETTER E WITH MACRON */ - { 0x03ab, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */ - { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ - { 0x03b3, 0x0157 }, /* rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA */ - { 0x03b5, 0x0129 }, /* itilde ĩ LATIN SMALL LETTER I WITH TILDE */ - { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ - { 0x03ba, 0x0113 }, /* emacron ē LATIN SMALL LETTER E WITH MACRON */ - { 0x03bb, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */ - { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ - { 0x03bd, 0x014a }, /* ENG Ŋ LATIN CAPITAL LETTER ENG */ - { 0x03bf, 0x014b }, /* eng ŋ LATIN SMALL LETTER ENG */ - { 0x03c0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */ - { 0x03c7, 0x012e }, /* Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK */ - { 0x03cc, 0x0116 }, /* Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE */ - { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ - { 0x03d1, 0x0145 }, /* Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA */ - { 0x03d2, 0x014c }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */ - { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ - { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ - { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ - { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ - { 0x03e0, 0x0101 }, /* amacron ā LATIN SMALL LETTER A WITH MACRON */ - { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ - { 0x03ec, 0x0117 }, /* eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE */ - { 0x03ef, 0x012b }, /* imacron ī LATIN SMALL LETTER I WITH MACRON */ - { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ - { 0x03f2, 0x014d }, /* omacron ō LATIN SMALL LETTER O WITH MACRON */ - { 0x03f3, 0x0137 }, /* kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA */ - { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ - { 0x03fd, 0x0169 }, /* utilde ũ LATIN SMALL LETTER U WITH TILDE */ - { 0x03fe, 0x016b }, /* umacron ū LATIN SMALL LETTER U WITH MACRON */ - { 0x047e, 0x203e }, /* overline ‾ OVERLINE */ - { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ - { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */ - { 0x04a3, 0x300d }, /* kana_closingbracket 」 RIGHT CORNER BRACKET */ - { 0x04a4, 0x3001 }, /* kana_comma 、 IDEOGRAPHIC COMMA */ - { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ - { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */ - { 0x04a7, 0x30a1 }, /* kana_a ァ KATAKANA LETTER SMALL A */ - { 0x04a8, 0x30a3 }, /* kana_i ィ KATAKANA LETTER SMALL I */ - { 0x04a9, 0x30a5 }, /* kana_u ゥ KATAKANA LETTER SMALL U */ - { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */ - { 0x04ab, 0x30a9 }, /* kana_o ォ KATAKANA LETTER SMALL O */ - { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */ - { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */ - { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */ - { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ - { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ - { 0x04b1, 0x30a2 }, /* kana_A ア KATAKANA LETTER A */ - { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */ - { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */ - { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */ - { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */ - { 0x04b6, 0x30ab }, /* kana_KA カ KATAKANA LETTER KA */ - { 0x04b7, 0x30ad }, /* kana_KI キ KATAKANA LETTER KI */ - { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */ - { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */ - { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */ - { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */ - { 0x04bc, 0x30b7 }, /* kana_SHI シ KATAKANA LETTER SI */ - { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */ - { 0x04be, 0x30bb }, /* kana_SE セ KATAKANA LETTER SE */ - { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */ - { 0x04c0, 0x30bf }, /* kana_TA タ KATAKANA LETTER TA */ - { 0x04c1, 0x30c1 }, /* kana_CHI チ KATAKANA LETTER TI */ - { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */ - { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */ - { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */ - { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */ - { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */ - { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */ - { 0x04c8, 0x30cd }, /* kana_NE ネ KATAKANA LETTER NE */ - { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */ - { 0x04ca, 0x30cf }, /* kana_HA ハ KATAKANA LETTER HA */ - { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */ - { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */ - { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */ - { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */ - { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */ - { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */ - { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */ - { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */ - { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */ - { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */ - { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */ - { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */ - { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */ - { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */ - { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */ - { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */ - { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */ - { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */ - { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */ - { 0x04de, 0x309b }, /* voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK */ - { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ - { 0x05ac, 0x060c }, /* Arabic_comma ، ARABIC COMMA */ - { 0x05bb, 0x061b }, /* Arabic_semicolon ؛ ARABIC SEMICOLON */ - { 0x05bf, 0x061f }, /* Arabic_question_mark ؟ ARABIC QUESTION MARK */ - { 0x05c1, 0x0621 }, /* Arabic_hamza ء ARABIC LETTER HAMZA */ - { 0x05c2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */ - { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */ - { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ - { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */ - { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ - { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */ - { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */ - { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA */ - { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */ - { 0x05cb, 0x062b }, /* Arabic_theh ث ARABIC LETTER THEH */ - { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */ - { 0x05cd, 0x062d }, /* Arabic_hah ح ARABIC LETTER HAH */ - { 0x05ce, 0x062e }, /* Arabic_khah خ ARABIC LETTER KHAH */ - { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */ - { 0x05d0, 0x0630 }, /* Arabic_thal ذ ARABIC LETTER THAL */ - { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */ - { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */ - { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */ - { 0x05d4, 0x0634 }, /* Arabic_sheen ش ARABIC LETTER SHEEN */ - { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */ - { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */ - { 0x05d7, 0x0637 }, /* Arabic_tah ط ARABIC LETTER TAH */ - { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */ - { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */ - { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */ - { 0x05e0, 0x0640 }, /* Arabic_tatweel ـ ARABIC TATWEEL */ - { 0x05e1, 0x0641 }, /* Arabic_feh ف ARABIC LETTER FEH */ - { 0x05e2, 0x0642 }, /* Arabic_qaf ق ARABIC LETTER QAF */ - { 0x05e3, 0x0643 }, /* Arabic_kaf ك ARABIC LETTER KAF */ - { 0x05e4, 0x0644 }, /* Arabic_lam ل ARABIC LETTER LAM */ - { 0x05e5, 0x0645 }, /* Arabic_meem م ARABIC LETTER MEEM */ - { 0x05e6, 0x0646 }, /* Arabic_noon ن ARABIC LETTER NOON */ - { 0x05e7, 0x0647 }, /* Arabic_ha ه ARABIC LETTER HEH */ - { 0x05e8, 0x0648 }, /* Arabic_waw و ARABIC LETTER WAW */ - { 0x05e9, 0x0649 }, /* Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA */ - { 0x05ea, 0x064a }, /* Arabic_yeh ي ARABIC LETTER YEH */ - { 0x05eb, 0x064b }, /* Arabic_fathatan ً ARABIC FATHATAN */ - { 0x05ec, 0x064c }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */ - { 0x05ed, 0x064d }, /* Arabic_kasratan ٍ ARABIC KASRATAN */ - { 0x05ee, 0x064e }, /* Arabic_fatha َ ARABIC FATHA */ - { 0x05ef, 0x064f }, /* Arabic_damma ُ ARABIC DAMMA */ - { 0x05f0, 0x0650 }, /* Arabic_kasra ِ ARABIC KASRA */ - { 0x05f1, 0x0651 }, /* Arabic_shadda ّ ARABIC SHADDA */ - { 0x05f2, 0x0652 }, /* Arabic_sukun ْ ARABIC SUKUN */ - { 0x06a1, 0x0452 }, /* Serbian_dje ђ CYRILLIC SMALL LETTER DJE */ - { 0x06a2, 0x0453 }, /* Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE */ - { 0x06a3, 0x0451 }, /* Cyrillic_io ё CYRILLIC SMALL LETTER IO */ - { 0x06a4, 0x0454 }, /* Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE */ - { 0x06a5, 0x0455 }, /* Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE */ - { 0x06a6, 0x0456 }, /* Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ - { 0x06a7, 0x0457 }, /* Ukrainian_yi ї CYRILLIC SMALL LETTER YI */ - { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ - { 0x06a9, 0x0459 }, /* Cyrillic_lje љ CYRILLIC SMALL LETTER LJE */ - { 0x06aa, 0x045a }, /* Cyrillic_nje њ CYRILLIC SMALL LETTER NJE */ - { 0x06ab, 0x045b }, /* Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE */ - { 0x06ac, 0x045c }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */ - { 0x06ad, 0x0491 }, /* Ukrainian_ghe_with_upturn ґ CYRILLIC SMALL LETTER GHE WITH UPTURN */ - { 0x06ae, 0x045e }, /* Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U */ - { 0x06af, 0x045f }, /* Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE */ - { 0x06b0, 0x2116 }, /* numerosign № NUMERO SIGN */ - { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ - { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ - { 0x06b3, 0x0401 }, /* Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO */ - { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ - { 0x06b5, 0x0405 }, /* Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE */ - { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ - { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ - { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ - { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ - { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ - { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ - { 0x06bc, 0x040c }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */ - { 0x06bd, 0x0490 }, /* Ukrainian_GHE_WITH_UPTURN Ґ CYRILLIC CAPITAL LETTER GHE WITH UPTURN */ - { 0x06be, 0x040e }, /* Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U */ - { 0x06bf, 0x040f }, /* Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE */ - { 0x06c0, 0x044e }, /* Cyrillic_yu ю CYRILLIC SMALL LETTER YU */ - { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ - { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ - { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ - { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ - { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ - { 0x06c6, 0x0444 }, /* Cyrillic_ef ф CYRILLIC SMALL LETTER EF */ - { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ - { 0x06c8, 0x0445 }, /* Cyrillic_ha х CYRILLIC SMALL LETTER HA */ - { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ - { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ - { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ - { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ - { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ - { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ - { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ - { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ - { 0x06d1, 0x044f }, /* Cyrillic_ya я CYRILLIC SMALL LETTER YA */ - { 0x06d2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */ - { 0x06d3, 0x0441 }, /* Cyrillic_es с CYRILLIC SMALL LETTER ES */ - { 0x06d4, 0x0442 }, /* Cyrillic_te т CYRILLIC SMALL LETTER TE */ - { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ - { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ - { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ - { 0x06d8, 0x044c }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */ - { 0x06d9, 0x044b }, /* Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU */ - { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ - { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ - { 0x06dc, 0x044d }, /* Cyrillic_e э CYRILLIC SMALL LETTER E */ - { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ - { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ - { 0x06df, 0x044a }, /* Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN */ - { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ - { 0x06e1, 0x0410 }, /* Cyrillic_A А CYRILLIC CAPITAL LETTER A */ - { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ - { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ - { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ - { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ - { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ - { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ - { 0x06e8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */ - { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ - { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ - { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ - { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ - { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */ - { 0x06ee, 0x041d }, /* Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN */ - { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ - { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ - { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ - { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */ - { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ - { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ - { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ - { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ - { 0x06f7, 0x0412 }, /* Cyrillic_VE В CYRILLIC CAPITAL LETTER VE */ - { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ - { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ - { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ - { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ - { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */ - { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ - { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ - { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ - { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ - { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ - { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ - { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ - { 0x07a5, 0x03aa }, /* Greek_IOTAdieresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ - { 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */ - { 0x07a8, 0x038e }, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */ - { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ - { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS */ - { 0x07ae, 0x0385 }, /* Greek_accentdieresis ΅ GREEK DIALYTIKA TONOS */ - { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */ - { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ - { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */ - { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ - { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ - { 0x07b5, 0x03ca }, /* Greek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ - { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ - { 0x07b7, 0x03cc }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */ - { 0x07b8, 0x03cd }, /* Greek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS */ - { 0x07b9, 0x03cb }, /* Greek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ - { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ - { 0x07bb, 0x03ce }, /* Greek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS */ - { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ - { 0x07c2, 0x0392 }, /* Greek_BETA Β GREEK CAPITAL LETTER BETA */ - { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ - { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ - { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ - { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ - { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ - { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ - { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ - { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ - { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */ - { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */ - { 0x07cd, 0x039d }, /* Greek_NU Ν GREEK CAPITAL LETTER NU */ - { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ - { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ - { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */ - { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ - { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ - { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ - { 0x07d5, 0x03a5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */ - { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ - { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ - { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ - { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ - { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ - { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */ - { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ - { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */ - { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ - { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ - { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */ - { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */ - { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */ - { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ - { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */ - { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */ - { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */ - { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */ - { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ - { 0x07f0, 0x03c0 }, /* Greek_pi π GREEK SMALL LETTER PI */ - { 0x07f1, 0x03c1 }, /* Greek_rho ρ GREEK SMALL LETTER RHO */ - { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ - { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA */ - { 0x07f4, 0x03c4 }, /* Greek_tau τ GREEK SMALL LETTER TAU */ - { 0x07f5, 0x03c5 }, /* Greek_upsilon υ GREEK SMALL LETTER UPSILON */ - { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */ - { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */ - { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */ - { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ -/* 0x08a1 leftradical ? ??? */ -/* 0x08a2 topleftradical ? ??? */ -/* 0x08a3 horizconnector ? ??? */ - { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */ - { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ - { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ -/* 0x08a7 topleftsqbracket ? ??? */ -/* 0x08a8 botleftsqbracket ? ??? */ -/* 0x08a9 toprightsqbracket ? ??? */ -/* 0x08aa botrightsqbracket ? ??? */ -/* 0x08ab topleftparens ? ??? */ -/* 0x08ac botleftparens ? ??? */ -/* 0x08ad toprightparens ? ??? */ -/* 0x08ae botrightparens ? ??? */ -/* 0x08af leftmiddlecurlybrace ? ??? */ -/* 0x08b0 rightmiddlecurlybrace ? ??? */ -/* 0x08b1 topleftsummation ? ??? */ -/* 0x08b2 botleftsummation ? ??? */ -/* 0x08b3 topvertsummationconnector ? ??? */ -/* 0x08b4 botvertsummationconnector ? ??? */ -/* 0x08b5 toprightsummation ? ??? */ -/* 0x08b6 botrightsummation ? ??? */ -/* 0x08b7 rightmiddlesummation ? ??? */ - { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ - { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */ - { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ - { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */ - { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */ - { 0x08c1, 0x221d }, /* variation ∝ PROPORTIONAL TO */ - { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */ - { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */ - { 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */ -/* 0x08c9 similarequal ? ??? */ - { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ - { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ - { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */ - { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */ - { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */ - { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */ - { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */ - { 0x08dd, 0x222a }, /* union ∪ UNION */ - { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */ - { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */ - { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ - { 0x08f6, 0x0192 }, /* function ƒ LATIN SMALL LETTER F WITH HOOK */ - { 0x08fb, 0x2190 }, /* leftarrow ← LEFTWARDS ARROW */ - { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */ - { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */ - { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */ - { 0x09df, 0x2422 }, /* blank ␢ BLANK SYMBOL */ - { 0x09e0, 0x25c6 }, /* soliddiamond ◆ BLACK DIAMOND */ - { 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */ - { 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */ - { 0x09e3, 0x240c }, /* ff ␌ SYMBOL FOR FORM FEED */ - { 0x09e4, 0x240d }, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */ - { 0x09e5, 0x240a }, /* lf ␊ SYMBOL FOR LINE FEED */ - { 0x09e8, 0x2424 }, /* nl ␤ SYMBOL FOR NEWLINE */ - { 0x09e9, 0x240b }, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */ - { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ - { 0x09eb, 0x2510 }, /* uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */ - { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ - { 0x09ed, 0x2514 }, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */ - { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ -/* 0x09ef horizlinescan1 ? ??? */ -/* 0x09f0 horizlinescan3 ? ??? */ - { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ -/* 0x09f2 horizlinescan7 ? ??? */ -/* 0x09f3 horizlinescan9 ? ??? */ - { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ - { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ - { 0x09f6, 0x2534 }, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ - { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ - { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ - { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */ - { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */ - { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */ - { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */ - { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */ - { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */ - { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */ - { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */ - { 0x0aa9, 0x2014 }, /* emdash — EM DASH */ - { 0x0aaa, 0x2013 }, /* endash – EN DASH */ -/* 0x0aac signifblank ? ??? */ - { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */ -/* 0x0aaf doubbaselinedot ? ??? */ - { 0x0ab0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */ - { 0x0ab1, 0x2154 }, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */ - { 0x0ab2, 0x2155 }, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */ - { 0x0ab3, 0x2156 }, /* twofifths ⅖ VULGAR FRACTION TWO FIFTHS */ - { 0x0ab4, 0x2157 }, /* threefifths ⅗ VULGAR FRACTION THREE FIFTHS */ - { 0x0ab5, 0x2158 }, /* fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS */ - { 0x0ab6, 0x2159 }, /* onesixth ⅙ VULGAR FRACTION ONE SIXTH */ - { 0x0ab7, 0x215a }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */ - { 0x0ab8, 0x2105 }, /* careof ℅ CARE OF */ - { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */ - { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */ - { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */ - { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */ -/* 0x0abf marker ? ??? */ - { 0x0ac3, 0x215b }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */ - { 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */ - { 0x0ac5, 0x215d }, /* fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS */ - { 0x0ac6, 0x215e }, /* seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS */ - { 0x0ac9, 0x2122 }, /* trademark ™ TRADE MARK SIGN */ - { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */ -/* 0x0acb trademarkincircle ? ??? */ - { 0x0acc, 0x25c1 }, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */ - { 0x0acd, 0x25b7 }, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */ - { 0x0ace, 0x25cb }, /* emopencircle ○ WHITE CIRCLE */ - { 0x0acf, 0x25a1 }, /* emopenrectangle □ WHITE SQUARE */ - { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ - { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ - { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ - { 0x0ad3, 0x201d }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */ - { 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */ - { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */ - { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */ - { 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */ -/* 0x0ada hexagram ? ??? */ - { 0x0adb, 0x25ac }, /* filledrectbullet ▬ BLACK RECTANGLE */ - { 0x0adc, 0x25c0 }, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */ - { 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */ - { 0x0ade, 0x25cf }, /* emfilledcircle ● BLACK CIRCLE */ - { 0x0adf, 0x25a0 }, /* emfilledrect ■ BLACK SQUARE */ - { 0x0ae0, 0x25e6 }, /* enopencircbullet ◦ WHITE BULLET */ - { 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */ - { 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */ - { 0x0ae3, 0x25b3 }, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */ - { 0x0ae4, 0x25bd }, /* opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE */ - { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */ - { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */ - { 0x0ae7, 0x25aa }, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */ - { 0x0ae8, 0x25b2 }, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */ - { 0x0ae9, 0x25bc }, /* filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE */ - { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ - { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ - { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */ - { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */ - { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */ - { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */ - { 0x0af1, 0x2020 }, /* dagger † DAGGER */ - { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */ - { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */ - { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */ - { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */ - { 0x0af6, 0x266d }, /* musicalflat ♭ MUSIC FLAT SIGN */ - { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */ - { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */ - { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */ - { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */ - { 0x0afb, 0x2117 }, /* phonographcopyright ℗ SOUND RECORDING COPYRIGHT */ - { 0x0afc, 0x2038 }, /* caret ‸ CARET */ - { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ - { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ -/* 0x0aff cursor ? ??? */ - { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */ - { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */ - { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */ - { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */ - { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */ - { 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */ - { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */ - { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */ - { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */ - { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */ - { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */ - { 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */ - { 0x0bcf, 0x25cb }, /* circle ○ WHITE CIRCLE */ - { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */ - { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */ - { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */ - { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */ - { 0x0bdc, 0x22a3 }, /* lefttack ⊣ LEFT TACK */ - { 0x0bfc, 0x22a2 }, /* righttack ⊢ RIGHT TACK */ - { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ - { 0x0ce0, 0x05d0 }, /* hebrew_aleph א HEBREW LETTER ALEF */ - { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */ - { 0x0ce2, 0x05d2 }, /* hebrew_gimel ג HEBREW LETTER GIMEL */ - { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */ - { 0x0ce4, 0x05d4 }, /* hebrew_he ה HEBREW LETTER HE */ - { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */ - { 0x0ce6, 0x05d6 }, /* hebrew_zain ז HEBREW LETTER ZAYIN */ - { 0x0ce7, 0x05d7 }, /* hebrew_chet ח HEBREW LETTER HET */ - { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */ - { 0x0ce9, 0x05d9 }, /* hebrew_yod י HEBREW LETTER YOD */ - { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ - { 0x0ceb, 0x05db }, /* hebrew_kaph כ HEBREW LETTER KAF */ - { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */ - { 0x0ced, 0x05dd }, /* hebrew_finalmem ם HEBREW LETTER FINAL MEM */ - { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */ - { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ - { 0x0cf0, 0x05e0 }, /* hebrew_nun נ HEBREW LETTER NUN */ - { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */ - { 0x0cf2, 0x05e2 }, /* hebrew_ayin ע HEBREW LETTER AYIN */ - { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ף HEBREW LETTER FINAL PE */ - { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */ - { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ץ HEBREW LETTER FINAL TSADI */ - { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */ - { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */ - { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */ - { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */ - { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */ - { 0x0da1, 0x0e01 }, /* Thai_kokai ก THAI CHARACTER KO KAI */ - { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ - { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ - { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ - { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ - { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ - { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ - { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ - { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ - { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ - { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */ - { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ - { 0x0dad, 0x0e0d }, /* Thai_yoying ญ THAI CHARACTER YO YING */ - { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ - { 0x0daf, 0x0e0f }, /* Thai_topatak ฏ THAI CHARACTER TO PATAK */ - { 0x0db0, 0x0e10 }, /* Thai_thothan ฐ THAI CHARACTER THO THAN */ - { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ - { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ - { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */ - { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */ - { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */ - { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ - { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ - { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */ - { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */ - { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ - { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */ - { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ - { 0x0dbd, 0x0e1d }, /* Thai_fofa ฝ THAI CHARACTER FO FA */ - { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ - { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ - { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */ - { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */ - { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */ - { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */ - { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */ - { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */ - { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */ - { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ - { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */ - { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ - { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */ - { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */ - { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ - { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */ - { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ - { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ - { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */ - { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ - { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */ - { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */ - { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */ - { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */ - { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */ - { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ - { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */ - { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */ - { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ - { 0x0dde, 0x0e3e }, /* Thai_maihanakat_maitho ฾ ??? */ - { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ - { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */ - { 0x0de1, 0x0e41 }, /* Thai_saraae แ THAI CHARACTER SARA AE */ - { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */ - { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ - { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ - { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ - { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ - { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ - { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */ - { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */ - { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ - { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ - { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ - { 0x0ded, 0x0e4d }, /* Thai_nikhahit ํ THAI CHARACTER NIKHAHIT */ - { 0x0df0, 0x0e50 }, /* Thai_leksun ๐ THAI DIGIT ZERO */ - { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */ - { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */ - { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */ - { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */ - { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */ - { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */ - { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ - { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ - { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */ - { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ - { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ - { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ - { 0x0ea4, 0x3134 }, /* Hangul_Nieun ㄴ HANGUL LETTER NIEUN */ - { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ - { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */ - { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT */ - { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ - { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ - { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ - { 0x0eab, 0x313b }, /* Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM */ - { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ - { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ - { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ - { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH */ - { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH */ - { 0x0eb1, 0x3141 }, /* Hangul_Mieum ㅁ HANGUL LETTER MIEUM */ - { 0x0eb2, 0x3142 }, /* Hangul_Pieub ㅂ HANGUL LETTER PIEUP */ - { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP */ - { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS */ - { 0x0eb5, 0x3145 }, /* Hangul_Sios ㅅ HANGUL LETTER SIOS */ - { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS */ - { 0x0eb7, 0x3147 }, /* Hangul_Ieung ㅇ HANGUL LETTER IEUNG */ - { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ㅈ HANGUL LETTER CIEUC */ - { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC */ - { 0x0eba, 0x314a }, /* Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH */ - { 0x0ebb, 0x314b }, /* Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH */ - { 0x0ebc, 0x314c }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */ - { 0x0ebd, 0x314d }, /* Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH */ - { 0x0ebe, 0x314e }, /* Hangul_Hieuh ㅎ HANGUL LETTER HIEUH */ - { 0x0ebf, 0x314f }, /* Hangul_A ㅏ HANGUL LETTER A */ - { 0x0ec0, 0x3150 }, /* Hangul_AE ㅐ HANGUL LETTER AE */ - { 0x0ec1, 0x3151 }, /* Hangul_YA ㅑ HANGUL LETTER YA */ - { 0x0ec2, 0x3152 }, /* Hangul_YAE ㅒ HANGUL LETTER YAE */ - { 0x0ec3, 0x3153 }, /* Hangul_EO ㅓ HANGUL LETTER EO */ - { 0x0ec4, 0x3154 }, /* Hangul_E ㅔ HANGUL LETTER E */ - { 0x0ec5, 0x3155 }, /* Hangul_YEO ㅕ HANGUL LETTER YEO */ - { 0x0ec6, 0x3156 }, /* Hangul_YE ㅖ HANGUL LETTER YE */ - { 0x0ec7, 0x3157 }, /* Hangul_O ㅗ HANGUL LETTER O */ - { 0x0ec8, 0x3158 }, /* Hangul_WA ㅘ HANGUL LETTER WA */ - { 0x0ec9, 0x3159 }, /* Hangul_WAE ㅙ HANGUL LETTER WAE */ - { 0x0eca, 0x315a }, /* Hangul_OE ㅚ HANGUL LETTER OE */ - { 0x0ecb, 0x315b }, /* Hangul_YO ㅛ HANGUL LETTER YO */ - { 0x0ecc, 0x315c }, /* Hangul_U ㅜ HANGUL LETTER U */ - { 0x0ecd, 0x315d }, /* Hangul_WEO ㅝ HANGUL LETTER WEO */ - { 0x0ece, 0x315e }, /* Hangul_WE ㅞ HANGUL LETTER WE */ - { 0x0ecf, 0x315f }, /* Hangul_WI ㅟ HANGUL LETTER WI */ - { 0x0ed0, 0x3160 }, /* Hangul_YU ㅠ HANGUL LETTER YU */ - { 0x0ed1, 0x3161 }, /* Hangul_EU ㅡ HANGUL LETTER EU */ - { 0x0ed2, 0x3162 }, /* Hangul_YI ㅢ HANGUL LETTER YI */ - { 0x0ed3, 0x3163 }, /* Hangul_I ㅣ HANGUL LETTER I */ - { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ - { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ - { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ - { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ - { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ - { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */ - { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ - { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ - { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ - { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ - { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ - { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ - { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ - { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ - { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ - { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ - { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ - { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ - { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ - { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ - { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ - { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ - { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ - { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ - { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ - { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */ - { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ - { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH */ - { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */ - { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */ - { 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */ -/* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */ - { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ - { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ - { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */ - { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ - { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ -/* 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ??? */ - { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ - { 0x0eff, 0x20a9 }, /* Korean_Won ₩ WON SIGN */ - { 0x13bc, 0x0152 }, /* OE Œ LATIN CAPITAL LIGATURE OE */ - { 0x13bd, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */ - { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ - { 0x20a0, 0x20a0 }, /* EcuSign ₠ EURO-CURRENCY SIGN */ - { 0x20a1, 0x20a1 }, /* ColonSign ₡ COLON SIGN */ - { 0x20a2, 0x20a2 }, /* CruzeiroSign ₢ CRUZEIRO SIGN */ - { 0x20a3, 0x20a3 }, /* FFrancSign ₣ FRENCH FRANC SIGN */ - { 0x20a4, 0x20a4 }, /* LiraSign ₤ LIRA SIGN */ - { 0x20a5, 0x20a5 }, /* MillSign ₥ MILL SIGN */ - { 0x20a6, 0x20a6 }, /* NairaSign ₦ NAIRA SIGN */ - { 0x20a7, 0x20a7 }, /* PesetaSign ₧ PESETA SIGN */ - { 0x20a8, 0x20a8 }, /* RupeeSign ₨ RUPEE SIGN */ - { 0x20a9, 0x20a9 }, /* WonSign ₩ WON SIGN */ - { 0x20aa, 0x20aa }, /* NewSheqelSign ₪ NEW SHEQEL SIGN */ - { 0x20ab, 0x20ab }, /* DongSign ₫ DONG SIGN */ - { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */ - - - /* Following items added to GTK, not in the xterm table */ - - /* Numeric keypad */ - - { 0xFF80 /* Space */, ' ' }, - { 0xFFAA /* Multiply */, '*' }, - { 0xFFAB /* Add */, '+' }, - { 0xFFAC /* Separator */, ',' }, - { 0xFFAD /* Subtract */, '-' }, - { 0xFFAE /* Decimal */, '.' }, - { 0xFFAF /* Divide */, '/' }, - { 0xFFB0 /* 0 */, '0' }, - { 0xFFB1 /* 1 */, '1' }, - { 0xFFB2 /* 2 */, '2' }, - { 0xFFB3 /* 3 */, '3' }, - { 0xFFB4 /* 4 */, '4' }, - { 0xFFB5 /* 5 */, '5' }, - { 0xFFB6 /* 6 */, '6' }, - { 0xFFB7 /* 7 */, '7' }, - { 0xFFB8 /* 8 */, '8' }, - { 0xFFB9 /* 9 */, '9' }, - { 0xFFBD /* Equal */, '=' }, - - /* End numeric keypad */ -}; - -static const int clutter_keysym_to_unicode_tab_size = - G_N_ELEMENTS (clutter_keysym_to_unicode_tab); - -/** - * clutter_keysym_to_unicode: - * @keyval: a key symbol - * - * Converts @keyval from a Clutter key symbol to the corresponding - * ISO10646 (Unicode) character. - * - * Return value: a Unicode character, or 0 if there is no corresponding - * character. - */ -guint32 -clutter_keysym_to_unicode (guint keyval) -{ - int min = 0; - int max = clutter_keysym_to_unicode_tab_size - 1; - int mid; - - /* First check for Latin-1 characters (1:1 mapping) */ - if ((keyval >= 0x0020 && keyval <= 0x007e) || - (keyval >= 0x00a0 && keyval <= 0x00ff)) - return keyval; - - /* Also check for directly encoded 24-bit UCS characters: */ - if ((keyval & 0xff000000) == 0x01000000) - return keyval & 0x00ffffff; - - /* binary search in table */ - while (max >= min) - { - mid = (min + max) / 2; - - if (clutter_keysym_to_unicode_tab[mid].keysym < keyval) - min = mid + 1; - else if (clutter_keysym_to_unicode_tab[mid].keysym > keyval) - max = mid - 1; - else - { - /* found it */ - return clutter_keysym_to_unicode_tab[mid].ucs; - } - } - - /* No matching Unicode value found */ - return 0; -} - -static const struct { - unsigned short keysym; - unsigned short ucs; -} clutter_unicode_to_keysym_tab[] = { - { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */ - { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */ - { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */ - { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */ - { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */ - { 0x03c0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */ - { 0x03e0, 0x0101 }, /* amacron ā LATIN SMALL LETTER A WITH MACRON */ - { 0x01c3, 0x0102 }, /* Abreve Ă LATIN CAPITAL LETTER A WITH BREVE */ - { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ - { 0x01a1, 0x0104 }, /* Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */ - { 0x01b1, 0x0105 }, /* aogonek ą LATIN SMALL LETTER A WITH OGONEK */ - { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ - { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ - { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ - { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ - { 0x02c5, 0x010a }, /* Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE */ - { 0x02e5, 0x010b }, /* cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE */ - { 0x01c8, 0x010c }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */ - { 0x01e8, 0x010d }, /* ccaron č LATIN SMALL LETTER C WITH CARON */ - { 0x01cf, 0x010e }, /* Dcaron Ď LATIN CAPITAL LETTER D WITH CARON */ - { 0x01ef, 0x010f }, /* dcaron ď LATIN SMALL LETTER D WITH CARON */ - { 0x01d0, 0x0110 }, /* Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE */ - { 0x01f0, 0x0111 }, /* dstroke đ LATIN SMALL LETTER D WITH STROKE */ - { 0x03aa, 0x0112 }, /* Emacron Ē LATIN CAPITAL LETTER E WITH MACRON */ - { 0x03ba, 0x0113 }, /* emacron ē LATIN SMALL LETTER E WITH MACRON */ - { 0x03cc, 0x0116 }, /* Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE */ - { 0x03ec, 0x0117 }, /* eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE */ - { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ - { 0x01ea, 0x0119 }, /* eogonek ę LATIN SMALL LETTER E WITH OGONEK */ - { 0x01cc, 0x011a }, /* Ecaron Ě LATIN CAPITAL LETTER E WITH CARON */ - { 0x01ec, 0x011b }, /* ecaron ě LATIN SMALL LETTER E WITH CARON */ - { 0x02d8, 0x011c }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ - { 0x02f8, 0x011d }, /* gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX */ - { 0x02ab, 0x011e }, /* Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE */ - { 0x02bb, 0x011f }, /* gbreve ğ LATIN SMALL LETTER G WITH BREVE */ - { 0x02d5, 0x0120 }, /* Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE */ - { 0x02f5, 0x0121 }, /* gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE */ - { 0x03ab, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */ - { 0x03bb, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */ - { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ - { 0x02b6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ - { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ - { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ - { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ - { 0x03b5, 0x0129 }, /* itilde ĩ LATIN SMALL LETTER I WITH TILDE */ - { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ - { 0x03ef, 0x012b }, /* imacron ī LATIN SMALL LETTER I WITH MACRON */ - { 0x03c7, 0x012e }, /* Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK */ - { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ - { 0x02a9, 0x0130 }, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */ - { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */ - { 0x02ac, 0x0134 }, /* Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ - { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ - { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ - { 0x03f3, 0x0137 }, /* kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA */ - { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */ - { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ - { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ - { 0x03a6, 0x013b }, /* Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA */ - { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ - { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ - { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ - { 0x01a3, 0x0141 }, /* Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE */ - { 0x01b3, 0x0142 }, /* lstroke ł LATIN SMALL LETTER L WITH STROKE */ - { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ - { 0x01f1, 0x0144 }, /* nacute ń LATIN SMALL LETTER N WITH ACUTE */ - { 0x03d1, 0x0145 }, /* Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA */ - { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ - { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ - { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ - { 0x03bd, 0x014a }, /* ENG Ŋ LATIN CAPITAL LETTER ENG */ - { 0x03bf, 0x014b }, /* eng ŋ LATIN SMALL LETTER ENG */ - { 0x03d2, 0x014c }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */ - { 0x03f2, 0x014d }, /* omacron ō LATIN SMALL LETTER O WITH MACRON */ - { 0x01d5, 0x0150 }, /* Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ - { 0x01f5, 0x0151 }, /* odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE */ - { 0x13bc, 0x0152 }, /* OE Œ LATIN CAPITAL LIGATURE OE */ - { 0x13bd, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */ - { 0x01c0, 0x0154 }, /* Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE */ - { 0x01e0, 0x0155 }, /* racute ŕ LATIN SMALL LETTER R WITH ACUTE */ - { 0x03a3, 0x0156 }, /* Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA */ - { 0x03b3, 0x0157 }, /* rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA */ - { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ - { 0x01f8, 0x0159 }, /* rcaron ř LATIN SMALL LETTER R WITH CARON */ - { 0x01a6, 0x015a }, /* Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE */ - { 0x01b6, 0x015b }, /* sacute ś LATIN SMALL LETTER S WITH ACUTE */ - { 0x02de, 0x015c }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ - { 0x02fe, 0x015d }, /* scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX */ - { 0x01aa, 0x015e }, /* Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA */ - { 0x01ba, 0x015f }, /* scedilla ş LATIN SMALL LETTER S WITH CEDILLA */ - { 0x01a9, 0x0160 }, /* Scaron Š LATIN CAPITAL LETTER S WITH CARON */ - { 0x01b9, 0x0161 }, /* scaron š LATIN SMALL LETTER S WITH CARON */ - { 0x01de, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */ - { 0x01fe, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */ - { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ - { 0x01bb, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */ - { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ - { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ - { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ - { 0x03fd, 0x0169 }, /* utilde ũ LATIN SMALL LETTER U WITH TILDE */ - { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ - { 0x03fe, 0x016b }, /* umacron ū LATIN SMALL LETTER U WITH MACRON */ - { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ - { 0x02fd, 0x016d }, /* ubreve ŭ LATIN SMALL LETTER U WITH BREVE */ - { 0x01d9, 0x016e }, /* Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE */ - { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ - { 0x01db, 0x0170 }, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ - { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ - { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ - { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ - { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ - { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ - { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ - { 0x01af, 0x017b }, /* Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE */ - { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ - { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ - { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ - { 0x08f6, 0x0192 }, /* function ƒ LATIN SMALL LETTER F WITH HOOK */ - { 0x01b7, 0x02c7 }, /* caron ˇ CARON */ - { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */ - { 0x01ff, 0x02d9 }, /* abovedot ˙ DOT ABOVE */ - { 0x01b2, 0x02db }, /* ogonek ˛ OGONEK */ - { 0x01bd, 0x02dd }, /* doubleacute ˝ DOUBLE ACUTE ACCENT */ - { 0x07ae, 0x0385 }, /* Greek_accentdieresis ΅ GREEK DIALYTIKA TONOS */ - { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ - { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ - { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ - { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ - { 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */ - { 0x07a8, 0x038e }, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */ - { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS */ - { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ - { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ - { 0x07c2, 0x0392 }, /* Greek_BETA Β GREEK CAPITAL LETTER BETA */ - { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ - { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ - { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ - { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ - { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ - { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ - { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ - { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ - { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */ - { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */ - { 0x07cd, 0x039d }, /* Greek_NU Ν GREEK CAPITAL LETTER NU */ - { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ - { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ - { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */ - { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ - { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ - { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ - { 0x07d5, 0x03a5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */ - { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ - { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ - { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ - { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ - { 0x07a5, 0x03aa }, /* Greek_IOTAdieresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ - { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ - { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ - { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */ - { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ - { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ - { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ - { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ - { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */ - { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ - { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */ - { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ - { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ - { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */ - { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */ - { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */ - { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ - { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */ - { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */ - { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */ - { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */ - { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ - { 0x07f0, 0x03c0 }, /* Greek_pi π GREEK SMALL LETTER PI */ - { 0x07f1, 0x03c1 }, /* Greek_rho ρ GREEK SMALL LETTER RHO */ - { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA */ - { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ - { 0x07f4, 0x03c4 }, /* Greek_tau τ GREEK SMALL LETTER TAU */ - { 0x07f5, 0x03c5 }, /* Greek_upsilon υ GREEK SMALL LETTER UPSILON */ - { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */ - { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */ - { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */ - { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ - { 0x07b5, 0x03ca }, /* Greek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ - { 0x07b9, 0x03cb }, /* Greek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ - { 0x07b7, 0x03cc }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */ - { 0x07b8, 0x03cd }, /* Greek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS */ - { 0x07bb, 0x03ce }, /* Greek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS */ - { 0x06b3, 0x0401 }, /* Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO */ - { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ - { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ - { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ - { 0x06b5, 0x0405 }, /* Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE */ - { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ - { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ - { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ - { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ - { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ - { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ - { 0x06bc, 0x040c }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */ - { 0x06be, 0x040e }, /* Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U */ - { 0x06bf, 0x040f }, /* Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE */ - { 0x06e1, 0x0410 }, /* Cyrillic_A А CYRILLIC CAPITAL LETTER A */ - { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ - { 0x06f7, 0x0412 }, /* Cyrillic_VE В CYRILLIC CAPITAL LETTER VE */ - { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ - { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ - { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ - { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ - { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ - { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ - { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ - { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ - { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ - { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */ - { 0x06ee, 0x041d }, /* Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN */ - { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ - { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ - { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */ - { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ - { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ - { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ - { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ - { 0x06e8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */ - { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ - { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ - { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ - { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ - { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ - { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ - { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ - { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */ - { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ - { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ - { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ - { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ - { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ - { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ - { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ - { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ - { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ - { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ - { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ - { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ - { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ - { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ - { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ - { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ - { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ - { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ - { 0x06d2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */ - { 0x06d3, 0x0441 }, /* Cyrillic_es с CYRILLIC SMALL LETTER ES */ - { 0x06d4, 0x0442 }, /* Cyrillic_te т CYRILLIC SMALL LETTER TE */ - { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ - { 0x06c6, 0x0444 }, /* Cyrillic_ef ф CYRILLIC SMALL LETTER EF */ - { 0x06c8, 0x0445 }, /* Cyrillic_ha х CYRILLIC SMALL LETTER HA */ - { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ - { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ - { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ - { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ - { 0x06df, 0x044a }, /* Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN */ - { 0x06d9, 0x044b }, /* Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU */ - { 0x06d8, 0x044c }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */ - { 0x06dc, 0x044d }, /* Cyrillic_e э CYRILLIC SMALL LETTER E */ - { 0x06c0, 0x044e }, /* Cyrillic_yu ю CYRILLIC SMALL LETTER YU */ - { 0x06d1, 0x044f }, /* Cyrillic_ya я CYRILLIC SMALL LETTER YA */ - { 0x06a3, 0x0451 }, /* Cyrillic_io ё CYRILLIC SMALL LETTER IO */ - { 0x06a1, 0x0452 }, /* Serbian_dje ђ CYRILLIC SMALL LETTER DJE */ - { 0x06a2, 0x0453 }, /* Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE */ - { 0x06a4, 0x0454 }, /* Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE */ - { 0x06a5, 0x0455 }, /* Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE */ - { 0x06a6, 0x0456 }, /* Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ - { 0x06a7, 0x0457 }, /* Ukrainian_yi ї CYRILLIC SMALL LETTER YI */ - { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ - { 0x06a9, 0x0459 }, /* Cyrillic_lje љ CYRILLIC SMALL LETTER LJE */ - { 0x06aa, 0x045a }, /* Cyrillic_nje њ CYRILLIC SMALL LETTER NJE */ - { 0x06ab, 0x045b }, /* Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE */ - { 0x06ac, 0x045c }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */ - { 0x06ae, 0x045e }, /* Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U */ - { 0x06af, 0x045f }, /* Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE */ - { 0x0ce0, 0x05d0 }, /* hebrew_aleph א HEBREW LETTER ALEF */ - { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */ - { 0x0ce2, 0x05d2 }, /* hebrew_gimel ג HEBREW LETTER GIMEL */ - { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */ - { 0x0ce4, 0x05d4 }, /* hebrew_he ה HEBREW LETTER HE */ - { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */ - { 0x0ce6, 0x05d6 }, /* hebrew_zain ז HEBREW LETTER ZAYIN */ - { 0x0ce7, 0x05d7 }, /* hebrew_chet ח HEBREW LETTER HET */ - { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */ - { 0x0ce9, 0x05d9 }, /* hebrew_yod י HEBREW LETTER YOD */ - { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ - { 0x0ceb, 0x05db }, /* hebrew_kaph כ HEBREW LETTER KAF */ - { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */ - { 0x0ced, 0x05dd }, /* hebrew_finalmem ם HEBREW LETTER FINAL MEM */ - { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */ - { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ - { 0x0cf0, 0x05e0 }, /* hebrew_nun נ HEBREW LETTER NUN */ - { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */ - { 0x0cf2, 0x05e2 }, /* hebrew_ayin ע HEBREW LETTER AYIN */ - { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ף HEBREW LETTER FINAL PE */ - { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */ - { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ץ HEBREW LETTER FINAL TSADI */ - { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */ - { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */ - { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */ - { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */ - { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */ - { 0x05ac, 0x060c }, /* Arabic_comma ، ARABIC COMMA */ - { 0x05bb, 0x061b }, /* Arabic_semicolon ؛ ARABIC SEMICOLON */ - { 0x05bf, 0x061f }, /* Arabic_question_mark ؟ ARABIC QUESTION MARK */ - { 0x05c1, 0x0621 }, /* Arabic_hamza ء ARABIC LETTER HAMZA */ - { 0x05c2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */ - { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */ - { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ - { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */ - { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ - { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */ - { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */ - { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA */ - { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */ - { 0x05cb, 0x062b }, /* Arabic_theh ث ARABIC LETTER THEH */ - { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */ - { 0x05cd, 0x062d }, /* Arabic_hah ح ARABIC LETTER HAH */ - { 0x05ce, 0x062e }, /* Arabic_khah خ ARABIC LETTER KHAH */ - { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */ - { 0x05d0, 0x0630 }, /* Arabic_thal ذ ARABIC LETTER THAL */ - { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */ - { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */ - { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */ - { 0x05d4, 0x0634 }, /* Arabic_sheen ش ARABIC LETTER SHEEN */ - { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */ - { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */ - { 0x05d7, 0x0637 }, /* Arabic_tah ط ARABIC LETTER TAH */ - { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */ - { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */ - { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */ - { 0x05e0, 0x0640 }, /* Arabic_tatweel ـ ARABIC TATWEEL */ - { 0x05e1, 0x0641 }, /* Arabic_feh ف ARABIC LETTER FEH */ - { 0x05e2, 0x0642 }, /* Arabic_qaf ق ARABIC LETTER QAF */ - { 0x05e3, 0x0643 }, /* Arabic_kaf ك ARABIC LETTER KAF */ - { 0x05e4, 0x0644 }, /* Arabic_lam ل ARABIC LETTER LAM */ - { 0x05e5, 0x0645 }, /* Arabic_meem م ARABIC LETTER MEEM */ - { 0x05e6, 0x0646 }, /* Arabic_noon ن ARABIC LETTER NOON */ - { 0x05e7, 0x0647 }, /* Arabic_ha ه ARABIC LETTER HEH */ - { 0x05e8, 0x0648 }, /* Arabic_waw و ARABIC LETTER WAW */ - { 0x05e9, 0x0649 }, /* Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA */ - { 0x05ea, 0x064a }, /* Arabic_yeh ي ARABIC LETTER YEH */ - { 0x05eb, 0x064b }, /* Arabic_fathatan ً ARABIC FATHATAN */ - { 0x05ec, 0x064c }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */ - { 0x05ed, 0x064d }, /* Arabic_kasratan ٍ ARABIC KASRATAN */ - { 0x05ee, 0x064e }, /* Arabic_fatha َ ARABIC FATHA */ - { 0x05ef, 0x064f }, /* Arabic_damma ُ ARABIC DAMMA */ - { 0x05f0, 0x0650 }, /* Arabic_kasra ِ ARABIC KASRA */ - { 0x05f1, 0x0651 }, /* Arabic_shadda ّ ARABIC SHADDA */ - { 0x05f2, 0x0652 }, /* Arabic_sukun ْ ARABIC SUKUN */ - { 0x0da1, 0x0e01 }, /* Thai_kokai ก THAI CHARACTER KO KAI */ - { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ - { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ - { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ - { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ - { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ - { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ - { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ - { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ - { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ - { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */ - { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ - { 0x0dad, 0x0e0d }, /* Thai_yoying ญ THAI CHARACTER YO YING */ - { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ - { 0x0daf, 0x0e0f }, /* Thai_topatak ฏ THAI CHARACTER TO PATAK */ - { 0x0db0, 0x0e10 }, /* Thai_thothan ฐ THAI CHARACTER THO THAN */ - { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ - { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ - { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */ - { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */ - { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */ - { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ - { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ - { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */ - { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */ - { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ - { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */ - { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ - { 0x0dbd, 0x0e1d }, /* Thai_fofa ฝ THAI CHARACTER FO FA */ - { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ - { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ - { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */ - { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */ - { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */ - { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */ - { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */ - { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */ - { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */ - { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ - { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */ - { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ - { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */ - { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */ - { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ - { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */ - { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ - { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ - { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */ - { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ - { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */ - { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */ - { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */ - { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */ - { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */ - { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ - { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */ - { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */ - { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ - { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ - { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */ - { 0x0de1, 0x0e41 }, /* Thai_saraae แ THAI CHARACTER SARA AE */ - { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */ - { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ - { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ - { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ - { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ - { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ - { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */ - { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */ - { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ - { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ - { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ - { 0x0ded, 0x0e4d }, /* Thai_nikhahit ํ THAI CHARACTER NIKHAHIT */ - { 0x0df0, 0x0e50 }, /* Thai_leksun ๐ THAI DIGIT ZERO */ - { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */ - { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */ - { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */ - { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */ - { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */ - { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */ - { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ - { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ - { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */ - { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ - { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ - { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ - { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ - { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ - { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */ - { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ - { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ - { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ - { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ - { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ - { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ - { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ - { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ - { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ - { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ - { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ - { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ - { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ - { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ - { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ - { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ - { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ - { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ - { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ - { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */ - { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ - { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ - { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ - { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */ - { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */ - { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */ - { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */ - { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */ - { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */ - { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */ - { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */ - { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */ - { 0x0aaa, 0x2013 }, /* endash – EN DASH */ - { 0x0aa9, 0x2014 }, /* emdash — EM DASH */ - { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */ - { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ - { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ - { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ - { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ - { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ - { 0x0ad3, 0x201d }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */ - { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ - { 0x0af1, 0x2020 }, /* dagger † DAGGER */ - { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */ - { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */ - { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */ - { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */ - { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */ - { 0x0afc, 0x2038 }, /* caret ‸ CARET */ - { 0x047e, 0x203e }, /* overline ‾ OVERLINE */ - { 0x20a0, 0x20a0 }, /* EcuSign ₠ EURO-CURRENCY SIGN */ - { 0x20a1, 0x20a1 }, /* ColonSign ₡ COLON SIGN */ - { 0x20a2, 0x20a2 }, /* CruzeiroSign ₢ CRUZEIRO SIGN */ - { 0x20a3, 0x20a3 }, /* FFrancSign ₣ FRENCH FRANC SIGN */ - { 0x20a4, 0x20a4 }, /* LiraSign ₤ LIRA SIGN */ - { 0x20a5, 0x20a5 }, /* MillSign ₥ MILL SIGN */ - { 0x20a6, 0x20a6 }, /* NairaSign ₦ NAIRA SIGN */ - { 0x20a7, 0x20a7 }, /* PesetaSign ₧ PESETA SIGN */ - { 0x20a8, 0x20a8 }, /* RupeeSign ₨ RUPEE SIGN */ - { 0x0eff, 0x20a9 }, /* Korean_Won ₩ WON SIGN */ - { 0x20a9, 0x20a9 }, /* WonSign ₩ WON SIGN */ - { 0x20aa, 0x20aa }, /* NewSheqelSign ₪ NEW SHEQEL SIGN */ - { 0x20ab, 0x20ab }, /* DongSign ₫ DONG SIGN */ - { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */ - { 0x0ab8, 0x2105 }, /* careof ℅ CARE OF */ - { 0x06b0, 0x2116 }, /* numerosign № NUMERO SIGN */ - { 0x0afb, 0x2117 }, /* phonographcopyright ℗ SOUND RECORDING COPYRIGHT */ - { 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */ - { 0x0ac9, 0x2122 }, /* trademark ™ TRADE MARK SIGN */ - { 0x0ab0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */ - { 0x0ab1, 0x2154 }, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */ - { 0x0ab2, 0x2155 }, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */ - { 0x0ab3, 0x2156 }, /* twofifths ⅖ VULGAR FRACTION TWO FIFTHS */ - { 0x0ab4, 0x2157 }, /* threefifths ⅗ VULGAR FRACTION THREE FIFTHS */ - { 0x0ab5, 0x2158 }, /* fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS */ - { 0x0ab6, 0x2159 }, /* onesixth ⅙ VULGAR FRACTION ONE SIXTH */ - { 0x0ab7, 0x215a }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */ - { 0x0ac3, 0x215b }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */ - { 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */ - { 0x0ac5, 0x215d }, /* fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS */ - { 0x0ac6, 0x215e }, /* seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS */ - { 0x08fb, 0x2190 }, /* leftarrow ← LEFTWARDS ARROW */ - { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */ - { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */ - { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */ - { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ - { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ - { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ - { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */ - { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */ - { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */ - { 0x08c1, 0x221d }, /* variation ∝ PROPORTIONAL TO */ - { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */ - { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */ - { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */ - { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */ - { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */ - { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */ - { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */ - { 0x08dd, 0x222a }, /* union ∪ UNION */ - { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */ - { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */ - { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */ - { 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */ - { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */ - { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */ - { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ - { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ - { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */ - { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */ - { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */ - { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */ - { 0x0bfc, 0x22a2 }, /* righttack ⊢ RIGHT TACK */ - { 0x0bdc, 0x22a3 }, /* lefttack ⊣ LEFT TACK */ - { 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */ - { 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */ - { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */ - { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */ - { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */ - { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */ - { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ - { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */ - { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */ - { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */ - { 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */ - { 0x09e5, 0x240a }, /* lf ␊ SYMBOL FOR LINE FEED */ - { 0x09e9, 0x240b }, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */ - { 0x09e3, 0x240c }, /* ff ␌ SYMBOL FOR FORM FEED */ - { 0x09e4, 0x240d }, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */ - { 0x09df, 0x2422 }, /* blank ␢ BLANK SYMBOL */ - { 0x09e8, 0x2424 }, /* nl ␤ SYMBOL FOR NEWLINE */ - { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ - { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ - { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ - { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ - { 0x09eb, 0x2510 }, /* uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */ - { 0x09ed, 0x2514 }, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */ - { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ - { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ - { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ - { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ - { 0x09f6, 0x2534 }, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ - { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ - { 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */ - { 0x0adf, 0x25a0 }, /* emfilledrect ■ BLACK SQUARE */ - { 0x0acf, 0x25a1 }, /* emopenrectangle □ WHITE SQUARE */ - { 0x0ae7, 0x25aa }, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */ - { 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */ - { 0x0adb, 0x25ac }, /* filledrectbullet ▬ BLACK RECTANGLE */ - { 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */ - { 0x0ae8, 0x25b2 }, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */ - { 0x0ae3, 0x25b3 }, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */ - { 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */ - { 0x0acd, 0x25b7 }, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */ - { 0x0ae9, 0x25bc }, /* filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE */ - { 0x0ae4, 0x25bd }, /* opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE */ - { 0x0adc, 0x25c0 }, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */ - { 0x0acc, 0x25c1 }, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */ - { 0x09e0, 0x25c6 }, /* soliddiamond ◆ BLACK DIAMOND */ - { 0x0ace, 0x25cb }, /* emopencircle ○ WHITE CIRCLE */ - { 0x0bcf, 0x25cb }, /* circle ○ WHITE CIRCLE */ - { 0x0ade, 0x25cf }, /* emfilledcircle ● BLACK CIRCLE */ - { 0x0ae0, 0x25e6 }, /* enopencircbullet ◦ WHITE BULLET */ - { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */ - { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */ - { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */ - { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ - { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ - { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */ - { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */ - { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */ - { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */ - { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */ - { 0x0af6, 0x266d }, /* musicalflat ♭ MUSIC FLAT SIGN */ - { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */ - { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */ - { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */ - { 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */ - { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */ - { 0x04a4, 0x3001 }, /* kana_comma 、 IDEOGRAPHIC COMMA */ - { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ - { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */ - { 0x04a3, 0x300d }, /* kana_closingbracket 」 RIGHT CORNER BRACKET */ - { 0x04de, 0x309b }, /* voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK */ - { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ - { 0x04a7, 0x30a1 }, /* kana_a ァ KATAKANA LETTER SMALL A */ - { 0x04b1, 0x30a2 }, /* kana_A ア KATAKANA LETTER A */ - { 0x04a8, 0x30a3 }, /* kana_i ィ KATAKANA LETTER SMALL I */ - { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */ - { 0x04a9, 0x30a5 }, /* kana_u ゥ KATAKANA LETTER SMALL U */ - { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */ - { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */ - { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */ - { 0x04ab, 0x30a9 }, /* kana_o ォ KATAKANA LETTER SMALL O */ - { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */ - { 0x04b6, 0x30ab }, /* kana_KA カ KATAKANA LETTER KA */ - { 0x04b7, 0x30ad }, /* kana_KI キ KATAKANA LETTER KI */ - { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */ - { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */ - { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */ - { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */ - { 0x04bc, 0x30b7 }, /* kana_SHI シ KATAKANA LETTER SI */ - { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */ - { 0x04be, 0x30bb }, /* kana_SE セ KATAKANA LETTER SE */ - { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */ - { 0x04c0, 0x30bf }, /* kana_TA タ KATAKANA LETTER TA */ - { 0x04c1, 0x30c1 }, /* kana_CHI チ KATAKANA LETTER TI */ - { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ - { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */ - { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */ - { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */ - { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */ - { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */ - { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */ - { 0x04c8, 0x30cd }, /* kana_NE ネ KATAKANA LETTER NE */ - { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */ - { 0x04ca, 0x30cf }, /* kana_HA ハ KATAKANA LETTER HA */ - { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */ - { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */ - { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */ - { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */ - { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */ - { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */ - { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */ - { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */ - { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */ - { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */ - { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */ - { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */ - { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */ - { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */ - { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */ - { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */ - { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */ - { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */ - { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */ - { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */ - { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */ - { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */ - { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */ - { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ - { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ - { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ - { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ - { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ - { 0x0ea4, 0x3134 }, /* Hangul_Nieun ㄴ HANGUL LETTER NIEUN */ - { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ - { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */ - { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT */ - { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ - { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ - { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ - { 0x0eab, 0x313b }, /* Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM */ - { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ - { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ - { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ - { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH */ - { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH */ - { 0x0eb1, 0x3141 }, /* Hangul_Mieum ㅁ HANGUL LETTER MIEUM */ - { 0x0eb2, 0x3142 }, /* Hangul_Pieub ㅂ HANGUL LETTER PIEUP */ - { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP */ - { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS */ - { 0x0eb5, 0x3145 }, /* Hangul_Sios ㅅ HANGUL LETTER SIOS */ - { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS */ - { 0x0eb7, 0x3147 }, /* Hangul_Ieung ㅇ HANGUL LETTER IEUNG */ - { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ㅈ HANGUL LETTER CIEUC */ - { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC */ - { 0x0eba, 0x314a }, /* Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH */ - { 0x0ebb, 0x314b }, /* Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH */ - { 0x0ebc, 0x314c }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */ - { 0x0ebd, 0x314d }, /* Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH */ - { 0x0ebe, 0x314e }, /* Hangul_Hieuh ㅎ HANGUL LETTER HIEUH */ - { 0x0ebf, 0x314f }, /* Hangul_A ㅏ HANGUL LETTER A */ - { 0x0ec0, 0x3150 }, /* Hangul_AE ㅐ HANGUL LETTER AE */ - { 0x0ec1, 0x3151 }, /* Hangul_YA ㅑ HANGUL LETTER YA */ - { 0x0ec2, 0x3152 }, /* Hangul_YAE ㅒ HANGUL LETTER YAE */ - { 0x0ec3, 0x3153 }, /* Hangul_EO ㅓ HANGUL LETTER EO */ - { 0x0ec4, 0x3154 }, /* Hangul_E ㅔ HANGUL LETTER E */ - { 0x0ec5, 0x3155 }, /* Hangul_YEO ㅕ HANGUL LETTER YEO */ - { 0x0ec6, 0x3156 }, /* Hangul_YE ㅖ HANGUL LETTER YE */ - { 0x0ec7, 0x3157 }, /* Hangul_O ㅗ HANGUL LETTER O */ - { 0x0ec8, 0x3158 }, /* Hangul_WA ㅘ HANGUL LETTER WA */ - { 0x0ec9, 0x3159 }, /* Hangul_WAE ㅙ HANGUL LETTER WAE */ - { 0x0eca, 0x315a }, /* Hangul_OE ㅚ HANGUL LETTER OE */ - { 0x0ecb, 0x315b }, /* Hangul_YO ㅛ HANGUL LETTER YO */ - { 0x0ecc, 0x315c }, /* Hangul_U ㅜ HANGUL LETTER U */ - { 0x0ecd, 0x315d }, /* Hangul_WEO ㅝ HANGUL LETTER WEO */ - { 0x0ece, 0x315e }, /* Hangul_WE ㅞ HANGUL LETTER WE */ - { 0x0ecf, 0x315f }, /* Hangul_WI ㅟ HANGUL LETTER WI */ - { 0x0ed0, 0x3160 }, /* Hangul_YU ㅠ HANGUL LETTER YU */ - { 0x0ed1, 0x3161 }, /* Hangul_EU ㅡ HANGUL LETTER EU */ - { 0x0ed2, 0x3162 }, /* Hangul_YI ㅢ HANGUL LETTER YI */ - { 0x0ed3, 0x3163 }, /* Hangul_I ㅣ HANGUL LETTER I */ - { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH */ - { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */ - { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */ - { 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */ - { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ - { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ - { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */ - { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ -}; - -static const int clutter_unicode_to_keysym_tab_size = - G_N_ELEMENTS (clutter_unicode_to_keysym_tab); - -/** - * clutter_unicode_to_keysym: - * @wc: a ISO10646 encoded character - * - * Convert from a ISO10646 character to a key symbol. - * - * Return value: the corresponding Clutter key symbol, if one exists. - * or, if there is no corresponding symbol, wc | 0x01000000 - */ -guint -clutter_unicode_to_keysym (guint32 wc) -{ - int min = 0; - int max = clutter_unicode_to_keysym_tab_size - 1; - int mid; - - /* First check for Latin-1 characters (1:1 mapping) */ - if ((wc >= 0x0020 && wc <= 0x007e) || - (wc >= 0x00a0 && wc <= 0x00ff)) - return wc; - - /* Binary search in table */ - while (max >= min) - { - mid = (min + max) / 2; - - if (clutter_unicode_to_keysym_tab[mid].ucs < wc) - min = mid + 1; - else if (clutter_unicode_to_keysym_tab[mid].ucs > wc) - max = mid - 1; - else - { - /* found it */ - return clutter_unicode_to_keysym_tab[mid].keysym; - } - } - - /* No matching keysym value found, return Unicode value plus 0x01000000 - * (a convention introduced in the UTF-8 work on xterm). - */ - return wc | 0x01000000; -} diff --git a/mutter/clutter/clutter/clutter-keysyms-update.pl b/mutter/clutter/clutter/clutter-keysyms-update.pl deleted file mode 100755 index 13e8df2..0000000 --- a/mutter/clutter/clutter/clutter-keysyms-update.pl +++ /dev/null @@ -1,173 +0,0 @@ -#!/usr/bin/env perl - -# Author : Simos Xenitellis . -# Author : Bastien Nocera -# Version : 1.2 -# -# Notes : It downloads keysymdef.h from the Internet, if not found locally, -# Notes : and creates an updated clutter-keysyms.h - -use strict; - -my $update_url = 'http://git.clutter-project.org/clutter/plain/clutter/clutter-keysyms-update.pl'; - -# Used for reading the keysymdef symbols. -my @keysymelements; - -my $keysymdef_url = 'http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h'; - -if ( ! -f "keysymdef.h" ) -{ - print "Trying to download keysymdef.h from\n", $keysymdef_url, "\n"; - die "Unable to download keysymdef.h: $!" - unless system("wget -c -O keysymdef.h \"$keysymdef_url\"") == 0; - print " done.\n\n"; -} -else -{ - print "We are using existing keysymdef.h found in this directory.\n"; - print "It is assumed that you took care and it is a recent version\n"; -} - -my $XF86keysym_url = 'http://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h'; - -if ( ! -f "XF86keysym.h" ) -{ - print "Trying to download XF86keysym.h from\n", $XF86keysym_url, "\n"; - die "Unable to download keysymdef.h: $!\n" - unless system("wget -c -O XF86keysym.h \"$XF86keysym_url\"") == 0; - print " done.\n\n"; -} -else -{ - print "We are using existing XF86keysym.h found in this directory.\n"; - print "It is assumed that you took care and it is a recent version\n"; -} - -if ( -f "clutter-keysyms.h" ) -{ - print "There is already a clutter-keysyms.h file in this directory. We are not overwriting it.\n"; - print "Please move it somewhere else in order to run this script.\n"; - die "Exiting...\n\n"; -} - -die "Could not open file keysymdef.h: $!\n" - unless open(IN_KEYSYMDEF, "<:utf8", "keysymdef.h"); - -# Output: clutter/clutter/clutter-keysyms.h -die "Could not open file clutter-keysyms.h: $!\n" - unless open(OUT_KEYSYMS, ">:utf8", "clutter-keysyms.h"); - -my $LICENSE_HEADER= <. - */ - -EOF - -print OUT_KEYSYMS $LICENSE_HEADER; - -print OUT_KEYSYMS<) -{ - next if ( ! /^#define / ); - - @keysymelements = split(/\s+/); - die "Internal error, no \@keysymelements: $_\n" unless @keysymelements; - - $_ = $keysymelements[1]; - die "Internal error, was expecting \"XC_*\", found: $_\n" if ( ! /^XK_/ ); - - $_ = $keysymelements[2]; - die "Internal error, was expecting \"0x*\", found: $_\n" if ( ! /^0x/ ); - - my $element = $keysymelements[1]; - my $binding = $element; - $binding =~ s/^XK_/CLUTTER_KEY_/g; - - printf OUT_KEYSYMS "#define %s 0x%03x\n", $binding, hex($keysymelements[2]); -} - -close IN_KEYSYMDEF; - -#$cluttersyms{"0"} = "0000"; - -# Source: http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob;f=XF86keysym.h -die "Could not open file XF86keysym.h: $!\n" unless open(IN_XF86KEYSYM, "<:utf8", "XF86keysym.h"); - -while () -{ - next if ( ! /^#define / ); - - @keysymelements = split(/\s+/); - die "Internal error, no \@keysymelements: $_\n" unless @keysymelements; - - $_ = $keysymelements[1]; - die "Internal error, was expecting \"XF86XK_*\", found: $_\n" if ( ! /^XF86XK_/ ); - - # Work-around https://bugs.freedesktop.org/show_bug.cgi?id=11193 - if ($_ eq "XF86XK_XF86BackForward") { - $keysymelements[1] = "XF86XK_AudioForward"; - } - # XF86XK_Clear could end up a dupe of XK_Clear - # XF86XK_Select could end up a dupe of XK_Select - if ($_ eq "XF86XK_Clear") { - $keysymelements[1] = "XF86XK_WindowClear"; - } - if ($_ eq "XF86XK_Select") { - $keysymelements[1] = "XF86XK_SelectButton"; - } - - # Ignore XF86XK_Q - next if ( $_ eq "XF86XK_Q"); - # XF86XK_Calculater is misspelled, and a dupe - next if ( $_ eq "XF86XK_Calculater"); - - $_ = $keysymelements[2]; - die "Internal error, was expecting \"0x*\", found: $_\n" if ( ! /^0x/ ); - - my $element = $keysymelements[1]; - my $binding = $element; - $binding =~ s/^XF86XK_/CLUTTER_KEY_/g; - - printf OUT_KEYSYMS "#define %s 0x%03x\n", $binding, hex($keysymelements[2]); -} - -close IN_XF86KEYSYM; - -foreach my $f (qw/ keysymdef.h XF86keysym.h /) { - unlink $f or die "Unable to delete $f: $!"; -} - -printf "We just finished converting keysymdef.h to clutter-keysyms.h " - . "and deprecated/clutter-keysyms.h\nThank you\n"; diff --git a/mutter/clutter/clutter/clutter-keysyms.h b/mutter/clutter/clutter/clutter-keysyms.h deleted file mode 100644 index 253b96a..0000000 --- a/mutter/clutter/clutter/clutter-keysyms.h +++ /dev/null @@ -1,2304 +0,0 @@ -/* Clutter - * - * Copyright (C) 2006, 2007, 2008 OpenedHand Ltd - * Copyright (C) 2009, 2010 Intel Corp - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - - -/* - * File auto-generated from script at: - * http://git.clutter-project.org/clutter/plain/clutter/clutter-keysyms-update.pl - * - * using the input files: - * http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h - * and - * http://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h - */ - -#define CLUTTER_KEY_VoidSymbol 0xffffff -#define CLUTTER_KEY_BackSpace 0xff08 -#define CLUTTER_KEY_Tab 0xff09 -#define CLUTTER_KEY_Linefeed 0xff0a -#define CLUTTER_KEY_Clear 0xff0b -#define CLUTTER_KEY_Return 0xff0d -#define CLUTTER_KEY_Pause 0xff13 -#define CLUTTER_KEY_Scroll_Lock 0xff14 -#define CLUTTER_KEY_Sys_Req 0xff15 -#define CLUTTER_KEY_Escape 0xff1b -#define CLUTTER_KEY_Delete 0xffff -#define CLUTTER_KEY_Multi_key 0xff20 -#define CLUTTER_KEY_Codeinput 0xff37 -#define CLUTTER_KEY_SingleCandidate 0xff3c -#define CLUTTER_KEY_MultipleCandidate 0xff3d -#define CLUTTER_KEY_PreviousCandidate 0xff3e -#define CLUTTER_KEY_Kanji 0xff21 -#define CLUTTER_KEY_Muhenkan 0xff22 -#define CLUTTER_KEY_Henkan_Mode 0xff23 -#define CLUTTER_KEY_Henkan 0xff23 -#define CLUTTER_KEY_Romaji 0xff24 -#define CLUTTER_KEY_Hiragana 0xff25 -#define CLUTTER_KEY_Katakana 0xff26 -#define CLUTTER_KEY_Hiragana_Katakana 0xff27 -#define CLUTTER_KEY_Zenkaku 0xff28 -#define CLUTTER_KEY_Hankaku 0xff29 -#define CLUTTER_KEY_Zenkaku_Hankaku 0xff2a -#define CLUTTER_KEY_Touroku 0xff2b -#define CLUTTER_KEY_Massyo 0xff2c -#define CLUTTER_KEY_Kana_Lock 0xff2d -#define CLUTTER_KEY_Kana_Shift 0xff2e -#define CLUTTER_KEY_Eisu_Shift 0xff2f -#define CLUTTER_KEY_Eisu_toggle 0xff30 -#define CLUTTER_KEY_Kanji_Bangou 0xff37 -#define CLUTTER_KEY_Zen_Koho 0xff3d -#define CLUTTER_KEY_Mae_Koho 0xff3e -#define CLUTTER_KEY_Home 0xff50 -#define CLUTTER_KEY_Left 0xff51 -#define CLUTTER_KEY_Up 0xff52 -#define CLUTTER_KEY_Right 0xff53 -#define CLUTTER_KEY_Down 0xff54 -#define CLUTTER_KEY_Prior 0xff55 -#define CLUTTER_KEY_Page_Up 0xff55 -#define CLUTTER_KEY_Next 0xff56 -#define CLUTTER_KEY_Page_Down 0xff56 -#define CLUTTER_KEY_End 0xff57 -#define CLUTTER_KEY_Begin 0xff58 -#define CLUTTER_KEY_Select 0xff60 -#define CLUTTER_KEY_Print 0xff61 -#define CLUTTER_KEY_Execute 0xff62 -#define CLUTTER_KEY_Insert 0xff63 -#define CLUTTER_KEY_Undo 0xff65 -#define CLUTTER_KEY_Redo 0xff66 -#define CLUTTER_KEY_Menu 0xff67 -#define CLUTTER_KEY_Find 0xff68 -#define CLUTTER_KEY_Cancel 0xff69 -#define CLUTTER_KEY_Help 0xff6a -#define CLUTTER_KEY_Break 0xff6b -#define CLUTTER_KEY_Mode_switch 0xff7e -#define CLUTTER_KEY_script_switch 0xff7e -#define CLUTTER_KEY_Num_Lock 0xff7f -#define CLUTTER_KEY_KP_Space 0xff80 -#define CLUTTER_KEY_KP_Tab 0xff89 -#define CLUTTER_KEY_KP_Enter 0xff8d -#define CLUTTER_KEY_KP_F1 0xff91 -#define CLUTTER_KEY_KP_F2 0xff92 -#define CLUTTER_KEY_KP_F3 0xff93 -#define CLUTTER_KEY_KP_F4 0xff94 -#define CLUTTER_KEY_KP_Home 0xff95 -#define CLUTTER_KEY_KP_Left 0xff96 -#define CLUTTER_KEY_KP_Up 0xff97 -#define CLUTTER_KEY_KP_Right 0xff98 -#define CLUTTER_KEY_KP_Down 0xff99 -#define CLUTTER_KEY_KP_Prior 0xff9a -#define CLUTTER_KEY_KP_Page_Up 0xff9a -#define CLUTTER_KEY_KP_Next 0xff9b -#define CLUTTER_KEY_KP_Page_Down 0xff9b -#define CLUTTER_KEY_KP_End 0xff9c -#define CLUTTER_KEY_KP_Begin 0xff9d -#define CLUTTER_KEY_KP_Insert 0xff9e -#define CLUTTER_KEY_KP_Delete 0xff9f -#define CLUTTER_KEY_KP_Equal 0xffbd -#define CLUTTER_KEY_KP_Multiply 0xffaa -#define CLUTTER_KEY_KP_Add 0xffab -#define CLUTTER_KEY_KP_Separator 0xffac -#define CLUTTER_KEY_KP_Subtract 0xffad -#define CLUTTER_KEY_KP_Decimal 0xffae -#define CLUTTER_KEY_KP_Divide 0xffaf -#define CLUTTER_KEY_KP_0 0xffb0 -#define CLUTTER_KEY_KP_1 0xffb1 -#define CLUTTER_KEY_KP_2 0xffb2 -#define CLUTTER_KEY_KP_3 0xffb3 -#define CLUTTER_KEY_KP_4 0xffb4 -#define CLUTTER_KEY_KP_5 0xffb5 -#define CLUTTER_KEY_KP_6 0xffb6 -#define CLUTTER_KEY_KP_7 0xffb7 -#define CLUTTER_KEY_KP_8 0xffb8 -#define CLUTTER_KEY_KP_9 0xffb9 -#define CLUTTER_KEY_F1 0xffbe -#define CLUTTER_KEY_F2 0xffbf -#define CLUTTER_KEY_F3 0xffc0 -#define CLUTTER_KEY_F4 0xffc1 -#define CLUTTER_KEY_F5 0xffc2 -#define CLUTTER_KEY_F6 0xffc3 -#define CLUTTER_KEY_F7 0xffc4 -#define CLUTTER_KEY_F8 0xffc5 -#define CLUTTER_KEY_F9 0xffc6 -#define CLUTTER_KEY_F10 0xffc7 -#define CLUTTER_KEY_F11 0xffc8 -#define CLUTTER_KEY_L1 0xffc8 -#define CLUTTER_KEY_F12 0xffc9 -#define CLUTTER_KEY_L2 0xffc9 -#define CLUTTER_KEY_F13 0xffca -#define CLUTTER_KEY_L3 0xffca -#define CLUTTER_KEY_F14 0xffcb -#define CLUTTER_KEY_L4 0xffcb -#define CLUTTER_KEY_F15 0xffcc -#define CLUTTER_KEY_L5 0xffcc -#define CLUTTER_KEY_F16 0xffcd -#define CLUTTER_KEY_L6 0xffcd -#define CLUTTER_KEY_F17 0xffce -#define CLUTTER_KEY_L7 0xffce -#define CLUTTER_KEY_F18 0xffcf -#define CLUTTER_KEY_L8 0xffcf -#define CLUTTER_KEY_F19 0xffd0 -#define CLUTTER_KEY_L9 0xffd0 -#define CLUTTER_KEY_F20 0xffd1 -#define CLUTTER_KEY_L10 0xffd1 -#define CLUTTER_KEY_F21 0xffd2 -#define CLUTTER_KEY_R1 0xffd2 -#define CLUTTER_KEY_F22 0xffd3 -#define CLUTTER_KEY_R2 0xffd3 -#define CLUTTER_KEY_F23 0xffd4 -#define CLUTTER_KEY_R3 0xffd4 -#define CLUTTER_KEY_F24 0xffd5 -#define CLUTTER_KEY_R4 0xffd5 -#define CLUTTER_KEY_F25 0xffd6 -#define CLUTTER_KEY_R5 0xffd6 -#define CLUTTER_KEY_F26 0xffd7 -#define CLUTTER_KEY_R6 0xffd7 -#define CLUTTER_KEY_F27 0xffd8 -#define CLUTTER_KEY_R7 0xffd8 -#define CLUTTER_KEY_F28 0xffd9 -#define CLUTTER_KEY_R8 0xffd9 -#define CLUTTER_KEY_F29 0xffda -#define CLUTTER_KEY_R9 0xffda -#define CLUTTER_KEY_F30 0xffdb -#define CLUTTER_KEY_R10 0xffdb -#define CLUTTER_KEY_F31 0xffdc -#define CLUTTER_KEY_R11 0xffdc -#define CLUTTER_KEY_F32 0xffdd -#define CLUTTER_KEY_R12 0xffdd -#define CLUTTER_KEY_F33 0xffde -#define CLUTTER_KEY_R13 0xffde -#define CLUTTER_KEY_F34 0xffdf -#define CLUTTER_KEY_R14 0xffdf -#define CLUTTER_KEY_F35 0xffe0 -#define CLUTTER_KEY_R15 0xffe0 -#define CLUTTER_KEY_Shift_L 0xffe1 -#define CLUTTER_KEY_Shift_R 0xffe2 -#define CLUTTER_KEY_Control_L 0xffe3 -#define CLUTTER_KEY_Control_R 0xffe4 -#define CLUTTER_KEY_Caps_Lock 0xffe5 -#define CLUTTER_KEY_Shift_Lock 0xffe6 -#define CLUTTER_KEY_Meta_L 0xffe7 -#define CLUTTER_KEY_Meta_R 0xffe8 -#define CLUTTER_KEY_Alt_L 0xffe9 -#define CLUTTER_KEY_Alt_R 0xffea -#define CLUTTER_KEY_Super_L 0xffeb -#define CLUTTER_KEY_Super_R 0xffec -#define CLUTTER_KEY_Hyper_L 0xffed -#define CLUTTER_KEY_Hyper_R 0xffee -#define CLUTTER_KEY_ISO_Lock 0xfe01 -#define CLUTTER_KEY_ISO_Level2_Latch 0xfe02 -#define CLUTTER_KEY_ISO_Level3_Shift 0xfe03 -#define CLUTTER_KEY_ISO_Level3_Latch 0xfe04 -#define CLUTTER_KEY_ISO_Level3_Lock 0xfe05 -#define CLUTTER_KEY_ISO_Level5_Shift 0xfe11 -#define CLUTTER_KEY_ISO_Level5_Latch 0xfe12 -#define CLUTTER_KEY_ISO_Level5_Lock 0xfe13 -#define CLUTTER_KEY_ISO_Group_Shift 0xff7e -#define CLUTTER_KEY_ISO_Group_Latch 0xfe06 -#define CLUTTER_KEY_ISO_Group_Lock 0xfe07 -#define CLUTTER_KEY_ISO_Next_Group 0xfe08 -#define CLUTTER_KEY_ISO_Next_Group_Lock 0xfe09 -#define CLUTTER_KEY_ISO_Prev_Group 0xfe0a -#define CLUTTER_KEY_ISO_Prev_Group_Lock 0xfe0b -#define CLUTTER_KEY_ISO_First_Group 0xfe0c -#define CLUTTER_KEY_ISO_First_Group_Lock 0xfe0d -#define CLUTTER_KEY_ISO_Last_Group 0xfe0e -#define CLUTTER_KEY_ISO_Last_Group_Lock 0xfe0f -#define CLUTTER_KEY_ISO_Left_Tab 0xfe20 -#define CLUTTER_KEY_ISO_Move_Line_Up 0xfe21 -#define CLUTTER_KEY_ISO_Move_Line_Down 0xfe22 -#define CLUTTER_KEY_ISO_Partial_Line_Up 0xfe23 -#define CLUTTER_KEY_ISO_Partial_Line_Down 0xfe24 -#define CLUTTER_KEY_ISO_Partial_Space_Left 0xfe25 -#define CLUTTER_KEY_ISO_Partial_Space_Right 0xfe26 -#define CLUTTER_KEY_ISO_Set_Margin_Left 0xfe27 -#define CLUTTER_KEY_ISO_Set_Margin_Right 0xfe28 -#define CLUTTER_KEY_ISO_Release_Margin_Left 0xfe29 -#define CLUTTER_KEY_ISO_Release_Margin_Right 0xfe2a -#define CLUTTER_KEY_ISO_Release_Both_Margins 0xfe2b -#define CLUTTER_KEY_ISO_Fast_Cursor_Left 0xfe2c -#define CLUTTER_KEY_ISO_Fast_Cursor_Right 0xfe2d -#define CLUTTER_KEY_ISO_Fast_Cursor_Up 0xfe2e -#define CLUTTER_KEY_ISO_Fast_Cursor_Down 0xfe2f -#define CLUTTER_KEY_ISO_Continuous_Underline 0xfe30 -#define CLUTTER_KEY_ISO_Discontinuous_Underline 0xfe31 -#define CLUTTER_KEY_ISO_Emphasize 0xfe32 -#define CLUTTER_KEY_ISO_Center_Object 0xfe33 -#define CLUTTER_KEY_ISO_Enter 0xfe34 -#define CLUTTER_KEY_dead_grave 0xfe50 -#define CLUTTER_KEY_dead_acute 0xfe51 -#define CLUTTER_KEY_dead_circumflex 0xfe52 -#define CLUTTER_KEY_dead_tilde 0xfe53 -#define CLUTTER_KEY_dead_perispomeni 0xfe53 -#define CLUTTER_KEY_dead_macron 0xfe54 -#define CLUTTER_KEY_dead_breve 0xfe55 -#define CLUTTER_KEY_dead_abovedot 0xfe56 -#define CLUTTER_KEY_dead_diaeresis 0xfe57 -#define CLUTTER_KEY_dead_abovering 0xfe58 -#define CLUTTER_KEY_dead_doubleacute 0xfe59 -#define CLUTTER_KEY_dead_caron 0xfe5a -#define CLUTTER_KEY_dead_cedilla 0xfe5b -#define CLUTTER_KEY_dead_ogonek 0xfe5c -#define CLUTTER_KEY_dead_iota 0xfe5d -#define CLUTTER_KEY_dead_voiced_sound 0xfe5e -#define CLUTTER_KEY_dead_semivoiced_sound 0xfe5f -#define CLUTTER_KEY_dead_belowdot 0xfe60 -#define CLUTTER_KEY_dead_hook 0xfe61 -#define CLUTTER_KEY_dead_horn 0xfe62 -#define CLUTTER_KEY_dead_stroke 0xfe63 -#define CLUTTER_KEY_dead_abovecomma 0xfe64 -#define CLUTTER_KEY_dead_psili 0xfe64 -#define CLUTTER_KEY_dead_abovereversedcomma 0xfe65 -#define CLUTTER_KEY_dead_dasia 0xfe65 -#define CLUTTER_KEY_dead_doublegrave 0xfe66 -#define CLUTTER_KEY_dead_belowring 0xfe67 -#define CLUTTER_KEY_dead_belowmacron 0xfe68 -#define CLUTTER_KEY_dead_belowcircumflex 0xfe69 -#define CLUTTER_KEY_dead_belowtilde 0xfe6a -#define CLUTTER_KEY_dead_belowbreve 0xfe6b -#define CLUTTER_KEY_dead_belowdiaeresis 0xfe6c -#define CLUTTER_KEY_dead_invertedbreve 0xfe6d -#define CLUTTER_KEY_dead_belowcomma 0xfe6e -#define CLUTTER_KEY_dead_currency 0xfe6f -#define CLUTTER_KEY_dead_lowline 0xfe90 -#define CLUTTER_KEY_dead_aboveverticalline 0xfe91 -#define CLUTTER_KEY_dead_belowverticalline 0xfe92 -#define CLUTTER_KEY_dead_longsolidusoverlay 0xfe93 -#define CLUTTER_KEY_dead_a 0xfe80 -#define CLUTTER_KEY_dead_A 0xfe81 -#define CLUTTER_KEY_dead_e 0xfe82 -#define CLUTTER_KEY_dead_E 0xfe83 -#define CLUTTER_KEY_dead_i 0xfe84 -#define CLUTTER_KEY_dead_I 0xfe85 -#define CLUTTER_KEY_dead_o 0xfe86 -#define CLUTTER_KEY_dead_O 0xfe87 -#define CLUTTER_KEY_dead_u 0xfe88 -#define CLUTTER_KEY_dead_U 0xfe89 -#define CLUTTER_KEY_dead_small_schwa 0xfe8a -#define CLUTTER_KEY_dead_capital_schwa 0xfe8b -#define CLUTTER_KEY_dead_greek 0xfe8c -#define CLUTTER_KEY_First_Virtual_Screen 0xfed0 -#define CLUTTER_KEY_Prev_Virtual_Screen 0xfed1 -#define CLUTTER_KEY_Next_Virtual_Screen 0xfed2 -#define CLUTTER_KEY_Last_Virtual_Screen 0xfed4 -#define CLUTTER_KEY_Terminate_Server 0xfed5 -#define CLUTTER_KEY_AccessX_Enable 0xfe70 -#define CLUTTER_KEY_AccessX_Feedback_Enable 0xfe71 -#define CLUTTER_KEY_RepeatKeys_Enable 0xfe72 -#define CLUTTER_KEY_SlowKeys_Enable 0xfe73 -#define CLUTTER_KEY_BounceKeys_Enable 0xfe74 -#define CLUTTER_KEY_StickyKeys_Enable 0xfe75 -#define CLUTTER_KEY_MouseKeys_Enable 0xfe76 -#define CLUTTER_KEY_MouseKeys_Accel_Enable 0xfe77 -#define CLUTTER_KEY_Overlay1_Enable 0xfe78 -#define CLUTTER_KEY_Overlay2_Enable 0xfe79 -#define CLUTTER_KEY_AudibleBell_Enable 0xfe7a -#define CLUTTER_KEY_Pointer_Left 0xfee0 -#define CLUTTER_KEY_Pointer_Right 0xfee1 -#define CLUTTER_KEY_Pointer_Up 0xfee2 -#define CLUTTER_KEY_Pointer_Down 0xfee3 -#define CLUTTER_KEY_Pointer_UpLeft 0xfee4 -#define CLUTTER_KEY_Pointer_UpRight 0xfee5 -#define CLUTTER_KEY_Pointer_DownLeft 0xfee6 -#define CLUTTER_KEY_Pointer_DownRight 0xfee7 -#define CLUTTER_KEY_Pointer_Button_Dflt 0xfee8 -#define CLUTTER_KEY_Pointer_Button1 0xfee9 -#define CLUTTER_KEY_Pointer_Button2 0xfeea -#define CLUTTER_KEY_Pointer_Button3 0xfeeb -#define CLUTTER_KEY_Pointer_Button4 0xfeec -#define CLUTTER_KEY_Pointer_Button5 0xfeed -#define CLUTTER_KEY_Pointer_DblClick_Dflt 0xfeee -#define CLUTTER_KEY_Pointer_DblClick1 0xfeef -#define CLUTTER_KEY_Pointer_DblClick2 0xfef0 -#define CLUTTER_KEY_Pointer_DblClick3 0xfef1 -#define CLUTTER_KEY_Pointer_DblClick4 0xfef2 -#define CLUTTER_KEY_Pointer_DblClick5 0xfef3 -#define CLUTTER_KEY_Pointer_Drag_Dflt 0xfef4 -#define CLUTTER_KEY_Pointer_Drag1 0xfef5 -#define CLUTTER_KEY_Pointer_Drag2 0xfef6 -#define CLUTTER_KEY_Pointer_Drag3 0xfef7 -#define CLUTTER_KEY_Pointer_Drag4 0xfef8 -#define CLUTTER_KEY_Pointer_Drag5 0xfefd -#define CLUTTER_KEY_Pointer_EnableKeys 0xfef9 -#define CLUTTER_KEY_Pointer_Accelerate 0xfefa -#define CLUTTER_KEY_Pointer_DfltBtnNext 0xfefb -#define CLUTTER_KEY_Pointer_DfltBtnPrev 0xfefc -#define CLUTTER_KEY_ch 0xfea0 -#define CLUTTER_KEY_Ch 0xfea1 -#define CLUTTER_KEY_CH 0xfea2 -#define CLUTTER_KEY_c_h 0xfea3 -#define CLUTTER_KEY_C_h 0xfea4 -#define CLUTTER_KEY_C_H 0xfea5 -#define CLUTTER_KEY_3270_Duplicate 0xfd01 -#define CLUTTER_KEY_3270_FieldMark 0xfd02 -#define CLUTTER_KEY_3270_Right2 0xfd03 -#define CLUTTER_KEY_3270_Left2 0xfd04 -#define CLUTTER_KEY_3270_BackTab 0xfd05 -#define CLUTTER_KEY_3270_EraseEOF 0xfd06 -#define CLUTTER_KEY_3270_EraseInput 0xfd07 -#define CLUTTER_KEY_3270_Reset 0xfd08 -#define CLUTTER_KEY_3270_Quit 0xfd09 -#define CLUTTER_KEY_3270_PA1 0xfd0a -#define CLUTTER_KEY_3270_PA2 0xfd0b -#define CLUTTER_KEY_3270_PA3 0xfd0c -#define CLUTTER_KEY_3270_Test 0xfd0d -#define CLUTTER_KEY_3270_Attn 0xfd0e -#define CLUTTER_KEY_3270_CursorBlink 0xfd0f -#define CLUTTER_KEY_3270_AltCursor 0xfd10 -#define CLUTTER_KEY_3270_KeyClick 0xfd11 -#define CLUTTER_KEY_3270_Jump 0xfd12 -#define CLUTTER_KEY_3270_Ident 0xfd13 -#define CLUTTER_KEY_3270_Rule 0xfd14 -#define CLUTTER_KEY_3270_Copy 0xfd15 -#define CLUTTER_KEY_3270_Play 0xfd16 -#define CLUTTER_KEY_3270_Setup 0xfd17 -#define CLUTTER_KEY_3270_Record 0xfd18 -#define CLUTTER_KEY_3270_ChangeScreen 0xfd19 -#define CLUTTER_KEY_3270_DeleteWord 0xfd1a -#define CLUTTER_KEY_3270_ExSelect 0xfd1b -#define CLUTTER_KEY_3270_CursorSelect 0xfd1c -#define CLUTTER_KEY_3270_PrintScreen 0xfd1d -#define CLUTTER_KEY_3270_Enter 0xfd1e -#define CLUTTER_KEY_space 0x020 -#define CLUTTER_KEY_exclam 0x021 -#define CLUTTER_KEY_quotedbl 0x022 -#define CLUTTER_KEY_numbersign 0x023 -#define CLUTTER_KEY_dollar 0x024 -#define CLUTTER_KEY_percent 0x025 -#define CLUTTER_KEY_ampersand 0x026 -#define CLUTTER_KEY_apostrophe 0x027 -#define CLUTTER_KEY_quoteright 0x027 -#define CLUTTER_KEY_parenleft 0x028 -#define CLUTTER_KEY_parenright 0x029 -#define CLUTTER_KEY_asterisk 0x02a -#define CLUTTER_KEY_plus 0x02b -#define CLUTTER_KEY_comma 0x02c -#define CLUTTER_KEY_minus 0x02d -#define CLUTTER_KEY_period 0x02e -#define CLUTTER_KEY_slash 0x02f -#define CLUTTER_KEY_0 0x030 -#define CLUTTER_KEY_1 0x031 -#define CLUTTER_KEY_2 0x032 -#define CLUTTER_KEY_3 0x033 -#define CLUTTER_KEY_4 0x034 -#define CLUTTER_KEY_5 0x035 -#define CLUTTER_KEY_6 0x036 -#define CLUTTER_KEY_7 0x037 -#define CLUTTER_KEY_8 0x038 -#define CLUTTER_KEY_9 0x039 -#define CLUTTER_KEY_colon 0x03a -#define CLUTTER_KEY_semicolon 0x03b -#define CLUTTER_KEY_less 0x03c -#define CLUTTER_KEY_equal 0x03d -#define CLUTTER_KEY_greater 0x03e -#define CLUTTER_KEY_question 0x03f -#define CLUTTER_KEY_at 0x040 -#define CLUTTER_KEY_A 0x041 -#define CLUTTER_KEY_B 0x042 -#define CLUTTER_KEY_C 0x043 -#define CLUTTER_KEY_D 0x044 -#define CLUTTER_KEY_E 0x045 -#define CLUTTER_KEY_F 0x046 -#define CLUTTER_KEY_G 0x047 -#define CLUTTER_KEY_H 0x048 -#define CLUTTER_KEY_I 0x049 -#define CLUTTER_KEY_J 0x04a -#define CLUTTER_KEY_K 0x04b -#define CLUTTER_KEY_L 0x04c -#define CLUTTER_KEY_M 0x04d -#define CLUTTER_KEY_N 0x04e -#define CLUTTER_KEY_O 0x04f -#define CLUTTER_KEY_P 0x050 -#define CLUTTER_KEY_Q 0x051 -#define CLUTTER_KEY_R 0x052 -#define CLUTTER_KEY_S 0x053 -#define CLUTTER_KEY_T 0x054 -#define CLUTTER_KEY_U 0x055 -#define CLUTTER_KEY_V 0x056 -#define CLUTTER_KEY_W 0x057 -#define CLUTTER_KEY_X 0x058 -#define CLUTTER_KEY_Y 0x059 -#define CLUTTER_KEY_Z 0x05a -#define CLUTTER_KEY_bracketleft 0x05b -#define CLUTTER_KEY_backslash 0x05c -#define CLUTTER_KEY_bracketright 0x05d -#define CLUTTER_KEY_asciicircum 0x05e -#define CLUTTER_KEY_underscore 0x05f -#define CLUTTER_KEY_grave 0x060 -#define CLUTTER_KEY_quoteleft 0x060 -#define CLUTTER_KEY_a 0x061 -#define CLUTTER_KEY_b 0x062 -#define CLUTTER_KEY_c 0x063 -#define CLUTTER_KEY_d 0x064 -#define CLUTTER_KEY_e 0x065 -#define CLUTTER_KEY_f 0x066 -#define CLUTTER_KEY_g 0x067 -#define CLUTTER_KEY_h 0x068 -#define CLUTTER_KEY_i 0x069 -#define CLUTTER_KEY_j 0x06a -#define CLUTTER_KEY_k 0x06b -#define CLUTTER_KEY_l 0x06c -#define CLUTTER_KEY_m 0x06d -#define CLUTTER_KEY_n 0x06e -#define CLUTTER_KEY_o 0x06f -#define CLUTTER_KEY_p 0x070 -#define CLUTTER_KEY_q 0x071 -#define CLUTTER_KEY_r 0x072 -#define CLUTTER_KEY_s 0x073 -#define CLUTTER_KEY_t 0x074 -#define CLUTTER_KEY_u 0x075 -#define CLUTTER_KEY_v 0x076 -#define CLUTTER_KEY_w 0x077 -#define CLUTTER_KEY_x 0x078 -#define CLUTTER_KEY_y 0x079 -#define CLUTTER_KEY_z 0x07a -#define CLUTTER_KEY_braceleft 0x07b -#define CLUTTER_KEY_bar 0x07c -#define CLUTTER_KEY_braceright 0x07d -#define CLUTTER_KEY_asciitilde 0x07e -#define CLUTTER_KEY_nobreakspace 0x0a0 -#define CLUTTER_KEY_exclamdown 0x0a1 -#define CLUTTER_KEY_cent 0x0a2 -#define CLUTTER_KEY_sterling 0x0a3 -#define CLUTTER_KEY_currency 0x0a4 -#define CLUTTER_KEY_yen 0x0a5 -#define CLUTTER_KEY_brokenbar 0x0a6 -#define CLUTTER_KEY_section 0x0a7 -#define CLUTTER_KEY_diaeresis 0x0a8 -#define CLUTTER_KEY_copyright 0x0a9 -#define CLUTTER_KEY_ordfeminine 0x0aa -#define CLUTTER_KEY_guillemotleft 0x0ab -#define CLUTTER_KEY_notsign 0x0ac -#define CLUTTER_KEY_hyphen 0x0ad -#define CLUTTER_KEY_registered 0x0ae -#define CLUTTER_KEY_macron 0x0af -#define CLUTTER_KEY_degree 0x0b0 -#define CLUTTER_KEY_plusminus 0x0b1 -#define CLUTTER_KEY_twosuperior 0x0b2 -#define CLUTTER_KEY_threesuperior 0x0b3 -#define CLUTTER_KEY_acute 0x0b4 -#define CLUTTER_KEY_mu 0x0b5 -#define CLUTTER_KEY_paragraph 0x0b6 -#define CLUTTER_KEY_periodcentered 0x0b7 -#define CLUTTER_KEY_cedilla 0x0b8 -#define CLUTTER_KEY_onesuperior 0x0b9 -#define CLUTTER_KEY_masculine 0x0ba -#define CLUTTER_KEY_guillemotright 0x0bb -#define CLUTTER_KEY_onequarter 0x0bc -#define CLUTTER_KEY_onehalf 0x0bd -#define CLUTTER_KEY_threequarters 0x0be -#define CLUTTER_KEY_questiondown 0x0bf -#define CLUTTER_KEY_Agrave 0x0c0 -#define CLUTTER_KEY_Aacute 0x0c1 -#define CLUTTER_KEY_Acircumflex 0x0c2 -#define CLUTTER_KEY_Atilde 0x0c3 -#define CLUTTER_KEY_Adiaeresis 0x0c4 -#define CLUTTER_KEY_Aring 0x0c5 -#define CLUTTER_KEY_AE 0x0c6 -#define CLUTTER_KEY_Ccedilla 0x0c7 -#define CLUTTER_KEY_Egrave 0x0c8 -#define CLUTTER_KEY_Eacute 0x0c9 -#define CLUTTER_KEY_Ecircumflex 0x0ca -#define CLUTTER_KEY_Ediaeresis 0x0cb -#define CLUTTER_KEY_Igrave 0x0cc -#define CLUTTER_KEY_Iacute 0x0cd -#define CLUTTER_KEY_Icircumflex 0x0ce -#define CLUTTER_KEY_Idiaeresis 0x0cf -#define CLUTTER_KEY_ETH 0x0d0 -#define CLUTTER_KEY_Eth 0x0d0 -#define CLUTTER_KEY_Ntilde 0x0d1 -#define CLUTTER_KEY_Ograve 0x0d2 -#define CLUTTER_KEY_Oacute 0x0d3 -#define CLUTTER_KEY_Ocircumflex 0x0d4 -#define CLUTTER_KEY_Otilde 0x0d5 -#define CLUTTER_KEY_Odiaeresis 0x0d6 -#define CLUTTER_KEY_multiply 0x0d7 -#define CLUTTER_KEY_Oslash 0x0d8 -#define CLUTTER_KEY_Ooblique 0x0d8 -#define CLUTTER_KEY_Ugrave 0x0d9 -#define CLUTTER_KEY_Uacute 0x0da -#define CLUTTER_KEY_Ucircumflex 0x0db -#define CLUTTER_KEY_Udiaeresis 0x0dc -#define CLUTTER_KEY_Yacute 0x0dd -#define CLUTTER_KEY_THORN 0x0de -#define CLUTTER_KEY_Thorn 0x0de -#define CLUTTER_KEY_ssharp 0x0df -#define CLUTTER_KEY_agrave 0x0e0 -#define CLUTTER_KEY_aacute 0x0e1 -#define CLUTTER_KEY_acircumflex 0x0e2 -#define CLUTTER_KEY_atilde 0x0e3 -#define CLUTTER_KEY_adiaeresis 0x0e4 -#define CLUTTER_KEY_aring 0x0e5 -#define CLUTTER_KEY_ae 0x0e6 -#define CLUTTER_KEY_ccedilla 0x0e7 -#define CLUTTER_KEY_egrave 0x0e8 -#define CLUTTER_KEY_eacute 0x0e9 -#define CLUTTER_KEY_ecircumflex 0x0ea -#define CLUTTER_KEY_ediaeresis 0x0eb -#define CLUTTER_KEY_igrave 0x0ec -#define CLUTTER_KEY_iacute 0x0ed -#define CLUTTER_KEY_icircumflex 0x0ee -#define CLUTTER_KEY_idiaeresis 0x0ef -#define CLUTTER_KEY_eth 0x0f0 -#define CLUTTER_KEY_ntilde 0x0f1 -#define CLUTTER_KEY_ograve 0x0f2 -#define CLUTTER_KEY_oacute 0x0f3 -#define CLUTTER_KEY_ocircumflex 0x0f4 -#define CLUTTER_KEY_otilde 0x0f5 -#define CLUTTER_KEY_odiaeresis 0x0f6 -#define CLUTTER_KEY_division 0x0f7 -#define CLUTTER_KEY_oslash 0x0f8 -#define CLUTTER_KEY_ooblique 0x0f8 -#define CLUTTER_KEY_ugrave 0x0f9 -#define CLUTTER_KEY_uacute 0x0fa -#define CLUTTER_KEY_ucircumflex 0x0fb -#define CLUTTER_KEY_udiaeresis 0x0fc -#define CLUTTER_KEY_yacute 0x0fd -#define CLUTTER_KEY_thorn 0x0fe -#define CLUTTER_KEY_ydiaeresis 0x0ff -#define CLUTTER_KEY_Aogonek 0x1a1 -#define CLUTTER_KEY_breve 0x1a2 -#define CLUTTER_KEY_Lstroke 0x1a3 -#define CLUTTER_KEY_Lcaron 0x1a5 -#define CLUTTER_KEY_Sacute 0x1a6 -#define CLUTTER_KEY_Scaron 0x1a9 -#define CLUTTER_KEY_Scedilla 0x1aa -#define CLUTTER_KEY_Tcaron 0x1ab -#define CLUTTER_KEY_Zacute 0x1ac -#define CLUTTER_KEY_Zcaron 0x1ae -#define CLUTTER_KEY_Zabovedot 0x1af -#define CLUTTER_KEY_aogonek 0x1b1 -#define CLUTTER_KEY_ogonek 0x1b2 -#define CLUTTER_KEY_lstroke 0x1b3 -#define CLUTTER_KEY_lcaron 0x1b5 -#define CLUTTER_KEY_sacute 0x1b6 -#define CLUTTER_KEY_caron 0x1b7 -#define CLUTTER_KEY_scaron 0x1b9 -#define CLUTTER_KEY_scedilla 0x1ba -#define CLUTTER_KEY_tcaron 0x1bb -#define CLUTTER_KEY_zacute 0x1bc -#define CLUTTER_KEY_doubleacute 0x1bd -#define CLUTTER_KEY_zcaron 0x1be -#define CLUTTER_KEY_zabovedot 0x1bf -#define CLUTTER_KEY_Racute 0x1c0 -#define CLUTTER_KEY_Abreve 0x1c3 -#define CLUTTER_KEY_Lacute 0x1c5 -#define CLUTTER_KEY_Cacute 0x1c6 -#define CLUTTER_KEY_Ccaron 0x1c8 -#define CLUTTER_KEY_Eogonek 0x1ca -#define CLUTTER_KEY_Ecaron 0x1cc -#define CLUTTER_KEY_Dcaron 0x1cf -#define CLUTTER_KEY_Dstroke 0x1d0 -#define CLUTTER_KEY_Nacute 0x1d1 -#define CLUTTER_KEY_Ncaron 0x1d2 -#define CLUTTER_KEY_Odoubleacute 0x1d5 -#define CLUTTER_KEY_Rcaron 0x1d8 -#define CLUTTER_KEY_Uring 0x1d9 -#define CLUTTER_KEY_Udoubleacute 0x1db -#define CLUTTER_KEY_Tcedilla 0x1de -#define CLUTTER_KEY_racute 0x1e0 -#define CLUTTER_KEY_abreve 0x1e3 -#define CLUTTER_KEY_lacute 0x1e5 -#define CLUTTER_KEY_cacute 0x1e6 -#define CLUTTER_KEY_ccaron 0x1e8 -#define CLUTTER_KEY_eogonek 0x1ea -#define CLUTTER_KEY_ecaron 0x1ec -#define CLUTTER_KEY_dcaron 0x1ef -#define CLUTTER_KEY_dstroke 0x1f0 -#define CLUTTER_KEY_nacute 0x1f1 -#define CLUTTER_KEY_ncaron 0x1f2 -#define CLUTTER_KEY_odoubleacute 0x1f5 -#define CLUTTER_KEY_rcaron 0x1f8 -#define CLUTTER_KEY_uring 0x1f9 -#define CLUTTER_KEY_udoubleacute 0x1fb -#define CLUTTER_KEY_tcedilla 0x1fe -#define CLUTTER_KEY_abovedot 0x1ff -#define CLUTTER_KEY_Hstroke 0x2a1 -#define CLUTTER_KEY_Hcircumflex 0x2a6 -#define CLUTTER_KEY_Iabovedot 0x2a9 -#define CLUTTER_KEY_Gbreve 0x2ab -#define CLUTTER_KEY_Jcircumflex 0x2ac -#define CLUTTER_KEY_hstroke 0x2b1 -#define CLUTTER_KEY_hcircumflex 0x2b6 -#define CLUTTER_KEY_idotless 0x2b9 -#define CLUTTER_KEY_gbreve 0x2bb -#define CLUTTER_KEY_jcircumflex 0x2bc -#define CLUTTER_KEY_Cabovedot 0x2c5 -#define CLUTTER_KEY_Ccircumflex 0x2c6 -#define CLUTTER_KEY_Gabovedot 0x2d5 -#define CLUTTER_KEY_Gcircumflex 0x2d8 -#define CLUTTER_KEY_Ubreve 0x2dd -#define CLUTTER_KEY_Scircumflex 0x2de -#define CLUTTER_KEY_cabovedot 0x2e5 -#define CLUTTER_KEY_ccircumflex 0x2e6 -#define CLUTTER_KEY_gabovedot 0x2f5 -#define CLUTTER_KEY_gcircumflex 0x2f8 -#define CLUTTER_KEY_ubreve 0x2fd -#define CLUTTER_KEY_scircumflex 0x2fe -#define CLUTTER_KEY_kra 0x3a2 -#define CLUTTER_KEY_kappa 0x3a2 -#define CLUTTER_KEY_Rcedilla 0x3a3 -#define CLUTTER_KEY_Itilde 0x3a5 -#define CLUTTER_KEY_Lcedilla 0x3a6 -#define CLUTTER_KEY_Emacron 0x3aa -#define CLUTTER_KEY_Gcedilla 0x3ab -#define CLUTTER_KEY_Tslash 0x3ac -#define CLUTTER_KEY_rcedilla 0x3b3 -#define CLUTTER_KEY_itilde 0x3b5 -#define CLUTTER_KEY_lcedilla 0x3b6 -#define CLUTTER_KEY_emacron 0x3ba -#define CLUTTER_KEY_gcedilla 0x3bb -#define CLUTTER_KEY_tslash 0x3bc -#define CLUTTER_KEY_ENG 0x3bd -#define CLUTTER_KEY_eng 0x3bf -#define CLUTTER_KEY_Amacron 0x3c0 -#define CLUTTER_KEY_Iogonek 0x3c7 -#define CLUTTER_KEY_Eabovedot 0x3cc -#define CLUTTER_KEY_Imacron 0x3cf -#define CLUTTER_KEY_Ncedilla 0x3d1 -#define CLUTTER_KEY_Omacron 0x3d2 -#define CLUTTER_KEY_Kcedilla 0x3d3 -#define CLUTTER_KEY_Uogonek 0x3d9 -#define CLUTTER_KEY_Utilde 0x3dd -#define CLUTTER_KEY_Umacron 0x3de -#define CLUTTER_KEY_amacron 0x3e0 -#define CLUTTER_KEY_iogonek 0x3e7 -#define CLUTTER_KEY_eabovedot 0x3ec -#define CLUTTER_KEY_imacron 0x3ef -#define CLUTTER_KEY_ncedilla 0x3f1 -#define CLUTTER_KEY_omacron 0x3f2 -#define CLUTTER_KEY_kcedilla 0x3f3 -#define CLUTTER_KEY_uogonek 0x3f9 -#define CLUTTER_KEY_utilde 0x3fd -#define CLUTTER_KEY_umacron 0x3fe -#define CLUTTER_KEY_Wcircumflex 0x1000174 -#define CLUTTER_KEY_wcircumflex 0x1000175 -#define CLUTTER_KEY_Ycircumflex 0x1000176 -#define CLUTTER_KEY_ycircumflex 0x1000177 -#define CLUTTER_KEY_Babovedot 0x1001e02 -#define CLUTTER_KEY_babovedot 0x1001e03 -#define CLUTTER_KEY_Dabovedot 0x1001e0a -#define CLUTTER_KEY_dabovedot 0x1001e0b -#define CLUTTER_KEY_Fabovedot 0x1001e1e -#define CLUTTER_KEY_fabovedot 0x1001e1f -#define CLUTTER_KEY_Mabovedot 0x1001e40 -#define CLUTTER_KEY_mabovedot 0x1001e41 -#define CLUTTER_KEY_Pabovedot 0x1001e56 -#define CLUTTER_KEY_pabovedot 0x1001e57 -#define CLUTTER_KEY_Sabovedot 0x1001e60 -#define CLUTTER_KEY_sabovedot 0x1001e61 -#define CLUTTER_KEY_Tabovedot 0x1001e6a -#define CLUTTER_KEY_tabovedot 0x1001e6b -#define CLUTTER_KEY_Wgrave 0x1001e80 -#define CLUTTER_KEY_wgrave 0x1001e81 -#define CLUTTER_KEY_Wacute 0x1001e82 -#define CLUTTER_KEY_wacute 0x1001e83 -#define CLUTTER_KEY_Wdiaeresis 0x1001e84 -#define CLUTTER_KEY_wdiaeresis 0x1001e85 -#define CLUTTER_KEY_Ygrave 0x1001ef2 -#define CLUTTER_KEY_ygrave 0x1001ef3 -#define CLUTTER_KEY_OE 0x13bc -#define CLUTTER_KEY_oe 0x13bd -#define CLUTTER_KEY_Ydiaeresis 0x13be -#define CLUTTER_KEY_overline 0x47e -#define CLUTTER_KEY_kana_fullstop 0x4a1 -#define CLUTTER_KEY_kana_openingbracket 0x4a2 -#define CLUTTER_KEY_kana_closingbracket 0x4a3 -#define CLUTTER_KEY_kana_comma 0x4a4 -#define CLUTTER_KEY_kana_conjunctive 0x4a5 -#define CLUTTER_KEY_kana_middledot 0x4a5 -#define CLUTTER_KEY_kana_WO 0x4a6 -#define CLUTTER_KEY_kana_a 0x4a7 -#define CLUTTER_KEY_kana_i 0x4a8 -#define CLUTTER_KEY_kana_u 0x4a9 -#define CLUTTER_KEY_kana_e 0x4aa -#define CLUTTER_KEY_kana_o 0x4ab -#define CLUTTER_KEY_kana_ya 0x4ac -#define CLUTTER_KEY_kana_yu 0x4ad -#define CLUTTER_KEY_kana_yo 0x4ae -#define CLUTTER_KEY_kana_tsu 0x4af -#define CLUTTER_KEY_kana_tu 0x4af -#define CLUTTER_KEY_prolongedsound 0x4b0 -#define CLUTTER_KEY_kana_A 0x4b1 -#define CLUTTER_KEY_kana_I 0x4b2 -#define CLUTTER_KEY_kana_U 0x4b3 -#define CLUTTER_KEY_kana_E 0x4b4 -#define CLUTTER_KEY_kana_O 0x4b5 -#define CLUTTER_KEY_kana_KA 0x4b6 -#define CLUTTER_KEY_kana_KI 0x4b7 -#define CLUTTER_KEY_kana_KU 0x4b8 -#define CLUTTER_KEY_kana_KE 0x4b9 -#define CLUTTER_KEY_kana_KO 0x4ba -#define CLUTTER_KEY_kana_SA 0x4bb -#define CLUTTER_KEY_kana_SHI 0x4bc -#define CLUTTER_KEY_kana_SU 0x4bd -#define CLUTTER_KEY_kana_SE 0x4be -#define CLUTTER_KEY_kana_SO 0x4bf -#define CLUTTER_KEY_kana_TA 0x4c0 -#define CLUTTER_KEY_kana_CHI 0x4c1 -#define CLUTTER_KEY_kana_TI 0x4c1 -#define CLUTTER_KEY_kana_TSU 0x4c2 -#define CLUTTER_KEY_kana_TU 0x4c2 -#define CLUTTER_KEY_kana_TE 0x4c3 -#define CLUTTER_KEY_kana_TO 0x4c4 -#define CLUTTER_KEY_kana_NA 0x4c5 -#define CLUTTER_KEY_kana_NI 0x4c6 -#define CLUTTER_KEY_kana_NU 0x4c7 -#define CLUTTER_KEY_kana_NE 0x4c8 -#define CLUTTER_KEY_kana_NO 0x4c9 -#define CLUTTER_KEY_kana_HA 0x4ca -#define CLUTTER_KEY_kana_HI 0x4cb -#define CLUTTER_KEY_kana_FU 0x4cc -#define CLUTTER_KEY_kana_HU 0x4cc -#define CLUTTER_KEY_kana_HE 0x4cd -#define CLUTTER_KEY_kana_HO 0x4ce -#define CLUTTER_KEY_kana_MA 0x4cf -#define CLUTTER_KEY_kana_MI 0x4d0 -#define CLUTTER_KEY_kana_MU 0x4d1 -#define CLUTTER_KEY_kana_ME 0x4d2 -#define CLUTTER_KEY_kana_MO 0x4d3 -#define CLUTTER_KEY_kana_YA 0x4d4 -#define CLUTTER_KEY_kana_YU 0x4d5 -#define CLUTTER_KEY_kana_YO 0x4d6 -#define CLUTTER_KEY_kana_RA 0x4d7 -#define CLUTTER_KEY_kana_RI 0x4d8 -#define CLUTTER_KEY_kana_RU 0x4d9 -#define CLUTTER_KEY_kana_RE 0x4da -#define CLUTTER_KEY_kana_RO 0x4db -#define CLUTTER_KEY_kana_WA 0x4dc -#define CLUTTER_KEY_kana_N 0x4dd -#define CLUTTER_KEY_voicedsound 0x4de -#define CLUTTER_KEY_semivoicedsound 0x4df -#define CLUTTER_KEY_kana_switch 0xff7e -#define CLUTTER_KEY_Farsi_0 0x10006f0 -#define CLUTTER_KEY_Farsi_1 0x10006f1 -#define CLUTTER_KEY_Farsi_2 0x10006f2 -#define CLUTTER_KEY_Farsi_3 0x10006f3 -#define CLUTTER_KEY_Farsi_4 0x10006f4 -#define CLUTTER_KEY_Farsi_5 0x10006f5 -#define CLUTTER_KEY_Farsi_6 0x10006f6 -#define CLUTTER_KEY_Farsi_7 0x10006f7 -#define CLUTTER_KEY_Farsi_8 0x10006f8 -#define CLUTTER_KEY_Farsi_9 0x10006f9 -#define CLUTTER_KEY_Arabic_percent 0x100066a -#define CLUTTER_KEY_Arabic_superscript_alef 0x1000670 -#define CLUTTER_KEY_Arabic_tteh 0x1000679 -#define CLUTTER_KEY_Arabic_peh 0x100067e -#define CLUTTER_KEY_Arabic_tcheh 0x1000686 -#define CLUTTER_KEY_Arabic_ddal 0x1000688 -#define CLUTTER_KEY_Arabic_rreh 0x1000691 -#define CLUTTER_KEY_Arabic_comma 0x5ac -#define CLUTTER_KEY_Arabic_fullstop 0x10006d4 -#define CLUTTER_KEY_Arabic_0 0x1000660 -#define CLUTTER_KEY_Arabic_1 0x1000661 -#define CLUTTER_KEY_Arabic_2 0x1000662 -#define CLUTTER_KEY_Arabic_3 0x1000663 -#define CLUTTER_KEY_Arabic_4 0x1000664 -#define CLUTTER_KEY_Arabic_5 0x1000665 -#define CLUTTER_KEY_Arabic_6 0x1000666 -#define CLUTTER_KEY_Arabic_7 0x1000667 -#define CLUTTER_KEY_Arabic_8 0x1000668 -#define CLUTTER_KEY_Arabic_9 0x1000669 -#define CLUTTER_KEY_Arabic_semicolon 0x5bb -#define CLUTTER_KEY_Arabic_question_mark 0x5bf -#define CLUTTER_KEY_Arabic_hamza 0x5c1 -#define CLUTTER_KEY_Arabic_maddaonalef 0x5c2 -#define CLUTTER_KEY_Arabic_hamzaonalef 0x5c3 -#define CLUTTER_KEY_Arabic_hamzaonwaw 0x5c4 -#define CLUTTER_KEY_Arabic_hamzaunderalef 0x5c5 -#define CLUTTER_KEY_Arabic_hamzaonyeh 0x5c6 -#define CLUTTER_KEY_Arabic_alef 0x5c7 -#define CLUTTER_KEY_Arabic_beh 0x5c8 -#define CLUTTER_KEY_Arabic_tehmarbuta 0x5c9 -#define CLUTTER_KEY_Arabic_teh 0x5ca -#define CLUTTER_KEY_Arabic_theh 0x5cb -#define CLUTTER_KEY_Arabic_jeem 0x5cc -#define CLUTTER_KEY_Arabic_hah 0x5cd -#define CLUTTER_KEY_Arabic_khah 0x5ce -#define CLUTTER_KEY_Arabic_dal 0x5cf -#define CLUTTER_KEY_Arabic_thal 0x5d0 -#define CLUTTER_KEY_Arabic_ra 0x5d1 -#define CLUTTER_KEY_Arabic_zain 0x5d2 -#define CLUTTER_KEY_Arabic_seen 0x5d3 -#define CLUTTER_KEY_Arabic_sheen 0x5d4 -#define CLUTTER_KEY_Arabic_sad 0x5d5 -#define CLUTTER_KEY_Arabic_dad 0x5d6 -#define CLUTTER_KEY_Arabic_tah 0x5d7 -#define CLUTTER_KEY_Arabic_zah 0x5d8 -#define CLUTTER_KEY_Arabic_ain 0x5d9 -#define CLUTTER_KEY_Arabic_ghain 0x5da -#define CLUTTER_KEY_Arabic_tatweel 0x5e0 -#define CLUTTER_KEY_Arabic_feh 0x5e1 -#define CLUTTER_KEY_Arabic_qaf 0x5e2 -#define CLUTTER_KEY_Arabic_kaf 0x5e3 -#define CLUTTER_KEY_Arabic_lam 0x5e4 -#define CLUTTER_KEY_Arabic_meem 0x5e5 -#define CLUTTER_KEY_Arabic_noon 0x5e6 -#define CLUTTER_KEY_Arabic_ha 0x5e7 -#define CLUTTER_KEY_Arabic_heh 0x5e7 -#define CLUTTER_KEY_Arabic_waw 0x5e8 -#define CLUTTER_KEY_Arabic_alefmaksura 0x5e9 -#define CLUTTER_KEY_Arabic_yeh 0x5ea -#define CLUTTER_KEY_Arabic_fathatan 0x5eb -#define CLUTTER_KEY_Arabic_dammatan 0x5ec -#define CLUTTER_KEY_Arabic_kasratan 0x5ed -#define CLUTTER_KEY_Arabic_fatha 0x5ee -#define CLUTTER_KEY_Arabic_damma 0x5ef -#define CLUTTER_KEY_Arabic_kasra 0x5f0 -#define CLUTTER_KEY_Arabic_shadda 0x5f1 -#define CLUTTER_KEY_Arabic_sukun 0x5f2 -#define CLUTTER_KEY_Arabic_madda_above 0x1000653 -#define CLUTTER_KEY_Arabic_hamza_above 0x1000654 -#define CLUTTER_KEY_Arabic_hamza_below 0x1000655 -#define CLUTTER_KEY_Arabic_jeh 0x1000698 -#define CLUTTER_KEY_Arabic_veh 0x10006a4 -#define CLUTTER_KEY_Arabic_keheh 0x10006a9 -#define CLUTTER_KEY_Arabic_gaf 0x10006af -#define CLUTTER_KEY_Arabic_noon_ghunna 0x10006ba -#define CLUTTER_KEY_Arabic_heh_doachashmee 0x10006be -#define CLUTTER_KEY_Farsi_yeh 0x10006cc -#define CLUTTER_KEY_Arabic_farsi_yeh 0x10006cc -#define CLUTTER_KEY_Arabic_yeh_baree 0x10006d2 -#define CLUTTER_KEY_Arabic_heh_goal 0x10006c1 -#define CLUTTER_KEY_Arabic_switch 0xff7e -#define CLUTTER_KEY_Cyrillic_GHE_bar 0x1000492 -#define CLUTTER_KEY_Cyrillic_ghe_bar 0x1000493 -#define CLUTTER_KEY_Cyrillic_ZHE_descender 0x1000496 -#define CLUTTER_KEY_Cyrillic_zhe_descender 0x1000497 -#define CLUTTER_KEY_Cyrillic_KA_descender 0x100049a -#define CLUTTER_KEY_Cyrillic_ka_descender 0x100049b -#define CLUTTER_KEY_Cyrillic_KA_vertstroke 0x100049c -#define CLUTTER_KEY_Cyrillic_ka_vertstroke 0x100049d -#define CLUTTER_KEY_Cyrillic_EN_descender 0x10004a2 -#define CLUTTER_KEY_Cyrillic_en_descender 0x10004a3 -#define CLUTTER_KEY_Cyrillic_U_straight 0x10004ae -#define CLUTTER_KEY_Cyrillic_u_straight 0x10004af -#define CLUTTER_KEY_Cyrillic_U_straight_bar 0x10004b0 -#define CLUTTER_KEY_Cyrillic_u_straight_bar 0x10004b1 -#define CLUTTER_KEY_Cyrillic_HA_descender 0x10004b2 -#define CLUTTER_KEY_Cyrillic_ha_descender 0x10004b3 -#define CLUTTER_KEY_Cyrillic_CHE_descender 0x10004b6 -#define CLUTTER_KEY_Cyrillic_che_descender 0x10004b7 -#define CLUTTER_KEY_Cyrillic_CHE_vertstroke 0x10004b8 -#define CLUTTER_KEY_Cyrillic_che_vertstroke 0x10004b9 -#define CLUTTER_KEY_Cyrillic_SHHA 0x10004ba -#define CLUTTER_KEY_Cyrillic_shha 0x10004bb -#define CLUTTER_KEY_Cyrillic_SCHWA 0x10004d8 -#define CLUTTER_KEY_Cyrillic_schwa 0x10004d9 -#define CLUTTER_KEY_Cyrillic_I_macron 0x10004e2 -#define CLUTTER_KEY_Cyrillic_i_macron 0x10004e3 -#define CLUTTER_KEY_Cyrillic_O_bar 0x10004e8 -#define CLUTTER_KEY_Cyrillic_o_bar 0x10004e9 -#define CLUTTER_KEY_Cyrillic_U_macron 0x10004ee -#define CLUTTER_KEY_Cyrillic_u_macron 0x10004ef -#define CLUTTER_KEY_Serbian_dje 0x6a1 -#define CLUTTER_KEY_Macedonia_gje 0x6a2 -#define CLUTTER_KEY_Cyrillic_io 0x6a3 -#define CLUTTER_KEY_Ukrainian_ie 0x6a4 -#define CLUTTER_KEY_Ukranian_je 0x6a4 -#define CLUTTER_KEY_Macedonia_dse 0x6a5 -#define CLUTTER_KEY_Ukrainian_i 0x6a6 -#define CLUTTER_KEY_Ukranian_i 0x6a6 -#define CLUTTER_KEY_Ukrainian_yi 0x6a7 -#define CLUTTER_KEY_Ukranian_yi 0x6a7 -#define CLUTTER_KEY_Cyrillic_je 0x6a8 -#define CLUTTER_KEY_Serbian_je 0x6a8 -#define CLUTTER_KEY_Cyrillic_lje 0x6a9 -#define CLUTTER_KEY_Serbian_lje 0x6a9 -#define CLUTTER_KEY_Cyrillic_nje 0x6aa -#define CLUTTER_KEY_Serbian_nje 0x6aa -#define CLUTTER_KEY_Serbian_tshe 0x6ab -#define CLUTTER_KEY_Macedonia_kje 0x6ac -#define CLUTTER_KEY_Ukrainian_ghe_with_upturn 0x6ad -#define CLUTTER_KEY_Byelorussian_shortu 0x6ae -#define CLUTTER_KEY_Cyrillic_dzhe 0x6af -#define CLUTTER_KEY_Serbian_dze 0x6af -#define CLUTTER_KEY_numerosign 0x6b0 -#define CLUTTER_KEY_Serbian_DJE 0x6b1 -#define CLUTTER_KEY_Macedonia_GJE 0x6b2 -#define CLUTTER_KEY_Cyrillic_IO 0x6b3 -#define CLUTTER_KEY_Ukrainian_IE 0x6b4 -#define CLUTTER_KEY_Ukranian_JE 0x6b4 -#define CLUTTER_KEY_Macedonia_DSE 0x6b5 -#define CLUTTER_KEY_Ukrainian_I 0x6b6 -#define CLUTTER_KEY_Ukranian_I 0x6b6 -#define CLUTTER_KEY_Ukrainian_YI 0x6b7 -#define CLUTTER_KEY_Ukranian_YI 0x6b7 -#define CLUTTER_KEY_Cyrillic_JE 0x6b8 -#define CLUTTER_KEY_Serbian_JE 0x6b8 -#define CLUTTER_KEY_Cyrillic_LJE 0x6b9 -#define CLUTTER_KEY_Serbian_LJE 0x6b9 -#define CLUTTER_KEY_Cyrillic_NJE 0x6ba -#define CLUTTER_KEY_Serbian_NJE 0x6ba -#define CLUTTER_KEY_Serbian_TSHE 0x6bb -#define CLUTTER_KEY_Macedonia_KJE 0x6bc -#define CLUTTER_KEY_Ukrainian_GHE_WITH_UPTURN 0x6bd -#define CLUTTER_KEY_Byelorussian_SHORTU 0x6be -#define CLUTTER_KEY_Cyrillic_DZHE 0x6bf -#define CLUTTER_KEY_Serbian_DZE 0x6bf -#define CLUTTER_KEY_Cyrillic_yu 0x6c0 -#define CLUTTER_KEY_Cyrillic_a 0x6c1 -#define CLUTTER_KEY_Cyrillic_be 0x6c2 -#define CLUTTER_KEY_Cyrillic_tse 0x6c3 -#define CLUTTER_KEY_Cyrillic_de 0x6c4 -#define CLUTTER_KEY_Cyrillic_ie 0x6c5 -#define CLUTTER_KEY_Cyrillic_ef 0x6c6 -#define CLUTTER_KEY_Cyrillic_ghe 0x6c7 -#define CLUTTER_KEY_Cyrillic_ha 0x6c8 -#define CLUTTER_KEY_Cyrillic_i 0x6c9 -#define CLUTTER_KEY_Cyrillic_shorti 0x6ca -#define CLUTTER_KEY_Cyrillic_ka 0x6cb -#define CLUTTER_KEY_Cyrillic_el 0x6cc -#define CLUTTER_KEY_Cyrillic_em 0x6cd -#define CLUTTER_KEY_Cyrillic_en 0x6ce -#define CLUTTER_KEY_Cyrillic_o 0x6cf -#define CLUTTER_KEY_Cyrillic_pe 0x6d0 -#define CLUTTER_KEY_Cyrillic_ya 0x6d1 -#define CLUTTER_KEY_Cyrillic_er 0x6d2 -#define CLUTTER_KEY_Cyrillic_es 0x6d3 -#define CLUTTER_KEY_Cyrillic_te 0x6d4 -#define CLUTTER_KEY_Cyrillic_u 0x6d5 -#define CLUTTER_KEY_Cyrillic_zhe 0x6d6 -#define CLUTTER_KEY_Cyrillic_ve 0x6d7 -#define CLUTTER_KEY_Cyrillic_softsign 0x6d8 -#define CLUTTER_KEY_Cyrillic_yeru 0x6d9 -#define CLUTTER_KEY_Cyrillic_ze 0x6da -#define CLUTTER_KEY_Cyrillic_sha 0x6db -#define CLUTTER_KEY_Cyrillic_e 0x6dc -#define CLUTTER_KEY_Cyrillic_shcha 0x6dd -#define CLUTTER_KEY_Cyrillic_che 0x6de -#define CLUTTER_KEY_Cyrillic_hardsign 0x6df -#define CLUTTER_KEY_Cyrillic_YU 0x6e0 -#define CLUTTER_KEY_Cyrillic_A 0x6e1 -#define CLUTTER_KEY_Cyrillic_BE 0x6e2 -#define CLUTTER_KEY_Cyrillic_TSE 0x6e3 -#define CLUTTER_KEY_Cyrillic_DE 0x6e4 -#define CLUTTER_KEY_Cyrillic_IE 0x6e5 -#define CLUTTER_KEY_Cyrillic_EF 0x6e6 -#define CLUTTER_KEY_Cyrillic_GHE 0x6e7 -#define CLUTTER_KEY_Cyrillic_HA 0x6e8 -#define CLUTTER_KEY_Cyrillic_I 0x6e9 -#define CLUTTER_KEY_Cyrillic_SHORTI 0x6ea -#define CLUTTER_KEY_Cyrillic_KA 0x6eb -#define CLUTTER_KEY_Cyrillic_EL 0x6ec -#define CLUTTER_KEY_Cyrillic_EM 0x6ed -#define CLUTTER_KEY_Cyrillic_EN 0x6ee -#define CLUTTER_KEY_Cyrillic_O 0x6ef -#define CLUTTER_KEY_Cyrillic_PE 0x6f0 -#define CLUTTER_KEY_Cyrillic_YA 0x6f1 -#define CLUTTER_KEY_Cyrillic_ER 0x6f2 -#define CLUTTER_KEY_Cyrillic_ES 0x6f3 -#define CLUTTER_KEY_Cyrillic_TE 0x6f4 -#define CLUTTER_KEY_Cyrillic_U 0x6f5 -#define CLUTTER_KEY_Cyrillic_ZHE 0x6f6 -#define CLUTTER_KEY_Cyrillic_VE 0x6f7 -#define CLUTTER_KEY_Cyrillic_SOFTSIGN 0x6f8 -#define CLUTTER_KEY_Cyrillic_YERU 0x6f9 -#define CLUTTER_KEY_Cyrillic_ZE 0x6fa -#define CLUTTER_KEY_Cyrillic_SHA 0x6fb -#define CLUTTER_KEY_Cyrillic_E 0x6fc -#define CLUTTER_KEY_Cyrillic_SHCHA 0x6fd -#define CLUTTER_KEY_Cyrillic_CHE 0x6fe -#define CLUTTER_KEY_Cyrillic_HARDSIGN 0x6ff -#define CLUTTER_KEY_Greek_ALPHAaccent 0x7a1 -#define CLUTTER_KEY_Greek_EPSILONaccent 0x7a2 -#define CLUTTER_KEY_Greek_ETAaccent 0x7a3 -#define CLUTTER_KEY_Greek_IOTAaccent 0x7a4 -#define CLUTTER_KEY_Greek_IOTAdieresis 0x7a5 -#define CLUTTER_KEY_Greek_IOTAdiaeresis 0x7a5 -#define CLUTTER_KEY_Greek_OMICRONaccent 0x7a7 -#define CLUTTER_KEY_Greek_UPSILONaccent 0x7a8 -#define CLUTTER_KEY_Greek_UPSILONdieresis 0x7a9 -#define CLUTTER_KEY_Greek_OMEGAaccent 0x7ab -#define CLUTTER_KEY_Greek_accentdieresis 0x7ae -#define CLUTTER_KEY_Greek_horizbar 0x7af -#define CLUTTER_KEY_Greek_alphaaccent 0x7b1 -#define CLUTTER_KEY_Greek_epsilonaccent 0x7b2 -#define CLUTTER_KEY_Greek_etaaccent 0x7b3 -#define CLUTTER_KEY_Greek_iotaaccent 0x7b4 -#define CLUTTER_KEY_Greek_iotadieresis 0x7b5 -#define CLUTTER_KEY_Greek_iotaaccentdieresis 0x7b6 -#define CLUTTER_KEY_Greek_omicronaccent 0x7b7 -#define CLUTTER_KEY_Greek_upsilonaccent 0x7b8 -#define CLUTTER_KEY_Greek_upsilondieresis 0x7b9 -#define CLUTTER_KEY_Greek_upsilonaccentdieresis 0x7ba -#define CLUTTER_KEY_Greek_omegaaccent 0x7bb -#define CLUTTER_KEY_Greek_ALPHA 0x7c1 -#define CLUTTER_KEY_Greek_BETA 0x7c2 -#define CLUTTER_KEY_Greek_GAMMA 0x7c3 -#define CLUTTER_KEY_Greek_DELTA 0x7c4 -#define CLUTTER_KEY_Greek_EPSILON 0x7c5 -#define CLUTTER_KEY_Greek_ZETA 0x7c6 -#define CLUTTER_KEY_Greek_ETA 0x7c7 -#define CLUTTER_KEY_Greek_THETA 0x7c8 -#define CLUTTER_KEY_Greek_IOTA 0x7c9 -#define CLUTTER_KEY_Greek_KAPPA 0x7ca -#define CLUTTER_KEY_Greek_LAMDA 0x7cb -#define CLUTTER_KEY_Greek_LAMBDA 0x7cb -#define CLUTTER_KEY_Greek_MU 0x7cc -#define CLUTTER_KEY_Greek_NU 0x7cd -#define CLUTTER_KEY_Greek_XI 0x7ce -#define CLUTTER_KEY_Greek_OMICRON 0x7cf -#define CLUTTER_KEY_Greek_PI 0x7d0 -#define CLUTTER_KEY_Greek_RHO 0x7d1 -#define CLUTTER_KEY_Greek_SIGMA 0x7d2 -#define CLUTTER_KEY_Greek_TAU 0x7d4 -#define CLUTTER_KEY_Greek_UPSILON 0x7d5 -#define CLUTTER_KEY_Greek_PHI 0x7d6 -#define CLUTTER_KEY_Greek_CHI 0x7d7 -#define CLUTTER_KEY_Greek_PSI 0x7d8 -#define CLUTTER_KEY_Greek_OMEGA 0x7d9 -#define CLUTTER_KEY_Greek_alpha 0x7e1 -#define CLUTTER_KEY_Greek_beta 0x7e2 -#define CLUTTER_KEY_Greek_gamma 0x7e3 -#define CLUTTER_KEY_Greek_delta 0x7e4 -#define CLUTTER_KEY_Greek_epsilon 0x7e5 -#define CLUTTER_KEY_Greek_zeta 0x7e6 -#define CLUTTER_KEY_Greek_eta 0x7e7 -#define CLUTTER_KEY_Greek_theta 0x7e8 -#define CLUTTER_KEY_Greek_iota 0x7e9 -#define CLUTTER_KEY_Greek_kappa 0x7ea -#define CLUTTER_KEY_Greek_lamda 0x7eb -#define CLUTTER_KEY_Greek_lambda 0x7eb -#define CLUTTER_KEY_Greek_mu 0x7ec -#define CLUTTER_KEY_Greek_nu 0x7ed -#define CLUTTER_KEY_Greek_xi 0x7ee -#define CLUTTER_KEY_Greek_omicron 0x7ef -#define CLUTTER_KEY_Greek_pi 0x7f0 -#define CLUTTER_KEY_Greek_rho 0x7f1 -#define CLUTTER_KEY_Greek_sigma 0x7f2 -#define CLUTTER_KEY_Greek_finalsmallsigma 0x7f3 -#define CLUTTER_KEY_Greek_tau 0x7f4 -#define CLUTTER_KEY_Greek_upsilon 0x7f5 -#define CLUTTER_KEY_Greek_phi 0x7f6 -#define CLUTTER_KEY_Greek_chi 0x7f7 -#define CLUTTER_KEY_Greek_psi 0x7f8 -#define CLUTTER_KEY_Greek_omega 0x7f9 -#define CLUTTER_KEY_Greek_switch 0xff7e -#define CLUTTER_KEY_leftradical 0x8a1 -#define CLUTTER_KEY_topleftradical 0x8a2 -#define CLUTTER_KEY_horizconnector 0x8a3 -#define CLUTTER_KEY_topintegral 0x8a4 -#define CLUTTER_KEY_botintegral 0x8a5 -#define CLUTTER_KEY_vertconnector 0x8a6 -#define CLUTTER_KEY_topleftsqbracket 0x8a7 -#define CLUTTER_KEY_botleftsqbracket 0x8a8 -#define CLUTTER_KEY_toprightsqbracket 0x8a9 -#define CLUTTER_KEY_botrightsqbracket 0x8aa -#define CLUTTER_KEY_topleftparens 0x8ab -#define CLUTTER_KEY_botleftparens 0x8ac -#define CLUTTER_KEY_toprightparens 0x8ad -#define CLUTTER_KEY_botrightparens 0x8ae -#define CLUTTER_KEY_leftmiddlecurlybrace 0x8af -#define CLUTTER_KEY_rightmiddlecurlybrace 0x8b0 -#define CLUTTER_KEY_topleftsummation 0x8b1 -#define CLUTTER_KEY_botleftsummation 0x8b2 -#define CLUTTER_KEY_topvertsummationconnector 0x8b3 -#define CLUTTER_KEY_botvertsummationconnector 0x8b4 -#define CLUTTER_KEY_toprightsummation 0x8b5 -#define CLUTTER_KEY_botrightsummation 0x8b6 -#define CLUTTER_KEY_rightmiddlesummation 0x8b7 -#define CLUTTER_KEY_lessthanequal 0x8bc -#define CLUTTER_KEY_notequal 0x8bd -#define CLUTTER_KEY_greaterthanequal 0x8be -#define CLUTTER_KEY_integral 0x8bf -#define CLUTTER_KEY_therefore 0x8c0 -#define CLUTTER_KEY_variation 0x8c1 -#define CLUTTER_KEY_infinity 0x8c2 -#define CLUTTER_KEY_nabla 0x8c5 -#define CLUTTER_KEY_approximate 0x8c8 -#define CLUTTER_KEY_similarequal 0x8c9 -#define CLUTTER_KEY_ifonlyif 0x8cd -#define CLUTTER_KEY_implies 0x8ce -#define CLUTTER_KEY_identical 0x8cf -#define CLUTTER_KEY_radical 0x8d6 -#define CLUTTER_KEY_includedin 0x8da -#define CLUTTER_KEY_includes 0x8db -#define CLUTTER_KEY_intersection 0x8dc -#define CLUTTER_KEY_union 0x8dd -#define CLUTTER_KEY_logicaland 0x8de -#define CLUTTER_KEY_logicalor 0x8df -#define CLUTTER_KEY_partialderivative 0x8ef -#define CLUTTER_KEY_function 0x8f6 -#define CLUTTER_KEY_leftarrow 0x8fb -#define CLUTTER_KEY_uparrow 0x8fc -#define CLUTTER_KEY_rightarrow 0x8fd -#define CLUTTER_KEY_downarrow 0x8fe -#define CLUTTER_KEY_blank 0x9df -#define CLUTTER_KEY_soliddiamond 0x9e0 -#define CLUTTER_KEY_checkerboard 0x9e1 -#define CLUTTER_KEY_ht 0x9e2 -#define CLUTTER_KEY_ff 0x9e3 -#define CLUTTER_KEY_cr 0x9e4 -#define CLUTTER_KEY_lf 0x9e5 -#define CLUTTER_KEY_nl 0x9e8 -#define CLUTTER_KEY_vt 0x9e9 -#define CLUTTER_KEY_lowrightcorner 0x9ea -#define CLUTTER_KEY_uprightcorner 0x9eb -#define CLUTTER_KEY_upleftcorner 0x9ec -#define CLUTTER_KEY_lowleftcorner 0x9ed -#define CLUTTER_KEY_crossinglines 0x9ee -#define CLUTTER_KEY_horizlinescan1 0x9ef -#define CLUTTER_KEY_horizlinescan3 0x9f0 -#define CLUTTER_KEY_horizlinescan5 0x9f1 -#define CLUTTER_KEY_horizlinescan7 0x9f2 -#define CLUTTER_KEY_horizlinescan9 0x9f3 -#define CLUTTER_KEY_leftt 0x9f4 -#define CLUTTER_KEY_rightt 0x9f5 -#define CLUTTER_KEY_bott 0x9f6 -#define CLUTTER_KEY_topt 0x9f7 -#define CLUTTER_KEY_vertbar 0x9f8 -#define CLUTTER_KEY_emspace 0xaa1 -#define CLUTTER_KEY_enspace 0xaa2 -#define CLUTTER_KEY_em3space 0xaa3 -#define CLUTTER_KEY_em4space 0xaa4 -#define CLUTTER_KEY_digitspace 0xaa5 -#define CLUTTER_KEY_punctspace 0xaa6 -#define CLUTTER_KEY_thinspace 0xaa7 -#define CLUTTER_KEY_hairspace 0xaa8 -#define CLUTTER_KEY_emdash 0xaa9 -#define CLUTTER_KEY_endash 0xaaa -#define CLUTTER_KEY_signifblank 0xaac -#define CLUTTER_KEY_ellipsis 0xaae -#define CLUTTER_KEY_doubbaselinedot 0xaaf -#define CLUTTER_KEY_onethird 0xab0 -#define CLUTTER_KEY_twothirds 0xab1 -#define CLUTTER_KEY_onefifth 0xab2 -#define CLUTTER_KEY_twofifths 0xab3 -#define CLUTTER_KEY_threefifths 0xab4 -#define CLUTTER_KEY_fourfifths 0xab5 -#define CLUTTER_KEY_onesixth 0xab6 -#define CLUTTER_KEY_fivesixths 0xab7 -#define CLUTTER_KEY_careof 0xab8 -#define CLUTTER_KEY_figdash 0xabb -#define CLUTTER_KEY_leftanglebracket 0xabc -#define CLUTTER_KEY_decimalpoint 0xabd -#define CLUTTER_KEY_rightanglebracket 0xabe -#define CLUTTER_KEY_marker 0xabf -#define CLUTTER_KEY_oneeighth 0xac3 -#define CLUTTER_KEY_threeeighths 0xac4 -#define CLUTTER_KEY_fiveeighths 0xac5 -#define CLUTTER_KEY_seveneighths 0xac6 -#define CLUTTER_KEY_trademark 0xac9 -#define CLUTTER_KEY_signaturemark 0xaca -#define CLUTTER_KEY_trademarkincircle 0xacb -#define CLUTTER_KEY_leftopentriangle 0xacc -#define CLUTTER_KEY_rightopentriangle 0xacd -#define CLUTTER_KEY_emopencircle 0xace -#define CLUTTER_KEY_emopenrectangle 0xacf -#define CLUTTER_KEY_leftsinglequotemark 0xad0 -#define CLUTTER_KEY_rightsinglequotemark 0xad1 -#define CLUTTER_KEY_leftdoublequotemark 0xad2 -#define CLUTTER_KEY_rightdoublequotemark 0xad3 -#define CLUTTER_KEY_prescription 0xad4 -#define CLUTTER_KEY_permille 0xad5 -#define CLUTTER_KEY_minutes 0xad6 -#define CLUTTER_KEY_seconds 0xad7 -#define CLUTTER_KEY_latincross 0xad9 -#define CLUTTER_KEY_hexagram 0xada -#define CLUTTER_KEY_filledrectbullet 0xadb -#define CLUTTER_KEY_filledlefttribullet 0xadc -#define CLUTTER_KEY_filledrighttribullet 0xadd -#define CLUTTER_KEY_emfilledcircle 0xade -#define CLUTTER_KEY_emfilledrect 0xadf -#define CLUTTER_KEY_enopencircbullet 0xae0 -#define CLUTTER_KEY_enopensquarebullet 0xae1 -#define CLUTTER_KEY_openrectbullet 0xae2 -#define CLUTTER_KEY_opentribulletup 0xae3 -#define CLUTTER_KEY_opentribulletdown 0xae4 -#define CLUTTER_KEY_openstar 0xae5 -#define CLUTTER_KEY_enfilledcircbullet 0xae6 -#define CLUTTER_KEY_enfilledsqbullet 0xae7 -#define CLUTTER_KEY_filledtribulletup 0xae8 -#define CLUTTER_KEY_filledtribulletdown 0xae9 -#define CLUTTER_KEY_leftpointer 0xaea -#define CLUTTER_KEY_rightpointer 0xaeb -#define CLUTTER_KEY_club 0xaec -#define CLUTTER_KEY_diamond 0xaed -#define CLUTTER_KEY_heart 0xaee -#define CLUTTER_KEY_maltesecross 0xaf0 -#define CLUTTER_KEY_dagger 0xaf1 -#define CLUTTER_KEY_doubledagger 0xaf2 -#define CLUTTER_KEY_checkmark 0xaf3 -#define CLUTTER_KEY_ballotcross 0xaf4 -#define CLUTTER_KEY_musicalsharp 0xaf5 -#define CLUTTER_KEY_musicalflat 0xaf6 -#define CLUTTER_KEY_malesymbol 0xaf7 -#define CLUTTER_KEY_femalesymbol 0xaf8 -#define CLUTTER_KEY_telephone 0xaf9 -#define CLUTTER_KEY_telephonerecorder 0xafa -#define CLUTTER_KEY_phonographcopyright 0xafb -#define CLUTTER_KEY_caret 0xafc -#define CLUTTER_KEY_singlelowquotemark 0xafd -#define CLUTTER_KEY_doublelowquotemark 0xafe -#define CLUTTER_KEY_cursor 0xaff -#define CLUTTER_KEY_leftcaret 0xba3 -#define CLUTTER_KEY_rightcaret 0xba6 -#define CLUTTER_KEY_downcaret 0xba8 -#define CLUTTER_KEY_upcaret 0xba9 -#define CLUTTER_KEY_overbar 0xbc0 -#define CLUTTER_KEY_downtack 0xbc2 -#define CLUTTER_KEY_upshoe 0xbc3 -#define CLUTTER_KEY_downstile 0xbc4 -#define CLUTTER_KEY_underbar 0xbc6 -#define CLUTTER_KEY_jot 0xbca -#define CLUTTER_KEY_quad 0xbcc -#define CLUTTER_KEY_uptack 0xbce -#define CLUTTER_KEY_circle 0xbcf -#define CLUTTER_KEY_upstile 0xbd3 -#define CLUTTER_KEY_downshoe 0xbd6 -#define CLUTTER_KEY_rightshoe 0xbd8 -#define CLUTTER_KEY_leftshoe 0xbda -#define CLUTTER_KEY_lefttack 0xbdc -#define CLUTTER_KEY_righttack 0xbfc -#define CLUTTER_KEY_hebrew_doublelowline 0xcdf -#define CLUTTER_KEY_hebrew_aleph 0xce0 -#define CLUTTER_KEY_hebrew_bet 0xce1 -#define CLUTTER_KEY_hebrew_beth 0xce1 -#define CLUTTER_KEY_hebrew_gimel 0xce2 -#define CLUTTER_KEY_hebrew_gimmel 0xce2 -#define CLUTTER_KEY_hebrew_dalet 0xce3 -#define CLUTTER_KEY_hebrew_daleth 0xce3 -#define CLUTTER_KEY_hebrew_he 0xce4 -#define CLUTTER_KEY_hebrew_waw 0xce5 -#define CLUTTER_KEY_hebrew_zain 0xce6 -#define CLUTTER_KEY_hebrew_zayin 0xce6 -#define CLUTTER_KEY_hebrew_chet 0xce7 -#define CLUTTER_KEY_hebrew_het 0xce7 -#define CLUTTER_KEY_hebrew_tet 0xce8 -#define CLUTTER_KEY_hebrew_teth 0xce8 -#define CLUTTER_KEY_hebrew_yod 0xce9 -#define CLUTTER_KEY_hebrew_finalkaph 0xcea -#define CLUTTER_KEY_hebrew_kaph 0xceb -#define CLUTTER_KEY_hebrew_lamed 0xcec -#define CLUTTER_KEY_hebrew_finalmem 0xced -#define CLUTTER_KEY_hebrew_mem 0xcee -#define CLUTTER_KEY_hebrew_finalnun 0xcef -#define CLUTTER_KEY_hebrew_nun 0xcf0 -#define CLUTTER_KEY_hebrew_samech 0xcf1 -#define CLUTTER_KEY_hebrew_samekh 0xcf1 -#define CLUTTER_KEY_hebrew_ayin 0xcf2 -#define CLUTTER_KEY_hebrew_finalpe 0xcf3 -#define CLUTTER_KEY_hebrew_pe 0xcf4 -#define CLUTTER_KEY_hebrew_finalzade 0xcf5 -#define CLUTTER_KEY_hebrew_finalzadi 0xcf5 -#define CLUTTER_KEY_hebrew_zade 0xcf6 -#define CLUTTER_KEY_hebrew_zadi 0xcf6 -#define CLUTTER_KEY_hebrew_qoph 0xcf7 -#define CLUTTER_KEY_hebrew_kuf 0xcf7 -#define CLUTTER_KEY_hebrew_resh 0xcf8 -#define CLUTTER_KEY_hebrew_shin 0xcf9 -#define CLUTTER_KEY_hebrew_taw 0xcfa -#define CLUTTER_KEY_hebrew_taf 0xcfa -#define CLUTTER_KEY_Hebrew_switch 0xff7e -#define CLUTTER_KEY_Thai_kokai 0xda1 -#define CLUTTER_KEY_Thai_khokhai 0xda2 -#define CLUTTER_KEY_Thai_khokhuat 0xda3 -#define CLUTTER_KEY_Thai_khokhwai 0xda4 -#define CLUTTER_KEY_Thai_khokhon 0xda5 -#define CLUTTER_KEY_Thai_khorakhang 0xda6 -#define CLUTTER_KEY_Thai_ngongu 0xda7 -#define CLUTTER_KEY_Thai_chochan 0xda8 -#define CLUTTER_KEY_Thai_choching 0xda9 -#define CLUTTER_KEY_Thai_chochang 0xdaa -#define CLUTTER_KEY_Thai_soso 0xdab -#define CLUTTER_KEY_Thai_chochoe 0xdac -#define CLUTTER_KEY_Thai_yoying 0xdad -#define CLUTTER_KEY_Thai_dochada 0xdae -#define CLUTTER_KEY_Thai_topatak 0xdaf -#define CLUTTER_KEY_Thai_thothan 0xdb0 -#define CLUTTER_KEY_Thai_thonangmontho 0xdb1 -#define CLUTTER_KEY_Thai_thophuthao 0xdb2 -#define CLUTTER_KEY_Thai_nonen 0xdb3 -#define CLUTTER_KEY_Thai_dodek 0xdb4 -#define CLUTTER_KEY_Thai_totao 0xdb5 -#define CLUTTER_KEY_Thai_thothung 0xdb6 -#define CLUTTER_KEY_Thai_thothahan 0xdb7 -#define CLUTTER_KEY_Thai_thothong 0xdb8 -#define CLUTTER_KEY_Thai_nonu 0xdb9 -#define CLUTTER_KEY_Thai_bobaimai 0xdba -#define CLUTTER_KEY_Thai_popla 0xdbb -#define CLUTTER_KEY_Thai_phophung 0xdbc -#define CLUTTER_KEY_Thai_fofa 0xdbd -#define CLUTTER_KEY_Thai_phophan 0xdbe -#define CLUTTER_KEY_Thai_fofan 0xdbf -#define CLUTTER_KEY_Thai_phosamphao 0xdc0 -#define CLUTTER_KEY_Thai_moma 0xdc1 -#define CLUTTER_KEY_Thai_yoyak 0xdc2 -#define CLUTTER_KEY_Thai_rorua 0xdc3 -#define CLUTTER_KEY_Thai_ru 0xdc4 -#define CLUTTER_KEY_Thai_loling 0xdc5 -#define CLUTTER_KEY_Thai_lu 0xdc6 -#define CLUTTER_KEY_Thai_wowaen 0xdc7 -#define CLUTTER_KEY_Thai_sosala 0xdc8 -#define CLUTTER_KEY_Thai_sorusi 0xdc9 -#define CLUTTER_KEY_Thai_sosua 0xdca -#define CLUTTER_KEY_Thai_hohip 0xdcb -#define CLUTTER_KEY_Thai_lochula 0xdcc -#define CLUTTER_KEY_Thai_oang 0xdcd -#define CLUTTER_KEY_Thai_honokhuk 0xdce -#define CLUTTER_KEY_Thai_paiyannoi 0xdcf -#define CLUTTER_KEY_Thai_saraa 0xdd0 -#define CLUTTER_KEY_Thai_maihanakat 0xdd1 -#define CLUTTER_KEY_Thai_saraaa 0xdd2 -#define CLUTTER_KEY_Thai_saraam 0xdd3 -#define CLUTTER_KEY_Thai_sarai 0xdd4 -#define CLUTTER_KEY_Thai_saraii 0xdd5 -#define CLUTTER_KEY_Thai_saraue 0xdd6 -#define CLUTTER_KEY_Thai_sarauee 0xdd7 -#define CLUTTER_KEY_Thai_sarau 0xdd8 -#define CLUTTER_KEY_Thai_sarauu 0xdd9 -#define CLUTTER_KEY_Thai_phinthu 0xdda -#define CLUTTER_KEY_Thai_maihanakat_maitho 0xdde -#define CLUTTER_KEY_Thai_baht 0xddf -#define CLUTTER_KEY_Thai_sarae 0xde0 -#define CLUTTER_KEY_Thai_saraae 0xde1 -#define CLUTTER_KEY_Thai_sarao 0xde2 -#define CLUTTER_KEY_Thai_saraaimaimuan 0xde3 -#define CLUTTER_KEY_Thai_saraaimaimalai 0xde4 -#define CLUTTER_KEY_Thai_lakkhangyao 0xde5 -#define CLUTTER_KEY_Thai_maiyamok 0xde6 -#define CLUTTER_KEY_Thai_maitaikhu 0xde7 -#define CLUTTER_KEY_Thai_maiek 0xde8 -#define CLUTTER_KEY_Thai_maitho 0xde9 -#define CLUTTER_KEY_Thai_maitri 0xdea -#define CLUTTER_KEY_Thai_maichattawa 0xdeb -#define CLUTTER_KEY_Thai_thanthakhat 0xdec -#define CLUTTER_KEY_Thai_nikhahit 0xded -#define CLUTTER_KEY_Thai_leksun 0xdf0 -#define CLUTTER_KEY_Thai_leknung 0xdf1 -#define CLUTTER_KEY_Thai_leksong 0xdf2 -#define CLUTTER_KEY_Thai_leksam 0xdf3 -#define CLUTTER_KEY_Thai_leksi 0xdf4 -#define CLUTTER_KEY_Thai_lekha 0xdf5 -#define CLUTTER_KEY_Thai_lekhok 0xdf6 -#define CLUTTER_KEY_Thai_lekchet 0xdf7 -#define CLUTTER_KEY_Thai_lekpaet 0xdf8 -#define CLUTTER_KEY_Thai_lekkao 0xdf9 -#define CLUTTER_KEY_Hangul 0xff31 -#define CLUTTER_KEY_Hangul_Start 0xff32 -#define CLUTTER_KEY_Hangul_End 0xff33 -#define CLUTTER_KEY_Hangul_Hanja 0xff34 -#define CLUTTER_KEY_Hangul_Jamo 0xff35 -#define CLUTTER_KEY_Hangul_Romaja 0xff36 -#define CLUTTER_KEY_Hangul_Codeinput 0xff37 -#define CLUTTER_KEY_Hangul_Jeonja 0xff38 -#define CLUTTER_KEY_Hangul_Banja 0xff39 -#define CLUTTER_KEY_Hangul_PreHanja 0xff3a -#define CLUTTER_KEY_Hangul_PostHanja 0xff3b -#define CLUTTER_KEY_Hangul_SingleCandidate 0xff3c -#define CLUTTER_KEY_Hangul_MultipleCandidate 0xff3d -#define CLUTTER_KEY_Hangul_PreviousCandidate 0xff3e -#define CLUTTER_KEY_Hangul_Special 0xff3f -#define CLUTTER_KEY_Hangul_switch 0xff7e -#define CLUTTER_KEY_Hangul_Kiyeog 0xea1 -#define CLUTTER_KEY_Hangul_SsangKiyeog 0xea2 -#define CLUTTER_KEY_Hangul_KiyeogSios 0xea3 -#define CLUTTER_KEY_Hangul_Nieun 0xea4 -#define CLUTTER_KEY_Hangul_NieunJieuj 0xea5 -#define CLUTTER_KEY_Hangul_NieunHieuh 0xea6 -#define CLUTTER_KEY_Hangul_Dikeud 0xea7 -#define CLUTTER_KEY_Hangul_SsangDikeud 0xea8 -#define CLUTTER_KEY_Hangul_Rieul 0xea9 -#define CLUTTER_KEY_Hangul_RieulKiyeog 0xeaa -#define CLUTTER_KEY_Hangul_RieulMieum 0xeab -#define CLUTTER_KEY_Hangul_RieulPieub 0xeac -#define CLUTTER_KEY_Hangul_RieulSios 0xead -#define CLUTTER_KEY_Hangul_RieulTieut 0xeae -#define CLUTTER_KEY_Hangul_RieulPhieuf 0xeaf -#define CLUTTER_KEY_Hangul_RieulHieuh 0xeb0 -#define CLUTTER_KEY_Hangul_Mieum 0xeb1 -#define CLUTTER_KEY_Hangul_Pieub 0xeb2 -#define CLUTTER_KEY_Hangul_SsangPieub 0xeb3 -#define CLUTTER_KEY_Hangul_PieubSios 0xeb4 -#define CLUTTER_KEY_Hangul_Sios 0xeb5 -#define CLUTTER_KEY_Hangul_SsangSios 0xeb6 -#define CLUTTER_KEY_Hangul_Ieung 0xeb7 -#define CLUTTER_KEY_Hangul_Jieuj 0xeb8 -#define CLUTTER_KEY_Hangul_SsangJieuj 0xeb9 -#define CLUTTER_KEY_Hangul_Cieuc 0xeba -#define CLUTTER_KEY_Hangul_Khieuq 0xebb -#define CLUTTER_KEY_Hangul_Tieut 0xebc -#define CLUTTER_KEY_Hangul_Phieuf 0xebd -#define CLUTTER_KEY_Hangul_Hieuh 0xebe -#define CLUTTER_KEY_Hangul_A 0xebf -#define CLUTTER_KEY_Hangul_AE 0xec0 -#define CLUTTER_KEY_Hangul_YA 0xec1 -#define CLUTTER_KEY_Hangul_YAE 0xec2 -#define CLUTTER_KEY_Hangul_EO 0xec3 -#define CLUTTER_KEY_Hangul_E 0xec4 -#define CLUTTER_KEY_Hangul_YEO 0xec5 -#define CLUTTER_KEY_Hangul_YE 0xec6 -#define CLUTTER_KEY_Hangul_O 0xec7 -#define CLUTTER_KEY_Hangul_WA 0xec8 -#define CLUTTER_KEY_Hangul_WAE 0xec9 -#define CLUTTER_KEY_Hangul_OE 0xeca -#define CLUTTER_KEY_Hangul_YO 0xecb -#define CLUTTER_KEY_Hangul_U 0xecc -#define CLUTTER_KEY_Hangul_WEO 0xecd -#define CLUTTER_KEY_Hangul_WE 0xece -#define CLUTTER_KEY_Hangul_WI 0xecf -#define CLUTTER_KEY_Hangul_YU 0xed0 -#define CLUTTER_KEY_Hangul_EU 0xed1 -#define CLUTTER_KEY_Hangul_YI 0xed2 -#define CLUTTER_KEY_Hangul_I 0xed3 -#define CLUTTER_KEY_Hangul_J_Kiyeog 0xed4 -#define CLUTTER_KEY_Hangul_J_SsangKiyeog 0xed5 -#define CLUTTER_KEY_Hangul_J_KiyeogSios 0xed6 -#define CLUTTER_KEY_Hangul_J_Nieun 0xed7 -#define CLUTTER_KEY_Hangul_J_NieunJieuj 0xed8 -#define CLUTTER_KEY_Hangul_J_NieunHieuh 0xed9 -#define CLUTTER_KEY_Hangul_J_Dikeud 0xeda -#define CLUTTER_KEY_Hangul_J_Rieul 0xedb -#define CLUTTER_KEY_Hangul_J_RieulKiyeog 0xedc -#define CLUTTER_KEY_Hangul_J_RieulMieum 0xedd -#define CLUTTER_KEY_Hangul_J_RieulPieub 0xede -#define CLUTTER_KEY_Hangul_J_RieulSios 0xedf -#define CLUTTER_KEY_Hangul_J_RieulTieut 0xee0 -#define CLUTTER_KEY_Hangul_J_RieulPhieuf 0xee1 -#define CLUTTER_KEY_Hangul_J_RieulHieuh 0xee2 -#define CLUTTER_KEY_Hangul_J_Mieum 0xee3 -#define CLUTTER_KEY_Hangul_J_Pieub 0xee4 -#define CLUTTER_KEY_Hangul_J_PieubSios 0xee5 -#define CLUTTER_KEY_Hangul_J_Sios 0xee6 -#define CLUTTER_KEY_Hangul_J_SsangSios 0xee7 -#define CLUTTER_KEY_Hangul_J_Ieung 0xee8 -#define CLUTTER_KEY_Hangul_J_Jieuj 0xee9 -#define CLUTTER_KEY_Hangul_J_Cieuc 0xeea -#define CLUTTER_KEY_Hangul_J_Khieuq 0xeeb -#define CLUTTER_KEY_Hangul_J_Tieut 0xeec -#define CLUTTER_KEY_Hangul_J_Phieuf 0xeed -#define CLUTTER_KEY_Hangul_J_Hieuh 0xeee -#define CLUTTER_KEY_Hangul_RieulYeorinHieuh 0xeef -#define CLUTTER_KEY_Hangul_SunkyeongeumMieum 0xef0 -#define CLUTTER_KEY_Hangul_SunkyeongeumPieub 0xef1 -#define CLUTTER_KEY_Hangul_PanSios 0xef2 -#define CLUTTER_KEY_Hangul_KkogjiDalrinIeung 0xef3 -#define CLUTTER_KEY_Hangul_SunkyeongeumPhieuf 0xef4 -#define CLUTTER_KEY_Hangul_YeorinHieuh 0xef5 -#define CLUTTER_KEY_Hangul_AraeA 0xef6 -#define CLUTTER_KEY_Hangul_AraeAE 0xef7 -#define CLUTTER_KEY_Hangul_J_PanSios 0xef8 -#define CLUTTER_KEY_Hangul_J_KkogjiDalrinIeung 0xef9 -#define CLUTTER_KEY_Hangul_J_YeorinHieuh 0xefa -#define CLUTTER_KEY_Korean_Won 0xeff -#define CLUTTER_KEY_Armenian_ligature_ew 0x1000587 -#define CLUTTER_KEY_Armenian_full_stop 0x1000589 -#define CLUTTER_KEY_Armenian_verjaket 0x1000589 -#define CLUTTER_KEY_Armenian_separation_mark 0x100055d -#define CLUTTER_KEY_Armenian_but 0x100055d -#define CLUTTER_KEY_Armenian_hyphen 0x100058a -#define CLUTTER_KEY_Armenian_yentamna 0x100058a -#define CLUTTER_KEY_Armenian_exclam 0x100055c -#define CLUTTER_KEY_Armenian_amanak 0x100055c -#define CLUTTER_KEY_Armenian_accent 0x100055b -#define CLUTTER_KEY_Armenian_shesht 0x100055b -#define CLUTTER_KEY_Armenian_question 0x100055e -#define CLUTTER_KEY_Armenian_paruyk 0x100055e -#define CLUTTER_KEY_Armenian_AYB 0x1000531 -#define CLUTTER_KEY_Armenian_ayb 0x1000561 -#define CLUTTER_KEY_Armenian_BEN 0x1000532 -#define CLUTTER_KEY_Armenian_ben 0x1000562 -#define CLUTTER_KEY_Armenian_GIM 0x1000533 -#define CLUTTER_KEY_Armenian_gim 0x1000563 -#define CLUTTER_KEY_Armenian_DA 0x1000534 -#define CLUTTER_KEY_Armenian_da 0x1000564 -#define CLUTTER_KEY_Armenian_YECH 0x1000535 -#define CLUTTER_KEY_Armenian_yech 0x1000565 -#define CLUTTER_KEY_Armenian_ZA 0x1000536 -#define CLUTTER_KEY_Armenian_za 0x1000566 -#define CLUTTER_KEY_Armenian_E 0x1000537 -#define CLUTTER_KEY_Armenian_e 0x1000567 -#define CLUTTER_KEY_Armenian_AT 0x1000538 -#define CLUTTER_KEY_Armenian_at 0x1000568 -#define CLUTTER_KEY_Armenian_TO 0x1000539 -#define CLUTTER_KEY_Armenian_to 0x1000569 -#define CLUTTER_KEY_Armenian_ZHE 0x100053a -#define CLUTTER_KEY_Armenian_zhe 0x100056a -#define CLUTTER_KEY_Armenian_INI 0x100053b -#define CLUTTER_KEY_Armenian_ini 0x100056b -#define CLUTTER_KEY_Armenian_LYUN 0x100053c -#define CLUTTER_KEY_Armenian_lyun 0x100056c -#define CLUTTER_KEY_Armenian_KHE 0x100053d -#define CLUTTER_KEY_Armenian_khe 0x100056d -#define CLUTTER_KEY_Armenian_TSA 0x100053e -#define CLUTTER_KEY_Armenian_tsa 0x100056e -#define CLUTTER_KEY_Armenian_KEN 0x100053f -#define CLUTTER_KEY_Armenian_ken 0x100056f -#define CLUTTER_KEY_Armenian_HO 0x1000540 -#define CLUTTER_KEY_Armenian_ho 0x1000570 -#define CLUTTER_KEY_Armenian_DZA 0x1000541 -#define CLUTTER_KEY_Armenian_dza 0x1000571 -#define CLUTTER_KEY_Armenian_GHAT 0x1000542 -#define CLUTTER_KEY_Armenian_ghat 0x1000572 -#define CLUTTER_KEY_Armenian_TCHE 0x1000543 -#define CLUTTER_KEY_Armenian_tche 0x1000573 -#define CLUTTER_KEY_Armenian_MEN 0x1000544 -#define CLUTTER_KEY_Armenian_men 0x1000574 -#define CLUTTER_KEY_Armenian_HI 0x1000545 -#define CLUTTER_KEY_Armenian_hi 0x1000575 -#define CLUTTER_KEY_Armenian_NU 0x1000546 -#define CLUTTER_KEY_Armenian_nu 0x1000576 -#define CLUTTER_KEY_Armenian_SHA 0x1000547 -#define CLUTTER_KEY_Armenian_sha 0x1000577 -#define CLUTTER_KEY_Armenian_VO 0x1000548 -#define CLUTTER_KEY_Armenian_vo 0x1000578 -#define CLUTTER_KEY_Armenian_CHA 0x1000549 -#define CLUTTER_KEY_Armenian_cha 0x1000579 -#define CLUTTER_KEY_Armenian_PE 0x100054a -#define CLUTTER_KEY_Armenian_pe 0x100057a -#define CLUTTER_KEY_Armenian_JE 0x100054b -#define CLUTTER_KEY_Armenian_je 0x100057b -#define CLUTTER_KEY_Armenian_RA 0x100054c -#define CLUTTER_KEY_Armenian_ra 0x100057c -#define CLUTTER_KEY_Armenian_SE 0x100054d -#define CLUTTER_KEY_Armenian_se 0x100057d -#define CLUTTER_KEY_Armenian_VEV 0x100054e -#define CLUTTER_KEY_Armenian_vev 0x100057e -#define CLUTTER_KEY_Armenian_TYUN 0x100054f -#define CLUTTER_KEY_Armenian_tyun 0x100057f -#define CLUTTER_KEY_Armenian_RE 0x1000550 -#define CLUTTER_KEY_Armenian_re 0x1000580 -#define CLUTTER_KEY_Armenian_TSO 0x1000551 -#define CLUTTER_KEY_Armenian_tso 0x1000581 -#define CLUTTER_KEY_Armenian_VYUN 0x1000552 -#define CLUTTER_KEY_Armenian_vyun 0x1000582 -#define CLUTTER_KEY_Armenian_PYUR 0x1000553 -#define CLUTTER_KEY_Armenian_pyur 0x1000583 -#define CLUTTER_KEY_Armenian_KE 0x1000554 -#define CLUTTER_KEY_Armenian_ke 0x1000584 -#define CLUTTER_KEY_Armenian_O 0x1000555 -#define CLUTTER_KEY_Armenian_o 0x1000585 -#define CLUTTER_KEY_Armenian_FE 0x1000556 -#define CLUTTER_KEY_Armenian_fe 0x1000586 -#define CLUTTER_KEY_Armenian_apostrophe 0x100055a -#define CLUTTER_KEY_Georgian_an 0x10010d0 -#define CLUTTER_KEY_Georgian_ban 0x10010d1 -#define CLUTTER_KEY_Georgian_gan 0x10010d2 -#define CLUTTER_KEY_Georgian_don 0x10010d3 -#define CLUTTER_KEY_Georgian_en 0x10010d4 -#define CLUTTER_KEY_Georgian_vin 0x10010d5 -#define CLUTTER_KEY_Georgian_zen 0x10010d6 -#define CLUTTER_KEY_Georgian_tan 0x10010d7 -#define CLUTTER_KEY_Georgian_in 0x10010d8 -#define CLUTTER_KEY_Georgian_kan 0x10010d9 -#define CLUTTER_KEY_Georgian_las 0x10010da -#define CLUTTER_KEY_Georgian_man 0x10010db -#define CLUTTER_KEY_Georgian_nar 0x10010dc -#define CLUTTER_KEY_Georgian_on 0x10010dd -#define CLUTTER_KEY_Georgian_par 0x10010de -#define CLUTTER_KEY_Georgian_zhar 0x10010df -#define CLUTTER_KEY_Georgian_rae 0x10010e0 -#define CLUTTER_KEY_Georgian_san 0x10010e1 -#define CLUTTER_KEY_Georgian_tar 0x10010e2 -#define CLUTTER_KEY_Georgian_un 0x10010e3 -#define CLUTTER_KEY_Georgian_phar 0x10010e4 -#define CLUTTER_KEY_Georgian_khar 0x10010e5 -#define CLUTTER_KEY_Georgian_ghan 0x10010e6 -#define CLUTTER_KEY_Georgian_qar 0x10010e7 -#define CLUTTER_KEY_Georgian_shin 0x10010e8 -#define CLUTTER_KEY_Georgian_chin 0x10010e9 -#define CLUTTER_KEY_Georgian_can 0x10010ea -#define CLUTTER_KEY_Georgian_jil 0x10010eb -#define CLUTTER_KEY_Georgian_cil 0x10010ec -#define CLUTTER_KEY_Georgian_char 0x10010ed -#define CLUTTER_KEY_Georgian_xan 0x10010ee -#define CLUTTER_KEY_Georgian_jhan 0x10010ef -#define CLUTTER_KEY_Georgian_hae 0x10010f0 -#define CLUTTER_KEY_Georgian_he 0x10010f1 -#define CLUTTER_KEY_Georgian_hie 0x10010f2 -#define CLUTTER_KEY_Georgian_we 0x10010f3 -#define CLUTTER_KEY_Georgian_har 0x10010f4 -#define CLUTTER_KEY_Georgian_hoe 0x10010f5 -#define CLUTTER_KEY_Georgian_fi 0x10010f6 -#define CLUTTER_KEY_Xabovedot 0x1001e8a -#define CLUTTER_KEY_Ibreve 0x100012c -#define CLUTTER_KEY_Zstroke 0x10001b5 -#define CLUTTER_KEY_Gcaron 0x10001e6 -#define CLUTTER_KEY_Ocaron 0x10001d1 -#define CLUTTER_KEY_Obarred 0x100019f -#define CLUTTER_KEY_xabovedot 0x1001e8b -#define CLUTTER_KEY_ibreve 0x100012d -#define CLUTTER_KEY_zstroke 0x10001b6 -#define CLUTTER_KEY_gcaron 0x10001e7 -#define CLUTTER_KEY_ocaron 0x10001d2 -#define CLUTTER_KEY_obarred 0x1000275 -#define CLUTTER_KEY_SCHWA 0x100018f -#define CLUTTER_KEY_schwa 0x1000259 -#define CLUTTER_KEY_EZH 0x10001b7 -#define CLUTTER_KEY_ezh 0x1000292 -#define CLUTTER_KEY_Lbelowdot 0x1001e36 -#define CLUTTER_KEY_lbelowdot 0x1001e37 -#define CLUTTER_KEY_Abelowdot 0x1001ea0 -#define CLUTTER_KEY_abelowdot 0x1001ea1 -#define CLUTTER_KEY_Ahook 0x1001ea2 -#define CLUTTER_KEY_ahook 0x1001ea3 -#define CLUTTER_KEY_Acircumflexacute 0x1001ea4 -#define CLUTTER_KEY_acircumflexacute 0x1001ea5 -#define CLUTTER_KEY_Acircumflexgrave 0x1001ea6 -#define CLUTTER_KEY_acircumflexgrave 0x1001ea7 -#define CLUTTER_KEY_Acircumflexhook 0x1001ea8 -#define CLUTTER_KEY_acircumflexhook 0x1001ea9 -#define CLUTTER_KEY_Acircumflextilde 0x1001eaa -#define CLUTTER_KEY_acircumflextilde 0x1001eab -#define CLUTTER_KEY_Acircumflexbelowdot 0x1001eac -#define CLUTTER_KEY_acircumflexbelowdot 0x1001ead -#define CLUTTER_KEY_Abreveacute 0x1001eae -#define CLUTTER_KEY_abreveacute 0x1001eaf -#define CLUTTER_KEY_Abrevegrave 0x1001eb0 -#define CLUTTER_KEY_abrevegrave 0x1001eb1 -#define CLUTTER_KEY_Abrevehook 0x1001eb2 -#define CLUTTER_KEY_abrevehook 0x1001eb3 -#define CLUTTER_KEY_Abrevetilde 0x1001eb4 -#define CLUTTER_KEY_abrevetilde 0x1001eb5 -#define CLUTTER_KEY_Abrevebelowdot 0x1001eb6 -#define CLUTTER_KEY_abrevebelowdot 0x1001eb7 -#define CLUTTER_KEY_Ebelowdot 0x1001eb8 -#define CLUTTER_KEY_ebelowdot 0x1001eb9 -#define CLUTTER_KEY_Ehook 0x1001eba -#define CLUTTER_KEY_ehook 0x1001ebb -#define CLUTTER_KEY_Etilde 0x1001ebc -#define CLUTTER_KEY_etilde 0x1001ebd -#define CLUTTER_KEY_Ecircumflexacute 0x1001ebe -#define CLUTTER_KEY_ecircumflexacute 0x1001ebf -#define CLUTTER_KEY_Ecircumflexgrave 0x1001ec0 -#define CLUTTER_KEY_ecircumflexgrave 0x1001ec1 -#define CLUTTER_KEY_Ecircumflexhook 0x1001ec2 -#define CLUTTER_KEY_ecircumflexhook 0x1001ec3 -#define CLUTTER_KEY_Ecircumflextilde 0x1001ec4 -#define CLUTTER_KEY_ecircumflextilde 0x1001ec5 -#define CLUTTER_KEY_Ecircumflexbelowdot 0x1001ec6 -#define CLUTTER_KEY_ecircumflexbelowdot 0x1001ec7 -#define CLUTTER_KEY_Ihook 0x1001ec8 -#define CLUTTER_KEY_ihook 0x1001ec9 -#define CLUTTER_KEY_Ibelowdot 0x1001eca -#define CLUTTER_KEY_ibelowdot 0x1001ecb -#define CLUTTER_KEY_Obelowdot 0x1001ecc -#define CLUTTER_KEY_obelowdot 0x1001ecd -#define CLUTTER_KEY_Ohook 0x1001ece -#define CLUTTER_KEY_ohook 0x1001ecf -#define CLUTTER_KEY_Ocircumflexacute 0x1001ed0 -#define CLUTTER_KEY_ocircumflexacute 0x1001ed1 -#define CLUTTER_KEY_Ocircumflexgrave 0x1001ed2 -#define CLUTTER_KEY_ocircumflexgrave 0x1001ed3 -#define CLUTTER_KEY_Ocircumflexhook 0x1001ed4 -#define CLUTTER_KEY_ocircumflexhook 0x1001ed5 -#define CLUTTER_KEY_Ocircumflextilde 0x1001ed6 -#define CLUTTER_KEY_ocircumflextilde 0x1001ed7 -#define CLUTTER_KEY_Ocircumflexbelowdot 0x1001ed8 -#define CLUTTER_KEY_ocircumflexbelowdot 0x1001ed9 -#define CLUTTER_KEY_Ohornacute 0x1001eda -#define CLUTTER_KEY_ohornacute 0x1001edb -#define CLUTTER_KEY_Ohorngrave 0x1001edc -#define CLUTTER_KEY_ohorngrave 0x1001edd -#define CLUTTER_KEY_Ohornhook 0x1001ede -#define CLUTTER_KEY_ohornhook 0x1001edf -#define CLUTTER_KEY_Ohorntilde 0x1001ee0 -#define CLUTTER_KEY_ohorntilde 0x1001ee1 -#define CLUTTER_KEY_Ohornbelowdot 0x1001ee2 -#define CLUTTER_KEY_ohornbelowdot 0x1001ee3 -#define CLUTTER_KEY_Ubelowdot 0x1001ee4 -#define CLUTTER_KEY_ubelowdot 0x1001ee5 -#define CLUTTER_KEY_Uhook 0x1001ee6 -#define CLUTTER_KEY_uhook 0x1001ee7 -#define CLUTTER_KEY_Uhornacute 0x1001ee8 -#define CLUTTER_KEY_uhornacute 0x1001ee9 -#define CLUTTER_KEY_Uhorngrave 0x1001eea -#define CLUTTER_KEY_uhorngrave 0x1001eeb -#define CLUTTER_KEY_Uhornhook 0x1001eec -#define CLUTTER_KEY_uhornhook 0x1001eed -#define CLUTTER_KEY_Uhorntilde 0x1001eee -#define CLUTTER_KEY_uhorntilde 0x1001eef -#define CLUTTER_KEY_Uhornbelowdot 0x1001ef0 -#define CLUTTER_KEY_uhornbelowdot 0x1001ef1 -#define CLUTTER_KEY_Ybelowdot 0x1001ef4 -#define CLUTTER_KEY_ybelowdot 0x1001ef5 -#define CLUTTER_KEY_Yhook 0x1001ef6 -#define CLUTTER_KEY_yhook 0x1001ef7 -#define CLUTTER_KEY_Ytilde 0x1001ef8 -#define CLUTTER_KEY_ytilde 0x1001ef9 -#define CLUTTER_KEY_Ohorn 0x10001a0 -#define CLUTTER_KEY_ohorn 0x10001a1 -#define CLUTTER_KEY_Uhorn 0x10001af -#define CLUTTER_KEY_uhorn 0x10001b0 -#define CLUTTER_KEY_EcuSign 0x10020a0 -#define CLUTTER_KEY_ColonSign 0x10020a1 -#define CLUTTER_KEY_CruzeiroSign 0x10020a2 -#define CLUTTER_KEY_FFrancSign 0x10020a3 -#define CLUTTER_KEY_LiraSign 0x10020a4 -#define CLUTTER_KEY_MillSign 0x10020a5 -#define CLUTTER_KEY_NairaSign 0x10020a6 -#define CLUTTER_KEY_PesetaSign 0x10020a7 -#define CLUTTER_KEY_RupeeSign 0x10020a8 -#define CLUTTER_KEY_WonSign 0x10020a9 -#define CLUTTER_KEY_NewSheqelSign 0x10020aa -#define CLUTTER_KEY_DongSign 0x10020ab -#define CLUTTER_KEY_EuroSign 0x20ac -#define CLUTTER_KEY_zerosuperior 0x1002070 -#define CLUTTER_KEY_foursuperior 0x1002074 -#define CLUTTER_KEY_fivesuperior 0x1002075 -#define CLUTTER_KEY_sixsuperior 0x1002076 -#define CLUTTER_KEY_sevensuperior 0x1002077 -#define CLUTTER_KEY_eightsuperior 0x1002078 -#define CLUTTER_KEY_ninesuperior 0x1002079 -#define CLUTTER_KEY_zerosubscript 0x1002080 -#define CLUTTER_KEY_onesubscript 0x1002081 -#define CLUTTER_KEY_twosubscript 0x1002082 -#define CLUTTER_KEY_threesubscript 0x1002083 -#define CLUTTER_KEY_foursubscript 0x1002084 -#define CLUTTER_KEY_fivesubscript 0x1002085 -#define CLUTTER_KEY_sixsubscript 0x1002086 -#define CLUTTER_KEY_sevensubscript 0x1002087 -#define CLUTTER_KEY_eightsubscript 0x1002088 -#define CLUTTER_KEY_ninesubscript 0x1002089 -#define CLUTTER_KEY_partdifferential 0x1002202 -#define CLUTTER_KEY_emptyset 0x1002205 -#define CLUTTER_KEY_elementof 0x1002208 -#define CLUTTER_KEY_notelementof 0x1002209 -#define CLUTTER_KEY_containsas 0x100220b -#define CLUTTER_KEY_squareroot 0x100221a -#define CLUTTER_KEY_cuberoot 0x100221b -#define CLUTTER_KEY_fourthroot 0x100221c -#define CLUTTER_KEY_dintegral 0x100222c -#define CLUTTER_KEY_tintegral 0x100222d -#define CLUTTER_KEY_because 0x1002235 -#define CLUTTER_KEY_approxeq 0x1002248 -#define CLUTTER_KEY_notapproxeq 0x1002247 -#define CLUTTER_KEY_notidentical 0x1002262 -#define CLUTTER_KEY_stricteq 0x1002263 -#define CLUTTER_KEY_braille_dot_1 0xfff1 -#define CLUTTER_KEY_braille_dot_2 0xfff2 -#define CLUTTER_KEY_braille_dot_3 0xfff3 -#define CLUTTER_KEY_braille_dot_4 0xfff4 -#define CLUTTER_KEY_braille_dot_5 0xfff5 -#define CLUTTER_KEY_braille_dot_6 0xfff6 -#define CLUTTER_KEY_braille_dot_7 0xfff7 -#define CLUTTER_KEY_braille_dot_8 0xfff8 -#define CLUTTER_KEY_braille_dot_9 0xfff9 -#define CLUTTER_KEY_braille_dot_10 0xfffa -#define CLUTTER_KEY_braille_blank 0x1002800 -#define CLUTTER_KEY_braille_dots_1 0x1002801 -#define CLUTTER_KEY_braille_dots_2 0x1002802 -#define CLUTTER_KEY_braille_dots_12 0x1002803 -#define CLUTTER_KEY_braille_dots_3 0x1002804 -#define CLUTTER_KEY_braille_dots_13 0x1002805 -#define CLUTTER_KEY_braille_dots_23 0x1002806 -#define CLUTTER_KEY_braille_dots_123 0x1002807 -#define CLUTTER_KEY_braille_dots_4 0x1002808 -#define CLUTTER_KEY_braille_dots_14 0x1002809 -#define CLUTTER_KEY_braille_dots_24 0x100280a -#define CLUTTER_KEY_braille_dots_124 0x100280b -#define CLUTTER_KEY_braille_dots_34 0x100280c -#define CLUTTER_KEY_braille_dots_134 0x100280d -#define CLUTTER_KEY_braille_dots_234 0x100280e -#define CLUTTER_KEY_braille_dots_1234 0x100280f -#define CLUTTER_KEY_braille_dots_5 0x1002810 -#define CLUTTER_KEY_braille_dots_15 0x1002811 -#define CLUTTER_KEY_braille_dots_25 0x1002812 -#define CLUTTER_KEY_braille_dots_125 0x1002813 -#define CLUTTER_KEY_braille_dots_35 0x1002814 -#define CLUTTER_KEY_braille_dots_135 0x1002815 -#define CLUTTER_KEY_braille_dots_235 0x1002816 -#define CLUTTER_KEY_braille_dots_1235 0x1002817 -#define CLUTTER_KEY_braille_dots_45 0x1002818 -#define CLUTTER_KEY_braille_dots_145 0x1002819 -#define CLUTTER_KEY_braille_dots_245 0x100281a -#define CLUTTER_KEY_braille_dots_1245 0x100281b -#define CLUTTER_KEY_braille_dots_345 0x100281c -#define CLUTTER_KEY_braille_dots_1345 0x100281d -#define CLUTTER_KEY_braille_dots_2345 0x100281e -#define CLUTTER_KEY_braille_dots_12345 0x100281f -#define CLUTTER_KEY_braille_dots_6 0x1002820 -#define CLUTTER_KEY_braille_dots_16 0x1002821 -#define CLUTTER_KEY_braille_dots_26 0x1002822 -#define CLUTTER_KEY_braille_dots_126 0x1002823 -#define CLUTTER_KEY_braille_dots_36 0x1002824 -#define CLUTTER_KEY_braille_dots_136 0x1002825 -#define CLUTTER_KEY_braille_dots_236 0x1002826 -#define CLUTTER_KEY_braille_dots_1236 0x1002827 -#define CLUTTER_KEY_braille_dots_46 0x1002828 -#define CLUTTER_KEY_braille_dots_146 0x1002829 -#define CLUTTER_KEY_braille_dots_246 0x100282a -#define CLUTTER_KEY_braille_dots_1246 0x100282b -#define CLUTTER_KEY_braille_dots_346 0x100282c -#define CLUTTER_KEY_braille_dots_1346 0x100282d -#define CLUTTER_KEY_braille_dots_2346 0x100282e -#define CLUTTER_KEY_braille_dots_12346 0x100282f -#define CLUTTER_KEY_braille_dots_56 0x1002830 -#define CLUTTER_KEY_braille_dots_156 0x1002831 -#define CLUTTER_KEY_braille_dots_256 0x1002832 -#define CLUTTER_KEY_braille_dots_1256 0x1002833 -#define CLUTTER_KEY_braille_dots_356 0x1002834 -#define CLUTTER_KEY_braille_dots_1356 0x1002835 -#define CLUTTER_KEY_braille_dots_2356 0x1002836 -#define CLUTTER_KEY_braille_dots_12356 0x1002837 -#define CLUTTER_KEY_braille_dots_456 0x1002838 -#define CLUTTER_KEY_braille_dots_1456 0x1002839 -#define CLUTTER_KEY_braille_dots_2456 0x100283a -#define CLUTTER_KEY_braille_dots_12456 0x100283b -#define CLUTTER_KEY_braille_dots_3456 0x100283c -#define CLUTTER_KEY_braille_dots_13456 0x100283d -#define CLUTTER_KEY_braille_dots_23456 0x100283e -#define CLUTTER_KEY_braille_dots_123456 0x100283f -#define CLUTTER_KEY_braille_dots_7 0x1002840 -#define CLUTTER_KEY_braille_dots_17 0x1002841 -#define CLUTTER_KEY_braille_dots_27 0x1002842 -#define CLUTTER_KEY_braille_dots_127 0x1002843 -#define CLUTTER_KEY_braille_dots_37 0x1002844 -#define CLUTTER_KEY_braille_dots_137 0x1002845 -#define CLUTTER_KEY_braille_dots_237 0x1002846 -#define CLUTTER_KEY_braille_dots_1237 0x1002847 -#define CLUTTER_KEY_braille_dots_47 0x1002848 -#define CLUTTER_KEY_braille_dots_147 0x1002849 -#define CLUTTER_KEY_braille_dots_247 0x100284a -#define CLUTTER_KEY_braille_dots_1247 0x100284b -#define CLUTTER_KEY_braille_dots_347 0x100284c -#define CLUTTER_KEY_braille_dots_1347 0x100284d -#define CLUTTER_KEY_braille_dots_2347 0x100284e -#define CLUTTER_KEY_braille_dots_12347 0x100284f -#define CLUTTER_KEY_braille_dots_57 0x1002850 -#define CLUTTER_KEY_braille_dots_157 0x1002851 -#define CLUTTER_KEY_braille_dots_257 0x1002852 -#define CLUTTER_KEY_braille_dots_1257 0x1002853 -#define CLUTTER_KEY_braille_dots_357 0x1002854 -#define CLUTTER_KEY_braille_dots_1357 0x1002855 -#define CLUTTER_KEY_braille_dots_2357 0x1002856 -#define CLUTTER_KEY_braille_dots_12357 0x1002857 -#define CLUTTER_KEY_braille_dots_457 0x1002858 -#define CLUTTER_KEY_braille_dots_1457 0x1002859 -#define CLUTTER_KEY_braille_dots_2457 0x100285a -#define CLUTTER_KEY_braille_dots_12457 0x100285b -#define CLUTTER_KEY_braille_dots_3457 0x100285c -#define CLUTTER_KEY_braille_dots_13457 0x100285d -#define CLUTTER_KEY_braille_dots_23457 0x100285e -#define CLUTTER_KEY_braille_dots_123457 0x100285f -#define CLUTTER_KEY_braille_dots_67 0x1002860 -#define CLUTTER_KEY_braille_dots_167 0x1002861 -#define CLUTTER_KEY_braille_dots_267 0x1002862 -#define CLUTTER_KEY_braille_dots_1267 0x1002863 -#define CLUTTER_KEY_braille_dots_367 0x1002864 -#define CLUTTER_KEY_braille_dots_1367 0x1002865 -#define CLUTTER_KEY_braille_dots_2367 0x1002866 -#define CLUTTER_KEY_braille_dots_12367 0x1002867 -#define CLUTTER_KEY_braille_dots_467 0x1002868 -#define CLUTTER_KEY_braille_dots_1467 0x1002869 -#define CLUTTER_KEY_braille_dots_2467 0x100286a -#define CLUTTER_KEY_braille_dots_12467 0x100286b -#define CLUTTER_KEY_braille_dots_3467 0x100286c -#define CLUTTER_KEY_braille_dots_13467 0x100286d -#define CLUTTER_KEY_braille_dots_23467 0x100286e -#define CLUTTER_KEY_braille_dots_123467 0x100286f -#define CLUTTER_KEY_braille_dots_567 0x1002870 -#define CLUTTER_KEY_braille_dots_1567 0x1002871 -#define CLUTTER_KEY_braille_dots_2567 0x1002872 -#define CLUTTER_KEY_braille_dots_12567 0x1002873 -#define CLUTTER_KEY_braille_dots_3567 0x1002874 -#define CLUTTER_KEY_braille_dots_13567 0x1002875 -#define CLUTTER_KEY_braille_dots_23567 0x1002876 -#define CLUTTER_KEY_braille_dots_123567 0x1002877 -#define CLUTTER_KEY_braille_dots_4567 0x1002878 -#define CLUTTER_KEY_braille_dots_14567 0x1002879 -#define CLUTTER_KEY_braille_dots_24567 0x100287a -#define CLUTTER_KEY_braille_dots_124567 0x100287b -#define CLUTTER_KEY_braille_dots_34567 0x100287c -#define CLUTTER_KEY_braille_dots_134567 0x100287d -#define CLUTTER_KEY_braille_dots_234567 0x100287e -#define CLUTTER_KEY_braille_dots_1234567 0x100287f -#define CLUTTER_KEY_braille_dots_8 0x1002880 -#define CLUTTER_KEY_braille_dots_18 0x1002881 -#define CLUTTER_KEY_braille_dots_28 0x1002882 -#define CLUTTER_KEY_braille_dots_128 0x1002883 -#define CLUTTER_KEY_braille_dots_38 0x1002884 -#define CLUTTER_KEY_braille_dots_138 0x1002885 -#define CLUTTER_KEY_braille_dots_238 0x1002886 -#define CLUTTER_KEY_braille_dots_1238 0x1002887 -#define CLUTTER_KEY_braille_dots_48 0x1002888 -#define CLUTTER_KEY_braille_dots_148 0x1002889 -#define CLUTTER_KEY_braille_dots_248 0x100288a -#define CLUTTER_KEY_braille_dots_1248 0x100288b -#define CLUTTER_KEY_braille_dots_348 0x100288c -#define CLUTTER_KEY_braille_dots_1348 0x100288d -#define CLUTTER_KEY_braille_dots_2348 0x100288e -#define CLUTTER_KEY_braille_dots_12348 0x100288f -#define CLUTTER_KEY_braille_dots_58 0x1002890 -#define CLUTTER_KEY_braille_dots_158 0x1002891 -#define CLUTTER_KEY_braille_dots_258 0x1002892 -#define CLUTTER_KEY_braille_dots_1258 0x1002893 -#define CLUTTER_KEY_braille_dots_358 0x1002894 -#define CLUTTER_KEY_braille_dots_1358 0x1002895 -#define CLUTTER_KEY_braille_dots_2358 0x1002896 -#define CLUTTER_KEY_braille_dots_12358 0x1002897 -#define CLUTTER_KEY_braille_dots_458 0x1002898 -#define CLUTTER_KEY_braille_dots_1458 0x1002899 -#define CLUTTER_KEY_braille_dots_2458 0x100289a -#define CLUTTER_KEY_braille_dots_12458 0x100289b -#define CLUTTER_KEY_braille_dots_3458 0x100289c -#define CLUTTER_KEY_braille_dots_13458 0x100289d -#define CLUTTER_KEY_braille_dots_23458 0x100289e -#define CLUTTER_KEY_braille_dots_123458 0x100289f -#define CLUTTER_KEY_braille_dots_68 0x10028a0 -#define CLUTTER_KEY_braille_dots_168 0x10028a1 -#define CLUTTER_KEY_braille_dots_268 0x10028a2 -#define CLUTTER_KEY_braille_dots_1268 0x10028a3 -#define CLUTTER_KEY_braille_dots_368 0x10028a4 -#define CLUTTER_KEY_braille_dots_1368 0x10028a5 -#define CLUTTER_KEY_braille_dots_2368 0x10028a6 -#define CLUTTER_KEY_braille_dots_12368 0x10028a7 -#define CLUTTER_KEY_braille_dots_468 0x10028a8 -#define CLUTTER_KEY_braille_dots_1468 0x10028a9 -#define CLUTTER_KEY_braille_dots_2468 0x10028aa -#define CLUTTER_KEY_braille_dots_12468 0x10028ab -#define CLUTTER_KEY_braille_dots_3468 0x10028ac -#define CLUTTER_KEY_braille_dots_13468 0x10028ad -#define CLUTTER_KEY_braille_dots_23468 0x10028ae -#define CLUTTER_KEY_braille_dots_123468 0x10028af -#define CLUTTER_KEY_braille_dots_568 0x10028b0 -#define CLUTTER_KEY_braille_dots_1568 0x10028b1 -#define CLUTTER_KEY_braille_dots_2568 0x10028b2 -#define CLUTTER_KEY_braille_dots_12568 0x10028b3 -#define CLUTTER_KEY_braille_dots_3568 0x10028b4 -#define CLUTTER_KEY_braille_dots_13568 0x10028b5 -#define CLUTTER_KEY_braille_dots_23568 0x10028b6 -#define CLUTTER_KEY_braille_dots_123568 0x10028b7 -#define CLUTTER_KEY_braille_dots_4568 0x10028b8 -#define CLUTTER_KEY_braille_dots_14568 0x10028b9 -#define CLUTTER_KEY_braille_dots_24568 0x10028ba -#define CLUTTER_KEY_braille_dots_124568 0x10028bb -#define CLUTTER_KEY_braille_dots_34568 0x10028bc -#define CLUTTER_KEY_braille_dots_134568 0x10028bd -#define CLUTTER_KEY_braille_dots_234568 0x10028be -#define CLUTTER_KEY_braille_dots_1234568 0x10028bf -#define CLUTTER_KEY_braille_dots_78 0x10028c0 -#define CLUTTER_KEY_braille_dots_178 0x10028c1 -#define CLUTTER_KEY_braille_dots_278 0x10028c2 -#define CLUTTER_KEY_braille_dots_1278 0x10028c3 -#define CLUTTER_KEY_braille_dots_378 0x10028c4 -#define CLUTTER_KEY_braille_dots_1378 0x10028c5 -#define CLUTTER_KEY_braille_dots_2378 0x10028c6 -#define CLUTTER_KEY_braille_dots_12378 0x10028c7 -#define CLUTTER_KEY_braille_dots_478 0x10028c8 -#define CLUTTER_KEY_braille_dots_1478 0x10028c9 -#define CLUTTER_KEY_braille_dots_2478 0x10028ca -#define CLUTTER_KEY_braille_dots_12478 0x10028cb -#define CLUTTER_KEY_braille_dots_3478 0x10028cc -#define CLUTTER_KEY_braille_dots_13478 0x10028cd -#define CLUTTER_KEY_braille_dots_23478 0x10028ce -#define CLUTTER_KEY_braille_dots_123478 0x10028cf -#define CLUTTER_KEY_braille_dots_578 0x10028d0 -#define CLUTTER_KEY_braille_dots_1578 0x10028d1 -#define CLUTTER_KEY_braille_dots_2578 0x10028d2 -#define CLUTTER_KEY_braille_dots_12578 0x10028d3 -#define CLUTTER_KEY_braille_dots_3578 0x10028d4 -#define CLUTTER_KEY_braille_dots_13578 0x10028d5 -#define CLUTTER_KEY_braille_dots_23578 0x10028d6 -#define CLUTTER_KEY_braille_dots_123578 0x10028d7 -#define CLUTTER_KEY_braille_dots_4578 0x10028d8 -#define CLUTTER_KEY_braille_dots_14578 0x10028d9 -#define CLUTTER_KEY_braille_dots_24578 0x10028da -#define CLUTTER_KEY_braille_dots_124578 0x10028db -#define CLUTTER_KEY_braille_dots_34578 0x10028dc -#define CLUTTER_KEY_braille_dots_134578 0x10028dd -#define CLUTTER_KEY_braille_dots_234578 0x10028de -#define CLUTTER_KEY_braille_dots_1234578 0x10028df -#define CLUTTER_KEY_braille_dots_678 0x10028e0 -#define CLUTTER_KEY_braille_dots_1678 0x10028e1 -#define CLUTTER_KEY_braille_dots_2678 0x10028e2 -#define CLUTTER_KEY_braille_dots_12678 0x10028e3 -#define CLUTTER_KEY_braille_dots_3678 0x10028e4 -#define CLUTTER_KEY_braille_dots_13678 0x10028e5 -#define CLUTTER_KEY_braille_dots_23678 0x10028e6 -#define CLUTTER_KEY_braille_dots_123678 0x10028e7 -#define CLUTTER_KEY_braille_dots_4678 0x10028e8 -#define CLUTTER_KEY_braille_dots_14678 0x10028e9 -#define CLUTTER_KEY_braille_dots_24678 0x10028ea -#define CLUTTER_KEY_braille_dots_124678 0x10028eb -#define CLUTTER_KEY_braille_dots_34678 0x10028ec -#define CLUTTER_KEY_braille_dots_134678 0x10028ed -#define CLUTTER_KEY_braille_dots_234678 0x10028ee -#define CLUTTER_KEY_braille_dots_1234678 0x10028ef -#define CLUTTER_KEY_braille_dots_5678 0x10028f0 -#define CLUTTER_KEY_braille_dots_15678 0x10028f1 -#define CLUTTER_KEY_braille_dots_25678 0x10028f2 -#define CLUTTER_KEY_braille_dots_125678 0x10028f3 -#define CLUTTER_KEY_braille_dots_35678 0x10028f4 -#define CLUTTER_KEY_braille_dots_135678 0x10028f5 -#define CLUTTER_KEY_braille_dots_235678 0x10028f6 -#define CLUTTER_KEY_braille_dots_1235678 0x10028f7 -#define CLUTTER_KEY_braille_dots_45678 0x10028f8 -#define CLUTTER_KEY_braille_dots_145678 0x10028f9 -#define CLUTTER_KEY_braille_dots_245678 0x10028fa -#define CLUTTER_KEY_braille_dots_1245678 0x10028fb -#define CLUTTER_KEY_braille_dots_345678 0x10028fc -#define CLUTTER_KEY_braille_dots_1345678 0x10028fd -#define CLUTTER_KEY_braille_dots_2345678 0x10028fe -#define CLUTTER_KEY_braille_dots_12345678 0x10028ff -#define CLUTTER_KEY_Sinh_ng 0x1000d82 -#define CLUTTER_KEY_Sinh_h2 0x1000d83 -#define CLUTTER_KEY_Sinh_a 0x1000d85 -#define CLUTTER_KEY_Sinh_aa 0x1000d86 -#define CLUTTER_KEY_Sinh_ae 0x1000d87 -#define CLUTTER_KEY_Sinh_aee 0x1000d88 -#define CLUTTER_KEY_Sinh_i 0x1000d89 -#define CLUTTER_KEY_Sinh_ii 0x1000d8a -#define CLUTTER_KEY_Sinh_u 0x1000d8b -#define CLUTTER_KEY_Sinh_uu 0x1000d8c -#define CLUTTER_KEY_Sinh_ri 0x1000d8d -#define CLUTTER_KEY_Sinh_rii 0x1000d8e -#define CLUTTER_KEY_Sinh_lu 0x1000d8f -#define CLUTTER_KEY_Sinh_luu 0x1000d90 -#define CLUTTER_KEY_Sinh_e 0x1000d91 -#define CLUTTER_KEY_Sinh_ee 0x1000d92 -#define CLUTTER_KEY_Sinh_ai 0x1000d93 -#define CLUTTER_KEY_Sinh_o 0x1000d94 -#define CLUTTER_KEY_Sinh_oo 0x1000d95 -#define CLUTTER_KEY_Sinh_au 0x1000d96 -#define CLUTTER_KEY_Sinh_ka 0x1000d9a -#define CLUTTER_KEY_Sinh_kha 0x1000d9b -#define CLUTTER_KEY_Sinh_ga 0x1000d9c -#define CLUTTER_KEY_Sinh_gha 0x1000d9d -#define CLUTTER_KEY_Sinh_ng2 0x1000d9e -#define CLUTTER_KEY_Sinh_nga 0x1000d9f -#define CLUTTER_KEY_Sinh_ca 0x1000da0 -#define CLUTTER_KEY_Sinh_cha 0x1000da1 -#define CLUTTER_KEY_Sinh_ja 0x1000da2 -#define CLUTTER_KEY_Sinh_jha 0x1000da3 -#define CLUTTER_KEY_Sinh_nya 0x1000da4 -#define CLUTTER_KEY_Sinh_jnya 0x1000da5 -#define CLUTTER_KEY_Sinh_nja 0x1000da6 -#define CLUTTER_KEY_Sinh_tta 0x1000da7 -#define CLUTTER_KEY_Sinh_ttha 0x1000da8 -#define CLUTTER_KEY_Sinh_dda 0x1000da9 -#define CLUTTER_KEY_Sinh_ddha 0x1000daa -#define CLUTTER_KEY_Sinh_nna 0x1000dab -#define CLUTTER_KEY_Sinh_ndda 0x1000dac -#define CLUTTER_KEY_Sinh_tha 0x1000dad -#define CLUTTER_KEY_Sinh_thha 0x1000dae -#define CLUTTER_KEY_Sinh_dha 0x1000daf -#define CLUTTER_KEY_Sinh_dhha 0x1000db0 -#define CLUTTER_KEY_Sinh_na 0x1000db1 -#define CLUTTER_KEY_Sinh_ndha 0x1000db3 -#define CLUTTER_KEY_Sinh_pa 0x1000db4 -#define CLUTTER_KEY_Sinh_pha 0x1000db5 -#define CLUTTER_KEY_Sinh_ba 0x1000db6 -#define CLUTTER_KEY_Sinh_bha 0x1000db7 -#define CLUTTER_KEY_Sinh_ma 0x1000db8 -#define CLUTTER_KEY_Sinh_mba 0x1000db9 -#define CLUTTER_KEY_Sinh_ya 0x1000dba -#define CLUTTER_KEY_Sinh_ra 0x1000dbb -#define CLUTTER_KEY_Sinh_la 0x1000dbd -#define CLUTTER_KEY_Sinh_va 0x1000dc0 -#define CLUTTER_KEY_Sinh_sha 0x1000dc1 -#define CLUTTER_KEY_Sinh_ssha 0x1000dc2 -#define CLUTTER_KEY_Sinh_sa 0x1000dc3 -#define CLUTTER_KEY_Sinh_ha 0x1000dc4 -#define CLUTTER_KEY_Sinh_lla 0x1000dc5 -#define CLUTTER_KEY_Sinh_fa 0x1000dc6 -#define CLUTTER_KEY_Sinh_al 0x1000dca -#define CLUTTER_KEY_Sinh_aa2 0x1000dcf -#define CLUTTER_KEY_Sinh_ae2 0x1000dd0 -#define CLUTTER_KEY_Sinh_aee2 0x1000dd1 -#define CLUTTER_KEY_Sinh_i2 0x1000dd2 -#define CLUTTER_KEY_Sinh_ii2 0x1000dd3 -#define CLUTTER_KEY_Sinh_u2 0x1000dd4 -#define CLUTTER_KEY_Sinh_uu2 0x1000dd6 -#define CLUTTER_KEY_Sinh_ru2 0x1000dd8 -#define CLUTTER_KEY_Sinh_e2 0x1000dd9 -#define CLUTTER_KEY_Sinh_ee2 0x1000dda -#define CLUTTER_KEY_Sinh_ai2 0x1000ddb -#define CLUTTER_KEY_Sinh_o2 0x1000ddc -#define CLUTTER_KEY_Sinh_oo2 0x1000ddd -#define CLUTTER_KEY_Sinh_au2 0x1000dde -#define CLUTTER_KEY_Sinh_lu2 0x1000ddf -#define CLUTTER_KEY_Sinh_ruu2 0x1000df2 -#define CLUTTER_KEY_Sinh_luu2 0x1000df3 -#define CLUTTER_KEY_Sinh_kunddaliya 0x1000df4 -#define CLUTTER_KEY_ModeLock 0x1008ff01 -#define CLUTTER_KEY_MonBrightnessUp 0x1008ff02 -#define CLUTTER_KEY_MonBrightnessDown 0x1008ff03 -#define CLUTTER_KEY_KbdLightOnOff 0x1008ff04 -#define CLUTTER_KEY_KbdBrightnessUp 0x1008ff05 -#define CLUTTER_KEY_KbdBrightnessDown 0x1008ff06 -#define CLUTTER_KEY_Standby 0x1008ff10 -#define CLUTTER_KEY_AudioLowerVolume 0x1008ff11 -#define CLUTTER_KEY_AudioMute 0x1008ff12 -#define CLUTTER_KEY_AudioRaiseVolume 0x1008ff13 -#define CLUTTER_KEY_AudioPlay 0x1008ff14 -#define CLUTTER_KEY_AudioStop 0x1008ff15 -#define CLUTTER_KEY_AudioPrev 0x1008ff16 -#define CLUTTER_KEY_AudioNext 0x1008ff17 -#define CLUTTER_KEY_HomePage 0x1008ff18 -#define CLUTTER_KEY_Mail 0x1008ff19 -#define CLUTTER_KEY_Start 0x1008ff1a -#define CLUTTER_KEY_Search 0x1008ff1b -#define CLUTTER_KEY_AudioRecord 0x1008ff1c -#define CLUTTER_KEY_Calculator 0x1008ff1d -#define CLUTTER_KEY_Memo 0x1008ff1e -#define CLUTTER_KEY_ToDoList 0x1008ff1f -#define CLUTTER_KEY_Calendar 0x1008ff20 -#define CLUTTER_KEY_PowerDown 0x1008ff21 -#define CLUTTER_KEY_ContrastAdjust 0x1008ff22 -#define CLUTTER_KEY_RockerUp 0x1008ff23 -#define CLUTTER_KEY_RockerDown 0x1008ff24 -#define CLUTTER_KEY_RockerEnter 0x1008ff25 -#define CLUTTER_KEY_Back 0x1008ff26 -#define CLUTTER_KEY_Forward 0x1008ff27 -#define CLUTTER_KEY_Stop 0x1008ff28 -#define CLUTTER_KEY_Refresh 0x1008ff29 -#define CLUTTER_KEY_PowerOff 0x1008ff2a -#define CLUTTER_KEY_WakeUp 0x1008ff2b -#define CLUTTER_KEY_Eject 0x1008ff2c -#define CLUTTER_KEY_ScreenSaver 0x1008ff2d -#define CLUTTER_KEY_WWW 0x1008ff2e -#define CLUTTER_KEY_Sleep 0x1008ff2f -#define CLUTTER_KEY_Favorites 0x1008ff30 -#define CLUTTER_KEY_AudioPause 0x1008ff31 -#define CLUTTER_KEY_AudioMedia 0x1008ff32 -#define CLUTTER_KEY_MyComputer 0x1008ff33 -#define CLUTTER_KEY_VendorHome 0x1008ff34 -#define CLUTTER_KEY_LightBulb 0x1008ff35 -#define CLUTTER_KEY_Shop 0x1008ff36 -#define CLUTTER_KEY_History 0x1008ff37 -#define CLUTTER_KEY_OpenURL 0x1008ff38 -#define CLUTTER_KEY_AddFavorite 0x1008ff39 -#define CLUTTER_KEY_HotLinks 0x1008ff3a -#define CLUTTER_KEY_BrightnessAdjust 0x1008ff3b -#define CLUTTER_KEY_Finance 0x1008ff3c -#define CLUTTER_KEY_Community 0x1008ff3d -#define CLUTTER_KEY_AudioRewind 0x1008ff3e -#define CLUTTER_KEY_BackForward 0x1008ff3f -#define CLUTTER_KEY_Launch0 0x1008ff40 -#define CLUTTER_KEY_Launch1 0x1008ff41 -#define CLUTTER_KEY_Launch2 0x1008ff42 -#define CLUTTER_KEY_Launch3 0x1008ff43 -#define CLUTTER_KEY_Launch4 0x1008ff44 -#define CLUTTER_KEY_Launch5 0x1008ff45 -#define CLUTTER_KEY_Launch6 0x1008ff46 -#define CLUTTER_KEY_Launch7 0x1008ff47 -#define CLUTTER_KEY_Launch8 0x1008ff48 -#define CLUTTER_KEY_Launch9 0x1008ff49 -#define CLUTTER_KEY_LaunchA 0x1008ff4a -#define CLUTTER_KEY_LaunchB 0x1008ff4b -#define CLUTTER_KEY_LaunchC 0x1008ff4c -#define CLUTTER_KEY_LaunchD 0x1008ff4d -#define CLUTTER_KEY_LaunchE 0x1008ff4e -#define CLUTTER_KEY_LaunchF 0x1008ff4f -#define CLUTTER_KEY_ApplicationLeft 0x1008ff50 -#define CLUTTER_KEY_ApplicationRight 0x1008ff51 -#define CLUTTER_KEY_Book 0x1008ff52 -#define CLUTTER_KEY_CD 0x1008ff53 -#define CLUTTER_KEY_WindowClear 0x1008ff55 -#define CLUTTER_KEY_Close 0x1008ff56 -#define CLUTTER_KEY_Copy 0x1008ff57 -#define CLUTTER_KEY_Cut 0x1008ff58 -#define CLUTTER_KEY_Display 0x1008ff59 -#define CLUTTER_KEY_DOS 0x1008ff5a -#define CLUTTER_KEY_Documents 0x1008ff5b -#define CLUTTER_KEY_Excel 0x1008ff5c -#define CLUTTER_KEY_Explorer 0x1008ff5d -#define CLUTTER_KEY_Game 0x1008ff5e -#define CLUTTER_KEY_Go 0x1008ff5f -#define CLUTTER_KEY_iTouch 0x1008ff60 -#define CLUTTER_KEY_LogOff 0x1008ff61 -#define CLUTTER_KEY_Market 0x1008ff62 -#define CLUTTER_KEY_Meeting 0x1008ff63 -#define CLUTTER_KEY_MenuKB 0x1008ff65 -#define CLUTTER_KEY_MenuPB 0x1008ff66 -#define CLUTTER_KEY_MySites 0x1008ff67 -#define CLUTTER_KEY_New 0x1008ff68 -#define CLUTTER_KEY_News 0x1008ff69 -#define CLUTTER_KEY_OfficeHome 0x1008ff6a -#define CLUTTER_KEY_Open 0x1008ff6b -#define CLUTTER_KEY_Option 0x1008ff6c -#define CLUTTER_KEY_Paste 0x1008ff6d -#define CLUTTER_KEY_Phone 0x1008ff6e -#define CLUTTER_KEY_Reply 0x1008ff72 -#define CLUTTER_KEY_Reload 0x1008ff73 -#define CLUTTER_KEY_RotateWindows 0x1008ff74 -#define CLUTTER_KEY_RotationPB 0x1008ff75 -#define CLUTTER_KEY_RotationKB 0x1008ff76 -#define CLUTTER_KEY_Save 0x1008ff77 -#define CLUTTER_KEY_ScrollUp 0x1008ff78 -#define CLUTTER_KEY_ScrollDown 0x1008ff79 -#define CLUTTER_KEY_ScrollClick 0x1008ff7a -#define CLUTTER_KEY_Send 0x1008ff7b -#define CLUTTER_KEY_Spell 0x1008ff7c -#define CLUTTER_KEY_SplitScreen 0x1008ff7d -#define CLUTTER_KEY_Support 0x1008ff7e -#define CLUTTER_KEY_TaskPane 0x1008ff7f -#define CLUTTER_KEY_Terminal 0x1008ff80 -#define CLUTTER_KEY_Tools 0x1008ff81 -#define CLUTTER_KEY_Travel 0x1008ff82 -#define CLUTTER_KEY_UserPB 0x1008ff84 -#define CLUTTER_KEY_User1KB 0x1008ff85 -#define CLUTTER_KEY_User2KB 0x1008ff86 -#define CLUTTER_KEY_Video 0x1008ff87 -#define CLUTTER_KEY_WheelButton 0x1008ff88 -#define CLUTTER_KEY_Word 0x1008ff89 -#define CLUTTER_KEY_Xfer 0x1008ff8a -#define CLUTTER_KEY_ZoomIn 0x1008ff8b -#define CLUTTER_KEY_ZoomOut 0x1008ff8c -#define CLUTTER_KEY_Away 0x1008ff8d -#define CLUTTER_KEY_Messenger 0x1008ff8e -#define CLUTTER_KEY_WebCam 0x1008ff8f -#define CLUTTER_KEY_MailForward 0x1008ff90 -#define CLUTTER_KEY_Pictures 0x1008ff91 -#define CLUTTER_KEY_Music 0x1008ff92 -#define CLUTTER_KEY_Battery 0x1008ff93 -#define CLUTTER_KEY_Bluetooth 0x1008ff94 -#define CLUTTER_KEY_WLAN 0x1008ff95 -#define CLUTTER_KEY_UWB 0x1008ff96 -#define CLUTTER_KEY_AudioForward 0x1008ff97 -#define CLUTTER_KEY_AudioRepeat 0x1008ff98 -#define CLUTTER_KEY_AudioRandomPlay 0x1008ff99 -#define CLUTTER_KEY_Subtitle 0x1008ff9a -#define CLUTTER_KEY_AudioCycleTrack 0x1008ff9b -#define CLUTTER_KEY_CycleAngle 0x1008ff9c -#define CLUTTER_KEY_FrameBack 0x1008ff9d -#define CLUTTER_KEY_FrameForward 0x1008ff9e -#define CLUTTER_KEY_Time 0x1008ff9f -#define CLUTTER_KEY_SelectButton 0x1008ffa0 -#define CLUTTER_KEY_View 0x1008ffa1 -#define CLUTTER_KEY_TopMenu 0x1008ffa2 -#define CLUTTER_KEY_Red 0x1008ffa3 -#define CLUTTER_KEY_Green 0x1008ffa4 -#define CLUTTER_KEY_Yellow 0x1008ffa5 -#define CLUTTER_KEY_Blue 0x1008ffa6 -#define CLUTTER_KEY_Suspend 0x1008ffa7 -#define CLUTTER_KEY_Hibernate 0x1008ffa8 -#define CLUTTER_KEY_TouchpadToggle 0x1008ffa9 -#define CLUTTER_KEY_TouchpadOn 0x1008ffb0 -#define CLUTTER_KEY_TouchpadOff 0x1008ffb1 -#define CLUTTER_KEY_AudioMicMute 0x1008ffb2 -#define CLUTTER_KEY_Switch_VT_1 0x1008fe01 -#define CLUTTER_KEY_Switch_VT_2 0x1008fe02 -#define CLUTTER_KEY_Switch_VT_3 0x1008fe03 -#define CLUTTER_KEY_Switch_VT_4 0x1008fe04 -#define CLUTTER_KEY_Switch_VT_5 0x1008fe05 -#define CLUTTER_KEY_Switch_VT_6 0x1008fe06 -#define CLUTTER_KEY_Switch_VT_7 0x1008fe07 -#define CLUTTER_KEY_Switch_VT_8 0x1008fe08 -#define CLUTTER_KEY_Switch_VT_9 0x1008fe09 -#define CLUTTER_KEY_Switch_VT_10 0x1008fe0a -#define CLUTTER_KEY_Switch_VT_11 0x1008fe0b -#define CLUTTER_KEY_Switch_VT_12 0x1008fe0c -#define CLUTTER_KEY_Ungrab 0x1008fe20 -#define CLUTTER_KEY_ClearGrab 0x1008fe21 -#define CLUTTER_KEY_Next_VMode 0x1008fe22 -#define CLUTTER_KEY_Prev_VMode 0x1008fe23 -#define CLUTTER_KEY_LogWindowTree 0x1008fe24 -#define CLUTTER_KEY_LogGrabInfo 0x1008fe25 diff --git a/mutter/clutter/clutter/clutter-keyval.c b/mutter/clutter/clutter/clutter-keyval.c deleted file mode 100644 index 676b0b8..0000000 --- a/mutter/clutter/clutter/clutter-keyval.c +++ /dev/null @@ -1,215 +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, see . - * - * Author: Bilal Elmoussaoui - * - * The code is a modified version of the GDK implementation - */ - -#include -#include - -#include "config.h" - -#include "clutter/clutter-keyval.h" -#include "clutter/clutter-event.h" -#include "clutter/clutter-keysyms.h" -#include "clutter/clutter-keyname-table.h" - -#define CLUTTER_NUM_KEYS G_N_ELEMENTS (clutter_keys_by_keyval) - -/** - * clutter_keyval_convert_case: - * @symbol: a keyval. - * @lower: (out): return location of the lowercase version of @symbol. - * @upper: (out): return location of the uppercase version of @symbol. - */ -void -clutter_keyval_convert_case (unsigned int symbol, - unsigned int *lower, - unsigned int *upper) -{ - unsigned int xlower, xupper; - - xlower = symbol; - xupper = symbol; - - /* Check for directly encoded 24-bit UCS characters: */ - if ((symbol & 0xff000000) == 0x01000000) - { - if (lower) - *lower = clutter_unicode_to_keysym (g_unichar_tolower (symbol & 0x00ffffff)); - if (upper) - *upper = clutter_unicode_to_keysym (g_unichar_toupper (symbol & 0x00ffffff)); - return; - } - - switch (symbol >> 8) - { - case 0: /* Latin 1 */ - if ((symbol >= CLUTTER_KEY_A) && (symbol <= CLUTTER_KEY_Z)) - xlower += (CLUTTER_KEY_a - CLUTTER_KEY_A); - else if ((symbol >= CLUTTER_KEY_a) && (symbol <= CLUTTER_KEY_z)) - xupper -= (CLUTTER_KEY_a - CLUTTER_KEY_A); - else if ((symbol >= CLUTTER_KEY_Agrave) && (symbol <= CLUTTER_KEY_Odiaeresis)) - xlower += (CLUTTER_KEY_agrave - CLUTTER_KEY_Agrave); - else if ((symbol >= CLUTTER_KEY_agrave) && (symbol <= CLUTTER_KEY_odiaeresis)) - xupper -= (CLUTTER_KEY_agrave - CLUTTER_KEY_Agrave); - else if ((symbol >= CLUTTER_KEY_Ooblique) && (symbol <= CLUTTER_KEY_Thorn)) - xlower += (CLUTTER_KEY_oslash - CLUTTER_KEY_Ooblique); - else if ((symbol >= CLUTTER_KEY_oslash) && (symbol <= CLUTTER_KEY_thorn)) - xupper -= (CLUTTER_KEY_oslash - CLUTTER_KEY_Ooblique); - break; - - case 1: /* Latin 2 */ - /* Assume the KeySym is a legal value (ignore discontinuities) */ - if (symbol == CLUTTER_KEY_Aogonek) - xlower = CLUTTER_KEY_aogonek; - else if (symbol >= CLUTTER_KEY_Lstroke && symbol <= CLUTTER_KEY_Sacute) - xlower += (CLUTTER_KEY_lstroke - CLUTTER_KEY_Lstroke); - else if (symbol >= CLUTTER_KEY_Scaron && symbol <= CLUTTER_KEY_Zacute) - xlower += (CLUTTER_KEY_scaron - CLUTTER_KEY_Scaron); - else if (symbol >= CLUTTER_KEY_Zcaron && symbol <= CLUTTER_KEY_Zabovedot) - xlower += (CLUTTER_KEY_zcaron - CLUTTER_KEY_Zcaron); - else if (symbol == CLUTTER_KEY_aogonek) - xupper = CLUTTER_KEY_Aogonek; - else if (symbol >= CLUTTER_KEY_lstroke && symbol <= CLUTTER_KEY_sacute) - xupper -= (CLUTTER_KEY_lstroke - CLUTTER_KEY_Lstroke); - else if (symbol >= CLUTTER_KEY_scaron && symbol <= CLUTTER_KEY_zacute) - xupper -= (CLUTTER_KEY_scaron - CLUTTER_KEY_Scaron); - else if (symbol >= CLUTTER_KEY_zcaron && symbol <= CLUTTER_KEY_zabovedot) - xupper -= (CLUTTER_KEY_zcaron - CLUTTER_KEY_Zcaron); - else if (symbol >= CLUTTER_KEY_Racute && symbol <= CLUTTER_KEY_Tcedilla) - xlower += (CLUTTER_KEY_racute - CLUTTER_KEY_Racute); - else if (symbol >= CLUTTER_KEY_racute && symbol <= CLUTTER_KEY_tcedilla) - xupper -= (CLUTTER_KEY_racute - CLUTTER_KEY_Racute); - break; - - case 2: /* Latin 3 */ - /* Assume the KeySym is a legal value (ignore discontinuities) */ - if (symbol >= CLUTTER_KEY_Hstroke && symbol <= CLUTTER_KEY_Hcircumflex) - xlower += (CLUTTER_KEY_hstroke - CLUTTER_KEY_Hstroke); - else if (symbol >= CLUTTER_KEY_Gbreve && symbol <= CLUTTER_KEY_Jcircumflex) - xlower += (CLUTTER_KEY_gbreve - CLUTTER_KEY_Gbreve); - else if (symbol >= CLUTTER_KEY_hstroke && symbol <= CLUTTER_KEY_hcircumflex) - xupper -= (CLUTTER_KEY_hstroke - CLUTTER_KEY_Hstroke); - else if (symbol >= CLUTTER_KEY_gbreve && symbol <= CLUTTER_KEY_jcircumflex) - xupper -= (CLUTTER_KEY_gbreve - CLUTTER_KEY_Gbreve); - else if (symbol >= CLUTTER_KEY_Cabovedot && symbol <= CLUTTER_KEY_Scircumflex) - xlower += (CLUTTER_KEY_cabovedot - CLUTTER_KEY_Cabovedot); - else if (symbol >= CLUTTER_KEY_cabovedot && symbol <= CLUTTER_KEY_scircumflex) - xupper -= (CLUTTER_KEY_cabovedot - CLUTTER_KEY_Cabovedot); - break; - - case 3: /* Latin 4 */ - /* Assume the KeySym is a legal value (ignore discontinuities) */ - if (symbol >= CLUTTER_KEY_Rcedilla && symbol <= CLUTTER_KEY_Tslash) - xlower += (CLUTTER_KEY_rcedilla - CLUTTER_KEY_Rcedilla); - else if (symbol >= CLUTTER_KEY_rcedilla && symbol <= CLUTTER_KEY_tslash) - xupper -= (CLUTTER_KEY_rcedilla - CLUTTER_KEY_Rcedilla); - else if (symbol == CLUTTER_KEY_ENG) - xlower = CLUTTER_KEY_eng; - else if (symbol == CLUTTER_KEY_eng) - xupper = CLUTTER_KEY_ENG; - else if (symbol >= CLUTTER_KEY_Amacron && symbol <= CLUTTER_KEY_Umacron) - xlower += (CLUTTER_KEY_amacron - CLUTTER_KEY_Amacron); - else if (symbol >= CLUTTER_KEY_amacron && symbol <= CLUTTER_KEY_umacron) - xupper -= (CLUTTER_KEY_amacron - CLUTTER_KEY_Amacron); - break; - - case 6: /* Cyrillic */ - /* Assume the KeySym is a legal value (ignore discontinuities) */ - if (symbol >= CLUTTER_KEY_Serbian_DJE && symbol <= CLUTTER_KEY_Serbian_DZE) - xlower -= (CLUTTER_KEY_Serbian_DJE - CLUTTER_KEY_Serbian_dje); - else if (symbol >= CLUTTER_KEY_Serbian_dje && symbol <= CLUTTER_KEY_Serbian_dze) - xupper += (CLUTTER_KEY_Serbian_DJE - CLUTTER_KEY_Serbian_dje); - else if (symbol >= CLUTTER_KEY_Cyrillic_YU && symbol <= CLUTTER_KEY_Cyrillic_HARDSIGN) - xlower -= (CLUTTER_KEY_Cyrillic_YU - CLUTTER_KEY_Cyrillic_yu); - else if (symbol >= CLUTTER_KEY_Cyrillic_yu && symbol <= CLUTTER_KEY_Cyrillic_hardsign) - xupper += (CLUTTER_KEY_Cyrillic_YU - CLUTTER_KEY_Cyrillic_yu); - break; - - case 7: /* Greek */ - /* Assume the KeySym is a legal value (ignore discontinuities) */ - if (symbol >= CLUTTER_KEY_Greek_ALPHAaccent && symbol <= CLUTTER_KEY_Greek_OMEGAaccent) - xlower += (CLUTTER_KEY_Greek_alphaaccent - CLUTTER_KEY_Greek_ALPHAaccent); - else if (symbol >= CLUTTER_KEY_Greek_alphaaccent && symbol <= CLUTTER_KEY_Greek_omegaaccent && - symbol != CLUTTER_KEY_Greek_iotaaccentdieresis && - symbol != CLUTTER_KEY_Greek_upsilonaccentdieresis) - xupper -= (CLUTTER_KEY_Greek_alphaaccent - CLUTTER_KEY_Greek_ALPHAaccent); - else if (symbol >= CLUTTER_KEY_Greek_ALPHA && symbol <= CLUTTER_KEY_Greek_OMEGA) - xlower += (CLUTTER_KEY_Greek_alpha - CLUTTER_KEY_Greek_ALPHA); - else if (symbol == CLUTTER_KEY_Greek_finalsmallsigma) - xupper = CLUTTER_KEY_Greek_SIGMA; - else if (symbol >= CLUTTER_KEY_Greek_alpha && symbol <= CLUTTER_KEY_Greek_omega) - xupper -= (CLUTTER_KEY_Greek_alpha - CLUTTER_KEY_Greek_ALPHA); - break; - - default: - break; - } - - if (lower) - *lower = xlower; - if (upper) - *upper = xupper; -} - -static int -clutter_keys_keyval_compare (const void *pkey, const void *pbase) -{ - return (*(int *) pkey) - ((clutter_key *) pbase)->keyval; -} - -/** - * clutter_keyval_name: - * @keyval: A key value. - * - * Returns: (nullable) (transfer none): The corresponding symbolic name. - */ -const char * -clutter_keyval_name (unsigned int keyval) -{ - static char buf[100]; - clutter_key *found; - - /* Check for directly encoded 24-bit UCS characters: */ - if ((keyval & 0xff000000) == 0x01000000) - { - g_sprintf (buf, "U+%.04X", (keyval & 0x00ffffff)); - return buf; - } - - found = bsearch (&keyval, clutter_keys_by_keyval, - CLUTTER_NUM_KEYS, sizeof (clutter_key), - clutter_keys_keyval_compare); - - if (found != NULL) - { - while ((found > clutter_keys_by_keyval) && - ((found - 1)->keyval == keyval)) - found--; - - return (char *) (keynames + found->offset); - } - else if (keyval != 0) - { - g_sprintf (buf, "%#x", keyval); - return buf; - } - - return NULL; -} diff --git a/mutter/clutter/clutter/clutter-keyval.h b/mutter/clutter/clutter/clutter-keyval.h deleted file mode 100644 index 8e6267a..0000000 --- a/mutter/clutter/clutter/clutter-keyval.h +++ /dev/null @@ -1,40 +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, see . - * - * Author: Bilal Elmoussaoui - * - * The code is a modified version of the GDK implementation - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -CLUTTER_EXPORT -void clutter_keyval_convert_case (unsigned int symbol, - unsigned int *lower, - unsigned int *upper); - -CLUTTER_EXPORT -const char * clutter_keyval_name (unsigned int keyval); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-layout-manager.c b/mutter/clutter/clutter/clutter-layout-manager.c deleted file mode 100644 index dee019e..0000000 --- a/mutter/clutter/clutter/clutter-layout-manager.c +++ /dev/null @@ -1,932 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterLayoutManager: - * - * Layout managers base class - * - * #ClutterLayoutManager is a base abstract class for layout managers. A - * layout manager implements the layouting policy for a composite or a - * container actor: it controls the preferred size of the actor to which - * it has been paired, and it controls the allocation of its children. - * - * Any composite or container [class@Clutter.Actor] subclass can delegate the - * layouting of its children to a #ClutterLayoutManager. - * - * Clutter provides some simple #ClutterLayoutManager sub-classes, like - * [class@Clutter.FlowLayout] and [class@Clutter.BinLayout]. - * - * ## Implementing a ClutterLayoutManager - * The implementation of a layout manager does not differ from the - * implementation of the size requisition and allocation bits of - * [class@Clutter.Actor], so you should read the relative documentation - * for subclassing [class@Clutter.Actor]. - * - * The layout manager implementation can hold a back pointer to the container - * [type@Clutter.Actor] by implementing the - * [vfunc@Clutter.LayoutManager.set_container] virtual function. The layout - * manager should not hold a real reference (i.e. call - * [method@GObject.Object.ref]) on the container actor, to avoid reference - * cycles. - * - * If a layout manager has properties affecting the layout policies then it should - * emit the [signal@Clutter.LayoutManager::layout-changed] signal on itself by using the - * [method@Clutter.LayoutManager.layout_changed] function whenever one of these properties - * changes. - * - * ## Layout Properties - * - * If a layout manager has layout properties, that is properties that - * should exist only as the result of the presence of a specific (layout - * manager, container actor, child actor) combination, and it wishes to store - * those properties inside a [class@Clutter.LayoutMeta], then it should override the - * [vfunc@Clutter.LayoutManager.get_child_meta_type] virtual function to return - * the #GType of the [class@Clutter.LayoutMeta] sub-class used to store the layout - * properties; optionally, the #ClutterLayoutManager sub-class might also - * override the [vfunc@Clutter.LayoutManager.create_child_meta] virtual function - * to control how the [class@Clutter.LayoutMeta] instance is created, otherwise the - * default implementation will be equivalent to: - * - * ```c - * ClutterLayoutManagerClass *klass; - * GType meta_type; - * - * klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager); - * meta_type = klass->get_child_meta_type (manager); - * - * return g_object_new (meta_type, - * "manager", manager, - * "container", container, - * "actor", actor, - * NULL); - * ``` - * - * Where `manager` is the #ClutterLayoutManager, `container` is the - * [class@Clutter.Actor] using the #ClutterLayoutManager, and `actor` is - * the [class@Clutter.Actor] child of the [class@Clutter.Actor]. - */ - -#include "config.h" - -#include -#include - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-layout-manager.h" -#include "clutter/clutter-layout-meta.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-timeline.h" - -#define LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED(m,method) G_STMT_START { \ - GObject *_obj = G_OBJECT (m); \ - g_warning ("Layout managers of type %s do not implement " \ - "the ClutterLayoutManager::%s method", \ - G_OBJECT_TYPE_NAME (_obj), \ - (method)); } G_STMT_END - -enum -{ - LAYOUT_CHANGED, - - LAST_SIGNAL -}; - -G_DEFINE_ABSTRACT_TYPE (ClutterLayoutManager, - clutter_layout_manager, - G_TYPE_INITIALLY_UNOWNED) - -static GQuark quark_layout_meta = 0; - -static guint manager_signals[LAST_SIGNAL] = { 0, }; - -static void -layout_manager_freeze_layout_change (ClutterLayoutManager *manager) -{ - gpointer is_frozen; - - CLUTTER_NOTE (LAYOUT, "Freezing changes for manager '%s'[%p]", - G_OBJECT_TYPE_NAME (manager), - manager); - - is_frozen = g_object_get_data (G_OBJECT (manager), "freeze-change"); - if (is_frozen == NULL) - g_object_set_data (G_OBJECT (manager), "freeze-change", - GUINT_TO_POINTER (1)); - else - { - guint level = GPOINTER_TO_UINT (is_frozen) + 1; - - g_object_set_data (G_OBJECT (manager), "freeze-change", - GUINT_TO_POINTER (level)); - } -} - -static void -layout_manager_thaw_layout_change (ClutterLayoutManager *manager) -{ - gpointer is_frozen; - - is_frozen = g_object_get_data (G_OBJECT (manager), "freeze-change"); - if (is_frozen == NULL) - g_critical (G_STRLOC ": Mismatched thaw; you have to call " - "clutter_layout_manager_freeze_layout_change() prior to " - "calling clutter_layout_manager_thaw_layout_change()"); - else - { - guint level = GPOINTER_TO_UINT (is_frozen); - - g_assert (level > 0); - - CLUTTER_NOTE (LAYOUT, "Thawing changes for manager '%s'[%p]", - G_OBJECT_TYPE_NAME (manager), - manager); - - level -= 1; - if (level == 0) - g_object_set_data (G_OBJECT (manager), "freeze-change", NULL); - else - g_object_set_data (G_OBJECT (manager), "freeze-change", - GUINT_TO_POINTER (level)); - } - -} - -static void -layout_manager_real_get_preferred_width (ClutterLayoutManager *manager, - ClutterActor *container, - gfloat for_height, - gfloat *min_width_p, - gfloat *nat_width_p) -{ - LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED (manager, "get_preferred_width"); - - if (min_width_p) - *min_width_p = 0.0; - - if (nat_width_p) - *nat_width_p = 0.0; -} - -static void -layout_manager_real_get_preferred_height (ClutterLayoutManager *manager, - ClutterActor *container, - gfloat for_width, - gfloat *min_height_p, - gfloat *nat_height_p) -{ - LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED (manager, "get_preferred_height"); - - if (min_height_p) - *min_height_p = 0.0; - - if (nat_height_p) - *nat_height_p = 0.0; -} - -static void -layout_manager_real_allocate (ClutterLayoutManager *manager, - ClutterActor *container, - const ClutterActorBox *allocation) -{ - LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED (manager, "allocate"); -} - -static void -layout_manager_real_set_container (ClutterLayoutManager *manager, - ClutterActor *container) -{ - if (container != NULL) - g_object_set_data (G_OBJECT (container), "clutter-layout-manager", manager); -} - -static ClutterLayoutMeta * -layout_manager_real_create_child_meta (ClutterLayoutManager *manager, - ClutterActor *container, - ClutterActor *actor) -{ - ClutterLayoutManagerClass *klass; - GType meta_type; - - klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager); - meta_type = klass->get_child_meta_type (manager); - - /* provide a default implementation to reduce common code */ - if (meta_type != G_TYPE_INVALID) - { - g_assert (g_type_is_a (meta_type, CLUTTER_TYPE_LAYOUT_META)); - - return g_object_new (meta_type, - "manager", manager, - "container", container, - "actor", actor, - NULL); - } - - return NULL; -} - -static GType -layout_manager_real_get_child_meta_type (ClutterLayoutManager *manager) -{ - return G_TYPE_INVALID; -} - -static void -clutter_layout_manager_class_init (ClutterLayoutManagerClass *klass) -{ - quark_layout_meta = - g_quark_from_static_string ("clutter-layout-manager-child-meta"); - - klass->get_preferred_width = layout_manager_real_get_preferred_width; - klass->get_preferred_height = layout_manager_real_get_preferred_height; - klass->allocate = layout_manager_real_allocate; - klass->create_child_meta = layout_manager_real_create_child_meta; - klass->get_child_meta_type = layout_manager_real_get_child_meta_type; - - /* XXX:2.0 - Remove */ - klass->set_container = layout_manager_real_set_container; - - /** - * ClutterLayoutManager::layout-changed: - * @manager: the #ClutterLayoutManager that emitted the signal - * - * The signal is emitted each time a layout manager - * has been changed. Every #ClutterActor using the @manager instance - * as a layout manager should connect a handler to the - * [signal@LayoutManager::layout-changed] - * signal and queue a relayout on themselves: - * - * ```c - * static void layout_changed (ClutterLayoutManager *manager, - * ClutterActor *self) - * { - * clutter_actor_queue_relayout (self); - * } - * ... - * self->manager = g_object_ref_sink (manager); - * g_signal_connect (self->manager, "layout-changed", - * G_CALLBACK (layout_changed), - * self); - * ``` - * - * Sub-classes of #ClutterLayoutManager that implement a layout that - * can be controlled or changed using parameters should emit the - * ::layout-changed signal whenever one of the parameters changes, - * by using [method@Clutter.LayoutManager.layout_changed]. - */ - manager_signals[LAYOUT_CHANGED] = - g_signal_new (I_("layout-changed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterLayoutManagerClass, - layout_changed), - NULL, NULL, NULL, - G_TYPE_NONE, 0); -} - -static void -clutter_layout_manager_init (ClutterLayoutManager *manager) -{ -} - -/** - * clutter_layout_manager_get_preferred_width: - * @manager: a #ClutterLayoutManager - * @container: the #ClutterActor using @manager - * @for_height: the height for which the width should be computed, or -1 - * @min_width_p: (out) (allow-none): return location for the minimum width - * of the layout, or %NULL - * @nat_width_p: (out) (allow-none): return location for the natural width - * of the layout, or %NULL - * - * Computes the minimum and natural widths of the @container according - * to @manager. - * - * See also [method@Clutter.Actor.get_preferred_width] - */ -void -clutter_layout_manager_get_preferred_width (ClutterLayoutManager *manager, - ClutterActor *container, - gfloat for_height, - gfloat *min_width_p, - gfloat *nat_width_p) -{ - ClutterLayoutManagerClass *klass; - - g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager)); - g_return_if_fail (CLUTTER_IS_ACTOR (container)); - - klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager); - klass->get_preferred_width (manager, container, for_height, - min_width_p, - nat_width_p); -} - -/** - * clutter_layout_manager_get_preferred_height: - * @manager: a #ClutterLayoutManager - * @container: the #ClutterActor using @manager - * @for_width: the width for which the height should be computed, or -1 - * @min_height_p: (out) (allow-none): return location for the minimum height - * of the layout, or %NULL - * @nat_height_p: (out) (allow-none): return location for the natural height - * of the layout, or %NULL - * - * Computes the minimum and natural heights of the @container according - * to @manager. - * - * See also [method@Clutter.Actor.get_preferred_height] - */ -void -clutter_layout_manager_get_preferred_height (ClutterLayoutManager *manager, - ClutterActor *container, - gfloat for_width, - gfloat *min_height_p, - gfloat *nat_height_p) -{ - ClutterLayoutManagerClass *klass; - - g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager)); - g_return_if_fail (CLUTTER_IS_ACTOR (container)); - - klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager); - klass->get_preferred_height (manager, container, for_width, - min_height_p, - nat_height_p); -} - -/** - * clutter_layout_manager_allocate: - * @manager: a #ClutterLayoutManager - * @container: the #ClutterActor using @manager - * @allocation: the #ClutterActorBox containing the allocated area - * of @container - * - * Allocates the children of @container given an area - * - * See also [method@Clutter.Actor.allocate] - */ -void -clutter_layout_manager_allocate (ClutterLayoutManager *manager, - ClutterActor *container, - const ClutterActorBox *allocation) -{ - ClutterLayoutManagerClass *klass; - - g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager)); - g_return_if_fail (CLUTTER_IS_ACTOR (container)); - g_return_if_fail (allocation != NULL); - - klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager); - klass->allocate (manager, container, allocation); -} - -/** - * clutter_layout_manager_layout_changed: - * @manager: a #ClutterLayoutManager - * - * Emits the [signal@Clutter.LayoutManager::layout-changed] signal on @manager - * - * This function should only be called by implementations of the - * #ClutterLayoutManager class - */ -void -clutter_layout_manager_layout_changed (ClutterLayoutManager *manager) -{ - gpointer is_frozen; - - g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager)); - - is_frozen = g_object_get_data (G_OBJECT (manager), "freeze-change"); - if (is_frozen == NULL) - g_signal_emit (manager, manager_signals[LAYOUT_CHANGED], 0); - else - CLUTTER_NOTE (LAYOUT, "Layout manager '%s'[%p] has been frozen", - G_OBJECT_TYPE_NAME (manager), - manager); -} - -/** - * clutter_layout_manager_set_container: - * @manager: a #ClutterLayoutManager - * @container: (allow-none): a [type@Clutter.Actor] using @manager - * - * If the #ClutterLayoutManager sub-class allows it, allow - * adding a weak reference of the @container using @manager - * from within the layout manager - * - * The layout manager should not increase the reference - * count of the @container - */ -void -clutter_layout_manager_set_container (ClutterLayoutManager *manager, - ClutterActor *container) -{ - ClutterLayoutManagerClass *klass; - - g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager)); - g_return_if_fail (container == NULL || CLUTTER_IS_ACTOR (container)); - - klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager); - if (klass->set_container) - klass->set_container (manager, container); -} - -static inline ClutterLayoutMeta * -create_child_meta (ClutterLayoutManager *manager, - ClutterActor *container, - ClutterActor *actor) -{ - ClutterLayoutManagerClass *klass; - ClutterLayoutMeta *meta = NULL; - - layout_manager_freeze_layout_change (manager); - - klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager); - if (klass->get_child_meta_type (manager) != G_TYPE_INVALID) - meta = klass->create_child_meta (manager, container, actor); - - layout_manager_thaw_layout_change (manager); - - return meta; -} - -static inline ClutterLayoutMeta * -get_child_meta (ClutterLayoutManager *manager, - ClutterActor *container, - ClutterActor *actor) -{ - ClutterLayoutMeta *layout = NULL; - - layout = g_object_get_qdata (G_OBJECT (actor), quark_layout_meta); - if (layout != NULL) - { - if (clutter_layout_meta_is_for (layout, manager, container, actor)) - return layout; - - /* if the LayoutMeta referenced is not attached to the - * layout manager then we simply ask the layout manager - * to replace it with the right one - */ - } - - layout = create_child_meta (manager, container, actor); - if (layout != NULL) - { - g_assert (CLUTTER_IS_LAYOUT_META (layout)); - g_object_set_qdata_full (G_OBJECT (actor), quark_layout_meta, - layout, - (GDestroyNotify) g_object_unref); - return layout; - } - - return NULL; -} - -/** - * clutter_layout_manager_get_child_meta: - * @manager: a #ClutterLayoutManager - * @container: a [type@Clutter.Actor] using @manager - * @actor: a [type@Clutter.Actor] child of @container - * - * Retrieves the #ClutterLayoutMeta that the layout @manager associated - * to the @actor child of @container, eventually by creating one if the - * #ClutterLayoutManager supports layout properties - * - * Return value: (transfer none): a #ClutterLayoutMeta, or %NULL if the - * #ClutterLayoutManager does not have layout properties. The returned - * layout meta instance is owned by the #ClutterLayoutManager and it - * should not be unreferenced - */ -ClutterLayoutMeta * -clutter_layout_manager_get_child_meta (ClutterLayoutManager *manager, - ClutterActor *container, - ClutterActor *actor) -{ - g_return_val_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager), NULL); - g_return_val_if_fail (CLUTTER_IS_ACTOR (container), NULL); - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); - - return get_child_meta (manager, container, actor); -} - -static inline gboolean -layout_set_property_internal (ClutterLayoutManager *manager, - GObject *gobject, - GParamSpec *pspec, - const GValue *value) -{ - if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) - { - g_warning ("%s: Child property '%s' of the layout manager of " - "type '%s' is constructor-only", - G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (manager)); - return FALSE; - } - - if (!(pspec->flags & G_PARAM_WRITABLE)) - { - g_warning ("%s: Child property '%s' of the layout manager of " - "type '%s' is not writable", - G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (manager)); - return FALSE; - } - - g_object_set_property (gobject, pspec->name, value); - - return TRUE; -} - -static inline gboolean -layout_get_property_internal (ClutterLayoutManager *manager, - GObject *gobject, - GParamSpec *pspec, - GValue *value) -{ - if (!(pspec->flags & G_PARAM_READABLE)) - { - g_warning ("%s: Child property '%s' of the layout manager of " - "type '%s' is not readable", - G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (manager)); - return FALSE; - } - - g_object_get_property (gobject, pspec->name, value); - - return TRUE; -} - -/** - * clutter_layout_manager_child_set: - * @manager: a #ClutterLayoutManager - * @container: a [type@Clutter.Actor] using @manager - * @actor: a [type@Clutter.Actor] child of @container - * @first_property: the first property name - * @...: a list of property name and value pairs - * - * Sets a list of properties and their values on the #ClutterLayoutMeta - * associated by @manager to a child of @container - * - * Languages bindings should use [method@Clutter.LayoutManager.child_set_property] - * instead - */ -void -clutter_layout_manager_child_set (ClutterLayoutManager *manager, - ClutterActor *container, - ClutterActor *actor, - const gchar *first_property, - ...) -{ - ClutterLayoutMeta *meta; - GObjectClass *klass; - const gchar *pname; - va_list var_args; - - g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager)); - g_return_if_fail (CLUTTER_IS_ACTOR (container)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - g_return_if_fail (first_property != NULL); - - meta = get_child_meta (manager, container, actor); - if (meta == NULL) - { - g_warning ("Layout managers of type '%s' do not support " - "layout metadata", - g_type_name (G_OBJECT_TYPE (manager))); - return; - } - - klass = G_OBJECT_GET_CLASS (meta); - - va_start (var_args, first_property); - - pname = first_property; - while (pname) - { - GValue value = G_VALUE_INIT; - GParamSpec *pspec; - gchar *error; - gboolean res; - - pspec = g_object_class_find_property (klass, pname); - if (pspec == NULL) - { - g_warning ("%s: Layout managers of type '%s' have no layout " - "property named '%s'", - G_STRLOC, G_OBJECT_TYPE_NAME (manager), pname); - break; - } - - G_VALUE_COLLECT_INIT (&value, G_PARAM_SPEC_VALUE_TYPE (pspec), - var_args, 0, - &error); - - if (error) - { - g_warning ("%s: %s", G_STRLOC, error); - g_free (error); - break; - } - - res = layout_set_property_internal (manager, G_OBJECT (meta), - pspec, - &value); - - g_value_unset (&value); - - if (!res) - break; - - pname = va_arg (var_args, gchar*); - } - - va_end (var_args); -} - -/** - * clutter_layout_manager_child_set_property: - * @manager: a #ClutterLayoutManager - * @container: a [type@Clutter.Actor] using @manager - * @actor: a [type@Clutter.Actor] child of @container - * @property_name: the name of the property to set - * @value: a #GValue with the value of the property to set - * - * Sets a property on the #ClutterLayoutMeta created by @manager and - * attached to a child of @container - */ -void -clutter_layout_manager_child_set_property (ClutterLayoutManager *manager, - ClutterActor *container, - ClutterActor *actor, - const gchar *property_name, - const GValue *value) -{ - ClutterLayoutMeta *meta; - GObjectClass *klass; - GParamSpec *pspec; - - g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager)); - g_return_if_fail (CLUTTER_IS_ACTOR (container)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - g_return_if_fail (property_name != NULL); - g_return_if_fail (value != NULL); - - meta = get_child_meta (manager, container, actor); - if (meta == NULL) - { - g_warning ("Layout managers of type '%s' do not support " - "layout metadata", - g_type_name (G_OBJECT_TYPE (manager))); - return; - } - - klass = G_OBJECT_GET_CLASS (meta); - - pspec = g_object_class_find_property (klass, property_name); - if (pspec == NULL) - { - g_warning ("%s: Layout managers of type '%s' have no layout " - "property named '%s'", - G_STRLOC, G_OBJECT_TYPE_NAME (manager), property_name); - return; - } - - layout_set_property_internal (manager, G_OBJECT (meta), pspec, value); -} - -/** - * clutter_layout_manager_child_get: - * @manager: a #ClutterLayoutManager - * @container: a [type@Clutter.Actor] using @manager - * @actor: a [type@Clutter.Actor] child of @container - * @first_property: the name of the first property - * @...: a list of property name and return location for the value pairs - * - * Retrieves the values for a list of properties out of the - * #ClutterLayoutMeta created by @manager and attached to the - * child of a @container - */ -void -clutter_layout_manager_child_get (ClutterLayoutManager *manager, - ClutterActor *container, - ClutterActor *actor, - const gchar *first_property, - ...) -{ - ClutterLayoutMeta *meta; - GObjectClass *klass; - const gchar *pname; - va_list var_args; - - g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager)); - g_return_if_fail (CLUTTER_IS_ACTOR (container)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - g_return_if_fail (first_property != NULL); - - meta = get_child_meta (manager, container, actor); - if (meta == NULL) - { - g_warning ("Layout managers of type '%s' do not support " - "layout metadata", - g_type_name (G_OBJECT_TYPE (manager))); - return; - } - - klass = G_OBJECT_GET_CLASS (meta); - - va_start (var_args, first_property); - - pname = first_property; - while (pname) - { - GValue value = G_VALUE_INIT; - GParamSpec *pspec; - gchar *error; - gboolean res; - - pspec = g_object_class_find_property (klass, pname); - if (pspec == NULL) - { - g_warning ("%s: Layout managers of type '%s' have no layout " - "property named '%s'", - G_STRLOC, G_OBJECT_TYPE_NAME (manager), pname); - break; - } - - g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - - res = layout_get_property_internal (manager, G_OBJECT (meta), - pspec, - &value); - if (!res) - { - g_value_unset (&value); - break; - } - - G_VALUE_LCOPY (&value, var_args, 0, &error); - if (error) - { - g_warning ("%s: %s", G_STRLOC, error); - g_free (error); - g_value_unset (&value); - break; - } - - g_value_unset (&value); - - pname = va_arg (var_args, gchar*); - } - - va_end (var_args); -} - -/** - * clutter_layout_manager_child_get_property: - * @manager: a #ClutterLayoutManager - * @container: a [type@Clutter.Actor] using @manager - * @actor: a [type@Clutter.Actor] child of @container - * @property_name: the name of the property to get - * @value: a #GValue with the value of the property to get - * - * Gets a property on the #ClutterLayoutMeta created by @manager and - * attached to a child of @container - * - * The #GValue must already be initialized to the type of the property - * and has to be unset with g_value_unset() after extracting the real - * value out of it - */ -void -clutter_layout_manager_child_get_property (ClutterLayoutManager *manager, - ClutterActor *container, - ClutterActor *actor, - const gchar *property_name, - GValue *value) -{ - ClutterLayoutMeta *meta; - GObjectClass *klass; - GParamSpec *pspec; - - g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager)); - g_return_if_fail (CLUTTER_IS_ACTOR (container)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - g_return_if_fail (property_name != NULL); - g_return_if_fail (value != NULL); - - meta = get_child_meta (manager, container, actor); - if (meta == NULL) - { - g_warning ("Layout managers of type %s do not support " - "layout metadata", - g_type_name (G_OBJECT_TYPE (manager))); - return; - } - - klass = G_OBJECT_GET_CLASS (meta); - - pspec = g_object_class_find_property (klass, property_name); - if (pspec == NULL) - { - g_warning ("%s: Layout managers of type '%s' have no layout " - "property named '%s'", - G_STRLOC, G_OBJECT_TYPE_NAME (manager), property_name); - return; - } - - layout_get_property_internal (manager, G_OBJECT (meta), pspec, value); -} - -/** - * clutter_layout_manager_find_child_property: - * @manager: a #ClutterLayoutManager - * @name: the name of the property - * - * Retrieves the #GParamSpec for the layout property @name inside - * the #ClutterLayoutMeta sub-class used by @manager - * - * Return value: (transfer none): a #GParamSpec describing the property, - * or %NULL if no property with that name exists. The returned - * #GParamSpec is owned by the layout manager and should not be - * modified or freed - */ -GParamSpec * -clutter_layout_manager_find_child_property (ClutterLayoutManager *manager, - const gchar *name) -{ - ClutterLayoutManagerClass *klass; - GObjectClass *meta_klass; - GParamSpec *pspec; - GType meta_type; - - klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager); - meta_type = klass->get_child_meta_type (manager); - if (meta_type == G_TYPE_INVALID) - return NULL; - - meta_klass = g_type_class_ref (meta_type); - - pspec = g_object_class_find_property (meta_klass, name); - - g_type_class_unref (meta_klass); - - return pspec; -} - -/** - * clutter_layout_manager_list_child_properties: - * @manager: a #ClutterLayoutManager - * @n_pspecs: (out): return location for the number of returned - * `GParamSpec`s - * - * Retrieves all the `GParamSpec`s for the layout properties - * stored inside the #ClutterLayoutMeta sub-class used by @manager - * - * Return value: (transfer full) (array length=n_pspecs): the newly-allocated, - * %NULL-terminated array of `GParamSpec`s. Use g_free() to free the - * resources allocated for the array - */ -GParamSpec ** -clutter_layout_manager_list_child_properties (ClutterLayoutManager *manager, - guint *n_pspecs) -{ - ClutterLayoutManagerClass *klass; - GObjectClass *meta_klass; - GParamSpec **pspecs; - GType meta_type; - - klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager); - meta_type = klass->get_child_meta_type (manager); - if (meta_type == G_TYPE_INVALID) - return NULL; - - meta_klass = g_type_class_ref (meta_type); - - pspecs = g_object_class_list_properties (meta_klass, n_pspecs); - - g_type_class_unref (meta_klass); - - return pspecs; -} diff --git a/mutter/clutter/clutter/clutter-layout-manager.h b/mutter/clutter/clutter/clutter-layout-manager.h deleted file mode 100644 index b7198c0..0000000 --- a/mutter/clutter/clutter/clutter-layout-manager.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_LAYOUT_MANAGER (clutter_layout_manager_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterLayoutManager, - clutter_layout_manager, - CLUTTER, - LAYOUT_MANAGER, - GInitiallyUnowned) - -/** - * ClutterLayoutManagerClass: - * @get_preferred_width: virtual function; override to provide a preferred - * width for the layout manager. See also the get_preferred_width() - * virtual function in #ClutterActor - * @get_preferred_height: virtual function; override to provide a preferred - * height for the layout manager. See also the get_preferred_height() - * virtual function in #ClutterActor - * @allocate: virtual function; override to allocate the children of the - * layout manager. See also the allocate() virtual function in - * #ClutterActor - * @set_container: virtual function; override to set a back pointer - * on the [type@Clutter.Actor] using the layout manager. The implementation - * should not take a reference on the container, but just take a weak - * reference, to avoid potential leaks due to reference cycles - * @get_child_meta_type: virtual function; override to return the #GType - * of the #ClutterLayoutMeta sub-class used by the #ClutterLayoutManager - * @create_child_meta: virtual function; override to create a - * [type@Clutter.LayoutMeta] instance associated to a container - * [type@Clutter.Actor] and a child [type@Clutter.Actor], used to maintain - * layout manager specific properties - * @layout_changed: class handler for the #ClutterLayoutManager::layout-changed - * signal - * - * The #ClutterLayoutManagerClass structure contains only private - * data and should be accessed using the provided API - */ -struct _ClutterLayoutManagerClass -{ - /*< private >*/ - GInitiallyUnownedClass parent_class; - - /*< public >*/ - void (* get_preferred_width) (ClutterLayoutManager *manager, - ClutterActor *container, - gfloat for_height, - gfloat *min_width_p, - gfloat *nat_width_p); - void (* get_preferred_height) (ClutterLayoutManager *manager, - ClutterActor *container, - gfloat for_width, - gfloat *min_height_p, - gfloat *nat_height_p); - void (* allocate) (ClutterLayoutManager *manager, - ClutterActor *container, - const ClutterActorBox *allocation); - - void (* set_container) (ClutterLayoutManager *manager, - ClutterActor *container); - - GType (* get_child_meta_type) (ClutterLayoutManager *manager); - ClutterLayoutMeta *(* create_child_meta) (ClutterLayoutManager *manager, - ClutterActor *container, - ClutterActor *actor); - - void (* layout_changed) (ClutterLayoutManager *manager); -}; - -CLUTTER_EXPORT -void clutter_layout_manager_get_preferred_width (ClutterLayoutManager *manager, - ClutterActor *container, - gfloat for_height, - gfloat *min_width_p, - gfloat *nat_width_p); -CLUTTER_EXPORT -void clutter_layout_manager_get_preferred_height (ClutterLayoutManager *manager, - ClutterActor *container, - gfloat for_width, - gfloat *min_height_p, - gfloat *nat_height_p); -CLUTTER_EXPORT -void clutter_layout_manager_allocate (ClutterLayoutManager *manager, - ClutterActor *container, - const ClutterActorBox *allocation); - -CLUTTER_EXPORT -void clutter_layout_manager_set_container (ClutterLayoutManager *manager, - ClutterActor *container); -CLUTTER_EXPORT -void clutter_layout_manager_layout_changed (ClutterLayoutManager *manager); - -CLUTTER_EXPORT -GParamSpec * clutter_layout_manager_find_child_property (ClutterLayoutManager *manager, - const gchar *name); -CLUTTER_EXPORT -GParamSpec ** clutter_layout_manager_list_child_properties (ClutterLayoutManager *manager, - guint *n_pspecs); - -CLUTTER_EXPORT -ClutterLayoutMeta *clutter_layout_manager_get_child_meta (ClutterLayoutManager *manager, - ClutterActor *container, - ClutterActor *actor); - -CLUTTER_EXPORT -void clutter_layout_manager_child_set (ClutterLayoutManager *manager, - ClutterActor *container, - ClutterActor *actor, - const gchar *first_property, - ...) G_GNUC_NULL_TERMINATED; -CLUTTER_EXPORT -void clutter_layout_manager_child_get (ClutterLayoutManager *manager, - ClutterActor *container, - ClutterActor *actor, - const gchar *first_property, - ...) G_GNUC_NULL_TERMINATED; -CLUTTER_EXPORT -void clutter_layout_manager_child_set_property (ClutterLayoutManager *manager, - ClutterActor *container, - ClutterActor *actor, - const gchar *property_name, - const GValue *value); -CLUTTER_EXPORT -void clutter_layout_manager_child_get_property (ClutterLayoutManager *manager, - ClutterActor *container, - ClutterActor *actor, - const gchar *property_name, - GValue *value); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-layout-meta.c b/mutter/clutter/clutter/clutter-layout-meta.c deleted file mode 100644 index b49917d..0000000 --- a/mutter/clutter/clutter/clutter-layout-meta.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterLayoutMeta: - * - * Wrapper for actors inside a layout manager - * - * [type@Clutter.LayoutMeta] is a wrapper object created by - * [class@LayoutManager] implementations in order to store child-specific data - * and properties. - * - * A [type@Clutter.LayoutMeta] wraps a [class@Actor] inside a container - * [class@Actor] using a [class@LayoutManager]. - */ - -#include "config.h" - -#include "clutter/clutter-layout-meta.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-private.h" - -typedef struct _ClutterLayoutMetaPrivate ClutterLayoutMetaPrivate; -struct _ClutterLayoutMetaPrivate -{ - ClutterLayoutManager *manager; - ClutterActor *container; - ClutterActor *actor; -}; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterLayoutMeta, - clutter_layout_meta, - G_TYPE_OBJECT); - -enum -{ - PROP_0, - - PROP_MANAGER, - PROP_CONTAINER, - PROP_ACTOR, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -static void -clutter_layout_meta_dispose (GObject *object) -{ - ClutterLayoutMeta *layout_meta = CLUTTER_LAYOUT_META (object); - ClutterLayoutMetaPrivate *priv = - clutter_layout_meta_get_instance_private (layout_meta); - - g_clear_weak_pointer (&priv->manager); - g_clear_weak_pointer (&priv->container); - g_clear_weak_pointer (&priv->actor); - - G_OBJECT_CLASS (clutter_layout_meta_parent_class)->dispose (object); -} - -static void -clutter_layout_meta_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterLayoutMeta *layout_meta = CLUTTER_LAYOUT_META (object); - ClutterLayoutMetaPrivate *priv = - clutter_layout_meta_get_instance_private (layout_meta); - - switch (prop_id) - { - case PROP_MANAGER: - g_set_weak_pointer (&priv->manager, g_value_get_object (value)); - break; - - case PROP_CONTAINER: - g_set_weak_pointer (&priv->container, g_value_get_object (value)); - break; - - case PROP_ACTOR: - g_set_weak_pointer (&priv->actor, g_value_get_object (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_layout_meta_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterLayoutMeta *layout_meta = CLUTTER_LAYOUT_META (object); - ClutterLayoutMetaPrivate *priv = - clutter_layout_meta_get_instance_private (layout_meta); - - switch (prop_id) - { - case PROP_MANAGER: - g_value_set_object (value, priv->manager); - break; - - case PROP_CONTAINER: - g_value_set_object (value, priv->container); - break; - - case PROP_ACTOR: - g_value_set_object (value, priv->actor); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_layout_meta_class_init (ClutterLayoutMetaClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->dispose = clutter_layout_meta_dispose; - gobject_class->set_property = clutter_layout_meta_set_property; - gobject_class->get_property = clutter_layout_meta_get_property; - - /** - * ClutterLayoutMeta:manager: - * - * The [class@LayoutManager] that created this [type@Clutter.LayoutMeta]. - */ - obj_props[PROP_MANAGER] = - g_param_spec_object ("manager", NULL, NULL, - CLUTTER_TYPE_LAYOUT_MANAGER, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterLayoutMeta:container: - * - * The [type@Clutter.Actor] containing [property@Clutter.LayoutMeta:actor] - */ - obj_props[PROP_CONTAINER] = - g_param_spec_object ("container", NULL, NULL, - CLUTTER_TYPE_ACTOR, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterLayoutMeta:actor: - * - * The [type@Clutter.Actor] being wrapped by this [type@Clutter.LayoutMeta] - */ - obj_props[PROP_ACTOR] = - g_param_spec_object ("actor", NULL, NULL, - CLUTTER_TYPE_ACTOR, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); -} - -static void -clutter_layout_meta_init (ClutterLayoutMeta *self) -{ -} - -/** - * clutter_layout_meta_get_manager: - * @data: a #ClutterLayoutMeta - * - * Retrieves the actor wrapped by @data - * - * Return value: (transfer none): a [type@Clutter.LayoutManager] - */ -ClutterLayoutManager * -clutter_layout_meta_get_manager (ClutterLayoutMeta *data) -{ - ClutterLayoutMetaPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_LAYOUT_META (data), NULL); - - priv = clutter_layout_meta_get_instance_private (data); - - return priv->manager; -} - -/** - * clutter_layout_meta_get_container: - * @data: a #ClutterLayoutMeta - * - * Retrieves the container using @data - * - * Return value: (transfer none): a [type@Clutter.Actor] - */ -ClutterActor * -clutter_layout_meta_get_container (ClutterLayoutMeta *data) -{ - ClutterLayoutMetaPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_LAYOUT_META (data), NULL); - - priv = clutter_layout_meta_get_instance_private (data); - - return priv->container; -} - -/** - * clutter_layout_meta_get_actor: - * @data: a #ClutterLayoutMeta - * - * Retrieves the actor wrapped by @data - * - * Return value: (transfer none): a [type@Clutter.Actor] - */ -ClutterActor * -clutter_layout_meta_get_actor (ClutterLayoutMeta *data) -{ - ClutterLayoutMetaPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_LAYOUT_META (data), NULL); - - priv = clutter_layout_meta_get_instance_private (data); - - return priv->actor; -} - -gboolean -clutter_layout_meta_is_for (ClutterLayoutMeta *data, - ClutterLayoutManager *manager, - ClutterActor *container, - ClutterActor *actor) -{ - ClutterLayoutMetaPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_LAYOUT_META (data), FALSE); - - priv = clutter_layout_meta_get_instance_private (data); - - return priv->manager == manager && - priv->container == container && priv->actor == actor; -} diff --git a/mutter/clutter/clutter/clutter-layout-meta.h b/mutter/clutter/clutter/clutter-layout-meta.h deleted file mode 100644 index b07fdd7..0000000 --- a/mutter/clutter/clutter/clutter-layout-meta.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" -#include "clutter/clutter-layout-manager.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_LAYOUT_META (clutter_layout_meta_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterLayoutMeta, clutter_layout_meta, CLUTTER, LAYOUT_META, GObject) - -struct _ClutterLayoutMetaClass -{ - GObjectClass parent_class; -}; - -CLUTTER_EXPORT -ClutterActor *clutter_layout_meta_get_container (ClutterLayoutMeta *data); -CLUTTER_EXPORT -ClutterActor *clutter_layout_meta_get_actor (ClutterLayoutMeta *data); -CLUTTER_EXPORT -ClutterLayoutManager *clutter_layout_meta_get_manager (ClutterLayoutMeta *data); -CLUTTER_EXPORT -gboolean clutter_layout_meta_is_for (ClutterLayoutMeta *data, - ClutterLayoutManager *manager, - ClutterActor *container, - ClutterActor *actor); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-macros.h b/mutter/clutter/clutter/clutter-macros.h deleted file mode 100644 index d42dd42..0000000 --- a/mutter/clutter/clutter/clutter-macros.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -/* some structures are meant to be opaque and still be allocated on the stack; - * in order to avoid people poking at their internals, we use this macro to - * ensure that users don't accidentally access a struct private members. - * - * we use the CLUTTER_COMPILATION define to allow us easier access, though. - */ -#ifdef CLUTTER_COMPILATION -#define CLUTTER_PRIVATE_FIELD(x) x -#else -#define CLUTTER_PRIVATE_FIELD(x) clutter_private_ ## x -#endif - -#define _CLUTTER_EXTERN __attribute__((visibility("default"))) extern - -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || \ - __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4) -#define _CLUTTER_GNUC_DO_PRAGMA(x) _Pragma(G_STRINGIFY (x)) -#define _CLUTTER_DEPRECATED_MACRO _CLUTTER_GNUC_DO_PRAGMA(GCC warning "Deprecated macro") -#define _CLUTTER_DEPRECATED_MACRO_FOR(f) _CLUTTER_GNUC_DO_PRAGMA(GCC warning #f) -#else -#define _CLUTTER_DEPRECATED_MACRO -#define _CLUTTER_DEPRECATED_MACRO_FOR(f) -#endif - -/* these macros are used to mark deprecated functions, and thus have to be - * exposed in a public header. - * - * do *not* use them in other libraries depending on Clutter: use G_DEPRECATED - * and G_DEPRECATED_FOR, or use your own wrappers around them. - */ -#ifdef CLUTTER_DISABLE_DEPRECATION_WARNINGS -#define CLUTTER_DEPRECATED _CLUTTER_EXTERN -#define CLUTTER_DEPRECATED_FOR(f) _CLUTTER_EXTERN -#define CLUTTER_DEPRECATED_MACRO -#define CLUTTER_DEPRECATED_MACRO_FOR(f) -#else -#define CLUTTER_DEPRECATED G_DEPRECATED _CLUTTER_EXTERN -#define CLUTTER_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f) _CLUTTER_EXTERN -#define CLUTTER_DEPRECATED_MACRO _CLUTTER_DEPRECATED_MACRO -#define CLUTTER_DEPRECATED_MACRO_FOR(f) _CLUTTER_DEPRECATED_MACRO_FOR(f) -#endif - -#define CLUTTER_MACRO_DEPRECATED CLUTTER_DEPRECATED_MACRO -#define CLUTTER_MACRO_DEPRECATED_FOR(f) CLUTTER_DEPRECATED_MACRO_FOR(f) - -#define CLUTTER_EXPORT _CLUTTER_EXTERN - -/* CLUTTER_EXPORT_TEST should be used to export symbols that are exported only - * for testability purposes - */ -#define CLUTTER_EXPORT_TEST CLUTTER_EXPORT diff --git a/mutter/clutter/clutter/clutter-main.c b/mutter/clutter/clutter/clutter-main.c deleted file mode 100644 index 1ab46c0..0000000 --- a/mutter/clutter/clutter/clutter-main.c +++ /dev/null @@ -1,1028 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * 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 . - */ -#include "config.h" - -#include -#include - -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-backend-private.h" -#include "clutter/clutter-context-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-event-private.h" -#include "clutter/clutter-input-device-private.h" -#include "clutter/clutter-input-pointer-a11y-private.h" -#include "clutter/clutter-graphene.h" -#include "clutter/clutter-main.h" -#include "clutter/clutter-mutter.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-settings-private.h" -#include "clutter/clutter-stage.h" -#include "clutter/clutter-stage-manager.h" -#include "clutter/clutter-stage-private.h" -#include "clutter/clutter-backend-private.h" - -#include "cogl/cogl.h" -#include "cogl-pango/cogl-pango.h" - -#include "cally/cally.h" /* For accessibility support */ - -typedef struct -{ - GSourceFunc func; - gpointer data; - GDestroyNotify notify; -} ClutterThreadsDispatch; - -/* main context */ -static ClutterContext *ClutterCntx = NULL; - -/* command line options */ -static gboolean clutter_is_initialized = FALSE; -static gboolean clutter_enable_accessibility = TRUE; - -/* debug flags */ -guint clutter_debug_flags = 0; -guint clutter_paint_debug_flags = 0; -guint clutter_pick_debug_flags = 0; - -/* A constant added to heuristic max render time to account for variations - * in the estimates. - */ -int clutter_max_render_time_constant_us = 1000; - -gboolean -_clutter_context_get_show_fps (void) -{ - ClutterContext *context = _clutter_context_get_default (); - - return context->show_fps; -} - -/** - * clutter_get_accessibility_enabled: - * - * Returns whether Clutter has accessibility support enabled. As - * least, a value of TRUE means that there are a proper AtkUtil - * implementation available - * - * Return value: %TRUE if Clutter has accessibility support enabled - */ -gboolean -clutter_get_accessibility_enabled (void) -{ - return cally_get_cally_initialized (); -} - -/** - * clutter_disable_accessibility: - * - * Disable loading the accessibility support. It has the same effect - * as setting the environment variable - * CLUTTER_DISABLE_ACCESSIBILITY. For the same reason, this method - * should be called before clutter_init(). - */ -void -clutter_disable_accessibility (void) -{ - if (clutter_is_initialized) - { - g_warning ("clutter_disable_accessibility() can only be called before " - "initializing Clutter."); - return; - } - - clutter_enable_accessibility = FALSE; -} - -static gboolean -_clutter_threads_dispatch (gpointer data) -{ - ClutterThreadsDispatch *dispatch = data; - gboolean ret = FALSE; - - if (!g_source_is_destroyed (g_main_current_source ())) - ret = dispatch->func (dispatch->data); - - return ret; -} - -static void -_clutter_threads_dispatch_free (gpointer data) -{ - ClutterThreadsDispatch *dispatch = data; - - /* XXX - we cannot hold the thread lock here because the main loop - * might destroy a source while still in the dispatcher function; so - * knowing whether the lock is being held or not is not known a priori. - * - * see bug: http://bugzilla.gnome.org/show_bug.cgi?id=459555 - */ - if (dispatch->notify) - dispatch->notify (dispatch->data); - - g_free (dispatch); -} - -/** - * clutter_threads_add_idle_full: (rename-to clutter_threads_add_idle) - * @priority: the priority of the timeout source. Typically this will be in the - * range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE - * @func: function to call - * @data: data to pass to the function - * @notify: function to call when the idle source is removed - * - * Adds a function to be called whenever there are no higher priority - * events pending. If the function returns %FALSE it is automatically - * removed from the list of event sources and will not be called again. - * - * This function can be considered a thread-safe variant of g_idle_add_full(): - * it will call @function while holding the Clutter lock. It is logically - * equivalent to the following implementation: - * - * ```c - * static gboolean - * idle_safe_callback (gpointer data) - * { - * SafeClosure *closure = data; - * gboolean res = FALSE; - * - * // the callback does not need to acquire the Clutter - * / lock itself, as it is held by the this proxy handler - * // - * res = closure->callback (closure->data); - * - * return res; - * } - * static gulong - * add_safe_idle (GSourceFunc callback, - * gpointer data) - * { - * SafeClosure *closure = g_new0 (SafeClosure, 1); - * - * closure->callback = callback; - * closure->data = data; - * - * return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, - * idle_safe_callback, - * closure, - * g_free) - * } - * ``` - * - * This function should be used by threaded applications to make sure - * that @func is emitted under the Clutter threads lock and invoked - * from the same thread that started the Clutter main loop. For instance, - * it can be used to update the UI using the results from a worker - * thread: - * - * ```c - * static gboolean - * update_ui (gpointer data) - * { - * SomeClosure *closure = data; - * - * // it is safe to call Clutter API from this function because - * / it is invoked from the same thread that started the main - * / loop and under the Clutter thread lock - * // - * clutter_label_set_text (CLUTTER_LABEL (closure->label), - * closure->text); - * - * g_object_unref (closure->label); - * g_free (closure); - * - * return FALSE; - * } - * - * // within another thread // - * closure = g_new0 (SomeClosure, 1); - * // always take a reference on GObject instances // - * closure->label = g_object_ref (my_application->label); - * closure->text = g_strdup (processed_text_to_update_the_label); - * - * clutter_threads_add_idle_full (G_PRIORITY_HIGH_IDLE, - * update_ui, - * closure, - * NULL); - * ``` - * - * Return value: the ID (greater than 0) of the event source. - */ -guint -clutter_threads_add_idle_full (gint priority, - GSourceFunc func, - gpointer data, - GDestroyNotify notify) -{ - ClutterThreadsDispatch *dispatch; - - g_return_val_if_fail (func != NULL, 0); - - dispatch = g_new0 (ClutterThreadsDispatch, 1); - dispatch->func = func; - dispatch->data = data; - dispatch->notify = notify; - - return g_idle_add_full (priority, - _clutter_threads_dispatch, dispatch, - _clutter_threads_dispatch_free); -} - -/** - * clutter_threads_add_idle: (skip) - * @func: function to call - * @data: data to pass to the function - * - * Simple wrapper around clutter_threads_add_idle_full() using the - * default priority. - * - * Return value: the ID (greater than 0) of the event source. - */ -guint -clutter_threads_add_idle (GSourceFunc func, - gpointer data) -{ - g_return_val_if_fail (func != NULL, 0); - - return clutter_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE, - func, data, - NULL); -} - -/** - * clutter_threads_add_timeout_full: (rename-to clutter_threads_add_timeout) - * @priority: the priority of the timeout source. Typically this will be in the - * range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH. - * @interval: the time between calls to the function, in milliseconds - * @func: function to call - * @data: data to pass to the function - * @notify: function to call when the timeout source is removed - * - * Sets a function to be called at regular intervals holding the Clutter - * threads lock, with the given priority. The function is called repeatedly - * until it returns %FALSE, at which point the timeout is automatically - * removed and the function will not be called again. The @notify function - * is called when the timeout is removed. - * - * The first call to the function will be at the end of the first @interval. - * - * It is important to note that, due to how the Clutter main loop is - * implemented, the timing will not be accurate and it will not try to - * "keep up" with the interval. - * - * See also clutter_threads_add_idle_full(). - * - * Return value: the ID (greater than 0) of the event source. - */ -guint -clutter_threads_add_timeout_full (gint priority, - guint interval, - GSourceFunc func, - gpointer data, - GDestroyNotify notify) -{ - ClutterThreadsDispatch *dispatch; - - g_return_val_if_fail (func != NULL, 0); - - dispatch = g_new0 (ClutterThreadsDispatch, 1); - dispatch->func = func; - dispatch->data = data; - dispatch->notify = notify; - - return g_timeout_add_full (priority, - interval, - _clutter_threads_dispatch, dispatch, - _clutter_threads_dispatch_free); -} - -/** - * clutter_threads_add_timeout: (skip) - * @interval: the time between calls to the function, in milliseconds - * @func: function to call - * @data: data to pass to the function - * - * Simple wrapper around clutter_threads_add_timeout_full(). - * - * Return value: the ID (greater than 0) of the event source. - */ -guint -clutter_threads_add_timeout (guint interval, - GSourceFunc func, - gpointer data) -{ - g_return_val_if_fail (func != NULL, 0); - - return clutter_threads_add_timeout_full (G_PRIORITY_DEFAULT, - interval, - func, data, - NULL); -} - -gboolean -_clutter_context_is_initialized (void) -{ - if (ClutterCntx == NULL) - return FALSE; - - return ClutterCntx->is_initialized; -} - -ClutterContext * -_clutter_context_get_default (void) -{ - g_assert (ClutterCntx); - return ClutterCntx; -} - -ClutterContext * -clutter_create_context (ClutterContextFlags flags, - ClutterBackendConstructor backend_constructor, - gpointer user_data, - GError **error) -{ - if (ClutterCntx) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Currently only creating one clutter context is supported"); - return NULL; - } - - ClutterCntx = clutter_context_new (flags, - backend_constructor, user_data, - error); - if (!ClutterCntx) - return NULL; - - clutter_is_initialized = TRUE; - g_object_add_weak_pointer (G_OBJECT (ClutterCntx), (gpointer *) &ClutterCntx); - return ClutterCntx; -} - -gboolean -_clutter_boolean_handled_accumulator (GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, - gpointer dummy) -{ - gboolean continue_emission; - gboolean signal_handled; - - signal_handled = g_value_get_boolean (handler_return); - g_value_set_boolean (return_accu, signal_handled); - continue_emission = !signal_handled; - - return continue_emission; -} - -gboolean -_clutter_boolean_continue_accumulator (GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, - gpointer dummy) -{ - gboolean continue_emission; - - continue_emission = g_value_get_boolean (handler_return); - g_value_set_boolean (return_accu, continue_emission); - - return continue_emission; -} - -/* - * Emits a pointer event after having prepared the event for delivery (setting - * source, generating enter/leave etc.). - */ - -static inline void -emit_event (ClutterStage *stage, - ClutterEvent *event) -{ - ClutterEventType event_type; - - event_type = clutter_event_type (event); - - if (event_type == CLUTTER_KEY_PRESS || - event_type == CLUTTER_KEY_RELEASE) - cally_snoop_key_event (stage, (ClutterKeyEvent *) event); - - clutter_stage_emit_event (stage, event); -} - -static void -maybe_remove_device_for_event (ClutterStage *stage, - ClutterEvent *event, - gboolean emit_crossing) -{ - ClutterInputDevice *device = clutter_event_get_device (event); - ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); - graphene_point_t point; - uint32_t time; - - if (clutter_event_type (event) == CLUTTER_DEVICE_REMOVED) - { - ClutterInputDeviceType device_type = - clutter_input_device_get_device_type (device); - - if (device_type != CLUTTER_POINTER_DEVICE && - device_type != CLUTTER_TABLET_DEVICE && - device_type != CLUTTER_PEN_DEVICE && - device_type != CLUTTER_ERASER_DEVICE && - device_type != CLUTTER_CURSOR_DEVICE) - return; - } - - clutter_event_get_coords (event, &point.x, &point.y); - time = clutter_event_get_time (event); - - clutter_stage_update_device (stage, - device, sequence, - NULL, - point, - time, - NULL, - NULL, - TRUE); - - clutter_stage_remove_device_entry (stage, device, sequence); -} - -/** - * clutter_stage_handle_event: - * @stage: a #ClutterStage. - * @event: a #ClutterEvent. - * - * Processes an event. - * - * The @event must be a valid #ClutterEvent and have a #ClutterStage - * associated to it. - * - * This function is only useful when embedding Clutter inside another - * toolkit, and it should never be called by applications. - */ -void -clutter_stage_handle_event (ClutterStage *stage, - ClutterEvent *event) -{ - ClutterContext *context = _clutter_context_get_default(); - ClutterActor *event_actor = NULL; - ClutterEventType event_type; - gboolean filtered; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - g_return_if_fail (event != NULL); - - /* stages in destruction do not process events */ - if (CLUTTER_ACTOR_IN_DESTRUCTION (stage)) - return; - - event_type = clutter_event_type (event); - - switch (event_type) - { - case CLUTTER_ENTER: - case CLUTTER_MOTION: - case CLUTTER_BUTTON_PRESS: - case CLUTTER_TOUCH_BEGIN: - case CLUTTER_TOUCH_UPDATE: - case CLUTTER_TOUCHPAD_PINCH: - case CLUTTER_TOUCHPAD_SWIPE: - case CLUTTER_TOUCHPAD_HOLD: - case CLUTTER_PROXIMITY_IN: - case CLUTTER_SCROLL: - clutter_stage_update_device_for_event (stage, event); - break; - default: - break; - } - - if (event_type != CLUTTER_DEVICE_ADDED && - event_type != CLUTTER_DEVICE_REMOVED && - event_type != CLUTTER_NOTHING && - event_type != CLUTTER_EVENT_LAST) - { - event_actor = clutter_stage_get_event_actor (stage, event); - } - - context->current_event = g_slist_prepend (context->current_event, event); - - filtered = _clutter_event_process_filters (event, event_actor); - - context->current_event = - g_slist_delete_link (context->current_event, context->current_event); - - if (filtered) - { - if (event_type == CLUTTER_MOTION || - event_type == CLUTTER_BUTTON_RELEASE || - event_type == CLUTTER_TOUCH_UPDATE || - event_type == CLUTTER_TOUCH_END || - event_type == CLUTTER_TOUCH_CANCEL) - { - ClutterInputDevice *device = clutter_event_get_device (event); - ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); - - clutter_stage_maybe_lost_implicit_grab (stage, device, sequence); - } - } - else - { - _clutter_stage_queue_event (stage, event, TRUE); - } - - if (event_type == CLUTTER_TOUCH_END || - event_type == CLUTTER_TOUCH_CANCEL || - event_type == CLUTTER_DEVICE_REMOVED) - { - _clutter_stage_process_queued_events (stage); - maybe_remove_device_for_event (stage, event, TRUE); - } -} - -static void -_clutter_process_event_details (ClutterActor *stage, - ClutterContext *context, - ClutterEvent *event) -{ - switch (clutter_event_type (event)) - { - case CLUTTER_NOTHING: - break; - - case CLUTTER_KEY_PRESS: - case CLUTTER_KEY_RELEASE: - 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: - case CLUTTER_ENTER: - case CLUTTER_LEAVE: - case CLUTTER_MOTION: - case CLUTTER_BUTTON_PRESS: - case CLUTTER_BUTTON_RELEASE: - case CLUTTER_SCROLL: - case CLUTTER_TOUCHPAD_PINCH: - case CLUTTER_TOUCHPAD_SWIPE: - case CLUTTER_TOUCHPAD_HOLD: - case CLUTTER_TOUCH_UPDATE: - case CLUTTER_TOUCH_BEGIN: - case CLUTTER_TOUCH_CANCEL: - case CLUTTER_TOUCH_END: - case CLUTTER_PROXIMITY_IN: - case CLUTTER_PROXIMITY_OUT: - emit_event (CLUTTER_STAGE (stage), event); - break; - - case CLUTTER_DEVICE_REMOVED: - case CLUTTER_DEVICE_ADDED: - case CLUTTER_EVENT_LAST: - break; - } -} - -/* - * clutter_stage_process_event - * @event: a #ClutterEvent. - * - * Does the actual work of processing an event that was queued earlier - * out of clutter_stage_handle_event(). - */ -void -clutter_stage_process_event (ClutterStage *stage, - ClutterEvent *event) -{ - ClutterContext *context; - ClutterSeat *seat; - - COGL_TRACE_BEGIN_SCOPED (ProcessEvent, "Clutter::Stage::process_event()"); - - context = _clutter_context_get_default (); - seat = clutter_backend_get_default_seat (context->backend); - - /* push events on a stack, so that we don't need to - * add an event parameter to all signals that can be emitted within - * an event chain - */ - context->current_event = g_slist_prepend (context->current_event, event); - - clutter_seat_handle_event_post (seat, event); - _clutter_process_event_details (CLUTTER_ACTOR (stage), context, event); - - context->current_event = g_slist_delete_link (context->current_event, context->current_event); -} - -/** - * clutter_get_font_map: - * - * Retrieves the #PangoFontMap instance used by Clutter. - * You can use the global font map object with the COGL - * Pango API. - * - * Return value: (transfer none): the #PangoFontMap instance. The returned - * value is owned by Clutter and it should never be unreferenced. - */ -PangoFontMap * -clutter_get_font_map (void) -{ - return PANGO_FONT_MAP (clutter_context_get_pango_fontmap (ClutterCntx)); -} - -typedef struct _ClutterRepaintFunction -{ - guint id; - ClutterRepaintFlags flags; - GSourceFunc func; - gpointer data; - GDestroyNotify notify; -} ClutterRepaintFunction; - -/** - * clutter_threads_remove_repaint_func: - * @handle_id: an unsigned integer greater than zero - * - * Removes the repaint function with @handle_id as its id - */ -void -clutter_threads_remove_repaint_func (guint handle_id) -{ - ClutterRepaintFunction *repaint_func; - ClutterContext *context; - GList *l; - - g_return_if_fail (handle_id > 0); - - context = _clutter_context_get_default (); - l = context->repaint_funcs; - while (l != NULL) - { - repaint_func = l->data; - - if (repaint_func->id == handle_id) - { - context->repaint_funcs = - g_list_remove_link (context->repaint_funcs, l); - - g_list_free (l); - - if (repaint_func->notify) - repaint_func->notify (repaint_func->data); - - g_free (repaint_func); - - break; - } - - l = l->next; - } -} - -/** - * clutter_threads_add_repaint_func: - * @func: the function to be called within the paint cycle - * @data: data to be passed to the function, or %NULL - * @notify: function to be called when removing the repaint - * function, or %NULL - * - * Adds a function to be called whenever Clutter is processing a new - * frame. - * - * If the function returns %FALSE it is automatically removed from the - * list of repaint functions and will not be called again. - * - * This function is guaranteed to be called from within the same thread - * that called clutter_main(), and while the Clutter lock is being held; - * the function will be called within the main loop, so it is imperative - * that it does not block, otherwise the frame time budget may be lost. - * - * A repaint function is useful to ensure that an update of the scenegraph - * is performed before the scenegraph is repainted. By default, a repaint - * function added using this function will be invoked prior to the frame - * being processed. - * - * Adding a repaint function does not automatically ensure that a new - * frame will be queued. - * - * When the repaint function is removed (either because it returned %FALSE - * or because clutter_threads_remove_repaint_func() has been called) the - * @notify function will be called, if any is set. - * - * See also: clutter_threads_add_repaint_func_full() - * - * Return value: the ID (greater than 0) of the repaint function. You - * can use the returned integer to remove the repaint function by - * calling clutter_threads_remove_repaint_func(). - */ -guint -clutter_threads_add_repaint_func (GSourceFunc func, - gpointer data, - GDestroyNotify notify) -{ - return clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_PRE_PAINT, - func, - data, notify); -} - -/** - * clutter_threads_add_repaint_func_full: - * @flags: flags for the repaint function - * @func: the function to be called within the paint cycle - * @data: data to be passed to the function, or %NULL - * @notify: function to be called when removing the repaint - * function, or %NULL - * - * Adds a function to be called whenever Clutter is processing a new - * frame. - * - * If the function returns %FALSE it is automatically removed from the - * list of repaint functions and will not be called again. - * - * This function is guaranteed to be called from within the same thread - * that called clutter_main(), and while the Clutter lock is being held; - * the function will be called within the main loop, so it is imperative - * that it does not block, otherwise the frame time budget may be lost. - * - * A repaint function is useful to ensure that an update of the scenegraph - * is performed before the scenegraph is repainted. The @flags passed to this - * function will determine the section of the frame processing that will - * result in @func being called. - * - * Adding a repaint function does not automatically ensure that a new - * frame will be queued. - * - * When the repaint function is removed (either because it returned %FALSE - * or because clutter_threads_remove_repaint_func() has been called) the - * @notify function will be called, if any is set. - * - * Return value: the ID (greater than 0) of the repaint function. You - * can use the returned integer to remove the repaint function by - * calling clutter_threads_remove_repaint_func(). - */ -guint -clutter_threads_add_repaint_func_full (ClutterRepaintFlags flags, - GSourceFunc func, - gpointer data, - GDestroyNotify notify) -{ - ClutterContext *context; - ClutterRepaintFunction *repaint_func; - - g_return_val_if_fail (func != NULL, 0); - - context = _clutter_context_get_default (); - - repaint_func = g_new0 (ClutterRepaintFunction, 1); - - repaint_func->id = context->last_repaint_id++; - - repaint_func->flags = flags; - repaint_func->func = func; - repaint_func->data = data; - repaint_func->notify = notify; - - context->repaint_funcs = g_list_prepend (context->repaint_funcs, - repaint_func); - - return repaint_func->id; -} - -/* - * _clutter_run_repaint_functions: - * @flags: only run the repaint functions matching the passed flags - * - * Executes the repaint functions added using the - * clutter_threads_add_repaint_func() function. - * - * Must be called with the Clutter thread lock held. - */ -void -_clutter_run_repaint_functions (ClutterRepaintFlags flags) -{ - ClutterContext *context = _clutter_context_get_default (); - ClutterRepaintFunction *repaint_func; - GList *invoke_list, *reinvoke_list, *l; - - if (context->repaint_funcs == NULL) - return; - - /* steal the list */ - invoke_list = context->repaint_funcs; - context->repaint_funcs = NULL; - - reinvoke_list = NULL; - - /* consume the whole list while we execute the functions */ - while (invoke_list != NULL) - { - gboolean res = FALSE; - - repaint_func = invoke_list->data; - - l = invoke_list; - invoke_list = g_list_remove_link (invoke_list, invoke_list); - - g_list_free (l); - - if ((repaint_func->flags & flags) != 0) - res = repaint_func->func (repaint_func->data); - else - res = TRUE; - - if (res) - reinvoke_list = g_list_prepend (reinvoke_list, repaint_func); - else - { - if (repaint_func->notify != NULL) - repaint_func->notify (repaint_func->data); - - g_free (repaint_func); - } - } - - if (context->repaint_funcs != NULL) - { - context->repaint_funcs = g_list_concat (context->repaint_funcs, - g_list_reverse (reinvoke_list)); - } - else - context->repaint_funcs = g_list_reverse (reinvoke_list); -} - -/** - * clutter_get_default_text_direction: - * - * Retrieves the default direction for the text. The text direction is - * determined by the locale and/or by the `CLUTTER_TEXT_DIRECTION` - * environment variable. - * - * The default text direction can be overridden on a per-actor basis by using - * [method@Actor.set_text_direction]. - * - * Return value: the default text direction - */ -ClutterTextDirection -clutter_get_default_text_direction (void) -{ - return clutter_context_get_text_direction (ClutterCntx); -} - -/*< private > - * clutter_clear_events_queue: - * - * Clears the events queue stored in the main context. - */ -void -_clutter_clear_events_queue (void) -{ - ClutterContext *context = _clutter_context_get_default (); - ClutterEvent *event; - GAsyncQueue *events_queue; - - if (!context->events_queue) - return; - - g_async_queue_lock (context->events_queue); - - while ((event = g_async_queue_try_pop_unlocked (context->events_queue))) - clutter_event_free (event); - - events_queue = context->events_queue; - context->events_queue = NULL; - - g_async_queue_unlock (events_queue); - g_async_queue_unref (events_queue); -} - -/** - * clutter_add_debug_flags: (skip) - * - * Adds the debug flags passed to the list of debug flags. - */ -void -clutter_add_debug_flags (ClutterDebugFlag debug_flags, - ClutterDrawDebugFlag draw_flags, - ClutterPickDebugFlag pick_flags) -{ - clutter_debug_flags |= debug_flags; - clutter_paint_debug_flags |= draw_flags; - clutter_pick_debug_flags |= pick_flags; -} - -/** - * clutter_remove_debug_flags: (skip) - * - * Removes the debug flags passed from the list of debug flags. - */ -void -clutter_remove_debug_flags (ClutterDebugFlag debug_flags, - ClutterDrawDebugFlag draw_flags, - ClutterPickDebugFlag pick_flags) -{ - clutter_debug_flags &= ~debug_flags; - clutter_paint_debug_flags &= ~draw_flags; - clutter_pick_debug_flags &= ~pick_flags; -} - -void -clutter_debug_set_max_render_time_constant (int max_render_time_constant_us) -{ - clutter_max_render_time_constant_us = max_render_time_constant_us; -} - -void -clutter_get_debug_flags (ClutterDebugFlag *debug_flags, - ClutterDrawDebugFlag *draw_flags, - ClutterPickDebugFlag *pick_flags) -{ - if (debug_flags) - *debug_flags = clutter_debug_flags; - if (draw_flags) - *draw_flags = clutter_paint_debug_flags; - if (pick_flags) - *pick_flags = clutter_pick_debug_flags; -} - -void -_clutter_debug_messagev (const char *format, - va_list var_args) -{ - static gint64 last_debug_stamp; - gchar *stamp, *fmt; - gint64 cur_time, debug_stamp; - - cur_time = g_get_monotonic_time (); - - /* if the last debug message happened less than a second ago, just - * show the increments instead of the full timestamp - */ - if (last_debug_stamp == 0 || - cur_time - last_debug_stamp >= G_USEC_PER_SEC) - { - debug_stamp = cur_time; - last_debug_stamp = debug_stamp; - - stamp = g_strdup_printf ("[%16" G_GINT64_FORMAT "]", debug_stamp); - } - else - { - debug_stamp = cur_time - last_debug_stamp; - - stamp = g_strdup_printf ("[%+16" G_GINT64_FORMAT "]", debug_stamp); - } - - fmt = g_strconcat (stamp, ":", format, NULL); - g_free (stamp); - - g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, var_args); - - g_free (fmt); -} - -void -_clutter_debug_message (const char *format, ...) -{ - va_list args; - - va_start (args, format); - _clutter_debug_messagev (format, args); - va_end (args); -} - -gboolean -_clutter_diagnostic_enabled (void) -{ - static const char *clutter_enable_diagnostic = NULL; - - if (G_UNLIKELY (clutter_enable_diagnostic == NULL)) - { - clutter_enable_diagnostic = g_getenv ("CLUTTER_ENABLE_DIAGNOSTIC"); - - if (clutter_enable_diagnostic == NULL) - clutter_enable_diagnostic = "0"; - } - - return *clutter_enable_diagnostic != '0'; -} diff --git a/mutter/clutter/clutter/clutter-main.h b/mutter/clutter/clutter/clutter-main.h deleted file mode 100644 index dc2b07f..0000000 --- a/mutter/clutter/clutter/clutter-main.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * 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 . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-actor.h" -#include "clutter/clutter-stage.h" -#include - -G_BEGIN_DECLS - -typedef enum -{ - CLUTTER_DEBUG_MISC = 1 << 0, - CLUTTER_DEBUG_ACTOR = 1 << 1, - CLUTTER_DEBUG_TEXTURE = 1 << 2, - CLUTTER_DEBUG_EVENT = 1 << 3, - CLUTTER_DEBUG_PAINT = 1 << 4, - CLUTTER_DEBUG_PANGO = 1 << 5, - CLUTTER_DEBUG_BACKEND = 1 << 6, - CLUTTER_DEBUG_SCHEDULER = 1 << 7, - CLUTTER_DEBUG_SCRIPT = 1 << 8, - CLUTTER_DEBUG_SHADER = 1 << 9, - CLUTTER_DEBUG_MULTISTAGE = 1 << 10, - CLUTTER_DEBUG_ANIMATION = 1 << 11, - CLUTTER_DEBUG_LAYOUT = 1 << 12, - CLUTTER_DEBUG_PICK = 1 << 13, - CLUTTER_DEBUG_EVENTLOOP = 1 << 14, - CLUTTER_DEBUG_CLIPPING = 1 << 15, - CLUTTER_DEBUG_OOB_TRANSFORMS = 1 << 16, - CLUTTER_DEBUG_FRAME_TIMINGS = 1 << 17, - CLUTTER_DEBUG_DETAILED_TRACE = 1 << 18, - CLUTTER_DEBUG_GRABS = 1 << 19, - CLUTTER_DEBUG_FRAME_CLOCK = 1 << 20, - CLUTTER_DEBUG_GESTURES = 1 << 21, -} ClutterDebugFlag; - -typedef enum -{ - CLUTTER_DEBUG_NOP_PICKING = 1 << 0, -} ClutterPickDebugFlag; - -typedef enum -{ - CLUTTER_DEBUG_DISABLE_SWAP_EVENTS = 1 << 0, - CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS = 1 << 1, - CLUTTER_DEBUG_REDRAWS = 1 << 2, - CLUTTER_DEBUG_PAINT_VOLUMES = 1 << 3, - CLUTTER_DEBUG_DISABLE_CULLING = 1 << 4, - CLUTTER_DEBUG_DISABLE_OFFSCREEN_REDIRECT = 1 << 5, - CLUTTER_DEBUG_CONTINUOUS_REDRAW = 1 << 6, - CLUTTER_DEBUG_PAINT_DEFORM_TILES = 1 << 7, - CLUTTER_DEBUG_PAINT_DAMAGE_REGION = 1 << 8, - CLUTTER_DEBUG_DISABLE_DYNAMIC_MAX_RENDER_TIME = 1 << 9, - CLUTTER_DEBUG_PAINT_MAX_RENDER_TIME = 1 << 10, -} ClutterDrawDebugFlag; - -/** - * CLUTTER_PRIORITY_REDRAW: - * - * Priority of the redraws. This is chosen to be lower than the GTK+ - * redraw and resize priorities, because in application with both - * GTK+ and Clutter it's more likely that the Clutter part will be - * continually animating (and thus able to starve GTK+) than - * vice-versa. - */ -#define CLUTTER_PRIORITY_REDRAW (G_PRIORITY_HIGH_IDLE + 50) - -CLUTTER_EXPORT -void clutter_stage_handle_event (ClutterStage *stage, - ClutterEvent *event); - -/* Debug utility functions */ -CLUTTER_EXPORT -gboolean clutter_get_accessibility_enabled (void); - -CLUTTER_EXPORT -void clutter_disable_accessibility (void); - -/* Threading functions */ -CLUTTER_EXPORT -guint clutter_threads_add_idle (GSourceFunc func, - gpointer data); -CLUTTER_EXPORT -guint clutter_threads_add_idle_full (gint priority, - GSourceFunc func, - gpointer data, - GDestroyNotify notify); -CLUTTER_EXPORT -guint clutter_threads_add_timeout (guint interval, - GSourceFunc func, - gpointer data); -CLUTTER_EXPORT -guint clutter_threads_add_timeout_full (gint priority, - guint interval, - GSourceFunc func, - gpointer data, - GDestroyNotify notify); -CLUTTER_EXPORT -guint clutter_threads_add_repaint_func (GSourceFunc func, - gpointer data, - GDestroyNotify notify); -CLUTTER_EXPORT -guint clutter_threads_add_repaint_func_full (ClutterRepaintFlags flags, - GSourceFunc func, - gpointer data, - GDestroyNotify notify); -CLUTTER_EXPORT -void clutter_threads_remove_repaint_func (guint handle_id); - -CLUTTER_EXPORT -PangoFontMap * clutter_get_font_map (void); - -CLUTTER_EXPORT -ClutterTextDirection clutter_get_default_text_direction (void); - -CLUTTER_EXPORT -void clutter_add_debug_flags (ClutterDebugFlag debug_flags, - ClutterDrawDebugFlag draw_flags, - ClutterPickDebugFlag pick_flags); - -CLUTTER_EXPORT -void clutter_remove_debug_flags (ClutterDebugFlag debug_flags, - ClutterDrawDebugFlag draw_flags, - ClutterPickDebugFlag pick_flags); - -CLUTTER_EXPORT -void clutter_debug_set_max_render_time_constant (int max_render_time_constant_us); - -CLUTTER_EXPORT -ClutterTextDirection clutter_get_text_direction (void); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-marshal.list b/mutter/clutter/clutter/clutter-marshal.list deleted file mode 100644 index c983888..0000000 --- a/mutter/clutter/clutter/clutter-marshal.list +++ /dev/null @@ -1,38 +0,0 @@ -BOOLEAN:BOXED -BOOLEAN:BOXED,INT,INT -BOOLEAN:OBJECT,BOOLEAN -BOOLEAN:OBJECT,BOXED -BOOLEAN:OBJECT,BOXED,DOUBLE -BOOLEAN:OBJECT,DOUBLE -BOOLEAN:OBJECT,ENUM -BOOLEAN:OBJECT,FLAGS -BOOLEAN:STRING,UINT,FLAGS -BOOLEAN:OBJECT -BOOLEAN:OBJECT,FLOAT,FLOAT -BOXED:UINT,UINT -DOUBLE:VOID -UINT:VOID -VOID:BOXED,FLAGS -VOID:INT64,INT64,FLOAT,BOOLEAN -VOID:INT,INT -VOID:INT,POINTER -VOID:FLOAT,FLOAT -VOID:INT,INT,INT,INT -VOID:OBJECT,BOXED -VOID:OBJECT,BOXED,BOXED -VOID:OBJECT,FLAGS -VOID:OBJECT,FLAGS,BOOLEAN -VOID:OBJECT,FLAGS,UINT -VOID:OBJECT,FLOAT,FLOAT -VOID:OBJECT,FLOAT,FLOAT,FLAGS -VOID:OBJECT,OBJECT -VOID:OBJECT,PARAM -VOID:OBJECT,POINTER -VOID:OBJECT,UINT -VOID:STRING,BOOLEAN -VOID:STRING,BOOLEAN,BOOLEAN -VOID:STRING,INT -VOID:UINT,STRING,UINT -VOID:UINT,UINT -VOID:STRING,INT,POINTER -VOID:VOID diff --git a/mutter/clutter/clutter/clutter-mutter.h b/mutter/clutter/clutter/clutter-mutter.h deleted file mode 100644 index cf46aaa..0000000 --- a/mutter/clutter/clutter/clutter-mutter.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2016 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 . - * - */ - -#pragma once - -#define __CLUTTER_H_INSIDE__ - -#include "clutter/clutter-backend.h" -#include "clutter/clutter-backend-private.h" -#include "clutter/clutter-damage-history.h" -#include "clutter/clutter-event-private.h" -#include "clutter/clutter-frame-private.h" -#include "clutter/clutter-input-device-private.h" -#include "clutter/clutter-input-pointer-a11y-private.h" -#include "clutter/clutter-macros.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-stage-private.h" -#include "clutter/clutter-stage-view.h" -#include "clutter/clutter-stage-view-private.h" -#include "clutter/clutter.h" -#include "mtk/mtk.h" - -/* An epsilon larger than FLT_EPSILON that is useful when comparing coordinates - * while ignoring floating point precision loss that might happen during - * various matrix calculations. */ -#define CLUTTER_COORDINATE_EPSILON (1.0 / 256.0) - -/** - * clutter_create_context: (skip) - */ -CLUTTER_EXPORT -ClutterContext * clutter_create_context (ClutterContextFlags flags, - ClutterBackendConstructor backend_constructor, - gpointer user_data, - GError **error); - -CLUTTER_EXPORT -GList * clutter_stage_peek_stage_views (ClutterStage *stage); - -CLUTTER_EXPORT -gboolean clutter_actor_is_effectively_on_stage_view (ClutterActor *self, - ClutterStageView *view); - -CLUTTER_EXPORT -int64_t clutter_stage_get_frame_counter (ClutterStage *stage); - -CLUTTER_EXPORT -void clutter_stage_capture_view_into (ClutterStage *stage, - ClutterStageView *view, - MtkRectangle *rect, - uint8_t *data, - int stride); - -CLUTTER_EXPORT -void clutter_stage_clear_stage_views (ClutterStage *stage); - -CLUTTER_EXPORT -void clutter_stage_view_assign_next_scanout (ClutterStageView *stage_view, - CoglScanout *scanout); - -CLUTTER_EXPORT -gboolean clutter_actor_has_damage (ClutterActor *actor); - -CLUTTER_EXPORT -gboolean clutter_actor_has_transitions (ClutterActor *actor); - -CLUTTER_EXPORT -ClutterFrameClock * clutter_actor_pick_frame_clock (ClutterActor *self, - ClutterActor **out_actor); -CLUTTER_EXPORT -gboolean clutter_seat_handle_event_post (ClutterSeat *seat, - const ClutterEvent *event); - -CLUTTER_EXPORT -void clutter_stage_update_device (ClutterStage *stage, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - ClutterInputDevice *source_device, - graphene_point_t point, - uint32_t time, - ClutterActor *new_actor, - MtkRegion *region, - gboolean emit_crossing); - -CLUTTER_EXPORT -gboolean clutter_stage_get_device_coords (ClutterStage *stage, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - graphene_point_t *coords); - -CLUTTER_EXPORT -void clutter_get_debug_flags (ClutterDebugFlag *debug_flags, - ClutterDrawDebugFlag *draw_flags, - ClutterPickDebugFlag *pick_flags); - -CLUTTER_EXPORT -void clutter_actor_notify_transform_invalid (ClutterActor *self); - -CLUTTER_EXPORT -void clutter_actor_get_relative_transformation_matrix (ClutterActor *self, - ClutterActor *ancestor, - graphene_matrix_t *matrix); - -#undef __CLUTTER_H_INSIDE__ diff --git a/mutter/clutter/clutter/clutter-offscreen-effect.c b/mutter/clutter/clutter/clutter-offscreen-effect.c deleted file mode 100644 index e8e3bee..0000000 --- a/mutter/clutter/clutter/clutter-offscreen-effect.c +++ /dev/null @@ -1,767 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Authors: - * Emmanuele Bassi - * Robert Bragg - */ - -/** - * ClutterOffscreenEffect: - * - * Base class for effects using offscreen buffers - * - * #ClutterOffscreenEffect is an abstract class that can be used by - * [class@Effect] sub-classes requiring access to an offscreen buffer. - * - * Some effects, like the fragment shader based effects, can only use GL - * textures, and in order to apply those effects to any kind of actor they - * require that all drawing operations are applied to an offscreen framebuffer - * that gets redirected to a texture. - * - * #ClutterOffscreenEffect provides all the heavy-lifting for creating the - * offscreen framebuffer, the redirection and the final paint of the texture on - * the desired stage. - * - * - * ## Implementing a ClutterOffscreenEffect - * - * Creating a sub-class of #ClutterOffscreenEffect requires, in case - * of overriding the [class@Effect] virtual functions, to chain up to the - * #ClutterOffscreenEffect's implementation. - * - * On top of the [class@Effect]'s virtual functions, - * #ClutterOffscreenEffect also provides a [vfunc@OffscreenEffect.paint_target] - * function, which encapsulates the effective painting of the texture that - * contains the result of the offscreen redirection. - * - * The size of the target material is defined to be as big as the - * transformed size of the [class@Actor] using the offscreen effect. - * Sub-classes of #ClutterOffscreenEffect can change the texture creation - * code to provide bigger textures by overriding the - * [vfunc@OffscreenEffect.create_texture] virtual function; no chain up - * to the #ClutterOffscreenEffect implementation is required in this - * case. - * - * ## Paint nodes - * - * #ClutterOffscreenEffect generates the following paint node tree: - * - * ``` - * Effect - * ├─────────┐ - * Layer Pipeline - * │ - * Actor - * ``` - * - * When the actor contents are cached, the generated paint node tree - * looks like this: - * - * ``` - * Effect - * │ - * Pipeline - * ``` - * - * In both cases, the "Pipeline" node is created with the return value - * of [vfunc@OffscreenEffect.create_pipeline]. - */ - -#include "config.h" - -#include "clutter/clutter-offscreen-effect.h" - -#include - -#include "cogl/cogl.h" - -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-stage-private.h" -#include "clutter/clutter-paint-context-private.h" -#include "clutter/clutter-paint-node-private.h" -#include "clutter/clutter-paint-nodes.h" -#include "clutter/clutter-paint-volume-private.h" -#include "clutter/clutter-actor-box-private.h" - -typedef struct _ClutterOffscreenEffectPrivate -{ - CoglOffscreen *offscreen; - CoglPipeline *pipeline; - CoglTexture *texture; - - ClutterActor *actor; - ClutterActor *stage; - - int fbo_offset_x; - int fbo_offset_y; - - /* This is the calculated size of the fbo before being passed - through create_texture(). This needs to be tracked separately so - that we can detect when a different size is calculated and - regenerate the fbo */ - int target_width; - int target_height; - - gulong purge_handler_id; -} ClutterOffscreenEffectPrivate; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterOffscreenEffect, - clutter_offscreen_effect, - CLUTTER_TYPE_EFFECT) - -static void -clutter_offscreen_effect_set_actor (ClutterActorMeta *meta, - ClutterActor *actor) -{ - ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (meta); - ClutterOffscreenEffectPrivate *priv = - clutter_offscreen_effect_get_instance_private (self); - ClutterActorMetaClass *meta_class; - - meta_class = CLUTTER_ACTOR_META_CLASS (clutter_offscreen_effect_parent_class); - meta_class->set_actor (meta, actor); - - /* clear out the previous state */ - g_clear_object (&priv->offscreen); - - /* we keep a back pointer here, to avoid going through the ActorMeta */ - priv->actor = clutter_actor_meta_get_actor (meta); -} - -static CoglTexture* -clutter_offscreen_effect_real_create_texture (ClutterOffscreenEffect *effect, - gfloat width, - gfloat height) -{ - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - - return cogl_texture_2d_new_with_size (ctx, MAX (width, 1), MAX (height, 1)); -} - -static void -ensure_pipeline_filter_for_scale (ClutterOffscreenEffect *self, - float resource_scale) -{ - ClutterOffscreenEffectPrivate *priv = - clutter_offscreen_effect_get_instance_private (self); - CoglPipelineFilter filter; - - if (!priv->pipeline) - return; - - /* If no fractional scaling is set, we're always going to render the texture - at a 1:1 texel:pixel ratio so, in such case we can use 'nearest' filtering - to decrease the effects of rounding errors in the geometry calculation; - if instead we we're using a global fractional scaling we need to make sure - that we're using the default linear effect, not to create artifacts when - scaling down the texture */ - if (fmodf (resource_scale, 1.0f) == 0) - filter = COGL_PIPELINE_FILTER_NEAREST; - else - filter = COGL_PIPELINE_FILTER_LINEAR; - - cogl_pipeline_set_layer_filters (priv->pipeline, 0 /* layer_index */, - filter, filter); -} - -static CoglPipeline * -clutter_offscreen_effect_real_create_pipeline (ClutterOffscreenEffect *effect, - CoglTexture *texture) -{ - ClutterOffscreenEffectPrivate *priv = - clutter_offscreen_effect_get_instance_private (effect); - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - CoglPipeline *pipeline; - float resource_scale; - - resource_scale = clutter_actor_get_real_resource_scale (priv->actor); - - pipeline = cogl_pipeline_new (ctx); - ensure_pipeline_filter_for_scale (effect, resource_scale); - cogl_pipeline_set_layer_texture (pipeline, 0, texture); - - return pipeline; -} - -static void -video_memory_purged (ClutterOffscreenEffect *self) -{ - ClutterOffscreenEffectPrivate *priv = - clutter_offscreen_effect_get_instance_private (self); - - g_clear_object (&priv->offscreen); -} - -static gboolean -update_fbo (ClutterEffect *effect, - int target_width, - int target_height, - float resource_scale) -{ - ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); - ClutterOffscreenEffectClass *offscreen_class = - CLUTTER_OFFSCREEN_EFFECT_GET_CLASS (self); - ClutterOffscreenEffectPrivate *priv = - clutter_offscreen_effect_get_instance_private (self); - ClutterActor *stage_actor; - CoglOffscreen *offscreen; - g_autoptr (GError) error = NULL; - - stage_actor = clutter_actor_get_stage (priv->actor); - if (stage_actor != priv->stage) - { - g_clear_signal_handler (&priv->purge_handler_id, priv->stage); - - priv->stage = stage_actor; - - if (priv->stage) - { - priv->purge_handler_id = - g_signal_connect_object (priv->stage, - "gl-video-memory-purged", - G_CALLBACK (video_memory_purged), - self, - G_CONNECT_SWAPPED); - } - } - - if (priv->stage == NULL) - { - CLUTTER_NOTE (MISC, "The actor '%s' is not part of a stage", - clutter_actor_get_name (priv->actor) == NULL - ? G_OBJECT_TYPE_NAME (priv->actor) - : clutter_actor_get_name (priv->actor)); - return FALSE; - } - - if (priv->target_width == target_width && - priv->target_height == target_height && - priv->offscreen != NULL) - { - ensure_pipeline_filter_for_scale (self, resource_scale); - return TRUE; - } - - g_clear_object (&priv->texture); - g_clear_object (&priv->offscreen); - - priv->texture = - clutter_offscreen_effect_create_texture (self, target_width, target_height); - if (priv->texture == NULL) - return FALSE; - - priv->target_width = target_width; - priv->target_height = target_height; - - offscreen = cogl_offscreen_new_with_texture (priv->texture); - if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (offscreen), &error)) - { - g_warning ("Failed to create offscreen effect framebuffer: %s", - error->message); - - g_object_unref (offscreen); - g_clear_object (&priv->pipeline); - - priv->target_width = 0; - priv->target_height = 0; - - return FALSE; - } - - priv->offscreen = offscreen; - - g_clear_object (&priv->pipeline); - priv->pipeline = offscreen_class->create_pipeline (self, priv->texture); - - return TRUE; -} - -static gboolean -clutter_offscreen_effect_pre_paint (ClutterEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); - ClutterOffscreenEffectPrivate *priv = - clutter_offscreen_effect_get_instance_private (self); - CoglFramebuffer *offscreen; - ClutterActorBox raw_box, box; - ClutterActor *stage; - graphene_matrix_t projection, modelview, transform; - const ClutterPaintVolume *volume; - gfloat stage_width, stage_height; - gfloat target_width = -1, target_height = -1; - float resource_scale; - float ceiled_resource_scale; - - if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect))) - goto disable_effect; - - if (priv->actor == NULL) - goto disable_effect; - - stage = _clutter_actor_get_stage_internal (priv->actor); - clutter_actor_get_size (stage, &stage_width, &stage_height); - - resource_scale = clutter_actor_get_real_resource_scale (priv->actor); - - ceiled_resource_scale = ceilf (resource_scale); - stage_width *= ceiled_resource_scale; - stage_height *= ceiled_resource_scale; - - /* Get the minimal bounding box for what we want to paint, relative to the - * parent of priv->actor. Note that we may actually be painting a clone of - * priv->actor so we need to be careful to avoid querying the transformation - * of priv->actor (like clutter_actor_get_paint_box would). Just stay in - * local coordinates for now... - */ - volume = clutter_actor_get_paint_volume (priv->actor); - if (volume) - { - ClutterPaintVolume mutable_volume; - - _clutter_paint_volume_copy_static (volume, &mutable_volume); - _clutter_paint_volume_get_bounding_box (&mutable_volume, &raw_box); - clutter_paint_volume_free (&mutable_volume); - - box = raw_box; - _clutter_actor_box_enlarge_for_effects (&box); - - priv->fbo_offset_x = box.x1; - priv->fbo_offset_y = box.y1; - } - else - { - clutter_actor_get_allocation_box (priv->actor, &raw_box); - - box = raw_box; - _clutter_actor_box_enlarge_for_effects (&box); - - priv->fbo_offset_x = box.x1 - raw_box.x1; - priv->fbo_offset_y = box.y1 - raw_box.y1; - } - - clutter_actor_box_scale (&box, ceiled_resource_scale); - clutter_actor_box_get_size (&box, &target_width, &target_height); - - target_width = ceilf (target_width); - target_height = ceilf (target_height); - - /* First assert that the framebuffer is the right size... */ - if (!update_fbo (effect, target_width, target_height, resource_scale)) - goto disable_effect; - - offscreen = COGL_FRAMEBUFFER (priv->offscreen); - - /* We don't want the FBO contents to be transformed. That could waste memory - * (e.g. during zoom), or result in something that's not rectangular (clipped - * incorrectly). So drop the modelview matrix of the current paint chain. - * This is fine since paint_texture runs with the same modelview matrix, - * so it will come out correctly whenever that is used to put the FBO - * contents on screen... - */ - clutter_actor_get_transform (priv->stage, &modelview); - graphene_matrix_init_translate (&transform, - &GRAPHENE_POINT3D_INIT (-priv->fbo_offset_x, - -priv->fbo_offset_y, - 0.0)); - graphene_matrix_scale (&transform, - stage_width / target_width, - stage_height / target_height, - 1.0); - graphene_matrix_multiply (&transform, &modelview, &modelview); - cogl_framebuffer_set_modelview_matrix (offscreen, &modelview); - - /* Set up the viewport so that it has the minimal size required to render any - * pixel in the FBO without clipping. - */ - cogl_framebuffer_set_viewport (offscreen, - 0, - 0, - target_width, - target_height); - - /* Copy the stage's projection matrix across to the offscreen */ - _clutter_stage_get_projection_matrix (CLUTTER_STAGE (priv->stage), - &projection); - - cogl_framebuffer_set_projection_matrix (offscreen, &projection); - - return TRUE; - -disable_effect: - g_clear_object (&priv->offscreen); - return FALSE; -} - -static void -clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterOffscreenEffectPrivate *priv = - clutter_offscreen_effect_get_instance_private (effect); - ClutterPaintNode *pipeline_node; - float paint_opacity; - CoglColor color; - - paint_opacity = clutter_actor_get_paint_opacity (priv->actor) / 255.0; - - cogl_color_init_from_4f (&color, - paint_opacity, paint_opacity, - paint_opacity, paint_opacity); - cogl_pipeline_set_color (priv->pipeline, &color); - - pipeline_node = clutter_pipeline_node_new (priv->pipeline); - clutter_paint_node_set_static_name (pipeline_node, - "ClutterOffscreenEffect (pipeline)"); - clutter_paint_node_add_child (node, pipeline_node); - - /* At this point we are in stage coordinates translated so if - * we draw our texture using a textured quad the size of the paint - * box then we will overlay where the actor would have drawn if it - * hadn't been redirected offscreen. - */ - clutter_paint_node_add_rectangle (pipeline_node, - &(ClutterActorBox) { - 0.f, 0.f, - cogl_texture_get_width (priv->texture), - cogl_texture_get_height (priv->texture), - }); - - clutter_paint_node_unref (pipeline_node); -} - -static void -clutter_offscreen_effect_paint_texture (ClutterOffscreenEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterOffscreenEffectPrivate *priv = - clutter_offscreen_effect_get_instance_private (effect); - graphene_matrix_t transform; - float unscale; - - unscale = 1.0 / clutter_actor_get_resource_scale (priv->actor); - graphene_matrix_init_scale (&transform, unscale, unscale, 1.0); - graphene_matrix_translate (&transform, - &GRAPHENE_POINT3D_INIT (priv->fbo_offset_x, - priv->fbo_offset_y, - 0.0)); - - if (!graphene_matrix_is_identity (&transform)) - { - ClutterPaintNode *transform_node; - - transform_node = clutter_transform_node_new (&transform); - clutter_paint_node_set_static_name (transform_node, - "ClutterOffscreenEffect (transform)"); - clutter_paint_node_add_child (node, transform_node); - clutter_paint_node_unref (transform_node); - - node = transform_node; - } - - /* paint the target material; this is virtualized for - * sub-classes that require special hand-holding - */ - clutter_offscreen_effect_paint_target (effect, node, paint_context); -} - -static void -clutter_offscreen_effect_post_paint (ClutterEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); - ClutterOffscreenEffectPrivate *priv = - clutter_offscreen_effect_get_instance_private (self); - - g_warn_if_fail (priv->offscreen); - g_warn_if_fail (priv->pipeline); - g_warn_if_fail (priv->actor); - - clutter_offscreen_effect_paint_texture (self, node, paint_context); -} - -static void -add_actor_node (ClutterOffscreenEffect *offscreen_effect, - ClutterPaintNode *node, - int paint_opacity) -{ - ClutterOffscreenEffectPrivate *priv = - clutter_offscreen_effect_get_instance_private (offscreen_effect); - ClutterPaintNode *actor_node; - - actor_node = clutter_actor_node_new (priv->actor, paint_opacity); - clutter_paint_node_add_child (node, actor_node); - clutter_paint_node_unref (actor_node); -} - -static void -clutter_offscreen_effect_paint_node (ClutterEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context, - ClutterEffectPaintFlags flags) -{ - ClutterOffscreenEffect *offscreen_effect = CLUTTER_OFFSCREEN_EFFECT (effect); - ClutterOffscreenEffectPrivate *priv = - clutter_offscreen_effect_get_instance_private (offscreen_effect); - ClutterPaintNode *layer_node; - CoglFramebuffer *fb; - - fb = COGL_FRAMEBUFFER (priv->offscreen); - layer_node = clutter_layer_node_new_to_framebuffer (fb, priv->pipeline); - clutter_paint_node_set_static_name (layer_node, - "ClutterOffscreenEffect (actor offscreen)"); - clutter_paint_node_add_child (node, layer_node); - clutter_paint_node_unref (layer_node); - - add_actor_node (offscreen_effect, layer_node, 255); -} - -static void -clutter_offscreen_effect_paint (ClutterEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context, - ClutterEffectPaintFlags flags) -{ - ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); - ClutterOffscreenEffectPrivate *priv = - clutter_offscreen_effect_get_instance_private (self); - ClutterEffectClass *parent_class = - CLUTTER_EFFECT_CLASS (clutter_offscreen_effect_parent_class); - - if (flags & CLUTTER_EFFECT_PAINT_BYPASS_EFFECT) - { - add_actor_node (self, node, -1); - g_clear_object (&priv->offscreen); - return; - } - - /* If we've already got a cached image and the actor hasn't been redrawn - * then we can just use the cached image in the FBO. - */ - if (priv->offscreen == NULL || (flags & CLUTTER_EFFECT_PAINT_ACTOR_DIRTY)) - parent_class->paint (effect, node, paint_context, flags); - else - clutter_offscreen_effect_paint_texture (self, node, paint_context); -} - -static void -clutter_offscreen_effect_set_enabled (ClutterActorMeta *meta, - gboolean is_enabled) -{ - ClutterActorMetaClass *parent_class = - CLUTTER_ACTOR_META_CLASS (clutter_offscreen_effect_parent_class); - ClutterOffscreenEffect *offscreen_effect = CLUTTER_OFFSCREEN_EFFECT (meta); - ClutterOffscreenEffectPrivate *priv = - clutter_offscreen_effect_get_instance_private (offscreen_effect); - - g_clear_object (&priv->offscreen); - - parent_class->set_enabled (meta, is_enabled); -} - -static void -clutter_offscreen_effect_finalize (GObject *gobject) -{ - ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (gobject); - ClutterOffscreenEffectPrivate *priv = - clutter_offscreen_effect_get_instance_private (self); - - g_clear_object (&priv->offscreen); - g_clear_object (&priv->texture); - g_clear_object (&priv->pipeline); - - G_OBJECT_CLASS (clutter_offscreen_effect_parent_class)->finalize (gobject); -} - -static void -clutter_offscreen_effect_class_init (ClutterOffscreenEffectClass *klass) -{ - ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); - ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass); - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - klass->create_texture = clutter_offscreen_effect_real_create_texture; - klass->create_pipeline = clutter_offscreen_effect_real_create_pipeline; - klass->paint_target = clutter_offscreen_effect_real_paint_target; - - meta_class->set_actor = clutter_offscreen_effect_set_actor; - meta_class->set_enabled = clutter_offscreen_effect_set_enabled; - - effect_class->pre_paint = clutter_offscreen_effect_pre_paint; - effect_class->post_paint = clutter_offscreen_effect_post_paint; - effect_class->paint = clutter_offscreen_effect_paint; - effect_class->paint_node = clutter_offscreen_effect_paint_node; - - gobject_class->finalize = clutter_offscreen_effect_finalize; -} - -static void -clutter_offscreen_effect_init (ClutterOffscreenEffect *self) -{ -} - -/** - * clutter_offscreen_effect_get_texture: - * @effect: a #ClutterOffscreenEffect - * - * Retrieves the texture used as a render target for the offscreen - * buffer created by @effect - * - * You should only use the returned texture when painting. The texture - * may change after [vfunc@Effect.pre_paint] is called so the effect - * implementation should update any references to the texture after - * chaining-up to the parent's pre_paint implementation. This can be - * used instead of [method@OffscreenEffect.get_texture] when the - * effect subclass wants to paint using its own material. - * - * Return value: (transfer none): a #CoglTexture or %NULL. The - * returned texture is owned by Clutter and it should not be - * modified or freed - */ -CoglTexture* -clutter_offscreen_effect_get_texture (ClutterOffscreenEffect *effect) -{ - ClutterOffscreenEffectPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect), - NULL); - - priv = clutter_offscreen_effect_get_instance_private (effect); - return priv->texture; -} - -/** - * clutter_offscreen_effect_get_pipeline: - * @effect: a #ClutterOffscreenEffect - * - * Retrieves the pipeline used as a render target for the offscreen - * buffer created by @effect - * - * You should only use the returned [class@Cogl.Pipeline] when painting. The - * returned pipeline might change between different frames. - * - * Return value: (transfer none)(nullable): a #CoglPipeline. The - * pipeline is owned by Clutter and it should not be modified - * or freed - */ -CoglPipeline * -clutter_offscreen_effect_get_pipeline (ClutterOffscreenEffect *effect) -{ - ClutterOffscreenEffectPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect), - NULL); - - priv = clutter_offscreen_effect_get_instance_private (effect); - return priv->pipeline; -} - -/** - * clutter_offscreen_effect_paint_target: - * @effect: a #ClutterOffscreenEffect - * @node: a #ClutterPaintNode - * @paint_context: a #ClutterPaintContext - * - * Calls the [vfunc@OffscreenEffect.paint_target] virtual function of the @effect - */ -void -clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - g_return_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect)); - - CLUTTER_OFFSCREEN_EFFECT_GET_CLASS (effect)->paint_target (effect, - node, - paint_context); -} - -/** - * clutter_offscreen_effect_create_texture: - * @effect: a #ClutterOffscreenEffect - * @width: the minimum width of the target texture - * @height: the minimum height of the target texture - * - * Calls the [vfunc@OffscreenEffect.create_texture] virtual function of the @effect - * - * Return value: (transfer full): a handle to a Cogl texture, or - * %NULL. The returned handle has its reference - * count increased. - */ -CoglTexture* -clutter_offscreen_effect_create_texture (ClutterOffscreenEffect *effect, - gfloat width, - gfloat height) -{ - g_return_val_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect), - NULL); - - return CLUTTER_OFFSCREEN_EFFECT_GET_CLASS (effect)->create_texture (effect, - width, - height); -} - -/** - * clutter_offscreen_effect_get_target_size: - * @effect: a #ClutterOffscreenEffect - * @width: (out): return location for the target width, or %NULL - * @height: (out): return location for the target height, or %NULL - * - * Retrieves the size of the offscreen buffer used by @effect to - * paint the actor to which it has been applied. - * - * This function should only be called by #ClutterOffscreenEffect - * implementations, from within the [vfunc@OffscreenEffect.paint_target] - * virtual function. - * - * Return value: %TRUE if the offscreen buffer has a valid size, - * and %FALSE otherwise - */ -gboolean -clutter_offscreen_effect_get_target_size (ClutterOffscreenEffect *effect, - gfloat *width, - gfloat *height) -{ - ClutterOffscreenEffectPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect), FALSE); - - priv = clutter_offscreen_effect_get_instance_private (effect); - - if (priv->texture == NULL) - return FALSE; - - if (width) - *width = cogl_texture_get_width (priv->texture); - - if (height) - *height = cogl_texture_get_height (priv->texture); - - return TRUE; -} diff --git a/mutter/clutter/clutter/clutter-offscreen-effect.h b/mutter/clutter/clutter/clutter-offscreen-effect.h deleted file mode 100644 index 88aee8c..0000000 --- a/mutter/clutter/clutter/clutter-offscreen-effect.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl.h" -#include "clutter/clutter-effect.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_OFFSCREEN_EFFECT (clutter_offscreen_effect_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterOffscreenEffect, - clutter_offscreen_effect, - CLUTTER, - OFFSCREEN_EFFECT, - ClutterEffect) - -/** - * ClutterOffscreenEffectClass: - * @create_texture: virtual function - * @paint_target: virtual function - * - * The #ClutterOffscreenEffectClass structure contains only private data - */ -struct _ClutterOffscreenEffectClass -{ - /*< private >*/ - ClutterEffectClass parent_class; - - /*< public >*/ - CoglTexture* (* create_texture) (ClutterOffscreenEffect *effect, - gfloat width, - gfloat height); - CoglPipeline* (* create_pipeline) (ClutterOffscreenEffect *effect, - CoglTexture *texture); - void (* paint_target) (ClutterOffscreenEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context); -}; - -CLUTTER_EXPORT -CoglPipeline * clutter_offscreen_effect_get_pipeline (ClutterOffscreenEffect *effect); - -CLUTTER_EXPORT -CoglTexture* clutter_offscreen_effect_get_texture (ClutterOffscreenEffect *effect); - -CLUTTER_EXPORT -void clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context); -CLUTTER_EXPORT -CoglTexture* clutter_offscreen_effect_create_texture (ClutterOffscreenEffect *effect, - gfloat width, - gfloat height); - -CLUTTER_EXPORT -gboolean clutter_offscreen_effect_get_target_size (ClutterOffscreenEffect *effect, - gfloat *width, - gfloat *height); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-page-turn-effect.c b/mutter/clutter/clutter/clutter-page-turn-effect.c deleted file mode 100644 index 0dce248..0000000 --- a/mutter/clutter/clutter/clutter-page-turn-effect.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - * - * Based on MxDeformPageTurn, written by: - * Chris Lord - */ - -/** - * ClutterPageTurnEffect: - * - * A page turning effect - * - * A simple page turning effect - */ - -#include "config.h" - -#include - -#include "clutter/clutter-page-turn-effect.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-private.h" - -struct _ClutterPageTurnEffect -{ - ClutterDeformEffect parent_instance; - - gdouble period; - gdouble angle; - - gfloat radius; -}; - -enum -{ - PROP_0, - - PROP_PERIOD, - PROP_ANGLE, - PROP_RADIUS, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -G_DEFINE_TYPE (ClutterPageTurnEffect, - clutter_page_turn_effect, - CLUTTER_TYPE_DEFORM_EFFECT); - -static void -clutter_page_turn_effect_deform_vertex (ClutterDeformEffect *effect, - gfloat width, - gfloat height, - CoglTextureVertex *vertex) -{ - ClutterPageTurnEffect *self = CLUTTER_PAGE_TURN_EFFECT (effect); - gfloat cx, cy, rx, ry, radians, turn_angle; - float shade; - - if (self->period == 0.0) - return; - - radians = self->angle / (180.0f / G_PI); - - /* Rotate the point around the centre of the page-curl ray to align it with - * the y-axis. - */ - cx = (1.f - self->period) * width; - cy = (1.f - self->period) * height; - - rx = ((vertex->x - cx) * cos (- radians)) - - ((vertex->y - cy) * sin (- radians)) - - self->radius; - ry = ((vertex->x - cx) * sin (- radians)) - + ((vertex->y - cy) * cos (- radians)); - - turn_angle = 0.f; - if (rx > self->radius * -2.0f) - { - /* Calculate the curl angle as a function from the distance of the curl - * ray (i.e. the page crease) - */ - turn_angle = (rx / self->radius * G_PI_2) - G_PI_2; - shade = ((sin (turn_angle) * 96.0f) + 159.0f) / 255.0; - - /* Add a gradient that makes it look like lighting and hides the switch - * between textures. - */ - cogl_color_init_from_4f (&vertex->color, shade, shade, shade, 1.0); - } - - if (rx > 0) - { - /* Make the curl radius smaller as more circles are formed (stops - * z-fighting and looks cool). Note that 10 is a semi-arbitrary - * number here - divide it by two and it's the amount of space - * between curled layers of the texture, in pixels. - */ - gfloat small_radius; - - small_radius = self->radius - - MIN (self->radius, (turn_angle * 10) / G_PI); - - /* Calculate a point on a cylinder (maybe make this a cone at some - * point) and rotate it by the specified angle. - */ - rx = (small_radius * cos (turn_angle)) + self->radius; - - vertex->x = (rx * cos (radians)) - (ry * sin (radians)) + cx; - vertex->y = (rx * sin (radians)) + (ry * cos (radians)) + cy; - vertex->z = (small_radius * sin (turn_angle)) + self->radius; - } -} - -static void -clutter_page_turn_effect_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterPageTurnEffect *effect = CLUTTER_PAGE_TURN_EFFECT (gobject); - - switch (prop_id) - { - case PROP_PERIOD: - clutter_page_turn_effect_set_period (effect, g_value_get_double (value)); - break; - - case PROP_ANGLE: - clutter_page_turn_effect_set_angle (effect, g_value_get_double (value)); - break; - - case PROP_RADIUS: - clutter_page_turn_effect_set_radius (effect, g_value_get_float (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_page_turn_effect_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterPageTurnEffect *effect = CLUTTER_PAGE_TURN_EFFECT (gobject); - - switch (prop_id) - { - case PROP_PERIOD: - g_value_set_double (value, effect->period); - break; - - case PROP_ANGLE: - g_value_set_double (value, effect->angle); - break; - - case PROP_RADIUS: - g_value_set_float (value, effect->radius); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_page_turn_effect_class_init (ClutterPageTurnEffectClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterDeformEffectClass *deform_class = CLUTTER_DEFORM_EFFECT_CLASS (klass); - GParamSpec *pspec; - - gobject_class->set_property = clutter_page_turn_effect_set_property; - gobject_class->get_property = clutter_page_turn_effect_get_property; - - /** - * ClutterPageTurnEffect:period: - * - * The period of the page turn, between 0.0 (no curling) and - * 1.0 (fully curled) - */ - pspec = g_param_spec_double ("period", NULL, NULL, - 0.0, 1.0, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_PERIOD] = pspec; - g_object_class_install_property (gobject_class, PROP_PERIOD, pspec); - - /** - * ClutterPageTurnEffect:angle: - * - * The angle of the page rotation, in degrees, between 0.0 and 360.0 - */ - pspec = g_param_spec_double ("angle", NULL, NULL, - 0.0, 360.0, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_ANGLE] = pspec; - g_object_class_install_property (gobject_class, PROP_ANGLE, pspec); - - /** - * ClutterPageTurnEffect:radius: - * - * The radius of the page curl, in pixels - */ - pspec = g_param_spec_float ("radius", NULL, NULL, - -G_MAXFLOAT, G_MAXFLOAT, - 24.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_RADIUS] = pspec; - g_object_class_install_property (gobject_class, PROP_RADIUS, pspec); - - deform_class->deform_vertex = clutter_page_turn_effect_deform_vertex; -} - -static void -clutter_page_turn_effect_init (ClutterPageTurnEffect *self) -{ - self->period = 0.0; - self->angle = 0.0; - self->radius = 24.0f; -} - -/** - * clutter_page_turn_effect_new: - * @period: the period of the page curl, between 0.0 and 1.0 - * @angle: the angle of the page curl, between 0.0 and 360.0 - * @radius: the radius of the page curl, in pixels - * - * Creates a new #ClutterPageTurnEffect instance with the given parameters - * - * Return value: the newly created #ClutterPageTurnEffect - */ -ClutterEffect * -clutter_page_turn_effect_new (gdouble period, - gdouble angle, - gfloat radius) -{ - g_return_val_if_fail (period >= 0.0 && period <= 1.0, NULL); - g_return_val_if_fail (angle >= 0.0 && angle <= 360.0, NULL); - - return g_object_new (CLUTTER_TYPE_PAGE_TURN_EFFECT, - "period", period, - "angle", angle, - "radius", radius, - NULL); -} - -/** - * clutter_page_turn_effect_set_period: - * @effect: a #ClutterPageTurnEffect - * @period: the period of the page curl, between 0.0 and 1.0 - * - * Sets the period of the page curling, between 0.0 (no curling) - * and 1.0 (fully curled) - */ -void -clutter_page_turn_effect_set_period (ClutterPageTurnEffect *effect, - gdouble period) -{ - g_return_if_fail (CLUTTER_IS_PAGE_TURN_EFFECT (effect)); - g_return_if_fail (period >= 0.0 && period <= 1.0); - - effect->period = period; - - clutter_deform_effect_invalidate (CLUTTER_DEFORM_EFFECT (effect)); - - g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_PERIOD]); -} - -/** - * clutter_page_turn_effect_get_period: - * @effect: a #ClutterPageTurnEffect - * - * Retrieves the value set using [method@PageTurnEffect.get_period] - * - * Return value: the period of the page curling - */ -gdouble -clutter_page_turn_effect_get_period (ClutterPageTurnEffect *effect) -{ - g_return_val_if_fail (CLUTTER_IS_PAGE_TURN_EFFECT (effect), 0.0); - - return effect->period; -} - -/** - * clutter_page_turn_effect_set_angle: - * @effect: #ClutterPageTurnEffect - * @angle: the angle of the page curl, in degrees - * - * Sets the angle of the page curling, in degrees - */ -void -clutter_page_turn_effect_set_angle (ClutterPageTurnEffect *effect, - gdouble angle) -{ - g_return_if_fail (CLUTTER_IS_PAGE_TURN_EFFECT (effect)); - g_return_if_fail (angle >= 0.0 && angle <= 360.0); - - effect->angle = angle; - - clutter_deform_effect_invalidate (CLUTTER_DEFORM_EFFECT (effect)); - - g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_ANGLE]); -} - -/** - * clutter_page_turn_effect_get_angle: - * @effect: a #ClutterPageTurnEffect: - * - * Retrieves the value set using [method@PageTurnEffect.get_angle] - * - * Return value: the angle of the page curling - */ -gdouble -clutter_page_turn_effect_get_angle (ClutterPageTurnEffect *effect) -{ - g_return_val_if_fail (CLUTTER_IS_PAGE_TURN_EFFECT (effect), 0.0); - - return effect->angle; -} - -/** - * clutter_page_turn_effect_set_radius: - * @effect: a #ClutterPageTurnEffect: - * @radius: the radius of the page curling, in pixels - * - * Sets the radius of the page curling - */ -void -clutter_page_turn_effect_set_radius (ClutterPageTurnEffect *effect, - gfloat radius) -{ - g_return_if_fail (CLUTTER_IS_PAGE_TURN_EFFECT (effect)); - - effect->radius = radius; - - clutter_deform_effect_invalidate (CLUTTER_DEFORM_EFFECT (effect)); - - g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_RADIUS]); -} - -/** - * clutter_page_turn_effect_get_radius: - * @effect: a #ClutterPageTurnEffect - * - * Retrieves the value set using [method@PageTurnEffect.set_radius] - * - * Return value: the radius of the page curling - */ -gfloat -clutter_page_turn_effect_get_radius (ClutterPageTurnEffect *effect) -{ - g_return_val_if_fail (CLUTTER_IS_PAGE_TURN_EFFECT (effect), 0.0); - - return effect->radius; -} diff --git a/mutter/clutter/clutter/clutter-page-turn-effect.h b/mutter/clutter/clutter/clutter-page-turn-effect.h deleted file mode 100644 index 68a0477..0000000 --- a/mutter/clutter/clutter/clutter-page-turn-effect.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - * - * Based on MxDeformPageTurn, written by: - * Chris Lord - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-deform-effect.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_PAGE_TURN_EFFECT (clutter_page_turn_effect_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_FINAL_TYPE (ClutterPageTurnEffect, - clutter_page_turn_effect, - CLUTTER, PAGE_TURN_EFFECT, - ClutterDeformEffect) - -CLUTTER_EXPORT -ClutterEffect *clutter_page_turn_effect_new (gdouble period, - gdouble angle, - gfloat radius); - -CLUTTER_EXPORT -void clutter_page_turn_effect_set_period (ClutterPageTurnEffect *effect, - gdouble period); -CLUTTER_EXPORT -gdouble clutter_page_turn_effect_get_period (ClutterPageTurnEffect *effect); -CLUTTER_EXPORT -void clutter_page_turn_effect_set_angle (ClutterPageTurnEffect *effect, - gdouble angle); -CLUTTER_EXPORT -gdouble clutter_page_turn_effect_get_angle (ClutterPageTurnEffect *effect); -CLUTTER_EXPORT -void clutter_page_turn_effect_set_radius (ClutterPageTurnEffect *effect, - gfloat radius); -CLUTTER_EXPORT -gfloat clutter_page_turn_effect_get_radius (ClutterPageTurnEffect *effect); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-paint-context-private.h b/mutter/clutter/clutter/clutter-paint-context-private.h deleted file mode 100644 index b13ed29..0000000 --- a/mutter/clutter/clutter/clutter-paint-context-private.h +++ /dev/null @@ -1,36 +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 . - */ - -#pragma once - -#include "clutter/clutter-paint-context.h" - -ClutterPaintContext * -clutter_paint_context_new_for_view (ClutterStageView *view, - const MtkRegion *redraw_clip, - GArray *clip_frusta, - ClutterPaintFlag paint_flags); - -gboolean clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context); - -CoglFramebuffer * clutter_paint_context_get_base_framebuffer (ClutterPaintContext *paint_context); - -const GArray * -clutter_paint_context_get_clip_frusta (ClutterPaintContext *paint_context); - -void clutter_paint_context_assign_frame (ClutterPaintContext *paint_context, - ClutterFrame *frame); diff --git a/mutter/clutter/clutter/clutter-paint-context.c b/mutter/clutter/clutter/clutter-paint-context.c deleted file mode 100644 index 9a1a644..0000000 --- a/mutter/clutter/clutter/clutter-paint-context.c +++ /dev/null @@ -1,231 +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 . - */ - -#include "config.h" - -#include "clutter/clutter-paint-context-private.h" -#include "clutter/clutter-frame.h" - -struct _ClutterPaintContext -{ - grefcount ref_count; - - ClutterPaintFlag paint_flags; - - GList *framebuffers; - - ClutterStageView *view; - ClutterFrame *frame; - - MtkRegion *redraw_clip; - GArray *clip_frusta; -}; - -G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context, - clutter_paint_context_ref, - clutter_paint_context_unref) - -ClutterPaintContext * -clutter_paint_context_new_for_view (ClutterStageView *view, - const MtkRegion *redraw_clip, - GArray *clip_frusta, - ClutterPaintFlag paint_flags) -{ - ClutterPaintContext *paint_context; - CoglFramebuffer *framebuffer; - - paint_context = g_new0 (ClutterPaintContext, 1); - g_ref_count_init (&paint_context->ref_count); - paint_context->view = view; - paint_context->redraw_clip = mtk_region_copy (redraw_clip); - paint_context->clip_frusta = g_array_ref (clip_frusta); - paint_context->paint_flags = paint_flags; - - framebuffer = clutter_stage_view_get_framebuffer (view); - clutter_paint_context_push_framebuffer (paint_context, framebuffer); - - return paint_context; -} - -/** - * clutter_paint_context_new_for_framebuffer: (skip) - */ -ClutterPaintContext * -clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer, - const MtkRegion *redraw_clip, - ClutterPaintFlag paint_flags) -{ - ClutterPaintContext *paint_context; - - paint_context = g_new0 (ClutterPaintContext, 1); - g_ref_count_init (&paint_context->ref_count); - paint_context->paint_flags = paint_flags; - - if (redraw_clip) - paint_context->redraw_clip = mtk_region_copy (redraw_clip); - - clutter_paint_context_push_framebuffer (paint_context, framebuffer); - - return paint_context; -} - -ClutterPaintContext * -clutter_paint_context_ref (ClutterPaintContext *paint_context) -{ - g_ref_count_inc (&paint_context->ref_count); - return paint_context; -} - -static void -clutter_paint_context_dispose (ClutterPaintContext *paint_context) -{ - g_list_free_full (paint_context->framebuffers, g_object_unref); - paint_context->framebuffers = NULL; - g_clear_pointer (&paint_context->redraw_clip, mtk_region_unref); - g_clear_pointer (&paint_context->clip_frusta, g_array_unref); - g_clear_pointer (&paint_context->frame, clutter_frame_unref); -} - -void -clutter_paint_context_unref (ClutterPaintContext *paint_context) -{ - if (g_ref_count_dec (&paint_context->ref_count)) - { - clutter_paint_context_dispose (paint_context); - g_free (paint_context); - } -} - -void -clutter_paint_context_destroy (ClutterPaintContext *paint_context) -{ - clutter_paint_context_dispose (paint_context); - clutter_paint_context_unref (paint_context); -} - -void -clutter_paint_context_push_framebuffer (ClutterPaintContext *paint_context, - CoglFramebuffer *framebuffer) -{ - paint_context->framebuffers = g_list_prepend (paint_context->framebuffers, - g_object_ref (framebuffer)); -} - -void -clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context) -{ - g_return_if_fail (paint_context->framebuffers); - - g_object_unref (paint_context->framebuffers->data); - paint_context->framebuffers = - g_list_delete_link (paint_context->framebuffers, - paint_context->framebuffers); -} - -const MtkRegion * -clutter_paint_context_get_redraw_clip (ClutterPaintContext *paint_context) -{ - return paint_context->redraw_clip; -} - -const GArray * -clutter_paint_context_get_clip_frusta (ClutterPaintContext *paint_context) -{ - return paint_context->clip_frusta; -} - -/** - * clutter_paint_context_get_framebuffer: - * @paint_context: The #ClutterPaintContext - * - * Returns: (transfer none): The #CoglFramebuffer used for drawing - */ -CoglFramebuffer * -clutter_paint_context_get_framebuffer (ClutterPaintContext *paint_context) -{ - g_return_val_if_fail (paint_context->framebuffers, NULL); - - return paint_context->framebuffers->data; -} - -CoglFramebuffer * -clutter_paint_context_get_base_framebuffer (ClutterPaintContext *paint_context) -{ - return g_list_last (paint_context->framebuffers)->data; -} - -/** - * clutter_paint_context_get_stage_view: (skip) - */ -ClutterStageView * -clutter_paint_context_get_stage_view (ClutterPaintContext *paint_context) -{ - return paint_context->view; -} - -/** - * clutter_paint_context_is_drawing_off_stage: (skip) - * - * Return %TRUE if the paint context is currently drawing off stage. - * This happens if there are any framebuffers pushed, and the base framebuffer - * comes from the stage view. - */ -gboolean -clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context) -{ - if (g_list_length (paint_context->framebuffers) > 1) - return TRUE; - - return !paint_context->view; -} - -/** - * clutter_paint_context_get_paint_flags: (skip) - */ -ClutterPaintFlag -clutter_paint_context_get_paint_flags (ClutterPaintContext *paint_context) -{ - return paint_context->paint_flags; -} - -void -clutter_paint_context_assign_frame (ClutterPaintContext *paint_context, - ClutterFrame *frame) -{ - g_assert (paint_context != NULL); - g_assert (paint_context->frame == NULL); - g_assert (frame != NULL); - - paint_context->frame = clutter_frame_ref (frame); -} - -/** - * clutter_paint_context_get_frame: (skip) - * @paint_context: The #ClutterPaintContext - * - * Retrieves the #ClutterFrame assigned to @paint_context, if any. A frame is - * only assigned when the paint context is created as part of a frame scheduled - * by the frame clock, and won't be assigned e.g. on offscreen paints. - * - * Returns: (transfer none)(nullable): The #ClutterFrame associated with the - * @paint_context, or %NULL - */ -ClutterFrame * -clutter_paint_context_get_frame (ClutterPaintContext *paint_context) -{ - return paint_context->frame; -} diff --git a/mutter/clutter/clutter/clutter-paint-context.h b/mutter/clutter/clutter/clutter-paint-context.h deleted file mode 100644 index 9a9e665..0000000 --- a/mutter/clutter/clutter/clutter-paint-context.h +++ /dev/null @@ -1,80 +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 . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -#include "clutter/clutter-macros.h" -#include "clutter/clutter-stage-view.h" - -typedef struct _ClutterPaintContext ClutterPaintContext; - -typedef enum _ClutterPaintFlag -{ - CLUTTER_PAINT_FLAG_NONE = 0, - CLUTTER_PAINT_FLAG_NO_CURSORS = 1 << 0, - CLUTTER_PAINT_FLAG_FORCE_CURSORS = 1 << 1, - CLUTTER_PAINT_FLAG_CLEAR = 1 << 2, -} ClutterPaintFlag; - -#define CLUTTER_TYPE_PAINT_CONTEXT (clutter_paint_context_get_type ()) - -CLUTTER_EXPORT -GType clutter_paint_context_get_type (void); - -CLUTTER_EXPORT -ClutterPaintContext * clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer, - const MtkRegion *redraw_clip, - ClutterPaintFlag paint_flags); - -CLUTTER_EXPORT -ClutterPaintContext * clutter_paint_context_ref (ClutterPaintContext *paint_context); - -CLUTTER_EXPORT -void clutter_paint_context_unref (ClutterPaintContext *paint_context); - -CLUTTER_EXPORT -void clutter_paint_context_destroy (ClutterPaintContext *paint_context); - -CLUTTER_EXPORT -CoglFramebuffer * clutter_paint_context_get_framebuffer (ClutterPaintContext *paint_context); - -CLUTTER_EXPORT -ClutterStageView * clutter_paint_context_get_stage_view (ClutterPaintContext *paint_context); - -CLUTTER_EXPORT -void clutter_paint_context_push_framebuffer (ClutterPaintContext *paint_context, - CoglFramebuffer *framebuffer); - -CLUTTER_EXPORT -void clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context); - -CLUTTER_EXPORT -const MtkRegion * clutter_paint_context_get_redraw_clip (ClutterPaintContext *paint_context); - -CLUTTER_EXPORT -ClutterPaintFlag clutter_paint_context_get_paint_flags (ClutterPaintContext *paint_context); - -CLUTTER_EXPORT -ClutterFrame * clutter_paint_context_get_frame (ClutterPaintContext *paint_context); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintContext, clutter_paint_context_unref) diff --git a/mutter/clutter/clutter/clutter-paint-node-private.h b/mutter/clutter/clutter/clutter-paint-node-private.h deleted file mode 100644 index 5968188..0000000 --- a/mutter/clutter/clutter/clutter-paint-node-private.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#include - -#include "clutter/clutter-backend.h" -#include "clutter/clutter-paint-context.h" -#include "clutter/clutter-paint-node.h" - -G_BEGIN_DECLS - -#define CLUTTER_PAINT_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_PAINT_NODE, ClutterPaintNodeClass)) -#define CLUTTER_IS_PAINT_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_PAINT_NODE)) -#define CLUTTER_PAINT_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_PAINT_NODE, ClutterPaintNodeClass)) - -typedef struct _ClutterPaintOperation ClutterPaintOperation; - -struct _ClutterPaintNode -{ - GTypeInstance parent_instance; - - ClutterPaintNode *parent; - - ClutterPaintNode *first_child; - ClutterPaintNode *prev_sibling; - ClutterPaintNode *next_sibling; - ClutterPaintNode *last_child; - - GArray *operations; - - const gchar *name; - - guint n_children; - - volatile int ref_count; -}; - -struct _ClutterPaintNodeClass -{ - GTypeClass base_class; - - void (* finalize) (ClutterPaintNode *node); - - gboolean (* pre_draw) (ClutterPaintNode *node, - ClutterPaintContext *paint_context); - void (* draw) (ClutterPaintNode *node, - ClutterPaintContext *paint_context); - void (* post_draw) (ClutterPaintNode *node, - ClutterPaintContext *paint_context); - CoglFramebuffer *(* get_framebuffer) (ClutterPaintNode *node); -}; - -#define PAINT_OP_INIT { PAINT_OP_INVALID } - -typedef enum -{ - PAINT_OP_INVALID = 0, - PAINT_OP_TEX_RECT, - PAINT_OP_TEX_RECTS, - PAINT_OP_MULTITEX_RECT, - PAINT_OP_PRIMITIVE -} PaintOpCode; - -struct _ClutterPaintOperation -{ - PaintOpCode opcode; - - GArray *coords; - - union { - float texrect[8]; - - CoglPrimitive *primitive; - } op; -}; - -GType _clutter_dummy_node_get_type (void) G_GNUC_CONST; - -void clutter_paint_node_init_types (ClutterBackend *clutter_backend); -gpointer _clutter_paint_node_create (GType gtype); - -ClutterPaintNode * _clutter_dummy_node_new (ClutterActor *actor, - CoglFramebuffer *framebuffer); -G_GNUC_INTERNAL -guint clutter_paint_node_get_n_children (ClutterPaintNode *node); - -#define CLUTTER_TYPE_EFFECT_NODE (clutter_effect_node_get_type ()) -#define CLUTTER_EFFECT_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_EFFECT_NODE, ClutterEffectNode)) -#define CLUTTER_IS_EFFECT_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_EFFECT_NODE)) - -/** - * ClutterEffectNode: - * - * The #ClutterEffectNode structure is an opaque - * type whose members cannot be directly accessed. - */ -typedef struct _ClutterEffectNode ClutterEffectNode; -typedef struct _ClutterEffectNode ClutterEffectNodeClass; - -CLUTTER_EXPORT -GType clutter_effect_node_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterPaintNode * clutter_effect_node_new (ClutterEffect *effect); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-paint-node.c b/mutter/clutter/clutter/clutter-paint-node.c deleted file mode 100644 index 94b2075..0000000 --- a/mutter/clutter/clutter/clutter-paint-node.c +++ /dev/null @@ -1,928 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterPaintNode:(ref-func clutter_paint_node_ref) (unref-func clutter_paint_node_unref) (set-value-func clutter_value_set_paint_node) (get-value-func clutter_value_get_paint_node) - * - * Paint objects - * - * #ClutterPaintNode is an element in the render graph. - * - * The render graph contains all the elements that need to be painted by - * Clutter when submitting a frame to the graphics system. - * - * The render graph is distinct from the scene graph: the scene graph is - * composed by actors, which can be visible or invisible; the scene graph - * elements also respond to events. The render graph, instead, is only - * composed by nodes that will be painted. - * - * Each #ClutterActor can submit multiple `ClutterPaintNode`s to - * the render graph. - */ - -/** - * ClutterPaintNodeClass: - * - * The `ClutterPaintNodeClass` structure contains only private data. - */ - -#include "config.h" - -#include - -#include "cogl/cogl.h" -#include "clutter/clutter-paint-node-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-private.h" - - -static inline void clutter_paint_operation_clear (ClutterPaintOperation *op); - -static void clutter_paint_node_remove_child (ClutterPaintNode *node, - ClutterPaintNode *child); - -static void -value_paint_node_init (GValue *value) -{ - value->data[0].v_pointer = NULL; -} - -static void -value_paint_node_free_value (GValue *value) -{ - if (value->data[0].v_pointer != NULL) - clutter_paint_node_unref (value->data[0].v_pointer); -} - -static void -value_paint_node_copy_value (const GValue *src, - GValue *dst) -{ - if (src->data[0].v_pointer != NULL) - dst->data[0].v_pointer = clutter_paint_node_ref (src->data[0].v_pointer); - else - dst->data[0].v_pointer = NULL; -} - -static gpointer -value_paint_node_peek_pointer (const GValue *value) -{ - return value->data[0].v_pointer; -} - -static gchar * -value_paint_node_collect_value (GValue *value, - guint n_collect_values, - GTypeCValue *collect_values, - guint collect_flags) -{ - ClutterPaintNode *node; - - node = collect_values[0].v_pointer; - - if (node == NULL) - { - value->data[0].v_pointer = NULL; - return NULL; - } - - if (node->parent_instance.g_class == NULL) - return g_strconcat ("invalid unclassed ClutterPaintNode pointer for " - "value type '", - G_VALUE_TYPE_NAME (value), - "'", - NULL); - - value->data[0].v_pointer = clutter_paint_node_ref (node); - - return NULL; -} - -static gchar * -value_paint_node_lcopy_value (const GValue *value, - guint n_collect_values, - GTypeCValue *collect_values, - guint collect_flags) -{ - ClutterPaintNode **node_p = collect_values[0].v_pointer; - - if (node_p == NULL) - return g_strconcat ("value location for '", - G_VALUE_TYPE_NAME (value), - "' passed as NULL", - NULL); - - if (value->data[0].v_pointer == NULL) - *node_p = NULL; - else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) - *node_p = value->data[0].v_pointer; - else - *node_p = clutter_paint_node_ref (value->data[0].v_pointer); - - return NULL; -} - -static void -clutter_paint_node_class_base_init (ClutterPaintNodeClass *klass) -{ -} - -static void -clutter_paint_node_class_base_finalize (ClutterPaintNodeClass *klass) -{ -} - -static void -clutter_paint_node_real_finalize (ClutterPaintNode *node) -{ - ClutterPaintNode *iter; - - if (node->operations != NULL) - { - guint i; - - for (i = 0; i < node->operations->len; i++) - { - ClutterPaintOperation *op; - - op = &g_array_index (node->operations, ClutterPaintOperation, i); - clutter_paint_operation_clear (op); - } - - g_array_unref (node->operations); - } - - iter = node->first_child; - while (iter != NULL) - { - ClutterPaintNode *next = iter->next_sibling; - - clutter_paint_node_remove_child (node, iter); - - iter = next; - } - - g_type_free_instance ((GTypeInstance *) node); -} - -static gboolean -clutter_paint_node_real_pre_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - return FALSE; -} - -static void -clutter_paint_node_real_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ -} - -static void -clutter_paint_node_real_post_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ -} - -static void -clutter_paint_node_class_init (ClutterPaintNodeClass *klass) -{ - klass->pre_draw = clutter_paint_node_real_pre_draw; - klass->draw = clutter_paint_node_real_draw; - klass->post_draw = clutter_paint_node_real_post_draw; - klass->finalize = clutter_paint_node_real_finalize; -} - -static void -clutter_paint_node_init (ClutterPaintNode *self) -{ - self->ref_count = 1; -} - -GType -clutter_paint_node_get_type (void) -{ - static size_t paint_node_type_id = 0; - - if (g_once_init_enter (&paint_node_type_id)) - { - static const GTypeFundamentalInfo finfo = { - (G_TYPE_FLAG_CLASSED | - G_TYPE_FLAG_INSTANTIATABLE | - G_TYPE_FLAG_DERIVABLE | - G_TYPE_FLAG_DEEP_DERIVABLE), - }; - - static const GTypeValueTable value_table = { - value_paint_node_init, - value_paint_node_free_value, - value_paint_node_copy_value, - value_paint_node_peek_pointer, - "p", - value_paint_node_collect_value, - "p", - value_paint_node_lcopy_value, - }; - - const GTypeInfo node_info = { - sizeof (ClutterPaintNodeClass), - - (GBaseInitFunc) clutter_paint_node_class_base_init, - (GBaseFinalizeFunc) clutter_paint_node_class_base_finalize, - (GClassInitFunc) clutter_paint_node_class_init, - (GClassFinalizeFunc) NULL, - NULL, - - sizeof (ClutterPaintNode), - 0, - (GInstanceInitFunc) clutter_paint_node_init, - - &value_table, - }; - - GType id = - g_type_register_fundamental (g_type_fundamental_next (), - I_("ClutterPaintNode"), - &node_info, &finfo, - G_TYPE_FLAG_ABSTRACT); - - g_once_init_leave (&paint_node_type_id, id); - } - - return paint_node_type_id; -} - -/** - * clutter_paint_node_set_name: - * @node: a #ClutterPaintNode - * @name: a string annotating the @node - * - * Sets a user-readable @name for @node. - * - * The @name will be used for debugging purposes. - * - * The @node will intern @name using g_intern_string(). If you have access to a - * static string, use clutter_paint_node_set_static_name() instead. - */ -void -clutter_paint_node_set_name (ClutterPaintNode *node, - const char *name) -{ - g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); - - node->name = g_intern_string (name); -} - -/** - * clutter_paint_node_set_static_name: (skip) - * - * Like clutter_paint_node_set_name() but uses a static or interned string - * containing the name. - */ -void -clutter_paint_node_set_static_name (ClutterPaintNode *node, - const char *name) -{ - g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); - - node->name = name; -} - -/** - * clutter_paint_node_ref: - * @node: a #ClutterPaintNode - * - * Acquires a reference on @node. - * - * Return value: (transfer full): the #ClutterPaintNode - */ -ClutterPaintNode * -clutter_paint_node_ref (ClutterPaintNode *node) -{ - g_return_val_if_fail (CLUTTER_IS_PAINT_NODE (node), NULL); - - g_atomic_int_inc (&node->ref_count); - - return node; -} - -/** - * clutter_paint_node_unref: - * @node: a #ClutterPaintNode - * - * Releases a reference on @node. - */ -void -clutter_paint_node_unref (ClutterPaintNode *node) -{ - g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); - - if (g_atomic_int_dec_and_test (&node->ref_count)) - { - ClutterPaintNodeClass *klass = CLUTTER_PAINT_NODE_GET_CLASS (node); - - klass->finalize (node); - } -} - -/** - * clutter_paint_node_add_child: - * @node: a #ClutterPaintNode - * @child: the child #ClutterPaintNode to add - * - * Adds @child to the list of children of @node. - * - * This function will acquire a reference on @child. - */ -void -clutter_paint_node_add_child (ClutterPaintNode *node, - ClutterPaintNode *child) -{ - g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); - g_return_if_fail (CLUTTER_IS_PAINT_NODE (child)); - g_return_if_fail (node != child); - g_return_if_fail (child->parent == NULL); - - child->parent = node; - clutter_paint_node_ref (child); - - node->n_children += 1; - - child->prev_sibling = node->last_child; - - if (node->last_child != NULL) - { - ClutterPaintNode *tmp = node->last_child; - - tmp->next_sibling = child; - } - - if (child->prev_sibling == NULL) - node->first_child = child; - - if (child->next_sibling == NULL) - node->last_child = child; -} - -/** - * clutter_paint_node_remove_child: - * @node: a #ClutterPaintNode - * @child: the #ClutterPaintNode to remove - * - * Removes @child from the list of children of @node. - * - * This function will release the reference on @child acquired by - * using clutter_paint_node_add_child(). - */ -static void -clutter_paint_node_remove_child (ClutterPaintNode *node, - ClutterPaintNode *child) -{ - ClutterPaintNode *prev, *next; - - g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); - g_return_if_fail (CLUTTER_IS_PAINT_NODE (child)); - g_return_if_fail (node != child); - g_return_if_fail (child->parent == node); - - node->n_children -= 1; - - prev = child->prev_sibling; - next = child->next_sibling; - - if (prev != NULL) - prev->next_sibling = next; - - if (next != NULL) - next->prev_sibling = prev; - - if (node->first_child == child) - node->first_child = next; - - if (node->last_child == child) - node->last_child = prev; - - child->prev_sibling = NULL; - child->next_sibling = NULL; - child->parent = NULL; - - clutter_paint_node_unref (child); -} - - -/** - * clutter_paint_node_get_n_children: - * @node: a #ClutterPaintNode - * - * Retrieves the number of children of @node. - * - * Return value: the number of children of a #ClutterPaintNode - */ -guint -clutter_paint_node_get_n_children (ClutterPaintNode *node) -{ - g_return_val_if_fail (CLUTTER_IS_PAINT_NODE (node), 0); - - return node->n_children; -} - -/** - * clutter_value_set_paint_node: - * @value: a #GValue initialized with %CLUTTER_TYPE_PAINT_NODE - * @node: (type Clutter.PaintNode) (allow-none): a #ClutterPaintNode, or %NULL - * - * Sets the contents of a #GValue initialized with %CLUTTER_TYPE_PAINT_NODE. - * - * This function increased the reference count of @node; if you do not wish - * to increase the reference count, use clutter_value_take_paint_node() - * instead. The reference count will be released by g_value_unset(). - */ -void -clutter_value_set_paint_node (GValue *value, - gpointer node) -{ - ClutterPaintNode *old_node; - - g_return_if_fail (CLUTTER_VALUE_HOLDS_PAINT_NODE (value)); - - old_node = value->data[0].v_pointer; - - if (node != NULL) - { - g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); - - value->data[0].v_pointer = clutter_paint_node_ref (node); - } - else - value->data[0].v_pointer = NULL; - - if (old_node != NULL) - clutter_paint_node_unref (old_node); -} - -/** - * clutter_value_take_paint_node: - * @value: a #GValue, initialized with %CLUTTER_TYPE_PAINT_NODE - * @node: (type Clutter.PaintNode) (allow-none): a #ClutterPaintNode, or %NULL - * - * Sets the contents of a #GValue initialized with %CLUTTER_TYPE_PAINT_NODE. - * - * Unlike clutter_value_set_paint_node(), this function will not take a - * reference on the passed @node: instead, it will take ownership of the - * current reference count. - */ -void -clutter_value_take_paint_node (GValue *value, - gpointer node) -{ - ClutterPaintNode *old_node; - - g_return_if_fail (CLUTTER_VALUE_HOLDS_PAINT_NODE (value)); - - old_node = value->data[0].v_pointer; - - if (node != NULL) - { - g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); - - /* take over ownership */ - value->data[0].v_pointer = node; - } - else - value->data[0].v_pointer = NULL; - - if (old_node != NULL) - clutter_paint_node_unref (old_node); -} - -/** - * clutter_value_get_paint_node: - * @value: a #GValue initialized with %CLUTTER_TYPE_PAINT_NODE - * - * Retrieves a pointer to the #ClutterPaintNode contained inside - * the passed #GValue. - * - * Return value: (transfer none) (type Clutter.PaintNode): a pointer to - * a #ClutterPaintNode, or %NULL - */ -gpointer -clutter_value_get_paint_node (const GValue *value) -{ - g_return_val_if_fail (CLUTTER_VALUE_HOLDS_PAINT_NODE (value), NULL); - - return value->data[0].v_pointer; -} - -/** - * clutter_value_dup_paint_node: - * @value: a #GValue initialized with %CLUTTER_TYPE_PAINT_NODE - * - * Retrieves a pointer to the #ClutterPaintNode contained inside - * the passed #GValue, and if not %NULL it will increase the - * reference count. - * - * Return value: (transfer full) (type Clutter.PaintNode): a pointer - * to the #ClutterPaintNode, with its reference count increased, - * or %NULL - */ -gpointer -clutter_value_dup_paint_node (const GValue *value) -{ - g_return_val_if_fail (CLUTTER_VALUE_HOLDS_PAINT_NODE (value), NULL); - - if (value->data[0].v_pointer != NULL) - return clutter_paint_node_ref (value->data[0].v_pointer); - - return NULL; -} - -static inline void -clutter_paint_operation_clear (ClutterPaintOperation *op) -{ - switch (op->opcode) - { - case PAINT_OP_INVALID: - break; - - case PAINT_OP_TEX_RECT: - break; - - case PAINT_OP_TEX_RECTS: - case PAINT_OP_MULTITEX_RECT: - g_clear_pointer (&op->coords, g_array_unref); - break; - - case PAINT_OP_PRIMITIVE: - if (op->op.primitive != NULL) - g_object_unref (op->op.primitive); - break; - } -} - -static inline void -clutter_paint_op_init_tex_rect (ClutterPaintOperation *op, - const ClutterActorBox *rect, - float x_1, - float y_1, - float x_2, - float y_2) -{ - clutter_paint_operation_clear (op); - - op->opcode = PAINT_OP_TEX_RECT; - op->op.texrect[0] = rect->x1; - op->op.texrect[1] = rect->y1; - op->op.texrect[2] = rect->x2; - op->op.texrect[3] = rect->y2; - op->op.texrect[4] = x_1; - op->op.texrect[5] = y_1; - op->op.texrect[6] = x_2; - op->op.texrect[7] = y_2; -} - -static inline void -clutter_paint_op_init_tex_rects (ClutterPaintOperation *op, - const float *coords, - unsigned int n_rects, - gboolean use_default_tex_coords) -{ - const unsigned int n_floats = n_rects * 8; - - clutter_paint_operation_clear (op); - - op->opcode = PAINT_OP_TEX_RECTS; - op->coords = g_array_sized_new (FALSE, FALSE, sizeof (float), n_floats); - - if (use_default_tex_coords) - { - const float default_tex_coords[4] = { 0.0, 0.0, 1.0, 1.0 }; - int i; - - for (i = 0; i < n_rects; i++) - { - g_array_append_vals (op->coords, &coords[i * 4], 4); - g_array_append_vals (op->coords, default_tex_coords, 4); - } - } - else - { - g_array_append_vals (op->coords, coords, n_floats); - } -} - -static inline void -clutter_paint_op_init_multitex_rect (ClutterPaintOperation *op, - const ClutterActorBox *rect, - const float *tex_coords, - unsigned int tex_coords_len) -{ - clutter_paint_operation_clear (op); - - op->opcode = PAINT_OP_MULTITEX_RECT; - op->coords = g_array_sized_new (FALSE, FALSE, - sizeof (float), - tex_coords_len); - - g_array_append_vals (op->coords, tex_coords, tex_coords_len); - - op->op.texrect[0] = rect->x1; - op->op.texrect[1] = rect->y1; - op->op.texrect[2] = rect->x2; - op->op.texrect[3] = rect->y2; -} - -static inline void -clutter_paint_op_init_primitive (ClutterPaintOperation *op, - CoglPrimitive *primitive) -{ - clutter_paint_operation_clear (op); - - op->opcode = PAINT_OP_PRIMITIVE; - op->op.primitive = g_object_ref (primitive); -} - -static inline void -clutter_paint_node_maybe_init_operations (ClutterPaintNode *node) -{ - if (node->operations != NULL) - return; - - node->operations = - g_array_new (FALSE, FALSE, sizeof (ClutterPaintOperation)); -} - -/** - * clutter_paint_node_add_rectangle: - * @node: a #ClutterPaintNode - * @rect: a #ClutterActorBox - * - * Adds a rectangle region to the @node, as described by the - * passed @rect. - */ -void -clutter_paint_node_add_rectangle (ClutterPaintNode *node, - const ClutterActorBox *rect) -{ - ClutterPaintOperation operation = PAINT_OP_INIT; - - g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); - g_return_if_fail (rect != NULL); - - clutter_paint_node_maybe_init_operations (node); - - clutter_paint_op_init_tex_rect (&operation, rect, 0.0, 0.0, 1.0, 1.0); - g_array_append_val (node->operations, operation); -} - -/** - * clutter_paint_node_add_texture_rectangle: - * @node: a #ClutterPaintNode - * @rect: a #ClutterActorBox - * @x_1: the left X coordinate of the texture - * @y_1: the top Y coordinate of the texture - * @x_2: the right X coordinate of the texture - * @y_2: the bottom Y coordinate of the texture - * - * Adds a rectangle region to the @node, with texture coordinates. - */ -void -clutter_paint_node_add_texture_rectangle (ClutterPaintNode *node, - const ClutterActorBox *rect, - float x_1, - float y_1, - float x_2, - float y_2) -{ - ClutterPaintOperation operation = PAINT_OP_INIT; - - g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); - g_return_if_fail (rect != NULL); - - clutter_paint_node_maybe_init_operations (node); - - clutter_paint_op_init_tex_rect (&operation, rect, x_1, y_1, x_2, y_2); - g_array_append_val (node->operations, operation); -} - - -/** - * clutter_paint_node_add_multitexture_rectangle: - * @node: a #ClutterPaintNode - * @rect: a #ClutterActorBox - * @text_coords: array of multitexture values - * @text_coords_len: number of items of @text_coords - * - * Adds a rectangle region to the @node, with multitexture coordinates. - */ -void -clutter_paint_node_add_multitexture_rectangle (ClutterPaintNode *node, - const ClutterActorBox *rect, - const float *text_coords, - unsigned int text_coords_len) -{ - ClutterPaintOperation operation = PAINT_OP_INIT; - - g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); - g_return_if_fail (rect != NULL); - - clutter_paint_node_maybe_init_operations (node); - - clutter_paint_op_init_multitex_rect (&operation, rect, text_coords, text_coords_len); - g_array_append_val (node->operations, operation); -} - -/** - * clutter_paint_node_add_rectangles: - * @node: a #ClutterPaintNode - * @coords: (in) (array length=n_rects) (transfer none): array of - * coordinates containing groups of 4 float values: [x_1, y_1, x_2, y_2] that - * are interpreted as two position coordinates; one for the top left of the - * rectangle (x1, y1), and one for the bottom right of the rectangle - * (x2, y2). - * @n_rects: number of rectangles defined in @coords. - * - * Adds a series of rectangles to @node. - * - * As a general rule for better performance its recommended to use this API - * instead of calling clutter_paint_node_add_rectangle() separately for - * multiple rectangles if all of the rectangles will be drawn together. - * - * See cogl_framebuffer_draw_rectangles(). - */ -void -clutter_paint_node_add_rectangles (ClutterPaintNode *node, - const float *coords, - unsigned int n_rects) -{ - ClutterPaintOperation operation = PAINT_OP_INIT; - - g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); - g_return_if_fail (coords != NULL); - - clutter_paint_node_maybe_init_operations (node); - - clutter_paint_op_init_tex_rects (&operation, coords, n_rects, TRUE); - g_array_append_val (node->operations, operation); -} - -/** - * clutter_paint_node_add_texture_rectangles: - * @node: a #ClutterPaintNode - * @coords: (in) (array length=n_rects) (transfer none): array containing - * groups of 8 float values: [x_1, y_1, x_2, y_2, s_1, t_1, s_2, t_2] - * that have the same meaning as the arguments for - * cogl_framebuffer_draw_textured_rectangle(). - * @n_rects: number of rectangles defined in @coords. - * - * Adds a series of rectangles to @node. - * - * The given texture coordinates should always be normalized such that - * (0, 0) corresponds to the top left and (1, 1) corresponds to the - * bottom right. To map an entire texture across the rectangle pass - * in s_1=0, t_1=0, s_2=1, t_2=1. - * - * See cogl_framebuffer_draw_textured_rectangles(). - */ -void -clutter_paint_node_add_texture_rectangles (ClutterPaintNode *node, - const float *coords, - unsigned int n_rects) -{ - ClutterPaintOperation operation = PAINT_OP_INIT; - - g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); - g_return_if_fail (coords != NULL); - - clutter_paint_node_maybe_init_operations (node); - - clutter_paint_op_init_tex_rects (&operation, coords, n_rects, FALSE); - g_array_append_val (node->operations, operation); -} - -/** - * clutter_paint_node_add_primitive: (skip) - * @node: a #ClutterPaintNode - * @primitive: a Cogl primitive - * - * Adds a region described by a Cogl primitive to the @node. - * - * This function acquires a reference on @primitive, so it is safe - * to call g_object_unref() when it returns. - */ -void -clutter_paint_node_add_primitive (ClutterPaintNode *node, - CoglPrimitive *primitive) -{ - ClutterPaintOperation operation = PAINT_OP_INIT; - - g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); - g_return_if_fail (COGL_IS_PRIMITIVE (primitive)); - - clutter_paint_node_maybe_init_operations (node); - - clutter_paint_op_init_primitive (&operation, primitive); - g_array_append_val (node->operations, operation); -} - -/** - * clutter_paint_node_paint: - * @node: a #ClutterPaintNode - * - * Paints the @node using the class implementation, traversing - * its children, if any. - */ -void -clutter_paint_node_paint (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterPaintNodeClass *klass = CLUTTER_PAINT_NODE_GET_CLASS (node); - ClutterPaintNode *iter; - gboolean res; - - res = klass->pre_draw (node, paint_context); - - if (res) - { - klass->draw (node, paint_context); - } - - for (iter = node->first_child; - iter != NULL; - iter = iter->next_sibling) - { - clutter_paint_node_paint (iter, paint_context); - } - - if (res) - { - klass->post_draw (node, paint_context); - } -} - -/*< private > - * _clutter_paint_node_create: - * @gtype: a #ClutterPaintNode type - * - * Creates a new #ClutterPaintNode instance using @gtype - * - * Return value: (transfer full): the newly created #ClutterPaintNode - * sub-class instance; use clutter_paint_node_unref() when done - */ -gpointer -_clutter_paint_node_create (GType gtype) -{ - g_return_val_if_fail (g_type_is_a (gtype, CLUTTER_TYPE_PAINT_NODE), NULL); - - return (gpointer) g_type_create_instance (gtype); -} - -/** - * clutter_paint_node_get_framebuffer: - * @node: a #ClutterPaintNode - * - * Retrieves the #CoglFramebuffer that @node will draw - * into. If @node doesn't specify a custom framebuffer, - * the first ancestor with a custom framebuffer will be - * used. - * - * Returns: (transfer none): a #CoglFramebuffer or %NULL if no custom one is - * set. - */ -CoglFramebuffer * -clutter_paint_node_get_framebuffer (ClutterPaintNode *node) -{ - ClutterPaintNodeClass *klass; - - while (node) - { - klass = CLUTTER_PAINT_NODE_GET_CLASS (node); - - if (klass->get_framebuffer != NULL) - return klass->get_framebuffer (node); - - node = node->parent; - } - - return NULL; -} diff --git a/mutter/clutter/clutter/clutter-paint-node.h b/mutter/clutter/clutter/clutter-paint-node.h deleted file mode 100644 index 895ea65..0000000 --- a/mutter/clutter/clutter/clutter-paint-node.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl.h" -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_PAINT_NODE (clutter_paint_node_get_type ()) -#define CLUTTER_PAINT_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_PAINT_NODE, ClutterPaintNode)) -#define CLUTTER_IS_PAINT_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_PAINT_NODE)) - -typedef struct _ClutterPaintNodePrivate ClutterPaintNodePrivate; -typedef struct _ClutterPaintNodeClass ClutterPaintNodeClass; - -CLUTTER_EXPORT -GType clutter_paint_node_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterPaintNode * clutter_paint_node_ref (ClutterPaintNode *node); -CLUTTER_EXPORT -void clutter_paint_node_unref (ClutterPaintNode *node); - -CLUTTER_EXPORT -void clutter_paint_node_paint (ClutterPaintNode *node, - ClutterPaintContext *paint_context); - -CLUTTER_EXPORT -void clutter_paint_node_set_name (ClutterPaintNode *node, - const char *name); -CLUTTER_EXPORT -void clutter_paint_node_set_static_name (ClutterPaintNode *node, - const char *name); - -CLUTTER_EXPORT -CoglFramebuffer * clutter_paint_node_get_framebuffer (ClutterPaintNode *node); - -CLUTTER_EXPORT -void clutter_paint_node_add_child (ClutterPaintNode *node, - ClutterPaintNode *child); -CLUTTER_EXPORT -void clutter_paint_node_add_rectangle (ClutterPaintNode *node, - const ClutterActorBox *rect); -CLUTTER_EXPORT -void clutter_paint_node_add_texture_rectangle (ClutterPaintNode *node, - const ClutterActorBox *rect, - float x_1, - float y_1, - float x_2, - float y_2); - -CLUTTER_EXPORT -void clutter_paint_node_add_multitexture_rectangle (ClutterPaintNode *node, - const ClutterActorBox *rect, - const float *text_coords, - unsigned int text_coords_len); - -CLUTTER_EXPORT -void clutter_paint_node_add_rectangles (ClutterPaintNode *node, - const float *coords, - unsigned int n_rects); -CLUTTER_EXPORT -void clutter_paint_node_add_texture_rectangles (ClutterPaintNode *node, - const float *coords, - unsigned int n_rects); - -CLUTTER_EXPORT -void clutter_paint_node_add_primitive (ClutterPaintNode *node, - CoglPrimitive *primitive); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintNode, clutter_paint_node_unref) - -/** - * CLUTTER_VALUE_HOLDS_PAINT_NODE: - * @value: a #GValue - * - * Evaluates to %TRUE if the @value has been initialized to hold - * a #ClutterPaintNode. - */ -#define CLUTTER_VALUE_HOLDS_PAINT_NODE(value) (G_VALUE_HOLDS (value, CLUTTER_TYPE_PAINT_NODE)) - -CLUTTER_EXPORT -void clutter_value_set_paint_node (GValue *value, - gpointer node); -CLUTTER_EXPORT -void clutter_value_take_paint_node (GValue *value, - gpointer node); -CLUTTER_EXPORT -gpointer clutter_value_get_paint_node (const GValue *value); -CLUTTER_EXPORT -gpointer clutter_value_dup_paint_node (const GValue *value); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-paint-nodes.c b/mutter/clutter/clutter/clutter-paint-nodes.c deleted file mode 100644 index 3384ca6..0000000 --- a/mutter/clutter/clutter/clutter-paint-nodes.c +++ /dev/null @@ -1,1609 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - - -#include "config.h" - -#include "clutter/clutter-paint-node-private.h" - -#include - -#include "cogl/cogl.h" -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-blur-private.h" -#include "clutter/clutter-color.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-paint-context-private.h" - -#include "clutter/clutter-paint-nodes.h" - -static CoglPipeline *default_color_pipeline = NULL; -static CoglPipeline *default_texture_pipeline = NULL; - -/*< private > - * clutter_paint_node_init_types: - * - * Initializes the required types for ClutterPaintNode subclasses - */ -void -clutter_paint_node_init_types (ClutterBackend *clutter_backend) -{ - CoglContext *cogl_context; - CoglColor cogl_color; - GType node_type G_GNUC_UNUSED; - - if (G_LIKELY (default_color_pipeline != NULL)) - return; - - cogl_context = clutter_backend_get_cogl_context (clutter_backend); - - node_type = clutter_paint_node_get_type (); - - cogl_color_init_from_4f (&cogl_color, 1.0, 1.0, 1.0, 1.0); - - default_color_pipeline = cogl_pipeline_new (cogl_context); - cogl_pipeline_set_color (default_color_pipeline, &cogl_color); - - default_texture_pipeline = cogl_pipeline_new (cogl_context); - cogl_pipeline_set_layer_null_texture (default_texture_pipeline, 0); - cogl_pipeline_set_color (default_texture_pipeline, &cogl_color); - cogl_pipeline_set_layer_wrap_mode (default_texture_pipeline, 0, - COGL_PIPELINE_WRAP_MODE_AUTOMATIC); -} - -/* - * ClutterRootNode: - * - * Any frame can only have a since RootNode instance for each - * top-level actor. - */ - -#define clutter_root_node_get_type clutter_root_node_get_type - -struct _ClutterRootNode -{ - ClutterPaintNode parent_instance; - - CoglFramebuffer *framebuffer; - - CoglBufferBit clear_flags; - CoglColor clear_color; -}; - -G_DEFINE_TYPE (ClutterRootNode, clutter_root_node, CLUTTER_TYPE_PAINT_NODE) - -static gboolean -clutter_root_node_pre_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterRootNode *rnode = (ClutterRootNode *) node; - - clutter_paint_context_push_framebuffer (paint_context, rnode->framebuffer); - - cogl_framebuffer_clear (rnode->framebuffer, - rnode->clear_flags, - &rnode->clear_color); - - return TRUE; -} - -static void -clutter_root_node_post_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - clutter_paint_context_pop_framebuffer (paint_context); -} - -static void -clutter_root_node_finalize (ClutterPaintNode *node) -{ - ClutterRootNode *rnode = (ClutterRootNode *) node; - - g_object_unref (rnode->framebuffer); - - CLUTTER_PAINT_NODE_CLASS (clutter_root_node_parent_class)->finalize (node); -} - -static CoglFramebuffer * -clutter_root_node_get_framebuffer (ClutterPaintNode *node) -{ - ClutterRootNode *rnode = (ClutterRootNode *) node; - - return rnode->framebuffer; -} - -static void -clutter_root_node_class_init (ClutterRootNodeClass *klass) -{ - ClutterPaintNodeClass *node_class = CLUTTER_PAINT_NODE_CLASS (klass); - - node_class->pre_draw = clutter_root_node_pre_draw; - node_class->post_draw = clutter_root_node_post_draw; - node_class->finalize = clutter_root_node_finalize; - node_class->get_framebuffer = clutter_root_node_get_framebuffer; -} - -static void -clutter_root_node_init (ClutterRootNode *self) -{ -} - -ClutterPaintNode * -clutter_root_node_new (CoglFramebuffer *framebuffer, - const ClutterColor *clear_color, - CoglBufferBit clear_flags) -{ - ClutterRootNode *res; - - g_return_val_if_fail (framebuffer, NULL); - - res = _clutter_paint_node_create (CLUTTER_TYPE_ROOT_NODE); - - cogl_color_init_from_4f (&res->clear_color, - clear_color->red / 255.0, - clear_color->green / 255.0, - clear_color->blue / 255.0, - clear_color->alpha / 255.0); - cogl_color_premultiply (&res->clear_color); - - res->framebuffer = g_object_ref (framebuffer); - res->clear_flags = clear_flags; - - return (ClutterPaintNode *) res; -} - -/* - * ClutterTransformNode: - */ - -struct _ClutterTransformNode -{ - ClutterPaintNode parent_instance; - - graphene_matrix_t transform; -}; - -struct _ClutterTransformNodeClass -{ - ClutterPaintNodeClass parent_class; -}; - -G_DEFINE_TYPE (ClutterTransformNode, clutter_transform_node, CLUTTER_TYPE_PAINT_NODE) - -static gboolean -clutter_transform_node_pre_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterTransformNode *transform_node = (ClutterTransformNode *) node; - CoglFramebuffer *fb = - clutter_paint_context_get_framebuffer (paint_context); - - cogl_framebuffer_push_matrix (fb); - cogl_framebuffer_transform (fb, &transform_node->transform); - - return TRUE; -} - -static void -clutter_transform_node_post_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - CoglFramebuffer *fb = - clutter_paint_context_get_framebuffer (paint_context); - - cogl_framebuffer_pop_matrix (fb); -} - -static void -clutter_transform_node_class_init (ClutterTransformNodeClass *klass) -{ - ClutterPaintNodeClass *node_class; - - node_class = CLUTTER_PAINT_NODE_CLASS (klass); - node_class->pre_draw = clutter_transform_node_pre_draw; - node_class->post_draw = clutter_transform_node_post_draw; -} - -static void -clutter_transform_node_init (ClutterTransformNode *self) -{ - graphene_matrix_init_identity (&self->transform); -} - -/* - * clutter_transform_node_new: - * @transform: (nullable): the transform matrix to apply - * - * Return value: (transfer full): the newly created #ClutterTransformNode. - * Use clutter_paint_node_unref() when done. - */ -ClutterPaintNode * -clutter_transform_node_new (const graphene_matrix_t *transform) -{ - ClutterTransformNode *res; - - res = _clutter_paint_node_create (CLUTTER_TYPE_TRANSFORM_NODE); - if (transform) - graphene_matrix_init_from_matrix (&res->transform, transform); - - return (ClutterPaintNode *) res; -} - -/* - * Dummy node, private - * - * an empty node, used temporarily until we can drop API compatibility, - * and we'll be able to build a full render tree for each frame. - */ - -#define clutter_dummy_node_get_type _clutter_dummy_node_get_type - -typedef struct _ClutterDummyNode ClutterDummyNode; -typedef struct _ClutterPaintNodeClass ClutterDummyNodeClass; - -struct _ClutterDummyNode -{ - ClutterPaintNode parent_instance; - - ClutterActor *actor; - CoglFramebuffer *framebuffer; -}; - -G_DEFINE_TYPE (ClutterDummyNode, clutter_dummy_node, CLUTTER_TYPE_PAINT_NODE) - -static gboolean -clutter_dummy_node_pre_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - return TRUE; -} - -static CoglFramebuffer * -clutter_dummy_node_get_framebuffer (ClutterPaintNode *node) -{ - ClutterDummyNode *dnode = (ClutterDummyNode *) node; - - return dnode->framebuffer; -} - -static void -clutter_dummy_node_finalize (ClutterPaintNode *node) -{ - ClutterDummyNode *dnode = (ClutterDummyNode *) node; - - g_clear_object (&dnode->framebuffer); - - CLUTTER_PAINT_NODE_CLASS (clutter_dummy_node_parent_class)->finalize (node); -} - -static void -clutter_dummy_node_class_init (ClutterDummyNodeClass *klass) -{ - ClutterPaintNodeClass *node_class = CLUTTER_PAINT_NODE_CLASS (klass); - - node_class->pre_draw = clutter_dummy_node_pre_draw; - node_class->get_framebuffer = clutter_dummy_node_get_framebuffer; - node_class->finalize = clutter_dummy_node_finalize; -} - -static void -clutter_dummy_node_init (ClutterDummyNode *self) -{ -} - -ClutterPaintNode * -_clutter_dummy_node_new (ClutterActor *actor, - CoglFramebuffer *framebuffer) -{ - ClutterPaintNode *res; - ClutterDummyNode *dnode; - - res = _clutter_paint_node_create (_clutter_dummy_node_get_type ()); - - dnode = (ClutterDummyNode *) res; - dnode->actor = actor; - dnode->framebuffer = g_object_ref (framebuffer); - - return res; -} - -/** - * ClutterPipelineNode: - */ - -struct _ClutterPipelineNode -{ - ClutterPaintNode parent_instance; - - CoglPipeline *pipeline; -}; - -/** - * ClutterPipelineNodeClass: - * - * The `ClutterPipelineNodeClass` structure is an opaque - * type whose members cannot be directly accessed. - */ -struct _ClutterPipelineNodeClass -{ - ClutterPaintNodeClass parent_class; -}; - -G_DEFINE_TYPE (ClutterPipelineNode, clutter_pipeline_node, CLUTTER_TYPE_PAINT_NODE) - -static void -clutter_pipeline_node_finalize (ClutterPaintNode *node) -{ - ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node); - - g_clear_object (&pnode->pipeline); - - CLUTTER_PAINT_NODE_CLASS (clutter_pipeline_node_parent_class)->finalize (node); -} - -static gboolean -clutter_pipeline_node_pre_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node); - - if (node->operations != NULL && - pnode->pipeline != NULL) - return TRUE; - - return FALSE; -} - -static CoglFramebuffer * -get_target_framebuffer (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - CoglFramebuffer *framebuffer; - - framebuffer = clutter_paint_node_get_framebuffer (node); - if (framebuffer) - return framebuffer; - - return clutter_paint_context_get_framebuffer (paint_context); -} - -static void -clutter_pipeline_node_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node); - CoglFramebuffer *fb; - guint i; - - if (pnode->pipeline == NULL) - return; - - if (node->operations == NULL) - return; - - fb = clutter_paint_context_get_framebuffer (paint_context); - - for (i = 0; i < node->operations->len; i++) - { - const ClutterPaintOperation *op; - - op = &g_array_index (node->operations, ClutterPaintOperation, i); - - switch (op->opcode) - { - case PAINT_OP_INVALID: - break; - - case PAINT_OP_TEX_RECT: - cogl_framebuffer_draw_textured_rectangle (fb, - pnode->pipeline, - op->op.texrect[0], - op->op.texrect[1], - op->op.texrect[2], - op->op.texrect[3], - op->op.texrect[4], - op->op.texrect[5], - op->op.texrect[6], - op->op.texrect[7]); - break; - - case PAINT_OP_TEX_RECTS: - cogl_framebuffer_draw_textured_rectangles (fb, - pnode->pipeline, - (float *) op->coords->data, - op->coords->len / 8); - break; - - case PAINT_OP_MULTITEX_RECT: - cogl_framebuffer_draw_multitextured_rectangle (fb, - pnode->pipeline, - op->op.texrect[0], - op->op.texrect[1], - op->op.texrect[2], - op->op.texrect[3], - (float *) op->coords->data, - op->coords->len); - break; - - case PAINT_OP_PRIMITIVE: - cogl_primitive_draw (op->op.primitive, - fb, - pnode->pipeline); - break; - } - } -} - -static void -clutter_pipeline_node_post_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ -} - -static void -clutter_pipeline_node_class_init (ClutterPipelineNodeClass *klass) -{ - ClutterPaintNodeClass *node_class; - - node_class = CLUTTER_PAINT_NODE_CLASS (klass); - node_class->pre_draw = clutter_pipeline_node_pre_draw; - node_class->draw = clutter_pipeline_node_draw; - node_class->post_draw = clutter_pipeline_node_post_draw; - node_class->finalize = clutter_pipeline_node_finalize; -} - -static void -clutter_pipeline_node_init (ClutterPipelineNode *self) -{ -} - -/** - * clutter_pipeline_node_new: - * @pipeline: (allow-none): a Cogl pipeline state object, or %NULL - * - * Creates a new #ClutterPaintNode that will use the @pipeline to - * paint its contents. - * - * This function will acquire a reference on the passed @pipeline, - * so it is safe to call g_object_unref() when it returns. - * - * Return value: (transfer full): the newly created #ClutterPaintNode. - * Use clutter_paint_node_unref() when done. - */ -ClutterPaintNode * -clutter_pipeline_node_new (CoglPipeline *pipeline) -{ - ClutterPipelineNode *res; - - g_return_val_if_fail (pipeline == NULL || COGL_IS_PIPELINE (pipeline), NULL); - - res = _clutter_paint_node_create (CLUTTER_TYPE_PIPELINE_NODE); - - if (pipeline != NULL) - res->pipeline = g_object_ref (pipeline); - - return (ClutterPaintNode *) res; -} - -/** - * ClutterColorNode: - */ - -struct _ClutterColorNode -{ - ClutterPipelineNode parent_instance; -}; - -/** - * ClutterColorNodeClass: - * - * The `ClutterColorNodeClass` structure is an - * opaque type whose members cannot be directly accessed. - */ -struct _ClutterColorNodeClass -{ - ClutterPipelineNodeClass parent_class; -}; - -G_DEFINE_TYPE (ClutterColorNode, clutter_color_node, CLUTTER_TYPE_PIPELINE_NODE) - -static void -clutter_color_node_class_init (ClutterColorNodeClass *klass) -{ - -} - -static void -clutter_color_node_init (ClutterColorNode *cnode) -{ - ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (cnode); - - g_assert (default_color_pipeline != NULL); - pnode->pipeline = cogl_pipeline_copy (default_color_pipeline); -} - -/** - * clutter_color_node_new: - * @color: (allow-none): the color to paint, or %NULL - * - * Creates a new #ClutterPaintNode that will paint a solid color - * fill using @color. - * - * Return value: (transfer full): the newly created #ClutterPaintNode. Use - * clutter_paint_node_unref() when done - */ -ClutterPaintNode * -clutter_color_node_new (const ClutterColor *color) -{ - ClutterPipelineNode *cnode; - - cnode = _clutter_paint_node_create (CLUTTER_TYPE_COLOR_NODE); - - if (color != NULL) - { - CoglColor cogl_color; - - cogl_color_init_from_4f (&cogl_color, - color->red / 255.0, - color->green / 255.0, - color->blue / 255.0, - color->alpha / 255.0); - cogl_color_premultiply (&cogl_color); - - cogl_pipeline_set_color (cnode->pipeline, &cogl_color); - } - - return (ClutterPaintNode *) cnode; -} - -/** - * ClutterTextureNode: - * - */ - -struct _ClutterTextureNode -{ - ClutterPipelineNode parent_instance; -}; - -/** - * ClutterTextureNodeClass: - * - * The `ClutterTextureNodeClass` structure is an - * opaque type whose members cannot be directly accessed. - */ -struct _ClutterTextureNodeClass -{ - ClutterPipelineNodeClass parent_class; -}; - -G_DEFINE_TYPE (ClutterTextureNode, clutter_texture_node, CLUTTER_TYPE_PIPELINE_NODE) - -static void -clutter_texture_node_class_init (ClutterTextureNodeClass *klass) -{ -} - -static void -clutter_texture_node_init (ClutterTextureNode *self) -{ - ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (self); - - g_assert (default_texture_pipeline != NULL); - pnode->pipeline = cogl_pipeline_copy (default_texture_pipeline); -} - -static CoglPipelineFilter -clutter_scaling_filter_to_cogl_pipeline_filter (ClutterScalingFilter filter) -{ - switch (filter) - { - case CLUTTER_SCALING_FILTER_NEAREST: - return COGL_PIPELINE_FILTER_NEAREST; - - case CLUTTER_SCALING_FILTER_LINEAR: - return COGL_PIPELINE_FILTER_LINEAR; - - case CLUTTER_SCALING_FILTER_TRILINEAR: - return COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR; - } - - return COGL_PIPELINE_FILTER_LINEAR; -} - -/** - * clutter_texture_node_new: - * @texture: a #CoglTexture - * @color: (allow-none): a #ClutterColor used for blending, or %NULL - * @min_filter: the minification filter for the texture - * @mag_filter: the magnification filter for the texture - * - * Creates a new #ClutterPaintNode that will paint the passed @texture. - * - * This function will take a reference on @texture, so it is safe to - * call g_object_unref() on @texture when it returns. - * - * The @color must not be pre-multiplied with its #ClutterColor.alpha - * channel value; if @color is %NULL, a fully opaque white color will - * be used for blending. - * - * Return value: (transfer full): the newly created #ClutterPaintNode. - * Use clutter_paint_node_unref() when done - */ -ClutterPaintNode * -clutter_texture_node_new (CoglTexture *texture, - const ClutterColor *color, - ClutterScalingFilter min_filter, - ClutterScalingFilter mag_filter) -{ - ClutterPipelineNode *tnode; - CoglColor cogl_color; - CoglPipelineFilter min_f, mag_f; - - g_return_val_if_fail (COGL_IS_TEXTURE (texture), NULL); - - tnode = _clutter_paint_node_create (CLUTTER_TYPE_TEXTURE_NODE); - - cogl_pipeline_set_layer_texture (tnode->pipeline, 0, texture); - - min_f = clutter_scaling_filter_to_cogl_pipeline_filter (min_filter); - mag_f = clutter_scaling_filter_to_cogl_pipeline_filter (mag_filter); - cogl_pipeline_set_layer_filters (tnode->pipeline, 0, min_f, mag_f); - - if (color != NULL) - { - cogl_color_init_from_4f (&cogl_color, - color->red / 255.0, - color->green / 255.0, - color->blue / 255.0, - color->alpha / 255.0); - cogl_color_premultiply (&cogl_color); - } - else - cogl_color_init_from_4f (&cogl_color, 1.0, 1.0, 1.0, 1.0); - - cogl_pipeline_set_color (tnode->pipeline, &cogl_color); - - return (ClutterPaintNode *) tnode; -} - - -/** - * ClutterTextNode: - */ -struct _ClutterTextNode -{ - ClutterPaintNode parent_instance; - - PangoLayout *layout; - CoglColor color; -}; - -/** - * ClutterTextNodeClass: - * - * The `ClutterTextNodeClass` structure is an opaque - * type whose contents cannot be directly accessed. - */ -struct _ClutterTextNodeClass -{ - ClutterPaintNodeClass parent_class; -}; - -G_DEFINE_TYPE (ClutterTextNode, clutter_text_node, CLUTTER_TYPE_PAINT_NODE) - -static void -clutter_text_node_finalize (ClutterPaintNode *node) -{ - ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node); - - g_clear_object (&tnode->layout); - - CLUTTER_PAINT_NODE_CLASS (clutter_text_node_parent_class)->finalize (node); -} - -static gboolean -clutter_text_node_pre_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node); - - return tnode->layout != NULL; -} - -static void -clutter_text_node_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node); - PangoRectangle extents; - CoglFramebuffer *fb; - guint i; - - if (node->operations == NULL) - return; - - fb = get_target_framebuffer (node, paint_context); - - pango_layout_get_pixel_extents (tnode->layout, NULL, &extents); - - for (i = 0; i < node->operations->len; i++) - { - const ClutterPaintOperation *op; - float op_width, op_height; - gboolean clipped = FALSE; - - op = &g_array_index (node->operations, ClutterPaintOperation, i); - - switch (op->opcode) - { - case PAINT_OP_TEX_RECT: - op_width = op->op.texrect[2] - op->op.texrect[0]; - op_height = op->op.texrect[3] - op->op.texrect[1]; - - /* if the primitive size was smaller than the layout, - * we clip the layout when drawin, to avoid spilling - * it out - */ - if (extents.width > op_width || - extents.height > op_height) - { - cogl_framebuffer_push_rectangle_clip (fb, - op->op.texrect[0], - op->op.texrect[1], - op->op.texrect[2], - op->op.texrect[3]); - clipped = TRUE; - } - - cogl_pango_show_layout (fb, - tnode->layout, - op->op.texrect[0], - op->op.texrect[1], - &tnode->color); - - if (clipped) - cogl_framebuffer_pop_clip (fb); - break; - - case PAINT_OP_TEX_RECTS: - case PAINT_OP_MULTITEX_RECT: - case PAINT_OP_PRIMITIVE: - case PAINT_OP_INVALID: - break; - } - } -} - -static void -clutter_text_node_class_init (ClutterTextNodeClass *klass) -{ - ClutterPaintNodeClass *node_class = CLUTTER_PAINT_NODE_CLASS (klass); - - node_class->pre_draw = clutter_text_node_pre_draw; - node_class->draw = clutter_text_node_draw; - node_class->finalize = clutter_text_node_finalize; -} - -static void -clutter_text_node_init (ClutterTextNode *self) -{ - cogl_color_init_from_4f (&self->color, 0.0, 0.0, 0.0, 1.0); -} - -/** - * clutter_text_node_new: - * @layout: (allow-none): a #PangoLayout, or %NULL - * @color: (allow-none): the color used to paint the layout, - * or %NULL - * - * Creates a new #ClutterPaintNode that will paint a #PangoLayout - * with the given color. - * - * This function takes a reference on the passed @layout, so it - * is safe to call g_object_unref() after it returns. - * - * Return value: (transfer full): the newly created #ClutterPaintNode. - * Use clutter_paint_node_unref() when done - */ -ClutterPaintNode * -clutter_text_node_new (PangoLayout *layout, - const ClutterColor *color) -{ - ClutterTextNode *res; - - g_return_val_if_fail (layout == NULL || PANGO_IS_LAYOUT (layout), NULL); - - res = _clutter_paint_node_create (CLUTTER_TYPE_TEXT_NODE); - - if (layout != NULL) - res->layout = g_object_ref (layout); - - if (color != NULL) - { - cogl_color_init_from_4f (&res->color, - color->red / 255.0, - color->green / 255.0, - color->blue / 255.0, - color->alpha / 255.0); - } - - return (ClutterPaintNode *) res; -} - -/** - * ClutterClipNode: - */ -struct _ClutterClipNode -{ - ClutterPaintNode parent_instance; -}; - -/** - * ClutterClipNodeClass: - * - * The `ClutterClipNodeClass` structure is an opaque - * type whose members cannot be directly accessed. - */ -struct _ClutterClipNodeClass -{ - ClutterPaintNodeClass parent_class; -}; - -G_DEFINE_TYPE (ClutterClipNode, clutter_clip_node, CLUTTER_TYPE_PAINT_NODE) - -static gboolean -clutter_clip_node_pre_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - gboolean retval = FALSE; - CoglFramebuffer *fb; - guint i; - - if (node->operations == NULL) - return FALSE; - - fb = get_target_framebuffer (node, paint_context); - - for (i = 0; i < node->operations->len; i++) - { - const ClutterPaintOperation *op; - - op = &g_array_index (node->operations, ClutterPaintOperation, i); - - switch (op->opcode) - { - case PAINT_OP_TEX_RECT: - cogl_framebuffer_push_rectangle_clip (fb, - op->op.texrect[0], - op->op.texrect[1], - op->op.texrect[2], - op->op.texrect[3]); - retval = TRUE; - break; - - case PAINT_OP_TEX_RECTS: - case PAINT_OP_MULTITEX_RECT: - case PAINT_OP_PRIMITIVE: - case PAINT_OP_INVALID: - break; - } - } - - return retval; -} - -static void -clutter_clip_node_post_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - CoglFramebuffer *fb; - guint i; - - if (node->operations == NULL) - return; - - fb = get_target_framebuffer (node, paint_context); - - for (i = 0; i < node->operations->len; i++) - { - const ClutterPaintOperation *op; - - op = &g_array_index (node->operations, ClutterPaintOperation, i); - - switch (op->opcode) - { - case PAINT_OP_TEX_RECT: - cogl_framebuffer_pop_clip (fb); - break; - - case PAINT_OP_TEX_RECTS: - case PAINT_OP_MULTITEX_RECT: - case PAINT_OP_PRIMITIVE: - case PAINT_OP_INVALID: - break; - } - } -} - -static void -clutter_clip_node_class_init (ClutterClipNodeClass *klass) -{ - ClutterPaintNodeClass *node_class; - - node_class = CLUTTER_PAINT_NODE_CLASS (klass); - node_class->pre_draw = clutter_clip_node_pre_draw; - node_class->post_draw = clutter_clip_node_post_draw; -} - -static void -clutter_clip_node_init (ClutterClipNode *self) -{ -} - -/** - * clutter_clip_node_new: - * - * Creates a new #ClutterPaintNode that will clip its child - * nodes to the 2D regions added to it. - * - * Return value: (transfer full): the newly created #ClutterPaintNode. - * Use clutter_paint_node_unref() when done. - */ -ClutterPaintNode * -clutter_clip_node_new (void) -{ - return _clutter_paint_node_create (CLUTTER_TYPE_CLIP_NODE); -} - -/** - * ClutterActorNode: - */ - -struct _ClutterActorNode -{ - ClutterPaintNode parent_instance; - - ClutterActor *actor; - int opacity_override; - int saved_opacity_override; -}; - -struct _ClutterActorNodeClass -{ - ClutterPaintNodeClass parent_class; -}; - -G_DEFINE_TYPE (ClutterActorNode, clutter_actor_node, CLUTTER_TYPE_PAINT_NODE) - -static gboolean -clutter_actor_node_pre_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node); - - if (actor_node->opacity_override != -1) - { - actor_node->saved_opacity_override = - clutter_actor_get_opacity_override (actor_node->actor); - clutter_actor_set_opacity_override (actor_node->actor, - actor_node->opacity_override); - } - - CLUTTER_SET_PRIVATE_FLAGS (actor_node->actor, CLUTTER_IN_PAINT); - - return TRUE; -} - -static void -clutter_actor_node_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node); - - clutter_actor_continue_paint (actor_node->actor, paint_context); -} - -static void -clutter_actor_node_post_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node); - - CLUTTER_UNSET_PRIVATE_FLAGS (actor_node->actor, CLUTTER_IN_PAINT); - - if (actor_node->opacity_override != -1) - { - clutter_actor_set_opacity_override (actor_node->actor, - actor_node->saved_opacity_override); - } -} - -static void -clutter_actor_node_class_init (ClutterActorNodeClass *klass) -{ - ClutterPaintNodeClass *node_class; - - node_class = CLUTTER_PAINT_NODE_CLASS (klass); - node_class->pre_draw = clutter_actor_node_pre_draw; - node_class->draw = clutter_actor_node_draw; - node_class->post_draw = clutter_actor_node_post_draw; -} - -static void -clutter_actor_node_init (ClutterActorNode *self) -{ -} - -/* - * clutter_actor_node_new: - * @actor: the actor to paint - * @opacity: opacity to draw the actor with, or -1 to use the actor's opacity - * - * Creates a new #ClutterActorNode. - * - * The actor is painted together with any effects - * applied to it. Children of this node will draw - * over the actor contents. - * - * Return value: (transfer full): the newly created #ClutterActorNode. - * Use clutter_paint_node_unref() when done. - */ -ClutterPaintNode * -clutter_actor_node_new (ClutterActor *actor, - int opacity) -{ - ClutterActorNode *res; - - g_assert (actor != NULL); - - res = _clutter_paint_node_create (CLUTTER_TYPE_ACTOR_NODE); - res->actor = actor; - res->opacity_override = CLAMP (opacity, -1, 255); - - return (ClutterPaintNode *) res; -} - - -/* - * ClutterEffectNode - */ - -struct _ClutterEffectNode -{ - ClutterPaintNode parent_instance; - - ClutterEffect *effect; -}; - -struct _ClutterEffectNodeClass -{ - ClutterPaintNodeClass parent_class; -}; - -G_DEFINE_TYPE (ClutterEffectNode, clutter_effect_node, CLUTTER_TYPE_PAINT_NODE) - -static void -clutter_effect_node_class_init (ClutterEffectNodeClass *klass) -{ -} - -static void -clutter_effect_node_init (ClutterEffectNode *self) -{ -} - -/** - * clutter_effect_node_new: - * @effect: the actor to paint - * - * Creates a new #ClutterEffectNode. - * - * Return value: (transfer full): the newly created #ClutterEffectNode. - * Use clutter_paint_node_unref() when done. - */ -ClutterPaintNode * -clutter_effect_node_new (ClutterEffect *effect) -{ - ClutterEffectNode *res; - - g_assert (CLUTTER_IS_EFFECT (effect)); - - res = _clutter_paint_node_create (CLUTTER_TYPE_EFFECT_NODE); - res->effect = effect; - - return (ClutterPaintNode *) res; -} - -/* - * ClutterLayerNode - */ - -struct _ClutterLayerNode -{ - ClutterPaintNode parent_instance; - - float fbo_width; - float fbo_height; - - CoglPipeline *pipeline; - CoglFramebuffer *offscreen; - - guint8 opacity; -}; - -struct _ClutterLayerNodeClass -{ - ClutterPaintNodeClass parent_class; -}; - -G_DEFINE_TYPE (ClutterLayerNode, clutter_layer_node, CLUTTER_TYPE_PAINT_NODE) - -static gboolean -clutter_layer_node_pre_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterLayerNode *lnode = (ClutterLayerNode *) node; - - /* if we were unable to create an offscreen buffer for this node, then - * we simply ignore it - */ - if (lnode->offscreen == NULL) - return FALSE; - - clutter_paint_context_push_framebuffer (paint_context, lnode->offscreen); - - /* clear out the target framebuffer */ - cogl_framebuffer_clear4f (lnode->offscreen, - COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH, - 0.f, 0.f, 0.f, 0.f); - - cogl_framebuffer_push_matrix (lnode->offscreen); - - /* every draw operation after this point will happen an offscreen - * framebuffer - */ - - return TRUE; -} - -static void -clutter_layer_node_post_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterLayerNode *lnode = CLUTTER_LAYER_NODE (node); - CoglFramebuffer *fb; - guint i; - - /* switch to the previous framebuffer */ - cogl_framebuffer_pop_matrix (lnode->offscreen); - clutter_paint_context_pop_framebuffer (paint_context); - - if (!node->operations) - return; - - fb = clutter_paint_context_get_framebuffer (paint_context); - - for (i = 0; i < node->operations->len; i++) - { - const ClutterPaintOperation *op; - - op = &g_array_index (node->operations, ClutterPaintOperation, i); - switch (op->opcode) - { - case PAINT_OP_INVALID: - break; - - case PAINT_OP_TEX_RECT: - /* now we need to paint the texture */ - cogl_framebuffer_draw_textured_rectangle (fb, - lnode->pipeline, - op->op.texrect[0], - op->op.texrect[1], - op->op.texrect[2], - op->op.texrect[3], - op->op.texrect[4], - op->op.texrect[5], - op->op.texrect[6], - op->op.texrect[7]); - break; - - case PAINT_OP_TEX_RECTS: - cogl_framebuffer_draw_textured_rectangles (fb, - lnode->pipeline, - (float *) op->coords->data, - op->coords->len / 8); - break; - - case PAINT_OP_MULTITEX_RECT: - cogl_framebuffer_draw_multitextured_rectangle (fb, - lnode->pipeline, - op->op.texrect[0], - op->op.texrect[1], - op->op.texrect[2], - op->op.texrect[3], - (float *) op->coords->data, - op->coords->len); - break; - - case PAINT_OP_PRIMITIVE: - cogl_primitive_draw (op->op.primitive, - fb, - lnode->pipeline); - break; - } - } -} - -static void -clutter_layer_node_finalize (ClutterPaintNode *node) -{ - ClutterLayerNode *lnode = CLUTTER_LAYER_NODE (node); - - g_clear_object (&lnode->pipeline); - g_clear_object (&lnode->offscreen); - - CLUTTER_PAINT_NODE_CLASS (clutter_layer_node_parent_class)->finalize (node); -} - -static void -clutter_layer_node_class_init (ClutterLayerNodeClass *klass) -{ - ClutterPaintNodeClass *node_class; - - node_class = CLUTTER_PAINT_NODE_CLASS (klass); - node_class->pre_draw = clutter_layer_node_pre_draw; - node_class->post_draw = clutter_layer_node_post_draw; - node_class->finalize = clutter_layer_node_finalize; -} - -static void -clutter_layer_node_init (ClutterLayerNode *self) -{ -} - - -/** - * clutter_layer_node_new_to_framebuffer: - * @framebuffer: a #CoglFramebuffer - * @pipeline: a #CoglPipeline - * - * Creates a new #ClutterLayerNode that will redirect drawing at - * @framebuffer. It will then use @pipeline to paint the stored - * operations. - * - * When using this constructor, the caller is responsible for setting - * up @framebuffer, including its modelview and projection matrices, - * and the viewport, and the @pipeline as well. - * - * Return value: (transfer full): the newly created #ClutterLayerNode. - * Use clutter_paint_node_unref() when done. - */ -ClutterPaintNode * -clutter_layer_node_new_to_framebuffer (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline) -{ - ClutterLayerNode *res; - - g_return_val_if_fail (COGL_IS_FRAMEBUFFER (framebuffer), NULL); - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), NULL); - - res = _clutter_paint_node_create (CLUTTER_TYPE_LAYER_NODE); - - res->fbo_width = cogl_framebuffer_get_width (framebuffer); - res->fbo_height = cogl_framebuffer_get_height (framebuffer); - res->offscreen = g_object_ref (framebuffer); - res->pipeline = cogl_pipeline_copy (pipeline); - - return (ClutterPaintNode *) res; -} - -/* - * ClutterBlitNode - */ - -struct _ClutterBlitNode -{ - ClutterPaintNode parent_instance; - - CoglFramebuffer *src; -}; - -G_DEFINE_TYPE (ClutterBlitNode, clutter_blit_node, CLUTTER_TYPE_PAINT_NODE) - -static gboolean -clutter_blit_node_pre_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - return TRUE; -} - -static void -clutter_blit_node_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterBlitNode *blit_node = CLUTTER_BLIT_NODE (node); - g_autoptr (GError) error = NULL; - CoglFramebuffer *framebuffer; - unsigned int i; - - if (node->operations == NULL) - return; - - framebuffer = get_target_framebuffer (node, paint_context); - - for (i = 0; i < node->operations->len; i++) - { - const ClutterPaintOperation *op; - float op_width, op_height; - - op = &g_array_index (node->operations, ClutterPaintOperation, i); - - switch (op->opcode) - { - case PAINT_OP_INVALID: - break; - - case PAINT_OP_TEX_RECT: - op_width = op->op.texrect[6] - op->op.texrect[4]; - op_height = op->op.texrect[7] - op->op.texrect[5]; - - cogl_blit_framebuffer (blit_node->src, - framebuffer, - op->op.texrect[0], - op->op.texrect[1], - op->op.texrect[4], - op->op.texrect[5], - op_width, - op_height, - &error); - - if (error) - { - g_warning ("Error blitting framebuffers: %s", error->message); - return; - } - break; - - case PAINT_OP_TEX_RECTS: - case PAINT_OP_MULTITEX_RECT: - case PAINT_OP_PRIMITIVE: - break; - } - } -} - -static void -clutter_blit_node_finalize (ClutterPaintNode *node) -{ - ClutterBlitNode *blit_node = CLUTTER_BLIT_NODE (node); - - g_clear_object (&blit_node->src); - - CLUTTER_PAINT_NODE_CLASS (clutter_blit_node_parent_class)->finalize (node); -} - -static void -clutter_blit_node_class_init (ClutterBlitNodeClass *klass) -{ - ClutterPaintNodeClass *node_class; - - node_class = CLUTTER_PAINT_NODE_CLASS (klass); - node_class->pre_draw = clutter_blit_node_pre_draw; - node_class->draw = clutter_blit_node_draw; - node_class->finalize = clutter_blit_node_finalize; -} - -static void -clutter_blit_node_init (ClutterBlitNode *self) -{ -} - -/** - * clutter_blit_node_new: - * @src: the source #CoglFramebuffer - * - * Creates a new #ClutterBlitNode that blits @src into the current - * draw framebuffer. - * - * You must only add rectangles using [method@BlitNode.add_blit_rectangle]. - * - * Return value: (transfer full): the newly created #ClutterBlitNode. - * Use clutter_paint_node_unref() when done. - */ -ClutterPaintNode * -clutter_blit_node_new (CoglFramebuffer *src) -{ - ClutterBlitNode *res; - - g_return_val_if_fail (COGL_IS_FRAMEBUFFER (src), NULL); - - res = _clutter_paint_node_create (CLUTTER_TYPE_BLIT_NODE); - res->src = g_object_ref (src); - - return (ClutterPaintNode *) res; -} - -/** - * clutter_blit_node_add_blit_rectangle: - * @blit_node: a #ClutterBlitNode - * @src_x: Source x position - * @src_y: Source y position - * @dst_x: Destination x position - * @dst_y: Destination y position - * @width: Width of region to copy - * @height: Height of region to copy - * - * Adds a new blit rectangle to the stack of rectangles. All the - * constraints of [func@Cogl.blit_framebuffer] apply here. - */ -void -clutter_blit_node_add_blit_rectangle (ClutterBlitNode *blit_node, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height) -{ - g_return_if_fail (CLUTTER_IS_BLIT_NODE (blit_node)); - - clutter_paint_node_add_texture_rectangle (CLUTTER_PAINT_NODE (blit_node), - &(ClutterActorBox) { - .x1 = src_x, - .y1 = src_y, - .x2 = src_x + width, - .y2 = src_y + height, - }, - dst_x, - dst_y, - dst_x + width, - dst_y + height); -} - -/** - * ClutterBlurNode: - */ - -struct _ClutterBlurNode -{ - ClutterLayerNode parent_instance; - - ClutterBlur *blur; - unsigned int radius; -}; - -G_DEFINE_TYPE (ClutterBlurNode, clutter_blur_node, CLUTTER_TYPE_LAYER_NODE) - -static void -clutter_blur_node_post_draw (ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterPaintNodeClass *parent_class = - CLUTTER_PAINT_NODE_CLASS (clutter_blur_node_parent_class); - ClutterBlurNode *blur_node = CLUTTER_BLUR_NODE (node); - - clutter_blur_apply (blur_node->blur); - - parent_class->post_draw (node, paint_context); -} - -static void -clutter_blur_node_finalize (ClutterPaintNode *node) -{ - ClutterBlurNode *blur_node = CLUTTER_BLUR_NODE (node); - - g_clear_pointer (&blur_node->blur, clutter_blur_free); - - CLUTTER_PAINT_NODE_CLASS (clutter_blur_node_parent_class)->finalize (node); -} - -static void -clutter_blur_node_class_init (ClutterBlurNodeClass *klass) -{ - ClutterPaintNodeClass *node_class; - - node_class = CLUTTER_PAINT_NODE_CLASS (klass); - node_class->post_draw = clutter_blur_node_post_draw; - node_class->finalize = clutter_blur_node_finalize; -} - -static void -clutter_blur_node_init (ClutterBlurNode *blur_node) -{ -} - -/** - * clutter_blur_node_new: - * @width width of the blur layer - * @height: height of the blur layer - * @radius: radius (in pixels) of the blur - * - * Creates a new #ClutterBlurNode. - * - * Children of this node will be painted inside a separate framebuffer, - * which will be blurred and painted on the current draw framebuffer. - * - * Return value: (transfer full): the newly created #ClutterBlurNode. - * Use clutter_paint_node_unref() when done. - */ -ClutterPaintNode * -clutter_blur_node_new (unsigned int width, - unsigned int height, - float radius) -{ - g_autoptr (CoglOffscreen) offscreen = NULL; - g_autoptr (GError) error = NULL; - ClutterLayerNode *layer_node; - ClutterBlurNode *blur_node; - CoglContext *context; - CoglTexture *texture; - ClutterBlur *blur; - - g_return_val_if_fail (radius >= 0.0, NULL); - - blur_node = _clutter_paint_node_create (CLUTTER_TYPE_BLUR_NODE); - blur_node->radius = radius; - context = clutter_backend_get_cogl_context (clutter_get_default_backend ()); - texture = cogl_texture_2d_new_with_size (context, width, height); - - cogl_texture_set_premultiplied (texture, TRUE); - - offscreen = cogl_offscreen_new_with_texture (texture); - g_object_unref (texture); - if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (offscreen), &error)) - { - g_warning ("Unable to allocate paint node offscreen: %s", - error->message); - goto out; - } - - blur = clutter_blur_new (texture, radius); - blur_node->blur = blur; - - if (!blur) - { - g_warning ("Failed to create blur pipeline"); - goto out; - } - - layer_node = CLUTTER_LAYER_NODE (blur_node); - layer_node->offscreen = COGL_FRAMEBUFFER (g_steal_pointer (&offscreen)); - layer_node->pipeline = cogl_pipeline_copy (default_texture_pipeline); - cogl_pipeline_set_layer_filters (layer_node->pipeline, 0, - COGL_PIPELINE_FILTER_LINEAR, - COGL_PIPELINE_FILTER_LINEAR); - cogl_pipeline_set_layer_texture (layer_node->pipeline, - 0, - clutter_blur_get_texture (blur)); - - cogl_framebuffer_orthographic (layer_node->offscreen, - 0.0, 0.0, - width, height, - 0.0, 1.0); - -out: - return (ClutterPaintNode *) blur_node; -} diff --git a/mutter/clutter/clutter/clutter-paint-nodes.h b/mutter/clutter/clutter/clutter-paint-nodes.h deleted file mode 100644 index 7e737f7..0000000 --- a/mutter/clutter/clutter/clutter-paint-nodes.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl.h" -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_COLOR_NODE (clutter_color_node_get_type ()) -#define CLUTTER_COLOR_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_COLOR_NODE, ClutterColorNode)) -#define CLUTTER_IS_COLOR_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_COLOR_NODE)) - -typedef struct _ClutterColorNode ClutterColorNode; -typedef struct _ClutterColorNodeClass ClutterColorNodeClass; - -CLUTTER_EXPORT -GType clutter_color_node_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterPaintNode * clutter_color_node_new (const ClutterColor *color); - -#define CLUTTER_TYPE_TEXTURE_NODE (clutter_texture_node_get_type ()) -#define CLUTTER_TEXTURE_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_TEXTURE_NODE, ClutterTextureNode)) -#define CLUTTER_IS_TEXTURE_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_TEXTURE_NODE)) - -typedef struct _ClutterTextureNode ClutterTextureNode; -typedef struct _ClutterTextureNodeClass ClutterTextureNodeClass; - -CLUTTER_EXPORT -GType clutter_texture_node_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterPaintNode * clutter_texture_node_new (CoglTexture *texture, - const ClutterColor *color, - ClutterScalingFilter min_filter, - ClutterScalingFilter mag_filter); - -#define CLUTTER_TYPE_CLIP_NODE (clutter_clip_node_get_type ()) -#define CLUTTER_CLIP_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CLIP_NODE, ClutterClipNode)) -#define CLUTTER_IS_CLIP_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CLIP_NODE)) - -typedef struct _ClutterClipNode ClutterClipNode; -typedef struct _ClutterClipNodeClass ClutterClipNodeClass; - -CLUTTER_EXPORT -GType clutter_clip_node_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterPaintNode * clutter_clip_node_new (void); - -#define CLUTTER_TYPE_PIPELINE_NODE (clutter_pipeline_node_get_type ()) -#define CLUTTER_PIPELINE_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_PIPELINE_NODE, ClutterPipelineNode)) -#define CLUTTER_IS_PIPELINE_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_PIPELINE_NODE)) - -typedef struct _ClutterPipelineNode ClutterPipelineNode; -typedef struct _ClutterPipelineNodeClass ClutterPipelineNodeClass; - -CLUTTER_EXPORT -GType clutter_pipeline_node_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterPaintNode * clutter_pipeline_node_new (CoglPipeline *pipeline); - -#define CLUTTER_TYPE_TEXT_NODE (clutter_text_node_get_type ()) -#define CLUTTER_TEXT_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_TEXT_NODE, ClutterTextNode)) -#define CLUTTER_IS_TEXT_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_TEXT_NODE)) - -typedef struct _ClutterTextNode ClutterTextNode; -typedef struct _ClutterTextNodeClass ClutterTextNodeClass; - -CLUTTER_EXPORT -GType clutter_text_node_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterPaintNode * clutter_text_node_new (PangoLayout *layout, - const ClutterColor *color); - -#define CLUTTER_TYPE_ACTOR_NODE (clutter_actor_node_get_type ()) -#define CLUTTER_ACTOR_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTOR_NODE, ClutterActorNode)) -#define CLUTTER_IS_ACTOR_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTOR_NODE)) - -typedef struct _ClutterActorNode ClutterActorNode; -typedef struct _ClutterActorNode ClutterActorNodeClass; - -CLUTTER_EXPORT -GType clutter_actor_node_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterPaintNode * clutter_actor_node_new (ClutterActor *actor, - int opacity); - -#define CLUTTER_TYPE_ROOT_NODE (clutter_root_node_get_type ()) -#define CLUTTER_ROOT_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ROOT_NODE, ClutterRootNode)) -#define CLUTTER_IS_ROOT_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ROOT_NODE)) - -typedef struct _ClutterRootNode ClutterRootNode; -typedef struct _ClutterPaintNodeClass ClutterRootNodeClass; - -CLUTTER_EXPORT -GType clutter_root_node_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterPaintNode * clutter_root_node_new (CoglFramebuffer *framebuffer, - const ClutterColor *clear_color, - CoglBufferBit clear_flags); - -#define CLUTTER_TYPE_LAYER_NODE (clutter_layer_node_get_type ()) -#define CLUTTER_LAYER_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_LAYER_NODE, ClutterLayerNode)) -#define CLUTTER_IS_LAYER_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_LAYER_NODE)) - -typedef struct _ClutterLayerNode ClutterLayerNode; -typedef struct _ClutterLayerNodeClass ClutterLayerNodeClass; - -CLUTTER_EXPORT -GType clutter_layer_node_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterPaintNode * clutter_layer_node_new_to_framebuffer (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline); - - -#define CLUTTER_TYPE_TRANSFORM_NODE (clutter_transform_node_get_type ()) -#define CLUTTER_TRANSFORM_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_TRANSFORM_NODE, ClutterTransformNode)) -#define CLUTTER_IS_TRANSFORM_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_TRANSFORM_NODE)) - -typedef struct _ClutterTransformNode ClutterTransformNode; -typedef struct _ClutterPaintNodeClass ClutterTransformNodeClass; - -CLUTTER_EXPORT -GType clutter_transform_node_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterPaintNode * clutter_transform_node_new (const graphene_matrix_t *projection); - -#define CLUTTER_TYPE_BLIT_NODE (clutter_blit_node_get_type ()) -#define CLUTTER_BLIT_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BLIT_NODE, ClutterBlitNode)) -#define CLUTTER_IS_BLIT_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BLIT_NODE)) - -typedef struct _ClutterBlitNode ClutterBlitNode; -typedef struct _ClutterPaintNodeClass ClutterBlitNodeClass; - -CLUTTER_EXPORT -GType clutter_blit_node_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterPaintNode * clutter_blit_node_new (CoglFramebuffer *src); - -CLUTTER_EXPORT -void clutter_blit_node_add_blit_rectangle (ClutterBlitNode *blit_node, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height); - -#define CLUTTER_TYPE_BLUR_NODE (clutter_blur_node_get_type ()) -#define CLUTTER_BLUR_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BLUR_NODE, ClutterBlurNode)) -#define CLUTTER_IS_BLUR_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BLUR_NODE)) - -typedef struct _ClutterBlurNode ClutterBlurNode; -typedef struct _ClutterLayerNodeClass ClutterBlurNodeClass; - -CLUTTER_EXPORT -GType clutter_blur_node_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterPaintNode * clutter_blur_node_new (unsigned int width, - unsigned int height, - float radius); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-paint-volume-private.h b/mutter/clutter/clutter/clutter-paint-volume-private.h deleted file mode 100644 index 2218078..0000000 --- a/mutter/clutter/clutter/clutter-paint-volume-private.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#include "clutter/clutter-types.h" -#include "clutter/clutter-private.h" - -G_BEGIN_DECLS - -struct _ClutterPaintVolume -{ - /* A paint volume represents a volume in a given actors private - * coordinate system. */ - ClutterActor *actor; - - /* cuboid for the volume: - * - * 4━━━━━━━┓5 - * ┏━━━━━━━━┓╱┃ - * ┃0 ┊7 1┃ ┃ - * ┃ ┄┄┄┄┄┃┄┃6 - * ┃3 2┃╱ - * ┗━━━━━━━━┛ - * - * 0: top, left (origin) : always valid - * 1: top, right : always valid - * 2: bottom, right : updated lazily - * 3: bottom, left : always valid - * - * 4: top, left, back : always valid - * 5: top, right, back : updated lazily - * 6: bottom, right, back : updated lazily - * 7: bottom, left, back : updated lazily - * - * Elements 0, 1, 3 and 4 are filled in by the PaintVolume setters - * - * Note: the reason for this ordering is that we can simply ignore - * elements 4, 5, 6 and 7 most of the time for 2D actors when - * calculating the projected paint box. - */ - graphene_point3d_t vertices[8]; - - /* As an optimization for internally managed PaintVolumes we allow - * initializing ClutterPaintVolume variables allocated on the stack - * so we can avoid hammering the memory allocator. */ - guint is_static:1; - - /* A newly initialized PaintVolume is considered empty as it is - * degenerate on all three axis. - * - * We consider this carefully when we union an empty volume with - * another so that the union simply results in a copy of the other - * volume instead of also bounding the origin of the empty volume. - * - * For example this is a convenient property when calculating the - * volume of a container as the union of the volume of its children - * where the initial volume passed to the containers - * ->get_paint_volume method will be empty. */ - guint is_empty:1; - - /* TRUE when we've updated the values we calculate lazily */ - guint is_complete:1; - - /* TRUE if vertices 4-7 can be ignored. (Only valid if complete is - * TRUE) */ - guint is_2d:1; - - /* Set to TRUE initially but cleared if the paint volume is - * transformed by a matrix. */ - guint is_axis_aligned:1; - - - /* Note: There is a precedence to the above bitfields that should be - * considered whenever we implement code that manipulates - * PaintVolumes... - * - * Firstly if ->is_empty == TRUE then the values for ->is_complete - * and ->is_2d are undefined, so you should typically check - * ->is_empty as the first priority. - * - * XXX: document other invariables... - */ -}; - -void _clutter_paint_volume_init_static (ClutterPaintVolume *pv, - ClutterActor *actor); -void _clutter_paint_volume_copy_static (const ClutterPaintVolume *src_pv, - ClutterPaintVolume *dst_pv); -void _clutter_paint_volume_set_from_volume (ClutterPaintVolume *pv, - const ClutterPaintVolume *src); - -void _clutter_paint_volume_complete (ClutterPaintVolume *pv); -void _clutter_paint_volume_transform (ClutterPaintVolume *pv, - const graphene_matrix_t *matrix); -void _clutter_paint_volume_get_bounding_box (ClutterPaintVolume *pv, - ClutterActorBox *box); -void _clutter_paint_volume_set_reference_actor (ClutterPaintVolume *pv, - ClutterActor *actor); - -ClutterCullResult _clutter_paint_volume_cull (ClutterPaintVolume *pv, - const graphene_frustum_t *frustum); - -void _clutter_paint_volume_get_stage_paint_box (const ClutterPaintVolume *pv, - ClutterStage *stage, - ClutterActorBox *box); - -void _clutter_paint_volume_transform_relative (ClutterPaintVolume *pv, - ClutterActor *relative_to_ancestor); - -void clutter_paint_volume_to_box (ClutterPaintVolume *pv, - graphene_box_t *box); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-paint-volume.c b/mutter/clutter/clutter/clutter-paint-volume.c deleted file mode 100644 index 191febd..0000000 --- a/mutter/clutter/clutter/clutter-paint-volume.c +++ /dev/null @@ -1,1100 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * Authors: - * Robert Bragg - * Emmanuele Bassi - */ - -#include "config.h" - -#include - -#include -#include - -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-paint-volume-private.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-stage-private.h" -#include "clutter/clutter-actor-box-private.h" - -static void _clutter_paint_volume_axis_align (ClutterPaintVolume *pv); - -G_DEFINE_BOXED_TYPE (ClutterPaintVolume, clutter_paint_volume, - clutter_paint_volume_copy, - clutter_paint_volume_free); - -/* Since paint volumes are used so heavily in a typical paint - * traversal of a Clutter scene graph and since paint volumes often - * have a very short life cycle that maps well to stack allocation we - * allow initializing a static ClutterPaintVolume variable to avoid - * hammering the memory allocator. - * - * We were seeing slice allocation take about 1% cumulative CPU time - * for some very simple clutter tests which although it isn't a *lot* - * this is an easy way to basically drop that to 0%. - * - * The PaintVolume will be internally marked as static and - * clutter_paint_volume_free should still be used to "free" static - * volumes. This allows us to potentially store dynamically allocated - * data inside paint volumes in the future since we would be able to - * free it during _paint_volume_free(). - */ -void -_clutter_paint_volume_init_static (ClutterPaintVolume *pv, - ClutterActor *actor) -{ - pv->actor = actor; - - memset (pv->vertices, 0, 8 * sizeof (graphene_point3d_t)); - - pv->is_static = TRUE; - pv->is_empty = TRUE; - pv->is_axis_aligned = TRUE; - pv->is_complete = TRUE; - pv->is_2d = TRUE; -} - -void -_clutter_paint_volume_copy_static (const ClutterPaintVolume *src_pv, - ClutterPaintVolume *dst_pv) -{ - - g_return_if_fail (src_pv != NULL && dst_pv != NULL); - - memcpy (dst_pv, src_pv, sizeof (ClutterPaintVolume)); - dst_pv->is_static = TRUE; -} - -/** - * clutter_paint_volume_copy: - * @pv: a #ClutterPaintVolume - * - * Copies @pv into a new #ClutterPaintVolume - * - * Return value: a newly allocated copy of a #ClutterPaintVolume - */ -ClutterPaintVolume * -clutter_paint_volume_copy (const ClutterPaintVolume *pv) -{ - ClutterPaintVolume *copy; - - g_return_val_if_fail (pv != NULL, NULL); - - copy = g_memdup2 (pv, sizeof (ClutterPaintVolume)); - copy->is_static = FALSE; - - return copy; -} - -void -_clutter_paint_volume_set_from_volume (ClutterPaintVolume *pv, - const ClutterPaintVolume *src) -{ - gboolean is_static = pv->is_static; - memcpy (pv, src, sizeof (ClutterPaintVolume)); - pv->is_static = is_static; -} - -/** - * clutter_paint_volume_free: - * @pv: a #ClutterPaintVolume - * - * Frees the resources allocated by @pv - */ -void -clutter_paint_volume_free (ClutterPaintVolume *pv) -{ - g_return_if_fail (pv != NULL); - - if (G_LIKELY (pv->is_static)) - return; - - g_free (pv); -} - -/** - * clutter_paint_volume_set_origin: - * @pv: a #ClutterPaintVolume - * @origin: a #graphene_point3d_t - * - * Sets the origin of the paint volume. - * - * The origin is defined as the X, Y and Z coordinates of the top-left - * corner of an actor's paint volume, in actor coordinates. - * - * The default is origin is assumed at: (0, 0, 0) - */ -void -clutter_paint_volume_set_origin (ClutterPaintVolume *pv, - const graphene_point3d_t *origin) -{ - static const int key_vertices[4] = { 0, 1, 3, 4 }; - float dx, dy, dz; - int i; - - g_return_if_fail (pv != NULL); - - dx = origin->x - pv->vertices[0].x; - dy = origin->y - pv->vertices[0].y; - dz = origin->z - pv->vertices[0].z; - - /* If we change the origin then all the key vertices of the paint - * volume need to be shifted too... */ - for (i = 0; i < 4; i++) - { - pv->vertices[key_vertices[i]].x += dx; - pv->vertices[key_vertices[i]].y += dy; - pv->vertices[key_vertices[i]].z += dz; - } - - pv->is_complete = FALSE; -} - -/** - * clutter_paint_volume_get_origin: - * @pv: a #ClutterPaintVolume - * @vertex: (out): the return location for a #graphene_point3d_t - * - * Retrieves the origin of the #ClutterPaintVolume. - */ -void -clutter_paint_volume_get_origin (const ClutterPaintVolume *pv, - graphene_point3d_t *vertex) -{ - g_return_if_fail (pv != NULL); - g_return_if_fail (vertex != NULL); - - *vertex = pv->vertices[0]; -} - -static void -_clutter_paint_volume_update_is_empty (ClutterPaintVolume *pv) -{ - if (pv->vertices[0].x == pv->vertices[1].x && - pv->vertices[0].y == pv->vertices[3].y && - pv->vertices[0].z == pv->vertices[4].z) - pv->is_empty = TRUE; - else - pv->is_empty = FALSE; -} - -/** - * clutter_paint_volume_set_width: - * @pv: a #ClutterPaintVolume - * @width: the width of the paint volume, in pixels - * - * Sets the width of the paint volume. The width is measured along - * the x axis in the actor coordinates that @pv is associated with. - */ -void -clutter_paint_volume_set_width (ClutterPaintVolume *pv, - gfloat width) -{ - gfloat right_xpos; - - g_return_if_fail (pv != NULL); - g_return_if_fail (width >= 0.0f); - - /* If the volume is currently empty then only the origin is - * currently valid */ - if (pv->is_empty) - pv->vertices[1] = pv->vertices[3] = pv->vertices[4] = pv->vertices[0]; - - if (!pv->is_axis_aligned) - _clutter_paint_volume_axis_align (pv); - - right_xpos = pv->vertices[0].x + width; - - /* Move the right vertices of the paint box relative to the - * origin... */ - pv->vertices[1].x = right_xpos; - /* pv->vertices[2].x = right_xpos; NB: updated lazily */ - /* pv->vertices[5].x = right_xpos; NB: updated lazily */ - /* pv->vertices[6].x = right_xpos; NB: updated lazily */ - - pv->is_complete = FALSE; - - _clutter_paint_volume_update_is_empty (pv); -} - -/** - * clutter_paint_volume_get_width: - * @pv: a #ClutterPaintVolume - * - * Retrieves the width of the volume's, axis aligned, bounding box. - * - * In other words; this takes into account what actor's coordinate - * space @pv belongs too and conceptually fits an axis aligned box - * around the volume. It returns the size of that bounding box as - * measured along the x-axis. - * - * If, for example, [method@Actor.get_transformed_paint_volume] - * is used to transform a 2D child actor that is 100px wide, 100px - * high and 0px deep into container coordinates then the width might - * not simply be 100px if the child actor has a 3D rotation applied to - * it. - * - * Remember: if [method@Actor.get_transformed_paint_volume] is - * used then a transformed child volume will be defined relative to the - * ancestor container actor and so a 2D child actor can have a 3D - * bounding volume. - * - * There are no accuracy guarantees for the reported width, - * except that it must always be greater than, or equal to, the - * actor's width. This is because actors may report simple, loose - * fitting paint volumes for efficiency. - - * Return value: the width, in units of @pv's local coordinate system. - */ -gfloat -clutter_paint_volume_get_width (const ClutterPaintVolume *pv) -{ - g_return_val_if_fail (pv != NULL, 0.0); - - if (pv->is_empty) - return 0; - else if (!pv->is_axis_aligned) - { - ClutterPaintVolume tmp; - float width; - _clutter_paint_volume_copy_static (pv, &tmp); - _clutter_paint_volume_axis_align (&tmp); - width = tmp.vertices[1].x - tmp.vertices[0].x; - clutter_paint_volume_free (&tmp); - return width; - } - else - return pv->vertices[1].x - pv->vertices[0].x; -} - -/** - * clutter_paint_volume_set_height: - * @pv: a #ClutterPaintVolume - * @height: the height of the paint volume, in pixels - * - * Sets the height of the paint volume. The height is measured along - * the y axis in the actor coordinates that @pv is associated with. - */ -void -clutter_paint_volume_set_height (ClutterPaintVolume *pv, - gfloat height) -{ - gfloat height_ypos; - - g_return_if_fail (pv != NULL); - g_return_if_fail (height >= 0.0f); - - /* If the volume is currently empty then only the origin is - * currently valid */ - if (pv->is_empty) - pv->vertices[1] = pv->vertices[3] = pv->vertices[4] = pv->vertices[0]; - - if (!pv->is_axis_aligned) - _clutter_paint_volume_axis_align (pv); - - height_ypos = pv->vertices[0].y + height; - - /* Move the bottom vertices of the paint box relative to the - * origin... */ - /* pv->vertices[2].y = height_ypos; NB: updated lazily */ - pv->vertices[3].y = height_ypos; - /* pv->vertices[6].y = height_ypos; NB: updated lazily */ - /* pv->vertices[7].y = height_ypos; NB: updated lazily */ - pv->is_complete = FALSE; - - _clutter_paint_volume_update_is_empty (pv); -} - -/** - * clutter_paint_volume_get_height: - * @pv: a #ClutterPaintVolume - * - * Retrieves the height of the volume's, axis aligned, bounding box. - * - * In other words; this takes into account what actor's coordinate - * space @pv belongs too and conceptually fits an axis aligned box - * around the volume. It returns the size of that bounding box as - * measured along the y-axis. - * - * If, for example, [method@Actor.get_transformed_paint_volume] - * is used to transform a 2D child actor that is 100px wide, 100px - * high and 0px deep into container coordinates then the height might - * not simply be 100px if the child actor has a 3D rotation applied to - * it. - * - * Remember: if [method@Actor.get_transformed_paint_volume] is - * used then a transformed child volume will be defined relative to the - * ancestor container actor and so a 2D child actor - * can have a 3D bounding volume. - * - * There are no accuracy guarantees for the reported height, - * except that it must always be greater than, or equal to, the actor's - * height. This is because actors may report simple, loose fitting paint - * volumes for efficiency. - * - * Return value: the height, in units of @pv's local coordinate system. - */ -gfloat -clutter_paint_volume_get_height (const ClutterPaintVolume *pv) -{ - g_return_val_if_fail (pv != NULL, 0.0); - - if (pv->is_empty) - return 0; - else if (!pv->is_axis_aligned) - { - ClutterPaintVolume tmp; - float height; - _clutter_paint_volume_copy_static (pv, &tmp); - _clutter_paint_volume_axis_align (&tmp); - height = tmp.vertices[3].y - tmp.vertices[0].y; - clutter_paint_volume_free (&tmp); - return height; - } - else - return pv->vertices[3].y - pv->vertices[0].y; -} - -/** - * clutter_paint_volume_set_depth: - * @pv: a #ClutterPaintVolume - * @depth: the depth of the paint volume, in pixels - * - * Sets the depth of the paint volume. The depth is measured along - * the z axis in the actor coordinates that @pv is associated with. - */ -void -clutter_paint_volume_set_depth (ClutterPaintVolume *pv, - gfloat depth) -{ - gfloat depth_zpos; - - g_return_if_fail (pv != NULL); - g_return_if_fail (depth >= 0.0f); - - /* If the volume is currently empty then only the origin is - * currently valid */ - if (pv->is_empty) - pv->vertices[1] = pv->vertices[3] = pv->vertices[4] = pv->vertices[0]; - - if (!pv->is_axis_aligned) - _clutter_paint_volume_axis_align (pv); - - depth_zpos = pv->vertices[0].z + depth; - - /* Move the back vertices of the paint box relative to the - * origin... */ - pv->vertices[4].z = depth_zpos; - /* pv->vertices[5].z = depth_zpos; NB: updated lazily */ - /* pv->vertices[6].z = depth_zpos; NB: updated lazily */ - /* pv->vertices[7].z = depth_zpos; NB: updated lazily */ - - pv->is_complete = FALSE; - pv->is_2d = depth ? FALSE : TRUE; - _clutter_paint_volume_update_is_empty (pv); -} - -/** - * clutter_paint_volume_get_depth: - * @pv: a #ClutterPaintVolume - * - * Retrieves the depth of the volume's, axis aligned, bounding box. - * - * In other words; this takes into account what actor's coordinate - * space @pv belongs too and conceptually fits an axis aligned box - * around the volume. It returns the size of that bounding box as - * measured along the z-axis. - * - * If, for example, [method@Actor.get_transformed_paint_volume] - * is used to transform a 2D child actor that is 100px wide, 100px - * high and 0px deep into container coordinates then the depth might - * not simply be 0px if the child actor has a 3D rotation applied to - * it. - * - * Remember: if [method@Actor.get_transformed_paint_volume] is - * used then the transformed volume will be defined relative to the - * container actor and in container coordinates a 2D child actor - * can have a 3D bounding volume. - * - * There are no accuracy guarantees for the reported depth, - * except that it must always be greater than, or equal to, the actor's - * depth. This is because actors may report simple, loose fitting paint - * volumes for efficiency. - * - * Return value: the depth, in units of @pv's local coordinate system. - */ -gfloat -clutter_paint_volume_get_depth (const ClutterPaintVolume *pv) -{ - g_return_val_if_fail (pv != NULL, 0.0); - - if (pv->is_empty) - return 0; - else if (!pv->is_axis_aligned) - { - ClutterPaintVolume tmp; - float depth; - _clutter_paint_volume_copy_static (pv, &tmp); - _clutter_paint_volume_axis_align (&tmp); - depth = tmp.vertices[4].z - tmp.vertices[0].z; - clutter_paint_volume_free (&tmp); - return depth; - } - else - return pv->vertices[4].z - pv->vertices[0].z; -} - -/** - * clutter_paint_volume_union: - * @pv: The first #ClutterPaintVolume and destination for resulting - * union - * @another_pv: A second #ClutterPaintVolume to union with @pv - * - * Updates the geometry of @pv to encompass @pv and @another_pv. - * - * There are no guarantees about how precisely the two volumes - * will be unioned. - */ -void -clutter_paint_volume_union (ClutterPaintVolume *pv, - const ClutterPaintVolume *another_pv) -{ - ClutterPaintVolume aligned_pv; - graphene_point3d_t min; - graphene_point3d_t max; - graphene_box_t another_box; - graphene_box_t union_box; - graphene_box_t box; - - g_return_if_fail (pv != NULL); - g_return_if_fail (another_pv != NULL); - - /* Both volumes have to belong to the same local coordinate space */ - g_return_if_fail (pv->actor == another_pv->actor); - - /* We special case empty volumes because otherwise we'd end up - * calculating a bounding box that would enclose the origin of - * the empty volume which isn't desired. - */ - if (another_pv->is_empty) - return; - - if (pv->is_empty) - { - _clutter_paint_volume_set_from_volume (pv, another_pv); - goto done; - } - - if (!pv->is_axis_aligned) - _clutter_paint_volume_axis_align (pv); - - _clutter_paint_volume_complete (pv); - - if (!another_pv->is_axis_aligned || !another_pv->is_complete) - { - _clutter_paint_volume_copy_static (another_pv, &aligned_pv); - _clutter_paint_volume_axis_align (&aligned_pv); - _clutter_paint_volume_complete (&aligned_pv); - another_pv = &aligned_pv; - } - - if (G_LIKELY (pv->is_2d)) - graphene_box_init_from_points (&box, 4, pv->vertices); - else - graphene_box_init_from_points (&box, 8, pv->vertices); - - if (G_LIKELY (another_pv->is_2d)) - graphene_box_init_from_points (&another_box, 4, another_pv->vertices); - else - graphene_box_init_from_points (&another_box, 8, another_pv->vertices); - - graphene_box_union (&box, &another_box, &union_box); - - graphene_box_get_min (&union_box, &min); - graphene_box_get_max (&union_box, &max); - graphene_point3d_init (&pv->vertices[0], min.x, min.y, min.z); - graphene_point3d_init (&pv->vertices[1], max.x, min.y, min.z); - graphene_point3d_init (&pv->vertices[3], min.x, max.y, min.z); - graphene_point3d_init (&pv->vertices[4], min.x, min.y, max.z); - - if (pv->vertices[4].z == pv->vertices[0].z) - pv->is_2d = TRUE; - else - pv->is_2d = FALSE; - -done: - pv->is_empty = FALSE; - pv->is_complete = FALSE; -} - -/** - * clutter_paint_volume_union_box: - * @pv: a #ClutterPaintVolume - * @box: a #ClutterActorBox to union to @pv - * - * Unions the 2D region represented by @box to a #ClutterPaintVolume. - * - * This function is similar to [method@PaintVolume.union], but it is - * specific for 2D regions. - */ -void -clutter_paint_volume_union_box (ClutterPaintVolume *pv, - const ClutterActorBox *box) -{ - ClutterPaintVolume volume; - graphene_point3d_t origin; - - g_return_if_fail (pv != NULL); - g_return_if_fail (box != NULL); - - _clutter_paint_volume_init_static (&volume, pv->actor); - - origin.x = box->x1; - origin.y = box->y1; - origin.z = 0.f; - clutter_paint_volume_set_origin (&volume, &origin); - clutter_paint_volume_set_width (&volume, box->x2 - box->x1); - clutter_paint_volume_set_height (&volume, box->y2 - box->y1); - - clutter_paint_volume_union (pv, &volume); - - clutter_paint_volume_free (&volume); -} - -/* The paint_volume setters only update vertices 0, 1, 3 and - * 4 since the others can be drived from them. - * - * This will set pv->completed = TRUE; - */ -void -_clutter_paint_volume_complete (ClutterPaintVolume *pv) -{ - float dx_l2r, dy_l2r, dz_l2r; - float dx_t2b, dy_t2b, dz_t2b; - - if (pv->is_empty) - return; - - if (pv->is_complete) - return; - - /* Find the vector that takes us from any vertex on the left face to - * the corresponding vertex on the right face. */ - dx_l2r = pv->vertices[1].x - pv->vertices[0].x; - dy_l2r = pv->vertices[1].y - pv->vertices[0].y; - dz_l2r = pv->vertices[1].z - pv->vertices[0].z; - - /* Find the vector that takes us from any vertex on the top face to - * the corresponding vertex on the bottom face. */ - dx_t2b = pv->vertices[3].x - pv->vertices[0].x; - dy_t2b = pv->vertices[3].y - pv->vertices[0].y; - dz_t2b = pv->vertices[3].z - pv->vertices[0].z; - - /* front-bottom-right */ - pv->vertices[2].x = pv->vertices[3].x + dx_l2r; - pv->vertices[2].y = pv->vertices[3].y + dy_l2r; - pv->vertices[2].z = pv->vertices[3].z + dz_l2r; - - if (G_UNLIKELY (!pv->is_2d)) - { - /* back-top-right */ - pv->vertices[5].x = pv->vertices[4].x + dx_l2r; - pv->vertices[5].y = pv->vertices[4].y + dy_l2r; - pv->vertices[5].z = pv->vertices[4].z + dz_l2r; - - /* back-bottom-right */ - pv->vertices[6].x = pv->vertices[5].x + dx_t2b; - pv->vertices[6].y = pv->vertices[5].y + dy_t2b; - pv->vertices[6].z = pv->vertices[5].z + dz_t2b; - - /* back-bottom-left */ - pv->vertices[7].x = pv->vertices[4].x + dx_t2b; - pv->vertices[7].y = pv->vertices[4].y + dy_t2b; - pv->vertices[7].z = pv->vertices[4].z + dz_t2b; - } - - pv->is_complete = TRUE; -} - -/* - * _clutter_paint_volume_get_box: - * @pv: a #ClutterPaintVolume - * @box: a pixel aligned #ClutterActorBox - * - * Transforms a 3D paint volume into a 2D bounding box in the - * same coordinate space as the 3D paint volume. - * - * To get an actors "paint box" you should first project - * the paint volume into window coordinates before getting - * the 2D bounding box. - * - * The coordinates of the returned box are not clamped to - * integer pixel values; if you need them to be rounded to the - * nearest integer pixel values, you can use the - * clutter_actor_box_clamp_to_pixel() function. - */ -void -_clutter_paint_volume_get_bounding_box (ClutterPaintVolume *pv, - ClutterActorBox *box) -{ - gfloat x_min, y_min, x_max, y_max; - graphene_point3d_t *vertices; - int count; - gint i; - - g_return_if_fail (pv != NULL); - g_return_if_fail (box != NULL); - - if (pv->is_empty) - { - box->x1 = box->x2 = pv->vertices[0].x; - box->y1 = box->y2 = pv->vertices[0].y; - return; - } - - /* Updates the vertices we calculate lazily - * (See ClutterPaintVolume typedef for more details) */ - _clutter_paint_volume_complete (pv); - - vertices = pv->vertices; - - x_min = x_max = vertices[0].x; - y_min = y_max = vertices[0].y; - - /* Most actors are 2D so we only have to look at the front 4 - * vertices of the paint volume... */ - if (G_LIKELY (pv->is_2d)) - count = 4; - else - count = 8; - - for (i = 1; i < count; i++) - { - if (vertices[i].x < x_min) - x_min = vertices[i].x; - else if (vertices[i].x > x_max) - x_max = vertices[i].x; - - if (vertices[i].y < y_min) - y_min = vertices[i].y; - else if (vertices[i].y > y_max) - y_max = vertices[i].y; - } - - box->x1 = x_min; - box->y1 = y_min; - box->x2 = x_max; - box->y2 = y_max; -} - -static void -_clutter_paint_volume_project (ClutterPaintVolume *pv, - const graphene_matrix_t *modelview, - const graphene_matrix_t *projection, - const float *viewport) -{ - int transform_count; - - if (pv->is_empty) - { - /* Just transform the origin... */ - _clutter_util_fully_transform_vertices (modelview, - projection, - viewport, - pv->vertices, - pv->vertices, - 1); - return; - } - - /* All the vertices must be up to date, since after the projection - * it won't be trivial to derive the other vertices. */ - _clutter_paint_volume_complete (pv); - - /* Most actors are 2D so we only have to transform the front 4 - * vertices of the paint volume... */ - if (G_LIKELY (pv->is_2d)) - transform_count = 4; - else - transform_count = 8; - - _clutter_util_fully_transform_vertices (modelview, - projection, - viewport, - pv->vertices, - pv->vertices, - transform_count); - - pv->is_axis_aligned = FALSE; -} - -void -_clutter_paint_volume_transform (ClutterPaintVolume *pv, - const graphene_matrix_t *matrix) -{ - int transform_count; - - if (pv->is_empty) - { - gfloat w = 1; - /* Just transform the origin */ - cogl_graphene_matrix_project_point (matrix, - &pv->vertices[0].x, - &pv->vertices[0].y, - &pv->vertices[0].z, - &w); - return; - } - - /* All the vertices must be up to date, since after the transform - * it won't be trivial to derive the other vertices. */ - _clutter_paint_volume_complete (pv); - - /* Most actors are 2D so we only have to transform the front 4 - * vertices of the paint volume... */ - if (G_LIKELY (pv->is_2d)) - transform_count = 4; - else - transform_count = 8; - - cogl_graphene_matrix_transform_points (matrix, - 3, - sizeof (graphene_point3d_t), - pv->vertices, - sizeof (graphene_point3d_t), - pv->vertices, - transform_count); - - pv->is_axis_aligned = FALSE; -} - - -/* Given a paint volume that has been transformed by an arbitrary - * modelview and is no longer axis aligned, this derives a replacement - * that is axis aligned. */ -static void -_clutter_paint_volume_axis_align (ClutterPaintVolume *pv) -{ - int count; - int i; - graphene_point3d_t origin; - float max_x; - float max_y; - float max_z; - - g_return_if_fail (pv != NULL); - - if (pv->is_empty) - return; - - if (G_LIKELY (pv->is_axis_aligned)) - return; - - if (G_LIKELY (pv->vertices[0].x == pv->vertices[1].x && - pv->vertices[0].y == pv->vertices[3].y && - pv->vertices[0].z == pv->vertices[4].z)) - { - pv->is_axis_aligned = TRUE; - return; - } - - if (!pv->is_complete) - _clutter_paint_volume_complete (pv); - - origin = pv->vertices[0]; - max_x = pv->vertices[0].x; - max_y = pv->vertices[0].y; - max_z = pv->vertices[0].z; - - count = pv->is_2d ? 4 : 8; - for (i = 1; i < count; i++) - { - if (pv->vertices[i].x < origin.x) - origin.x = pv->vertices[i].x; - else if (pv->vertices[i].x > max_x) - max_x = pv->vertices[i].x; - - if (pv->vertices[i].y < origin.y) - origin.y = pv->vertices[i].y; - else if (pv->vertices[i].y > max_y) - max_y = pv->vertices[i].y; - - if (pv->vertices[i].z < origin.z) - origin.z = pv->vertices[i].z; - else if (pv->vertices[i].z > max_z) - max_z = pv->vertices[i].z; - } - - pv->vertices[0] = origin; - - pv->vertices[1].x = max_x; - pv->vertices[1].y = origin.y; - pv->vertices[1].z = origin.z; - - pv->vertices[3].x = origin.x; - pv->vertices[3].y = max_y; - pv->vertices[3].z = origin.z; - - pv->vertices[4].x = origin.x; - pv->vertices[4].y = origin.y; - pv->vertices[4].z = max_z; - - pv->is_complete = FALSE; - pv->is_axis_aligned = TRUE; - - if (pv->vertices[4].z == pv->vertices[0].z) - pv->is_2d = TRUE; - else - pv->is_2d = FALSE; -} - -/* - * _clutter_actor_set_default_paint_volume: - * @self: a #ClutterActor - * @check_gtype: if not %G_TYPE_INVALID, match the type of @self against - * this type - * @volume: the #ClutterPaintVolume to set - * - * Sets the default paint volume for @self. - * - * This function should be called by #ClutterActor sub-classes that follow - * the default assumption that their paint volume is defined by their - * allocation. - * - * If @check_gtype is not %G_TYPE_INVALID, this function will check the - * type of @self and only compute the paint volume if the type matches; - * this can be used to avoid computing the paint volume for sub-classes - * of an actor class - * - * Return value: %TRUE if the paint volume was set, and %FALSE otherwise - */ -gboolean -_clutter_actor_set_default_paint_volume (ClutterActor *self, - GType check_gtype, - ClutterPaintVolume *volume) -{ - ClutterActorBox box; - - if (check_gtype != G_TYPE_INVALID) - { - if (G_OBJECT_TYPE (self) != check_gtype) - return FALSE; - } - - /* calling clutter_actor_get_allocation_* can potentially be very - * expensive, as it can result in a synchronous full stage relayout - * and redraw - */ - if (!clutter_actor_has_allocation (self)) - return FALSE; - - clutter_actor_get_allocation_box (self, &box); - - /* we only set the width and height, as the paint volume is defined - * to be relative to the actor's modelview, which means that the - * allocation's origin has already been applied - */ - clutter_paint_volume_set_width (volume, box.x2 - box.x1); - clutter_paint_volume_set_height (volume, box.y2 - box.y1); - - return TRUE; -} - -/** - * clutter_paint_volume_set_from_allocation: - * @pv: a #ClutterPaintVolume - * @actor: a #ClutterActor - * - * Sets the #ClutterPaintVolume from the allocation of @actor. - * - * This function should be used when overriding the - * [vfunc@Actor.get_paint_volume] by [class@Actor] sub-classes - * that do not paint outside their allocation. - * - * A typical example is: - * - * ```c - * static gboolean - * my_actor_get_paint_volume (ClutterActor *self, - * ClutterPaintVolume *volume) - * { - * return clutter_paint_volume_set_from_allocation (volume, self); - * } - * ``` - * - * Return value: %TRUE if the paint volume was successfully set, and %FALSE - * otherwise - */ -gboolean -clutter_paint_volume_set_from_allocation (ClutterPaintVolume *pv, - ClutterActor *actor) -{ - g_return_val_if_fail (pv != NULL, FALSE); - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE); - - return _clutter_actor_set_default_paint_volume (actor, G_TYPE_INVALID, pv); -} - -/* Currently paint volumes are defined relative to a given actor, but - * in some cases it is desirable to be able to change the actor that - * a volume relates too (For instance for ClutterClone actors where we - * need to masquerade the source actors volume as the volume for the - * clone). */ -void -_clutter_paint_volume_set_reference_actor (ClutterPaintVolume *pv, - ClutterActor *actor) -{ - g_return_if_fail (pv != NULL); - - pv->actor = actor; -} - -ClutterCullResult -_clutter_paint_volume_cull (ClutterPaintVolume *pv, - const graphene_frustum_t *frustum) -{ - int vertex_count; - graphene_box_t box; - - if (pv->is_empty) - return CLUTTER_CULL_RESULT_OUT; - - /* We expect the volume to already be transformed into eye coordinates - */ - g_return_val_if_fail (pv->is_complete == TRUE, CLUTTER_CULL_RESULT_IN); - g_return_val_if_fail (pv->actor == NULL, CLUTTER_CULL_RESULT_IN); - - /* Most actors are 2D so we only have to transform the front 4 - * vertices of the paint volume... */ - if (G_LIKELY (pv->is_2d)) - vertex_count = 4; - else - vertex_count = 8; - - graphene_box_init_from_points (&box, vertex_count, pv->vertices); - - if (graphene_frustum_intersects_box (frustum, &box)) - return CLUTTER_CULL_RESULT_IN; - else - return CLUTTER_CULL_RESULT_OUT; -} - -void -_clutter_paint_volume_get_stage_paint_box (const ClutterPaintVolume *pv, - ClutterStage *stage, - ClutterActorBox *box) -{ - ClutterPaintVolume projected_pv; - graphene_matrix_t modelview; - graphene_matrix_t projection; - float viewport[4]; - - _clutter_paint_volume_copy_static (pv, &projected_pv); - - graphene_matrix_init_identity (&modelview); - - /* If the paint volume isn't already in eye coordinates... */ - if (pv->actor) - _clutter_actor_apply_relative_transformation_matrix (pv->actor, NULL, - &modelview); - - _clutter_stage_get_projection_matrix (stage, &projection); - _clutter_stage_get_viewport (stage, - &viewport[0], - &viewport[1], - &viewport[2], - &viewport[3]); - - _clutter_paint_volume_project (&projected_pv, - &modelview, - &projection, - viewport); - - _clutter_paint_volume_get_bounding_box (&projected_pv, box); - - if (pv->is_2d && - (!pv->actor || clutter_actor_get_z_position (pv->actor) == 0)) - { - /* If the volume/actor are perfectly 2D, take the bounding box as - * good. We won't need to add any extra room for sub-pixel positioning - * in this case. - */ - clutter_paint_volume_free (&projected_pv); - clutter_round_to_256ths (&box->x1); - clutter_round_to_256ths (&box->y1); - clutter_round_to_256ths (&box->x2); - clutter_round_to_256ths (&box->y2); - box->x1 = floorf (box->x1); - box->y1 = floorf (box->y1); - box->x2 = ceilf (box->x2); - box->y2 = ceilf (box->y2); - return; - } - - _clutter_actor_box_enlarge_for_effects (box); - - clutter_paint_volume_free (&projected_pv); -} - -void -_clutter_paint_volume_transform_relative (ClutterPaintVolume *pv, - ClutterActor *relative_to_ancestor) -{ - graphene_matrix_t matrix; - ClutterActor *actor; - - actor = pv->actor; - - g_return_if_fail (actor != NULL); - - _clutter_paint_volume_set_reference_actor (pv, relative_to_ancestor); - - graphene_matrix_init_identity (&matrix); - _clutter_actor_apply_relative_transformation_matrix (actor, - relative_to_ancestor, - &matrix); - - _clutter_paint_volume_transform (pv, &matrix); -} - -void -clutter_paint_volume_to_box (ClutterPaintVolume *pv, - graphene_box_t *box) -{ - int vertex_count; - - if (pv->is_empty) - { - graphene_box_init_from_box (box, graphene_box_empty ()); - return; - } - - _clutter_paint_volume_complete (pv); - - if (G_LIKELY (pv->is_2d)) - vertex_count = 4; - else - vertex_count = 8; - - graphene_box_init_from_points (box, vertex_count, pv->vertices); -} diff --git a/mutter/clutter/clutter/clutter-pan-action.c b/mutter/clutter/clutter/clutter-pan-action.c deleted file mode 100644 index 8c9436d..0000000 --- a/mutter/clutter/clutter/clutter-pan-action.c +++ /dev/null @@ -1,1012 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * Copyright (C) 2011 Robert Bosch Car Multimedia GmbH. - * Copyright (C) 2012, 2014 Collabora Ltd. - * - * 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 . - * - * Author: - * Emanuele Aina - * - * Based on ClutterDragAction, ClutterSwipeAction, and MxKineticScrollView, - * written by: - * Emmanuele Bassi - * Tomeu Vizoso - * Chris Lord - */ - -/** - * ClutterPanAction: - * - * Action for pan gestures - * - * #ClutterPanAction is a sub-class of [class@GestureAction] that implements - * the logic for recognizing pan gestures. - * - * The simplest usage of #ClutterPanAction consists in adding it to - * a [class@Actor] with a child and setting it as reactive; for instance, - * the following code: - * - * ```c - * clutter_actor_add_action (actor, clutter_pan_action_new ()); - * clutter_actor_set_reactive (actor, TRUE); - * ``` - * - * will automatically result in the actor children to be moved - * when dragging. - */ - -#include "config.h" - -#include "clutter/clutter-pan-action.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-timeline.h" -#include - -#define FLOAT_EPSILON (1e-15) - -static const gfloat min_velocity = 0.1f; // measured in px/ms -static const gfloat reference_fps = 60.0f; // the fps assumed for the deceleration rate -static const gfloat default_deceleration_rate = 0.95f; -static const gfloat default_acceleration_factor = 1.0f; - -typedef enum -{ - PAN_STATE_INACTIVE, - PAN_STATE_PANNING, - PAN_STATE_INTERPOLATING -} PanState; - -typedef enum -{ - SCROLL_PINNED_UNKNOWN, - SCROLL_PINNED_NONE, - SCROLL_PINNED_HORIZONTAL, - SCROLL_PINNED_VERTICAL -} PinState; - -typedef struct _ClutterPanActionPrivate -{ - ClutterPanAxis pan_axis; - - PanState state; - - /* Variables for storing acceleration information */ - ClutterTimeline *deceleration_timeline; - gfloat target_x; - gfloat target_y; - gfloat dx; - gfloat dy; - gdouble deceleration_rate; - gdouble acceleration_factor; - - /* Inertial motion tracking */ - gfloat interpolated_x; - gfloat interpolated_y; - gfloat release_x; - gfloat release_y; - - guint should_interpolate : 1; - - PinState pin_state; -} ClutterPanActionPrivate; - -enum -{ - PROP_0, - - PROP_PAN_AXIS, - PROP_INTERPOLATE, - PROP_DECELERATION, - PROP_ACCELERATION_FACTOR, - - PROP_LAST -}; - -static GParamSpec *pan_props[PROP_LAST] = { NULL, }; - -enum -{ - PAN, - PAN_STOPPED, - - LAST_SIGNAL -}; - -static guint pan_signals[LAST_SIGNAL] = { 0, }; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterPanAction, clutter_pan_action, - CLUTTER_TYPE_GESTURE_ACTION) - -static void -emit_pan (ClutterPanAction *self, - ClutterActor *actor, - gboolean is_interpolated) -{ - ClutterPanActionPrivate *priv = - clutter_pan_action_get_instance_private (self); - gboolean retval; - - if (priv->pin_state == SCROLL_PINNED_UNKNOWN) - { - priv->pin_state = SCROLL_PINNED_NONE; - if (priv->pan_axis == CLUTTER_PAN_AXIS_AUTO) - { - gfloat delta_x; - gfloat delta_y; - gfloat scroll_threshold = G_PI_4/2; - gfloat drag_angle; - - clutter_gesture_action_get_motion_delta (CLUTTER_GESTURE_ACTION (self), - 0, - &delta_x, - &delta_y); - - if (delta_x != 0.0f) - drag_angle = atanf (delta_y / delta_x); - else - drag_angle = G_PI_2; - - if ((drag_angle > -scroll_threshold) && - (drag_angle < scroll_threshold)) - priv->pin_state = SCROLL_PINNED_HORIZONTAL; - else if ((drag_angle > (G_PI_2 - scroll_threshold)) || - (drag_angle < -(G_PI_2 - scroll_threshold))) - priv->pin_state = SCROLL_PINNED_VERTICAL; - } - } - - g_signal_emit (self, pan_signals[PAN], 0, actor, is_interpolated, &retval); -} - -static void -emit_pan_stopped (ClutterPanAction *self, - ClutterActor *actor) -{ - ClutterPanActionPrivate *priv = - clutter_pan_action_get_instance_private (self); - - g_signal_emit (self, pan_signals[PAN_STOPPED], 0, actor); - priv->state = PAN_STATE_INACTIVE; -} - -static void -on_deceleration_stopped (ClutterTimeline *timeline, - gboolean is_finished, - ClutterPanAction *self) -{ - ClutterPanActionPrivate *priv = - clutter_pan_action_get_instance_private (self); - ClutterActor *actor; - - g_object_unref (timeline); - priv->deceleration_timeline = NULL; - - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self)); - emit_pan_stopped (self, actor); -} - -static void -on_deceleration_new_frame (ClutterTimeline *timeline, - gint elapsed_time, - ClutterPanAction *self) -{ - ClutterPanActionPrivate *priv = - clutter_pan_action_get_instance_private (self); - ClutterActor *actor; - gdouble progress; - gfloat interpolated_x, interpolated_y; - - progress = clutter_timeline_get_progress (timeline); - - interpolated_x = priv->target_x * progress; - interpolated_y = priv->target_y * progress; - priv->dx = interpolated_x - priv->interpolated_x; - priv->dy = interpolated_y - priv->interpolated_y; - priv->interpolated_x = interpolated_x; - priv->interpolated_y = interpolated_y; - - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self)); - emit_pan (self, actor, TRUE); -} - -static gboolean -gesture_prepare (ClutterGestureAction *gesture, - ClutterActor *actor) -{ - ClutterPanAction *self = CLUTTER_PAN_ACTION (gesture); - ClutterPanActionPrivate *priv = - clutter_pan_action_get_instance_private (self); - - if (priv->state == PAN_STATE_INTERPOLATING && priv->deceleration_timeline) - clutter_timeline_stop (priv->deceleration_timeline); - - return TRUE; -} - -static gboolean -gesture_begin (ClutterGestureAction *gesture, - ClutterActor *actor) -{ - ClutterPanAction *self = CLUTTER_PAN_ACTION (gesture); - ClutterPanActionPrivate *priv = - clutter_pan_action_get_instance_private (self); - - priv->pin_state = SCROLL_PINNED_UNKNOWN; - priv->state = PAN_STATE_PANNING; - priv->interpolated_x = priv->interpolated_y = 0.0f; - priv->dx = priv->dy = 0.0f; - - return TRUE; -} - -static gboolean -gesture_progress (ClutterGestureAction *gesture, - ClutterActor *actor) -{ - ClutterPanAction *self = CLUTTER_PAN_ACTION (gesture); - - emit_pan (self, actor, FALSE); - - return TRUE; -} - -static void -gesture_cancel (ClutterGestureAction *gesture, - ClutterActor *actor) -{ - ClutterPanAction *self = CLUTTER_PAN_ACTION (gesture); - ClutterPanActionPrivate *priv = - clutter_pan_action_get_instance_private (self); - - priv->state = PAN_STATE_INACTIVE; -} - -static void -gesture_end (ClutterGestureAction *gesture, - ClutterActor *actor) -{ - ClutterPanAction *self = CLUTTER_PAN_ACTION (gesture); - ClutterPanActionPrivate *priv = - clutter_pan_action_get_instance_private (self); - gfloat velocity, velocity_x, velocity_y; - gfloat delta_x, delta_y; - gfloat tau; - gint duration; - - clutter_gesture_action_get_release_coords (CLUTTER_GESTURE_ACTION (self), - 0, - &priv->release_x, - &priv->release_y); - - if (!priv->should_interpolate) - { - priv->state = PAN_STATE_INACTIVE; - return; - } - - priv->state = PAN_STATE_INTERPOLATING; - - clutter_gesture_action_get_motion_delta (gesture, 0, &delta_x, &delta_y); - velocity = clutter_gesture_action_get_velocity (gesture, 0, - &velocity_x, - &velocity_y); - - /* Exponential timing constant v(t) = v(0) * exp(-t/tau) - * tau = 1000ms / (frame_per_second * - ln(decay_per_frame)) - * with frame_per_second = 60 and decay_per_frame = 0.95, tau ~= 325ms - * see http://ariya.ofilabs.com/2011/10/flick-list-with-its-momentum-scrolling-and-deceleration.html */ - tau = 1000.0f / (reference_fps * - logf (priv->deceleration_rate)); - - /* See where the decreasing velocity reaches $min_velocity px/ms - * v(t) = v(0) * exp(-t/tau) = min_velocity - * t = - tau * ln( min_velocity / |v(0)|) */ - duration = - tau * logf (min_velocity / (ABS (velocity) * - priv->acceleration_factor)); - - /* Target point: x(t) = v(0) * tau * [1 - exp(-t/tau)] */ - priv->target_x = (velocity_x * priv->acceleration_factor * tau * - (1 - exp ((float)-duration / tau))); - priv->target_y = (velocity_y * priv->acceleration_factor * tau * - (1 - exp ((float)-duration / tau))); - - if (ABS (velocity) * priv->acceleration_factor > min_velocity && - duration > FLOAT_EPSILON) - { - ClutterActor *pan_actor = - clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gesture)); - - priv->interpolated_x = priv->interpolated_y = 0.0f; - priv->deceleration_timeline = clutter_timeline_new_for_actor (pan_actor, - duration); - clutter_timeline_set_progress_mode (priv->deceleration_timeline, - CLUTTER_EASE_OUT_EXPO); - - g_signal_connect (priv->deceleration_timeline, "new_frame", - G_CALLBACK (on_deceleration_new_frame), self); - g_signal_connect (priv->deceleration_timeline, "stopped", - G_CALLBACK (on_deceleration_stopped), self); - clutter_timeline_start (priv->deceleration_timeline); - } - else - { - emit_pan_stopped (self, actor); - } -} - -static void -clutter_pan_action_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterPanAction *self = CLUTTER_PAN_ACTION (gobject); - - switch (prop_id) - { - case PROP_PAN_AXIS: - clutter_pan_action_set_pan_axis (self, g_value_get_enum (value)); - break; - - case PROP_INTERPOLATE : - clutter_pan_action_set_interpolate (self, g_value_get_boolean (value)); - break; - - case PROP_DECELERATION : - clutter_pan_action_set_deceleration (self, g_value_get_double (value)); - break; - - case PROP_ACCELERATION_FACTOR : - clutter_pan_action_set_acceleration_factor (self, - g_value_get_double (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - } -} - -static void -clutter_pan_action_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterPanAction *self = CLUTTER_PAN_ACTION (gobject); - ClutterPanActionPrivate *priv = - clutter_pan_action_get_instance_private (self); - - switch (prop_id) - { - case PROP_PAN_AXIS: - g_value_set_enum (value, priv->pan_axis); - break; - - case PROP_INTERPOLATE: - g_value_set_boolean (value, priv->should_interpolate); - break; - - case PROP_DECELERATION: - g_value_set_double (value, priv->deceleration_rate); - break; - - case PROP_ACCELERATION_FACTOR: - g_value_set_double (value, priv->acceleration_factor); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - } -} - -static void -clutter_pan_action_constructed (GObject *gobject) -{ - ClutterGestureAction *gesture; - ClutterGestureTriggerEdge edge; - - gesture = CLUTTER_GESTURE_ACTION (gobject); - edge = CLUTTER_GESTURE_TRIGGER_EDGE_AFTER; - clutter_gesture_action_set_threshold_trigger_edge (gesture, edge); -} - -static void -clutter_pan_action_dispose (GObject *gobject) -{ - ClutterPanActionPrivate *priv = - clutter_pan_action_get_instance_private (CLUTTER_PAN_ACTION (gobject)); - - g_clear_object (&priv->deceleration_timeline); - - G_OBJECT_CLASS (clutter_pan_action_parent_class)->dispose (gobject); -} - -static void -clutter_pan_action_set_actor (ClutterActorMeta *meta, - ClutterActor *actor) -{ - ClutterPanAction *self = CLUTTER_PAN_ACTION (meta); - ClutterPanActionPrivate *priv = - clutter_pan_action_get_instance_private (self); - ClutterActor *old_actor; - - old_actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self)); - if (old_actor != actor) - { - /* make sure we reset the state */ - if (priv->state == PAN_STATE_INTERPOLATING) - g_clear_object (&priv->deceleration_timeline); - else if (priv->deceleration_timeline) - clutter_timeline_set_actor (priv->deceleration_timeline, actor); - } - - CLUTTER_ACTOR_META_CLASS (clutter_pan_action_parent_class)->set_actor (meta, - actor); -} - - -static void -clutter_pan_action_class_init (ClutterPanActionClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); - ClutterGestureActionClass *gesture_class = - CLUTTER_GESTURE_ACTION_CLASS (klass); - - gesture_class->gesture_prepare = gesture_prepare; - gesture_class->gesture_begin = gesture_begin; - gesture_class->gesture_progress = gesture_progress; - gesture_class->gesture_cancel = gesture_cancel; - gesture_class->gesture_end = gesture_end; - - meta_class->set_actor = clutter_pan_action_set_actor; - - /** - * ClutterPanAction:pan-axis: - * - * Constraints the panning action to the specified axis - */ - pan_props[PROP_PAN_AXIS] = - g_param_spec_enum ("pan-axis", NULL, NULL, - CLUTTER_TYPE_PAN_AXIS, - CLUTTER_PAN_AXIS_NONE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterPanAction:interpolate: - * - * Whether interpolated events emission is enabled. - */ - pan_props[PROP_INTERPOLATE] = - g_param_spec_boolean ("interpolate", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterPanAction:deceleration: - * - * The rate at which the interpolated panning will decelerate in - * - * #ClutterPanAction will emit interpolated ::pan events with decreasing - * scroll deltas, using the rate specified by this property. - */ - pan_props[PROP_DECELERATION] = - g_param_spec_double ("deceleration", NULL, NULL, - FLOAT_EPSILON, 1.0, default_deceleration_rate, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterPanAction:acceleration-factor: - * - * The initial acceleration factor - * - * The kinetic momentum measured at the time of releasing the pointer will - * be multiplied by the factor specified by this property before being used - * to generate interpolated ::pan events. - */ - pan_props[PROP_ACCELERATION_FACTOR] = - g_param_spec_double ("acceleration-factor", NULL, NULL, - 1.0, G_MAXDOUBLE, default_acceleration_factor, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - gobject_class->constructed = clutter_pan_action_constructed; - gobject_class->set_property = clutter_pan_action_set_property; - gobject_class->get_property = clutter_pan_action_get_property; - gobject_class->dispose = clutter_pan_action_dispose; - g_object_class_install_properties (gobject_class, - PROP_LAST, - pan_props); - - /** - * ClutterPanAction::pan: - * @action: the #ClutterPanAction that emitted the signal - * @actor: the #ClutterActor attached to the @action - * @is_interpolated: if the event is the result of interpolating - * the motion velocity at the end of the drag - * - * The signal is emitted to keep track of the motion during - * a pan gesture. @is_interpolated is set to %TRUE during the - * interpolation phase of the pan, after the drag has ended and - * the :interpolate property was set to %TRUE. - * - * Return value: %TRUE if the pan should continue, and %FALSE if - * the pan should be cancelled. - */ - pan_signals[PAN] = - g_signal_new (I_("pan"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, g_signal_accumulator_true_handled, NULL, - _clutter_marshal_BOOLEAN__OBJECT_BOOLEAN, - G_TYPE_BOOLEAN, 2, - CLUTTER_TYPE_ACTOR, - G_TYPE_BOOLEAN); - - /** - * ClutterPanAction::pan-stopped: - * @action: the #ClutterPanAction that emitted the signal - * @actor: the #ClutterActor attached to the @action - * - * The signal is emitted at the end of the interpolation - * phase of the pan action, only when :interpolate is set to %TRUE. - */ - pan_signals[PAN_STOPPED] = - g_signal_new (I_("pan-stopped"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterPanActionClass, pan_stopped), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_ACTOR); -} - -static void -clutter_pan_action_init (ClutterPanAction *self) -{ - ClutterPanActionPrivate *priv = - clutter_pan_action_get_instance_private (self); - - priv->deceleration_rate = default_deceleration_rate; - priv->acceleration_factor = default_acceleration_factor; - priv->state = PAN_STATE_INACTIVE; -} - -/** - * clutter_pan_action_new: - * - * Creates a new #ClutterPanAction instance - * - * Return value: the newly created #ClutterPanAction - */ -ClutterAction * -clutter_pan_action_new (void) -{ - return g_object_new (CLUTTER_TYPE_PAN_ACTION, NULL); -} - -/** - * clutter_pan_action_set_pan_axis: - * @self: a #ClutterPanAction - * @axis: the axis to constraint the panning to - * - * Restricts the panning action to a specific axis - */ -void -clutter_pan_action_set_pan_axis (ClutterPanAction *self, - ClutterPanAxis axis) -{ - ClutterPanActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_PAN_ACTION (self)); - g_return_if_fail (axis >= CLUTTER_PAN_AXIS_NONE && - axis <= CLUTTER_PAN_AXIS_AUTO); - - priv = clutter_pan_action_get_instance_private (self); - - if (priv->pan_axis == axis) - return; - - priv->pan_axis = axis; - - g_object_notify_by_pspec (G_OBJECT (self), pan_props[PROP_PAN_AXIS]); -} - -/** - * clutter_pan_action_get_pan_axis: - * @self: a #ClutterPanAction - * - * Retrieves the axis constraint set by [method@PanAction.set_pan_axis] - * - * Return value: the axis constraint - */ -ClutterPanAxis -clutter_pan_action_get_pan_axis (ClutterPanAction *self) -{ - ClutterPanActionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_PAN_ACTION (self), - CLUTTER_PAN_AXIS_NONE); - - priv = clutter_pan_action_get_instance_private (self); - return priv->pan_axis; -} - -/** - * clutter_pan_action_set_interpolate: - * @self: a #ClutterPanAction - * @should_interpolate: whether to enable interpolated pan events - * - * Sets whether the action should emit interpolated ::pan events - * after the drag has ended, to emulate the gesture kinetic inertia. - */ -void -clutter_pan_action_set_interpolate (ClutterPanAction *self, - gboolean should_interpolate) -{ - ClutterPanActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_PAN_ACTION (self)); - - priv = clutter_pan_action_get_instance_private (self); - - should_interpolate = !!should_interpolate; - - if (priv->should_interpolate == should_interpolate) - return; - - priv->should_interpolate = should_interpolate; - - g_object_notify_by_pspec (G_OBJECT (self), pan_props[PROP_INTERPOLATE]); -} - -/** - * clutter_pan_action_get_interpolate: - * @self: a #ClutterPanAction - * - * Checks if the action should emit ::pan events even after releasing - * the pointer during a panning gesture, to emulate some kind of - * kinetic inertia. - * - * Return value: %TRUE if interpolated events emission is active. - */ -gboolean -clutter_pan_action_get_interpolate (ClutterPanAction *self) -{ - ClutterPanActionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_PAN_ACTION (self), - FALSE); - - priv = clutter_pan_action_get_instance_private (self); - return priv->should_interpolate; -} - -/** - * clutter_pan_action_set_deceleration: - * @self: A #ClutterPanAction - * @rate: The deceleration rate - * - * Sets the deceleration rate of the interpolated ::pan events generated - * after a pan gesture. This is approximately the value that the momentum - * at the time of releasing the pointer is divided by every 60th of a second. - */ -void -clutter_pan_action_set_deceleration (ClutterPanAction *self, - gdouble rate) -{ - ClutterPanActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_PAN_ACTION (self)); - g_return_if_fail (rate <= 1.0); - g_return_if_fail (rate > 0.0); - - priv = clutter_pan_action_get_instance_private (self); - priv->deceleration_rate = rate; - g_object_notify_by_pspec (G_OBJECT (self), pan_props[PROP_DECELERATION]); -} - -/** - * clutter_pan_action_get_deceleration: - * @self: A #ClutterPanAction - * - * Retrieves the deceleration rate of interpolated ::pan events. - * - * Return value: The deceleration rate of the interpolated events. - */ -gdouble -clutter_pan_action_get_deceleration (ClutterPanAction *self) -{ - ClutterPanActionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_PAN_ACTION (self), 0.95); - - priv = clutter_pan_action_get_instance_private (self); - return priv->deceleration_rate; -} - -/** - * clutter_pan_action_set_acceleration_factor: - * @self: A #ClutterPanAction - * @factor: The acceleration factor - * - * Factor applied to the momentum velocity at the time of releasing the - * pointer when generating interpolated ::pan events. - */ -void -clutter_pan_action_set_acceleration_factor (ClutterPanAction *self, - gdouble factor) -{ - ClutterPanActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_PAN_ACTION (self)); - g_return_if_fail (factor >= 0.0); - - priv = clutter_pan_action_get_instance_private (self); - priv->acceleration_factor = factor; - g_object_notify_by_pspec (G_OBJECT (self), pan_props[PROP_ACCELERATION_FACTOR]); -} - -/** - * clutter_pan_action_get_acceleration_factor: - * @self: A #ClutterPanAction - * - * Retrieves the initial acceleration factor for interpolated ::pan events. - * - * Return value: The initial acceleration factor for interpolated events. - */ -gdouble -clutter_pan_action_get_acceleration_factor (ClutterPanAction *self) -{ - ClutterPanActionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_PAN_ACTION (self), 1.0); - - priv = clutter_pan_action_get_instance_private (self); - return priv->acceleration_factor; -} - -/** - * clutter_pan_action_get_interpolated_coords: - * @self: A #ClutterPanAction - * @interpolated_x: (out) (allow-none): return location for the latest - * interpolated event's X coordinate - * @interpolated_y: (out) (allow-none): return location for the latest - * interpolated event's Y coordinate - * - * Retrieves the coordinates, in stage space, of the latest interpolated - * event, analogous to [method@GestureAction.get_motion_coords]. - */ -void -clutter_pan_action_get_interpolated_coords (ClutterPanAction *self, - gfloat *interpolated_x, - gfloat *interpolated_y) -{ - ClutterPanActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_PAN_ACTION (self)); - - priv = clutter_pan_action_get_instance_private (self); - - if (interpolated_x) - *interpolated_x = priv->release_x + priv->interpolated_x; - - if (interpolated_y) - *interpolated_y = priv->release_y + priv->interpolated_y; -} - -/** - * clutter_pan_action_get_interpolated_delta: - * @self: A #ClutterPanAction - * @delta_x: (out) (allow-none): return location for the X delta since - * the latest interpolated event - * @delta_y: (out) (allow-none): return location for the Y delta since - * the latest interpolated event - * - * Retrieves the delta, in stage space, since the latest interpolated - * event, analogous to [method@GestureAction.get_motion_delta]. - * - * Return value: the distance since the latest interpolated event - */ -gfloat -clutter_pan_action_get_interpolated_delta (ClutterPanAction *self, - gfloat *delta_x, - gfloat *delta_y) -{ - ClutterPanActionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_PAN_ACTION (self), 0.0f); - - priv = clutter_pan_action_get_instance_private (self); - - if (delta_x) - *delta_x = priv->dx; - - if (delta_y) - *delta_y = priv->dy; - - return sqrt ((priv->dx * priv->dx) + (priv->dy * priv->dy)); -} - -/** - * clutter_pan_action_get_constrained_motion_delta: - * @self: A #ClutterPanAction - * @point: the touch point index, with 0 being the first touch - * point received by the action - * @delta_x: (out) (optional): return location for the X delta - * @delta_y: (out) (optional): return location for the Y delta - * - * Retrieves the delta, in stage space, dependent on the current state - * of the #ClutterPanAction, and respecting the constraint specified by the - * [property@PanAction:pan-axis] property. - * - * Return value: the distance since last motion event4 - */ -gfloat -clutter_pan_action_get_constrained_motion_delta (ClutterPanAction *self, - guint point, - gfloat *out_delta_x, - gfloat *out_delta_y) -{ - ClutterPanActionPrivate *priv; - gfloat delta_x = 0.f, delta_y = 0.f, distance; - - g_return_val_if_fail (CLUTTER_IS_PAN_ACTION (self), 0.0f); - - priv = clutter_pan_action_get_instance_private (self); - - distance = clutter_pan_action_get_motion_delta (self, point, - &delta_x, - &delta_y); - - switch (priv->pan_axis) - { - case CLUTTER_PAN_AXIS_NONE: - break; - - case CLUTTER_PAN_AXIS_AUTO: - if (priv->pin_state == SCROLL_PINNED_VERTICAL) - delta_x = 0.0f; - else if (priv->pin_state == SCROLL_PINNED_HORIZONTAL) - delta_y = 0.0f; - break; - - case CLUTTER_PAN_X_AXIS: - delta_y = 0.0f; - break; - - case CLUTTER_PAN_Y_AXIS: - delta_x = 0.0f; - break; - } - - if (out_delta_x) - *out_delta_x = delta_x; - - if (out_delta_y) - *out_delta_y = delta_y; - - return distance; -} - -/** - * clutter_pan_action_get_motion_delta: - * @self: A #ClutterPanAction - * @point: the touch point index, with 0 being the first touch - * point received by the action - * @delta_x: (out) (allow-none): return location for the X delta - * @delta_y: (out) (allow-none): return location for the Y delta - * - * Retrieves the delta, in stage space, dependent on the current state - * of the #ClutterPanAction. If it is inactive, both fields will be - * set to 0. If it is panning by user action, the values will be equivalent - * to those returned by [method@GestureAction.get_motion_delta]. - * If it is interpolating with some form of kinetic scrolling, the values - * will be equivalent to those returned by - * [method@PanAction.get_interpolated_delta]. This is a convenience - * method designed to be used in replacement "pan" signal handlers. - */ -gfloat -clutter_pan_action_get_motion_delta (ClutterPanAction *self, - guint point, - gfloat *delta_x, - gfloat *delta_y) -{ - ClutterPanActionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_PAN_ACTION (self), 0.0f); - - priv = clutter_pan_action_get_instance_private (self); - - switch (priv->state) - { - case PAN_STATE_INACTIVE: - if (delta_x) - *delta_x = 0; - - if (delta_y) - *delta_y = 0; - - return 0; - case PAN_STATE_PANNING: - return clutter_gesture_action_get_motion_delta (CLUTTER_GESTURE_ACTION (self), - point, delta_x, delta_y); - case PAN_STATE_INTERPOLATING: - return clutter_pan_action_get_interpolated_delta (self, delta_x, delta_y); - default: - g_assert_not_reached (); - return 0.0f; - } -} - -/** - * clutter_pan_action_get_motion_coords: - * @self: A #ClutterPanAction - * @point: the touch point index, with 0 being the first touch - * point received by the action - * @motion_x: (out) (allow-none): return location for the X coordinate - * @motion_y: (out) (allow-none): return location for the Y coordinate - * - * Retrieves the coordinates, in stage space, dependent on the current state - * of the #ClutterPanAction. If it is inactive, both fields will be - * set to 0. If it is panning by user action, the values will be equivalent - * to those returned by [method@GestureAction.get_motion_coords]. - * If it is interpolating with some form of kinetic scrolling, the values - * will be equivalent to those returned by - * [method@PanAction.get_interpolated_coords]. This is a convenience - * method designed to be used in replacement "pan" signal handlers. - */ -void -clutter_pan_action_get_motion_coords (ClutterPanAction *self, - guint point, - gfloat *motion_x, - gfloat *motion_y) -{ - ClutterPanActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_PAN_ACTION (self)); - - priv = clutter_pan_action_get_instance_private (self); - - switch (priv->state) - { - case PAN_STATE_INACTIVE: - if (motion_x) - *motion_x = 0; - - if (motion_y) - *motion_y = 0; - break; - case PAN_STATE_PANNING: - clutter_gesture_action_get_motion_coords (CLUTTER_GESTURE_ACTION (self), - point, motion_x, motion_y); - break; - case PAN_STATE_INTERPOLATING: - clutter_pan_action_get_interpolated_coords (self, motion_x, motion_y); - break; - default: - g_assert_not_reached (); - } -} diff --git a/mutter/clutter/clutter/clutter-pan-action.h b/mutter/clutter/clutter/clutter-pan-action.h deleted file mode 100644 index e70eb49..0000000 --- a/mutter/clutter/clutter/clutter-pan-action.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * Copyright (C) 2011 Robert Bosch Car Multimedia GmbH. - * Copyright (C) 2012 Collabora Ltd. - * - * 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 . - * - * Author: - * Emanuele Aina - * - * Based on ClutterDragAction, ClutterSwipeAction, and MxKineticScrollView, - * written by: - * Emmanuele Bassi - * Tomeu Vizoso - * Chris Lord - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-gesture-action.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_PAN_ACTION (clutter_pan_action_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterPanAction, - clutter_pan_action, - CLUTTER, - PAN_ACTION, - ClutterGestureAction) - -/** - * ClutterPanActionClass: - * @pan: class handler for the #ClutterPanAction::pan signal - * @pan_stopped: class handler for the #ClutterPanAction::pan-stopped signal - * - * The #ClutterPanActionClass structure contains - * only private data. - */ -struct _ClutterPanActionClass -{ - /*< private >*/ - ClutterGestureActionClass parent_class; - - /*< public >*/ - void (* pan_stopped) (ClutterPanAction *action, - ClutterActor *actor); -}; - -CLUTTER_EXPORT -ClutterAction * clutter_pan_action_new (void); -CLUTTER_EXPORT -void clutter_pan_action_set_pan_axis (ClutterPanAction *self, - ClutterPanAxis axis); -CLUTTER_EXPORT -ClutterPanAxis clutter_pan_action_get_pan_axis (ClutterPanAction *self); -CLUTTER_EXPORT -void clutter_pan_action_set_interpolate (ClutterPanAction *self, - gboolean should_interpolate); -CLUTTER_EXPORT -gboolean clutter_pan_action_get_interpolate (ClutterPanAction *self); -CLUTTER_EXPORT -void clutter_pan_action_set_deceleration (ClutterPanAction *self, - gdouble rate); -CLUTTER_EXPORT -gdouble clutter_pan_action_get_deceleration (ClutterPanAction *self); -CLUTTER_EXPORT -void clutter_pan_action_set_acceleration_factor (ClutterPanAction *self, - gdouble factor); -CLUTTER_EXPORT -gdouble clutter_pan_action_get_acceleration_factor (ClutterPanAction *self); -CLUTTER_EXPORT -void clutter_pan_action_get_interpolated_coords (ClutterPanAction *self, - gfloat *interpolated_x, - gfloat *interpolated_y); -CLUTTER_EXPORT -gfloat clutter_pan_action_get_interpolated_delta (ClutterPanAction *self, - gfloat *delta_x, - gfloat *delta_y); -CLUTTER_EXPORT -gfloat clutter_pan_action_get_motion_delta (ClutterPanAction *self, - guint point, - gfloat *delta_x, - gfloat *delta_y); -CLUTTER_EXPORT -void clutter_pan_action_get_motion_coords (ClutterPanAction *self, - guint point, - gfloat *motion_x, - gfloat *motion_y); -CLUTTER_EXPORT -gfloat clutter_pan_action_get_constrained_motion_delta (ClutterPanAction *self, - guint point, - gfloat *delta_x, - gfloat *delta_y); -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-pick-context-private.h b/mutter/clutter/clutter/clutter-pick-context-private.h deleted file mode 100644 index 77d032a..0000000 --- a/mutter/clutter/clutter/clutter-pick-context-private.h +++ /dev/null @@ -1,34 +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 . - */ - -#pragma once - -#include "clutter/clutter-pick-context.h" -#include "clutter/clutter-pick-stack-private.h" - -ClutterPickContext * -clutter_pick_context_new_for_view (ClutterStageView *view, - ClutterPickMode mode, - const graphene_point3d_t *point, - const graphene_ray_t *ray); - -ClutterPickStack * -clutter_pick_context_steal_stack (ClutterPickContext *pick_context); - -gboolean -clutter_pick_context_intersects_box (ClutterPickContext *pick_context, - const graphene_box_t *box); diff --git a/mutter/clutter/clutter/clutter-pick-context.c b/mutter/clutter/clutter/clutter-pick-context.c deleted file mode 100644 index aa4f2e2..0000000 --- a/mutter/clutter/clutter/clutter-pick-context.c +++ /dev/null @@ -1,213 +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 . - */ - -#include "config.h" - -#include "clutter/clutter-backend.h" -#include "clutter/clutter-pick-context-private.h" - -struct _ClutterPickContext -{ - grefcount ref_count; - - ClutterPickMode mode; - ClutterPickStack *pick_stack; - - graphene_ray_t ray; - graphene_point3d_t point; -}; - -G_DEFINE_BOXED_TYPE (ClutterPickContext, clutter_pick_context, - clutter_pick_context_ref, - clutter_pick_context_unref) - -ClutterPickContext * -clutter_pick_context_new_for_view (ClutterStageView *view, - ClutterPickMode mode, - const graphene_point3d_t *point, - const graphene_ray_t *ray) -{ - ClutterPickContext *pick_context; - CoglContext *context; - - pick_context = g_new0 (ClutterPickContext, 1); - g_ref_count_init (&pick_context->ref_count); - pick_context->mode = mode; - graphene_ray_init_from_ray (&pick_context->ray, ray); - graphene_point3d_init_from_point (&pick_context->point, point); - - context = clutter_backend_get_cogl_context (clutter_get_default_backend ()); - pick_context->pick_stack = clutter_pick_stack_new (context); - - return pick_context; -} - -ClutterPickContext * -clutter_pick_context_ref (ClutterPickContext *pick_context) -{ - g_ref_count_inc (&pick_context->ref_count); - return pick_context; -} - -static void -clutter_pick_context_dispose (ClutterPickContext *pick_context) -{ - g_clear_pointer (&pick_context->pick_stack, clutter_pick_stack_unref); -} - -void -clutter_pick_context_unref (ClutterPickContext *pick_context) -{ - if (g_ref_count_dec (&pick_context->ref_count)) - { - clutter_pick_context_dispose (pick_context); - g_free (pick_context); - } -} - -void -clutter_pick_context_destroy (ClutterPickContext *pick_context) -{ - clutter_pick_context_dispose (pick_context); - clutter_pick_context_unref (pick_context); -} - -/** - * clutter_pick_context_get_mode: (skip) - */ -ClutterPickMode -clutter_pick_context_get_mode (ClutterPickContext *pick_context) -{ - return pick_context->mode; -} - -ClutterPickStack * -clutter_pick_context_steal_stack (ClutterPickContext *pick_context) -{ - clutter_pick_stack_seal (pick_context->pick_stack); - return g_steal_pointer (&pick_context->pick_stack); -} - -/** - * clutter_pick_context_log_pick: - * @pick_context: a #ClutterPickContext - * @box: a #ClutterActorBox - * @actor: a #ClutterActor - * - * Logs a pick rectangle into the pick stack. - */ -void -clutter_pick_context_log_pick (ClutterPickContext *pick_context, - const ClutterActorBox *box, - ClutterActor *actor) -{ - clutter_pick_stack_log_pick (pick_context->pick_stack, box, actor); -} - -/** - * clutter_pick_context_log_overlap: - * @pick_context: a #ClutterPickContext - * @actor: a #ClutterActor - * - * Logs an overlapping actor into the pick stack. - */ -void -clutter_pick_context_log_overlap (ClutterPickContext *pick_context, - ClutterActor *actor) -{ - clutter_pick_stack_log_overlap (pick_context->pick_stack, actor); -} - -/** - * clutter_pick_context_push_clip: - * @pick_context: a #ClutterPickContext - * @box: a #ClutterActorBox - * - * Pushes a clip rectangle defined by @box into the pick stack. Pop with - * [method@PickContext.pop_clip] when done. - */ -void -clutter_pick_context_push_clip (ClutterPickContext *pick_context, - const ClutterActorBox *box) -{ - clutter_pick_stack_push_clip (pick_context->pick_stack, box); -} - -/** - * clutter_pick_context_pop_clip: - * @pick_context: a #ClutterPickContext - * - * Pops the current clip rectangle from the clip stack. It is a programming - * error to call this without a corresponding [method@PickContext.push_clip] - * call first. - */ -void -clutter_pick_context_pop_clip (ClutterPickContext *pick_context) -{ - clutter_pick_stack_pop_clip (pick_context->pick_stack); -} - -/** - * clutter_pick_context_push_transform: - * @pick_context: a #ClutterPickContext - * @transform: a #graphene_matrix_t - * - * Pushes @transform into the pick stack. Pop with - * [method@PickContext.pop_transform] when done. - */ -void -clutter_pick_context_push_transform (ClutterPickContext *pick_context, - const graphene_matrix_t *transform) -{ - clutter_pick_stack_push_transform (pick_context->pick_stack, transform); -} - -/** - * clutter_pick_context_get_transform: - * @pick_context: a #ClutterPickContext - * @out_matrix: (out): a #graphene_matrix_t - * - * Retrieves the current transform of the pick stack. - */ -void -clutter_pick_context_get_transform (ClutterPickContext *pick_context, - graphene_matrix_t *out_transform) -{ - clutter_pick_stack_get_transform (pick_context->pick_stack, out_transform); -} - -/** - * clutter_pick_context_pop_transform: - * @pick_context: a #ClutterPickContext - * - * Pops the current transform from the clip stack. It is a programming error - * to call this without a corresponding [method@PickContext.push_transform] - * call first. - */ -void -clutter_pick_context_pop_transform (ClutterPickContext *pick_context) -{ - clutter_pick_stack_pop_transform (pick_context->pick_stack); -} - -gboolean -clutter_pick_context_intersects_box (ClutterPickContext *pick_context, - const graphene_box_t *box) -{ - return graphene_box_contains_point (box, &pick_context->point) || - graphene_ray_intersects_box (&pick_context->ray, box); -} diff --git a/mutter/clutter/clutter/clutter-pick-context.h b/mutter/clutter/clutter/clutter-pick-context.h deleted file mode 100644 index 2240526..0000000 --- a/mutter/clutter/clutter/clutter-pick-context.h +++ /dev/null @@ -1,72 +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 . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -#include "clutter/clutter-macros.h" -#include "clutter/clutter-stage-view.h" - -typedef struct _ClutterPickContext ClutterPickContext; - -#define CLUTTER_TYPE_PICK_CONTEXT (clutter_pick_context_get_type ()) - -CLUTTER_EXPORT -GType clutter_pick_context_get_type (void); - -CLUTTER_EXPORT -ClutterPickContext * clutter_pick_context_ref (ClutterPickContext *pick_context); - -CLUTTER_EXPORT -void clutter_pick_context_unref (ClutterPickContext *pick_context); - -CLUTTER_EXPORT -void clutter_pick_context_destroy (ClutterPickContext *pick_context); - -CLUTTER_EXPORT -ClutterPickMode clutter_pick_context_get_mode (ClutterPickContext *pick_context); - -CLUTTER_EXPORT -void clutter_pick_context_log_pick (ClutterPickContext *pick_context, - const ClutterActorBox *box, - ClutterActor *actor); -CLUTTER_EXPORT -void clutter_pick_context_log_overlap (ClutterPickContext *pick_context, - ClutterActor *actor); - -CLUTTER_EXPORT -void clutter_pick_context_push_clip (ClutterPickContext *pick_context, - const ClutterActorBox *box); - -CLUTTER_EXPORT -void clutter_pick_context_pop_clip (ClutterPickContext *pick_context); - -CLUTTER_EXPORT -void clutter_pick_context_push_transform (ClutterPickContext *pick_context, - const graphene_matrix_t *transform); - -CLUTTER_EXPORT -void clutter_pick_context_get_transform (ClutterPickContext *pick_context, - graphene_matrix_t *out_matrix); - -CLUTTER_EXPORT -void clutter_pick_context_pop_transform (ClutterPickContext *pick_context); diff --git a/mutter/clutter/clutter/clutter-pick-stack-private.h b/mutter/clutter/clutter/clutter-pick-stack-private.h deleted file mode 100644 index 7e1d840..0000000 --- a/mutter/clutter/clutter/clutter-pick-stack-private.h +++ /dev/null @@ -1,68 +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 . - */ - -#pragma once - -#include - -#include "clutter/clutter-macros.h" -#include "clutter/clutter-stage-view.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_PICK_STACK (clutter_pick_stack_get_type ()) - -typedef struct _ClutterPickStack ClutterPickStack; - -GType clutter_pick_stack_get_type (void) G_GNUC_CONST; - -ClutterPickStack * clutter_pick_stack_new (CoglContext *context); - -ClutterPickStack * clutter_pick_stack_ref (ClutterPickStack *pick_stack); - -void clutter_pick_stack_unref (ClutterPickStack *pick_stack); - -void clutter_pick_stack_seal (ClutterPickStack *pick_stack); - -void clutter_pick_stack_log_pick (ClutterPickStack *pick_stack, - const ClutterActorBox *box, - ClutterActor *actor); -void clutter_pick_stack_log_overlap (ClutterPickStack *pick_stack, - ClutterActor *actor); - -void clutter_pick_stack_push_clip (ClutterPickStack *pick_stack, - const ClutterActorBox *box); - -void clutter_pick_stack_pop_clip (ClutterPickStack *pick_stack); - -void clutter_pick_stack_push_transform (ClutterPickStack *pick_stack, - const graphene_matrix_t *transform); - -void clutter_pick_stack_get_transform (ClutterPickStack *pick_stack, - graphene_matrix_t *out_transform); - -void clutter_pick_stack_pop_transform (ClutterPickStack *pick_stack); - -ClutterActor * -clutter_pick_stack_search_actor (ClutterPickStack *pick_stack, - const graphene_point3d_t *point, - const graphene_ray_t *ray, - MtkRegion **clear_area); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPickStack, clutter_pick_stack_unref) - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-pick-stack.c b/mutter/clutter/clutter/clutter-pick-stack.c deleted file mode 100644 index dcc14b1..0000000 --- a/mutter/clutter/clutter/clutter-pick-stack.c +++ /dev/null @@ -1,546 +0,0 @@ -/* - * Copyright (C) 2020 Endless OS Foundation, LLC - * Copyright (C) 2018 Canonical Ltd. - * - * 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 . - */ - -#include "config.h" - -#include "clutter/clutter-pick-stack-private.h" -#include "clutter/clutter-private.h" - -typedef struct -{ - graphene_point3d_t vertices[4]; - CoglMatrixEntry *matrix_entry; - ClutterActorBox rect; - gboolean projected; -} Record; - -typedef struct -{ - Record base; - ClutterActor *actor; - int clip_index; - gboolean is_overlap; -} PickRecord; - -typedef struct -{ - Record base; - int prev; -} PickClipRecord; - -struct _ClutterPickStack -{ - grefcount ref_count; - - CoglMatrixStack *matrix_stack; - GArray *vertices_stack; - GArray *clip_stack; - int current_clip_stack_top; - - gboolean sealed : 1; -}; - -G_DEFINE_BOXED_TYPE (ClutterPickStack, clutter_pick_stack, - clutter_pick_stack_ref, clutter_pick_stack_unref) - -static void -project_vertices (CoglMatrixEntry *matrix_entry, - const ClutterActorBox *box, - graphene_point3d_t vertices[4]) -{ - graphene_matrix_t m; - int i; - - cogl_matrix_entry_get (matrix_entry, &m); - - graphene_point3d_init (&vertices[0], box->x1, box->y1, 0.f); - graphene_point3d_init (&vertices[1], box->x2, box->y1, 0.f); - graphene_point3d_init (&vertices[2], box->x2, box->y2, 0.f); - graphene_point3d_init (&vertices[3], box->x1, box->y2, 0.f); - - for (i = 0; i < 4; i++) - { - float w = 1.f; - - cogl_graphene_matrix_project_point (&m, - &vertices[i].x, - &vertices[i].y, - &vertices[i].z, - &w); - } -} - -static void -maybe_project_record (Record *rec) -{ - if (!rec->projected) - { - project_vertices (rec->matrix_entry, &rec->rect, rec->vertices); - rec->projected = TRUE; - } -} - -static inline gboolean -is_axis_aligned_2d_rectangle (const graphene_point3d_t vertices[4]) -{ - int i; - - for (i = 0; i < 4; i++) - { - if (!G_APPROX_VALUE (vertices[i].z, - vertices[(i + 1) % 4].z, - FLT_EPSILON)) - return FALSE; - - if (!G_APPROX_VALUE (vertices[i].x, - vertices[(i + 1) % 4].x, - FLT_EPSILON) && - !G_APPROX_VALUE (vertices[i].y, - vertices[(i + 1) % 4].y, - FLT_EPSILON)) - return FALSE; - } - - return TRUE; -} - -static gboolean -ray_intersects_input_region (Record *rec, - const graphene_ray_t *ray, - const graphene_point3d_t *point) -{ - maybe_project_record (rec); - - if (G_LIKELY (is_axis_aligned_2d_rectangle (rec->vertices))) - { - graphene_box_t box; - graphene_box_t right_border; - graphene_box_t bottom_border; - - /* Graphene considers both the start and end coordinates of boxes to be - * inclusive, while the vertices of a clutter actor are exclusive. So we - * need to manually exclude hits on these borders - */ - - graphene_box_init_from_points (&box, 4, rec->vertices); - graphene_box_init_from_points (&right_border, 2, rec->vertices + 1); - graphene_box_init_from_points (&bottom_border, 2, rec->vertices + 2); - - /* Fast path for actors without 3D transforms */ - if (graphene_box_contains_point (&box, point)) - { - return !graphene_box_contains_point (&right_border, point) && - !graphene_box_contains_point (&bottom_border, point); - } - - return graphene_ray_intersects_box (ray, &box) && - !graphene_ray_intersects_box (ray, &right_border) && - !graphene_ray_intersects_box (ray, &bottom_border); - } - else - { - graphene_triangle_t t0, t1; - - /* - * Degrade the projected quad into the following triangles: - * - * 0 -------------- 1 - * | • | - * | • t0 | - * | • | - * | t1 • | - * | • | - * 3 -------------- 2 - */ - - graphene_triangle_init_from_point3d (&t0, - &rec->vertices[0], - &rec->vertices[1], - &rec->vertices[2]); - - graphene_triangle_init_from_point3d (&t1, - &rec->vertices[0], - &rec->vertices[2], - &rec->vertices[3]); - - return graphene_triangle_contains_point (&t0, point) || - graphene_triangle_contains_point (&t1, point) || - graphene_ray_intersects_triangle (ray, &t0) || - graphene_ray_intersects_triangle (ray, &t1); - } -} - -static gboolean -ray_intersects_record (ClutterPickStack *pick_stack, - PickRecord *rec, - const graphene_point3d_t *point, - const graphene_ray_t *ray) -{ - int clip_index; - - if (!ray_intersects_input_region (&rec->base, ray, point)) - return FALSE; - - clip_index = rec->clip_index; - while (clip_index >= 0) - { - PickClipRecord *clip = - &g_array_index (pick_stack->clip_stack, PickClipRecord, clip_index); - - if (!ray_intersects_input_region (&clip->base, ray, point)) - return FALSE; - - clip_index = clip->prev; - } - - return TRUE; -} - -static void -add_pick_stack_weak_refs (ClutterPickStack *pick_stack) -{ - int i; - - g_assert (!pick_stack->sealed); - - for (i = 0; i < pick_stack->vertices_stack->len; i++) - { - PickRecord *rec = - &g_array_index (pick_stack->vertices_stack, PickRecord, i); - - if (rec->actor) - g_object_add_weak_pointer (G_OBJECT (rec->actor), - (gpointer) &rec->actor); - } -} - -static void -remove_pick_stack_weak_refs (ClutterPickStack *pick_stack) -{ - int i; - - for (i = 0; i < pick_stack->vertices_stack->len; i++) - { - PickRecord *rec = - &g_array_index (pick_stack->vertices_stack, PickRecord, i); - - if (rec->actor) - g_object_remove_weak_pointer (G_OBJECT (rec->actor), - (gpointer) &rec->actor); - } -} - -static void -clutter_pick_stack_dispose (ClutterPickStack *pick_stack) -{ - remove_pick_stack_weak_refs (pick_stack); - g_clear_object (&pick_stack->matrix_stack); - g_clear_pointer (&pick_stack->vertices_stack, g_array_unref); - g_clear_pointer (&pick_stack->clip_stack, g_array_unref); -} - -static void -clear_pick_record (gpointer data) -{ - PickRecord *rec = data; - g_clear_pointer (&rec->base.matrix_entry, cogl_matrix_entry_unref); -} - -static void -clear_clip_record (gpointer data) -{ - PickClipRecord *clip = data; - g_clear_pointer (&clip->base.matrix_entry, cogl_matrix_entry_unref); -} - -/** - * clutter_pick_stack_new: - * @context: a #CoglContext - * - * Creates a new #ClutterPickStack. - * - * Returns: (transfer full): A newly created #ClutterPickStack - */ -ClutterPickStack * -clutter_pick_stack_new (CoglContext *context) -{ - ClutterPickStack *pick_stack; - - pick_stack = g_new0 (ClutterPickStack, 1); - g_ref_count_init (&pick_stack->ref_count); - pick_stack->matrix_stack = cogl_matrix_stack_new (context); - pick_stack->vertices_stack = g_array_new (FALSE, FALSE, sizeof (PickRecord)); - pick_stack->clip_stack = g_array_new (FALSE, FALSE, sizeof (PickClipRecord)); - pick_stack->current_clip_stack_top = -1; - - g_array_set_clear_func (pick_stack->vertices_stack, clear_pick_record); - g_array_set_clear_func (pick_stack->clip_stack, clear_clip_record); - - return pick_stack; -} - -/** - * clutter_pick_stack_ref: - * @pick_stack: A #ClutterPickStack - * - * Increments the reference count of @pick_stack by one. - * - * Returns: (transfer full): @pick_stack - */ -ClutterPickStack * -clutter_pick_stack_ref (ClutterPickStack *pick_stack) -{ - g_ref_count_inc (&pick_stack->ref_count); - return pick_stack; -} - -/** - * clutter_pick_stack_unref: - * @pick_stack: A #ClutterPickStack - * - * Decrements the reference count of @pick_stack by one, freeing the structure - * when the reference count reaches zero. - */ -void -clutter_pick_stack_unref (ClutterPickStack *pick_stack) -{ - if (g_ref_count_dec (&pick_stack->ref_count)) - { - clutter_pick_stack_dispose (pick_stack); - g_free (pick_stack); - } -} - -void -clutter_pick_stack_seal (ClutterPickStack *pick_stack) -{ - g_assert (!pick_stack->sealed); - add_pick_stack_weak_refs (pick_stack); - pick_stack->sealed = TRUE; -} - -void -clutter_pick_stack_log_pick (ClutterPickStack *pick_stack, - const ClutterActorBox *box, - ClutterActor *actor) -{ - PickRecord rec; - - g_return_if_fail (actor != NULL); - - g_assert (!pick_stack->sealed); - - rec.is_overlap = FALSE; - rec.actor = actor; - rec.clip_index = pick_stack->current_clip_stack_top; - rec.base.rect = *box; - rec.base.projected = FALSE; - rec.base.matrix_entry = cogl_matrix_stack_get_entry (pick_stack->matrix_stack); - cogl_matrix_entry_ref (rec.base.matrix_entry); - - g_array_append_val (pick_stack->vertices_stack, rec); -} - -void -clutter_pick_stack_log_overlap (ClutterPickStack *pick_stack, - ClutterActor *actor) -{ - PickRecord rec = { 0 }; - - g_assert (!pick_stack->sealed); - - rec.is_overlap = TRUE; - rec.actor = actor; - rec.clip_index = pick_stack->current_clip_stack_top; - - g_array_append_val (pick_stack->vertices_stack, rec); -} - -void -clutter_pick_stack_push_clip (ClutterPickStack *pick_stack, - const ClutterActorBox *box) -{ - PickClipRecord clip; - - g_assert (!pick_stack->sealed); - - clip.prev = pick_stack->current_clip_stack_top; - clip.base.rect = *box; - clip.base.projected = FALSE; - clip.base.matrix_entry = cogl_matrix_stack_get_entry (pick_stack->matrix_stack); - cogl_matrix_entry_ref (clip.base.matrix_entry); - - g_array_append_val (pick_stack->clip_stack, clip); - pick_stack->current_clip_stack_top = pick_stack->clip_stack->len - 1; -} - -void -clutter_pick_stack_pop_clip (ClutterPickStack *pick_stack) -{ - const PickClipRecord *top; - - g_assert (!pick_stack->sealed); - g_assert (pick_stack->current_clip_stack_top >= 0); - - /* Individual elements of clip_stack are not freed. This is so they can - * be shared as part of a tree of different stacks used by different - * actors in the pick_stack. The whole clip_stack does however get - * freed later in clutter_pick_stack_dispose. - */ - - top = &g_array_index (pick_stack->clip_stack, - PickClipRecord, - pick_stack->current_clip_stack_top); - - pick_stack->current_clip_stack_top = top->prev; -} - -void -clutter_pick_stack_push_transform (ClutterPickStack *pick_stack, - const graphene_matrix_t *transform) -{ - cogl_matrix_stack_push (pick_stack->matrix_stack); - cogl_matrix_stack_multiply (pick_stack->matrix_stack, transform); -} - -void -clutter_pick_stack_get_transform (ClutterPickStack *pick_stack, - graphene_matrix_t *out_transform) -{ - cogl_matrix_stack_get (pick_stack->matrix_stack, out_transform); -} - -void -clutter_pick_stack_pop_transform (ClutterPickStack *pick_stack) -{ - cogl_matrix_stack_pop (pick_stack->matrix_stack); -} - -static gboolean -get_verts_rectangle (graphene_point3d_t verts[4], - MtkRectangle *rect) -{ - if (verts[0].x != verts[2].x || - verts[0].y != verts[1].y || - verts[3].x != verts[1].x || - verts[3].y != verts[2].y || - verts[0].x > verts[3].x || - verts[0].y > verts[3].y) - return FALSE; - - *rect = (MtkRectangle) { - .x = ceilf (verts[0].x), - .y = ceilf (verts[0].y), - .width = floor (verts[1].x - ceilf (verts[0].x)), - .height = floor (verts[2].y - ceilf (verts[0].y)), - }; - - return TRUE; -} - -static void -calculate_clear_area (ClutterPickStack *pick_stack, - PickRecord *pick_rec, - int elem, - MtkRegion **clear_area) -{ - MtkRegion *area = NULL; - graphene_point3d_t verts[4]; - MtkRectangle rect; - int i; - - if (!clutter_actor_has_allocation (pick_rec->actor)) - { - if (clear_area) - *clear_area = NULL; - return; - } - - clutter_actor_get_abs_allocation_vertices (pick_rec->actor, - (graphene_point3d_t *) &verts); - if (!get_verts_rectangle (verts, &rect)) - { - if (clear_area) - *clear_area = NULL; - return; - } - - rect.x += ceil (pick_rec->base.rect.x1); - rect.y += ceil (pick_rec->base.rect.y1); - rect.width = - MIN (rect.width, floor (pick_rec->base.rect.x2 - pick_rec->base.rect.x1)); - rect.height = - MIN (rect.height, floor (pick_rec->base.rect.y2 - pick_rec->base.rect.y1)); - - area = mtk_region_create_rectangle (&rect); - - for (i = elem + 1; i < pick_stack->vertices_stack->len; i++) - { - PickRecord *rec = - &g_array_index (pick_stack->vertices_stack, PickRecord, i); - ClutterActorBox paint_box; - - if (!rec->is_overlap && - (rec->base.rect.x1 == rec->base.rect.x2 || - rec->base.rect.y1 == rec->base.rect.y2)) - continue; - - if (!clutter_actor_get_paint_box (rec->actor, &paint_box)) - continue; - - mtk_region_subtract_rectangle (area, - &MTK_RECTANGLE_INIT (paint_box.x1, paint_box.y1, - paint_box.x2 - paint_box.x1, - paint_box.y2 - paint_box.y1) - ); - } - - if (clear_area) - *clear_area = g_steal_pointer (&area); - - g_clear_pointer (&area, mtk_region_unref); -} - -ClutterActor * -clutter_pick_stack_search_actor (ClutterPickStack *pick_stack, - const graphene_point3d_t *point, - const graphene_ray_t *ray, - MtkRegion **clear_area) -{ - int i; - - /* Search all "painted" pickable actors from front to back. A linear search - * is required, and also performs fine since there is typically only - * on the order of dozens of actors in the list (on screen) at a time. - */ - for (i = pick_stack->vertices_stack->len - 1; i >= 0; i--) - { - PickRecord *rec = - &g_array_index (pick_stack->vertices_stack, PickRecord, i); - - if (!rec->is_overlap && rec->actor && - ray_intersects_record (pick_stack, rec, point, ray)) - { - if (clear_area) - calculate_clear_area (pick_stack, rec, i, clear_area); - return rec->actor; - } - } - - return NULL; -} diff --git a/mutter/clutter/clutter/clutter-private.h b/mutter/clutter/clutter/clutter-private.h deleted file mode 100644 index 9677395..0000000 --- a/mutter/clutter/clutter/clutter-private.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * 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 . - * - * - */ - -#pragma once - -#include -#include -#include - -#include "cogl-pango/cogl-pango.h" - -#include "clutter/clutter-backend.h" -#include "clutter/clutter-context.h" -#include "clutter/clutter-effect.h" -#include "clutter/clutter-event.h" -#include "clutter/clutter-layout-manager.h" -#include "clutter/clutter-settings.h" -#include "clutter/clutter-stage-manager.h" -#include "clutter/clutter-stage.h" - -G_BEGIN_DECLS - -typedef struct _ClutterContext ClutterContext; - -#define CLUTTER_REGISTER_VALUE_TRANSFORM_TO(TYPE_TO,func) { \ - g_value_register_transform_func (g_define_type_id, TYPE_TO, func); \ -} - -#define CLUTTER_REGISTER_VALUE_TRANSFORM_FROM(TYPE_FROM,func) { \ - g_value_register_transform_func (TYPE_FROM, g_define_type_id, func); \ -} - -#define CLUTTER_REGISTER_INTERVAL_PROGRESS(func) { \ - clutter_interval_register_progress_func (g_define_type_id, func); \ -} - -#define CLUTTER_PRIVATE_FLAGS(a) (((ClutterActor *) (a))->private_flags) -#define CLUTTER_SET_PRIVATE_FLAGS(a,f) (CLUTTER_PRIVATE_FLAGS (a) |= (f)) -#define CLUTTER_UNSET_PRIVATE_FLAGS(a,f) (CLUTTER_PRIVATE_FLAGS (a) &= ~(f)) - -#define CLUTTER_ACTOR_IS_TOPLEVEL(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IS_TOPLEVEL) != FALSE) -#define CLUTTER_ACTOR_IN_DESTRUCTION(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_DESTRUCTION) != FALSE) -#define CLUTTER_ACTOR_IN_PAINT(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PAINT) != FALSE) -#define CLUTTER_ACTOR_IN_PICK(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PICK) != FALSE) -#define CLUTTER_ACTOR_IN_RELAYOUT(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_RELAYOUT) != FALSE) -#define CLUTTER_ACTOR_IN_MAP_UNMAP(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_MAP_UNMAP) != FALSE) - -#define CLUTTER_PARAM_ANIMATABLE (1 << G_PARAM_USER_SHIFT) - -/* automagic interning of a static string */ -#define I_(str) (g_intern_static_string ((str))) - -/* This is a replacement for the nearbyint function which always rounds to the - * nearest integer. nearbyint is apparently a C99 function so it might not - * always be available but also it seems in glibc it is defined as a function - * call so this macro could end up faster anyway. We can't just add 0.5f - * because it will break for negative numbers. */ -#define CLUTTER_NEARBYINT(x) ((int) ((x) < 0.0f ? (x) - 0.5f : (x) + 0.5f)) - -typedef enum -{ - CLUTTER_ACTOR_UNUSED_FLAG = 0, - - CLUTTER_IN_DESTRUCTION = 1 << 0, - CLUTTER_IS_TOPLEVEL = 1 << 1, - CLUTTER_IN_PREF_WIDTH = 1 << 3, - CLUTTER_IN_PREF_HEIGHT = 1 << 4, - - /* Used to avoid recursion */ - CLUTTER_IN_PAINT = 1 << 5, - CLUTTER_IN_PICK = 1 << 6, - - /* Used to avoid recursion */ - CLUTTER_IN_RELAYOUT = 1 << 7, - - CLUTTER_IN_MAP_UNMAP = 1 << 8, -} ClutterPrivateFlags; - -ClutterContext * _clutter_context_get_default (void); - -CLUTTER_EXPORT -gboolean _clutter_context_is_initialized (void); -gboolean _clutter_context_get_show_fps (void); - -/* Diagnostic mode */ -gboolean _clutter_diagnostic_enabled (void); - -/* use this function as the accumulator if you have a signal with - * a G_TYPE_BOOLEAN return value; this will stop the emission as - * soon as one handler returns TRUE - */ -gboolean _clutter_boolean_handled_accumulator (GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, - gpointer dummy); - -/* use this function as the accumulator if you have a signal with - * a G_TYPE_BOOLEAN return value; this will stop the emission as - * soon as one handler returns FALSE - */ -gboolean _clutter_boolean_continue_accumulator (GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, - gpointer dummy); - -void _clutter_run_repaint_functions (ClutterRepaintFlags flags); - -void _clutter_util_fully_transform_vertices (const graphene_matrix_t *modelview, - const graphene_matrix_t *projection, - const float *viewport, - const graphene_point3d_t *vertices_in, - graphene_point3d_t *vertices_out, - int n_vertices); - -CLUTTER_EXPORT -ClutterTextDirection clutter_unichar_direction (gunichar ch); - -ClutterTextDirection _clutter_find_base_dir (const gchar *text, - gint length); - -PangoDirection -clutter_text_direction_to_pango_direction (ClutterTextDirection dir); - -typedef enum _ClutterCullResult -{ - CLUTTER_CULL_RESULT_UNKNOWN, - CLUTTER_CULL_RESULT_IN, - CLUTTER_CULL_RESULT_OUT, -} ClutterCullResult; - -gboolean _clutter_has_progress_function (GType gtype); -gboolean _clutter_run_progress_function (GType gtype, - const GValue *initial, - const GValue *final, - gdouble progress, - GValue *retval); - -void clutter_timeline_cancel_delay (ClutterTimeline *timeline); - -static inline void -clutter_round_to_256ths (float *f) -{ - *f = roundf ((*f) * 256) / 256; -} - -static inline uint64_t -ns (uint64_t ns) -{ - return ns; -} - -static inline int64_t -us (int64_t us) -{ - return us; -} - -static inline int64_t -ms (int64_t ms) -{ - return ms; -} - -static inline int64_t -ms2us (int64_t ms) -{ - return us (ms * 1000); -} - -static inline int64_t -us2ns (int64_t us) -{ - return ns (us * 1000); -} - -static inline int64_t -us2ms (int64_t us) -{ - return (int64_t) (us / 1000); -} - -static inline int64_t -ns2us (int64_t ns) -{ - return us (ns / 1000); -} - -static inline int64_t -s2us (int64_t s) -{ - return s * G_USEC_PER_SEC; -} - -static inline int64_t -us2s (int64_t us) -{ - return us / G_USEC_PER_SEC; -} - -static inline int64_t -s2ns (int64_t s) -{ - return us2ns (s2us (s)); -} - -static inline int64_t -s2ms (int64_t s) -{ - return (int64_t) ms (s * 1000); -} - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-property-transition.c b/mutter/clutter/clutter/clutter-property-transition.c deleted file mode 100644 index f05fa09..0000000 --- a/mutter/clutter/clutter/clutter-property-transition.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/** - * ClutterPropertyTransition: - * - * Property transitions - * - * #ClutterPropertyTransition is a specialized [class@Transition] that - * can be used to tween a property of a [iface@Animatable] instance. - */ - -#include "config.h" - -#include "clutter/clutter-property-transition.h" - -#include "clutter/clutter-animatable.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-interval.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-transition.h" - -typedef struct _ClutterPropertyTransitionPrivate -{ - char *property_name; - - GParamSpec *pspec; -} ClutterPropertyTransitionPrivate; - -enum -{ - PROP_0, - - PROP_PROPERTY_NAME, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST] = { NULL, }; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterPropertyTransition, clutter_property_transition, CLUTTER_TYPE_TRANSITION) - -static inline void -clutter_property_transition_ensure_interval (ClutterPropertyTransition *transition, - ClutterAnimatable *animatable, - ClutterInterval *interval) -{ - ClutterPropertyTransitionPrivate *priv = - clutter_property_transition_get_instance_private (transition); - GValue *value_p; - - if (clutter_interval_is_valid (interval)) - return; - - /* if no initial value has been set, use the current value */ - value_p = clutter_interval_peek_initial_value (interval); - if (!G_IS_VALUE (value_p)) - { - g_value_init (value_p, clutter_interval_get_value_type (interval)); - clutter_animatable_get_initial_state (animatable, - priv->property_name, - value_p); - } - - /* if no final value has been set, use the current value */ - value_p = clutter_interval_peek_final_value (interval); - if (!G_IS_VALUE (value_p)) - { - g_value_init (value_p, clutter_interval_get_value_type (interval)); - clutter_animatable_get_initial_state (animatable, - priv->property_name, - value_p); - } -} - -static void -clutter_property_transition_attached (ClutterTransition *transition, - ClutterAnimatable *animatable) -{ - ClutterPropertyTransition *self = CLUTTER_PROPERTY_TRANSITION (transition); - ClutterPropertyTransitionPrivate *priv = - clutter_property_transition_get_instance_private (self); - ClutterInterval *interval; - - if (priv->property_name == NULL) - return; - - priv->pspec = - clutter_animatable_find_property (animatable, priv->property_name); - - if (priv->pspec == NULL) - return; - - interval = clutter_transition_get_interval (transition); - if (interval == NULL) - return; - - clutter_property_transition_ensure_interval (self, animatable, interval); -} - -static void -clutter_property_transition_detached (ClutterTransition *transition, - ClutterAnimatable *animatable) -{ - ClutterPropertyTransition *self = CLUTTER_PROPERTY_TRANSITION (transition); - ClutterPropertyTransitionPrivate *priv = - clutter_property_transition_get_instance_private (self); - - priv->pspec = NULL; -} - -static void -clutter_property_transition_compute_value (ClutterTransition *transition, - ClutterAnimatable *animatable, - ClutterInterval *interval, - gdouble progress) -{ - ClutterPropertyTransition *self = CLUTTER_PROPERTY_TRANSITION (transition); - ClutterPropertyTransitionPrivate *priv = - clutter_property_transition_get_instance_private (self); - GValue value = G_VALUE_INIT; - GType p_type, i_type; - gboolean res; - - /* if we have a GParamSpec we also have an animatable instance */ - if (priv->pspec == NULL) - return; - - clutter_property_transition_ensure_interval (self, animatable, interval); - - p_type = G_PARAM_SPEC_VALUE_TYPE (priv->pspec); - i_type = clutter_interval_get_value_type (interval); - - g_value_init (&value, i_type); - - res = clutter_animatable_interpolate_value (animatable, - priv->property_name, - interval, - progress, - &value); - - if (res) - { - if (i_type != p_type || g_type_is_a (i_type, p_type)) - { - if (g_value_type_transformable (i_type, p_type)) - { - GValue transform = G_VALUE_INIT; - - g_value_init (&transform, p_type); - - if (g_value_transform (&value, &transform)) - { - clutter_animatable_set_final_state (animatable, - priv->property_name, - &transform); - } - else - g_warning ("%s: Unable to convert a value of type '%s' from " - "the value type '%s' of the interval.", - G_STRLOC, - g_type_name (p_type), - g_type_name (i_type)); - - g_value_unset (&transform); - } - } - else - clutter_animatable_set_final_state (animatable, - priv->property_name, - &value); - } - - g_value_unset (&value); -} - -static void -clutter_property_transition_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterPropertyTransition *self = CLUTTER_PROPERTY_TRANSITION (gobject); - - switch (prop_id) - { - case PROP_PROPERTY_NAME: - clutter_property_transition_set_property_name (self, - g_value_get_string (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - } -} - -static void -clutter_property_transition_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterPropertyTransition *self = CLUTTER_PROPERTY_TRANSITION (gobject); - ClutterPropertyTransitionPrivate *priv = - clutter_property_transition_get_instance_private (self); - - switch (prop_id) - { - case PROP_PROPERTY_NAME: - g_value_set_string (value, priv->property_name); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - } -} - -static void -clutter_property_transition_finalize (GObject *gobject) -{ - ClutterPropertyTransition *self = CLUTTER_PROPERTY_TRANSITION (gobject); - ClutterPropertyTransitionPrivate *priv = - clutter_property_transition_get_instance_private (self); - - g_free (priv->property_name); - - G_OBJECT_CLASS (clutter_property_transition_parent_class)->finalize (gobject); -} - -static void -clutter_property_transition_class_init (ClutterPropertyTransitionClass *klass) -{ - ClutterTransitionClass *transition_class = CLUTTER_TRANSITION_CLASS (klass); - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - transition_class->attached = clutter_property_transition_attached; - transition_class->detached = clutter_property_transition_detached; - transition_class->compute_value = clutter_property_transition_compute_value; - - gobject_class->set_property = clutter_property_transition_set_property; - gobject_class->get_property = clutter_property_transition_get_property; - gobject_class->finalize = clutter_property_transition_finalize; - - /** - * ClutterPropertyTransition:property-name: - * - * The name of the property of a [iface@Animatable] to animate. - */ - obj_props[PROP_PROPERTY_NAME] = - g_param_spec_string ("property-name", NULL, NULL, - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); -} - -static void -clutter_property_transition_init (ClutterPropertyTransition *self) -{ -} - -/** - * clutter_property_transition_new_for_actor: - * @actor: a #ClutterActor - * @property_name: (allow-none): a property of @animatable, or %NULL - * - * Creates a new #ClutterPropertyTransition. - * - * Return value: (transfer full): the newly created #ClutterPropertyTransition. - * Use g_object_unref() when done - */ -ClutterTransition * -clutter_property_transition_new_for_actor (ClutterActor *actor, - const char *property_name) -{ - return g_object_new (CLUTTER_TYPE_PROPERTY_TRANSITION, - "actor", actor, - "property-name", property_name, - NULL); -} - -/** - * clutter_property_transition_new: - * @property_name: (allow-none): a property of @animatable, or %NULL - * - * Creates a new #ClutterPropertyTransition. - * - * Return value: (transfer full): the newly created #ClutterPropertyTransition. - * Use g_object_unref() when done - */ -ClutterTransition * -clutter_property_transition_new (const char *property_name) -{ - return g_object_new (CLUTTER_TYPE_PROPERTY_TRANSITION, - "property-name", property_name, - NULL); -} - -/** - * clutter_property_transition_set_property_name: - * @transition: a #ClutterPropertyTransition - * @property_name: (allow-none): a property name - * - * Sets the [property@PropertyTransition:property-name] property of @transition. - */ -void -clutter_property_transition_set_property_name (ClutterPropertyTransition *transition, - const char *property_name) -{ - ClutterPropertyTransitionPrivate *priv; - ClutterAnimatable *animatable; - - g_return_if_fail (CLUTTER_IS_PROPERTY_TRANSITION (transition)); - - priv = clutter_property_transition_get_instance_private (transition); - - if (g_strcmp0 (priv->property_name, property_name) == 0) - return; - - g_free (priv->property_name); - priv->property_name = g_strdup (property_name); - priv->pspec = NULL; - - animatable = - clutter_transition_get_animatable (CLUTTER_TRANSITION (transition)); - if (animatable != NULL) - { - priv->pspec = clutter_animatable_find_property (animatable, - priv->property_name); - } - - g_object_notify_by_pspec (G_OBJECT (transition), - obj_props[PROP_PROPERTY_NAME]); -} - -/** - * clutter_property_transition_get_property_name: - * @transition: a #ClutterPropertyTransition - * - * Retrieves the value of the [property@PropertyTransition:property-name] - * property. - * - * Return value: the name of the property being animated, or %NULL if - * none is set. The returned string is owned by the @transition and - * it should not be freed. - */ -const char * -clutter_property_transition_get_property_name (ClutterPropertyTransition *transition) -{ - ClutterPropertyTransitionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_PROPERTY_TRANSITION (transition), NULL); - - priv = clutter_property_transition_get_instance_private (transition); - return priv->property_name; -} diff --git a/mutter/clutter/clutter/clutter-property-transition.h b/mutter/clutter/clutter/clutter-property-transition.h deleted file mode 100644 index 95adf9b..0000000 --- a/mutter/clutter/clutter/clutter-property-transition.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" -#include "clutter/clutter-transition.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_PROPERTY_TRANSITION (clutter_property_transition_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterPropertyTransition, - clutter_property_transition, - CLUTTER, - PROPERTY_TRANSITION, - ClutterTransition) - -/** - * ClutterPropertyTransitionClass: - * - * The #ClutterPropertyTransitionClass structure - * contains private data. - */ -struct _ClutterPropertyTransitionClass -{ - /*< private >*/ - ClutterTransitionClass parent_class; -}; - -CLUTTER_EXPORT -ClutterTransition * clutter_property_transition_new_for_actor (ClutterActor *actor, - const char *property_name); - -CLUTTER_EXPORT -ClutterTransition * clutter_property_transition_new (const char *property_name); - -CLUTTER_EXPORT -void clutter_property_transition_set_property_name (ClutterPropertyTransition *transition, - const char *property_name); -CLUTTER_EXPORT -const char * clutter_property_transition_get_property_name (ClutterPropertyTransition *transition); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-rotate-action.c b/mutter/clutter/clutter/clutter-rotate-action.c deleted file mode 100644 index 14ad3dc..0000000 --- a/mutter/clutter/clutter/clutter-rotate-action.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Lionel Landwerlin - */ - -/** - * ClutterRotateAction: - * - * Action to rotate an actor - * - * #ClutterRotateAction is a sub-class of [class@GestureAction] that implements - * the logic for recognizing rotate gestures using two touch points. - */ - -#include "config.h" - -#include - -#include "clutter/clutter-rotate-action.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-private.h" - -typedef struct _ClutterRotateActionPrivate -{ - gfloat initial_vector[2]; - gdouble initial_vector_norm; - gdouble initial_rotation; -} ClutterRotateActionPrivate; - -enum -{ - ROTATE, - - LAST_SIGNAL -}; - -static guint rotate_signals[LAST_SIGNAL] = { 0, }; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterRotateAction, clutter_rotate_action, CLUTTER_TYPE_GESTURE_ACTION) - -static gboolean -clutter_rotate_action_gesture_begin (ClutterGestureAction *action, - ClutterActor *actor) -{ - ClutterRotateActionPrivate *priv = - clutter_rotate_action_get_instance_private (CLUTTER_ROTATE_ACTION (action)); - gfloat p1[2], p2[2]; - - /* capture initial vector */ - clutter_gesture_action_get_motion_coords (action, 0, &p1[0], &p1[1]); - clutter_gesture_action_get_motion_coords (action, 1, &p2[0], &p2[1]); - - priv->initial_vector[0] = p2[0] - p1[0]; - priv->initial_vector[1] = p2[1] - p1[1]; - - priv->initial_vector_norm = - sqrt (priv->initial_vector[0] * priv->initial_vector[0] + - priv->initial_vector[1] * priv->initial_vector[1]); - - priv->initial_rotation = clutter_actor_get_rotation_angle (actor, CLUTTER_Z_AXIS); - - return TRUE; -} - -static gboolean -clutter_rotate_action_gesture_progress (ClutterGestureAction *action, - ClutterActor *actor) -{ - ClutterRotateActionPrivate *priv = - clutter_rotate_action_get_instance_private (CLUTTER_ROTATE_ACTION (action)); - gfloat p1[2], p2[2]; - gfloat vector[2]; - gboolean retval; - - /* capture current vector */ - clutter_gesture_action_get_motion_coords (action, 0, &p1[0], &p1[1]); - clutter_gesture_action_get_motion_coords (action, 1, &p2[0], &p2[1]); - - vector[0] = p2[0] - p1[0]; - vector[1] = p2[1] - p1[1]; - - if ((vector[0] == priv->initial_vector[0]) && - (vector[1] == priv->initial_vector[1])) - { - g_signal_emit (action, rotate_signals[ROTATE], 0, - actor, (gdouble) 0.0, - &retval); - } - else - { - gfloat mult[2]; - gfloat norm; - gdouble angle; - - /* Computes angle between the 2 initial touch points and the - current position of the 2 touch points. */ - norm = sqrt (vector[0] * vector[0] + vector[1] * vector[1]); - norm = (priv->initial_vector[0] * vector[0] + - priv->initial_vector[1] * vector[1]) / (priv->initial_vector_norm * norm); - - if ((norm >= -1.0) && (norm <= 1.0)) - angle = acos (norm); - else - angle = 0; - - /* The angle given is comprise between 0 and 180 degrees, we - need some logic on top to get a value between 0 and 360. */ - mult[0] = priv->initial_vector[0] * vector[1] - - priv->initial_vector[1] * vector[0]; - mult[1] = priv->initial_vector[1] * vector[0] - - priv->initial_vector[0] * vector[1]; - - if (mult[0] < 0) - angle = -angle; - - /* Convert radians to degrees */ - angle = angle * 180.0 / G_PI; - - g_signal_emit (action, rotate_signals[ROTATE], 0, - actor, angle, - &retval); - } - - return TRUE; -} - -static void -clutter_rotate_action_gesture_cancel (ClutterGestureAction *action, - ClutterActor *actor) -{ - gboolean retval; - - g_signal_emit (action, rotate_signals[ROTATE], 0, - actor, (gdouble) 0.0, - &retval); -} - -static void -clutter_rotate_action_constructed (GObject *gobject) -{ - ClutterGestureAction *gesture; - - gesture = CLUTTER_GESTURE_ACTION (gobject); - clutter_gesture_action_set_threshold_trigger_edge (gesture, CLUTTER_GESTURE_TRIGGER_EDGE_NONE); -} - -static void -clutter_rotate_action_class_init (ClutterRotateActionClass *klass) -{ - ClutterGestureActionClass *gesture_class = - CLUTTER_GESTURE_ACTION_CLASS (klass); - GObjectClass *object_class = - G_OBJECT_CLASS (klass); - - object_class->constructed = clutter_rotate_action_constructed; - - gesture_class->gesture_begin = clutter_rotate_action_gesture_begin; - gesture_class->gesture_progress = clutter_rotate_action_gesture_progress; - gesture_class->gesture_cancel = clutter_rotate_action_gesture_cancel; - - /** - * ClutterRotateAction::rotate: - * @action: the #ClutterRotateAction that emitted the signal - * @actor: the #ClutterActor attached to the @action - * @angle: the difference of angle of rotation between the initial - * rotation and the current rotation - * - * The signal is emitted when a rotate gesture is - * recognized on the attached actor and when the gesture is - * cancelled (in this case with an angle value of 0). - * - * Return value: %TRUE if the rotation should continue, and %FALSE if - * the rotation should be cancelled. - */ - rotate_signals[ROTATE] = - g_signal_new (I_("rotate"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, g_signal_accumulator_true_handled, NULL, - _clutter_marshal_BOOLEAN__OBJECT_DOUBLE, - G_TYPE_BOOLEAN, 2, - CLUTTER_TYPE_ACTOR, - G_TYPE_DOUBLE); -} - -static void -clutter_rotate_action_init (ClutterRotateAction *self) -{ - clutter_gesture_action_set_n_touch_points (CLUTTER_GESTURE_ACTION (self), - 2); -} - -/** - * clutter_rotate_action_new: - * - * Creates a new #ClutterRotateAction instance - * - * Return value: the newly created #ClutterRotateAction - */ -ClutterAction * -clutter_rotate_action_new (void) -{ - return g_object_new (CLUTTER_TYPE_ROTATE_ACTION, NULL); -} diff --git a/mutter/clutter/clutter/clutter-rotate-action.h b/mutter/clutter/clutter/clutter-rotate-action.h deleted file mode 100644 index 136d111..0000000 --- a/mutter/clutter/clutter/clutter-rotate-action.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Lionel Landwerlin - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-gesture-action.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_ROTATE_ACTION (clutter_rotate_action_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterRotateAction, - clutter_rotate_action, - CLUTTER, - ROTATE_ACTION, - ClutterGestureAction) - -/** - * ClutterRotateActionClass: - * @rotate: class handler for the #ClutterRotateAction::rotate signal - * - * The #ClutterRotateActionClass structure contains - * only private data. - */ -struct _ClutterRotateActionClass -{ - /*< private >*/ - ClutterGestureActionClass parent_class; -}; - -CLUTTER_EXPORT -ClutterAction *clutter_rotate_action_new (void); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-scroll-actor.c b/mutter/clutter/clutter/clutter-scroll-actor.c deleted file mode 100644 index 34a6fa6..0000000 --- a/mutter/clutter/clutter/clutter-scroll-actor.c +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/** - * ClutterScrollActor: - * - * An actor for displaying a portion of its children - * - * #ClutterScrollActor is an actor that can be used to display a portion - * of the contents of its children. - * - * The extent of the area of a #ClutterScrollActor is defined by the size - * of its children; the visible region of the children of a #ClutterScrollActor - * is set by using [method@ScrollActor.scroll_to_point] or by using - * [method@ScrollActor.scroll_to_rect] to define a point or a rectangle - * acting as the origin, respectively. - * - * #ClutterScrollActor does not provide pointer or keyboard event handling, - * nor does it provide visible scroll handles. - */ - -#include "config.h" - -#include "clutter/clutter-scroll-actor.h" - -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-animatable.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-property-transition.h" -#include "clutter/clutter-transition.h" - -typedef struct _ClutterScrollActorPrivate -{ - graphene_point_t scroll_to; - - ClutterScrollMode scroll_mode; - - ClutterTransition *transition; -} ClutterScrollActorPrivate; - -enum -{ - PROP_0, - - PROP_SCROLL_MODE, - - PROP_LAST -}; - -enum -{ - ANIM_PROP_0, - - ANIM_PROP_SCROLL_TO, - - ANIM_PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST] = { NULL, }; -static GParamSpec *animatable_props[ANIM_PROP_LAST] = { NULL, }; - -static ClutterAnimatableInterface *parent_animatable_iface = NULL; - -static void clutter_animatable_iface_init (ClutterAnimatableInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (ClutterScrollActor, clutter_scroll_actor, CLUTTER_TYPE_ACTOR, - G_ADD_PRIVATE (ClutterScrollActor) - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_ANIMATABLE, - clutter_animatable_iface_init)) - -static void -clutter_scroll_actor_set_scroll_to_internal (ClutterScrollActor *self, - const graphene_point_t *point) -{ - ClutterScrollActorPrivate *priv = - clutter_scroll_actor_get_instance_private (self); - ClutterActor *actor = CLUTTER_ACTOR (self); - graphene_matrix_t m; - float dx, dy; - - if (graphene_point_equal (&priv->scroll_to, point)) - return; - - if (point == NULL) - graphene_point_init (&priv->scroll_to, 0.f, 0.f); - else - priv->scroll_to = *point; - - if (priv->scroll_mode & CLUTTER_SCROLL_HORIZONTALLY) - dx = -priv->scroll_to.x; - else - dx = 0.f; - - if (priv->scroll_mode & CLUTTER_SCROLL_VERTICALLY) - dy = -priv->scroll_to.y; - else - dy = 0.f; - - graphene_matrix_init_translate (&m, - &GRAPHENE_POINT3D_INIT (dx, dy, 0.f)); - clutter_actor_set_child_transform (actor, &m); -} - -static void -clutter_scroll_actor_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterScrollActor *actor = CLUTTER_SCROLL_ACTOR (gobject); - - switch (prop_id) - { - case PROP_SCROLL_MODE: - clutter_scroll_actor_set_scroll_mode (actor, g_value_get_flags (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - } -} - -static void -clutter_scroll_actor_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterScrollActor *actor = CLUTTER_SCROLL_ACTOR (gobject); - ClutterScrollActorPrivate *priv = - clutter_scroll_actor_get_instance_private (actor); - - switch (prop_id) - { - case PROP_SCROLL_MODE: - g_value_set_flags (value, priv->scroll_mode); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - } -} - -static void -clutter_scroll_actor_class_init (ClutterScrollActorClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->set_property = clutter_scroll_actor_set_property; - gobject_class->get_property = clutter_scroll_actor_get_property; - - /** - * ClutterScrollActor:scroll-mode: - * - * The scrolling direction. - */ - obj_props[PROP_SCROLL_MODE] = - g_param_spec_flags ("scroll-mode", NULL, NULL, - CLUTTER_TYPE_SCROLL_MODE, - CLUTTER_SCROLL_BOTH, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); -} - -static void -clutter_scroll_actor_init (ClutterScrollActor *self) -{ - ClutterScrollActorPrivate *priv = - clutter_scroll_actor_get_instance_private (self); - - priv->scroll_mode = CLUTTER_SCROLL_BOTH; - - clutter_actor_set_clip_to_allocation (CLUTTER_ACTOR (self), TRUE); -} - -static GParamSpec * -clutter_scroll_actor_find_property (ClutterAnimatable *animatable, - const char *property_name) -{ - if (strcmp (property_name, "scroll-to") == 0) - return animatable_props[ANIM_PROP_SCROLL_TO]; - - return parent_animatable_iface->find_property (animatable, property_name); -} - -static void -clutter_scroll_actor_set_final_state (ClutterAnimatable *animatable, - const char *property_name, - const GValue *value) -{ - if (strcmp (property_name, "scroll-to") == 0) - { - ClutterScrollActor *self = CLUTTER_SCROLL_ACTOR (animatable); - const graphene_point_t *point = g_value_get_boxed (value); - - clutter_scroll_actor_set_scroll_to_internal (self, point); - } - else - parent_animatable_iface->set_final_state (animatable, property_name, value); -} - -static void -clutter_scroll_actor_get_initial_state (ClutterAnimatable *animatable, - const char *property_name, - GValue *value) -{ - if (strcmp (property_name, "scroll-to") == 0) - { - ClutterScrollActor *self = CLUTTER_SCROLL_ACTOR (animatable); - ClutterScrollActorPrivate *priv = - clutter_scroll_actor_get_instance_private (self); - - g_value_set_boxed (value, &priv->scroll_to); - } - else - parent_animatable_iface->get_initial_state (animatable, property_name, value); -} - -static void -clutter_animatable_iface_init (ClutterAnimatableInterface *iface) -{ - parent_animatable_iface = g_type_interface_peek_parent (iface); - - animatable_props[ANIM_PROP_SCROLL_TO] = - g_param_spec_boxed ("scroll-to", NULL, NULL, - GRAPHENE_TYPE_POINT, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - CLUTTER_PARAM_ANIMATABLE); - - iface->find_property = clutter_scroll_actor_find_property; - iface->get_initial_state = clutter_scroll_actor_get_initial_state; - iface->set_final_state = clutter_scroll_actor_set_final_state; -} - -/** - * clutter_scroll_actor_new: - * - * Creates a new #ClutterScrollActor. - * - * Return value: The newly created #ClutterScrollActor - * instance. - */ -ClutterActor * -clutter_scroll_actor_new (void) -{ - return g_object_new (CLUTTER_TYPE_SCROLL_ACTOR, NULL); -} - -/** - * clutter_scroll_actor_set_scroll_mode: - * @actor: a #ClutterScrollActor - * @mode: a #ClutterScrollMode - * - * Sets the [property@ScrollActor:scroll-mode] property. - */ -void -clutter_scroll_actor_set_scroll_mode (ClutterScrollActor *actor, - ClutterScrollMode mode) -{ - ClutterScrollActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_SCROLL_ACTOR (actor)); - - priv = clutter_scroll_actor_get_instance_private (actor); - if (priv->scroll_mode == mode) - return; - - priv->scroll_mode = mode; - - g_object_notify_by_pspec (G_OBJECT (actor), obj_props[PROP_SCROLL_MODE]); -} - -/** - * clutter_scroll_actor_get_scroll_mode: - * @actor: a #ClutterScrollActor - * - * Retrieves the [property@ScrollActor:scroll-mode] property - * - * Return value: the scrolling mode - */ -ClutterScrollMode -clutter_scroll_actor_get_scroll_mode (ClutterScrollActor *actor) -{ - ClutterScrollActorPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_SCROLL_ACTOR (actor), CLUTTER_SCROLL_NONE); - - priv = clutter_scroll_actor_get_instance_private (actor); - return priv->scroll_mode; -} - -/** - * clutter_scroll_actor_scroll_to_point: - * @actor: a #ClutterScrollActor - * @point: a #graphene_point_t - * - * Scrolls the contents of @actor so that @point is the new origin - * of the visible area. - * - * The coordinates of @point must be relative to the @actor. - * - * This function will use the currently set easing state of the @actor - * to transition from the current scroll origin to the new one. - */ -void -clutter_scroll_actor_scroll_to_point (ClutterScrollActor *actor, - const graphene_point_t *point) -{ - ClutterScrollActorPrivate *priv; - const ClutterAnimationInfo *info; - - g_return_if_fail (CLUTTER_IS_SCROLL_ACTOR (actor)); - g_return_if_fail (point != NULL); - - priv = clutter_scroll_actor_get_instance_private (actor); - - info = _clutter_actor_get_animation_info (CLUTTER_ACTOR (actor)); - - /* jump to the end if there is no easing state, or if the easing - * state has a duration of 0 msecs - */ - if (info->cur_state == NULL || - info->cur_state->easing_duration == 0) - { - /* ensure that we remove any currently running transition */ - if (priv->transition != NULL) - { - clutter_actor_remove_transition (CLUTTER_ACTOR (actor), - "scroll-to"); - priv->transition = NULL; - } - - clutter_scroll_actor_set_scroll_to_internal (actor, point); - - return; - } - - if (priv->transition == NULL) - { - priv->transition = clutter_property_transition_new ("scroll-to"); - clutter_transition_set_animatable (priv->transition, - CLUTTER_ANIMATABLE (actor)); - clutter_transition_set_remove_on_complete (priv->transition, TRUE); - - /* delay only makes sense if the transition has just been created */ - clutter_timeline_set_delay (CLUTTER_TIMELINE (priv->transition), - info->cur_state->easing_delay); - /* we need this to clear the priv->transition pointer */ - g_object_add_weak_pointer (G_OBJECT (priv->transition), (gpointer *) &priv->transition); - - clutter_actor_add_transition (CLUTTER_ACTOR (actor), - "scroll-to", - priv->transition); - - /* the actor now owns the transition */ - g_object_unref (priv->transition); - } - - /* if a transition already exist, update its bounds */ - clutter_transition_set_from (priv->transition, - GRAPHENE_TYPE_POINT, - &priv->scroll_to); - clutter_transition_set_to (priv->transition, - GRAPHENE_TYPE_POINT, - point); - - /* always use the current easing state */ - clutter_timeline_set_duration (CLUTTER_TIMELINE (priv->transition), - info->cur_state->easing_duration); - clutter_timeline_set_progress_mode (CLUTTER_TIMELINE (priv->transition), - info->cur_state->easing_mode); - - /* ensure that we start from the beginning */ - clutter_timeline_rewind (CLUTTER_TIMELINE (priv->transition)); - clutter_timeline_start (CLUTTER_TIMELINE (priv->transition)); -} - -/** - * clutter_scroll_actor_scroll_to_rect: - * @actor: a #ClutterScrollActor - * @rect: a #ClutterRect - * - * Scrolls @actor so that @rect is in the visible portion. - */ -void -clutter_scroll_actor_scroll_to_rect (ClutterScrollActor *actor, - const graphene_rect_t *rect) -{ - graphene_rect_t n_rect; - - g_return_if_fail (CLUTTER_IS_SCROLL_ACTOR (actor)); - g_return_if_fail (rect != NULL); - - n_rect = *rect; - - /* normalize, so that we have a valid origin */ - graphene_rect_normalize (&n_rect); - - clutter_scroll_actor_scroll_to_point (actor, &n_rect.origin); -} diff --git a/mutter/clutter/clutter/clutter-scroll-actor.h b/mutter/clutter/clutter/clutter-scroll-actor.h deleted file mode 100644 index 7e91a0f..0000000 --- a/mutter/clutter/clutter/clutter-scroll-actor.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" -#include "clutter/clutter-actor.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_SCROLL_ACTOR (clutter_scroll_actor_get_type ()) - -/** - * ClutterScrollActorClass: - * - * The #ClutterScrollActor structure contains only - * private data. - */ -struct _ClutterScrollActorClass -{ - /*< private >*/ - ClutterActorClass parent_instance; -}; - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterScrollActor, - clutter_scroll_actor, - CLUTTER, SCROLL_ACTOR, - ClutterActor) - -CLUTTER_EXPORT -ClutterActor * clutter_scroll_actor_new (void); - -CLUTTER_EXPORT -void clutter_scroll_actor_set_scroll_mode (ClutterScrollActor *actor, - ClutterScrollMode mode); -CLUTTER_EXPORT -ClutterScrollMode clutter_scroll_actor_get_scroll_mode (ClutterScrollActor *actor); - -CLUTTER_EXPORT -void clutter_scroll_actor_scroll_to_point (ClutterScrollActor *actor, - const graphene_point_t *point); -CLUTTER_EXPORT -void clutter_scroll_actor_scroll_to_rect (ClutterScrollActor *actor, - const graphene_rect_t *rect); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-seat-private.h b/mutter/clutter/clutter/clutter-seat-private.h deleted file mode 100644 index 67f074c..0000000 --- a/mutter/clutter/clutter/clutter-seat-private.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2021 Red Hat Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - */ - -#pragma once - -#include "clutter/clutter-types.h" - -CLUTTER_EXPORT -void clutter_seat_destroy (ClutterSeat *seat); - -ClutterGrabState clutter_seat_grab (ClutterSeat *seat, - uint32_t time); -void clutter_seat_ungrab (ClutterSeat *seat, - uint32_t time); - -CLUTTER_EXPORT -void clutter_seat_init_pointer_position (ClutterSeat *seat, - float x, - float y); diff --git a/mutter/clutter/clutter/clutter-seat.c b/mutter/clutter/clutter/clutter-seat.c deleted file mode 100644 index 6cd9874..0000000 --- a/mutter/clutter/clutter/clutter-seat.c +++ /dev/null @@ -1,796 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * 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 . - * - * Author: Carlos Garnacho - */ - -#include "config.h" - -#include "clutter/clutter-input-device-tool.h" -#include "clutter/clutter-input-pointer-a11y-private.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-mutter.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-seat.h" -#include "clutter/clutter-seat-private.h" -#include "clutter/clutter-settings-private.h" -#include "clutter/clutter-virtual-input-device.h" - -enum -{ - DEVICE_ADDED, - DEVICE_REMOVED, - KBD_A11Y_MASK_CHANGED, - KBD_A11Y_FLAGS_CHANGED, - PTR_A11Y_DWELL_CLICK_TYPE_CHANGED, - PTR_A11Y_TIMEOUT_STARTED, - PTR_A11Y_TIMEOUT_STOPPED, - IS_UNFOCUS_INHIBITED_CHANGED, - N_SIGNALS, -}; - -static guint signals[N_SIGNALS] = { 0 }; - -enum -{ - PROP_0, - - PROP_NAME, - PROP_TOUCH_MODE, - - N_PROPS -}; - -static GParamSpec *props[N_PROPS]; - -typedef struct _ClutterSeatPrivate ClutterSeatPrivate; - -struct _ClutterSeatPrivate -{ - unsigned int inhibit_unfocus_count; - - /* Pointer a11y */ - ClutterPointerA11ySettings pointer_a11y_settings; - - char *name; -}; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterSeat, clutter_seat, G_TYPE_OBJECT) - -static void -clutter_seat_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterSeat *seat = CLUTTER_SEAT (object); - ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); - - switch (prop_id) - { - case PROP_NAME: - priv->name = g_value_dup_string (value); - break; - case PROP_TOUCH_MODE: - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -clutter_seat_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterSeat *seat = CLUTTER_SEAT (object); - ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); - - switch (prop_id) - { - case PROP_TOUCH_MODE: - g_value_set_boolean (value, FALSE); - break; - case PROP_NAME: - g_value_set_string (value, priv->name); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -clutter_seat_constructed (GObject *object) -{ - ClutterSettings *settings = clutter_settings_get_default (); - - G_OBJECT_CLASS (clutter_seat_parent_class)->constructed (object); - clutter_settings_ensure_pointer_a11y_settings (settings, - CLUTTER_SEAT (object)); -} - -static void -clutter_seat_finalize (GObject *object) -{ - ClutterSeat *seat = CLUTTER_SEAT (object); - ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); - - g_clear_pointer (&priv->name, g_free); - - G_OBJECT_CLASS (clutter_seat_parent_class)->finalize (object); -} - -static void -clutter_seat_class_init (ClutterSeatClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->set_property = clutter_seat_set_property; - object_class->get_property = clutter_seat_get_property; - object_class->constructed = clutter_seat_constructed; - object_class->finalize = clutter_seat_finalize; - - signals[DEVICE_ADDED] = - g_signal_new (I_("device-added"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_INPUT_DEVICE); - - signals[DEVICE_REMOVED] = - g_signal_new (I_("device-removed"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_INPUT_DEVICE); - - /** - * ClutterSeat::kbd-a11y-mods-state-changed: - * @seat: the #ClutterSeat that emitted the signal - * @latched_mask: the latched modifier mask from stickykeys - * @locked_mask: the locked modifier mask from stickykeys - * - * The signal is emitted each time either the - * latched modifiers mask or locked modifiers mask are changed as the - * result of keyboard accessibility's sticky keys operations. - */ - signals[KBD_A11Y_MASK_CHANGED] = - g_signal_new (I_("kbd-a11y-mods-state-changed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - _clutter_marshal_VOID__UINT_UINT, - G_TYPE_NONE, 2, - G_TYPE_UINT, - G_TYPE_UINT); - g_signal_set_va_marshaller (signals[KBD_A11Y_MASK_CHANGED], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_VOID__UINT_UINTv); - - /** - * ClutterSeat::kbd-a11y-flags-changed: - * @seat: the #ClutterSeat that emitted the signal - * @settings_flags: the new ClutterKeyboardA11yFlags configuration - * @changed_mask: the ClutterKeyboardA11yFlags changed - * - * The signal is emitted each time the ClutterKeyboardA11yFlags - * configuration is changed as the result of keyboard accessibility operations. - */ - signals[KBD_A11Y_FLAGS_CHANGED] = - g_signal_new (I_("kbd-a11y-flags-changed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - _clutter_marshal_VOID__UINT_UINT, - G_TYPE_NONE, 2, - G_TYPE_UINT, - G_TYPE_UINT); - g_signal_set_va_marshaller (signals[KBD_A11Y_FLAGS_CHANGED], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_VOID__UINT_UINTv); - - /** - * ClutterSeat::ptr-a11y-dwell-click-type-changed: - * @seat: the #ClutterSeat that emitted the signal - * @click_type: the new #ClutterPointerA11yDwellClickType mode - * - * The signal is emitted each time the ClutterPointerA11yDwellClickType - * mode is changed as the result of pointer accessibility operations. - */ - signals[PTR_A11Y_DWELL_CLICK_TYPE_CHANGED] = - g_signal_new (I_("ptr-a11y-dwell-click-type-changed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_POINTER_A11Y_DWELL_CLICK_TYPE); - - /** - * ClutterSeat::ptr-a11y-timeout-started: - * @seat: the #ClutterSeat that emitted the signal - * @device: the core pointer #ClutterInputDevice - * @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType - * @delay: the delay in ms before secondary-click is triggered. - * - * The signal is emitted when a pointer accessibility timeout delay is started, - * so that upper layers can notify the user with some visual feedback. - */ - signals[PTR_A11Y_TIMEOUT_STARTED] = - g_signal_new (I_("ptr-a11y-timeout-started"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - _clutter_marshal_VOID__OBJECT_FLAGS_UINT, - G_TYPE_NONE, 3, - CLUTTER_TYPE_INPUT_DEVICE, - CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE, - G_TYPE_UINT); - g_signal_set_va_marshaller (signals[PTR_A11Y_TIMEOUT_STARTED], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_VOID__OBJECT_FLAGS_UINTv); - - /** - * ClutterSeat::ptr-a11y-timeout-stopped: - * @seat: the #ClutterSeat that emitted the signal - * @device: the core pointer #ClutterInputDevice - * @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType - * @clicked: %TRUE if the timeout finished and triggered a click - * - * The signal is emitted when a running pointer accessibility timeout - * delay is stopped, either because it's triggered at the end of - * the delay or cancelled, so that upper layers can notify the user - * with some visual feedback. - */ - signals[PTR_A11Y_TIMEOUT_STOPPED] = - g_signal_new (I_("ptr-a11y-timeout-stopped"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - _clutter_marshal_VOID__OBJECT_FLAGS_BOOLEAN, - G_TYPE_NONE, 3, - CLUTTER_TYPE_INPUT_DEVICE, - CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE, - G_TYPE_BOOLEAN); - g_signal_set_va_marshaller (signals[PTR_A11Y_TIMEOUT_STOPPED], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_VOID__OBJECT_FLAGS_BOOLEANv); - - /** - * ClutterSeat::is-unfocus-inhibited-changed: - * @seat: the #ClutterSeat that emitted the signal - * - * The signal is emitted when the property to inhibit the unsetting - * of the focus-surface of the #ClutterSeat changed. - * - * To get the current state of this property, use [method@Seat.is_unfocus_inhibited]. - */ - signals[IS_UNFOCUS_INHIBITED_CHANGED] = - g_signal_new (I_("is-unfocus-inhibited-changed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); - - /** - * ClutterSeat:touch-mode: - * - * The current touch-mode of the #ClutterSeat, it is set to %TRUE if the - * requirements documented in [method@Seat.get_touch_mode] are fulfilled. - **/ - props[PROP_TOUCH_MODE] = - g_param_spec_boolean ("touch-mode", NULL, NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterSeat::name: - * - * The name of the seat. - **/ - props[PROP_NAME] = - g_param_spec_string ("name", NULL, NULL, - NULL, - G_PARAM_STATIC_STRINGS | - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY); - - g_object_class_install_properties (object_class, N_PROPS, props); -} - -static void -clutter_seat_init (ClutterSeat *seat) -{ -} - -/** - * clutter_seat_get_pointer: - * @seat: a #ClutterSeat - * - * Returns the logical pointer - * - * Returns: (transfer none): the logical pointer - **/ -ClutterInputDevice * -clutter_seat_get_pointer (ClutterSeat *seat) -{ - g_return_val_if_fail (CLUTTER_IS_SEAT (seat), NULL); - - return CLUTTER_SEAT_GET_CLASS (seat)->get_pointer (seat); -} - -/** - * clutter_seat_get_keyboard: - * @seat: a #ClutterSeat - * - * Returns the logical keyboard - * - * Returns: (transfer none): the logical keyboard - **/ -ClutterInputDevice * -clutter_seat_get_keyboard (ClutterSeat *seat) -{ - g_return_val_if_fail (CLUTTER_IS_SEAT (seat), NULL); - - return CLUTTER_SEAT_GET_CLASS (seat)->get_keyboard (seat); -} - -/** - * clutter_seat_peek_devices: (skip) - **/ -const GList * -clutter_seat_peek_devices (ClutterSeat *seat) -{ - g_return_val_if_fail (CLUTTER_IS_SEAT (seat), NULL); - - return CLUTTER_SEAT_GET_CLASS (seat)->peek_devices (seat); -} - -/** - * clutter_seat_list_devices: - * @seat: a #ClutterSeat - * - * Returns the list of HW devices - * - * Returns: (transfer container) (element-type Clutter.InputDevice): A list - * of #ClutterInputDevice. The elements of the returned list are owned by - * Clutter and may not be freed, the returned list should be freed using - * g_list_free() when done. - **/ -GList * -clutter_seat_list_devices (ClutterSeat *seat) -{ - g_return_val_if_fail (CLUTTER_IS_SEAT (seat), NULL); - - return g_list_copy ((GList *)clutter_seat_peek_devices (seat)); -} - -void -clutter_seat_bell_notify (ClutterSeat *seat) -{ - CLUTTER_SEAT_GET_CLASS (seat)->bell_notify (seat); -} - -/** - * clutter_seat_get_keymap: - * @seat: a #ClutterSeat - * - * Returns the seat keymap - * - * Returns: (transfer none): the seat keymap - **/ -ClutterKeymap * -clutter_seat_get_keymap (ClutterSeat *seat) -{ - return CLUTTER_SEAT_GET_CLASS (seat)->get_keymap (seat); -} - -void -clutter_seat_ensure_a11y_state (ClutterSeat *seat) -{ - ClutterInputDevice *core_pointer; - - core_pointer = clutter_seat_get_pointer (seat); - - if (core_pointer) - { - if (_clutter_is_input_pointer_a11y_enabled (core_pointer)) - _clutter_input_pointer_a11y_add_device (core_pointer); - } -} - -static gboolean -are_pointer_a11y_settings_equal (ClutterPointerA11ySettings *a, - ClutterPointerA11ySettings *b) -{ - return (memcmp (a, b, sizeof (ClutterPointerA11ySettings)) == 0); -} - -static void -clutter_seat_enable_pointer_a11y (ClutterSeat *seat) -{ - ClutterInputDevice *core_pointer; - - core_pointer = clutter_seat_get_pointer (seat); - - _clutter_input_pointer_a11y_add_device (core_pointer); -} - -static void -clutter_seat_disable_pointer_a11y (ClutterSeat *seat) -{ - ClutterInputDevice *core_pointer; - - core_pointer = clutter_seat_get_pointer (seat); - - _clutter_input_pointer_a11y_remove_device (core_pointer); -} - -/** - * clutter_seat_set_pointer_a11y_settings: - * @seat: a #ClutterSeat - * @settings: a pointer to a #ClutterPointerA11ySettings - * - * Sets the pointer accessibility settings - **/ -void -clutter_seat_set_pointer_a11y_settings (ClutterSeat *seat, - ClutterPointerA11ySettings *settings) -{ - ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); - - g_return_if_fail (CLUTTER_IS_SEAT (seat)); - - if (are_pointer_a11y_settings_equal (&priv->pointer_a11y_settings, settings)) - return; - - if (priv->pointer_a11y_settings.controls == 0 && settings->controls != 0) - clutter_seat_enable_pointer_a11y (seat); - else if (priv->pointer_a11y_settings.controls != 0 && settings->controls == 0) - clutter_seat_disable_pointer_a11y (seat); - - priv->pointer_a11y_settings = *settings; -} - -/** - * clutter_seat_get_pointer_a11y_settings: - * @seat: a #ClutterSeat - * @settings: a pointer to a #ClutterPointerA11ySettings - * - * Gets the current pointer accessibility settings - **/ -void -clutter_seat_get_pointer_a11y_settings (ClutterSeat *seat, - ClutterPointerA11ySettings *settings) -{ - ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); - - g_return_if_fail (CLUTTER_IS_SEAT (seat)); - - *settings = priv->pointer_a11y_settings; -} - -/** - * clutter_seat_set_pointer_a11y_dwell_click_type: - * @seat: a #ClutterSeat - * @click_type: type of click as #ClutterPointerA11yDwellClickType - * - * Sets the dwell click type - **/ -void -clutter_seat_set_pointer_a11y_dwell_click_type (ClutterSeat *seat, - ClutterPointerA11yDwellClickType click_type) -{ - ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); - - g_return_if_fail (CLUTTER_IS_SEAT (seat)); - - priv->pointer_a11y_settings.dwell_click_type = click_type; -} - -/** - * clutter_seat_inhibit_unfocus: - * @seat: a #ClutterSeat - * - * Inhibits unsetting of the pointer focus-surface for the #ClutterSeat @seat, - * this allows to keep using the pointer even when it's hidden. - * - * This property is refcounted, so [method@Seat.uninhibit_unfocus] must be - * called the exact same number of times as [method@Seat.inhibit_unfocus] - * was called before. - **/ -void -clutter_seat_inhibit_unfocus (ClutterSeat *seat) -{ - ClutterSeatPrivate *priv; - - g_return_if_fail (CLUTTER_IS_SEAT (seat)); - - priv = clutter_seat_get_instance_private (seat); - - priv->inhibit_unfocus_count++; - - if (priv->inhibit_unfocus_count == 1) - g_signal_emit (G_OBJECT (seat), signals[IS_UNFOCUS_INHIBITED_CHANGED], 0); -} - -/** - * clutter_seat_uninhibit_unfocus: - * @seat: a #ClutterSeat - * - * Disables the inhibiting of unsetting of the pointer focus-surface - * previously enabled by calling [method@Seat.inhibit_unfocus]. - * - * This property is refcounted, so [method@Seat.uninhibit_unfocus] must be - * called the exact same number of times as [method@Seat.inhibit_unfocus] - * was called before. - **/ -void -clutter_seat_uninhibit_unfocus (ClutterSeat *seat) -{ - ClutterSeatPrivate *priv; - - g_return_if_fail (CLUTTER_IS_SEAT (seat)); - - priv = clutter_seat_get_instance_private (seat); - - if (priv->inhibit_unfocus_count == 0) - { - g_warning ("Called clutter_seat_uninhibit_unfocus without inhibiting before"); - return; - } - - priv->inhibit_unfocus_count--; - - if (priv->inhibit_unfocus_count == 0) - g_signal_emit (G_OBJECT (seat), signals[IS_UNFOCUS_INHIBITED_CHANGED], 0); -} - -/** - * clutter_seat_is_unfocus_inhibited: - * @seat: a #ClutterSeat - * - * Gets whether unsetting of the pointer focus-surface is inhibited - * for the #ClutterSeat @seat. - * - * Returns: %TRUE if unsetting is inhibited, %FALSE otherwise - **/ -gboolean -clutter_seat_is_unfocus_inhibited (ClutterSeat *seat) -{ - ClutterSeatPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_SEAT (seat), FALSE); - - priv = clutter_seat_get_instance_private (seat); - - return priv->inhibit_unfocus_count > 0; -} - -/** - * clutter_seat_create_virtual_device: - * @seat: a #ClutterSeat - * @device_type: the type of the virtual device - * - * Creates a virtual input device. - * - * Returns: (transfer full): a newly created virtual device - **/ -ClutterVirtualInputDevice * -clutter_seat_create_virtual_device (ClutterSeat *seat, - ClutterInputDeviceType device_type) -{ - ClutterSeatClass *seat_class; - - g_return_val_if_fail (CLUTTER_IS_SEAT (seat), NULL); - - seat_class = CLUTTER_SEAT_GET_CLASS (seat); - return seat_class->create_virtual_device (seat, device_type); -} - -/** - * clutter_seat_get_supported_virtual_device_types: (skip) - **/ -ClutterVirtualDeviceType -clutter_seat_get_supported_virtual_device_types (ClutterSeat *seat) -{ - ClutterSeatClass *seat_class; - - g_return_val_if_fail (CLUTTER_IS_SEAT (seat), - CLUTTER_VIRTUAL_DEVICE_TYPE_NONE); - - seat_class = CLUTTER_SEAT_GET_CLASS (seat); - return seat_class->get_supported_virtual_device_types (seat); -} - -gboolean -clutter_seat_handle_event_post (ClutterSeat *seat, - const ClutterEvent *event) -{ - ClutterSeatClass *seat_class; - ClutterInputDevice *device; - - g_return_val_if_fail (CLUTTER_IS_SEAT (seat), FALSE); - g_return_val_if_fail (event, FALSE); - - seat_class = CLUTTER_SEAT_GET_CLASS (seat); - - if (seat_class->handle_event_post) - seat_class->handle_event_post (seat, event); - - device = clutter_event_get_source_device (event); - - switch (clutter_event_type (event)) - { - case CLUTTER_DEVICE_ADDED: - g_signal_emit (seat, signals[DEVICE_ADDED], 0, device); - break; - case CLUTTER_DEVICE_REMOVED: - g_signal_emit (seat, signals[DEVICE_REMOVED], 0, device); - g_object_run_dispose (G_OBJECT (device)); - break; - default: - break; - } - - return TRUE; -} - -void -clutter_seat_warp_pointer (ClutterSeat *seat, - int x, - int y) -{ - g_return_if_fail (CLUTTER_IS_SEAT (seat)); - - CLUTTER_SEAT_GET_CLASS (seat)->warp_pointer (seat, x, y); -} - -void -clutter_seat_init_pointer_position (ClutterSeat *seat, - float x, - float y) -{ - g_return_if_fail (CLUTTER_IS_SEAT (seat)); - - CLUTTER_SEAT_GET_CLASS (seat)->init_pointer_position (seat, x, y); -} - -/** - * clutter_seat_get_touch_mode: - * @seat: a #ClutterSeat - * - * Gets the current touch-mode state of the #ClutterSeat @seat. - * The [property@Seat:touch-mode] property is set to %TRUE if the following - * requirements are fulfilled: - * - * - A touchscreen is available - * - A tablet mode switch, if present, is enabled - * - * Returns: %TRUE if the device is a tablet that doesn't have an external - * keyboard attached, %FALSE otherwise. - **/ -gboolean -clutter_seat_get_touch_mode (ClutterSeat *seat) -{ - gboolean touch_mode; - - g_return_val_if_fail (CLUTTER_IS_SEAT (seat), FALSE); - - g_object_get (G_OBJECT (seat), "touch-mode", &touch_mode, NULL); - - return touch_mode; -} - -/** - * clutter_seat_has_touchscreen: (skip) - **/ -gboolean -clutter_seat_has_touchscreen (ClutterSeat *seat) -{ - gboolean has_touchscreen = FALSE; - const GList *devices, *l; - - g_return_val_if_fail (CLUTTER_IS_SEAT (seat), FALSE); - - devices = clutter_seat_peek_devices (seat); - for (l = devices; l; l = l->next) - { - ClutterInputDevice *device = l->data; - - if (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_LOGICAL && - clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE) - { - has_touchscreen = TRUE; - break; - } - } - - return has_touchscreen; -} - -/** - * clutter_seat_query_state: - * @seat: a #ClutterSeat - * @device: a #ClutterInputDevice - * @sequence: (nullable): a #ClutterEventSequence - * @coords: (out caller-allocates) (optional): the coordinates of the pointer - * @modifiers: (out) (optional): the current #ClutterModifierType of the pointer - * - * Returns: %TRUE if @device (or the specific @sequence) is on the stage, %FALSE - * otherwise. - **/ -gboolean -clutter_seat_query_state (ClutterSeat *seat, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - graphene_point_t *coords, - ClutterModifierType *modifiers) -{ - g_return_val_if_fail (CLUTTER_IS_SEAT (seat), FALSE); - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); - - return CLUTTER_SEAT_GET_CLASS (seat)->query_state (seat, - device, - sequence, - coords, - modifiers); -} - -void -clutter_seat_destroy (ClutterSeat *seat) -{ - g_object_run_dispose (G_OBJECT (seat)); - g_object_unref (seat); -} - -ClutterGrabState -clutter_seat_grab (ClutterSeat *seat, - uint32_t time) -{ - ClutterSeatClass *seat_class; - - seat_class = CLUTTER_SEAT_GET_CLASS (seat); - if (seat_class->grab) - return seat_class->grab (seat, time); - else - return CLUTTER_GRAB_STATE_ALL; -} - -void -clutter_seat_ungrab (ClutterSeat *seat, - uint32_t time) -{ - ClutterSeatClass *seat_class; - - seat_class = CLUTTER_SEAT_GET_CLASS (seat); - if (seat_class->ungrab) - return seat_class->ungrab (seat, time); -} - -const char * -clutter_seat_get_name (ClutterSeat *seat) -{ - ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); - - return priv->name; -} diff --git a/mutter/clutter/clutter/clutter-seat.h b/mutter/clutter/clutter/clutter-seat.h deleted file mode 100644 index bef35ac..0000000 --- a/mutter/clutter/clutter/clutter-seat.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * 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 . - * - * Author: Carlos Garnacho - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" -#include "clutter/clutter-keymap.h" - -#define CLUTTER_TYPE_SEAT (clutter_seat_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterSeat, clutter_seat, - CLUTTER, SEAT, GObject) - -/** - * ClutterPointerA11ySettings: - * - * The #ClutterPointerA11ySettings structure contains pointer accessibility - * settings - * - */ -typedef struct _ClutterPointerA11ySettings -{ - ClutterPointerA11yFlags controls; - ClutterPointerA11yDwellClickType dwell_click_type; - ClutterPointerA11yDwellMode dwell_mode; - ClutterPointerA11yDwellDirection dwell_gesture_single; - ClutterPointerA11yDwellDirection dwell_gesture_double; - ClutterPointerA11yDwellDirection dwell_gesture_drag; - ClutterPointerA11yDwellDirection dwell_gesture_secondary; - gint secondary_click_delay; - gint dwell_delay; - gint dwell_threshold; -} ClutterPointerA11ySettings; - -/** - * ClutterVirtualDeviceType: - */ -typedef enum -{ - CLUTTER_VIRTUAL_DEVICE_TYPE_NONE = 0, - CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD = 1 << 0, - CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER = 1 << 1, - CLUTTER_VIRTUAL_DEVICE_TYPE_TOUCHSCREEN = 1 << 2, -} ClutterVirtualDeviceType; - -typedef struct _ClutterSeatClass ClutterSeatClass; - -struct _ClutterSeatClass -{ - GObjectClass parent_class; - - ClutterInputDevice * (* get_pointer) (ClutterSeat *seat); - ClutterInputDevice * (* get_keyboard) (ClutterSeat *seat); - - const GList * (* peek_devices) (ClutterSeat *seat); - - void (* bell_notify) (ClutterSeat *seat); - - ClutterKeymap * (* get_keymap) (ClutterSeat *seat); - - gboolean (* handle_event_post) (ClutterSeat *seat, - const ClutterEvent *event); - - void (* warp_pointer) (ClutterSeat *seat, - int x, - int y); - - void (* init_pointer_position) (ClutterSeat *seat, - float x, - float y); - - gboolean (* query_state) (ClutterSeat *seat, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - graphene_point_t *coords, - ClutterModifierType *modifiers); - - ClutterGrabState (* grab) (ClutterSeat *seat, - uint32_t time); - void (* ungrab) (ClutterSeat *seat, - uint32_t time); - - /* Virtual devices */ - ClutterVirtualInputDevice * (* create_virtual_device) (ClutterSeat *seat, - ClutterInputDeviceType device_type); - ClutterVirtualDeviceType (* get_supported_virtual_device_types) (ClutterSeat *seat); -}; - -CLUTTER_EXPORT -ClutterInputDevice * clutter_seat_get_pointer (ClutterSeat *seat); -CLUTTER_EXPORT -ClutterInputDevice * clutter_seat_get_keyboard (ClutterSeat *seat); -CLUTTER_EXPORT -GList * clutter_seat_list_devices (ClutterSeat *seat); -const GList * clutter_seat_peek_devices (ClutterSeat *seat); -CLUTTER_EXPORT -void clutter_seat_bell_notify (ClutterSeat *seat); - -CLUTTER_EXPORT -ClutterKeymap * clutter_seat_get_keymap (ClutterSeat *seat); - -CLUTTER_EXPORT -void clutter_seat_ensure_a11y_state (ClutterSeat *seat); - -CLUTTER_EXPORT -void clutter_seat_set_pointer_a11y_settings (ClutterSeat *seat, - ClutterPointerA11ySettings *settings); - -CLUTTER_EXPORT -void clutter_seat_get_pointer_a11y_settings (ClutterSeat *seat, - ClutterPointerA11ySettings *settings); - -CLUTTER_EXPORT -void clutter_seat_set_pointer_a11y_dwell_click_type (ClutterSeat *seat, - ClutterPointerA11yDwellClickType click_type); - -CLUTTER_EXPORT -void clutter_seat_inhibit_unfocus (ClutterSeat *seat); - -CLUTTER_EXPORT -void clutter_seat_uninhibit_unfocus (ClutterSeat *seat); - -CLUTTER_EXPORT -gboolean clutter_seat_is_unfocus_inhibited (ClutterSeat *seat); - -CLUTTER_EXPORT -ClutterVirtualInputDevice *clutter_seat_create_virtual_device (ClutterSeat *seat, - ClutterInputDeviceType device_type); - -CLUTTER_EXPORT -ClutterVirtualDeviceType clutter_seat_get_supported_virtual_device_types (ClutterSeat *seat); - -CLUTTER_EXPORT -void clutter_seat_warp_pointer (ClutterSeat *seat, - int x, - int y); -CLUTTER_EXPORT -gboolean clutter_seat_get_touch_mode (ClutterSeat *seat); - -CLUTTER_EXPORT -gboolean clutter_seat_has_touchscreen (ClutterSeat *seat); - -CLUTTER_EXPORT -gboolean clutter_seat_query_state (ClutterSeat *seat, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - graphene_point_t *coords, - ClutterModifierType *modifiers); - -CLUTTER_EXPORT -const char * clutter_seat_get_name (ClutterSeat *seat); diff --git a/mutter/clutter/clutter/clutter-settings-private.h b/mutter/clutter/clutter/clutter-settings-private.h deleted file mode 100644 index 522f27d..0000000 --- a/mutter/clutter/clutter/clutter-settings-private.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "clutter/clutter-backend-private.h" -#include "clutter/clutter-settings.h" - -G_BEGIN_DECLS - -void _clutter_settings_set_backend (ClutterSettings *settings, - ClutterBackend *backend); - -void clutter_settings_ensure_pointer_a11y_settings (ClutterSettings *settings, - ClutterSeat *seat); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-settings.c b/mutter/clutter/clutter/clutter-settings.c deleted file mode 100644 index d542b15..0000000 --- a/mutter/clutter/clutter/clutter-settings.c +++ /dev/null @@ -1,991 +0,0 @@ -/** - * ClutterSettings: - * - * Settings configuration - * - * Clutter depends on some settings to perform operations like detecting - * multiple button press events, or font options to render text. - * - * Usually, Clutter will strive to use the platform's settings in order - * to be as much integrated as possible. It is, however, possible to - * change these settings on a per-application basis, by using the - * #ClutterSettings singleton object and setting its properties. It is - * also possible, for toolkit developers, to retrieve the settings from - * the #ClutterSettings properties when implementing new UI elements, - * for instance the default font name. - */ - -#include "config.h" - -#include "clutter/clutter-settings.h" - -#ifdef HAVE_PANGO_FT2 -/* for pango_fc_font_map_cache_clear() */ -#include -#endif /* HAVE_PANGO_FT2 */ - -#include "clutter/clutter-context-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-settings-private.h" -#include "clutter/clutter-stage-private.h" -#include "clutter/clutter-private.h" - -#include -#include - -#define DEFAULT_FONT_NAME "Sans 12" - -typedef struct -{ - cairo_antialias_t cairo_antialias; - gint clutter_font_antialias; - - cairo_hint_style_t cairo_hint_style; - const char *clutter_font_hint_style; - - cairo_subpixel_order_t cairo_subpixel_order; - const char *clutter_font_subpixel_order; -} FontSettings; - -struct _ClutterSettings -{ - GObject parent_instance; - - ClutterBackend *backend; - GSettings *font_settings; - GSettings *mouse_settings; - GSettings *mouse_a11y_settings; - - gint double_click_time; - gint double_click_distance; - - gint dnd_drag_threshold; - - gdouble resolution; - - gchar *font_name; - gint font_dpi; - - gint xft_hinting; - gint xft_antialias; - gchar *xft_hint_style; - gchar *xft_rgba; - - gint long_press_duration; - - guint last_fontconfig_timestamp; - - guint password_hint_time; - - gint unscaled_font_dpi; -}; - -enum -{ - PROP_0, - - PROP_DOUBLE_CLICK_TIME, - PROP_DOUBLE_CLICK_DISTANCE, - - PROP_DND_DRAG_THRESHOLD, - - PROP_FONT_NAME, - - PROP_FONT_ANTIALIAS, - PROP_FONT_DPI, - PROP_FONT_HINTING, - PROP_FONT_HINT_STYLE, - PROP_FONT_RGBA, - - PROP_LONG_PRESS_DURATION, - - PROP_FONTCONFIG_TIMESTAMP, - - PROP_PASSWORD_HINT_TIME, - - PROP_UNSCALED_FONT_DPI, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -G_DEFINE_FINAL_TYPE (ClutterSettings, clutter_settings, G_TYPE_OBJECT); - -static inline void -settings_update_font_options (ClutterSettings *self) -{ - cairo_hint_style_t hint_style = CAIRO_HINT_STYLE_NONE; - cairo_antialias_t antialias_mode = CAIRO_ANTIALIAS_GRAY; - cairo_subpixel_order_t subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT; - cairo_font_options_t *options; - - if (self->backend == NULL) - return; - - options = cairo_font_options_create (); - - cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON); - - if (self->xft_hinting >= 0 && - self->xft_hint_style == NULL) - { - hint_style = CAIRO_HINT_STYLE_NONE; - } - else if (self->xft_hint_style != NULL) - { - if (strcmp (self->xft_hint_style, "hintnone") == 0) - hint_style = CAIRO_HINT_STYLE_NONE; - else if (strcmp (self->xft_hint_style, "hintslight") == 0) - hint_style = CAIRO_HINT_STYLE_SLIGHT; - else if (strcmp (self->xft_hint_style, "hintmedium") == 0) - hint_style = CAIRO_HINT_STYLE_MEDIUM; - else if (strcmp (self->xft_hint_style, "hintfull") == 0) - hint_style = CAIRO_HINT_STYLE_FULL; - } - - cairo_font_options_set_hint_style (options, hint_style); - - if (self->xft_rgba) - { - if (strcmp (self->xft_rgba, "rgb") == 0) - subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB; - else if (strcmp (self->xft_rgba, "bgr") == 0) - subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR; - else if (strcmp (self->xft_rgba, "vrgb") == 0) - subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB; - else if (strcmp (self->xft_rgba, "vbgr") == 0) - subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR; - } - - cairo_font_options_set_subpixel_order (options, subpixel_order); - - if (self->xft_antialias >= 0 && !self->xft_antialias) - antialias_mode = CAIRO_ANTIALIAS_NONE; - else if (subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT) - antialias_mode = CAIRO_ANTIALIAS_SUBPIXEL; - else if (self->xft_antialias >= 0) - antialias_mode = CAIRO_ANTIALIAS_GRAY; - - cairo_font_options_set_antialias (options, antialias_mode); - - CLUTTER_NOTE (BACKEND, "New font options:\n" - " - font-name: %s\n" - " - antialias: %d\n" - " - hinting: %d\n" - " - hint-style: %s\n" - " - rgba: %s\n", - self->font_name != NULL ? self->font_name : DEFAULT_FONT_NAME, - self->xft_antialias, - self->xft_hinting, - self->xft_hint_style != NULL ? self->xft_hint_style : "", - self->xft_rgba != NULL ? self->xft_rgba : ""); - - clutter_backend_set_font_options (self->backend, options); - cairo_font_options_destroy (options); -} - -static void -settings_update_font_name (ClutterSettings *self) -{ - CLUTTER_NOTE (BACKEND, "New font-name: %s", self->font_name); - - if (self->backend != NULL) - g_signal_emit_by_name (self->backend, "font-changed"); -} - -static void -settings_update_resolution (ClutterSettings *self) -{ - const char *scale_env = NULL; - - if (self->font_dpi > 0) - self->resolution = (gdouble) self->font_dpi / 1024.0; - else - self->resolution = 96.0; - - scale_env = g_getenv ("GDK_DPI_SCALE"); - if (scale_env != NULL) - { - double scale = g_ascii_strtod (scale_env, NULL); - if (scale != 0 && self->resolution > 0) - self->resolution *= scale; - } - - CLUTTER_NOTE (BACKEND, "New resolution: %.2f (%s)", - self->resolution, - self->unscaled_font_dpi > 0 ? "unscaled" : "scaled"); - - if (self->backend != NULL) - g_signal_emit_by_name (self->backend, "resolution-changed"); -} - -static void -settings_update_fontmap (ClutterSettings *self, - guint stamp) -{ - if (self->backend == NULL) - return; - -#ifdef HAVE_PANGO_FT2 - CLUTTER_NOTE (BACKEND, "Update fontmaps (stamp: %d)", stamp); - - if (self->last_fontconfig_timestamp != stamp) - { - ClutterContext *context; - gboolean update_needed = FALSE; - - context = _clutter_context_get_default (); - - /* If there is no font map yet then we don't need to do anything - * because the config for fontconfig will be read when it is - * created */ - if (context->font_map) - { - PangoFontMap *fontmap = PANGO_FONT_MAP (context->font_map); - - if (PANGO_IS_FC_FONT_MAP (fontmap) && - !FcConfigUptoDate (NULL)) - { - pango_fc_font_map_cache_clear (PANGO_FC_FONT_MAP (fontmap)); - - if (FcInitReinitialize ()) - update_needed = TRUE; - } - } - - self->last_fontconfig_timestamp = stamp; - - if (update_needed) - g_signal_emit_by_name (self->backend, "font-changed"); - } -#endif /* HAVE_PANGO_FT2 */ -} - -static void -get_font_gsettings (GSettings *settings, - FontSettings *output) -{ - /* org.gnome.desktop.GDesktopFontAntialiasingMode */ - static const struct - { - cairo_antialias_t cairo_antialias; - gint clutter_font_antialias; - } - antialiasings[] = - { - /* none=0 */ {CAIRO_ANTIALIAS_NONE, 0}, - /* grayscale=1 */ {CAIRO_ANTIALIAS_GRAY, 1}, - /* rgba=2 */ {CAIRO_ANTIALIAS_SUBPIXEL, 1}, - }; - - /* org.gnome.desktop.GDesktopFontHinting */ - static const struct - { - cairo_hint_style_t cairo_hint_style; - const char *clutter_font_hint_style; - } - hintings[] = - { - /* none=0 */ {CAIRO_HINT_STYLE_NONE, "hintnone"}, - /* slight=1 */ {CAIRO_HINT_STYLE_SLIGHT, "hintslight"}, - /* medium=2 */ {CAIRO_HINT_STYLE_MEDIUM, "hintmedium"}, - /* full=3 */ {CAIRO_HINT_STYLE_FULL, "hintfull"}, - }; - - /* org.gnome.desktop.GDesktopFontRgbaOrder */ - static const struct - { - cairo_subpixel_order_t cairo_subpixel_order; - const char *clutter_font_subpixel_order; - } - rgba_orders[] = - { - /* rgba=0 */ {CAIRO_SUBPIXEL_ORDER_RGB, "rgb"}, /* XXX what is 'rgba'? */ - /* rgb=1 */ {CAIRO_SUBPIXEL_ORDER_RGB, "rgb"}, - /* bgr=2 */ {CAIRO_SUBPIXEL_ORDER_BGR, "bgr"}, - /* vrgb=3 */ {CAIRO_SUBPIXEL_ORDER_VRGB, "vrgb"}, - /* vbgr=4 */ {CAIRO_SUBPIXEL_ORDER_VBGR, "vbgr"}, - }; - guint i; - - i = g_settings_get_enum (settings, "font-hinting"); - if (i < G_N_ELEMENTS (hintings)) - { - output->cairo_hint_style = hintings[i].cairo_hint_style; - output->clutter_font_hint_style = hintings[i].clutter_font_hint_style; - } - else - { - output->cairo_hint_style = CAIRO_HINT_STYLE_DEFAULT; - output->clutter_font_hint_style = NULL; - } - - i = g_settings_get_enum (settings, "font-antialiasing"); - if (i < G_N_ELEMENTS (antialiasings)) - { - output->cairo_antialias = antialiasings[i].cairo_antialias; - output->clutter_font_antialias = antialiasings[i].clutter_font_antialias; - } - else - { - output->cairo_antialias = CAIRO_ANTIALIAS_DEFAULT; - output->clutter_font_antialias = -1; - } - - i = g_settings_get_enum (settings, "font-rgba-order"); - if (i < G_N_ELEMENTS (rgba_orders)) - { - output->cairo_subpixel_order = rgba_orders[i].cairo_subpixel_order; - output->clutter_font_subpixel_order = rgba_orders[i].clutter_font_subpixel_order; - } - else - { - output->cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT; - output->clutter_font_subpixel_order = NULL; - } - - if (output->cairo_antialias == CAIRO_ANTIALIAS_GRAY) - output->clutter_font_subpixel_order = "none"; -} - -static void -init_font_options (ClutterSettings *self) -{ - GSettings *settings = self->font_settings; - cairo_font_options_t *options = cairo_font_options_create (); - FontSettings fs; - - get_font_gsettings (settings, &fs); - - cairo_font_options_set_hint_style (options, fs.cairo_hint_style); - cairo_font_options_set_antialias (options, fs.cairo_antialias); - cairo_font_options_set_subpixel_order (options, fs.cairo_subpixel_order); - - clutter_backend_set_font_options (self->backend, options); - - cairo_font_options_destroy (options); -} - -static void -sync_mouse_options (ClutterSettings *self) -{ - int double_click; - int drag_threshold; - - double_click = g_settings_get_int (self->mouse_settings, "double-click"); - drag_threshold = g_settings_get_int (self->mouse_settings, "drag-threshold"); - - g_object_set (self, - "double-click-time", double_click, - "dnd-drag-threshold", drag_threshold, - NULL); -} - -static gboolean -on_font_settings_change_event (GSettings *settings, - gpointer keys, - gint n_keys, - gpointer user_data) -{ - ClutterSettings *self = CLUTTER_SETTINGS (user_data); - FontSettings fs; - gint hinting; - - get_font_gsettings (settings, &fs); - hinting = fs.cairo_hint_style == CAIRO_HINT_STYLE_NONE ? 0 : 1; - g_object_set (self, - "font-hinting", hinting, - "font-hint-style", fs.clutter_font_hint_style, - "font-antialias", fs.clutter_font_antialias, - "font-subpixel-order", fs.clutter_font_subpixel_order, - NULL); - - return FALSE; -} - -static gboolean -on_mouse_settings_change_event (GSettings *settings, - gpointer keys, - gint n_keys, - gpointer user_data) -{ - ClutterSettings *self = CLUTTER_SETTINGS (user_data); - - sync_mouse_options (self); - - return FALSE; -} - -struct _pointer_a11y_settings_flags_pair { - const char *name; - ClutterPointerA11yFlags flag; -} pointer_a11y_settings_flags_pair[] = { - { "secondary-click-enabled", CLUTTER_A11Y_SECONDARY_CLICK_ENABLED }, - { "dwell-click-enabled", CLUTTER_A11Y_DWELL_ENABLED }, -}; - -static ClutterPointerA11yDwellDirection -pointer_a11y_dwell_direction_from_setting (ClutterSettings *self, - const char *key) -{ - GDesktopMouseDwellDirection dwell_gesture_direction; - - dwell_gesture_direction = g_settings_get_enum (self->mouse_a11y_settings, - key); - switch (dwell_gesture_direction) - { - case G_DESKTOP_MOUSE_DWELL_DIRECTION_LEFT: - return CLUTTER_A11Y_DWELL_DIRECTION_LEFT; - break; - case G_DESKTOP_MOUSE_DWELL_DIRECTION_RIGHT: - return CLUTTER_A11Y_DWELL_DIRECTION_RIGHT; - break; - case G_DESKTOP_MOUSE_DWELL_DIRECTION_UP: - return CLUTTER_A11Y_DWELL_DIRECTION_UP; - break; - case G_DESKTOP_MOUSE_DWELL_DIRECTION_DOWN: - return CLUTTER_A11Y_DWELL_DIRECTION_DOWN; - break; - default: - break; - } - return CLUTTER_A11Y_DWELL_DIRECTION_NONE; -} - -static void -sync_pointer_a11y_settings (ClutterSettings *self, - ClutterSeat *seat) -{ - ClutterPointerA11ySettings pointer_a11y_settings; - GDesktopMouseDwellMode dwell_mode; - int i; - - clutter_seat_get_pointer_a11y_settings (seat, &pointer_a11y_settings); - pointer_a11y_settings.controls = 0; - for (i = 0; i < G_N_ELEMENTS (pointer_a11y_settings_flags_pair); i++) - { - if (!g_settings_get_boolean (self->mouse_a11y_settings, - pointer_a11y_settings_flags_pair[i].name)) - continue; - - pointer_a11y_settings.controls |= - pointer_a11y_settings_flags_pair[i].flag; - } - - /* "secondary-click-time" is expressed in seconds */ - pointer_a11y_settings.secondary_click_delay = - (1000 * g_settings_get_double (self->mouse_a11y_settings, - "secondary-click-time")); - /* "dwell-time" is expressed in seconds */ - pointer_a11y_settings.dwell_delay = - (1000 * g_settings_get_double (self->mouse_a11y_settings, "dwell-time")); - pointer_a11y_settings.dwell_threshold = - g_settings_get_int (self->mouse_a11y_settings, "dwell-threshold"); - - dwell_mode = g_settings_get_enum (self->mouse_a11y_settings, "dwell-mode"); - if (dwell_mode == G_DESKTOP_MOUSE_DWELL_MODE_WINDOW) - pointer_a11y_settings.dwell_mode = CLUTTER_A11Y_DWELL_MODE_WINDOW; - else - pointer_a11y_settings.dwell_mode = CLUTTER_A11Y_DWELL_MODE_GESTURE; - - pointer_a11y_settings.dwell_gesture_single = - pointer_a11y_dwell_direction_from_setting (self, "dwell-gesture-single"); - pointer_a11y_settings.dwell_gesture_double = - pointer_a11y_dwell_direction_from_setting (self, "dwell-gesture-double"); - pointer_a11y_settings.dwell_gesture_drag = - pointer_a11y_dwell_direction_from_setting (self, "dwell-gesture-drag"); - pointer_a11y_settings.dwell_gesture_secondary = - pointer_a11y_dwell_direction_from_setting (self, "dwell-gesture-secondary"); - - clutter_seat_set_pointer_a11y_settings (seat, &pointer_a11y_settings); -} - -static gboolean -on_mouse_a11y_settings_change_event (GSettings *settings, - gpointer keys, - int n_keys, - gpointer user_data) -{ - ClutterSettings *self = CLUTTER_SETTINGS (user_data); - ClutterSeat *seat = clutter_backend_get_default_seat (self->backend); - - sync_pointer_a11y_settings (self, seat); - - return FALSE; -} - -static void -load_initial_settings (ClutterSettings *self) -{ - static const gchar *font_settings_path = "org.gnome.desktop.interface"; - static const gchar *mouse_settings_path = "org.gnome.desktop.peripherals.mouse"; - static const char *mouse_a11y_settings_path = "org.gnome.desktop.a11y.mouse"; - GSettingsSchemaSource *source = g_settings_schema_source_get_default (); - GSettingsSchema *schema; - - schema = g_settings_schema_source_lookup (source, font_settings_path, TRUE); - if (!schema) - { - g_warning ("Failed to find schema: %s", font_settings_path); - } - else - { - self->font_settings = g_settings_new_full (schema, NULL, NULL); - if (self->font_settings) - { - init_font_options (self); - g_signal_connect (self->font_settings, "change-event", - G_CALLBACK (on_font_settings_change_event), - self); - } - } - - schema = g_settings_schema_source_lookup (source, mouse_settings_path, TRUE); - if (!schema) - { - g_warning ("Failed to find schema: %s", mouse_settings_path); - } - else - { - self->mouse_settings = g_settings_new_full (schema, NULL, NULL); - if (self->mouse_settings) - { - sync_mouse_options (self); - g_signal_connect (self->mouse_settings, "change-event", - G_CALLBACK (on_mouse_settings_change_event), - self); - } - } - - schema = g_settings_schema_source_lookup (source, mouse_a11y_settings_path, TRUE); - if (!schema) - { - g_warning ("Failed to find schema: %s", mouse_settings_path); - } - else - { - self->mouse_a11y_settings = g_settings_new_full (schema, NULL, NULL); - g_signal_connect (self->mouse_a11y_settings, "change-event", - G_CALLBACK (on_mouse_a11y_settings_change_event), - self); - } -} - -static void -clutter_settings_finalize (GObject *gobject) -{ - ClutterSettings *self = CLUTTER_SETTINGS (gobject); - - g_free (self->font_name); - g_free (self->xft_hint_style); - g_free (self->xft_rgba); - - g_clear_object (&self->font_settings); - g_clear_object (&self->mouse_settings); - g_clear_object (&self->mouse_a11y_settings); - - G_OBJECT_CLASS (clutter_settings_parent_class)->finalize (gobject); -} - -static void -clutter_settings_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterSettings *self = CLUTTER_SETTINGS (gobject); - - switch (prop_id) - { - case PROP_DOUBLE_CLICK_TIME: - self->double_click_time = g_value_get_int (value); - break; - - case PROP_DOUBLE_CLICK_DISTANCE: - self->double_click_distance = g_value_get_int (value); - break; - - case PROP_DND_DRAG_THRESHOLD: - self->dnd_drag_threshold = g_value_get_int (value); - break; - - case PROP_FONT_NAME: - g_free (self->font_name); - self->font_name = g_value_dup_string (value); - settings_update_font_name (self); - break; - - case PROP_FONT_ANTIALIAS: - self->xft_antialias = g_value_get_int (value); - settings_update_font_options (self); - break; - - case PROP_FONT_DPI: - self->font_dpi = g_value_get_int (value); - settings_update_resolution (self); - break; - - case PROP_FONT_HINTING: - self->xft_hinting = g_value_get_int (value); - settings_update_font_options (self); - break; - - case PROP_FONT_HINT_STYLE: - g_free (self->xft_hint_style); - self->xft_hint_style = g_value_dup_string (value); - settings_update_font_options (self); - break; - - case PROP_FONT_RGBA: - g_free (self->xft_rgba); - self->xft_rgba = g_value_dup_string (value); - settings_update_font_options (self); - break; - - case PROP_LONG_PRESS_DURATION: - self->long_press_duration = g_value_get_int (value); - break; - - case PROP_FONTCONFIG_TIMESTAMP: - settings_update_fontmap (self, g_value_get_uint (value)); - break; - - case PROP_PASSWORD_HINT_TIME: - self->password_hint_time = g_value_get_uint (value); - break; - - case PROP_UNSCALED_FONT_DPI: - self->font_dpi = g_value_get_int (value); - settings_update_resolution (self); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_settings_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterSettings *self = CLUTTER_SETTINGS (gobject); - - switch (prop_id) - { - case PROP_DOUBLE_CLICK_TIME: - g_value_set_int (value, self->double_click_time); - break; - - case PROP_DOUBLE_CLICK_DISTANCE: - g_value_set_int (value, self->double_click_distance); - break; - - case PROP_DND_DRAG_THRESHOLD: - g_value_set_int (value, self->dnd_drag_threshold); - break; - - case PROP_FONT_NAME: - g_value_set_string (value, self->font_name); - break; - - case PROP_FONT_ANTIALIAS: - g_value_set_int (value, self->xft_antialias); - break; - - case PROP_FONT_DPI: - g_value_set_int (value, self->resolution * 1024); - break; - - case PROP_FONT_HINTING: - g_value_set_int (value, self->xft_hinting); - break; - - case PROP_FONT_HINT_STYLE: - g_value_set_string (value, self->xft_hint_style); - break; - - case PROP_FONT_RGBA: - g_value_set_string (value, self->xft_rgba); - break; - - case PROP_LONG_PRESS_DURATION: - g_value_set_int (value, self->long_press_duration); - break; - - case PROP_PASSWORD_HINT_TIME: - g_value_set_uint (value, self->password_hint_time); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_settings_dispatch_properties_changed (GObject *gobject, - guint n_pspecs, - GParamSpec **pspecs) -{ - ClutterSettings *self = CLUTTER_SETTINGS (gobject); - GObjectClass *klass; - - /* chain up to emit ::notify */ - klass = G_OBJECT_CLASS (clutter_settings_parent_class); - klass->dispatch_properties_changed (gobject, n_pspecs, pspecs); - - /* emit settings-changed just once for multiple properties */ - if (self->backend != NULL) - g_signal_emit_by_name (self->backend, "settings-changed"); -} - -static void -clutter_settings_class_init (ClutterSettingsClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - /** - * ClutterSettings:double-click-time: - * - * The time, in milliseconds, that should elapse between button-press - * events in order to increase the click count by 1. - */ - obj_props[PROP_DOUBLE_CLICK_TIME] = - g_param_spec_int ("double-click-time", NULL, NULL, - 0, G_MAXINT, - 250, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterSettings:double-click-distance: - * - * The maximum distance, in pixels, between button-press events that - * determines whether or not to increase the click count by 1. - */ - obj_props[PROP_DOUBLE_CLICK_DISTANCE] = - g_param_spec_int ("double-click-distance", NULL, NULL, - 0, G_MAXINT, - 5, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterSettings:dnd-drag-threshold: - * - * The default distance that the cursor of a pointer device - * should travel before a drag operation should start. - */ - obj_props[PROP_DND_DRAG_THRESHOLD] = - g_param_spec_int ("dnd-drag-threshold", NULL, NULL, - 1, G_MAXINT, - 8, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterSettings:font-name: - * - * The default font name that should be used by text actors, as - * a string that can be passed to [func@Pango.FontDescription.from_string]. - */ - obj_props[PROP_FONT_NAME] = - g_param_spec_string ("font-name", NULL, NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterSettings:font-antialias: - * - * Whether or not to use antialiasing when rendering text; a value - * of 1 enables it unconditionally; a value of 0 disables it - * unconditionally; and -1 will use the system's default. - */ - obj_props[PROP_FONT_ANTIALIAS] = - g_param_spec_int ("font-antialias", NULL, NULL, - -1, 1, - -1, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterSettings:font-dpi: - * - * The DPI used when rendering text, as a value of 1024 * dots/inch. - * - * If set to -1, the system's default will be used instead - */ - obj_props[PROP_FONT_DPI] = - g_param_spec_int ("font-dpi", NULL, NULL, - -1, 1024 * 1024, - -1, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - obj_props[PROP_UNSCALED_FONT_DPI] = - g_param_spec_int ("unscaled-font-dpi", NULL, NULL, - -1, 1024 * 1024, - -1, - G_PARAM_WRITABLE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterSettings:font-hinting: - * - * Whether or not to use hinting when rendering text; a value of 1 - * unconditionally enables it; a value of 0 unconditionally disables - * it; and a value of -1 will use the system's default. - */ - obj_props[PROP_FONT_HINTING] = - g_param_spec_int ("font-hinting", NULL, NULL, - -1, 1, - -1, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterSettings:font-hint-style: - * - * The style of the hinting used when rendering text. Valid values - * are: - * - * - hintnone - * - hintslight - * - hintmedium - * - hintfull - */ - obj_props[PROP_FONT_HINT_STYLE] = - g_param_spec_string ("font-hint-style", NULL, NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterSettings:font-subpixel-order: - * - * The type of sub-pixel antialiasing used when rendering text. Valid - * values are: - * - * - none - * - rgb - * - bgr - * - vrgb - * - vbgr - */ - obj_props[PROP_FONT_RGBA] = - g_param_spec_string ("font-subpixel-order", NULL, NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterSettings:long-press-duration: - * - * Sets the minimum duration for a press to be recognized as a long press - * gesture. The duration is expressed in milliseconds. - * - * See also [property@ClickAction:long-press-duration]. - */ - obj_props[PROP_LONG_PRESS_DURATION] = - g_param_spec_int ("long-press-duration", NULL, NULL, - 0, G_MAXINT, - 500, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - obj_props[PROP_FONTCONFIG_TIMESTAMP] = - g_param_spec_uint ("fontconfig-timestamp", NULL, NULL, - 0, G_MAXUINT, - 0, - G_PARAM_WRITABLE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterText:password-hint-time: - * - * How long should Clutter show the last input character in editable - * [class@Text] actors. The value is in milliseconds. A value of 0 - * disables showing the password hint. 600 is a good value for - * enabling the hint. - */ - obj_props[PROP_PASSWORD_HINT_TIME] = - g_param_spec_uint ("password-hint-time", NULL, NULL, - 0, G_MAXUINT, - 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - gobject_class->set_property = clutter_settings_set_property; - gobject_class->get_property = clutter_settings_get_property; - gobject_class->dispatch_properties_changed = - clutter_settings_dispatch_properties_changed; - gobject_class->finalize = clutter_settings_finalize; - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); -} - -static void -clutter_settings_init (ClutterSettings *self) -{ - self->resolution = -1.0; - - self->font_dpi = -1; - self->unscaled_font_dpi = -1; - - self->double_click_time = 250; - self->double_click_distance = 5; - - self->dnd_drag_threshold = 8; - - self->font_name = g_strdup (DEFAULT_FONT_NAME); - - self->xft_antialias = -1; - self->xft_hinting = -1; - self->xft_hint_style = NULL; - self->xft_rgba = NULL; - - self->long_press_duration = 500; -} - -/** - * clutter_settings_get_default: - * - * Retrieves the singleton instance of #ClutterSettings - * - * Return value: (transfer none): the instance of #ClutterSettings. The - * returned object is owned by Clutter and it should not be unreferenced - * directly - */ -ClutterSettings * -clutter_settings_get_default (void) -{ - static ClutterSettings *settings = NULL; - - if (G_UNLIKELY (settings == NULL)) - settings = g_object_new (CLUTTER_TYPE_SETTINGS, NULL); - - return settings; -} - -void -_clutter_settings_set_backend (ClutterSettings *settings, - ClutterBackend *backend) -{ - g_assert (CLUTTER_IS_SETTINGS (settings)); - g_assert (CLUTTER_IS_BACKEND (backend)); - - settings->backend = backend; - - load_initial_settings (settings); -} - -void -clutter_settings_ensure_pointer_a11y_settings (ClutterSettings *settings, - ClutterSeat *seat) -{ - sync_pointer_a11y_settings (settings, seat); -} diff --git a/mutter/clutter/clutter/clutter-settings.h b/mutter/clutter/clutter/clutter-settings.h deleted file mode 100644 index 0516ddf..0000000 --- a/mutter/clutter/clutter/clutter-settings.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_SETTINGS (clutter_settings_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_FINAL_TYPE (ClutterSettings, clutter_settings, - CLUTTER, SETTINGS, - GObject) - -CLUTTER_EXPORT -ClutterSettings *clutter_settings_get_default (void); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-shader-effect.c b/mutter/clutter/clutter/clutter-shader-effect.c deleted file mode 100644 index 9d83bfc..0000000 --- a/mutter/clutter/clutter/clutter-shader-effect.c +++ /dev/null @@ -1,883 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterShaderEffect: - * - * Base class for shader effects - * - * #ClutterShaderEffect is a class that implements all the plumbing for - * creating [class@Effect]s using GLSL shaders. - * - * #ClutterShaderEffect creates an offscreen buffer and then applies the - * GLSL shader (after checking whether the compilation and linking were - * successful) to the buffer before painting it on screen. - * - * - * ## Implementing a ClutterShaderEffect - * - * Creating a sub-class of #ClutterShaderEffect requires the - * overriding of the [vfunc@OffscreenEffect.paint_target] virtual - * function from the [class@OffscreenEffect] class. It is also convenient - * to implement the [vfunc@ShaderEffect.get_static_shader_source] - * virtual function in case you are planning to create more than one - * instance of the effect. - * - * The [vfunc@ShaderEffect.get_static_shader_source] - * function should return a copy of the shader source to use. This - * function is only called once per subclass of #ClutterShaderEffect - * regardless of how many instances of the effect are created. The - * source for the shader is typically stored in a static const - * string which is returned from this function via - * g_strdup(). - * - * The [vfunc@OffscreenEffect.paint_target] should set the - * shader's uniforms if any. This is done by calling - * [method@ShaderEffect.set_uniform_value] or - * [method@ShaderEffect.set_uniform]. The sub-class should then - * chain up to the #ClutterShaderEffect implementation. - * - * ## Setting uniforms on a ClutterShaderEffect - * - * The example below shows a typical implementation of the - * [vfunc@ShaderEffect.get_static_shader_source] and - * [vfunc@OffscreenEffect.paint_target] virtual functions - * for a #ClutterShaderEffect subclass. - * - * ```c - * static gchar * - * my_effect_get_static_shader_source (ClutterShaderEffect *effect) - * { - * // shader_source is set elsewhere - * return g_strdup (shader_source); - * } - * - * static gboolean - * my_effect_paint_target (ClutterOffscreenEffect *effect) - * { - * MyEffect *self = MY_EFFECT (effect); - * ClutterShaderEffect *shader = CLUTTER_SHADER_EFFECT (effect); - * ClutterEffectClass *parent_class; - * gfloat component_r, component_g, component_b; - * - * // the "tex" uniform is declared in the shader as: - * // - * // uniform int tex; - * // - * // and it is passed a constant value of 0 - * clutter_shader_effect_set_uniform (shader, "tex", G_TYPE_INT, 1, 0); - * - * // the "component" uniform is declared in the shader as: - * // - * // uniform vec3 component; - * // - * // and it's defined to contain the normalized components - * // of a #ClutterColor - * component_r = self->color.red / 255.0f; - * component_g = self->color.green / 255.0f; - * component_b = self->color.blue / 255.0f; - * clutter_shader_effect_set_uniform (shader, "component", - * G_TYPE_FLOAT, 3, - * component_r, - * component_g, - * component_b); - * - * // chain up to the parent's implementation - * parent_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (my_effect_parent_class); - * return parent_class->paint_target (effect); - * } - * ``` - */ - -#include "config.h" - -#define COGL_DISABLE_DEPRECATION_WARNINGS - -#include "cogl/cogl.h" - -#include "clutter/clutter-shader-effect.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-shader-types.h" - -typedef struct _ShaderUniform -{ - gchar *name; - GType type; - GValue value; - int location; -} ShaderUniform; - -typedef struct _ClutterShaderEffectPrivate -{ - ClutterActor *actor; - - ClutterShaderType shader_type; - - CoglProgram *program; - CoglShader *shader; - - GHashTable *uniforms; -} ClutterShaderEffectPrivate; - -typedef struct _ClutterShaderEffectClassPrivate -{ - /* These are the per-class pre-compiled shader and program which is - used when the class implements get_static_shader_source without - calling set_shader_source. They will be shared by all instances - of this class */ - CoglProgram *program; - CoglShader *shader; -} ClutterShaderEffectClassPrivate; - -enum -{ - PROP_0, - - PROP_SHADER_TYPE, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -G_DEFINE_TYPE_WITH_CODE (ClutterShaderEffect, - clutter_shader_effect, - CLUTTER_TYPE_OFFSCREEN_EFFECT, - G_ADD_PRIVATE (ClutterShaderEffect) - g_type_add_class_private (g_define_type_id, - sizeof (ClutterShaderEffectClassPrivate))) - -static inline void -clutter_shader_effect_clear (ClutterShaderEffect *self, - gboolean reset_uniforms) -{ - ClutterShaderEffectPrivate *priv = - clutter_shader_effect_get_instance_private (self); - - g_clear_object (&priv->shader); - g_clear_object (&priv->program); - - if (reset_uniforms && priv->uniforms != NULL) - { - g_hash_table_destroy (priv->uniforms); - priv->uniforms = NULL; - } - - priv->actor = NULL; -} - -static void -clutter_shader_effect_update_uniforms (ClutterShaderEffect *effect) -{ - ClutterShaderEffectPrivate *priv = - clutter_shader_effect_get_instance_private (effect); - GHashTableIter iter; - gpointer key, value; - gsize size; - - if (priv->program == NULL) - return; - - if (priv->uniforms == NULL) - return; - - key = value = NULL; - g_hash_table_iter_init (&iter, priv->uniforms); - while (g_hash_table_iter_next (&iter, &key, &value)) - { - ShaderUniform *uniform = value; - - if (uniform->location == -1) - uniform->location = cogl_program_get_uniform_location (priv->program, - uniform->name); - - if (CLUTTER_VALUE_HOLDS_SHADER_FLOAT (&uniform->value)) - { - const float *floats; - - floats = clutter_value_get_shader_float (&uniform->value, &size); - cogl_program_set_uniform_float (priv->program, uniform->location, - size, 1, - floats); - } - else if (CLUTTER_VALUE_HOLDS_SHADER_INT (&uniform->value)) - { - const int *ints; - - ints = clutter_value_get_shader_int (&uniform->value, &size); - cogl_program_set_uniform_int (priv->program, uniform->location, - size, 1, - ints); - } - else if (CLUTTER_VALUE_HOLDS_SHADER_MATRIX (&uniform->value)) - { - const float *matrix; - - matrix = clutter_value_get_shader_matrix (&uniform->value, &size); - cogl_program_set_uniform_matrix (priv->program, uniform->location, - size, 1, - FALSE, - matrix); - } - else if (G_VALUE_HOLDS_FLOAT (&uniform->value)) - { - const float float_val = g_value_get_float (&uniform->value); - - cogl_program_set_uniform_float (priv->program, uniform->location, - 1, 1, - &float_val); - } - else if (G_VALUE_HOLDS_DOUBLE (&uniform->value)) - { - const float float_val = - (float) g_value_get_double (&uniform->value); - - cogl_program_set_uniform_float (priv->program, uniform->location, - 1, 1, - &float_val); - } - else if (G_VALUE_HOLDS_INT (&uniform->value)) - { - const int int_val = g_value_get_int (&uniform->value); - - cogl_program_set_uniform_int (priv->program, uniform->location, - 1, 1, - &int_val); - } - else - g_warning ("Invalid uniform of type '%s' for name '%s'", - g_type_name (G_VALUE_TYPE (&uniform->value)), - uniform->name); - } -} - -static void -clutter_shader_effect_set_actor (ClutterActorMeta *meta, - ClutterActor *actor) -{ - ClutterShaderEffect *self = CLUTTER_SHADER_EFFECT (meta); - ClutterShaderEffectPrivate *priv = - clutter_shader_effect_get_instance_private (self); - ClutterActorMetaClass *parent; - - parent = CLUTTER_ACTOR_META_CLASS (clutter_shader_effect_parent_class); - parent->set_actor (meta, actor); - - /* we keep a back pointer here */ - priv->actor = clutter_actor_meta_get_actor (meta); - if (priv->actor == NULL) - return; - - CLUTTER_NOTE (SHADER, "Preparing shader effect of type '%s'", - G_OBJECT_TYPE_NAME (meta)); -} - -static CoglShader* -clutter_shader_effect_create_shader (ClutterShaderEffect *self) -{ - ClutterShaderEffectPrivate *priv = - clutter_shader_effect_get_instance_private (self); - - switch (priv->shader_type) - { - case CLUTTER_FRAGMENT_SHADER: - return cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); - break; - - case CLUTTER_VERTEX_SHADER: - return cogl_create_shader (COGL_SHADER_TYPE_VERTEX); - break; - - default: - g_assert_not_reached (); - return NULL; - } -} - -static void -clutter_shader_effect_try_static_source (ClutterShaderEffect *self) -{ - ClutterShaderEffectPrivate *priv = - clutter_shader_effect_get_instance_private (self); - ClutterShaderEffectClass *shader_effect_class = - CLUTTER_SHADER_EFFECT_GET_CLASS (self); - - if (shader_effect_class->get_static_shader_source != NULL) - { - ClutterShaderEffectClassPrivate *class_priv; - - class_priv = - G_TYPE_CLASS_GET_PRIVATE (shader_effect_class, - CLUTTER_TYPE_SHADER_EFFECT, - ClutterShaderEffectClassPrivate); - - if (class_priv->shader == NULL) - { - gchar *source; - - class_priv->shader = clutter_shader_effect_create_shader (self); - - source = shader_effect_class->get_static_shader_source (self); - - cogl_shader_source (class_priv->shader, source); - - g_free (source); - - CLUTTER_NOTE (SHADER, "Compiling shader effect"); - - class_priv->program = cogl_create_program (); - - cogl_program_attach_shader (class_priv->program, - class_priv->shader); - - cogl_program_link (class_priv->program); - } - - priv->shader = g_object_ref (class_priv->shader); - - if (class_priv->program != NULL) - priv->program = g_object_ref (class_priv->program); - } -} - -static void -clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect, - ClutterPaintNode *node, - ClutterPaintContext *paint_context) -{ - ClutterShaderEffect *self = CLUTTER_SHADER_EFFECT (effect); - ClutterShaderEffectPrivate *priv = - clutter_shader_effect_get_instance_private (self); - ClutterOffscreenEffectClass *parent; - CoglPipeline *pipeline; - - /* If the source hasn't been set then we'll try to get it from the - static source instead */ - if (priv->shader == NULL) - clutter_shader_effect_try_static_source (self); - - /* we haven't been prepared or we don't have support for - * GLSL shaders in Clutter - */ - if (priv->program == NULL) - goto out; - - CLUTTER_NOTE (SHADER, "Applying the shader effect of type '%s'", - G_OBJECT_TYPE_NAME (effect)); - - clutter_shader_effect_update_uniforms (CLUTTER_SHADER_EFFECT (effect)); - - /* associate the program to the offscreen target pipeline */ - pipeline = clutter_offscreen_effect_get_pipeline (effect); - cogl_pipeline_set_user_program (pipeline, priv->program); - -out: - /* paint the offscreen buffer */ - parent = CLUTTER_OFFSCREEN_EFFECT_CLASS (clutter_shader_effect_parent_class); - parent->paint_target (effect, node, paint_context); - -} - -static void -clutter_shader_effect_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterShaderEffectPrivate *priv = - clutter_shader_effect_get_instance_private (CLUTTER_SHADER_EFFECT (gobject)); - - switch (prop_id) - { - case PROP_SHADER_TYPE: - priv->shader_type = g_value_get_enum (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_shader_effect_finalize (GObject *gobject) -{ - ClutterShaderEffect *effect = CLUTTER_SHADER_EFFECT (gobject); - - clutter_shader_effect_clear (effect, TRUE); - - G_OBJECT_CLASS (clutter_shader_effect_parent_class)->finalize (gobject); -} - -static void -clutter_shader_effect_class_init (ClutterShaderEffectClass *klass) -{ - ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterOffscreenEffectClass *offscreen_class; - - offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); - - /** - * ClutterShaderEffect:shader-type: - * - * The type of shader that is used by the effect. This property - * should be set by the constructor of #ClutterShaderEffect - * sub-classes. - */ - obj_props[PROP_SHADER_TYPE] = - g_param_spec_enum ("shader-type", NULL, NULL, - CLUTTER_TYPE_SHADER_TYPE, - CLUTTER_FRAGMENT_SHADER, - G_PARAM_WRITABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - gobject_class->set_property = clutter_shader_effect_set_property; - gobject_class->finalize = clutter_shader_effect_finalize; - g_object_class_install_properties (gobject_class, - PROP_LAST, - obj_props); - - meta_class->set_actor = clutter_shader_effect_set_actor; - - offscreen_class->paint_target = clutter_shader_effect_paint_target; -} - -static void -clutter_shader_effect_init (ClutterShaderEffect *effect) -{ - ClutterShaderEffectPrivate *priv = - clutter_shader_effect_get_instance_private (effect); - - priv->shader_type = CLUTTER_FRAGMENT_SHADER; -} - -/** - * clutter_shader_effect_new: - * @shader_type: the type of the shader, either %CLUTTER_FRAGMENT_SHADER, - * or %CLUTTER_VERTEX_SHADER - * - * Creates a new #ClutterShaderEffect, to be applied to an actor using - * [method@Actor.add_effect]. - * - * The effect will be empty until [method@ShaderEffect.set_shader_source] - * is called. - * - * Return value: the newly created #ClutterShaderEffect. - * Use g_object_unref() when done. - */ -ClutterEffect * -clutter_shader_effect_new (ClutterShaderType shader_type) -{ - return g_object_new (CLUTTER_TYPE_SHADER_EFFECT, - "shader-type", shader_type, - NULL); -} - -/** - * clutter_shader_effect_get_shader: - * @effect: a #ClutterShaderEffect - * - * Retrieves a pointer to the shader's handle - * - * Return value: (transfer none): a pointer to the shader's handle, - * or %NULL - */ -CoglShader* -clutter_shader_effect_get_shader (ClutterShaderEffect *effect) -{ - ClutterShaderEffectPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_SHADER_EFFECT (effect), - NULL); - - priv = clutter_shader_effect_get_instance_private (effect); - return priv->shader; -} - -/** - * clutter_shader_effect_get_program: - * @effect: a #ClutterShaderEffect - * - * Retrieves a pointer to the program's handle - * - * Return value: (transfer none): a pointer to the program's handle, - * or %NULL - */ -CoglProgram* -clutter_shader_effect_get_program (ClutterShaderEffect *effect) -{ - ClutterShaderEffectPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_SHADER_EFFECT (effect), - NULL); - - priv = clutter_shader_effect_get_instance_private (effect); - return priv->program; -} - -static void -shader_uniform_free (gpointer data) -{ - if (data != NULL) - { - ShaderUniform *uniform = data; - - g_value_unset (&uniform->value); - g_free (uniform->name); - - g_free (uniform); - } -} - -static ShaderUniform * -shader_uniform_new (const gchar *name, - const GValue *value) -{ - ShaderUniform *retval; - - retval = g_new0 (ShaderUniform, 1); - retval->name = g_strdup (name); - retval->type = G_VALUE_TYPE (value); - retval->location = -1; - - g_value_init (&retval->value, retval->type); - g_value_copy (value, &retval->value); - - return retval; -} - -static void -shader_uniform_update (ShaderUniform *uniform, - const GValue *value) -{ - g_value_unset (&uniform->value); - - g_value_init (&uniform->value, G_VALUE_TYPE (value)); - g_value_copy (value, &uniform->value); -} - -static inline void -clutter_shader_effect_add_uniform (ClutterShaderEffect *effect, - const gchar *name, - const GValue *value) -{ - ClutterShaderEffectPrivate *priv = - clutter_shader_effect_get_instance_private (effect); - ShaderUniform *uniform; - - if (priv->uniforms == NULL) - { - priv->uniforms = g_hash_table_new_full (g_str_hash, g_str_equal, - NULL, - shader_uniform_free); - } - - uniform = g_hash_table_lookup (priv->uniforms, name); - if (uniform == NULL) - { - uniform = shader_uniform_new (name, value); - g_hash_table_insert (priv->uniforms, uniform->name, uniform); - } - else - shader_uniform_update (uniform, value); - - if (priv->actor != NULL && !CLUTTER_ACTOR_IN_PAINT (priv->actor)) - clutter_effect_queue_repaint (CLUTTER_EFFECT (effect)); -} - -/** - * clutter_shader_effect_set_uniform_value: - * @effect: a #ClutterShaderEffect - * @name: the name of the uniform to set - * @value: a #GValue with the value of the uniform to set - * - * Sets @value as the payload for the uniform @name inside the shader - * effect - * - * The #GType of the @value must be one of: %G_TYPE_INT, for a single - * integer value; %G_TYPE_FLOAT, for a single floating point value; - * %CLUTTER_TYPE_SHADER_INT, for an array of integer values; - * %CLUTTER_TYPE_SHADER_FLOAT, for an array of floating point values; - * and %CLUTTER_TYPE_SHADER_MATRIX, for a matrix of floating point - * values. It also accepts %G_TYPE_DOUBLE for compatibility with other - * languages than C. - */ -void -clutter_shader_effect_set_uniform_value (ClutterShaderEffect *effect, - const gchar *name, - const GValue *value) -{ - g_return_if_fail (CLUTTER_IS_SHADER_EFFECT (effect)); - g_return_if_fail (name != NULL); - g_return_if_fail (value != NULL); - - clutter_shader_effect_add_uniform (effect, name, value); -} - -static void -clutter_shader_effect_set_uniform_valist (ClutterShaderEffect *effect, - const gchar *name, - GType value_type, - gsize n_values, - va_list *args) -{ - GValue value = G_VALUE_INIT; - - if (value_type == CLUTTER_TYPE_SHADER_INT) - { - gint *int_values = va_arg (*args, gint*); - - g_value_init (&value, CLUTTER_TYPE_SHADER_INT); - clutter_value_set_shader_int (&value, n_values, int_values); - - goto add_uniform; - } - - if (value_type == CLUTTER_TYPE_SHADER_FLOAT) - { - gfloat *float_values = va_arg (*args, gfloat*); - - g_value_init (&value, CLUTTER_TYPE_SHADER_FLOAT); - clutter_value_set_shader_float (&value, n_values, float_values); - - goto add_uniform; - } - - if (value_type == CLUTTER_TYPE_SHADER_MATRIX) - { - gfloat *float_values = va_arg (*args, gfloat*); - - g_value_init (&value, CLUTTER_TYPE_SHADER_MATRIX); - clutter_value_set_shader_matrix (&value, n_values, float_values); - - goto add_uniform; - } - - if (value_type == G_TYPE_INT) - { - g_return_if_fail (n_values <= 4); - - /* if we only have one value we can go through the fast path - * of using G_TYPE_INT, otherwise we create a vector of integers - * from the passed values - */ - if (n_values == 1) - { - gint int_val = va_arg (*args, gint); - - g_value_init (&value, G_TYPE_INT); - g_value_set_int (&value, int_val); - } - else - { - gint *int_values = g_new (gint, n_values); - gint i; - - for (i = 0; i < n_values; i++) - int_values[i] = va_arg (*args, gint); - - g_value_init (&value, CLUTTER_TYPE_SHADER_INT); - clutter_value_set_shader_int (&value, n_values, int_values); - - g_free (int_values); - } - - goto add_uniform; - } - - if (value_type == G_TYPE_FLOAT) - { - g_return_if_fail (n_values <= 4); - - /* if we only have one value we can go through the fast path - * of using G_TYPE_FLOAT, otherwise we create a vector of floats - * from the passed values - */ - if (n_values == 1) - { - gfloat float_val = (gfloat) va_arg (*args, gdouble); - - g_value_init (&value, G_TYPE_FLOAT); - g_value_set_float (&value, float_val); - } - else - { - gfloat *float_values = g_new (gfloat, n_values); - gint i; - - for (i = 0; i < n_values; i++) - float_values[i] = (gfloat) va_arg (*args, double); - - g_value_init (&value, CLUTTER_TYPE_SHADER_FLOAT); - clutter_value_set_shader_float (&value, n_values, float_values); - - g_free (float_values); - } - - goto add_uniform; - } - - g_warning ("Unrecognized type '%s' (values: %d) for uniform name '%s'", - g_type_name (value_type), - (int) n_values, - name); - return; - -add_uniform: - clutter_shader_effect_add_uniform (effect, name, &value); - g_value_unset (&value); -} - -/** - * clutter_shader_effect_set_uniform: - * @effect: a #ClutterShaderEffect - * @name: the name of the uniform to set - * @gtype: the type of the uniform to set - * @n_values: the number of values - * @...: a list of values - * - * Sets a list of values as the payload for the uniform @name inside - * the shader effect - * - * The @gtype must be one of: %G_TYPE_INT, for 1 or more integer values; - * %G_TYPE_FLOAT, for 1 or more floating point values; - * %CLUTTER_TYPE_SHADER_INT, for a pointer to an array of integer values; - * %CLUTTER_TYPE_SHADER_FLOAT, for a pointer to an array of floating point - * values; and %CLUTTER_TYPE_SHADER_MATRIX, for a pointer to an array of - * floating point values mapping a matrix - * - * The number of values interpreted is defined by the @n_value - * argument, and by the @gtype argument. For instance, a uniform named - * "sampler0" and containing a single integer value is set using: - * - * ```c - * clutter_shader_effect_set_uniform (effect, "sampler0", - * G_TYPE_INT, 1, - * 0); - * ``` - * - * While a uniform named "components" and containing a 3-elements vector - * of floating point values (a "vec3") can be set using: - * - * ```c - * gfloat component_r, component_g, component_b; - * - * clutter_shader_effect_set_uniform (effect, "components", - * G_TYPE_FLOAT, 3, - * component_r, - * component_g, - * component_b); - * ``` - * - * or can be set using: - * - * ```c - * gfloat component_vec[3]; - * - * clutter_shader_effect_set_uniform (effect, "components", - * CLUTTER_TYPE_SHADER_FLOAT, 3, - * component_vec); - * ``` - * - * Finally, a uniform named "map" and containing a matrix can be set using: - * - * ```c - * float v[16]; - * - * cogl_matrix_to_float (&matrix, v); - * clutter_shader_effect_set_uniform (effect, "map", - * CLUTTER_TYPE_SHADER_MATRIX, - * 1, v); - * ``` - */ -void -clutter_shader_effect_set_uniform (ClutterShaderEffect *effect, - const gchar *name, - GType gtype, - gsize n_values, - ...) -{ - va_list args; - - g_return_if_fail (CLUTTER_IS_SHADER_EFFECT (effect)); - g_return_if_fail (name != NULL); - g_return_if_fail (gtype != G_TYPE_INVALID); - g_return_if_fail (n_values > 0); - - va_start (args, n_values); - clutter_shader_effect_set_uniform_valist (effect, name, - gtype, - n_values, - &args); - va_end (args); -} - -/** - * clutter_shader_effect_set_shader_source: - * @effect: a #ClutterShaderEffect - * @source: the source of a GLSL shader - * - * Sets the source of the GLSL shader used by @effect - * - * This function should only be called by implementations of - * the #ClutterShaderEffect class, and not by application code. - * - * This function can only be called once; subsequent calls will - * yield no result. - * - * Return value: %TRUE if the source was set - */ -gboolean -clutter_shader_effect_set_shader_source (ClutterShaderEffect *effect, - const gchar *source) -{ - ClutterShaderEffectPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_SHADER_EFFECT (effect), FALSE); - g_return_val_if_fail (source != NULL && *source != '\0', FALSE); - - priv = clutter_shader_effect_get_instance_private (effect); - - if (priv->shader != NULL) - return TRUE; - - priv->shader = clutter_shader_effect_create_shader (effect); - - cogl_shader_source (priv->shader, source); - - CLUTTER_NOTE (SHADER, "Compiling shader effect"); - - priv->program = cogl_create_program (); - - cogl_program_attach_shader (priv->program, priv->shader); - - cogl_program_link (priv->program); - - return TRUE; -} diff --git a/mutter/clutter/clutter/clutter-shader-effect.h b/mutter/clutter/clutter/clutter-shader-effect.h deleted file mode 100644 index 201c447..0000000 --- a/mutter/clutter/clutter/clutter-shader-effect.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-offscreen-effect.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_SHADER_EFFECT (clutter_shader_effect_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterShaderEffect, - clutter_shader_effect, - CLUTTER, - SHADER_EFFECT, - ClutterOffscreenEffect) - -/** - * ClutterShaderEffectClass: - * @get_static_shader_source: Returns the GLSL source code to use for - * instances of this shader effect. Note that this function is only - * called once per subclass of #ClutterShaderEffect regardless of how - * many instances are used. It is expected that subclasses will return - * a copy of a static string from this function. - * - * The #ClutterShaderEffectClass structure contains - * only private data - */ -struct _ClutterShaderEffectClass -{ - /*< private >*/ - ClutterOffscreenEffectClass parent_class; - - /*< public >*/ - gchar * (* get_static_shader_source) (ClutterShaderEffect *effect); -}; - -CLUTTER_EXPORT -ClutterEffect * clutter_shader_effect_new (ClutterShaderType shader_type); - -CLUTTER_EXPORT -gboolean clutter_shader_effect_set_shader_source (ClutterShaderEffect *effect, - const gchar *source); - -CLUTTER_EXPORT -void clutter_shader_effect_set_uniform (ClutterShaderEffect *effect, - const gchar *name, - GType gtype, - gsize n_values, - ...); -CLUTTER_EXPORT -void clutter_shader_effect_set_uniform_value (ClutterShaderEffect *effect, - const gchar *name, - const GValue *value); - -CLUTTER_EXPORT -CoglShader* clutter_shader_effect_get_shader (ClutterShaderEffect *effect); -CLUTTER_EXPORT -CoglProgram* clutter_shader_effect_get_program (ClutterShaderEffect *effect); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-shader-types.c b/mutter/clutter/clutter/clutter-shader-types.c deleted file mode 100644 index 25dae6f..0000000 --- a/mutter/clutter/clutter/clutter-shader-types.c +++ /dev/null @@ -1,555 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Chris Lord - * - * Copyright (C) 2008 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#include "config.h" - -#include -#include - -#include "clutter/clutter-shader-types.h" -#include "clutter/clutter-private.h" - -static GTypeInfo shader_float_info = { - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - 0, - 0, - NULL, - NULL, -}; - -static GTypeFundamentalInfo shader_float_finfo = { 0, }; - -static GTypeInfo shader_int_info = { - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - 0, - 0, - NULL, - NULL, -}; - -static GTypeFundamentalInfo shader_int_finfo = { 0, }; - -static GTypeInfo shader_matrix_info = { - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - 0, - 0, - NULL, - NULL, -}; - -static GTypeFundamentalInfo shader_matrix_finfo = { 0, }; - -struct _ClutterShaderFloat -{ - gint size; - float value[4]; -}; - -struct _ClutterShaderInt -{ - gint size; - int value[4]; -}; - -struct _ClutterShaderMatrix -{ - gint size; - float value[16]; -}; - -static gpointer -clutter_value_peek_pointer (const GValue *value) -{ - return value->data[0].v_pointer; -} - -/* Float */ - -static void -clutter_value_init_shader_float (GValue *value) -{ - value->data[0].v_pointer = g_new0 (ClutterShaderFloat, 1); -} - -static void -clutter_value_free_shader_float (GValue *value) -{ - g_free (value->data[0].v_pointer); -} - -static void -clutter_value_copy_shader_float (const GValue *src, - GValue *dest) -{ - dest->data[0].v_pointer = - g_memdup2 (src->data[0].v_pointer, sizeof (ClutterShaderFloat)); -} - -static gchar * -clutter_value_collect_shader_float (GValue *value, - guint n_collect_values, - GTypeCValue *collect_values, - guint collect_flags) -{ - gint float_count = collect_values[0].v_int; - const float *floats = collect_values[1].v_pointer; - - if (!floats) - return g_strdup_printf ("value location for '%s' passed as NULL", - G_VALUE_TYPE_NAME (value)); - - clutter_value_init_shader_float (value); - clutter_value_set_shader_float (value, float_count, floats); - - return NULL; -} - -static gchar * -clutter_value_lcopy_shader_float (const GValue *value, - guint n_collect_values, - GTypeCValue *collect_values, - guint collect_flags) -{ - gint *float_count = collect_values[0].v_pointer; - float **floats = collect_values[1].v_pointer; - ClutterShaderFloat *shader_float = value->data[0].v_pointer; - - if (!float_count || !floats) - return g_strdup_printf ("value location for '%s' passed as NULL", - G_VALUE_TYPE_NAME (value)); - - *float_count = shader_float->size; - *floats = g_memdup2 (shader_float->value, - shader_float->size * sizeof (float)); - - return NULL; -} - -static const GTypeValueTable _clutter_shader_float_value_table = { - clutter_value_init_shader_float, - clutter_value_free_shader_float, - clutter_value_copy_shader_float, - clutter_value_peek_pointer, - "ip", - clutter_value_collect_shader_float, - "pp", - clutter_value_lcopy_shader_float -}; - -GType -clutter_shader_float_get_type (void) -{ - static GType _clutter_shader_float_type = 0; - - if (G_UNLIKELY (_clutter_shader_float_type == 0)) - { - shader_float_info.value_table = & _clutter_shader_float_value_table; - _clutter_shader_float_type = - g_type_register_fundamental (g_type_fundamental_next (), - I_("ClutterShaderFloat"), - &shader_float_info, - &shader_float_finfo, 0); - } - - return _clutter_shader_float_type; -} - - -/* Integer */ - -static void -clutter_value_init_shader_int (GValue *value) -{ - value->data[0].v_pointer = g_new0 (ClutterShaderInt, 1); -} - -static void -clutter_value_free_shader_int (GValue *value) -{ - g_free (value->data[0].v_pointer); -} - -static void -clutter_value_copy_shader_int (const GValue *src, - GValue *dest) -{ - dest->data[0].v_pointer = - g_memdup2 (src->data[0].v_pointer, sizeof (ClutterShaderInt)); -} - -static gchar * -clutter_value_collect_shader_int (GValue *value, - guint n_collect_values, - GTypeCValue *collect_values, - guint collect_flags) -{ - gint int_count = collect_values[0].v_int; - const int *ints = collect_values[1].v_pointer; - - if (!ints) - return g_strdup_printf ("value location for '%s' passed as NULL", - G_VALUE_TYPE_NAME (value)); - - clutter_value_init_shader_int (value); - clutter_value_set_shader_int (value, int_count, ints); - - return NULL; -} - -static gchar * -clutter_value_lcopy_shader_int (const GValue *value, - guint n_collect_values, - GTypeCValue *collect_values, - guint collect_flags) -{ - gint *int_count = collect_values[0].v_pointer; - int **ints = collect_values[1].v_pointer; - ClutterShaderInt *shader_int = value->data[0].v_pointer; - - if (!int_count || !ints) - return g_strdup_printf ("value location for '%s' passed as NULL", - G_VALUE_TYPE_NAME (value)); - - *int_count = shader_int->size; - *ints = g_memdup2 (shader_int->value, shader_int->size * sizeof (int)); - - return NULL; -} - -static const GTypeValueTable _clutter_shader_int_value_table = { - clutter_value_init_shader_int, - clutter_value_free_shader_int, - clutter_value_copy_shader_int, - clutter_value_peek_pointer, - "ip", - clutter_value_collect_shader_int, - "pp", - clutter_value_lcopy_shader_int -}; - -GType -clutter_shader_int_get_type (void) -{ - static GType _clutter_shader_int_type = 0; - - if (G_UNLIKELY (_clutter_shader_int_type == 0)) - { - shader_int_info.value_table = & _clutter_shader_int_value_table; - _clutter_shader_int_type = - g_type_register_fundamental (g_type_fundamental_next (), - I_("ClutterShaderInt"), - &shader_int_info, - &shader_int_finfo, 0); - } - - return _clutter_shader_int_type; -} - - -/* Matrix */ - -static void -clutter_value_init_shader_matrix (GValue *value) -{ - value->data[0].v_pointer = g_new0 (ClutterShaderMatrix, 1); -} - -static void -clutter_value_free_shader_matrix (GValue *value) -{ - g_free (value->data[0].v_pointer); -} - -static void -clutter_value_copy_shader_matrix (const GValue *src, - GValue *dest) -{ - dest->data[0].v_pointer = - g_memdup2 (src->data[0].v_pointer, sizeof (ClutterShaderMatrix)); -} - -static gchar * -clutter_value_collect_shader_matrix (GValue *value, - guint n_collect_values, - GTypeCValue *collect_values, - guint collect_flags) -{ - gint float_count = collect_values[0].v_int; - const float *floats = collect_values[1].v_pointer; - - if (!floats) - return g_strdup_printf ("value location for '%s' passed as NULL", - G_VALUE_TYPE_NAME (value)); - - clutter_value_init_shader_matrix (value); - clutter_value_set_shader_matrix (value, float_count, floats); - - return NULL; -} - -static gchar * -clutter_value_lcopy_shader_matrix (const GValue *value, - guint n_collect_values, - GTypeCValue *collect_values, - guint collect_flags) -{ - gint *float_count = collect_values[0].v_pointer; - float **floats = collect_values[1].v_pointer; - ClutterShaderFloat *shader_float = value->data[0].v_pointer; - - if (!float_count || !floats) - return g_strdup_printf ("value location for '%s' passed as NULL", - G_VALUE_TYPE_NAME (value)); - - *float_count = shader_float->size; - *floats = g_memdup2 (shader_float->value, - shader_float->size * - shader_float->size * - sizeof (float)); - - return NULL; -} - -static const GTypeValueTable _clutter_shader_matrix_value_table = { - clutter_value_init_shader_matrix, - clutter_value_free_shader_matrix, - clutter_value_copy_shader_matrix, - clutter_value_peek_pointer, - "ip", - clutter_value_collect_shader_matrix, - "pp", - clutter_value_lcopy_shader_matrix -}; - -GType -clutter_shader_matrix_get_type (void) -{ - static GType _clutter_shader_matrix_type = 0; - - if (G_UNLIKELY (_clutter_shader_matrix_type == 0)) - { - shader_matrix_info.value_table = & _clutter_shader_matrix_value_table; - _clutter_shader_matrix_type = - g_type_register_fundamental (g_type_fundamental_next (), - I_("ClutterShaderMatrix"), - &shader_matrix_info, - &shader_matrix_finfo, 0); - } - - return _clutter_shader_matrix_type; -} - - -/* Utility functions */ - -/** - * clutter_value_set_shader_float: - * @value: a #GValue - * @size: number of floating point values in @floats - * @floats: (array length=size): an array of floating point values - * - * Sets @floats as the contents of @value. The passed [struct@GObject.Value] - * must have been initialized using %CLUTTER_TYPE_SHADER_FLOAT. - */ -void -clutter_value_set_shader_float (GValue *value, - gint size, - const gfloat *floats) -{ - ClutterShaderFloat *shader_float; - gint i; - - g_return_if_fail (CLUTTER_VALUE_HOLDS_SHADER_FLOAT (value)); - g_return_if_fail (size <= 4); - - shader_float = value->data[0].v_pointer; - - shader_float->size = size; - - for (i = 0; i < size; i++) - shader_float->value[i] = floats[i]; -} - -/** - * clutter_value_set_shader_int: - * @value: a #GValue - * @size: number of integer values in @ints - * @ints: (array length=size): an array of integer values - * - * Sets @ints as the contents of @value. The passed [struct@GObject.Value] - * must have been initialized using %CLUTTER_TYPE_SHADER_INT. - */ -void -clutter_value_set_shader_int (GValue *value, - gint size, - const gint *ints) -{ - ClutterShaderInt *shader_int; - gint i; - - g_return_if_fail (CLUTTER_VALUE_HOLDS_SHADER_INT (value)); - g_return_if_fail (size <= 4); - - shader_int = value->data[0].v_pointer; - - shader_int->size = size; - - for (i = 0; i < size; i++) - shader_int->value[i] = ints[i]; -} - -/** - * clutter_value_set_shader_matrix: - * @value: a #GValue - * @size: number of floating point values in @floats - * @matrix: (array length=size): a matrix of floating point values - * - * Sets @matrix as the contents of @value. The passed [struct@GObject.Value] - * must have been initialized using %CLUTTER_TYPE_SHADER_MATRIX. - */ -void -clutter_value_set_shader_matrix (GValue *value, - gint size, - const gfloat *matrix) -{ - ClutterShaderMatrix *shader_matrix; - gint i; - - g_return_if_fail (CLUTTER_VALUE_HOLDS_SHADER_MATRIX (value)); - g_return_if_fail (size <= 4); - - shader_matrix = value->data[0].v_pointer; - - shader_matrix->size = size; - - for (i = 0; i < size * size; i++) - shader_matrix->value[i] = matrix[i]; -} - -/** - * clutter_value_get_shader_float: - * @value: a #GValue - * @length: (out): return location for the number of returned floating - * point values, or %NULL - * - * Retrieves the list of floating point values stored inside - * the passed [struct@GObject.Value]. @value must have been initialized with - * %CLUTTER_TYPE_SHADER_FLOAT. - * - * Return value: (array length=length): the pointer to a list of - * floating point values. The returned value is owned by the - * #GValue and should never be modified or freed. - */ -const gfloat * -clutter_value_get_shader_float (const GValue *value, - gsize *length) -{ - ClutterShaderFloat *shader_float; - - g_return_val_if_fail (CLUTTER_VALUE_HOLDS_SHADER_FLOAT (value), NULL); - - shader_float = value->data[0].v_pointer; - - if (length) - *length = shader_float->size; - - return shader_float->value; -} - -/** - * clutter_value_get_shader_int: - * @value: a #GValue - * @length: (out): return location for the number of returned integer - * values, or %NULL - * - * Retrieves the list of integer values stored inside the passed - * [struct@GObject.Value]. @value must have been initialized with - * %CLUTTER_TYPE_SHADER_INT. - * - * Return value: (array length=length): the pointer to a list of - * integer values. The returned value is owned by the #GValue and - * should never be modified or freed. - */ -const gint * -clutter_value_get_shader_int (const GValue *value, - gsize *length) -{ - ClutterShaderInt *shader_int; - - g_return_val_if_fail (CLUTTER_VALUE_HOLDS_SHADER_INT (value), NULL); - - shader_int = value->data[0].v_pointer; - - if (length) - *length = shader_int->size; - - return shader_int->value; -} - -/** - * clutter_value_get_shader_matrix: - * @value: a #GValue - * @length: (out): return location for the number of returned floating - * point values, or %NULL - * - * Retrieves a matrix of floating point values stored inside - * the passed [struct@GObject.Value]. @value must have been initialized with - * %CLUTTER_TYPE_SHADER_MATRIX. - * - * Return value: (array length=length) (transfer none): the pointer to a matrix - * of floating point values. The returned value is owned by the #GValue and - * should never be modified or freed. - */ -const gfloat * -clutter_value_get_shader_matrix (const GValue *value, - gsize *length) -{ - ClutterShaderMatrix *shader_matrix; - - g_return_val_if_fail (CLUTTER_VALUE_HOLDS_SHADER_MATRIX (value), NULL); - - shader_matrix = value->data[0].v_pointer; - - if (length) - *length = shader_matrix->size; - - return shader_matrix->value; -} diff --git a/mutter/clutter/clutter/clutter-shader-types.h b/mutter/clutter/clutter/clutter-shader-types.h deleted file mode 100644 index cc2070b..0000000 --- a/mutter/clutter/clutter/clutter-shader-types.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2008 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_SHADER_FLOAT (clutter_shader_float_get_type ()) -#define CLUTTER_TYPE_SHADER_INT (clutter_shader_int_get_type ()) -#define CLUTTER_TYPE_SHADER_MATRIX (clutter_shader_matrix_get_type ()) - -typedef struct _ClutterShaderFloat ClutterShaderFloat; -typedef struct _ClutterShaderInt ClutterShaderInt; -typedef struct _ClutterShaderMatrix ClutterShaderMatrix; - -/** - * CLUTTER_VALUE_HOLDS_SHADER_FLOAT: - * @x: a #GValue - * - * Evaluates to %TRUE if @x holds a #ClutterShaderFloat. - */ -#define CLUTTER_VALUE_HOLDS_SHADER_FLOAT(x) (G_VALUE_HOLDS ((x), CLUTTER_TYPE_SHADER_FLOAT)) - -/** - * CLUTTER_VALUE_HOLDS_SHADER_INT: - * @x: a #GValue - * - * Evaluates to %TRUE if @x holds a #ClutterShaderInt. - */ -#define CLUTTER_VALUE_HOLDS_SHADER_INT(x) (G_VALUE_HOLDS ((x), CLUTTER_TYPE_SHADER_INT)) - -/** - * CLUTTER_VALUE_HOLDS_SHADER_MATRIX: - * @x: a #GValue - * - * Evaluates to %TRUE if @x holds a #ClutterShaderMatrix. - */ -#define CLUTTER_VALUE_HOLDS_SHADER_MATRIX(x) (G_VALUE_HOLDS ((x), CLUTTER_TYPE_SHADER_MATRIX)) - -CLUTTER_EXPORT -GType clutter_shader_float_get_type (void) G_GNUC_CONST; -CLUTTER_EXPORT -GType clutter_shader_int_get_type (void) G_GNUC_CONST; -CLUTTER_EXPORT -GType clutter_shader_matrix_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -void clutter_value_set_shader_float (GValue *value, - gint size, - const gfloat *floats); -CLUTTER_EXPORT -void clutter_value_set_shader_int (GValue *value, - gint size, - const gint *ints); -CLUTTER_EXPORT -void clutter_value_set_shader_matrix (GValue *value, - gint size, - const gfloat *matrix); -CLUTTER_EXPORT -const gfloat * clutter_value_get_shader_float (const GValue *value, - gsize *length); -CLUTTER_EXPORT -const gint * clutter_value_get_shader_int (const GValue *value, - gsize *length); -CLUTTER_EXPORT -const gfloat * clutter_value_get_shader_matrix (const GValue *value, - gsize *length); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-snap-constraint.c b/mutter/clutter/clutter/clutter-snap-constraint.c deleted file mode 100644 index 2f59442..0000000 --- a/mutter/clutter/clutter/clutter-snap-constraint.c +++ /dev/null @@ -1,570 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterSnapConstraint: - * - * A constraint snapping two actors together - * - * #ClutterSnapConstraint is a constraint the snaps the edges of two - * actors together, expanding the actor's allocation if necessary. - * - * An offset can be applied to the constraint, to provide spacing. - */ - -#include "config.h" - -#include - -#include "clutter/clutter-snap-constraint.h" - -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-constraint.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-private.h" - - -struct _ClutterSnapConstraint -{ - ClutterConstraint parent_instance; - - ClutterActor *actor; - ClutterActor *source; - - ClutterSnapEdge from_edge; - ClutterSnapEdge to_edge; - - gfloat offset; -}; - -enum -{ - PROP_0, - - PROP_SOURCE, - PROP_FROM_EDGE, - PROP_TO_EDGE, - PROP_OFFSET, - - PROP_LAST -}; - -G_DEFINE_FINAL_TYPE (ClutterSnapConstraint, - clutter_snap_constraint, - CLUTTER_TYPE_CONSTRAINT); - -static GParamSpec *obj_props[PROP_LAST] = { NULL, }; - -static void -source_queue_relayout (ClutterActor *source, - ClutterSnapConstraint *constraint) -{ - if (constraint->actor != NULL) - _clutter_actor_queue_only_relayout (constraint->actor); -} - -static void -source_destroyed (ClutterActor *actor, - ClutterSnapConstraint *constraint) -{ - constraint->source = NULL; -} - -static inline void -warn_horizontal_edge (const gchar *edge, - ClutterActor *actor, - ClutterActor *source) -{ - g_warning (G_STRLOC ": the %s edge of actor '%s' can only be snapped " - "to either the right or the left edge of actor '%s'", - edge, - _clutter_actor_get_debug_name (actor), - _clutter_actor_get_debug_name (source)); -} - -static inline void -warn_vertical_edge (const gchar *edge, - ClutterActor *actor, - ClutterActor *source) -{ - g_warning (G_STRLOC ": the %s edge of actor '%s' can only " - "be snapped to the top or bottom edge of actor '%s'", - edge, - _clutter_actor_get_debug_name (actor), - _clutter_actor_get_debug_name (source)); -} - -static void -clutter_snap_constraint_update_allocation (ClutterConstraint *constraint, - ClutterActor *actor, - ClutterActorBox *allocation) -{ - ClutterSnapConstraint *self = CLUTTER_SNAP_CONSTRAINT (constraint); - gfloat source_width, source_height; - gfloat source_x, source_y; - gfloat actor_width, actor_height; - - if (self->source == NULL) - return; - - clutter_actor_get_position (self->source, &source_x, &source_y); - clutter_actor_get_size (self->source, &source_width, &source_height); - - clutter_actor_box_get_size (allocation, &actor_width, &actor_height); - - switch (self->to_edge) - { - case CLUTTER_SNAP_EDGE_LEFT: - if (self->from_edge == CLUTTER_SNAP_EDGE_LEFT) - allocation->x1 = source_x + self->offset; - else if (self->from_edge == CLUTTER_SNAP_EDGE_RIGHT) - allocation->x2 = source_x + self->offset; - else - warn_horizontal_edge ("left", self->actor, self->source); - break; - - case CLUTTER_SNAP_EDGE_RIGHT: - if (self->from_edge == CLUTTER_SNAP_EDGE_RIGHT) - allocation->x2 = source_x + source_width + self->offset; - else if (self->from_edge == CLUTTER_SNAP_EDGE_LEFT) - allocation->x1 = source_x + source_width + self->offset; - else - warn_horizontal_edge ("right", self->actor, self->source); - break; - - break; - - case CLUTTER_SNAP_EDGE_TOP: - if (self->from_edge == CLUTTER_SNAP_EDGE_TOP) - allocation->y1 = source_y + self->offset; - else if (self->from_edge == CLUTTER_SNAP_EDGE_BOTTOM) - allocation->y2 = source_y + self->offset; - else - warn_vertical_edge ("top", self->actor, self->source); - break; - - case CLUTTER_SNAP_EDGE_BOTTOM: - if (self->from_edge == CLUTTER_SNAP_EDGE_BOTTOM) - allocation->y2 = source_y + source_height + self->offset; - else if (self->from_edge == CLUTTER_SNAP_EDGE_TOP) - allocation->y1 = source_y + source_height + self->offset; - else - warn_vertical_edge ("bottom", self->actor, self->source); - break; - - default: - g_assert_not_reached (); - break; - } - - if (allocation->x2 - allocation->x1 < 0) - allocation->x2 = allocation->x1; - - if (allocation->y2 - allocation->y1 < 0) - allocation->y2 = allocation->y1; -} - -static void -clutter_snap_constraint_set_actor (ClutterActorMeta *meta, - ClutterActor *new_actor) -{ - ClutterSnapConstraint *self = CLUTTER_SNAP_CONSTRAINT (meta); - ClutterActorMetaClass *parent; - - /* store the pointer to the actor, for later use */ - self->actor = new_actor; - - parent = CLUTTER_ACTOR_META_CLASS (clutter_snap_constraint_parent_class); - parent->set_actor (meta, new_actor); -} - -static void -clutter_snap_constraint_dispose (GObject *gobject) -{ - ClutterSnapConstraint *snap = CLUTTER_SNAP_CONSTRAINT (gobject); - - if (snap->source != NULL) - { - g_signal_handlers_disconnect_by_func (snap->source, - G_CALLBACK (source_destroyed), - snap); - g_signal_handlers_disconnect_by_func (snap->source, - G_CALLBACK (source_queue_relayout), - snap); - snap->source = NULL; - } - - G_OBJECT_CLASS (clutter_snap_constraint_parent_class)->dispose (gobject); -} - -static void -clutter_snap_constraint_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterSnapConstraint *self = CLUTTER_SNAP_CONSTRAINT (gobject); - - switch (prop_id) - { - case PROP_SOURCE: - clutter_snap_constraint_set_source (self, g_value_get_object (value)); - break; - - case PROP_FROM_EDGE: - clutter_snap_constraint_set_edges (self, - g_value_get_enum (value), - self->to_edge); - break; - - case PROP_TO_EDGE: - clutter_snap_constraint_set_edges (self, - self->from_edge, - g_value_get_enum (value)); - break; - - case PROP_OFFSET: - clutter_snap_constraint_set_offset (self, g_value_get_float (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_snap_constraint_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterSnapConstraint *self = CLUTTER_SNAP_CONSTRAINT (gobject); - - switch (prop_id) - { - case PROP_SOURCE: - g_value_set_object (value, self->source); - break; - - case PROP_FROM_EDGE: - g_value_set_enum (value, self->from_edge); - break; - - case PROP_TO_EDGE: - g_value_set_enum (value, self->to_edge); - break; - - case PROP_OFFSET: - g_value_set_float (value, self->offset); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_snap_constraint_class_init (ClutterSnapConstraintClass *klass) -{ - ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); - ClutterConstraintClass *constraint_class = CLUTTER_CONSTRAINT_CLASS (klass); - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - meta_class->set_actor = clutter_snap_constraint_set_actor; - - constraint_class->update_allocation = clutter_snap_constraint_update_allocation; - /** - * ClutterSnapConstraint:source: - * - * The [class@Actor] used as the source for the constraint - */ - obj_props[PROP_SOURCE] = - g_param_spec_object ("source", NULL, NULL, - CLUTTER_TYPE_ACTOR, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT); - - /** - * ClutterSnapConstraint:from-edge: - * - * The edge of the [class@Actor] that should be snapped - */ - obj_props[PROP_FROM_EDGE] = - g_param_spec_enum ("from-edge", NULL, NULL, - CLUTTER_TYPE_SNAP_EDGE, - CLUTTER_SNAP_EDGE_RIGHT, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT); - - /** - * ClutterSnapConstraint:to-edge: - * - * The edge of the [property@SnapConstraint:source] that should be snapped - */ - obj_props[PROP_TO_EDGE] = - g_param_spec_enum ("to-edge", NULL, NULL, - CLUTTER_TYPE_SNAP_EDGE, - CLUTTER_SNAP_EDGE_RIGHT, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT); - - /** - * ClutterSnapConstraint:offset: - * - * The offset, in pixels, between [property@SnapConstraint:from-edge] - * and [property@SnapConstraint:to-edge] - */ - obj_props[PROP_OFFSET] = - g_param_spec_float ("offset", NULL, NULL, - -G_MAXFLOAT, G_MAXFLOAT, - 0.0f, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT); - - gobject_class->dispose = clutter_snap_constraint_dispose; - gobject_class->set_property = clutter_snap_constraint_set_property; - gobject_class->get_property = clutter_snap_constraint_get_property; - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); -} - -static void -clutter_snap_constraint_init (ClutterSnapConstraint *self) -{ - self->actor = NULL; - self->source = NULL; - - self->from_edge = CLUTTER_SNAP_EDGE_RIGHT; - self->to_edge = CLUTTER_SNAP_EDGE_RIGHT; - - self->offset = 0.0f; -} - -/** - * clutter_snap_constraint_new: - * @source: (allow-none): the #ClutterActor to use as the source of - * the constraint, or %NULL - * @from_edge: the edge of the actor to use in the constraint - * @to_edge: the edge of @source to use in the constraint - * @offset: the offset to apply to the constraint, in pixels - * - * Creates a new #ClutterSnapConstraint that will snap a [class@Actor] - * to the @edge of @source, with the given @offset. - * - * Return value: the newly created #ClutterSnapConstraint - */ -ClutterConstraint * -clutter_snap_constraint_new (ClutterActor *source, - ClutterSnapEdge from_edge, - ClutterSnapEdge to_edge, - gfloat offset) -{ - g_return_val_if_fail (source == NULL || CLUTTER_IS_ACTOR (source), NULL); - - return g_object_new (CLUTTER_TYPE_SNAP_CONSTRAINT, - "source", source, - "from-edge", from_edge, - "to-edge", to_edge, - "offset", offset, - NULL); -} - -/** - * clutter_snap_constraint_set_source: - * @constraint: a #ClutterSnapConstraint - * @source: (allow-none): a #ClutterActor, or %NULL to unset the source - * - * Sets the source [class@Actor] for the constraint - */ -void -clutter_snap_constraint_set_source (ClutterSnapConstraint *constraint, - ClutterActor *source) -{ - ClutterActor *old_source; - - g_return_if_fail (CLUTTER_IS_SNAP_CONSTRAINT (constraint)); - g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source)); - - if (constraint->source == source) - return; - - old_source = constraint->source; - if (old_source != NULL) - { - g_signal_handlers_disconnect_by_func (old_source, - G_CALLBACK (source_destroyed), - constraint); - g_signal_handlers_disconnect_by_func (old_source, - G_CALLBACK (source_queue_relayout), - constraint); - } - - constraint->source = source; - if (constraint->source != NULL) - { - g_signal_connect (constraint->source, "queue-relayout", - G_CALLBACK (source_queue_relayout), - constraint); - g_signal_connect (constraint->source, "destroy", - G_CALLBACK (source_destroyed), - constraint); - - if (constraint->actor != NULL) - clutter_actor_queue_relayout (constraint->actor); - } - - g_object_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_SOURCE]); -} - -/** - * clutter_snap_constraint_get_source: - * @constraint: a #ClutterSnapConstraint - * - * Retrieves the [class@Actor] set using [method@SnapConstraint.set_source] - * - * Return value: (transfer none): a pointer to the source actor - */ -ClutterActor * -clutter_snap_constraint_get_source (ClutterSnapConstraint *constraint) -{ - g_return_val_if_fail (CLUTTER_IS_SNAP_CONSTRAINT (constraint), NULL); - - return constraint->source; -} - -/** - * clutter_snap_constraint_set_edges: - * @constraint: a #ClutterSnapConstraint - * @from_edge: the edge on the actor - * @to_edge: the edge on the source - * - * Sets the edges to be used by the @constraint - * - * The @from_edge is the edge on the [class@Actor] to which @constraint - * has been added. The @to_edge is the edge of the [class@Actor] inside - * the [property@SnapConstraint:source] property. - */ -void -clutter_snap_constraint_set_edges (ClutterSnapConstraint *constraint, - ClutterSnapEdge from_edge, - ClutterSnapEdge to_edge) -{ - gboolean from_changed = FALSE, to_changed = FALSE; - - g_return_if_fail (CLUTTER_IS_SNAP_CONSTRAINT (constraint)); - - g_object_freeze_notify (G_OBJECT (constraint)); - - if (constraint->from_edge != from_edge) - { - constraint->from_edge = from_edge; - g_object_notify_by_pspec (G_OBJECT (constraint), - obj_props[PROP_FROM_EDGE]); - from_changed = TRUE; - } - - if (constraint->to_edge != to_edge) - { - constraint->to_edge = to_edge; - g_object_notify_by_pspec (G_OBJECT (constraint), - obj_props[PROP_TO_EDGE]); - to_changed = TRUE; - } - - if ((from_changed || to_changed) && - constraint->actor != NULL) - { - clutter_actor_queue_relayout (constraint->actor); - } - - g_object_thaw_notify (G_OBJECT (constraint)); -} - -/** - * clutter_snap_constraint_get_edges: - * @constraint: a #ClutterSnapConstraint - * @from_edge: (out): return location for the actor's edge, or %NULL - * @to_edge: (out): return location for the source's edge, or %NULL - * - * Retrieves the edges used by the @constraint - */ -void -clutter_snap_constraint_get_edges (ClutterSnapConstraint *constraint, - ClutterSnapEdge *from_edge, - ClutterSnapEdge *to_edge) -{ - g_return_if_fail (CLUTTER_IS_SNAP_CONSTRAINT (constraint)); - - if (from_edge) - *from_edge = constraint->from_edge; - - if (to_edge) - *to_edge = constraint->to_edge; -} - -/** - * clutter_snap_constraint_set_offset: - * @constraint: a #ClutterSnapConstraint - * @offset: the offset to apply, in pixels - * - * Sets the offset to be applied to the constraint - */ -void -clutter_snap_constraint_set_offset (ClutterSnapConstraint *constraint, - gfloat offset) -{ - g_return_if_fail (CLUTTER_IS_SNAP_CONSTRAINT (constraint)); - - if (fabs (constraint->offset - offset) < 0.00001f) - return; - - constraint->offset = offset; - - if (constraint->actor != NULL) - clutter_actor_queue_relayout (constraint->actor); - - g_object_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_OFFSET]); -} - -/** - * clutter_snap_constraint_get_offset: - * @constraint: a #ClutterSnapConstraint - * - * Retrieves the offset set using [method@SnapConstraint.set_offset] - * - * Return value: the offset, in pixels - */ -gfloat -clutter_snap_constraint_get_offset (ClutterSnapConstraint *constraint) -{ - g_return_val_if_fail (CLUTTER_IS_SNAP_CONSTRAINT (constraint), 0.0); - - return constraint->offset; -} diff --git a/mutter/clutter/clutter/clutter-snap-constraint.h b/mutter/clutter/clutter/clutter-snap-constraint.h deleted file mode 100644 index 4f35fca..0000000 --- a/mutter/clutter/clutter/clutter-snap-constraint.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-constraint.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_SNAP_CONSTRAINT (clutter_snap_constraint_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_FINAL_TYPE (ClutterSnapConstraint, clutter_snap_constraint, - CLUTTER, SNAP_CONSTRAINT, ClutterConstraint) - -CLUTTER_EXPORT -ClutterConstraint * clutter_snap_constraint_new (ClutterActor *source, - ClutterSnapEdge from_edge, - ClutterSnapEdge to_edge, - gfloat offset); - -CLUTTER_EXPORT -void clutter_snap_constraint_set_source (ClutterSnapConstraint *constraint, - ClutterActor *source); -CLUTTER_EXPORT -ClutterActor * clutter_snap_constraint_get_source (ClutterSnapConstraint *constraint); -CLUTTER_EXPORT -void clutter_snap_constraint_set_edges (ClutterSnapConstraint *constraint, - ClutterSnapEdge from_edge, - ClutterSnapEdge to_edge); -CLUTTER_EXPORT -void clutter_snap_constraint_get_edges (ClutterSnapConstraint *constraint, - ClutterSnapEdge *from_edge, - ClutterSnapEdge *to_edge); -CLUTTER_EXPORT -void clutter_snap_constraint_set_offset (ClutterSnapConstraint *constraint, - gfloat offset); -CLUTTER_EXPORT -gfloat clutter_snap_constraint_get_offset (ClutterSnapConstraint *constraint); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-stage-manager-private.h b/mutter/clutter/clutter/clutter-stage-manager-private.h deleted file mode 100644 index 9748c96..0000000 --- a/mutter/clutter/clutter/clutter-stage-manager-private.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#include "clutter/clutter-stage-manager.h" - -G_BEGIN_DECLS - -/* stage manager */ -void _clutter_stage_manager_add_stage (ClutterStageManager *stage_manager, - ClutterStage *stage); -void _clutter_stage_manager_remove_stage (ClutterStageManager *stage_manager, - ClutterStage *stage); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-stage-manager.c b/mutter/clutter/clutter/clutter-stage-manager.c deleted file mode 100644 index ecf0012..0000000 --- a/mutter/clutter/clutter/clutter-stage-manager.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2008 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -/** - * ClutterStageManager: - * - * Maintains the list of stages - * - * #ClutterStageManager is a singleton object, owned by Clutter, which - * maintains the list of currently active stages - * - * Every newly-created [class@Stage] will cause the emission of the - * [signal@StageManager::stage-added] signal; once a [class@Stage] has - * been destroyed, the [signal@StageManager::stage-removed] signal will - * be emitted - */ - -#include "config.h" - -#include "clutter/clutter-stage-manager-private.h" - -#include "clutter/clutter-context-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-private.h" - -enum -{ - PROP_0, - PROP_DEFAULT_STAGE -}; - -enum -{ - STAGE_ADDED, - STAGE_REMOVED, - - LAST_SIGNAL -}; - -static guint manager_signals[LAST_SIGNAL] = { 0, }; -static ClutterStage *default_stage = NULL; - -typedef struct _ClutterStageManagerPrivate -{ - GSList *stages; -} ClutterStageManagerPrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterStageManager, - clutter_stage_manager, - G_TYPE_OBJECT); - -static void -clutter_stage_manager_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) - { - case PROP_DEFAULT_STAGE: - g_value_set_object (value, default_stage); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_stage_manager_dispose (GObject *gobject) -{ - ClutterStageManager *stage_manager = CLUTTER_STAGE_MANAGER (gobject); - ClutterStageManagerPrivate *priv = - clutter_stage_manager_get_instance_private (stage_manager); - - g_slist_free_full (priv->stages, - (GDestroyNotify) clutter_actor_destroy); - priv->stages = NULL; - - G_OBJECT_CLASS (clutter_stage_manager_parent_class)->dispose (gobject); -} - -static void -clutter_stage_manager_class_init (ClutterStageManagerClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->dispose = clutter_stage_manager_dispose; - gobject_class->get_property = clutter_stage_manager_get_property; - - /** - * ClutterStageManager:default-stage: - * - * The default stage used by Clutter. - */ - g_object_class_install_property (gobject_class, - PROP_DEFAULT_STAGE, - g_param_spec_object ("default-stage", NULL, NULL, - CLUTTER_TYPE_STAGE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * ClutterStageManager::stage-added: - * @stage_manager: the object which received the signal - * @stage: the added stage - * - * The signal is emitted each time a new #ClutterStage - * has been added to the stage manager. - */ - manager_signals[STAGE_ADDED] = - g_signal_new ("stage-added", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterStageManagerClass, stage_added), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_STAGE); - /** - * ClutterStageManager::stage-removed: - * @stage_manager: the object which received the signal - * @stage: the removed stage - * - * The signal is emitted each time a #ClutterStage - * has been removed from the stage manager. - */ - manager_signals[STAGE_REMOVED] = - g_signal_new ("stage-removed", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterStageManagerClass, stage_removed), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_STAGE); -} - -static void -clutter_stage_manager_init (ClutterStageManager *stage_manager) -{ -} - -/** - * clutter_stage_manager_get_default: - * - * Returns the default #ClutterStageManager. - * - * Return value: (transfer none): the default stage manager instance. The returned - * object is owned by Clutter and you should not reference or unreference it. - */ -ClutterStageManager * -clutter_stage_manager_get_default (void) -{ - ClutterContext *context = _clutter_context_get_default (); - - if (G_UNLIKELY (context->stage_manager == NULL)) - context->stage_manager = g_object_new (CLUTTER_TYPE_STAGE_MANAGER, NULL); - - return context->stage_manager; -} - -/** - * clutter_stage_manager_get_default_stage: - * @stage_manager: a #ClutterStageManager - * - * Returns the default #ClutterStage. - * - * Return value: (transfer none): the default stage. The returned object - * is owned by Clutter and you should never reference or unreference it - */ -ClutterStage * -clutter_stage_manager_get_default_stage (ClutterStageManager *stage_manager) -{ - return default_stage; -} - -/** - * clutter_stage_manager_list_stages: - * @stage_manager: a #ClutterStageManager - * - * Lists all currently used stages. - * - * Return value: (transfer container) (element-type Clutter.Stage): a newly - * allocated list of #ClutterStage objects. Use g_slist_free() to - * deallocate it when done. - */ -GSList * -clutter_stage_manager_list_stages (ClutterStageManager *stage_manager) -{ - ClutterStageManagerPrivate *priv = - clutter_stage_manager_get_instance_private (stage_manager); - - return g_slist_copy (priv->stages); -} - -/** - * clutter_stage_manager_peek_stages: - * @stage_manager: a #ClutterStageManager - * - * Lists all currently used stages. - * - * Return value: (transfer none) (element-type Clutter.Stage): a pointer - * to the internal list of #ClutterStage objects. The returned list - * is owned by the #ClutterStageManager and should never be modified - * or freed - */ -const GSList * -clutter_stage_manager_peek_stages (ClutterStageManager *stage_manager) -{ - ClutterStageManagerPrivate *priv = - clutter_stage_manager_get_instance_private (stage_manager); - - return priv->stages; -} - -void -_clutter_stage_manager_add_stage (ClutterStageManager *stage_manager, - ClutterStage *stage) -{ - ClutterStageManagerPrivate *priv = - clutter_stage_manager_get_instance_private (stage_manager); - if (g_slist_find (priv->stages, stage)) - { - g_warning ("Trying to add a stage to the list of managed stages, " - "but it is already in it, aborting."); - return; - } - - g_object_ref_sink (stage); - - priv->stages = g_slist_append (priv->stages, stage); - - g_signal_emit (stage_manager, manager_signals[STAGE_ADDED], 0, stage); -} - -void -_clutter_stage_manager_remove_stage (ClutterStageManager *stage_manager, - ClutterStage *stage) -{ - ClutterStageManagerPrivate *priv = - clutter_stage_manager_get_instance_private (stage_manager); - /* this might be called multiple times from a ::dispose, so it - * needs to just return without warning - */ - if (!g_slist_find (priv->stages, stage)) - return; - - priv->stages = g_slist_remove (priv->stages, stage); - - /* if the default stage is being destroyed then we unset the pointer */ - if (default_stage == stage) - default_stage = NULL; - - g_signal_emit (stage_manager, manager_signals[STAGE_REMOVED], 0, stage); - - g_object_unref (stage); -} diff --git a/mutter/clutter/clutter/clutter-stage-manager.h b/mutter/clutter/clutter/clutter-stage-manager.h deleted file mode 100644 index c2897c5..0000000 --- a/mutter/clutter/clutter/clutter-stage-manager.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2008 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_STAGE_MANAGER (clutter_stage_manager_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterStageManager, - clutter_stage_manager, - CLUTTER, - STAGE_MANAGER, - GObject) - -/** - * ClutterStageManagerClass: - * - * The #ClutterStageManagerClass structure contains only private data - * and should be accessed using the provided API - */ -struct _ClutterStageManagerClass -{ - /*< private >*/ - GObjectClass parent_class; - - void (* stage_added) (ClutterStageManager *stage_manager, - ClutterStage *stage); - void (* stage_removed) (ClutterStageManager *stage_manager, - ClutterStage *stage); -}; - -CLUTTER_EXPORT -ClutterStageManager *clutter_stage_manager_get_default (void); -CLUTTER_EXPORT -ClutterStage * clutter_stage_manager_get_default_stage (ClutterStageManager *stage_manager); -CLUTTER_EXPORT -GSList * clutter_stage_manager_list_stages (ClutterStageManager *stage_manager); -CLUTTER_EXPORT -const GSList * clutter_stage_manager_peek_stages (ClutterStageManager *stage_manager); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-stage-private.h b/mutter/clutter/clutter/clutter-stage-private.h deleted file mode 100644 index 0701079..0000000 --- a/mutter/clutter/clutter/clutter-stage-private.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#include "clutter/clutter-grab.h" -#include "clutter/clutter-stage-window.h" -#include "clutter/clutter-stage.h" -#include "clutter/clutter-input-device.h" -#include "clutter/clutter-private.h" - -#include "cogl/cogl.h" - -G_BEGIN_DECLS - -typedef gboolean (* ClutterEventHandler) (const ClutterEvent *event, - gpointer user_data); -typedef enum -{ - CLUTTER_DEVICE_UPDATE_NONE = 0, - CLUTTER_DEVICE_UPDATE_EMIT_CROSSING = 1 << 0, - CLUTTER_DEVICE_UPDATE_IGNORE_CACHE = 1 << 1, -} ClutterDeviceUpdateFlags; - -/* stage */ -CLUTTER_EXPORT -void clutter_stage_paint_view (ClutterStage *stage, - ClutterStageView *view, - const MtkRegion *redraw_clip, - ClutterFrame *frame); - -void clutter_stage_emit_before_update (ClutterStage *stage, - ClutterStageView *view, - ClutterFrame *frame); -void clutter_stage_emit_prepare_frame (ClutterStage *stage, - ClutterStageView *view, - ClutterFrame *frame); -void clutter_stage_emit_before_paint (ClutterStage *stage, - ClutterStageView *view, - ClutterFrame *frame); -void clutter_stage_emit_after_paint (ClutterStage *stage, - ClutterStageView *view, - ClutterFrame *frame); -void clutter_stage_after_update (ClutterStage *stage, - ClutterStageView *view, - ClutterFrame *frame); - -CLUTTER_EXPORT -void _clutter_stage_set_window (ClutterStage *stage, - ClutterStageWindow *stage_window); -CLUTTER_EXPORT -ClutterStageWindow *_clutter_stage_get_window (ClutterStage *stage); -void _clutter_stage_get_projection_matrix (ClutterStage *stage, - graphene_matrix_t *projection); -void _clutter_stage_dirty_projection (ClutterStage *stage); -void _clutter_stage_get_viewport (ClutterStage *stage, - float *x, - float *y, - float *width, - float *height); -void _clutter_stage_dirty_viewport (ClutterStage *stage); -CLUTTER_EXPORT -void _clutter_stage_maybe_setup_viewport (ClutterStage *stage, - ClutterStageView *view); -void clutter_stage_maybe_relayout (ClutterActor *stage); -void clutter_stage_finish_layout (ClutterStage *stage); - -CLUTTER_EXPORT -void _clutter_stage_queue_event (ClutterStage *stage, - ClutterEvent *event, - gboolean copy_event); -void _clutter_stage_process_queued_events (ClutterStage *stage); - -void clutter_stage_presented (ClutterStage *stage, - ClutterStageView *view, - ClutterFrameInfo *frame_info); - -void clutter_stage_queue_actor_relayout (ClutterStage *stage, - ClutterActor *actor); - -void clutter_stage_dequeue_actor_relayout (ClutterStage *stage, - ClutterActor *actor); - -GList * clutter_stage_get_views_for_rect (ClutterStage *stage, - const graphene_rect_t *rect); - -void clutter_stage_set_actor_needs_immediate_relayout (ClutterStage *stage); - -void clutter_stage_remove_device_entry (ClutterStage *self, - ClutterInputDevice *device, - ClutterEventSequence *sequence); - -void clutter_stage_unlink_grab (ClutterStage *self, - ClutterGrab *grab); - -void clutter_stage_invalidate_focus (ClutterStage *self, - ClutterActor *actor); - -void clutter_stage_maybe_invalidate_focus (ClutterStage *self, - ClutterActor *actor); - -void clutter_stage_emit_event (ClutterStage *self, - const ClutterEvent *event); - -void clutter_stage_maybe_lost_implicit_grab (ClutterStage *self, - ClutterInputDevice *device, - ClutterEventSequence *sequence); - -void clutter_stage_implicit_grab_actor_unmapped (ClutterStage *self, - ClutterActor *actor); - -CLUTTER_EXPORT_TEST -void clutter_stage_notify_action_implicit_grab (ClutterStage *self, - ClutterInputDevice *device, - ClutterEventSequence *sequence); - -void clutter_stage_add_to_redraw_clip (ClutterStage *self, - ClutterPaintVolume *clip); - -CLUTTER_EXPORT -ClutterGrab * clutter_stage_grab_input_only_inactive (ClutterStage *self, - ClutterEventHandler handler, - gpointer user_data, - GDestroyNotify user_data_destroy); - -void clutter_stage_invalidate_devices (ClutterStage *stage); - -GPtrArray * clutter_stage_get_active_gestures_array (ClutterStage *self); - -ClutterActor * clutter_stage_update_device_for_event (ClutterStage *stage, - ClutterEvent *event); - -void clutter_stage_update_devices_in_view (ClutterStage *stage, - ClutterStageView *view); - -CLUTTER_EXPORT -ClutterGrab * clutter_stage_grab_inactive (ClutterStage *stage, - ClutterActor *actor); - -CLUTTER_EXPORT -void clutter_grab_activate (ClutterGrab *grab); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-stage-view-private.h b/mutter/clutter/clutter/clutter-stage-view-private.h deleted file mode 100644 index 98f2f7f..0000000 --- a/mutter/clutter/clutter/clutter-stage-view-private.h +++ /dev/null @@ -1,83 +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 . - */ - -#pragma once - -#include "clutter/clutter-stage-view.h" -#include "clutter/clutter-types.h" -#include "mtk/mtk.h" - -CLUTTER_EXPORT -void clutter_stage_view_after_paint (ClutterStageView *view, - MtkRegion *redraw_clip); - -CLUTTER_EXPORT -void clutter_stage_view_before_swap_buffer (ClutterStageView *view, - const MtkRegion *swap_region); - -gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view); - -void clutter_stage_view_invalidate_viewport (ClutterStageView *view); - -void clutter_stage_view_set_viewport (ClutterStageView *view, - float x, - float y, - float width, - float height); - -gboolean clutter_stage_view_is_dirty_projection (ClutterStageView *view); - -void clutter_stage_view_invalidate_projection (ClutterStageView *view); - -void clutter_stage_view_set_projection (ClutterStageView *view, - const graphene_matrix_t *matrix); - -CLUTTER_EXPORT -void clutter_stage_view_add_redraw_clip (ClutterStageView *view, - const MtkRectangle *clip); - -gboolean clutter_stage_view_has_full_redraw_clip (ClutterStageView *view); - -gboolean clutter_stage_view_has_redraw_clip (ClutterStageView *view); - -CLUTTER_EXPORT -MtkRegion * clutter_stage_view_take_accumulated_redraw_clip (ClutterStageView *view); - -CLUTTER_EXPORT -void clutter_stage_view_accumulate_redraw_clip (ClutterStageView *view); - -CLUTTER_EXPORT -CoglScanout * clutter_stage_view_take_scanout (ClutterStageView *view); - -CLUTTER_EXPORT -void clutter_stage_view_transform_rect_to_onscreen (ClutterStageView *view, - const MtkRectangle *src_rect, - int dst_width, - int dst_height, - MtkRectangle *dst_rect); - -CLUTTER_EXPORT -void clutter_stage_view_schedule_update (ClutterStageView *view); - -CLUTTER_EXPORT -void clutter_stage_view_notify_presented (ClutterStageView *view, - ClutterFrameInfo *frame_info); - -CLUTTER_EXPORT -void clutter_stage_view_notify_ready (ClutterStageView *view); - -void clutter_stage_view_invalidate_input_devices (ClutterStageView *view); diff --git a/mutter/clutter/clutter/clutter-stage-view.c b/mutter/clutter/clutter/clutter-stage-view.c deleted file mode 100644 index f5188e2..0000000 --- a/mutter/clutter/clutter/clutter-stage-view.c +++ /dev/null @@ -1,1258 +0,0 @@ -/* - * Copyright (C) 2016 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 . - */ - -#include "config.h" - -#define COGL_DISABLE_DEPRECATION_WARNINGS - -#include "clutter/clutter-stage-view.h" -#include "clutter/clutter-stage-view-private.h" - -#include - -#include "clutter/clutter-damage-history.h" -#include "clutter/clutter-frame-clock.h" -#include "clutter/clutter-frame-private.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-mutter.h" -#include "clutter/clutter-stage-private.h" -#include "cogl/cogl.h" - -enum -{ - PROP_0, - - PROP_NAME, - PROP_STAGE, - PROP_LAYOUT, - PROP_FRAMEBUFFER, - PROP_OFFSCREEN, - PROP_USE_SHADOWFB, - PROP_SCALE, - PROP_REFRESH_RATE, - PROP_VBLANK_DURATION_US, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -enum -{ - DESTROY, - N_SIGNALS -}; - -guint stage_view_signals[N_SIGNALS] = { 0 }; - -typedef struct _ClutterStageViewPrivate -{ - char *name; - - ClutterStage *stage; - - MtkRectangle layout; - float scale; - CoglFramebuffer *framebuffer; - - CoglOffscreen *offscreen; - CoglPipeline *offscreen_pipeline; - - gboolean use_shadowfb; - struct { - CoglOffscreen *framebuffer; - } shadow; - - CoglScanout *next_scanout; - - gboolean has_redraw_clip; - MtkRegion *redraw_clip; - gboolean has_accumulated_redraw_clip; - MtkRegion *accumulated_redraw_clip; - - float refresh_rate; - int64_t vblank_duration_us; - ClutterFrameClock *frame_clock; - - struct { - int frame_count; - int64_t last_print_time_us; - int64_t cumulative_draw_time_us; - int64_t began_draw_time_us; - int64_t worst_draw_time_us; - } frame_timings; - - guint dirty_viewport : 1; - guint dirty_projection : 1; - guint needs_update_devices : 1; -} ClutterStageViewPrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterStageView, clutter_stage_view, G_TYPE_OBJECT) - -void -clutter_stage_view_destroy (ClutterStageView *view) -{ - g_object_run_dispose (G_OBJECT (view)); - g_object_unref (view); -} - -void -clutter_stage_view_get_layout (ClutterStageView *view, - MtkRectangle *rect) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - *rect = priv->layout; -} - -/** - * clutter_stage_view_get_framebuffer: - * @view: a #ClutterStageView - * - * Retrieves the framebuffer of @view to draw to. - * - * Returns: (transfer none): a #CoglFramebuffer - */ -CoglFramebuffer * -clutter_stage_view_get_framebuffer (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - if (priv->offscreen) - return COGL_FRAMEBUFFER (priv->offscreen); - else if (priv->shadow.framebuffer) - return COGL_FRAMEBUFFER (priv->shadow.framebuffer); - else - return priv->framebuffer; -} - -/** - * clutter_stage_view_get_onscreen: - * @view: a #ClutterStageView - * - * Retrieves the onscreen framebuffer of @view if available. - * - * Returns: (transfer none): a #CoglFramebuffer - */ -CoglFramebuffer * -clutter_stage_view_get_onscreen (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - return priv->framebuffer; -} - -static CoglPipeline * -clutter_stage_view_create_offscreen_pipeline (CoglOffscreen *offscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (offscreen); - CoglPipeline *pipeline; - - pipeline = cogl_pipeline_new (cogl_framebuffer_get_context (framebuffer)); - - cogl_pipeline_set_layer_filters (pipeline, 0, - COGL_PIPELINE_FILTER_NEAREST, - COGL_PIPELINE_FILTER_NEAREST); - cogl_pipeline_set_layer_texture (pipeline, 0, - cogl_offscreen_get_texture (offscreen)); - cogl_pipeline_set_layer_wrap_mode (pipeline, 0, - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); - - return pipeline; -} - -static void -clutter_stage_view_ensure_offscreen_blit_pipeline (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - ClutterStageViewClass *view_class = - CLUTTER_STAGE_VIEW_GET_CLASS (view); - - g_assert (priv->offscreen != NULL); - - if (priv->offscreen_pipeline) - return; - - priv->offscreen_pipeline = - clutter_stage_view_create_offscreen_pipeline (priv->offscreen); - - if (view_class->setup_offscreen_transform) - view_class->setup_offscreen_transform (view, priv->offscreen_pipeline); -} - -void -clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - g_clear_object (&priv->offscreen_pipeline); -} - -void -clutter_stage_view_transform_rect_to_onscreen (ClutterStageView *view, - const MtkRectangle *src_rect, - int dst_width, - int dst_height, - MtkRectangle *dst_rect) -{ - ClutterStageViewClass *view_class = CLUTTER_STAGE_VIEW_GET_CLASS (view); - - view_class->transform_rect_to_onscreen (view, - src_rect, - dst_width, - dst_height, - dst_rect); -} - -static void -paint_transformed_framebuffer (ClutterStageView *view, - CoglPipeline *pipeline, - CoglOffscreen *src_framebuffer, - CoglFramebuffer *dst_framebuffer, - const MtkRegion *redraw_clip) -{ - graphene_matrix_t matrix; - unsigned int n_rectangles, i; - int dst_width, dst_height; - MtkRectangle view_layout; - MtkRectangle onscreen_layout; - float view_scale; - float *coordinates; - - dst_width = cogl_framebuffer_get_width (dst_framebuffer); - dst_height = cogl_framebuffer_get_height (dst_framebuffer); - clutter_stage_view_get_layout (view, &view_layout); - clutter_stage_view_transform_rect_to_onscreen (view, - &MTK_RECTANGLE_INIT (0, 0, - view_layout.width, view_layout.height), - view_layout.width, - view_layout.height, - &onscreen_layout); - view_scale = clutter_stage_view_get_scale (view); - - cogl_framebuffer_push_matrix (dst_framebuffer); - - graphene_matrix_init_translate (&matrix, - &GRAPHENE_POINT3D_INIT (-dst_width / 2.0, - -dst_height / 2.0, - 0.f)); - graphene_matrix_scale (&matrix, - 1.0 / (dst_width / 2.0), - -1.0 / (dst_height / 2.0), - 0.f); - cogl_framebuffer_set_projection_matrix (dst_framebuffer, &matrix); - cogl_framebuffer_set_viewport (dst_framebuffer, - 0, 0, dst_width, dst_height); - - n_rectangles = mtk_region_num_rectangles (redraw_clip); - coordinates = g_newa (float, 2 * 4 * n_rectangles); - - for (i = 0; i < n_rectangles; i++) - { - MtkRectangle src_rect; - MtkRectangle dst_rect; - - src_rect = mtk_region_get_rectangle (redraw_clip, i); - src_rect.x -= view_layout.x; - src_rect.y -= view_layout.y; - - clutter_stage_view_transform_rect_to_onscreen (view, - &src_rect, - onscreen_layout.width, - onscreen_layout.height, - &dst_rect); - - coordinates[i * 8 + 0] = (float) dst_rect.x * view_scale; - coordinates[i * 8 + 1] = (float) dst_rect.y * view_scale; - coordinates[i * 8 + 2] = ((float) (dst_rect.x + dst_rect.width) * - view_scale); - coordinates[i * 8 + 3] = ((float) (dst_rect.y + dst_rect.height) * - view_scale); - - coordinates[i * 8 + 4] = (((float) dst_rect.x / (float) dst_width) * - view_scale); - coordinates[i * 8 + 5] = (((float) dst_rect.y / (float) dst_height) * - view_scale); - coordinates[i * 8 + 6] = ((float) (dst_rect.x + dst_rect.width) / - (float) dst_width) * view_scale; - coordinates[i * 8 + 7] = ((float) (dst_rect.y + dst_rect.height) / - (float) dst_height) * view_scale; - } - - cogl_framebuffer_draw_textured_rectangles (dst_framebuffer, - pipeline, - coordinates, - n_rectangles); - - cogl_framebuffer_pop_matrix (dst_framebuffer); -} - -static CoglOffscreen * -create_offscreen_framebuffer (ClutterStageView *view, - int width, - int height, - GError **error) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - CoglContext *cogl_context; - CoglOffscreen *framebuffer; - CoglTexture *texture; - - cogl_context = cogl_framebuffer_get_context (priv->framebuffer); - texture = cogl_texture_2d_new_with_size (cogl_context, width, height); - cogl_primitive_texture_set_auto_mipmap (texture, FALSE); - - if (!cogl_texture_allocate (texture, error)) - { - g_object_unref (texture); - return FALSE; - } - - framebuffer = cogl_offscreen_new_with_texture (texture); - g_object_unref (texture); - if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (framebuffer), error)) - { - g_object_unref (framebuffer); - return FALSE; - } - - return framebuffer; -} - -static void -init_shadowfb (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - g_autoptr (GError) error = NULL; - int width; - int height; - CoglOffscreen *offscreen; - - width = cogl_framebuffer_get_width (priv->framebuffer); - height = cogl_framebuffer_get_height (priv->framebuffer); - - offscreen = create_offscreen_framebuffer (view, width, height, &error); - if (!offscreen) - { - g_warning ("Failed to create shadow framebuffer: %s", error->message); - return; - } - - priv->shadow.framebuffer = offscreen; - return; -} - -void -clutter_stage_view_after_paint (ClutterStageView *view, - MtkRegion *redraw_clip) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - if (priv->offscreen) - { - clutter_stage_view_ensure_offscreen_blit_pipeline (view); - - if (priv->shadow.framebuffer) - { - CoglFramebuffer *shadowfb = - COGL_FRAMEBUFFER (priv->shadow.framebuffer); - - paint_transformed_framebuffer (view, - priv->offscreen_pipeline, - priv->offscreen, - shadowfb, - redraw_clip); - } - else - { - paint_transformed_framebuffer (view, - priv->offscreen_pipeline, - priv->offscreen, - priv->framebuffer, - redraw_clip); - } - } -} - -static void -copy_shadowfb_to_onscreen (ClutterStageView *view, - const MtkRegion *swap_region) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - g_autoptr (MtkRegion) damage_region = NULL; - int i; - - if (mtk_region_is_empty (swap_region)) - { - MtkRectangle full_damage = { - .width = cogl_framebuffer_get_width (priv->framebuffer), - .height = cogl_framebuffer_get_height (priv->framebuffer), - }; - damage_region = mtk_region_create_rectangle (&full_damage); - } - else - { - damage_region = mtk_region_copy (swap_region); - } - - for (i = 0; i < mtk_region_num_rectangles (damage_region); i++) - { - CoglFramebuffer *shadowfb = COGL_FRAMEBUFFER (priv->shadow.framebuffer); - g_autoptr (GError) error = NULL; - MtkRectangle rect; - - rect = mtk_region_get_rectangle (damage_region, i); - - if (!cogl_blit_framebuffer (shadowfb, - priv->framebuffer, - rect.x, rect.y, - rect.x, rect.y, - rect.width, rect.height, - &error)) - { - g_warning ("Failed to blit shadow buffer: %s", error->message); - return; - } - } -} - -void -clutter_stage_view_before_swap_buffer (ClutterStageView *view, - const MtkRegion *swap_region) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - COGL_TRACE_BEGIN_SCOPED (BeforeSwap, - "Clutter::StageView::before_swap_buffer()"); - - if (priv->shadow.framebuffer) - copy_shadowfb_to_onscreen (view, swap_region); -} - -float -clutter_stage_view_get_scale (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - return priv->scale; -} - -typedef void (*FrontBufferCallback) (CoglFramebuffer *framebuffer, - gconstpointer user_data); - -static void -clutter_stage_view_foreach_front_buffer (ClutterStageView *view, - FrontBufferCallback callback, - gconstpointer user_data) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - if (priv->offscreen) - { - callback (COGL_FRAMEBUFFER (priv->offscreen), user_data); - } - else if (priv->shadow.framebuffer) - { - callback (COGL_FRAMEBUFFER (priv->shadow.framebuffer), user_data); - } - else - { - callback (priv->framebuffer, user_data); - } -} - -gboolean -clutter_stage_view_is_dirty_viewport (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - return priv->dirty_viewport; -} - -void -clutter_stage_view_invalidate_viewport (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - priv->dirty_viewport = TRUE; -} - -static void -set_framebuffer_viewport (CoglFramebuffer *framebuffer, - gconstpointer user_data) -{ - const graphene_rect_t *rect = user_data; - - cogl_framebuffer_set_viewport (framebuffer, - rect->origin.x, - rect->origin.y, - rect->size.width, - rect->size.height); -} - -void -clutter_stage_view_set_viewport (ClutterStageView *view, - float x, - float y, - float width, - float height) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - graphene_rect_t rect; - - priv->dirty_viewport = FALSE; - - rect = (graphene_rect_t) { - .origin = { .x = x, .y = y }, - .size = { .width = width, .height = height }, - }; - clutter_stage_view_foreach_front_buffer (view, - set_framebuffer_viewport, - &rect); -} - -gboolean -clutter_stage_view_is_dirty_projection (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - return priv->dirty_projection; -} - -static void -set_framebuffer_projection_matrix (CoglFramebuffer *framebuffer, - gconstpointer user_data) -{ - cogl_framebuffer_set_projection_matrix (framebuffer, user_data); -} - -void -clutter_stage_view_invalidate_projection (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - priv->dirty_projection = TRUE; -} - -void -clutter_stage_view_set_projection (ClutterStageView *view, - const graphene_matrix_t *matrix) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - priv->dirty_projection = FALSE; - clutter_stage_view_foreach_front_buffer (view, - set_framebuffer_projection_matrix, - matrix); -} - -void -clutter_stage_view_get_offscreen_transformation_matrix (ClutterStageView *view, - graphene_matrix_t *matrix) -{ - ClutterStageViewClass *view_class = CLUTTER_STAGE_VIEW_GET_CLASS (view); - - view_class->get_offscreen_transformation_matrix (view, matrix); -} - -static void -maybe_mark_full_redraw (ClutterStageView *view, - MtkRegion **region) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - if (mtk_region_num_rectangles (*region) == 1) - { - MtkRectangle region_extents; - - region_extents = mtk_region_get_extents (*region); - if (mtk_rectangle_equal (&priv->layout, ®ion_extents)) - g_clear_pointer (region, mtk_region_unref); - } -} - -void -clutter_stage_view_add_redraw_clip (ClutterStageView *view, - const MtkRectangle *clip) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - if (priv->has_redraw_clip && !priv->redraw_clip) - return; - - if (!clip) - { - g_clear_pointer (&priv->redraw_clip, mtk_region_unref); - priv->has_redraw_clip = TRUE; - return; - } - - if (clip->width == 0 || clip->height == 0) - return; - - if (!priv->redraw_clip) - { - if (!mtk_rectangle_equal (&priv->layout, clip)) - priv->redraw_clip = mtk_region_create_rectangle (clip); - } - else - { - mtk_region_union_rectangle (priv->redraw_clip, clip); - maybe_mark_full_redraw (view, &priv->redraw_clip); - } - - priv->has_redraw_clip = TRUE; -} - -gboolean -clutter_stage_view_has_redraw_clip (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - return priv->has_redraw_clip; -} - -gboolean -clutter_stage_view_has_full_redraw_clip (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - return priv->has_redraw_clip && !priv->redraw_clip; -} - -MtkRegion * -clutter_stage_view_take_accumulated_redraw_clip (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - g_return_val_if_fail (priv->has_redraw_clip, NULL); - - clutter_stage_view_accumulate_redraw_clip (view); - - priv->has_accumulated_redraw_clip = FALSE; - return g_steal_pointer (&priv->accumulated_redraw_clip); -} - -void -clutter_stage_view_accumulate_redraw_clip (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - g_return_if_fail (priv->has_redraw_clip); - - if (priv->redraw_clip && priv->accumulated_redraw_clip) - { - mtk_region_union (priv->accumulated_redraw_clip, priv->redraw_clip); - maybe_mark_full_redraw (view, &priv->accumulated_redraw_clip); - } - else if (priv->redraw_clip && !priv->has_accumulated_redraw_clip) - { - priv->accumulated_redraw_clip = g_steal_pointer (&priv->redraw_clip); - } - else - { - g_clear_pointer (&priv->accumulated_redraw_clip, mtk_region_unref); - } - - g_clear_pointer (&priv->redraw_clip, mtk_region_unref); - priv->has_accumulated_redraw_clip = TRUE; - priv->has_redraw_clip = FALSE; -} - -static void -clutter_stage_default_get_offscreen_transformation_matrix (ClutterStageView *view, - graphene_matrix_t *matrix) -{ - graphene_matrix_init_identity (matrix); -} - -void -clutter_stage_view_assign_next_scanout (ClutterStageView *view, - CoglScanout *scanout) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - g_set_object (&priv->next_scanout, scanout); -} - -CoglScanout * -clutter_stage_view_take_scanout (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - return g_steal_pointer (&priv->next_scanout); -} - -/** - * clutter_stage_view_peek_scanout: (skip) - */ -CoglScanout * -clutter_stage_view_peek_scanout (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - return priv->next_scanout; -} - -void -clutter_stage_view_schedule_update (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - clutter_frame_clock_schedule_update (priv->frame_clock); -} - -void -clutter_stage_view_schedule_update_now (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - clutter_frame_clock_schedule_update_now (priv->frame_clock); -} - -float -clutter_stage_view_get_refresh_rate (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - return priv->refresh_rate; -} - -/** - * clutter_stage_view_get_frame_clock: (skip) - */ -ClutterFrameClock * -clutter_stage_view_get_frame_clock (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - return priv->frame_clock; -} - -gboolean -clutter_stage_view_has_shadowfb (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - return priv->use_shadowfb; -} - -static void -handle_frame_clock_before_frame (ClutterFrameClock *frame_clock, - ClutterFrame *frame, - gpointer user_data) -{ - ClutterStageView *view = user_data; - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - _clutter_stage_process_queued_events (priv->stage); -} - -static void -begin_frame_timing_measurement (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - priv->frame_timings.began_draw_time_us = g_get_monotonic_time (); -} - -static void -end_frame_timing_measurement (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - int64_t now_us = g_get_monotonic_time (); - int64_t draw_time_us; - - draw_time_us = now_us - priv->frame_timings.began_draw_time_us; - - priv->frame_timings.frame_count++; - priv->frame_timings.cumulative_draw_time_us += draw_time_us; - if (draw_time_us > priv->frame_timings.worst_draw_time_us) - priv->frame_timings.worst_draw_time_us = draw_time_us; - - if (priv->frame_timings.frame_count && priv->frame_timings.last_print_time_us) - { - float time_since_last_print_s; - - time_since_last_print_s = - (now_us - priv->frame_timings.last_print_time_us) / - (float) G_USEC_PER_SEC; - - if (time_since_last_print_s >= 1.0) - { - float avg_fps, avg_draw_time_ms, worst_draw_time_ms; - - avg_fps = priv->frame_timings.frame_count / time_since_last_print_s; - - avg_draw_time_ms = - (priv->frame_timings.cumulative_draw_time_us / 1000.0) / - priv->frame_timings.frame_count; - - worst_draw_time_ms = priv->frame_timings.worst_draw_time_us / 1000.0; - - g_print ("*** %s frame timings over %.01fs: " - "%.02f FPS, average: %.01fms, peak: %.01fms\n", - priv->name, - time_since_last_print_s, - avg_fps, - avg_draw_time_ms, - worst_draw_time_ms); - - priv->frame_timings.frame_count = 0; - priv->frame_timings.cumulative_draw_time_us = 0; - priv->frame_timings.worst_draw_time_us = 0; - priv->frame_timings.last_print_time_us = now_us; - } - } - else if (!priv->frame_timings.last_print_time_us) - { - priv->frame_timings.last_print_time_us = now_us; - } -} - -static ClutterFrameResult -handle_frame_clock_frame (ClutterFrameClock *frame_clock, - ClutterFrame *frame, - gpointer user_data) -{ - ClutterStageView *view = user_data; - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - ClutterStage *stage = priv->stage; - ClutterStageWindow *stage_window = _clutter_stage_get_window (stage); - - if (CLUTTER_ACTOR_IN_DESTRUCTION (stage)) - return CLUTTER_FRAME_RESULT_IDLE; - - if (!clutter_actor_is_realized (CLUTTER_ACTOR (stage))) - return CLUTTER_FRAME_RESULT_IDLE; - - if (!clutter_actor_is_mapped (CLUTTER_ACTOR (stage))) - return CLUTTER_FRAME_RESULT_IDLE; - - if (_clutter_context_get_show_fps ()) - begin_frame_timing_measurement (view); - - _clutter_run_repaint_functions (CLUTTER_REPAINT_FLAGS_PRE_PAINT); - clutter_stage_emit_before_update (stage, view, frame); - - clutter_stage_maybe_relayout (CLUTTER_ACTOR (stage)); - - clutter_stage_finish_layout (stage); - - _clutter_stage_window_prepare_frame (stage_window, view, frame); - clutter_stage_emit_prepare_frame (stage, view, frame); - - if (clutter_stage_view_has_redraw_clip (view)) - { - clutter_stage_emit_before_paint (stage, view, frame); - - _clutter_stage_window_redraw_view (stage_window, view, frame); - - clutter_frame_clock_record_flip_time (frame_clock, - g_get_monotonic_time ()); - - clutter_stage_emit_after_paint (stage, view, frame); - - if (_clutter_context_get_show_fps ()) - end_frame_timing_measurement (view); - } - - _clutter_stage_window_finish_frame (stage_window, view, frame); - - if (priv->needs_update_devices) - { - clutter_stage_update_devices_in_view (stage, view); - priv->needs_update_devices = FALSE; - } - - _clutter_run_repaint_functions (CLUTTER_REPAINT_FLAGS_POST_PAINT); - clutter_stage_after_update (stage, view, frame); - - return clutter_frame_get_result (frame); -} - -static ClutterFrame * -handle_frame_clock_new_frame (ClutterFrameClock *frame_clock, - gpointer user_data) -{ - ClutterStageView *view = CLUTTER_STAGE_VIEW (user_data); - ClutterStageViewClass *view_class = CLUTTER_STAGE_VIEW_GET_CLASS (view); - - if (view_class->new_frame) - return view_class->new_frame (view); - else - return NULL; -} - -static const ClutterFrameListenerIface frame_clock_listener_iface = { - .before_frame = handle_frame_clock_before_frame, - .frame = handle_frame_clock_frame, - .new_frame = handle_frame_clock_new_frame, -}; - -void -clutter_stage_view_notify_presented (ClutterStageView *view, - ClutterFrameInfo *frame_info) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - clutter_stage_presented (priv->stage, view, frame_info); - clutter_frame_clock_notify_presented (priv->frame_clock, frame_info); -} - -void -clutter_stage_view_notify_ready (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - clutter_frame_clock_notify_ready (priv->frame_clock); -} - -static void -sanity_check_framebuffer (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - G_GNUC_UNUSED int fb_width, fb_height; - - fb_width = cogl_framebuffer_get_width (priv->framebuffer); - fb_height = cogl_framebuffer_get_height (priv->framebuffer); - - g_warn_if_fail (fabsf (roundf (fb_width / priv->scale) - - fb_width / priv->scale) < FLT_EPSILON); - g_warn_if_fail (fabsf (roundf (fb_height / priv->scale) - - fb_height / priv->scale) < FLT_EPSILON); -} - -static void -clutter_stage_view_set_framebuffer (ClutterStageView *view, - CoglFramebuffer *framebuffer) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - g_warn_if_fail (!priv->framebuffer); - if (framebuffer) - { - priv->framebuffer = g_object_ref (framebuffer); - sanity_check_framebuffer (view); - } -} - -static void -clutter_stage_view_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterStageView *view = CLUTTER_STAGE_VIEW (object); - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - switch (prop_id) - { - case PROP_NAME: - g_value_set_string (value, priv->name); - break; - case PROP_STAGE: - g_value_set_boxed (value, &priv->stage); - break; - case PROP_LAYOUT: - g_value_set_boxed (value, &priv->layout); - break; - case PROP_FRAMEBUFFER: - g_value_set_object (value, priv->framebuffer); - break; - case PROP_OFFSCREEN: - g_value_set_object (value, priv->offscreen); - break; - case PROP_USE_SHADOWFB: - g_value_set_boolean (value, priv->use_shadowfb); - break; - case PROP_SCALE: - g_value_set_float (value, priv->scale); - break; - case PROP_REFRESH_RATE: - g_value_set_float (value, priv->refresh_rate); - break; - case PROP_VBLANK_DURATION_US: - g_value_set_int64 (value, priv->vblank_duration_us); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -clutter_stage_view_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterStageView *view = CLUTTER_STAGE_VIEW (object); - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - MtkRectangle *layout; - switch (prop_id) - { - case PROP_NAME: - priv->name = g_value_dup_string (value); - break; - case PROP_STAGE: - priv->stage = g_value_get_object (value); - break; - case PROP_LAYOUT: - layout = g_value_get_boxed (value); - priv->layout = *layout; - break; - case PROP_FRAMEBUFFER: - clutter_stage_view_set_framebuffer (view, g_value_get_object (value)); - break; - case PROP_OFFSCREEN: - priv->offscreen = g_value_dup_object (value); - break; - case PROP_USE_SHADOWFB: - priv->use_shadowfb = g_value_get_boolean (value); - break; - case PROP_SCALE: - priv->scale = g_value_get_float (value); - break; - case PROP_REFRESH_RATE: - priv->refresh_rate = g_value_get_float (value); - break; - case PROP_VBLANK_DURATION_US: - priv->vblank_duration_us = g_value_get_int64 (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -clutter_stage_view_constructed (GObject *object) -{ - ClutterStageView *view = CLUTTER_STAGE_VIEW (object); - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - if (priv->use_shadowfb) - init_shadowfb (view); - - priv->frame_clock = clutter_frame_clock_new (priv->refresh_rate, - priv->vblank_duration_us, - priv->name, - &frame_clock_listener_iface, - view); - - clutter_stage_view_add_redraw_clip (view, NULL); - clutter_stage_view_schedule_update (view); - - G_OBJECT_CLASS (clutter_stage_view_parent_class)->constructed (object); -} - -static void -clutter_stage_view_dispose (GObject *object) -{ - ClutterStageView *view = CLUTTER_STAGE_VIEW (object); - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - g_signal_emit (view, stage_view_signals[DESTROY], 0); - - g_clear_pointer (&priv->name, g_free); - - g_clear_object (&priv->shadow.framebuffer); - - g_clear_object (&priv->offscreen); - g_clear_object (&priv->offscreen_pipeline); - g_clear_pointer (&priv->redraw_clip, mtk_region_unref); - g_clear_pointer (&priv->accumulated_redraw_clip, mtk_region_unref); - g_clear_pointer (&priv->frame_clock, clutter_frame_clock_destroy); - - G_OBJECT_CLASS (clutter_stage_view_parent_class)->dispose (object); -} - -static void -clutter_stage_view_finalize (GObject *object) -{ - ClutterStageView *view = CLUTTER_STAGE_VIEW (object); - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - g_clear_object (&priv->framebuffer); - - G_OBJECT_CLASS (clutter_stage_view_parent_class)->finalize (object); -} - -static void -clutter_stage_view_init (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - priv->dirty_viewport = TRUE; - priv->dirty_projection = TRUE; - priv->scale = 1.0; - priv->refresh_rate = 60.0; -} - -static void -clutter_stage_view_class_init (ClutterStageViewClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - klass->get_offscreen_transformation_matrix = - clutter_stage_default_get_offscreen_transformation_matrix; - - object_class->get_property = clutter_stage_view_get_property; - object_class->set_property = clutter_stage_view_set_property; - object_class->constructed = clutter_stage_view_constructed; - object_class->dispose = clutter_stage_view_dispose; - object_class->finalize = clutter_stage_view_finalize; - - obj_props[PROP_NAME] = - g_param_spec_string ("name", NULL, NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_props[PROP_STAGE] = - g_param_spec_object ("stage", NULL, NULL, - CLUTTER_TYPE_STAGE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_props[PROP_LAYOUT] = - g_param_spec_boxed ("layout", NULL, NULL, - MTK_TYPE_RECTANGLE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - obj_props[PROP_FRAMEBUFFER] = - g_param_spec_object ("framebuffer", NULL, NULL, - COGL_TYPE_FRAMEBUFFER, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - obj_props[PROP_OFFSCREEN] = - g_param_spec_object ("offscreen", NULL, NULL, - COGL_TYPE_OFFSCREEN, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_props[PROP_USE_SHADOWFB] = - g_param_spec_boolean ("use-shadowfb", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_props[PROP_SCALE] = - g_param_spec_float ("scale", NULL, NULL, - 0.5, G_MAXFLOAT, 1.0, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - obj_props[PROP_REFRESH_RATE] = - g_param_spec_float ("refresh-rate", NULL, NULL, - 1.0, G_MAXFLOAT, 60.0, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - obj_props[PROP_VBLANK_DURATION_US] = - g_param_spec_int64 ("vblank-duration-us", NULL, NULL, - 0, G_MAXINT64, 0, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, PROP_LAST, obj_props); - - stage_view_signals[DESTROY] = - g_signal_new ("destroy", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -void -clutter_stage_view_invalidate_input_devices (ClutterStageView *view) -{ - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - - priv->needs_update_devices = TRUE; -} - -ClutterPaintFlag -clutter_stage_view_get_default_paint_flags (ClutterStageView *view) -{ - ClutterStageViewClass *view_class = - CLUTTER_STAGE_VIEW_GET_CLASS (view); - - if (view_class->get_default_paint_flags) - return view_class->get_default_paint_flags (view); - else - return CLUTTER_PAINT_FLAG_NONE; -} diff --git a/mutter/clutter/clutter/clutter-stage-view.h b/mutter/clutter/clutter/clutter-stage-view.h deleted file mode 100644 index c0888f7..0000000 --- a/mutter/clutter/clutter/clutter-stage-view.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2016 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 . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -#include "cogl/cogl.h" -#include "clutter/clutter-macros.h" -#include "clutter/clutter-frame-clock.h" -#include "clutter/clutter-types.h" -#include "mtk/mtk.h" - -#define CLUTTER_TYPE_STAGE_VIEW (clutter_stage_view_get_type ()) -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterStageView, clutter_stage_view, - CLUTTER, STAGE_VIEW, - GObject) - -struct _ClutterStageViewClass -{ - GObjectClass parent_class; - - void (* setup_offscreen_transform) (ClutterStageView *view, - CoglPipeline *pipeline); - - void (* get_offscreen_transformation_matrix) (ClutterStageView *view, - graphene_matrix_t *matrix); - - void (* transform_rect_to_onscreen) (ClutterStageView *view, - const MtkRectangle *src_rect, - int dst_width, - int dst_height, - MtkRectangle *dst_rect); - - ClutterFrame * (* new_frame) (ClutterStageView *view); - - ClutterPaintFlag (* get_default_paint_flags) (ClutterStageView *view); -}; - -CLUTTER_EXPORT -void clutter_stage_view_destroy (ClutterStageView *view); - -CLUTTER_EXPORT -void clutter_stage_view_get_layout (ClutterStageView *view, - MtkRectangle *rect); - -CLUTTER_EXPORT -CoglFramebuffer *clutter_stage_view_get_framebuffer (ClutterStageView *view); -CLUTTER_EXPORT -CoglFramebuffer *clutter_stage_view_get_onscreen (ClutterStageView *view); -CLUTTER_EXPORT -void clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view); - -CLUTTER_EXPORT -float clutter_stage_view_get_scale (ClutterStageView *view); - -CLUTTER_EXPORT -void clutter_stage_view_get_offscreen_transformation_matrix (ClutterStageView *view, - graphene_matrix_t *matrix); - -CLUTTER_EXPORT -ClutterFrameClock * clutter_stage_view_get_frame_clock (ClutterStageView *view); - -CLUTTER_EXPORT -CoglScanout * clutter_stage_view_peek_scanout (ClutterStageView *view); - -CLUTTER_EXPORT -float clutter_stage_view_get_refresh_rate (ClutterStageView *view); - -CLUTTER_EXPORT -gboolean clutter_stage_view_has_shadowfb (ClutterStageView *view); - -CLUTTER_EXPORT -void clutter_stage_view_schedule_update_now (ClutterStageView *view); - -CLUTTER_EXPORT -ClutterPaintFlag clutter_stage_view_get_default_paint_flags (ClutterStageView *view); diff --git a/mutter/clutter/clutter/clutter-stage-window.c b/mutter/clutter/clutter/clutter-stage-window.c deleted file mode 100644 index 95a36ab..0000000 --- a/mutter/clutter/clutter/clutter-stage-window.c +++ /dev/null @@ -1,135 +0,0 @@ -#include "config.h" - -#include - -#include "clutter/clutter-actor.h" -#include "clutter/clutter-frame.h" -#include "clutter/clutter-stage-window.h" -#include "clutter/clutter-private.h" - -/** - * ClutterStageWindow: - * - * Handles the implementation for [class@Stage] - * - * #ClutterStageWindow is an interface that provides the implementation for the - * [class@Stage] actor, abstracting away the specifics of the windowing system. - */ - -G_DEFINE_INTERFACE (ClutterStageWindow, clutter_stage_window, G_TYPE_OBJECT); - -static void -clutter_stage_window_default_init (ClutterStageWindowInterface *iface) -{ -} - -gboolean -_clutter_stage_window_realize (ClutterStageWindow *window) -{ - return CLUTTER_STAGE_WINDOW_GET_IFACE (window)->realize (window); -} - -void -_clutter_stage_window_unrealize (ClutterStageWindow *window) -{ - CLUTTER_STAGE_WINDOW_GET_IFACE (window)->unrealize (window); -} - -void -_clutter_stage_window_show (ClutterStageWindow *window, - gboolean do_raise) -{ - CLUTTER_STAGE_WINDOW_GET_IFACE (window)->show (window, do_raise); -} - -void -_clutter_stage_window_hide (ClutterStageWindow *window) -{ - CLUTTER_STAGE_WINDOW_GET_IFACE (window)->hide (window); -} - -void -_clutter_stage_window_resize (ClutterStageWindow *window, - gint width, - gint height) -{ - CLUTTER_STAGE_WINDOW_GET_IFACE (window)->resize (window, width, height); -} - -void -_clutter_stage_window_get_geometry (ClutterStageWindow *window, - MtkRectangle *geometry) -{ - CLUTTER_STAGE_WINDOW_GET_IFACE (window)->get_geometry (window, geometry); -} - -void -_clutter_stage_window_redraw_view (ClutterStageWindow *window, - ClutterStageView *view, - ClutterFrame *frame) -{ - g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window)); - - CLUTTER_STAGE_WINDOW_GET_IFACE (window)->redraw_view (window, view, frame); -} - -gboolean -_clutter_stage_window_can_clip_redraws (ClutterStageWindow *window) -{ - ClutterStageWindowInterface *iface; - - g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE); - - iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); - if (iface->can_clip_redraws != NULL) - return iface->can_clip_redraws (window); - - return FALSE; -} - -GList * -_clutter_stage_window_get_views (ClutterStageWindow *window) -{ - ClutterStageWindowInterface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); - - return iface->get_views (window); -} - -void -_clutter_stage_window_prepare_frame (ClutterStageWindow *window, - ClutterStageView *view, - ClutterFrame *frame) -{ - ClutterStageWindowInterface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); - - if (iface->prepare_frame) - iface->prepare_frame (window, view, frame); -} - -void -_clutter_stage_window_finish_frame (ClutterStageWindow *window, - ClutterStageView *view, - ClutterFrame *frame) -{ - ClutterStageWindowInterface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); - - if (iface->finish_frame) - { - iface->finish_frame (window, view, frame); - return; - } - - if (!clutter_frame_has_result (frame)) - clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_IDLE); -} - -int64_t -_clutter_stage_window_get_frame_counter (ClutterStageWindow *window) -{ - ClutterStageWindowInterface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); - - if (iface->get_frame_counter) - return iface->get_frame_counter (window); - else - return 0; -} diff --git a/mutter/clutter/clutter/clutter-stage-window.h b/mutter/clutter/clutter/clutter-stage-window.h deleted file mode 100644 index db8e87c..0000000 --- a/mutter/clutter/clutter/clutter-stage-window.h +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once - -#include "cogl/cogl.h" -#include "clutter/clutter-types.h" -#include "clutter/clutter-stage-view.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_STAGE_WINDOW (clutter_stage_window_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_INTERFACE (ClutterStageWindow, clutter_stage_window, - CLUTTER, STAGE_WINDOW, - GObject) - -/* - * ClutterStageWindowInterface: (skip) - * - * The interface implemented by backends for stage windows - */ -struct _ClutterStageWindowInterface -{ - /*< private >*/ - GTypeInterface parent_iface; - - void (* set_title) (ClutterStageWindow *stage_window, - const gchar *title); - - gboolean (* realize) (ClutterStageWindow *stage_window); - void (* unrealize) (ClutterStageWindow *stage_window); - - void (* show) (ClutterStageWindow *stage_window, - gboolean do_raise); - void (* hide) (ClutterStageWindow *stage_window); - - void (* resize) (ClutterStageWindow *stage_window, - gint width, - gint height); - void (* get_geometry) (ClutterStageWindow *stage_window, - MtkRectangle *geometry); - - void (* redraw_view) (ClutterStageWindow *stage_window, - ClutterStageView *view, - ClutterFrame *frame); - - gboolean (* can_clip_redraws) (ClutterStageWindow *stage_window); - - GList *(* get_views) (ClutterStageWindow *stage_window); - int64_t (* get_frame_counter) (ClutterStageWindow *stage_window); - void (* prepare_frame) (ClutterStageWindow *stage_window, - ClutterStageView *view, - ClutterFrame *frame); - void (* finish_frame) (ClutterStageWindow *stage_window, - ClutterStageView *view, - ClutterFrame *frame); -}; - -void _clutter_stage_window_set_cursor_visible (ClutterStageWindow *window, - gboolean is_visible); - -gboolean _clutter_stage_window_realize (ClutterStageWindow *window); -void _clutter_stage_window_unrealize (ClutterStageWindow *window); - -void _clutter_stage_window_show (ClutterStageWindow *window, - gboolean do_raise); -void _clutter_stage_window_hide (ClutterStageWindow *window); - -void _clutter_stage_window_resize (ClutterStageWindow *window, - gint width, - gint height); -CLUTTER_EXPORT -void _clutter_stage_window_get_geometry (ClutterStageWindow *window, - MtkRectangle *geometry); - -void _clutter_stage_window_set_accept_focus (ClutterStageWindow *window, - gboolean accept_focus); - -void _clutter_stage_window_redraw_view (ClutterStageWindow *window, - ClutterStageView *view, - ClutterFrame *frame); - -CLUTTER_EXPORT -gboolean _clutter_stage_window_can_clip_redraws (ClutterStageWindow *window); - -GList * _clutter_stage_window_get_views (ClutterStageWindow *window); - -void _clutter_stage_window_prepare_frame (ClutterStageWindow *window, - ClutterStageView *view, - ClutterFrame *frame); - -void _clutter_stage_window_finish_frame (ClutterStageWindow *window, - ClutterStageView *view, - ClutterFrame *frame); - -int64_t _clutter_stage_window_get_frame_counter (ClutterStageWindow *window); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-stage.c b/mutter/clutter/clutter/clutter-stage.c deleted file mode 100644 index d5a5952..0000000 --- a/mutter/clutter/clutter/clutter-stage.c +++ /dev/null @@ -1,4633 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * 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 . - */ - -/** - * ClutterStage: - * - * Top level visual element to which actors are placed. - * - * #ClutterStage is a top level 'window' on which child actors are placed - * and manipulated. - * - * #ClutterStage is a proxy actor, wrapping the backend-specific implementation - * (a #StageWindow) of the windowing system. It is possible to subclass - * #ClutterStage, as long as every overridden virtual function chains up to the - * parent class corresponding function. - */ - -#include "config.h" - -#include - -#include "clutter/clutter-stage.h" - -#include "clutter/clutter-action-private.h" -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-backend-private.h" -#include "clutter/clutter-context-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-event-private.h" -#include "clutter/clutter-frame-clock.h" -#include "clutter/clutter-frame.h" -#include "clutter/clutter-grab-private.h" -#include "clutter/clutter-input-device-private.h" -#include "clutter/clutter-input-only-actor.h" -#include "clutter/clutter-main.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-mutter.h" -#include "clutter/clutter-paint-context-private.h" -#include "clutter/clutter-paint-volume-private.h" -#include "clutter/clutter-pick-context-private.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-seat-private.h" -#include "clutter/clutter-stage-manager-private.h" -#include "clutter/clutter-stage-private.h" -#include "clutter/clutter-stage-view-private.h" -#include "clutter/clutter-private.h" - -#include "cogl/cogl.h" - -#define MAX_FRUSTA 64 - -typedef struct _PickRecord -{ - graphene_point_t vertex[4]; - ClutterActor *actor; - int clip_stack_top; -} PickRecord; - -typedef struct _PickClipRecord -{ - int prev; - graphene_point_t vertex[4]; -} PickClipRecord; - -typedef struct _EventReceiver -{ - ClutterActor *actor; - ClutterEventPhase phase; - - ClutterAction *action; -} EventReceiver; - -typedef struct _PointerDeviceEntry -{ - ClutterStage *stage; - ClutterInputDevice *device; - ClutterEventSequence *sequence; - graphene_point_t coords; - ClutterActor *current_actor; - MtkRegion *clear_area; - - unsigned int press_count; - ClutterActor *implicit_grab_actor; - GArray *event_emission_chain; -} PointerDeviceEntry; - -typedef struct _ClutterStagePrivate -{ - /* the stage implementation */ - ClutterStageWindow *impl; - - ClutterPerspective perspective; - graphene_matrix_t projection; - graphene_matrix_t inverse_projection; - graphene_matrix_t view; - float viewport[4]; - - gchar *title; - ClutterActor *key_focused_actor; - - ClutterGrab *topmost_grab; - ClutterGrabState grab_state; - - GQueue *event_queue; - GPtrArray *cur_event_actors; - GArray *cur_event_emission_chain; - - GSList *pending_relayouts; - - int update_freeze_count; - - gboolean update_scheduled; - - GHashTable *pointer_devices; - GHashTable *touch_sequences; - - GPtrArray *all_active_gestures; - - guint actor_needs_immediate_relayout : 1; -} ClutterStagePrivate; - -enum -{ - PROP_0, - - PROP_PERSPECTIVE, - PROP_TITLE, - PROP_KEY_FOCUS, - PROP_IS_GRABBED, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST] = { NULL, }; - -enum -{ - ACTIVATE, - DEACTIVATE, - DELETE_EVENT, - BEFORE_UPDATE, - PREPARE_FRAME, - BEFORE_PAINT, - AFTER_PAINT, - AFTER_UPDATE, - PAINT_VIEW, - PRESENTED, - GL_VIDEO_MEMORY_PURGED, - - LAST_SIGNAL -}; - -static guint stage_signals[LAST_SIGNAL] = { 0, }; - -static const ClutterColor default_stage_color = { 255, 255, 255, 255 }; - -static void free_pointer_device_entry (PointerDeviceEntry *entry); -static void free_event_receiver (EventReceiver *receiver); -static void clutter_stage_update_view_perspective (ClutterStage *stage); -static void clutter_stage_set_viewport (ClutterStage *stage, - float width, - float height); - -static ClutterActor * clutter_stage_pick_and_update_device (ClutterStage *stage, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - ClutterInputDevice *source_device, - ClutterDeviceUpdateFlags flags, - graphene_point_t point, - uint32_t time_ms); - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterStage, clutter_stage, CLUTTER_TYPE_ACTOR) - -static void -clutter_stage_get_preferred_width (ClutterActor *self, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p) -{ - ClutterStagePrivate *priv = - clutter_stage_get_instance_private (CLUTTER_STAGE (self)); - MtkRectangle geom; - - if (priv->impl == NULL) - return; - - _clutter_stage_window_get_geometry (priv->impl, &geom); - - if (min_width_p) - *min_width_p = geom.width; - - if (natural_width_p) - *natural_width_p = geom.width; -} - -static void -clutter_stage_get_preferred_height (ClutterActor *self, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p) -{ - ClutterStagePrivate *priv = - clutter_stage_get_instance_private (CLUTTER_STAGE (self)); - MtkRectangle geom; - - if (priv->impl == NULL) - return; - - _clutter_stage_window_get_geometry (priv->impl, &geom); - - if (min_height_p) - *min_height_p = geom.height; - - if (natural_height_p) - *natural_height_p = geom.height; -} - -static void -clutter_stage_add_redraw_clip (ClutterStage *stage, - MtkRectangle *clip) -{ - GList *l; - - for (l = clutter_stage_peek_stage_views (stage); l; l = l->next) - { - ClutterStageView *view = l->data; - - if (!clip) - { - clutter_stage_view_add_redraw_clip (view, NULL); - } - else - { - MtkRectangle view_layout; - MtkRectangle intersection; - - clutter_stage_view_get_layout (view, &view_layout); - if (mtk_rectangle_intersect (&view_layout, clip, - &intersection)) - clutter_stage_view_add_redraw_clip (view, &intersection); - } - } -} - -static inline void -queue_full_redraw (ClutterStage *stage) -{ - ClutterStageWindow *stage_window; - - if (CLUTTER_ACTOR_IN_DESTRUCTION (stage)) - return; - - clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); - - /* Just calling clutter_actor_queue_redraw will typically only - * redraw the bounding box of the children parented on the stage but - * in this case we really need to ensure that the full stage is - * redrawn so we add a NULL redraw clip to the stage window. */ - stage_window = _clutter_stage_get_window (stage); - if (stage_window == NULL) - return; - - clutter_stage_add_redraw_clip (stage, NULL); -} - -static void -clutter_stage_allocate (ClutterActor *self, - const ClutterActorBox *box) -{ - ClutterStagePrivate *priv = - clutter_stage_get_instance_private (CLUTTER_STAGE (self)); - ClutterActorBox alloc = CLUTTER_ACTOR_BOX_INIT_ZERO; - float new_width, new_height; - float width, height; - MtkRectangle window_size; - ClutterActorBox children_box; - ClutterLayoutManager *layout_manager = clutter_actor_get_layout_manager (self); - - if (priv->impl == NULL) - return; - - /* the current allocation */ - clutter_actor_box_get_size (box, &width, &height); - - /* the current Stage implementation size */ - _clutter_stage_window_get_geometry (priv->impl, &window_size); - - children_box.x1 = children_box.y1 = 0.f; - children_box.x2 = box->x2 - box->x1; - children_box.y2 = box->y2 - box->y1; - - CLUTTER_NOTE (LAYOUT, - "Following allocation to %.2fx%.2f", - width, height); - - clutter_actor_set_allocation (self, box); - - clutter_layout_manager_allocate (layout_manager, - self, - &children_box); - - if (window_size.width != CLUTTER_NEARBYINT (width) || - window_size.height != CLUTTER_NEARBYINT (height)) - { - _clutter_stage_window_resize (priv->impl, - CLUTTER_NEARBYINT (width), - CLUTTER_NEARBYINT (height)); - } - - /* set the viewport to the new allocation */ - clutter_actor_get_allocation_box (self, &alloc); - clutter_actor_box_get_size (&alloc, &new_width, &new_height); - - clutter_stage_set_viewport (CLUTTER_STAGE (self), new_width, new_height); -} - -static void -setup_clip_frustum (ClutterStage *stage, - const MtkRectangle *clip, - graphene_frustum_t *frustum) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - MtkRectangle geom; - graphene_point3d_t camera_position; - graphene_point3d_t p[4]; - graphene_plane_t planes[6]; - graphene_vec4_t v; - int i; - - _clutter_stage_window_get_geometry (priv->impl, &geom); - - CLUTTER_NOTE (CLIPPING, "Creating stage clip frustum for " - "x=%d, y=%d, width=%d, height=%d", - clip->x, clip->y, clip->width, clip->height); - - camera_position = GRAPHENE_POINT3D_INIT_ZERO; - - p[0] = GRAPHENE_POINT3D_INIT (MAX (clip->x, 0), MAX (clip->y, 0), 0.f); - p[2] = GRAPHENE_POINT3D_INIT (MIN (clip->x + clip->width, geom.width), - MIN (clip->y + clip->height, geom.height), - 0.f); - - for (i = 0; i < 2; i++) - { - float w = 1.0; - cogl_graphene_matrix_project_point (&priv->view, - &p[2 * i].x, - &p[2 * i].y, - &p[2 * i].z, - &w); - } - - graphene_point3d_init (&p[1], p[2].x, p[0].y, p[0].z); - graphene_point3d_init (&p[3], p[0].x, p[2].y, p[0].z); - - for (i = 0; i < 4; i++) - { - graphene_plane_init_from_points (&planes[i], - &camera_position, - &p[i], - &p[(i + 1) % 4]); - } - - graphene_vec4_init (&v, 0.f, 0.f, -1.f, priv->perspective.z_near); - graphene_plane_init_from_vec4 (&planes[4], &v); - - graphene_vec4_init (&v, 0.f, 0.f, 1.f, priv->perspective.z_far); - graphene_plane_init_from_vec4 (&planes[5], &v); - - graphene_frustum_init (frustum, - &planes[0], &planes[1], - &planes[2], &planes[3], - &planes[4], &planes[5]); -} - -static void -clutter_stage_do_paint_view (ClutterStage *stage, - ClutterStageView *view, - ClutterFrame *frame, - const MtkRegion *redraw_clip) -{ - ClutterPaintContext *paint_context; - MtkRectangle clip_rect; - g_autoptr (GArray) clip_frusta = NULL; - graphene_frustum_t clip_frustum; - ClutterPaintNode *root_node; - CoglFramebuffer *fb; - ClutterColor bg_color; - int n_rectangles; - ClutterPaintFlag paint_flags; - - n_rectangles = redraw_clip ? mtk_region_num_rectangles (redraw_clip) : 0; - if (redraw_clip && n_rectangles < MAX_FRUSTA) - { - int i; - - clip_frusta = g_array_sized_new (FALSE, FALSE, - sizeof (graphene_frustum_t), - n_rectangles); - - for (i = 0; i < n_rectangles; i++) - { - clip_rect = mtk_region_get_rectangle (redraw_clip, i); - setup_clip_frustum (stage, &clip_rect, &clip_frustum); - g_array_append_val (clip_frusta, clip_frustum); - } - } - else - { - clip_frusta = g_array_sized_new (FALSE, FALSE, - sizeof (graphene_frustum_t), - 1); - if (redraw_clip) - clip_rect = mtk_region_get_extents (redraw_clip); - else - clutter_stage_view_get_layout (view, &clip_rect); - - setup_clip_frustum (stage, &clip_rect, &clip_frustum); - g_array_append_val (clip_frusta, clip_frustum); - } - - paint_flags = clutter_stage_view_get_default_paint_flags (view); - - paint_context = clutter_paint_context_new_for_view (view, - redraw_clip, - clip_frusta, - paint_flags); - - if (frame) - clutter_paint_context_assign_frame (paint_context, frame); - - clutter_actor_get_background_color (CLUTTER_ACTOR (stage), &bg_color); - bg_color.alpha = 255; - - fb = clutter_stage_view_get_framebuffer (view); - - root_node = clutter_root_node_new (fb, &bg_color, COGL_BUFFER_BIT_DEPTH); - clutter_paint_node_set_static_name (root_node, "Stage (root)"); - clutter_paint_node_paint (root_node, paint_context); - clutter_paint_node_unref (root_node); - - clutter_actor_paint (CLUTTER_ACTOR (stage), paint_context); - clutter_paint_context_destroy (paint_context); -} - -/* This provides a common point of entry for painting the scenegraph - * for picking or painting... - */ -void -clutter_stage_paint_view (ClutterStage *stage, - ClutterStageView *view, - const MtkRegion *redraw_clip, - ClutterFrame *frame) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - - if (!priv->impl) - return; - - COGL_TRACE_BEGIN_SCOPED (ClutterStagePaintView, "Clutter::Stage::paint_view()"); - - if (g_signal_has_handler_pending (stage, stage_signals[PAINT_VIEW], - 0, TRUE)) - g_signal_emit (stage, stage_signals[PAINT_VIEW], 0, view, redraw_clip, frame); - else - CLUTTER_STAGE_GET_CLASS (stage)->paint_view (stage, view, redraw_clip, frame); -} - -void -clutter_stage_emit_before_update (ClutterStage *stage, - ClutterStageView *view, - ClutterFrame *frame) -{ - g_signal_emit (stage, stage_signals[BEFORE_UPDATE], 0, view, frame); -} - -void -clutter_stage_emit_prepare_frame (ClutterStage *stage, - ClutterStageView *view, - ClutterFrame *frame) -{ - g_signal_emit (stage, stage_signals[PREPARE_FRAME], 0, view, frame); -} - -void -clutter_stage_emit_before_paint (ClutterStage *stage, - ClutterStageView *view, - ClutterFrame *frame) -{ - g_signal_emit (stage, stage_signals[BEFORE_PAINT], 0, view, frame); -} - -void -clutter_stage_emit_after_paint (ClutterStage *stage, - ClutterStageView *view, - ClutterFrame *frame) -{ - g_signal_emit (stage, stage_signals[AFTER_PAINT], 0, view, frame); -} - -void -clutter_stage_after_update (ClutterStage *stage, - ClutterStageView *view, - ClutterFrame *frame) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - - g_signal_emit (stage, stage_signals[AFTER_UPDATE], 0, view, frame); - - priv->update_scheduled = FALSE; -} - -static gboolean -clutter_stage_get_paint_volume (ClutterActor *self, - ClutterPaintVolume *volume) -{ - /* Returning False effectively means Clutter has to assume it covers - * everything... */ - return FALSE; -} - -static void -clutter_stage_realize (ClutterActor *self) -{ - ClutterStagePrivate *priv = - clutter_stage_get_instance_private (CLUTTER_STAGE (self)); - gboolean is_realized; - - g_assert (priv->impl != NULL); - is_realized = _clutter_stage_window_realize (priv->impl); - - if (!is_realized) - self->flags &= ~CLUTTER_ACTOR_REALIZED; -} - -static void -clutter_stage_unrealize (ClutterActor *self) -{ - ClutterStagePrivate *priv = - clutter_stage_get_instance_private (CLUTTER_STAGE (self)); - - /* and then unrealize the implementation */ - g_assert (priv->impl != NULL); - _clutter_stage_window_unrealize (priv->impl); - - self->flags &= ~CLUTTER_ACTOR_REALIZED; -} - -static void -clutter_stage_show (ClutterActor *self) -{ - ClutterStagePrivate *priv = - clutter_stage_get_instance_private (CLUTTER_STAGE (self)); - - CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->show (self); - - /* Possibly do an allocation run so that the stage will have the - right size before we map it */ - clutter_stage_maybe_relayout (self); - - g_assert (priv->impl != NULL); - _clutter_stage_window_show (priv->impl, TRUE); -} - -static void -clutter_stage_hide_all (ClutterActor *self) -{ - ClutterActorIter iter; - ClutterActor *child; - - clutter_actor_hide (self); - - /* we don't do a recursive hide_all(), to maintain the old invariants - * from ClutterGroup - */ - clutter_actor_iter_init (&iter, self); - while (clutter_actor_iter_next (&iter, &child)) - clutter_actor_hide (child); -} - -static void -clutter_stage_hide (ClutterActor *self) -{ - ClutterStagePrivate *priv = - clutter_stage_get_instance_private (CLUTTER_STAGE (self)); - - g_assert (priv->impl != NULL); - _clutter_stage_window_hide (priv->impl); - - CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->hide (self); -} - -static void -clutter_stage_emit_key_focus_event (ClutterStage *stage, - gboolean focus_in) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - - if (priv->key_focused_actor == NULL) - return; - - _clutter_actor_set_has_key_focus (CLUTTER_ACTOR (stage), focus_in); - - g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_KEY_FOCUS]); -} - -static void -clutter_stage_real_activate (ClutterStage *stage) -{ - clutter_stage_emit_key_focus_event (stage, TRUE); -} - -static void -clutter_stage_real_deactivate (ClutterStage *stage) -{ - clutter_stage_emit_key_focus_event (stage, FALSE); -} - -void -_clutter_stage_queue_event (ClutterStage *stage, - ClutterEvent *event, - gboolean copy_event) -{ - ClutterStagePrivate *priv; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - - priv = clutter_stage_get_instance_private (stage); - - g_queue_push_tail (priv->event_queue, - copy_event ? clutter_event_copy (event) : event); - - clutter_stage_schedule_update (stage); -} - -static ClutterEvent * -clutter_stage_compress_motion (ClutterStage *stage, - ClutterEvent *event, - const ClutterEvent *to_discard) -{ - double dx, dy; - double dx_unaccel, dy_unaccel; - double dx_constrained, dy_constrained; - double dst_dx = 0.0, dst_dy = 0.0; - double dst_dx_unaccel = 0.0, dst_dy_unaccel = 0.0; - double dst_dx_constrained = 0.0, dst_dy_constrained = 0.0; - graphene_point_t coords; - - if (!clutter_event_get_relative_motion (to_discard, - &dx, &dy, - &dx_unaccel, &dy_unaccel, - &dx_constrained, &dy_constrained)) - return NULL; - - clutter_event_get_relative_motion (event, - &dst_dx, &dst_dy, - &dst_dx_unaccel, &dst_dy_unaccel, - &dst_dx_constrained, &dst_dy_constrained); - - clutter_event_get_position (event, &coords); - - return clutter_event_motion_new (CLUTTER_EVENT_FLAG_RELATIVE_MOTION, - clutter_event_get_time_us (event), - clutter_event_get_source_device (event), - clutter_event_get_device_tool (event), - clutter_event_get_state (event), - coords, - GRAPHENE_POINT_INIT (dx + dst_dx, dy + dst_dy), - GRAPHENE_POINT_INIT (dx_unaccel + dst_dx_unaccel, - dy_unaccel + dst_dy_unaccel), - GRAPHENE_POINT_INIT (dx_constrained + dst_dx_constrained, - dy_constrained + dst_dy_constrained), - NULL); -} - -CLUTTER_EXPORT void -_clutter_stage_process_queued_events (ClutterStage *stage) -{ - ClutterStagePrivate *priv; - GList *events, *l; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - - COGL_TRACE_BEGIN_SCOPED (ProcessQueuedEvents, "Clutter::Stage::process_queued_events()"); - - priv = clutter_stage_get_instance_private (stage); - - if (priv->event_queue->length == 0) - return; - - /* In case the stage gets destroyed during event processing */ - g_object_ref (stage); - - /* Steal events before starting processing to avoid reentrancy - * issues */ - events = priv->event_queue->head; - priv->event_queue->head = NULL; - priv->event_queue->tail = NULL; - priv->event_queue->length = 0; - - for (l = events; l != NULL; l = l->next) - { - ClutterEvent *event; - ClutterEvent *next_event; - ClutterInputDevice *device; - ClutterInputDevice *next_device; - gboolean check_device = FALSE; - - event = l->data; - next_event = l->next ? l->next->data : NULL; - - COGL_TRACE_BEGIN_SCOPED (ProcessEvent, - "Clutter::Stage::process_queued_events#event()"); - COGL_TRACE_DESCRIBE (ProcessEvent, clutter_event_get_name (event)); - - device = clutter_event_get_device (event); - - if (next_event != NULL) - next_device = clutter_event_get_device (next_event); - else - next_device = NULL; - - if (device != NULL && next_device != NULL) - check_device = TRUE; - - /* Skip consecutive motion events coming from the same device. */ - if (next_event != NULL) - { - float x, y; - - clutter_event_get_coords (event, &x, &y); - - if (clutter_event_type (event) == CLUTTER_MOTION && - (clutter_event_type (next_event) == CLUTTER_MOTION || - clutter_event_type (next_event) == CLUTTER_LEAVE) && - (!check_device || (device == next_device))) - { - CLUTTER_NOTE (EVENT, - "Omitting motion event at %d, %d", - (int) x, - (int) y); - - if (clutter_event_type (next_event) == CLUTTER_MOTION) - { - ClutterEvent *new_event; - - new_event = - clutter_stage_compress_motion (stage, next_event, event); - if (new_event) - { - /* Replace the next event with the rewritten one */ - l->next->data = new_event; - clutter_event_free (next_event); - } - } - - goto next_event; - } - else if (clutter_event_type (event) == CLUTTER_TOUCH_UPDATE && - clutter_event_type (next_event) == CLUTTER_TOUCH_UPDATE && - clutter_event_get_event_sequence (event) == - clutter_event_get_event_sequence (next_event) && - (!check_device || (device == next_device))) - { - CLUTTER_NOTE (EVENT, - "Omitting touch update event at %d, %d", - (int) x, - (int) y); - goto next_event; - } - } - - clutter_stage_process_event (stage, event); - - next_event: - clutter_event_free (event); - } - - g_list_free (events); - - g_object_unref (stage); -} - -void -clutter_stage_queue_actor_relayout (ClutterStage *stage, - ClutterActor *actor) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - - clutter_stage_schedule_update (stage); - - priv->pending_relayouts = g_slist_prepend (priv->pending_relayouts, - g_object_ref (actor)); -} - -void -clutter_stage_dequeue_actor_relayout (ClutterStage *stage, - ClutterActor *actor) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - GSList *l; - - for (l = priv->pending_relayouts; l; l = l->next) - { - ClutterActor *relayout_actor = l->data; - - if (relayout_actor == actor) - { - g_object_unref (relayout_actor); - priv->pending_relayouts = - g_slist_delete_link (priv->pending_relayouts, l); - - return; - } - } -} - -void -clutter_stage_invalidate_devices (ClutterStage *stage) -{ - GList *l; - - for (l = clutter_stage_peek_stage_views (stage); l; l = l->next) - { - ClutterStageView *view = l->data; - - clutter_stage_view_invalidate_input_devices (view); - } -} - -void -clutter_stage_maybe_relayout (ClutterActor *actor) -{ - ClutterStage *stage = CLUTTER_STAGE (actor); - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - g_autoptr (GSList) stolen_list = NULL; - GSList *l; - int count = 0; - - /* No work to do? Avoid the extraneous debug log messages too. */ - if (priv->pending_relayouts == NULL) - return; - - COGL_TRACE_BEGIN_SCOPED (ClutterStageRelayout, "Clutter::Stage::maybe_relayout()"); - - CLUTTER_NOTE (ACTOR, ">>> Recomputing layout"); - - stolen_list = g_steal_pointer (&priv->pending_relayouts); - for (l = stolen_list; l; l = l->next) - { - g_autoptr (ClutterActor) queued_actor = l->data; - float x = 0.f; - float y = 0.f; - - if (CLUTTER_ACTOR_IN_RELAYOUT (queued_actor)) /* avoid reentrancy */ - continue; - - if (queued_actor == actor) - CLUTTER_NOTE (ACTOR, " Deep relayout of stage %s", - _clutter_actor_get_debug_name (queued_actor)); - else - CLUTTER_NOTE (ACTOR, " Shallow relayout of actor %s", - _clutter_actor_get_debug_name (queued_actor)); - - CLUTTER_SET_PRIVATE_FLAGS (queued_actor, CLUTTER_IN_RELAYOUT); - - clutter_actor_get_fixed_position (queued_actor, &x, &y); - clutter_actor_allocate_preferred_size (queued_actor, x, y); - - CLUTTER_UNSET_PRIVATE_FLAGS (queued_actor, CLUTTER_IN_RELAYOUT); - - count++; - } - - CLUTTER_NOTE (ACTOR, "<<< Completed recomputing layout of %d subtrees", count); - - if (count) - clutter_stage_invalidate_devices (stage); -} - -void -clutter_stage_finish_layout (ClutterStage *stage) -{ - ClutterActor *actor = CLUTTER_ACTOR (stage); - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - int phase; - - COGL_TRACE_BEGIN_SCOPED (ClutterStageUpdateActorStageViews, - "Clutter::Stage::finish_layout()"); - - /* If an actor needs an immediate relayout because its resource scale - * changed, we give it another chance to allocate correctly before - * the paint. - * - * We're doing the whole thing twice and pass the phase to - * clutter_actor_finish_layout() to allow actors to detect loops: - * If the resource scale changes again after the relayout, the new - * allocation of an actor probably moved the actor onto another stage - * view, so if an actor sees phase == 1, it can choose a "final" scale. - */ - for (phase = 0; phase < 2; phase++) - { - clutter_actor_finish_layout (actor, phase); - - if (!priv->actor_needs_immediate_relayout) - break; - - priv->actor_needs_immediate_relayout = FALSE; - clutter_stage_maybe_relayout (actor); - } - - g_warn_if_fail (!priv->actor_needs_immediate_relayout); -} - -static void -clutter_stage_real_queue_relayout (ClutterActor *self) -{ - ClutterStage *stage = CLUTTER_STAGE (self); - ClutterActorClass *parent_class; - - clutter_stage_queue_actor_relayout (stage, self); - - /* chain up */ - parent_class = CLUTTER_ACTOR_CLASS (clutter_stage_parent_class); - parent_class->queue_relayout (self); -} - -static gboolean -is_full_stage_redraw_queued (ClutterStage *stage) -{ - GList *l; - - for (l = clutter_stage_peek_stage_views (stage); l; l = l->next) - { - ClutterStageView *view = l->data; - - if (!clutter_stage_view_has_full_redraw_clip (view)) - return FALSE; - } - - return TRUE; -} - -static void -setup_ray_for_coordinates (ClutterStage *stage, - float x, - float y, - graphene_point3d_t *point, - graphene_ray_t *ray) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - graphene_point3d_t camera_position; - graphene_point3d_t p; - graphene_vec3_t direction; - graphene_vec3_t cv; - graphene_vec3_t v; - - camera_position = GRAPHENE_POINT3D_INIT_ZERO; - graphene_vec3_init (&cv, - camera_position.x, - camera_position.y, - camera_position.z); - - p = GRAPHENE_POINT3D_INIT (x, y, 0.f); - graphene_matrix_transform_point3d (&priv->view, &p, &p); - - graphene_vec3_init (&v, p.x, p.y, p.z); - graphene_vec3_subtract (&v, &cv, &direction); - graphene_vec3_normalize (&direction, &direction); - - graphene_ray_init (ray, &camera_position, &direction); - graphene_point3d_init_from_point (point, &p); -} - -static ClutterActor * -_clutter_stage_do_pick_on_view (ClutterStage *stage, - float x, - float y, - ClutterPickMode mode, - ClutterStageView *view, - MtkRegion **clear_area) -{ - g_autoptr (ClutterPickStack) pick_stack = NULL; - ClutterPickContext *pick_context; - graphene_point3d_t p; - graphene_ray_t ray; - ClutterActor *actor; - - COGL_TRACE_BEGIN_SCOPED (ClutterStagePickView, "Clutter::Stage::do_pick_on_view()"); - - setup_ray_for_coordinates (stage, x, y, &p, &ray); - - pick_context = clutter_pick_context_new_for_view (view, mode, &p, &ray); - - clutter_actor_pick (CLUTTER_ACTOR (stage), pick_context); - pick_stack = clutter_pick_context_steal_stack (pick_context); - clutter_pick_context_destroy (pick_context); - - actor = clutter_pick_stack_search_actor (pick_stack, &p, &ray, clear_area); - return actor ? actor : CLUTTER_ACTOR (stage); -} - -/** - * clutter_stage_get_view_at: (skip) - */ -ClutterStageView * -clutter_stage_get_view_at (ClutterStage *stage, - float x, - float y) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - GList *l; - - for (l = _clutter_stage_window_get_views (priv->impl); l; l = l->next) - { - ClutterStageView *view = l->data; - MtkRectangle view_layout; - - clutter_stage_view_get_layout (view, &view_layout); - if (x >= view_layout.x && - x < view_layout.x + view_layout.width && - y >= view_layout.y && - y < view_layout.y + view_layout.height) - return view; - } - - return NULL; -} - -static ClutterActor * -_clutter_stage_do_pick (ClutterStage *stage, - float x, - float y, - ClutterPickMode mode, - MtkRegion **clear_area) -{ - ClutterActor *actor = CLUTTER_ACTOR (stage); - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - float stage_width, stage_height; - ClutterStageView *view = NULL; - - priv = clutter_stage_get_instance_private (stage); - - if (CLUTTER_ACTOR_IN_DESTRUCTION (stage)) - return actor; - - if (G_UNLIKELY (clutter_pick_debug_flags & CLUTTER_DEBUG_NOP_PICKING)) - return actor; - - if (G_UNLIKELY (priv->impl == NULL)) - return actor; - - clutter_actor_get_size (CLUTTER_ACTOR (stage), &stage_width, &stage_height); - if (x < 0 || x >= stage_width || y < 0 || y >= stage_height) - return actor; - - view = clutter_stage_get_view_at (stage, x, y); - if (view) - return _clutter_stage_do_pick_on_view (stage, x, y, mode, view, clear_area); - - return actor; -} - -static void -clutter_stage_real_apply_transform (ClutterActor *stage, - graphene_matrix_t *matrix) -{ - ClutterStagePrivate *priv = - clutter_stage_get_instance_private (CLUTTER_STAGE (stage)); - - /* FIXME: we probably shouldn't be explicitly resetting the matrix - * here... */ - graphene_matrix_init_from_matrix (matrix, &priv->view); -} - -static void -clutter_stage_constructed (GObject *gobject) -{ - ClutterStage *self = CLUTTER_STAGE (gobject); - ClutterStageManager *stage_manager; - - stage_manager = clutter_stage_manager_get_default (); - - /* this will take care to sinking the floating reference */ - _clutter_stage_manager_add_stage (stage_manager, self); - - G_OBJECT_CLASS (clutter_stage_parent_class)->constructed (gobject); -} - -static void -clutter_stage_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterStage *stage = CLUTTER_STAGE (object); - - switch (prop_id) - { - case PROP_TITLE: - clutter_stage_set_title (stage, g_value_get_string (value)); - break; - - case PROP_KEY_FOCUS: - clutter_stage_set_key_focus (stage, g_value_get_object (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_stage_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterStagePrivate *priv = - clutter_stage_get_instance_private (CLUTTER_STAGE (gobject)); - - switch (prop_id) - { - case PROP_PERSPECTIVE: - g_value_set_boxed (value, &priv->perspective); - break; - - case PROP_TITLE: - g_value_set_string (value, priv->title); - break; - - case PROP_KEY_FOCUS: - g_value_set_object (value, priv->key_focused_actor); - break; - - case PROP_IS_GRABBED: - g_value_set_boolean (value, !!priv->topmost_grab); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_stage_dispose (GObject *object) -{ - ClutterStage *stage = CLUTTER_STAGE (object); - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - ClutterStageManager *stage_manager; - - clutter_actor_hide (CLUTTER_ACTOR (object)); - - _clutter_clear_events_queue (); - - if (priv->impl != NULL) - { - CLUTTER_NOTE (BACKEND, "Disposing of the stage implementation"); - - if (clutter_actor_is_realized (CLUTTER_ACTOR (object))) - _clutter_stage_window_unrealize (priv->impl); - - g_object_unref (priv->impl); - priv->impl = NULL; - } - - clutter_actor_destroy_all_children (CLUTTER_ACTOR (object)); - - g_slist_free_full (priv->pending_relayouts, - (GDestroyNotify) g_object_unref); - priv->pending_relayouts = NULL; - - /* this will release the reference on the stage */ - stage_manager = clutter_stage_manager_get_default (); - _clutter_stage_manager_remove_stage (stage_manager, stage); - - g_hash_table_remove_all (priv->pointer_devices); - g_hash_table_remove_all (priv->touch_sequences); - - G_OBJECT_CLASS (clutter_stage_parent_class)->dispose (object); -} - -static void -clutter_stage_finalize (GObject *object) -{ - ClutterStage *stage = CLUTTER_STAGE (object); - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - - g_queue_foreach (priv->event_queue, (GFunc) clutter_event_free, NULL); - g_queue_free (priv->event_queue); - - g_assert (priv->cur_event_actors->len == 0); - g_ptr_array_free (priv->cur_event_actors, TRUE); - g_assert (priv->cur_event_emission_chain->len == 0); - g_array_unref (priv->cur_event_emission_chain); - - g_assert (priv->all_active_gestures->len == 0); - g_ptr_array_free (priv->all_active_gestures, TRUE); - - g_hash_table_destroy (priv->pointer_devices); - g_hash_table_destroy (priv->touch_sequences); - - g_free (priv->title); - - G_OBJECT_CLASS (clutter_stage_parent_class)->finalize (object); -} - -static void -clutter_stage_real_paint_view (ClutterStage *stage, - ClutterStageView *view, - const MtkRegion *redraw_clip, - ClutterFrame *frame) -{ - clutter_stage_do_paint_view (stage, view, frame, redraw_clip); -} - -static void -clutter_stage_paint (ClutterActor *actor, - ClutterPaintContext *paint_context) -{ - ClutterStageView *view; - - CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (actor, paint_context); - - view = clutter_paint_context_get_stage_view (paint_context); - if (view && - G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_MAX_RENDER_TIME)) - { - MtkRectangle view_layout; - ClutterFrameClock *frame_clock; - g_autoptr (GString) string = NULL; - PangoLayout *layout; - PangoRectangle logical; - ClutterColor color; - g_autoptr (ClutterPaintNode) node = NULL; - ClutterActorBox box; - - clutter_stage_view_get_layout (view, &view_layout); - frame_clock = clutter_stage_view_get_frame_clock (view); - - string = clutter_frame_clock_get_max_render_time_debug_info (frame_clock); - - layout = clutter_actor_create_pango_layout (actor, string->str); - pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT); - pango_layout_get_pixel_extents (layout, NULL, &logical); - - clutter_color_init (&color, 255, 255, 255, 255); - node = clutter_text_node_new (layout, &color); - - box.x1 = view_layout.x; - box.y1 = view_layout.y + 30; - box.x2 = box.x1 + logical.width; - box.y2 = box.y1 + logical.height; - clutter_paint_node_add_rectangle (node, &box); - - clutter_paint_node_paint (node, paint_context); - - g_object_unref (layout); - } -} - -static void -clutter_stage_class_init (ClutterStageClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - - gobject_class->constructed = clutter_stage_constructed; - gobject_class->set_property = clutter_stage_set_property; - gobject_class->get_property = clutter_stage_get_property; - gobject_class->dispose = clutter_stage_dispose; - gobject_class->finalize = clutter_stage_finalize; - - actor_class->allocate = clutter_stage_allocate; - actor_class->get_preferred_width = clutter_stage_get_preferred_width; - actor_class->get_preferred_height = clutter_stage_get_preferred_height; - actor_class->get_paint_volume = clutter_stage_get_paint_volume; - actor_class->realize = clutter_stage_realize; - actor_class->unrealize = clutter_stage_unrealize; - actor_class->show = clutter_stage_show; - actor_class->hide = clutter_stage_hide; - actor_class->hide_all = clutter_stage_hide_all; - actor_class->queue_relayout = clutter_stage_real_queue_relayout; - actor_class->apply_transform = clutter_stage_real_apply_transform; - actor_class->paint = clutter_stage_paint; - - klass->paint_view = clutter_stage_real_paint_view; - - /** - * ClutterStage:perspective: - * - * The parameters used for the perspective projection from 3D - * coordinates to 2D - */ - obj_props[PROP_PERSPECTIVE] = - g_param_spec_boxed ("perspective", NULL, NULL, - CLUTTER_TYPE_PERSPECTIVE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterStage:title: - * - * The stage's title - usually displayed in stage windows title decorations. - */ - obj_props[PROP_TITLE] = - g_param_spec_string ("title", NULL, NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterStage:key-focus: - * - * The [class@Clutter.Actor] that will receive key events from the underlying - * windowing system. - * - * If %NULL, the #ClutterStage will receive the events. - */ - obj_props[PROP_KEY_FOCUS] = - g_param_spec_object ("key-focus", NULL, NULL, - CLUTTER_TYPE_ACTOR, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - /** - * ClutterStage:is-grabbed: - * - * %TRUE if there is currently an active grab on the stage. - */ - obj_props[PROP_IS_GRABBED] = - g_param_spec_boolean ("is-grabbed", NULL, NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_EXPLICIT_NOTIFY); - - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); - - /** - * ClutterStage::activate: - * @stage: the stage which was activated - * - * The signal is emitted when the stage receives key focus - * from the underlying window system. - */ - stage_signals[ACTIVATE] = - g_signal_new (I_("activate"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterStageClass, activate), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - /** - * ClutterStage::deactivate: - * @stage: the stage which was deactivated - * - * The signal is emitted when the stage loses key focus - * from the underlying window system. - */ - stage_signals[DEACTIVATE] = - g_signal_new (I_("deactivate"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterStageClass, deactivate), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - /** - * ClutterStage::before-update: - * @stage: the #ClutterStage - * @view: a #ClutterStageView - * @frame: a #ClutterFrame - */ - stage_signals[BEFORE_UPDATE] = - g_signal_new (I_("before-update"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - _clutter_marshal_VOID__OBJECT_BOXED, - G_TYPE_NONE, 2, - CLUTTER_TYPE_STAGE_VIEW, - CLUTTER_TYPE_FRAME | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (stage_signals[BEFORE_UPDATE], - G_TYPE_FROM_CLASS (gobject_class), - _clutter_marshal_VOID__OBJECT_BOXEDv); - - /** - * ClutterStage::prepare-frame: - * @stage: the stage that received the event - * @view: a #ClutterStageView - * @frame: a #ClutterFrame - * - * The signal is emitted after the stage is updated, - * before the stage is painted, even if it will not be painted. - */ - stage_signals[PREPARE_FRAME] = - g_signal_new (I_("prepare-frame"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - _clutter_marshal_VOID__OBJECT_BOXED, - G_TYPE_NONE, 2, - CLUTTER_TYPE_STAGE_VIEW, - CLUTTER_TYPE_FRAME | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (stage_signals[PREPARE_FRAME], - G_TYPE_FROM_CLASS (gobject_class), - _clutter_marshal_VOID__OBJECT_BOXEDv); - - /** - * ClutterStage::before-paint: - * @stage: the stage that received the event - * @view: a #ClutterStageView - * @frame: a #ClutterFrame - * - * The signal is emitted before the stage is painted. - */ - stage_signals[BEFORE_PAINT] = - g_signal_new (I_("before-paint"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterStageClass, before_paint), - NULL, NULL, - _clutter_marshal_VOID__OBJECT_BOXED, - G_TYPE_NONE, 2, - CLUTTER_TYPE_STAGE_VIEW, - CLUTTER_TYPE_FRAME | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (stage_signals[BEFORE_PAINT], - G_TYPE_FROM_CLASS (gobject_class), - _clutter_marshal_VOID__OBJECT_BOXEDv); - - /** - * ClutterStage::after-paint: - * @stage: the stage that received the event - * @view: a #ClutterStageView - * @frame: a #ClutterFrame - * - * The signal is emitted after the stage is painted, - * but before the results are displayed on the screen.0 - */ - stage_signals[AFTER_PAINT] = - g_signal_new (I_("after-paint"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - 0, /* no corresponding vfunc */ - NULL, NULL, - _clutter_marshal_VOID__OBJECT_BOXED, - G_TYPE_NONE, 2, - CLUTTER_TYPE_STAGE_VIEW, - CLUTTER_TYPE_FRAME | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (stage_signals[AFTER_PAINT], - G_TYPE_FROM_CLASS (gobject_class), - _clutter_marshal_VOID__OBJECT_BOXEDv); - - /** - * ClutterStage::after-update: - * @stage: the #ClutterStage - * @view: a #ClutterStageView - * @frame: a #ClutterFrame - */ - stage_signals[AFTER_UPDATE] = - g_signal_new (I_("after-update"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - _clutter_marshal_VOID__OBJECT_BOXED, - G_TYPE_NONE, 2, - CLUTTER_TYPE_STAGE_VIEW, - CLUTTER_TYPE_FRAME | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (stage_signals[AFTER_UPDATE], - G_TYPE_FROM_CLASS (gobject_class), - _clutter_marshal_VOID__OBJECT_BOXEDv); - - /** - * ClutterStage::paint-view: - * @stage: the stage that received the event - * @view: a #ClutterStageView - * @redraw_clip: a #MtkRegion with the redraw clip - * @frame: a #ClutterFrame - * - * The signal is emitted before a [class@Clutter.StageView] is being - * painted. - * - * The view is painted in the default handler. Hence, if you want to perform - * some action after the view is painted, like reading the contents of the - * framebuffer, use [func@GObject.signal_connect_after] or pass %G_CONNECT_AFTER. - */ - stage_signals[PAINT_VIEW] = - g_signal_new (I_("paint-view"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterStageClass, paint_view), - NULL, NULL, - _clutter_marshal_VOID__OBJECT_BOXED_BOXED, - G_TYPE_NONE, 3, - CLUTTER_TYPE_STAGE_VIEW, - MTK_TYPE_REGION | G_SIGNAL_TYPE_STATIC_SCOPE, - CLUTTER_TYPE_FRAME | G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_set_va_marshaller (stage_signals[PAINT_VIEW], - G_TYPE_FROM_CLASS (gobject_class), - _clutter_marshal_VOID__OBJECT_BOXED_BOXEDv); - - /** - * ClutterStage::presented: (skip) - * @stage: the stage that received the event - * @view: the #ClutterStageView presented - * @frame_info: a #ClutterFrameInfo - * - * Signals that the #ClutterStage was presented on the screen to the user. - */ - stage_signals[PRESENTED] = - g_signal_new (I_("presented"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - _clutter_marshal_VOID__OBJECT_POINTER, - G_TYPE_NONE, 2, - CLUTTER_TYPE_STAGE_VIEW, - G_TYPE_POINTER); - g_signal_set_va_marshaller (stage_signals[PRESENTED], - G_TYPE_FROM_CLASS (gobject_class), - _clutter_marshal_VOID__OBJECT_POINTERv); - - /** - * ClutterStage::gl-video-memory-purged: (skip) - * @stage: the stage that received the event - * - * Signals that the underlying GL driver has had its texture memory purged - * so anything presently held in texture memory is now invalidated, and - * likely corrupt. It needs redrawing. - */ - stage_signals[GL_VIDEO_MEMORY_PURGED] = - g_signal_new (I_("gl-video-memory-purged"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - klass->activate = clutter_stage_real_activate; - klass->deactivate = clutter_stage_real_deactivate; -} - -static void -on_seat_unfocus_inhibited_changed (ClutterStage *stage, - ClutterSeat *seat) -{ - ClutterInputDevice *device; - graphene_point_t point = GRAPHENE_POINT_INIT_ZERO; - - device = clutter_seat_get_pointer (seat); - - if (!clutter_stage_get_device_coords (stage, device, NULL, &point)) - return; - - clutter_stage_pick_and_update_device (stage, - device, - NULL, NULL, - CLUTTER_DEVICE_UPDATE_IGNORE_CACHE | - CLUTTER_DEVICE_UPDATE_EMIT_CROSSING, - point, - CLUTTER_CURRENT_TIME); -} - -static void -clutter_stage_init (ClutterStage *self) -{ - MtkRectangle geom = { 0, }; - ClutterStagePrivate *priv; - ClutterStageWindow *impl; - ClutterBackend *backend; - ClutterSeat *seat; - GError *error; - - /* a stage is a top-level object */ - CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IS_TOPLEVEL); - - priv = clutter_stage_get_instance_private (self); - - CLUTTER_NOTE (BACKEND, "Creating stage from the default backend"); - backend = clutter_get_default_backend (); - - error = NULL; - impl = _clutter_backend_create_stage (backend, self, &error); - - if (G_LIKELY (impl != NULL)) - { - _clutter_stage_set_window (self, impl); - _clutter_stage_window_get_geometry (priv->impl, &geom); - } - else - { - if (error != NULL) - { - g_critical ("Unable to create a new stage implementation: %s", - error->message); - g_error_free (error); - } - else - g_critical ("Unable to create a new stage implementation."); - } - - priv->event_queue = g_queue_new (); - priv->cur_event_actors = g_ptr_array_sized_new (32); - priv->cur_event_emission_chain = - g_array_sized_new (FALSE, TRUE, sizeof (EventReceiver), 32); - g_array_set_clear_func (priv->cur_event_emission_chain, - (GDestroyNotify) free_event_receiver); - - priv->pointer_devices = - g_hash_table_new_full (NULL, NULL, - NULL, (GDestroyNotify) free_pointer_device_entry); - priv->touch_sequences = - g_hash_table_new_full (NULL, NULL, - NULL, (GDestroyNotify) free_pointer_device_entry); - - priv->all_active_gestures = g_ptr_array_sized_new (64); - - clutter_actor_set_background_color (CLUTTER_ACTOR (self), - &default_stage_color); - - clutter_stage_queue_actor_relayout (self, CLUTTER_ACTOR (self)); - - clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); - clutter_stage_set_title (self, g_get_prgname ()); - clutter_stage_set_key_focus (self, NULL); - clutter_stage_set_viewport (self, geom.width, geom.height); - - seat = clutter_backend_get_default_seat (backend); - g_signal_connect_object (seat, "is-unfocus-inhibited-changed", - G_CALLBACK (on_seat_unfocus_inhibited_changed), - self, - G_CONNECT_SWAPPED); -} - -static void -clutter_stage_set_perspective (ClutterStage *stage, - ClutterPerspective *perspective) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - - if (priv->perspective.fovy == perspective->fovy && - priv->perspective.aspect == perspective->aspect && - priv->perspective.z_near == perspective->z_near && - priv->perspective.z_far == perspective->z_far) - return; - - priv->perspective = *perspective; - - graphene_matrix_init_perspective (&priv->projection, - priv->perspective.fovy, - priv->perspective.aspect, - priv->perspective.z_near, - priv->perspective.z_far); - graphene_matrix_inverse (&priv->projection, - &priv->inverse_projection); - - _clutter_stage_dirty_projection (stage); - clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); -} - -/** - * clutter_stage_get_perspective: - * @stage: A #ClutterStage - * @perspective: (out caller-allocates) (allow-none): return location for a - * #ClutterPerspective - * - * Retrieves the stage perspective. - */ -void -clutter_stage_get_perspective (ClutterStage *stage, - ClutterPerspective *perspective) -{ - ClutterStagePrivate *priv; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - g_return_if_fail (perspective != NULL); - - priv = clutter_stage_get_instance_private (stage); - *perspective = priv->perspective; -} - -/* - * clutter_stage_get_projection_matrix: - * @stage: A #ClutterStage - * @projection: return location for a #graphene_matrix_t representing the - * perspective projection applied to actors on the given - * @stage. - * - * Retrieves the @stage's projection matrix. This is derived from the - * current perspective. - */ -void -_clutter_stage_get_projection_matrix (ClutterStage *stage, - graphene_matrix_t *projection) -{ - ClutterStagePrivate *priv; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - g_return_if_fail (projection != NULL); - - priv = clutter_stage_get_instance_private (stage); - *projection = priv->projection; -} - -/* This simply provides a simple mechanism for us to ensure that - * the projection matrix gets re-asserted before painting. - * - * This is used when switching between multiple stages */ -void -_clutter_stage_dirty_projection (ClutterStage *stage) -{ - ClutterStagePrivate *priv; - GList *l; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - - priv = clutter_stage_get_instance_private (stage); - - for (l = _clutter_stage_window_get_views (priv->impl); l; l = l->next) - { - ClutterStageView *view = l->data; - - clutter_stage_view_invalidate_projection (view); - } -} - -/* - * clutter_stage_set_viewport: - * @stage: A #ClutterStage - * @width: The width to render the stage at, in window coordinates - * @height: The height to render the stage at, in window coordinates - * - * Sets the stage viewport. The viewport defines a final scale and - * translation of your rendered stage and actors. This lets you render - * your stage into a subregion of the stage window or you could use it to - * pan a subregion of the stage if your stage window is smaller then - * the stage. (XXX: currently this isn't possible) - * - * Unlike a scale and translation done using the modelview matrix this - * is done after everything has had perspective projection applied, so - * for example if you were to pan across a subregion of the stage using - * the viewport then you would not see a change in perspective for the - * actors on the stage. - * - * Normally the stage viewport will automatically track the size of the - * stage window with no offset so the stage will fill your window. This - * behaviour can be changed with the "viewport-mimics-window" property - * which will automatically be set to FALSE if you use this API. If - * you want to revert to the original behaviour then you should set - * this property back to %TRUE using - * clutter_stage_set_viewport_mimics_window(). - * (XXX: If we were to make this API public then we might want to do - * add that property.) - * - * Note: currently this interface only support integer precision - * offsets and sizes for viewports but the interface takes floats because - * OpenGL 4.0 has introduced floating point viewports which we might - * want to expose via this API eventually. - */ -static void -clutter_stage_set_viewport (ClutterStage *stage, - float width, - float height) -{ - ClutterStagePrivate *priv; - float x, y; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - - priv = clutter_stage_get_instance_private (stage); - - x = 0.f; - y = 0.f; - width = roundf (width); - height = roundf (height); - - if (x == priv->viewport[0] && - y == priv->viewport[1] && - width == priv->viewport[2] && - height == priv->viewport[3]) - return; - - priv->viewport[0] = x; - priv->viewport[1] = y; - priv->viewport[2] = width; - priv->viewport[3] = height; - - clutter_stage_update_view_perspective (stage); - _clutter_stage_dirty_viewport (stage); - - queue_full_redraw (stage); -} - -/* This simply provides a simple mechanism for us to ensure that - * the viewport gets re-asserted before next painting. - * - * This is used when switching between multiple stages */ -void -_clutter_stage_dirty_viewport (ClutterStage *stage) -{ - ClutterStagePrivate *priv; - GList *l; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - - priv = clutter_stage_get_instance_private (stage); - - for (l = _clutter_stage_window_get_views (priv->impl); l; l = l->next) - { - ClutterStageView *view = l->data; - - clutter_stage_view_invalidate_viewport (view); - } -} - -/* - * clutter_stage_get_viewport: - * @stage: A #ClutterStage - * @x: A location for the X position where the stage is rendered, - * in window coordinates. - * @y: A location for the Y position where the stage is rendered, - * in window coordinates. - * @width: A location for the width the stage is rendered at, - * in window coordinates. - * @height: A location for the height the stage is rendered at, - * in window coordinates. - * - * Returns the viewport offset and size set using - * clutter_stage_set_viewport() or if the "viewport-mimics-window" property - * is TRUE then @x and @y will be set to 0 and @width and @height will equal - * the width if the stage window. - */ -void -_clutter_stage_get_viewport (ClutterStage *stage, - float *x, - float *y, - float *width, - float *height) -{ - ClutterStagePrivate *priv; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - - priv = clutter_stage_get_instance_private (stage); - - *x = priv->viewport[0]; - *y = priv->viewport[1]; - *width = priv->viewport[2]; - *height = priv->viewport[3]; -} - -/** - * clutter_stage_read_pixels: - * @stage: A #ClutterStage - * @x: x coordinate of the first pixel that is read from stage - * @y: y coordinate of the first pixel that is read from stage - * @width: Width dimension of pixels to be read, or -1 for the - * entire stage width - * @height: Height dimension of pixels to be read, or -1 for the - * entire stage height - * - * Makes a screenshot of the stage in RGBA 8bit data, returns a - * linear buffer with @width * 4 as rowstride. - * - * The alpha data contained in the returned buffer is driver-dependent, - * and not guaranteed to hold any sensible value. - * - * Return value: (transfer full) (array): a pointer to newly allocated memory with the buffer - * or %NULL if the read failed. Use g_free() on the returned data - * to release the resources it has allocated. - */ -guchar * -clutter_stage_read_pixels (ClutterStage *stage, - gint x, - gint y, - gint width, - gint height) -{ - ClutterStagePrivate *priv; - ClutterActorBox box; - GList *l; - ClutterStageView *view; - g_autoptr (MtkRegion) clip = NULL; - MtkRectangle clip_rect; - CoglFramebuffer *framebuffer; - float view_scale; - float pixel_width; - float pixel_height; - uint8_t *pixels; - - COGL_TRACE_BEGIN_SCOPED (ClutterStageReadPixels, "Clutter::Stage::read_pixels()"); - - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL); - - priv = clutter_stage_get_instance_private (stage); - - clutter_actor_get_allocation_box (CLUTTER_ACTOR (stage), &box); - - if (width < 0) - width = ceilf (box.x2 - box.x1); - - if (height < 0) - height = ceilf (box.y2 - box.y1); - - l = _clutter_stage_window_get_views (priv->impl); - - if (!l) - return NULL; - - /* XXX: We only read the first view. Needs different API for multi view screen - * capture. */ - view = l->data; - - clutter_stage_view_get_layout (view, &clip_rect); - clip = mtk_region_create_rectangle (&clip_rect); - mtk_region_intersect_rectangle (clip, - &MTK_RECTANGLE_INIT (x, y, width, height)); - clip_rect = mtk_region_get_extents (clip); - - if (clip_rect.width == 0 || clip_rect.height == 0) - return NULL; - - framebuffer = clutter_stage_view_get_framebuffer (view); - clutter_stage_do_paint_view (stage, view, NULL, clip); - - view_scale = clutter_stage_view_get_scale (view); - pixel_width = roundf (clip_rect.width * view_scale); - pixel_height = roundf (clip_rect.height * view_scale); - - pixels = g_malloc0 (pixel_width * pixel_height * 4); - cogl_framebuffer_read_pixels (framebuffer, - clip_rect.x * view_scale, - clip_rect.y * view_scale, - pixel_width, pixel_height, - COGL_PIXEL_FORMAT_RGBA_8888, - pixels); - - return pixels; -} - -/** - * clutter_stage_get_actor_at_pos: - * @stage: a #ClutterStage - * @pick_mode: how the scene graph should be painted - * @x: X coordinate to check - * @y: Y coordinate to check - * - * Checks the scene at the coordinates @x and @y and returns a pointer - * to the [class@Clutter.Actor] at those coordinates. The result is the actor which - * would be at the specified location on the next redraw, and is not - * necessarily that which was there on the previous redraw. This allows the - * function to perform chronologically correctly after any queued changes to - * the scene, and even if nothing has been drawn. - * - * By using @pick_mode it is possible to control which actors will be - * painted and thus available. - * - * Return value: (transfer none): the actor at the specified coordinates, - * if any - */ -ClutterActor * -clutter_stage_get_actor_at_pos (ClutterStage *stage, - ClutterPickMode pick_mode, - float x, - float y) -{ - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL); - - return _clutter_stage_do_pick (stage, x, y, pick_mode, NULL); -} - -/** - * clutter_stage_set_title: - * @stage: A #ClutterStage - * @title: A utf8 string for the stage windows title. - * - * Sets the stage title. - **/ -void -clutter_stage_set_title (ClutterStage *stage, - const gchar *title) -{ - ClutterStagePrivate *priv; - ClutterStageWindow *impl; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - - priv = clutter_stage_get_instance_private (stage); - - g_free (priv->title); - priv->title = g_strdup (title); - - impl = CLUTTER_STAGE_WINDOW (priv->impl); - if (CLUTTER_STAGE_WINDOW_GET_IFACE(impl)->set_title != NULL) - CLUTTER_STAGE_WINDOW_GET_IFACE (impl)->set_title (impl, priv->title); - - g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_TITLE]); -} - -/** - * clutter_stage_get_title: - * @stage: A #ClutterStage - * - * Gets the stage title. - * - * Return value: pointer to the title string for the stage. The - * returned string is owned by the actor and should not - * be modified or freed. - **/ -const gchar * -clutter_stage_get_title (ClutterStage *stage) -{ - ClutterStagePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL); - - priv = clutter_stage_get_instance_private (stage); - return priv->title; -} - -/** - * clutter_stage_set_key_focus: - * @stage: the #ClutterStage - * @actor: (allow-none): the actor to set key focus to, or %NULL - * - * Sets the key focus on @actor. An actor with key focus will receive - * all the key events. If @actor is %NULL, the stage will receive - * focus. - */ -void -clutter_stage_set_key_focus (ClutterStage *stage, - ClutterActor *actor) -{ - ClutterStagePrivate *priv; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor)); - - priv = clutter_stage_get_instance_private (stage); - - /* normalize the key focus. NULL == stage */ - if (actor == CLUTTER_ACTOR (stage)) - actor = NULL; - - /* avoid emitting signals and notifications if we're setting the same - * actor as the key focus - */ - if (priv->key_focused_actor == actor) - return; - - if (priv->key_focused_actor != NULL) - { - ClutterActor *old_focused_actor; - - old_focused_actor = priv->key_focused_actor; - - /* set key_focused_actor to NULL before emitting the signal or someone - * might hide the previously focused actor in the signal handler - */ - priv->key_focused_actor = NULL; - - _clutter_actor_set_has_key_focus (old_focused_actor, FALSE); - } - else - _clutter_actor_set_has_key_focus (CLUTTER_ACTOR (stage), FALSE); - - /* Note, if someone changes key focus in focus-out signal handler we'd be - * overriding the latter call below moving the focus where it was originally - * intended. The order of events would be: - * 1st focus-out, 2nd focus-out (on stage), 2nd focus-in, 1st focus-in - */ - priv->key_focused_actor = actor; - - /* If the key focused actor is allowed to receive key events according - * to the given grab (or there is none) set key focus on it, otherwise - * key focus is delayed until there are grabbing conditions that allow - * it to get key focus. - */ - if (!priv->topmost_grab || - priv->topmost_grab->actor == CLUTTER_ACTOR (stage) || - priv->topmost_grab->actor == actor || - (actor && clutter_actor_contains (priv->topmost_grab->actor, actor))) - { - if (actor != NULL) - _clutter_actor_set_has_key_focus (actor, TRUE); - else - _clutter_actor_set_has_key_focus (CLUTTER_ACTOR (stage), TRUE); - } - - g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_KEY_FOCUS]); -} - -/** - * clutter_stage_get_key_focus: - * @stage: the #ClutterStage - * - * Retrieves the actor that is currently under key focus. - * - * Return value: (transfer none): the actor with key focus, or the stage - */ -ClutterActor * -clutter_stage_get_key_focus (ClutterStage *stage) -{ - ClutterStagePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL); - - priv = clutter_stage_get_instance_private (stage); - if (priv->key_focused_actor) - return priv->key_focused_actor; - - return CLUTTER_ACTOR (stage); -} - -/*** Perspective boxed type ******/ - -static gpointer -clutter_perspective_copy (gpointer data) -{ - if (G_LIKELY (data)) - return g_memdup2 (data, sizeof (ClutterPerspective)); - - return NULL; -} - -static void -clutter_perspective_free (gpointer data) -{ - if (G_LIKELY (data)) - g_free (data); -} - -G_DEFINE_BOXED_TYPE (ClutterPerspective, clutter_perspective, - clutter_perspective_copy, - clutter_perspective_free); - -/** - * clutter_stage_ensure_viewport: - * @stage: a #ClutterStage - * - * Ensures that the GL viewport is updated with the current - * stage window size. - * - * This function will queue a redraw of @stage. - * - * This function should not be called by applications; it is used - * when embedding a #ClutterStage into a toolkit with another - * windowing system, like GTK+. - */ -void -clutter_stage_ensure_viewport (ClutterStage *stage) -{ - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - - _clutter_stage_dirty_viewport (stage); - - clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); -} - -# define _DEG_TO_RAD(d) ((d) * ((float) G_PI / 180.0f)) - -/* This calculates a distance into the view frustum to position the - * stage so there is a decent amount of space to position geometry - * between the stage and the near clipping plane. - * - * Some awkward issues with this problem are: - * - It's not possible to have a gap as large as the stage size with - * a fov > 53° which is basically always the case since the default - * fov is 60°. - * - This can be deduced if you consider that this requires a - * triangle as wide as it is deep to fit in the frustum in front - * of the z_near plane. That triangle will always have an angle - * of 53.13° at the point sitting on the z_near plane, but if the - * frustum has a wider fov angle the left/right clipping planes - * can never converge with the two corners of our triangle no - * matter what size the triangle has. - * - With a fov > 53° there is a trade off between maximizing the gap - * size relative to the stage size but not losing depth precision. - * - Perhaps ideally we wouldn't just consider the fov on the y-axis - * that is usually used to define a perspective, we would consider - * the fov of the axis with the largest stage size so the gap would - * accommodate that size best. - * - * After going around in circles a few times with how to handle these - * issues, we decided in the end to go for the simplest solution to - * start with instead of an elaborate function that handles arbitrary - * fov angles that we currently have no use-case for. - * - * The solution assumes a fovy of 60° and for that case gives a gap - * that's 85% of the stage height. We can consider more elaborate - * functions if necessary later. - * - * One guide we had to steer the gap size we support is the - * interactive test, test-texture-quality which expects to animate an - * actor to +400 on the z axis with a stage size of 640x480. A gap - * that's 85% of the stage height gives a gap of 408 in that case. - */ -static float -calculate_z_translation (float z_near) -{ - /* This solution uses fairly basic trigonometry, but is seems worth - * clarifying the particular geometry we are looking at in-case - * anyone wants to develop this further later. Not sure how well an - * ascii diagram is going to work :-) - * - * |--- stage_height ---| - * | stage line | - * ╲━━━━━━━━━━━━━━━━━━━━━╱------------ - * ╲. (2) │ .╱ | | - * C ╲ . │ . ╱ gap| | - * =0.5°╲ . a │ . ╱ | | - * b╲(1). D│ . ╱ | | - * ╲ B.│. ╱near plane | | - * A= ╲━━━━━━━━━╱------------- | - * 120° ╲ c │ ╱ | z_2d - * ╲ │ ╱ z_near | - * left ╲ │ ╱ | | - * clip 60°fovy | | - * plane ╳---------------------- - * | - * | - * origin line - * - * The area of interest is the triangle labeled (1) at the top left - * marked with the ... line (a) from where the origin line crosses - * the near plane to the top left where the stage line cross the - * left clip plane. - * - * The sides of the triangle are a, b and c and the corresponding - * angles opposite those sides are A, B and C. - * - * The angle of C is what trades off the gap size we have relative - * to the stage size vs the depth precision we have. - * - * As mentioned above we arove at the angle for C is by working - * backwards from how much space we want for test-texture-quality. - * With a stage_height of 480 we want a gap > 400, ideally we also - * wanted a somewhat round number as a percentage of the height for - * documentation purposes. ~87% or a gap of ~416 is the limit - * because that's where we approach a C angle of 0° and effectively - * loose all depth precision. - * - * So for our test app with a stage_height of 480 if we aim for a - * gap of 408 (85% of 480) we can get the angle D as - * atan (stage_height/2/408) = 30.5°. - * - * That gives us the angle for B as 90° - 30.5° = 59.5° - * - * We can already determine that A has an angle of (fovy/2 + 90°) = - * 120° - * - * Therefore C = 180 - A - B = 0.5° - * - * The length of c = z_near * tan (30°) - * - * Now we can use the rule a/SinA = c/SinC to calculate the - * length of a. After some rearranging that gives us: - * - * a c - * ---------- = ---------- - * sin (120°) sin (0.5°) - * - * c * sin (120°) - * a = -------------- - * sin (0.5°) - * - * And with that we can determine z_2d = cos (D) * a = - * cos (30.5°) * a + z_near: - * - * c * sin (120°) * cos (30.5°) - * z_2d = --------------------------- + z_near - * sin (0.5°) - */ - - /* We expect the compiler should boil this down to z_near * CONSTANT - * already, but just in case we use precomputed constants - */ -#if 0 -# define A tanf (_DEG_TO_RAD (30.f)) -# define B sinf (_DEG_TO_RAD (120.f)) -# define C cosf (_DEG_TO_RAD (30.5f)) -# define D sinf (_DEG_TO_RAD (.5f)) -#else -# define A 0.57735025882720947265625f -# define B 0.866025388240814208984375f -# define C 0.86162912845611572265625f -# define D 0.00872653536498546600341796875f -#endif - - return z_near - * A * B * C - / D - + z_near; -} - -static void -view_2d_in_perspective (graphene_matrix_t *matrix, - float fov_y, - float aspect, - float z_near, - float z_2d, - float width_2d, - float height_2d) -{ - float top = z_near * tan (fov_y * G_PI / 360.0); - float left = -top * aspect; - float right = top * aspect; - float bottom = -top; - - float left_2d_plane = left / z_near * z_2d; - float right_2d_plane = right / z_near * z_2d; - float bottom_2d_plane = bottom / z_near * z_2d; - float top_2d_plane = top / z_near * z_2d; - - float width_2d_start = right_2d_plane - left_2d_plane; - float height_2d_start = top_2d_plane - bottom_2d_plane; - - /* Factors to scale from framebuffer geometry to frustum - * cross-section geometry. */ - float width_scale = width_2d_start / width_2d; - float height_scale = height_2d_start / height_2d; - - graphene_matrix_init_scale (matrix, width_scale, -height_scale, width_scale); - graphene_matrix_translate (matrix, - &GRAPHENE_POINT3D_INIT (left_2d_plane, - top_2d_plane, - -z_2d)); -} - -static void -clutter_stage_update_view_perspective (ClutterStage *stage) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - ClutterPerspective perspective; - float z_2d; - - perspective = priv->perspective; - - perspective.fovy = 60.0; /* 60 Degrees */ - perspective.z_near = 1.0; - perspective.aspect = priv->viewport[2] / priv->viewport[3]; - z_2d = calculate_z_translation (perspective.z_near); - - /* NB: z_2d is only enough room for 85% of the stage_height between - * the stage and the z_near plane. For behind the stage plane we - * want a more consistent gap of 10 times the stage_height before - * hitting the far plane so we calculate that relative to the final - * height of the stage plane at the z_2d_distance we got... */ - perspective.z_far = z_2d + - tanf (_DEG_TO_RAD (perspective.fovy / 2.0f)) * z_2d * 20.0f; - - clutter_stage_set_perspective (stage, &perspective); - - view_2d_in_perspective (&priv->view, - perspective.fovy, - perspective.aspect, - perspective.z_near, - z_2d, - priv->viewport[2], - priv->viewport[3]); - - clutter_actor_invalidate_transform (CLUTTER_ACTOR (stage)); -} - -void -_clutter_stage_maybe_setup_viewport (ClutterStage *stage, - ClutterStageView *view) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - - if (clutter_stage_view_is_dirty_viewport (view)) - { - MtkRectangle view_layout; - float fb_scale; - float viewport_offset_x; - float viewport_offset_y; - float viewport_x; - float viewport_y; - float viewport_width; - float viewport_height; - - CLUTTER_NOTE (PAINT, - "Setting up the viewport { w:%f, h:%f }", - priv->viewport[2], - priv->viewport[3]); - - fb_scale = clutter_stage_view_get_scale (view); - clutter_stage_view_get_layout (view, &view_layout); - - viewport_offset_x = view_layout.x * fb_scale; - viewport_offset_y = view_layout.y * fb_scale; - viewport_x = roundf (priv->viewport[0] * fb_scale - viewport_offset_x); - viewport_y = roundf (priv->viewport[1] * fb_scale - viewport_offset_y); - viewport_width = roundf (priv->viewport[2] * fb_scale); - viewport_height = roundf (priv->viewport[3] * fb_scale); - - clutter_stage_view_set_viewport (view, - viewport_x, viewport_y, - viewport_width, viewport_height); - } - - if (clutter_stage_view_is_dirty_projection (view)) - clutter_stage_view_set_projection (view, &priv->projection); -} - -#undef _DEG_TO_RAD - -/** - * clutter_stage_is_redraw_queued_on_view: (skip) - */ -gboolean -clutter_stage_is_redraw_queued_on_view (ClutterStage *stage, - ClutterStageView *view) -{ - clutter_stage_finish_layout (stage); - - return clutter_stage_view_has_redraw_clip (view); -} - -void -_clutter_stage_set_window (ClutterStage *stage, - ClutterStageWindow *stage_window) -{ - ClutterStagePrivate *priv; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (stage_window)); - - priv = clutter_stage_get_instance_private (stage); - - if (priv->impl != NULL) - g_object_unref (priv->impl); - - priv->impl = stage_window; -} - -ClutterStageWindow * -_clutter_stage_get_window (ClutterStage *stage) -{ - ClutterStagePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL); - - priv = clutter_stage_get_instance_private (stage); - - return CLUTTER_STAGE_WINDOW (priv->impl); -} - -/** - * clutter_stage_schedule_update: - * @stage: a #ClutterStage actor - * - * Schedules a redraw of the #ClutterStage at the next optimal timestamp. - */ -void -clutter_stage_schedule_update (ClutterStage *stage) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - ClutterStageWindow *stage_window; - gboolean first_event; - GList *l; - - if (CLUTTER_ACTOR_IN_DESTRUCTION (stage)) - return; - - first_event = priv->event_queue->length == 0; - - if (priv->update_scheduled && !first_event) - return; - - stage_window = _clutter_stage_get_window (stage); - if (stage_window == NULL) - return; - - for (l = clutter_stage_peek_stage_views (stage); l; l = l->next) - { - ClutterStageView *view = l->data; - - clutter_stage_view_schedule_update (view); - } - - priv->update_scheduled = TRUE; -} - -void -clutter_stage_add_to_redraw_clip (ClutterStage *stage, - ClutterPaintVolume *redraw_clip) -{ - ClutterStageWindow *stage_window; - ClutterActorBox bounding_box; - ClutterActorBox intersection_box; - MtkRectangle geom, stage_clip; - - if (CLUTTER_ACTOR_IN_DESTRUCTION (CLUTTER_ACTOR (stage))) - return; - - stage_window = _clutter_stage_get_window (stage); - if (stage_window == NULL) - return; - - if (is_full_stage_redraw_queued (stage)) - return; - - if (redraw_clip == NULL) - { - clutter_stage_add_redraw_clip (stage, NULL); - return; - } - - if (redraw_clip->is_empty) - return; - - /* Now transform and project the clip volume to view coordinates and get - * the axis aligned bounding box that's aligned to the pixel grid. - */ - _clutter_paint_volume_get_stage_paint_box (redraw_clip, - stage, - &bounding_box); - - _clutter_stage_window_get_geometry (stage_window, &geom); - - intersection_box.x1 = MAX (bounding_box.x1, 0); - intersection_box.y1 = MAX (bounding_box.y1, 0); - intersection_box.x2 = MIN (bounding_box.x2, geom.width); - intersection_box.y2 = MIN (bounding_box.y2, geom.height); - - /* There is no need to track degenerate/empty redraw clips */ - if (intersection_box.x2 <= intersection_box.x1 || - intersection_box.y2 <= intersection_box.y1) - return; - - stage_clip.x = intersection_box.x1; - stage_clip.y = intersection_box.y1; - stage_clip.width = intersection_box.x2 - stage_clip.x; - stage_clip.height = intersection_box.y2 - stage_clip.y; - - clutter_stage_add_redraw_clip (stage, &stage_clip); -} - -int64_t -clutter_stage_get_frame_counter (ClutterStage *stage) -{ - ClutterStageWindow *stage_window; - - stage_window = _clutter_stage_get_window (stage); - return _clutter_stage_window_get_frame_counter (stage_window); -} - -void -clutter_stage_presented (ClutterStage *stage, - ClutterStageView *view, - ClutterFrameInfo *frame_info) -{ - g_signal_emit (stage, stage_signals[PRESENTED], 0, view, frame_info); -} - -/** - * clutter_stage_get_capture_final_size: - * @stage: a #ClutterStage actor - * @rect: a rectangle - * @out_width: (out) (optional): the final width - * @out_height: (out) (optional): the final height - * @out_scale: (out) (optional): the final scale factor - * - * Get the size of the framebuffer one must pass to - * [method@Stage.paint_to_buffer] or [method@Stage.paint_to_framebuffer] - * would be used with the same @rect. - * - * Returns: %TRUE if the size has been retrieved, %FALSE otherwise. - */ -gboolean -clutter_stage_get_capture_final_size (ClutterStage *stage, - MtkRectangle *rect, - int *out_width, - int *out_height, - float *out_scale) -{ - float max_scale = 1.0; - - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); - - if (rect) - { - graphene_rect_t capture_rect; - g_autoptr (GList) views = NULL; - GList *l; - - capture_rect = mtk_rectangle_to_graphene_rect (rect); - views = clutter_stage_get_views_for_rect (stage, &capture_rect); - - if (!views) - return FALSE; - - for (l = views; l; l = l->next) - { - ClutterStageView *view = l->data; - - max_scale = MAX (clutter_stage_view_get_scale (view), max_scale); - } - - if (out_width) - *out_width = (gint) roundf (rect->width * max_scale); - - if (out_height) - *out_height = (gint) roundf (rect->height * max_scale); - } - else - { - ClutterActorBox alloc; - float stage_width, stage_height; - - clutter_actor_get_allocation_box (CLUTTER_ACTOR (stage), &alloc); - clutter_actor_box_get_size (&alloc, &stage_width, &stage_height); - max_scale = clutter_actor_get_real_resource_scale (CLUTTER_ACTOR (stage)); - - if (out_width) - *out_width = (gint) roundf (stage_width * max_scale); - - if (out_height) - *out_height = (gint) roundf (stage_height * max_scale); - } - - if (out_scale) - *out_scale = max_scale; - - return TRUE; -} - -void -clutter_stage_paint_to_framebuffer (ClutterStage *stage, - CoglFramebuffer *framebuffer, - const MtkRectangle *rect, - float scale, - ClutterPaintFlag paint_flags) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - ClutterPaintContext *paint_context; - g_autoptr (MtkRegion) redraw_clip = NULL; - - COGL_TRACE_BEGIN_SCOPED (PaintToFramebuffer, - "Clutter::Stage::paint_to_framebuffer()"); - - if (paint_flags & CLUTTER_PAINT_FLAG_CLEAR) - { - CoglColor clear_color; - - cogl_color_init_from_4f (&clear_color, 0.0, 0.0, 0.0, 0.0); - cogl_framebuffer_clear (framebuffer, COGL_BUFFER_BIT_COLOR, &clear_color); - } - - redraw_clip = mtk_region_create_rectangle (rect); - paint_context = - clutter_paint_context_new_for_framebuffer (framebuffer, - redraw_clip, - paint_flags); - - cogl_framebuffer_push_matrix (framebuffer); - cogl_framebuffer_set_projection_matrix (framebuffer, &priv->projection); - cogl_framebuffer_set_viewport (framebuffer, - -(rect->x * scale), - -(rect->y * scale), - priv->viewport[2] * scale, - priv->viewport[3] * scale); - clutter_actor_paint (CLUTTER_ACTOR (stage), paint_context); - cogl_framebuffer_pop_matrix (framebuffer); - - clutter_paint_context_destroy (paint_context); -} - -/** - * clutter_stage_paint_to_buffer: - * @stage: a #ClutterStage actor - * @rect: a rectangle - * @scale: the scale - * @data: (array) (element-type guint8): a pointer to the data - * @stride: stride of the image surface - * @format: the pixel format - * @paint_flags: the #ClutterPaintFlag - * @error: the error - * - * Take a snapshot of the stage to a provided buffer. - * - * Returns: %TRUE is the buffer has been paint successfully, %FALSE otherwise. - */ -gboolean -clutter_stage_paint_to_buffer (ClutterStage *stage, - const MtkRectangle *rect, - float scale, - uint8_t *data, - int stride, - CoglPixelFormat format, - ClutterPaintFlag paint_flags, - GError **error) -{ - ClutterBackend *clutter_backend = clutter_get_default_backend (); - CoglContext *cogl_context = - clutter_backend_get_cogl_context (clutter_backend); - int texture_width, texture_height; - CoglTexture *texture; - CoglOffscreen *offscreen; - CoglFramebuffer *framebuffer; - CoglBitmap *bitmap; - - texture_width = (int) roundf (rect->width * scale); - texture_height = (int) roundf (rect->height * scale); - texture = cogl_texture_2d_new_with_size (cogl_context, - texture_width, - texture_height); - if (!texture) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Failed to create %dx%d texture", - texture_width, texture_height); - return FALSE; - } - - offscreen = cogl_offscreen_new_with_texture (texture); - framebuffer = COGL_FRAMEBUFFER (offscreen); - - g_object_unref (texture); - - if (!cogl_framebuffer_allocate (framebuffer, error)) - return FALSE; - - clutter_stage_paint_to_framebuffer (stage, framebuffer, - rect, scale, paint_flags); - - bitmap = cogl_bitmap_new_for_data (cogl_context, - texture_width, texture_height, - format, - stride, - data); - - cogl_framebuffer_read_pixels_into_bitmap (framebuffer, - 0, 0, - COGL_READ_PIXELS_COLOR_BUFFER, - bitmap); - - g_object_unref (bitmap); - g_object_unref (framebuffer); - - return TRUE; -} - -/** - * clutter_stage_paint_to_content: - * @stage: a #ClutterStage actor - * @rect: a rectangle - * @scale: the scale - * @paint_flags: the #ClutterPaintFlag - * @error: the error - * - * Take a snapshot of the stage to a #ClutterContent. - * - * Returns: (transfer full): the #ClutterContent or %NULL on error. - */ -ClutterContent * -clutter_stage_paint_to_content (ClutterStage *stage, - const MtkRectangle *rect, - float scale, - ClutterPaintFlag paint_flags, - GError **error) -{ - ClutterBackend *clutter_backend = clutter_get_default_backend (); - CoglContext *cogl_context = - clutter_backend_get_cogl_context (clutter_backend); - int texture_width, texture_height; - CoglTexture *texture; - CoglOffscreen *offscreen; - g_autoptr (CoglFramebuffer) framebuffer = NULL; - - texture_width = (int) roundf (rect->width * scale); - texture_height = (int) roundf (rect->height * scale); - texture = cogl_texture_2d_new_with_size (cogl_context, - texture_width, - texture_height); - if (!texture) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Failed to create %dx%d texture", - texture_width, texture_height); - return NULL; - } - - offscreen = cogl_offscreen_new_with_texture (texture); - framebuffer = COGL_FRAMEBUFFER (offscreen); - - g_object_unref (texture); - - if (!cogl_framebuffer_allocate (framebuffer, error)) - return NULL; - - clutter_stage_paint_to_framebuffer (stage, framebuffer, - rect, scale, paint_flags); - - return clutter_texture_content_new_from_texture (cogl_offscreen_get_texture (offscreen), - NULL); -} - -void -clutter_stage_capture_view_into (ClutterStage *stage, - ClutterStageView *view, - MtkRectangle *rect, - uint8_t *data, - int stride) -{ - CoglFramebuffer *framebuffer; - ClutterBackend *backend; - CoglContext *context; - CoglBitmap *bitmap; - MtkRectangle view_layout; - float view_scale; - float texture_width; - float texture_height; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - - framebuffer = clutter_stage_view_get_framebuffer (view); - - clutter_stage_view_get_layout (view, &view_layout); - - if (!rect) - rect = &view_layout; - - view_scale = clutter_stage_view_get_scale (view); - texture_width = roundf (rect->width * view_scale); - texture_height = roundf (rect->height * view_scale); - - backend = clutter_get_default_backend (); - context = clutter_backend_get_cogl_context (backend); - bitmap = cogl_bitmap_new_for_data (context, - texture_width, texture_height, - COGL_PIXEL_FORMAT_CAIRO_ARGB32_COMPAT, - stride, - data); - - cogl_framebuffer_read_pixels_into_bitmap (framebuffer, - roundf ((rect->x - view_layout.x) * view_scale), - roundf ((rect->y - view_layout.y) * view_scale), - COGL_READ_PIXELS_COLOR_BUFFER, - bitmap); - - g_object_unref (bitmap); -} - -/** - * clutter_stage_peek_stage_views: (skip) - */ -GList * -clutter_stage_peek_stage_views (ClutterStage *stage) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - - return _clutter_stage_window_get_views (priv->impl); -} - -void -clutter_stage_clear_stage_views (ClutterStage *stage) -{ - clutter_actor_clear_stage_views_recursive (CLUTTER_ACTOR (stage), FALSE); -} - -GList * -clutter_stage_get_views_for_rect (ClutterStage *stage, - const graphene_rect_t *rect) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - GList *views_for_rect = NULL; - GList *l; - - for (l = _clutter_stage_window_get_views (priv->impl); l; l = l->next) - { - ClutterStageView *view = l->data; - MtkRectangle view_layout; - graphene_rect_t view_rect; - - clutter_stage_view_get_layout (view, &view_layout); - view_rect = mtk_rectangle_to_graphene_rect (&view_layout); - - if (graphene_rect_intersection (&view_rect, rect, NULL)) - views_for_rect = g_list_prepend (views_for_rect, view); - } - - return views_for_rect; -} - -void -clutter_stage_set_actor_needs_immediate_relayout (ClutterStage *stage) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - - priv->actor_needs_immediate_relayout = TRUE; -} - -void -clutter_stage_maybe_invalidate_focus (ClutterStage *self, - ClutterActor *actor) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (self); - GHashTableIter iter; - gpointer value; - - if (CLUTTER_ACTOR_IN_DESTRUCTION (self)) - return; - - g_hash_table_iter_init (&iter, priv->pointer_devices); - while (g_hash_table_iter_next (&iter, NULL, &value)) - { - PointerDeviceEntry *entry = value; - - if (entry->current_actor != actor) - continue; - - clutter_stage_pick_and_update_device (self, - entry->device, - NULL, NULL, - CLUTTER_DEVICE_UPDATE_IGNORE_CACHE | - CLUTTER_DEVICE_UPDATE_EMIT_CROSSING, - entry->coords, - CLUTTER_CURRENT_TIME); - } - - g_hash_table_iter_init (&iter, priv->touch_sequences); - while (g_hash_table_iter_next (&iter, NULL, &value)) - { - PointerDeviceEntry *entry = value; - - if (entry->current_actor != actor) - continue; - - clutter_stage_pick_and_update_device (self, - entry->device, - entry->sequence, - NULL, - CLUTTER_DEVICE_UPDATE_IGNORE_CACHE | - CLUTTER_DEVICE_UPDATE_EMIT_CROSSING, - entry->coords, - CLUTTER_CURRENT_TIME); - } -} - -void -clutter_stage_invalidate_focus (ClutterStage *self, - ClutterActor *actor) -{ - if (CLUTTER_ACTOR_IN_DESTRUCTION (self)) - return; - - g_assert (!clutter_actor_is_mapped (actor) || !clutter_actor_get_reactive (actor)); - - clutter_stage_maybe_invalidate_focus (self, actor); - - if (actor != CLUTTER_ACTOR (self)) - g_assert (!clutter_actor_has_pointer (actor)); -} - -static void -free_pointer_device_entry (PointerDeviceEntry *entry) -{ - if (entry->current_actor) - _clutter_actor_set_has_pointer (entry->current_actor, FALSE); - - g_clear_pointer (&entry->clear_area, mtk_region_unref); - - g_assert (!entry->press_count); - g_assert (entry->event_emission_chain->len == 0); - g_array_unref (entry->event_emission_chain); - - g_free (entry); -} - -static void -clutter_stage_update_device_entry (ClutterStage *self, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - graphene_point_t coords, - ClutterActor *actor, - MtkRegion *clear_area) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (self); - PointerDeviceEntry *entry = NULL; - - g_assert (device != NULL); - - if (sequence != NULL) - entry = g_hash_table_lookup (priv->touch_sequences, sequence); - else - entry = g_hash_table_lookup (priv->pointer_devices, device); - - if (!entry) - { - entry = g_new0 (PointerDeviceEntry, 1); - - if (sequence != NULL) - g_hash_table_insert (priv->touch_sequences, sequence, entry); - else - g_hash_table_insert (priv->pointer_devices, device, entry); - - entry->stage = self; - entry->device = device; - entry->sequence = sequence; - entry->press_count = 0; - entry->implicit_grab_actor = NULL; - entry->event_emission_chain = - g_array_sized_new (FALSE, TRUE, sizeof (EventReceiver), 32); - g_array_set_clear_func (entry->event_emission_chain, - (GDestroyNotify) free_event_receiver); - } - - entry->coords = coords; - - if (entry->current_actor != actor) - { - if (entry->current_actor) - _clutter_actor_set_has_pointer (entry->current_actor, FALSE); - - entry->current_actor = actor; - - if (actor) - _clutter_actor_set_has_pointer (actor, TRUE); - } - - g_clear_pointer (&entry->clear_area, mtk_region_unref); - if (clear_area) - entry->clear_area = mtk_region_ref (clear_area); -} - -void -clutter_stage_remove_device_entry (ClutterStage *self, - ClutterInputDevice *device, - ClutterEventSequence *sequence) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (self); - gboolean removed; - - g_assert (device != NULL); - - if (sequence != NULL) - removed = g_hash_table_remove (priv->touch_sequences, sequence); - else - removed = g_hash_table_remove (priv->pointer_devices, device); - - g_assert (removed); -} - -/** - * clutter_stage_get_device_actor: - * @stage: a #ClutterStage - * @device: a #ClutterInputDevice - * @sequence: (allow-none): an optional #ClutterEventSequence - * - * Retrieves the [class@Clutter.Actor] underneath the pointer or touch point - * of @device and @sequence. - * - * Returns: (transfer none) (nullable): a pointer to the #ClutterActor or %NULL - */ -ClutterActor * -clutter_stage_get_device_actor (ClutterStage *stage, - ClutterInputDevice *device, - ClutterEventSequence *sequence) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - PointerDeviceEntry *entry = NULL; - - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL); - g_return_val_if_fail (device != NULL, NULL); - - if (sequence != NULL) - entry = g_hash_table_lookup (priv->touch_sequences, sequence); - else - entry = g_hash_table_lookup (priv->pointer_devices, device); - - if (entry) - return entry->current_actor; - - return NULL; -} - -/** - * clutter_stage_get_device_coords: (skip): - */ -gboolean -clutter_stage_get_device_coords (ClutterStage *stage, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - graphene_point_t *coords) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - PointerDeviceEntry *entry = NULL; - - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); - g_return_val_if_fail (device != NULL, FALSE); - - if (sequence != NULL) - entry = g_hash_table_lookup (priv->touch_sequences, sequence); - else - entry = g_hash_table_lookup (priv->pointer_devices, device); - - if (!entry) - return FALSE; - - if (coords) - *coords = entry->coords; - - return TRUE; -} - -static void -clutter_stage_set_device_coords (ClutterStage *stage, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - graphene_point_t coords) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - PointerDeviceEntry *entry = NULL; - - if (sequence != NULL) - entry = g_hash_table_lookup (priv->touch_sequences, sequence); - else - entry = g_hash_table_lookup (priv->pointer_devices, device); - - if (entry) - entry->coords = coords; -} - -static ClutterActor * -find_common_root_actor (ClutterStage *stage, - ClutterActor *a, - ClutterActor *b) -{ - if (a && b) - { - while (a) - { - if (a == b || clutter_actor_contains (a, b)) - return a; - - a = clutter_actor_get_parent (a); - } - } - - return CLUTTER_ACTOR (stage); -} - -static inline void -add_actor_to_event_emission_chain (GArray *chain, - ClutterActor *actor, - ClutterEventPhase phase) -{ - EventReceiver *receiver; - - g_array_set_size (chain, chain->len + 1); - receiver = &g_array_index (chain, EventReceiver, chain->len - 1); - - receiver->actor = g_object_ref (actor); - receiver->phase = phase; -} - -static inline void -add_action_to_event_emission_chain (GArray *chain, - ClutterAction *action) -{ - EventReceiver *receiver; - - g_array_set_size (chain, chain->len + 1); - receiver = &g_array_index (chain, EventReceiver, chain->len - 1); - - receiver->action = g_object_ref (action); -} - -static void -create_event_emission_chain (ClutterStage *stage, - GArray *chain, - ClutterActor *topmost, - ClutterActor *deepmost) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - int i; - - g_assert (priv->cur_event_actors->len == 0); - clutter_actor_collect_event_actors (topmost, deepmost, priv->cur_event_actors); - - for (i = priv->cur_event_actors->len - 1; i >= 0; i--) - { - ClutterActor *actor = g_ptr_array_index (priv->cur_event_actors, i); - const GList *l; - - for (l = clutter_actor_peek_actions (actor); l; l = l->next) - { - ClutterAction *action = l->data; - - if (clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)) && - clutter_action_get_phase (action) == CLUTTER_PHASE_CAPTURE) - add_action_to_event_emission_chain (chain, action); - } - - add_actor_to_event_emission_chain (chain, actor, CLUTTER_PHASE_CAPTURE); - } - - for (i = 0; i < priv->cur_event_actors->len; i++) - { - ClutterActor *actor = g_ptr_array_index (priv->cur_event_actors, i); - const GList *l; - - for (l = clutter_actor_peek_actions (actor); l; l = l->next) - { - ClutterAction *action = l->data; - - if (clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)) && - clutter_action_get_phase (action) == CLUTTER_PHASE_BUBBLE) - add_action_to_event_emission_chain (chain, action); - } - - add_actor_to_event_emission_chain (chain, actor, CLUTTER_PHASE_BUBBLE); - } - - priv->cur_event_actors->len = 0; -} - -typedef enum -{ - EVENT_NOT_HANDLED, - EVENT_HANDLED_BY_ACTOR, - EVENT_HANDLED_BY_ACTION -} EventHandledState; - -static EventHandledState -emit_event (const ClutterEvent *event, - GArray *event_emission_chain) -{ - unsigned int i; - - for (i = 0; i < event_emission_chain->len; i++) - { - EventReceiver *receiver = - &g_array_index (event_emission_chain, EventReceiver, i); - - if (receiver->actor) - { - if (clutter_actor_event (receiver->actor, event, receiver->phase == CLUTTER_PHASE_CAPTURE)) - return EVENT_HANDLED_BY_ACTOR; - } - else if (receiver->action) - { - if (clutter_action_handle_event (receiver->action, event)) - return EVENT_HANDLED_BY_ACTION; - } - } - - return EVENT_NOT_HANDLED; -} - -static void -clutter_stage_emit_crossing_event (ClutterStage *self, - const ClutterEvent *event, - ClutterActor *deepmost, - ClutterActor *topmost) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (self); - ClutterInputDevice *device = clutter_event_get_device (event); - ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); - PointerDeviceEntry *entry; - - if (topmost == NULL) - topmost = CLUTTER_ACTOR (self); - - if (sequence != NULL) - entry = g_hash_table_lookup (priv->touch_sequences, sequence); - else - entry = g_hash_table_lookup (priv->pointer_devices, device); - - g_assert (entry != NULL); - - if (entry->press_count && - !(clutter_event_get_flags (event) & CLUTTER_EVENT_FLAG_GRAB_NOTIFY)) - { - emit_event (event, entry->event_emission_chain); - } - else - { - gboolean in_event_emission; - GArray *event_emission_chain; - - /* Crossings can happen while we're in the middle of event emission - * (for example when an actor goes unmapped or gets grabbed), so we - * can't reuse priv->cur_event_emission_chain here, it might already be in use. - */ - in_event_emission = priv->cur_event_emission_chain->len != 0; - - if (in_event_emission) - { - event_emission_chain = - g_array_sized_new (FALSE, TRUE, sizeof (EventReceiver), 32); - g_array_set_clear_func (event_emission_chain, - (GDestroyNotify) free_event_receiver); - } - else - { - event_emission_chain = g_array_ref (priv->cur_event_emission_chain); - } - - create_event_emission_chain (self, event_emission_chain, topmost, deepmost); - - emit_event (event, event_emission_chain); - - g_array_remove_range (event_emission_chain, 0, event_emission_chain->len); - g_array_unref (event_emission_chain); - } -} - -static void -sync_crossings_on_implicit_grab_end (ClutterStage *self, - PointerDeviceEntry *entry) -{ - ClutterActor *deepmost, *topmost; - ClutterActor *parent; - ClutterEvent *crossing; - - deepmost = entry->current_actor; - - if (clutter_actor_contains (entry->current_actor, entry->implicit_grab_actor)) - return; - - topmost = entry->current_actor; - while ((parent = clutter_actor_get_parent (topmost))) - { - if (clutter_actor_contains (parent, entry->implicit_grab_actor)) - break; - - topmost = parent; - } - - crossing = clutter_event_crossing_new (CLUTTER_ENTER, - CLUTTER_EVENT_FLAG_GRAB_NOTIFY, - CLUTTER_CURRENT_TIME, - entry->device, - entry->sequence, - entry->coords, - entry->current_actor, - NULL); - - if (!_clutter_event_process_filters (crossing, deepmost)) - { - clutter_stage_emit_crossing_event (self, - crossing, - deepmost, - topmost); - } - - clutter_event_free (crossing); -} - -void -clutter_stage_update_device (ClutterStage *stage, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - ClutterInputDevice *source_device, - graphene_point_t point, - uint32_t time_ms, - ClutterActor *new_actor, - MtkRegion *clear_area, - gboolean emit_crossing) -{ - ClutterInputDeviceType device_type; - ClutterActor *old_actor, *root; - gboolean device_actor_changed; - ClutterEvent *event; - - device_type = clutter_input_device_get_device_type (device); - - g_assert (device_type != CLUTTER_KEYBOARD_DEVICE && - device_type != CLUTTER_PAD_DEVICE); - - old_actor = clutter_stage_get_device_actor (stage, device, sequence); - device_actor_changed = new_actor != old_actor; - - if (!source_device) - source_device = device; - - clutter_stage_update_device_entry (stage, - device, sequence, - point, - new_actor, - clear_area); - - if (device_actor_changed) - { - CLUTTER_NOTE (EVENT, - "Updating actor under cursor (device %s, at %.2f, %.2f): %s", - clutter_input_device_get_device_name (device), - point.x, - point.y, - _clutter_actor_get_debug_name (new_actor)); - - if (emit_crossing) - { - ClutterActor *grab_actor; - - root = find_common_root_actor (stage, new_actor, old_actor); - - grab_actor = clutter_stage_get_grab_actor (stage); - - /* If the common root is outside the currently effective grab, - * it involves actors outside the grabbed actor hierarchy, the - * events should be propagated from/inside the grab actor. - */ - if (grab_actor && - root != grab_actor && - !clutter_actor_contains (grab_actor, root)) - root = grab_actor; - } - - /* we need to make sure that this event is processed - * before any other event we might have queued up until - * now, so we go on, and synthesize the event emission - * ourselves - */ - if (old_actor && emit_crossing) - { - event = clutter_event_crossing_new (CLUTTER_LEAVE, - CLUTTER_EVENT_NONE, - ms2us (time_ms), - source_device, - sequence, - point, - old_actor, - new_actor); - if (!_clutter_event_process_filters (event, old_actor)) - { - clutter_stage_emit_crossing_event (stage, - event, - old_actor, - root); - } - - clutter_event_free (event); - } - - if (new_actor && emit_crossing) - { - event = clutter_event_crossing_new (CLUTTER_ENTER, - CLUTTER_EVENT_NONE, - ms2us (time_ms), - source_device, - sequence, - point, - new_actor, - old_actor); - if (!_clutter_event_process_filters (event, new_actor)) - { - clutter_stage_emit_crossing_event (stage, - event, - new_actor, - root); - } - - clutter_event_free (event); - } - } -} - -static gboolean -clutter_stage_check_in_clear_area (ClutterStage *stage, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - graphene_point_t point) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - PointerDeviceEntry *entry = NULL; - - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); - g_return_val_if_fail (device != NULL, FALSE); - - if (sequence != NULL) - entry = g_hash_table_lookup (priv->touch_sequences, sequence); - else - entry = g_hash_table_lookup (priv->pointer_devices, device); - - if (!entry) - return FALSE; - if (!entry->clear_area) - return FALSE; - - return mtk_region_contains_point (entry->clear_area, - point.x, point.y); -} - -static ClutterActor * -clutter_stage_pick_and_update_device (ClutterStage *stage, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - ClutterInputDevice *source_device, - ClutterDeviceUpdateFlags flags, - graphene_point_t point, - uint32_t time_ms) -{ - ClutterActor *new_actor = NULL; - MtkRegion *clear_area = NULL; - ClutterSeat *seat; - - seat = clutter_input_device_get_seat (device); - - if (sequence || - device != clutter_seat_get_pointer (seat) || - clutter_seat_is_unfocus_inhibited (seat)) - { - if ((flags & CLUTTER_DEVICE_UPDATE_IGNORE_CACHE) == 0) - { - if (clutter_stage_check_in_clear_area (stage, device, - sequence, point)) - { - clutter_stage_set_device_coords (stage, device, - sequence, point); - return clutter_stage_get_device_actor (stage, device, sequence); - } - } - - new_actor = _clutter_stage_do_pick (stage, - point.x, - point.y, - CLUTTER_PICK_REACTIVE, - &clear_area); - - /* Picking should never fail, but if it does, we bail out here */ - g_return_val_if_fail (new_actor != NULL, NULL); - } - - clutter_stage_update_device (stage, - device, sequence, - source_device, - point, - time_ms, - new_actor, - clear_area, - !!(flags & CLUTTER_DEVICE_UPDATE_EMIT_CROSSING)); - - g_clear_pointer (&clear_area, mtk_region_unref); - - return new_actor; -} - -static void -cleanup_implicit_grab (PointerDeviceEntry *entry) -{ - clutter_actor_set_implicitly_grabbed (entry->implicit_grab_actor, FALSE); - entry->implicit_grab_actor = NULL; - - g_array_remove_range (entry->event_emission_chain, 0, - entry->event_emission_chain->len); - - entry->press_count = 0; -} - -static void -clutter_stage_notify_grab_on_pointer_entry (ClutterStage *stage, - PointerDeviceEntry *entry, - ClutterActor *grab_actor, - ClutterActor *old_grab_actor) -{ - gboolean pointer_in_grab, pointer_in_old_grab; - gboolean implicit_grab_cancelled = FALSE; - unsigned int implicit_grab_n_removed = 0, implicit_grab_n_remaining = 0; - ClutterEventType event_type = CLUTTER_NOTHING; - ClutterActor *topmost, *deepmost; - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - if (!entry->current_actor) - return; - - pointer_in_grab = - !grab_actor || - grab_actor == entry->current_actor || - clutter_actor_contains (grab_actor, entry->current_actor); - pointer_in_old_grab = - !old_grab_actor || - old_grab_actor == entry->current_actor || - clutter_actor_contains (old_grab_actor, entry->current_actor); - - if (grab_actor && entry->press_count > 0) - { - ClutterInputDevice *device = entry->device; - ClutterEventSequence *sequence = entry->sequence; - unsigned int i; - - for (i = 0; i < entry->event_emission_chain->len; i++) - { - EventReceiver *receiver = - &g_array_index (entry->event_emission_chain, EventReceiver, i); - - if (receiver->actor) - { - if (!clutter_actor_contains (grab_actor, receiver->actor)) - { - g_clear_object (&receiver->actor); - implicit_grab_n_removed++; - } - else - { - implicit_grab_n_remaining++; - } - } - else if (receiver->action) - { - ClutterActor *action_actor = - clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (receiver->action)); - - if (!action_actor || !clutter_actor_contains (grab_actor, action_actor)) - { - clutter_action_sequence_cancelled (receiver->action, - device, - sequence); - g_clear_object (&receiver->action); - implicit_grab_n_removed++; - } - else - { - implicit_grab_n_remaining++; - } - } - } - - /* Seat grabs win over implicit grabs, so we default to cancel the ongoing - * implicit grab. If the seat grab contains one or more actors from - * the implicit grab though, the implicit grab remains in effect. - */ - implicit_grab_cancelled = implicit_grab_n_remaining == 0; - - CLUTTER_NOTE (GRABS, - "[grab=%p device=%p sequence=%p implicit_grab_cancelled=%d] " - "Cancelled %u actors and actions (%u remaining) on implicit " - "grab due to new seat grab", - priv->topmost_grab, device, sequence, implicit_grab_cancelled, - implicit_grab_n_removed, implicit_grab_n_remaining); - } - - /* Equate NULL actors to the stage here, to ease calculations further down. */ - if (!grab_actor) - grab_actor = CLUTTER_ACTOR (stage); - if (!old_grab_actor) - old_grab_actor = CLUTTER_ACTOR (stage); - - if (grab_actor == old_grab_actor) - { - g_assert ((implicit_grab_n_removed == 0 && implicit_grab_n_remaining == 0) || - !implicit_grab_cancelled); - return; - } - - if (pointer_in_grab && pointer_in_old_grab) - { - /* Both grabs happen to contain the pointer actor, we have to figure out - * which is topmost, and emit ENTER/LEAVE events accordingly on the actors - * between old/new grabs. - */ - if (clutter_actor_contains (grab_actor, old_grab_actor)) - { - /* grab_actor is above old_grab_actor, emit ENTER events in the - * line between those two actors. - */ - event_type = CLUTTER_ENTER; - deepmost = clutter_actor_get_parent (old_grab_actor); - topmost = grab_actor; - } - else if (clutter_actor_contains (old_grab_actor, grab_actor)) - { - /* old_grab_actor is above grab_actor, emit LEAVE events in the - * line between those two actors. - */ - event_type = CLUTTER_LEAVE; - deepmost = clutter_actor_get_parent (grab_actor); - topmost = old_grab_actor; - } - } - else if (pointer_in_grab) - { - /* Pointer is somewhere inside the grab_actor hierarchy. Emit ENTER events - * from the current grab actor to the pointer actor. - */ - event_type = CLUTTER_ENTER; - deepmost = entry->current_actor; - topmost = grab_actor; - } - else if (pointer_in_old_grab) - { - /* Pointer is somewhere inside the old_grab_actor hierarchy. Emit LEAVE - * events from the common root of old/cur grab actors to the pointer - * actor. - */ - event_type = CLUTTER_LEAVE; - deepmost = entry->current_actor; - topmost = find_common_root_actor (stage, grab_actor, old_grab_actor); - } - - if (event_type == CLUTTER_ENTER && implicit_grab_cancelled) - cleanup_implicit_grab (entry); - - if (event_type != CLUTTER_NOTHING) - { - ClutterEvent *event; - - if (entry->implicit_grab_actor) - deepmost = find_common_root_actor (stage, entry->implicit_grab_actor, deepmost); - - event = clutter_event_crossing_new (event_type, - CLUTTER_EVENT_FLAG_GRAB_NOTIFY, - CLUTTER_CURRENT_TIME, - entry->device, - entry->sequence, - entry->coords, - entry->current_actor, - event_type == CLUTTER_LEAVE ? - grab_actor : old_grab_actor); - if (!_clutter_event_process_filters (event, entry->current_actor)) - { - clutter_stage_emit_crossing_event (stage, - event, - deepmost, - topmost); - } - - clutter_event_free (event); - } - - if ((event_type == CLUTTER_NOTHING || event_type == CLUTTER_LEAVE) && - implicit_grab_cancelled) - cleanup_implicit_grab (entry); -} - -static void -clutter_stage_notify_grab_on_key_focus (ClutterStage *stage, - ClutterActor *grab_actor, - ClutterActor *old_grab_actor) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - ClutterActor *key_focus; - gboolean focus_in_grab, focus_in_old_grab; - - key_focus = priv->key_focused_actor ? - priv->key_focused_actor : CLUTTER_ACTOR (stage); - - focus_in_grab = - !grab_actor || - grab_actor == key_focus || - clutter_actor_contains (grab_actor, key_focus); - focus_in_old_grab = - !old_grab_actor || - old_grab_actor == key_focus || - clutter_actor_contains (old_grab_actor, key_focus); - - if (focus_in_grab && !focus_in_old_grab) - _clutter_actor_set_has_key_focus (CLUTTER_ACTOR (key_focus), TRUE); - else if (!focus_in_grab && focus_in_old_grab) - _clutter_actor_set_has_key_focus (CLUTTER_ACTOR (key_focus), FALSE); -} - -static void -clutter_stage_notify_grab (ClutterStage *stage, - ClutterGrab *cur, - ClutterGrab *old) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - ClutterActor *cur_actor = NULL, *old_actor = NULL; - PointerDeviceEntry *entry; - GHashTableIter iter; - - if (cur) - cur_actor = cur->actor; - if (old) - old_actor = old->actor; - - /* Nothing to notify */ - if (cur_actor == old_actor) - return; - - g_hash_table_iter_init (&iter, priv->pointer_devices); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &entry)) - { - /* Update pointers */ - clutter_stage_notify_grab_on_pointer_entry (stage, - entry, - cur_actor, - old_actor); - } - - g_hash_table_iter_init (&iter, priv->touch_sequences); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &entry)) - { - /* Update touch sequences */ - clutter_stage_notify_grab_on_pointer_entry (stage, - entry, - cur_actor, - old_actor); - } - - clutter_stage_notify_grab_on_key_focus (stage, cur_actor, old_actor); -} - -static ClutterGrab * -clutter_stage_grab_full (ClutterStage *stage, - ClutterActor *actor, - gboolean owns_actor) -{ - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL); - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); - g_return_val_if_fail (stage == - (ClutterStage *) _clutter_actor_get_stage_internal (actor), - NULL); - - return clutter_grab_new (stage, actor, owns_actor); -} - -void -clutter_grab_activate (ClutterGrab *grab) -{ - ClutterStage *stage; - ClutterStagePrivate *priv; - gboolean was_grabbed; - - g_return_if_fail (CLUTTER_IS_GRAB (grab)); - - stage = grab->stage; - priv = clutter_stage_get_instance_private (stage); - - /* This grab is already active */ - if (grab->prev || grab->next || priv->topmost_grab == grab) - return; - - if (!priv->topmost_grab) - { - ClutterContext *context; - ClutterSeat *seat; - - /* First grab in the chain, trigger a backend grab too */ - context = _clutter_context_get_default (); - seat = clutter_backend_get_default_seat (context->backend); - priv->grab_state = - clutter_seat_grab (seat, clutter_get_current_event_time ()); - } - - grab->prev = NULL; - grab->next = priv->topmost_grab; - - was_grabbed = !!priv->topmost_grab; - - if (priv->topmost_grab) - priv->topmost_grab->prev = grab; - - priv->topmost_grab = grab; - - if (G_UNLIKELY (clutter_debug_flags & CLUTTER_DEBUG_GRABS)) - { - unsigned int n_grabs = 0; - ClutterGrab *g; - - for (g = priv->topmost_grab; g != NULL; g = g->next) - n_grabs++; - - CLUTTER_NOTE (GRABS, - "[grab=%p] Attached seat grab (n_grabs: %u) on actor: %s", - grab, n_grabs, _clutter_actor_get_debug_name (grab->actor)); - } - - clutter_actor_attach_grab (grab->actor, grab); - clutter_stage_notify_grab (stage, grab, grab->next); - - if (was_grabbed != !!priv->topmost_grab) - g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_IS_GRABBED]); - - if (grab->next) - clutter_grab_notify (grab->next); -} - -/** - * clutter_stage_grab: - * @stage: The #ClutterStage - * @actor: The actor grabbing input - * - * Grabs input onto a certain actor. Events will be propagated as - * usual inside its hierarchy. - * - * Returns: (transfer full): an opaque #ClutterGrab handle, drop - * with [method@Grab.dismiss] - **/ -ClutterGrab * -clutter_stage_grab (ClutterStage *stage, - ClutterActor *actor) -{ - ClutterGrab *grab; - - grab = clutter_stage_grab_full (stage, actor, FALSE); - clutter_grab_activate (grab); - - return grab; -} - -ClutterGrab * -clutter_stage_grab_inactive (ClutterStage *stage, - ClutterActor *actor) -{ - return clutter_stage_grab_full (stage, actor, FALSE); -} - -ClutterGrab * -clutter_stage_grab_input_only_inactive (ClutterStage *stage, - ClutterEventHandler handler, - gpointer user_data, - GDestroyNotify user_data_destroy) -{ - ClutterInputOnlyActor *input_only_actor; - ClutterActor *actor; - - input_only_actor = clutter_input_only_actor_new (handler, user_data, - user_data_destroy); - actor = CLUTTER_ACTOR (input_only_actor); - clutter_actor_set_name (actor, "input only grab actor"); - - clutter_actor_insert_child_at_index (CLUTTER_ACTOR (stage), actor, 0); - - return clutter_stage_grab_full (stage, actor, TRUE); -} - -void -clutter_stage_unlink_grab (ClutterStage *stage, - ClutterGrab *grab) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - ClutterGrab *prev, *next; - gboolean was_grabbed; - - /* This grab is already detached */ - if (!grab->prev && !grab->next && priv->topmost_grab != grab) - return; - - prev = grab->prev; - next = grab->next; - - if (prev) - prev->next = next; - if (next) - next->prev = prev; - - was_grabbed = !!priv->topmost_grab; - - if (priv->topmost_grab == grab) - { - /* This is the active grab */ - g_assert (prev == NULL); - priv->topmost_grab = next; - clutter_stage_notify_grab (stage, next, grab); - } - - clutter_actor_detach_grab (grab->actor, grab); - - if (!priv->topmost_grab) - { - ClutterContext *context; - ClutterSeat *seat; - - /* This was the last remaining grab, trigger a backend ungrab */ - context = _clutter_context_get_default (); - seat = clutter_backend_get_default_seat (context->backend); - clutter_seat_ungrab (seat, clutter_get_current_event_time ()); - priv->grab_state = CLUTTER_GRAB_STATE_NONE; - } - - if (was_grabbed != !!priv->topmost_grab) - g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_IS_GRABBED]); - - if (G_UNLIKELY (clutter_debug_flags & CLUTTER_DEBUG_GRABS)) - { - unsigned int n_grabs = 0; - ClutterGrab *g; - - for (g = priv->topmost_grab; g != NULL; g = g->next) - n_grabs++; - - CLUTTER_NOTE (GRABS, - "[grab=%p] Detached seat grab (n_grabs: %u)", - grab, n_grabs); - } - - grab->next = NULL; - grab->prev = NULL; - - if (grab->owns_actor) - g_clear_pointer (&grab->actor, clutter_actor_destroy); - - if (priv->topmost_grab) - clutter_grab_notify (priv->topmost_grab); -} - -/** - * clutter_grab_dismiss: - * @grab: Grab to undo - * - * Removes a grab. If this grab is effective, crossing events - * will be generated to indicate the change in event redirection. - **/ -void -clutter_grab_dismiss (ClutterGrab *grab) -{ - g_return_if_fail (grab != NULL); - - clutter_stage_unlink_grab (grab->stage, grab); -} - -/** - * clutter_grab_get_seat_state: - * @grab: a Grab handle - * - * Returns the windowing-level state of the - * grab, the devices that are guaranteed to be - * grabbed. - * - * Returns: The state of the grab. - **/ -ClutterGrabState -clutter_grab_get_seat_state (ClutterGrab *grab) -{ - ClutterStagePrivate *priv; - - g_return_val_if_fail (grab != NULL, CLUTTER_GRAB_STATE_NONE); - - priv = clutter_stage_get_instance_private (grab->stage); - return priv->grab_state; -} - -/** - * clutter_stage_get_grab_actor: - * @stage: a #ClutterStage - * - * Gets the actor that currently holds a grab. - * - * Returns: (transfer none) (nullable): The grabbing actor - **/ -ClutterActor * -clutter_stage_get_grab_actor (ClutterStage *stage) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - - if (!priv->topmost_grab) - return NULL; - - /* Return active grab */ - return priv->topmost_grab->actor; -} - -/** - * clutter_stage_get_event_actor: - * @stage: a #ClutterStage - * @event: an event received on the stage - * - * Retrieves the current focus actor for an event. This is - * the key focus for key events and other events directed - * to the key focus, or the actor directly under the - * coordinates of a device or touch sequence. - * - * The actor is looked up at the time of calling this function, - * and may differ from the actor that the stage originally - * delivered the event to. - * - * Returns: (transfer none) (nullable): a pointer to the #ClutterActor or %NULL - **/ -ClutterActor * -clutter_stage_get_event_actor (ClutterStage *stage, - const ClutterEvent *event) -{ - ClutterInputDevice *device; - ClutterEventSequence *sequence; - - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL); - g_return_val_if_fail (event != NULL, NULL); - - switch (clutter_event_type (event)) - { - case CLUTTER_KEY_PRESS: - case CLUTTER_KEY_RELEASE: - case CLUTTER_PAD_BUTTON_PRESS: - case CLUTTER_PAD_BUTTON_RELEASE: - case CLUTTER_PAD_RING: - case CLUTTER_PAD_STRIP: - case CLUTTER_IM_COMMIT: - case CLUTTER_IM_DELETE: - case CLUTTER_IM_PREEDIT: - return clutter_stage_get_key_focus (stage); - case CLUTTER_MOTION: - case CLUTTER_ENTER: - case CLUTTER_LEAVE: - case CLUTTER_BUTTON_PRESS: - case CLUTTER_BUTTON_RELEASE: - case CLUTTER_SCROLL: - case CLUTTER_TOUCH_BEGIN: - case CLUTTER_TOUCH_UPDATE: - case CLUTTER_TOUCH_END: - case CLUTTER_TOUCH_CANCEL: - case CLUTTER_TOUCHPAD_PINCH: - case CLUTTER_TOUCHPAD_SWIPE: - case CLUTTER_TOUCHPAD_HOLD: - case CLUTTER_PROXIMITY_IN: - case CLUTTER_PROXIMITY_OUT: - device = clutter_event_get_device (event); - sequence = clutter_event_get_event_sequence (event); - - return clutter_stage_get_device_actor (stage, device, sequence); - case CLUTTER_DEVICE_ADDED: - case CLUTTER_DEVICE_REMOVED: - case CLUTTER_NOTHING: - case CLUTTER_EVENT_LAST: - g_warn_if_reached (); - } - - return NULL; -} - -static void -free_event_receiver (EventReceiver *receiver) -{ - g_clear_object (&receiver->actor); - g_clear_object (&receiver->action); -} - -static void -remove_all_actors_from_chain (PointerDeviceEntry *entry) -{ - unsigned int i; - - for (i = 0; i < entry->event_emission_chain->len; i++) - { - EventReceiver *receiver = - &g_array_index (entry->event_emission_chain, EventReceiver, i); - - if (receiver->actor) - g_clear_object (&receiver->actor); - } -} - -static void -remove_all_actions_from_chain (PointerDeviceEntry *entry) -{ - unsigned int i; - - for (i = 0; i < entry->event_emission_chain->len; i++) - { - EventReceiver *receiver = - &g_array_index (entry->event_emission_chain, EventReceiver, i); - - if (receiver->action) - { - clutter_action_sequence_cancelled (receiver->action, - entry->device, - entry->sequence); - g_clear_object (&receiver->action); - } - } -} - -static gboolean -setup_implicit_grab (PointerDeviceEntry *entry) -{ - /* With a mouse, it's possible to press two buttons at the same time, - * We ignore the second BUTTON_PRESS event here, and we'll release the - * implicit grab on the BUTTON_RELEASE of the second press. - */ - if (entry->sequence == NULL && entry->press_count) - { - entry->press_count++; - return FALSE; - } - - CLUTTER_NOTE (GRABS, - "[device=%p sequence=%p] Acquiring implicit grab", - entry->device, entry->sequence); - - g_assert (entry->press_count == 0); - g_assert (entry->event_emission_chain->len == 0); - - entry->press_count = 1; - return TRUE; -} - -static gboolean -release_implicit_grab (PointerDeviceEntry *entry) -{ - if (!entry->press_count) - return FALSE; - - /* See comment in setup_implicit_grab() */ - if (entry->sequence == NULL && entry->press_count > 1) - { - entry->press_count--; - return FALSE; - } - - CLUTTER_NOTE (GRABS, - "[device=%p sequence=%p] Releasing implicit grab", - entry->device, entry->sequence); - - g_assert (entry->press_count == 1); - - entry->press_count = 0; - return TRUE; -} - -void -clutter_stage_maybe_lost_implicit_grab (ClutterStage *self, - ClutterInputDevice *device, - ClutterEventSequence *sequence) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (self); - PointerDeviceEntry *entry = NULL; - unsigned int i; - - if (sequence != NULL) - entry = g_hash_table_lookup (priv->touch_sequences, sequence); - else - entry = g_hash_table_lookup (priv->pointer_devices, device); - - g_assert (entry != NULL); - - if (!entry->press_count) - return; - - CLUTTER_NOTE (GRABS, - "[device=%p sequence=%p] Lost implicit grab", - device, sequence); - - for (i = 0; i < entry->event_emission_chain->len; i++) - { - EventReceiver *receiver = - &g_array_index (entry->event_emission_chain, EventReceiver, i); - - if (receiver->action) - clutter_action_sequence_cancelled (receiver->action, device, sequence); - } - - sync_crossings_on_implicit_grab_end (self, entry); - - cleanup_implicit_grab (entry); -} - -static void -setup_sequence_actions (GArray *emission_chain, - const ClutterEvent *sequence_begin_event) -{ - ClutterInputDevice *device = clutter_event_get_device (sequence_begin_event); - ClutterEventSequence *sequence = clutter_event_get_event_sequence (sequence_begin_event); - unsigned int i, j; - - for (i = 0; i < emission_chain->len; i++) - { - EventReceiver *receiver = &g_array_index (emission_chain, EventReceiver, i); - - if (!receiver->action) - continue; - - if (!clutter_action_register_sequence (receiver->action, sequence_begin_event)) - g_clear_object (&receiver->action); - } - - for (i = 0; i < emission_chain->len; i++) - { - EventReceiver *receiver_1 = &g_array_index (emission_chain, EventReceiver, i); - - if (!receiver_1->action) - continue; - - for (j = i + 1; j < emission_chain->len; j++) - { - EventReceiver *receiver_2 = &g_array_index (emission_chain, EventReceiver, j); - - if (!receiver_2->action) - continue; - - clutter_action_setup_sequence_relationship (receiver_1->action, - receiver_2->action, - device, - sequence); - } - } -} - -void -clutter_stage_emit_event (ClutterStage *self, - const ClutterEvent *event) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (self); - ClutterInputDevice *device = clutter_event_get_device (event); - ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); - PointerDeviceEntry *entry; - ClutterActor *target_actor = NULL, *seat_grab_actor = NULL; - gboolean is_sequence_begin, is_sequence_end; - ClutterEventType event_type; - - COGL_TRACE_BEGIN_SCOPED (EmitEvent, "Clutter::Stage::emit_event()"); - - if (sequence != NULL) - entry = g_hash_table_lookup (priv->touch_sequences, sequence); - else - entry = g_hash_table_lookup (priv->pointer_devices, device); - - event_type = clutter_event_type (event); - - switch (event_type) - { - case CLUTTER_NOTHING: - case CLUTTER_DEVICE_REMOVED: - case CLUTTER_DEVICE_ADDED: - case CLUTTER_EVENT_LAST: - return; - - case CLUTTER_KEY_PRESS: - case CLUTTER_KEY_RELEASE: - 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: - { - target_actor = priv->key_focused_actor ? - priv->key_focused_actor : CLUTTER_ACTOR (self); - break; - } - - /* x11 stage enter/leave events */ - case CLUTTER_ENTER: - case CLUTTER_LEAVE: - { - target_actor = entry->current_actor; - break; - } - - case CLUTTER_MOTION: - case CLUTTER_BUTTON_PRESS: - case CLUTTER_BUTTON_RELEASE: - case CLUTTER_SCROLL: - case CLUTTER_TOUCHPAD_PINCH: - case CLUTTER_TOUCHPAD_SWIPE: - case CLUTTER_TOUCHPAD_HOLD: - case CLUTTER_TOUCH_UPDATE: - case CLUTTER_TOUCH_BEGIN: - case CLUTTER_TOUCH_CANCEL: - case CLUTTER_TOUCH_END: - case CLUTTER_PROXIMITY_IN: - case CLUTTER_PROXIMITY_OUT: - { - float x, y; - - clutter_event_get_coords (event, &x, &y); - - CLUTTER_NOTE (EVENT, - "Reactive event received at %.2f, %.2f - actor: %p", - x, y, entry->current_actor); - - target_actor = entry->current_actor; - break; - } - } - - if (!target_actor) - return; - - seat_grab_actor = priv->topmost_grab ? priv->topmost_grab->actor : CLUTTER_ACTOR (self); - - is_sequence_begin = - event_type == CLUTTER_BUTTON_PRESS || event_type == CLUTTER_TOUCH_BEGIN; - is_sequence_end = - event_type == CLUTTER_BUTTON_RELEASE || event_type == CLUTTER_TOUCH_END || - event_type == CLUTTER_TOUCH_CANCEL; - - if (is_sequence_begin && setup_implicit_grab (entry)) - { - g_assert (entry->implicit_grab_actor == NULL); - entry->implicit_grab_actor = target_actor; - clutter_actor_set_implicitly_grabbed (entry->implicit_grab_actor, TRUE); - - create_event_emission_chain (self, entry->event_emission_chain, seat_grab_actor, target_actor); - setup_sequence_actions (entry->event_emission_chain, event); - } - - if (entry && entry->press_count) - { - EventHandledState state; - - state = emit_event (event, entry->event_emission_chain); - - if (state == EVENT_HANDLED_BY_ACTOR) - remove_all_actions_from_chain (entry); - } - else - { - create_event_emission_chain (self, priv->cur_event_emission_chain, seat_grab_actor, target_actor); - - emit_event (event, priv->cur_event_emission_chain); - - g_array_remove_range (priv->cur_event_emission_chain, 0, priv->cur_event_emission_chain->len); - } - - if (is_sequence_end && release_implicit_grab (entry)) - { - /* Sync crossings after the implicit grab for mice */ - if (event_type == CLUTTER_BUTTON_RELEASE) - sync_crossings_on_implicit_grab_end (self, entry); - - cleanup_implicit_grab (entry); - } -} - -static void -cancel_implicit_grab_on_actor (PointerDeviceEntry *entry, - ClutterActor *actor) -{ - unsigned int i; - ClutterActor *parent = clutter_actor_get_parent (actor); - - CLUTTER_NOTE (GRABS, - "[device=%p sequence=%p] Cancelling implicit grab on actor (%s) " - "due to unmap", - entry->device, entry->sequence, - _clutter_actor_get_debug_name (actor)); - - for (i = 0; i < entry->event_emission_chain->len; i++) - { - EventReceiver *receiver = - &g_array_index (entry->event_emission_chain, EventReceiver, i); - - if (receiver->actor) - { - if (receiver->actor == actor) - g_clear_object (&receiver->actor); - } - else if (receiver->action) - { - ClutterActor *action_actor = - clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (receiver->action)); - - if (!action_actor || action_actor == actor) - { - clutter_action_sequence_cancelled (receiver->action, - entry->device, - entry->sequence); - g_clear_object (&receiver->action); - } - } - } - - clutter_actor_set_implicitly_grabbed (entry->implicit_grab_actor, FALSE); - entry->implicit_grab_actor = NULL; - - if (parent) - { - g_assert (clutter_actor_is_mapped (parent)); - - entry->implicit_grab_actor = parent; - clutter_actor_set_implicitly_grabbed (entry->implicit_grab_actor, TRUE); - } -} - -void -clutter_stage_implicit_grab_actor_unmapped (ClutterStage *self, - ClutterActor *actor) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (self); - GHashTableIter iter; - PointerDeviceEntry *entry; - - g_hash_table_iter_init (&iter, priv->pointer_devices); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &entry)) - { - if (entry->implicit_grab_actor == actor) - cancel_implicit_grab_on_actor (entry, actor); - } - - g_hash_table_iter_init (&iter, priv->touch_sequences); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &entry)) - { - if (entry->implicit_grab_actor == actor) - cancel_implicit_grab_on_actor (entry, actor); - } -} - -void -clutter_stage_notify_action_implicit_grab (ClutterStage *self, - ClutterInputDevice *device, - ClutterEventSequence *sequence) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (self); - PointerDeviceEntry *entry; - - if (sequence != NULL) - entry = g_hash_table_lookup (priv->touch_sequences, sequence); - else - entry = g_hash_table_lookup (priv->pointer_devices, device); - - g_assert (entry->press_count > 0); - - remove_all_actors_from_chain (entry); -} - -/** - * clutter_stage_pointing_input_foreach: - * @self: The stage - * @func: (scope call): Iterator function - * @user_data: user data - * - * Iterates over active input. - * - * Returns: %TRUE if the foreach function did not stop. - **/ -gboolean -clutter_stage_pointing_input_foreach (ClutterStage *self, - ClutterStageInputForeachFunc func, - gpointer user_data) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (self); - GHashTableIter iter; - PointerDeviceEntry *entry; - - g_return_val_if_fail (CLUTTER_IS_STAGE (self), FALSE); - g_return_val_if_fail (func != NULL, FALSE); - - g_hash_table_iter_init (&iter, priv->pointer_devices); - while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &entry)) - { - if (!func (self, entry->device, entry->sequence, user_data)) - return FALSE; - } - - g_hash_table_iter_init (&iter, priv->touch_sequences); - while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &entry)) - { - if (!func (self, entry->device, entry->sequence, user_data)) - return FALSE; - } - - return TRUE; -} - -GPtrArray * -clutter_stage_get_active_gestures_array (ClutterStage *self) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (self); - - return priv->all_active_gestures; -} - -ClutterActor * -clutter_stage_update_device_for_event (ClutterStage *stage, - ClutterEvent *event) -{ - ClutterInputDevice *device = clutter_event_get_device (event); - ClutterInputDevice *source_device = clutter_event_get_source_device (event); - ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); - ClutterDeviceUpdateFlags flags; - graphene_point_t point; - uint32_t time_ms; - - clutter_event_get_coords (event, &point.x, &point.y); - time_ms = clutter_event_get_time (event); - - flags = CLUTTER_DEVICE_UPDATE_EMIT_CROSSING; - - return clutter_stage_pick_and_update_device (stage, - device, - sequence, - source_device, - flags, - point, - time_ms); -} - -void -clutter_stage_update_devices_in_view (ClutterStage *stage, - ClutterStageView *view) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - GHashTableIter iter; - gpointer value; - - g_hash_table_iter_init (&iter, priv->pointer_devices); - while (g_hash_table_iter_next (&iter, NULL, &value)) - { - PointerDeviceEntry *entry = value; - ClutterStageView *pointer_view; - - pointer_view = clutter_stage_get_view_at (stage, - entry->coords.x, - entry->coords.y); - if (!pointer_view) - continue; - if (pointer_view != view) - continue; - - clutter_stage_pick_and_update_device (stage, - entry->device, - NULL, NULL, - CLUTTER_DEVICE_UPDATE_IGNORE_CACHE | - CLUTTER_DEVICE_UPDATE_EMIT_CROSSING, - entry->coords, - CLUTTER_CURRENT_TIME); - } -} diff --git a/mutter/clutter/clutter/clutter-stage.h b/mutter/clutter/clutter/clutter-stage.h deleted file mode 100644 index b9f21ca..0000000 --- a/mutter/clutter/clutter/clutter-stage.h +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * 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 . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-actor.h" -#include "clutter/clutter-grab.h" -#include "clutter/clutter-types.h" -#include "clutter/clutter-stage-view.h" -#include "mtk/mtk.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_STAGE (clutter_stage_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterStage, - clutter_stage, - CLUTTER, - STAGE, - ClutterActor) -/** - * ClutterStageClass: - * @activate: handler for the #ClutterStage::activate signal - * @deactivate: handler for the #ClutterStage::deactivate signal - * - * The #ClutterStageClass structure contains only private data - */ - -struct _ClutterStageClass -{ - /*< private >*/ - ClutterActorClass parent_class; - - /*< public >*/ - /* signals */ - void (* activate) (ClutterStage *stage); - void (* deactivate) (ClutterStage *stage); - - void (* before_paint) (ClutterStage *stage, - ClutterStageView *view, - ClutterFrame *frame); - - void (* paint_view) (ClutterStage *stage, - ClutterStageView *view, - const MtkRegion *redraw_clip, - ClutterFrame *frame); -}; - -/** - * ClutterPerspective: - * @fovy: the field of view angle, in degrees, in the y direction - * @aspect: the aspect ratio that determines the field of view in the x - * direction. The aspect ratio is the ratio of x (width) to y (height) - * @z_near: the distance from the viewer to the near clipping - * plane (always positive) - * @z_far: the distance from the viewer to the far clipping - * plane (always positive) - * - * Stage perspective definition. - */ -struct _ClutterPerspective -{ - gfloat fovy; - gfloat aspect; - gfloat z_near; - gfloat z_far; -}; - -typedef enum -{ - CLUTTER_FRAME_INFO_FLAG_NONE = 0, - /* presentation_time timestamp was provided by the hardware */ - CLUTTER_FRAME_INFO_FLAG_HW_CLOCK = 1 << 0, - /* - * The presentation of this frame was done zero-copy. This means the buffer - * from the client was given to display hardware as is, without copying it. - * Compositing with OpenGL counts as copying, even if textured directly from - * the client buffer. Possible zero-copy cases include direct scanout of a - * fullscreen surface and a surface on a hardware overlay. - */ - CLUTTER_FRAME_INFO_FLAG_ZERO_COPY = 1 << 1, - /* - * The presentation was synchronized to the "vertical retrace" by the display - * hardware such that tearing does not happen. Relying on user space - * scheduling is not acceptable for this flag. If presentation is done by a - * copy to the active frontbuffer, then it must guarantee that tearing cannot - * happen. - */ - CLUTTER_FRAME_INFO_FLAG_VSYNC = 1 << 2, -} ClutterFrameInfoFlag; - -/** - * ClutterFrameInfo: (skip) - */ -struct _ClutterFrameInfo -{ - int64_t frame_counter; - int64_t presentation_time; /* microseconds; CLOCK_MONOTONIC */ - float refresh_rate; - - ClutterFrameInfoFlag flags; - - unsigned int sequence; - - gboolean has_valid_gpu_rendering_duration; - int64_t gpu_rendering_duration_ns; - int64_t cpu_time_before_buffer_swap_us; -}; - -CLUTTER_EXPORT -GType clutter_perspective_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -void clutter_stage_get_perspective (ClutterStage *stage, - ClutterPerspective *perspective); -CLUTTER_EXPORT -void clutter_stage_set_title (ClutterStage *stage, - const gchar *title); -CLUTTER_EXPORT -const gchar * clutter_stage_get_title (ClutterStage *stage); - -CLUTTER_EXPORT -void clutter_stage_set_minimum_size (ClutterStage *stage, - guint width, - guint height); -CLUTTER_EXPORT -void clutter_stage_set_key_focus (ClutterStage *stage, - ClutterActor *actor); -CLUTTER_EXPORT -ClutterActor * clutter_stage_get_key_focus (ClutterStage *stage); - -CLUTTER_EXPORT -ClutterActor * clutter_stage_get_actor_at_pos (ClutterStage *stage, - ClutterPickMode pick_mode, - float x, - float y); -CLUTTER_EXPORT -guchar * clutter_stage_read_pixels (ClutterStage *stage, - gint x, - gint y, - gint width, - gint height); - -CLUTTER_EXPORT -void clutter_stage_ensure_viewport (ClutterStage *stage); - -CLUTTER_EXPORT -gboolean clutter_stage_is_redraw_queued_on_view (ClutterStage *stage, - ClutterStageView *view); -CLUTTER_EXPORT -void clutter_stage_schedule_update (ClutterStage *stage); - -CLUTTER_EXPORT -gboolean clutter_stage_get_capture_final_size (ClutterStage *stage, - MtkRectangle *rect, - int *out_width, - int *out_height, - float *out_scale); - -CLUTTER_EXPORT -void clutter_stage_paint_to_framebuffer (ClutterStage *stage, - CoglFramebuffer *framebuffer, - const MtkRectangle *rect, - float scale, - ClutterPaintFlag paint_flags); - -CLUTTER_EXPORT -gboolean clutter_stage_paint_to_buffer (ClutterStage *stage, - const MtkRectangle *rect, - float scale, - uint8_t *data, - int stride, - CoglPixelFormat format, - ClutterPaintFlag paint_flags, - GError **error); - -CLUTTER_EXPORT -ClutterContent * clutter_stage_paint_to_content (ClutterStage *stage, - const MtkRectangle *rect, - float scale, - ClutterPaintFlag paint_flags, - GError **error); - -CLUTTER_EXPORT -ClutterStageView * clutter_stage_get_view_at (ClutterStage *stage, - float x, - float y); - -CLUTTER_EXPORT -ClutterActor * clutter_stage_get_device_actor (ClutterStage *stage, - ClutterInputDevice *device, - ClutterEventSequence *sequence); -CLUTTER_EXPORT -ClutterActor * clutter_stage_get_event_actor (ClutterStage *stage, - const ClutterEvent *event); - -CLUTTER_EXPORT -ClutterGrab * clutter_stage_grab (ClutterStage *stage, - ClutterActor *actor); - -CLUTTER_EXPORT -ClutterActor * clutter_stage_get_grab_actor (ClutterStage *stage); - -/** - * ClutterStageInputForeachFunc: - * @stage: the stage - * @device: Active input device - * @sequence: Active sequence in @device, or %NULL - * @user_data: Data passed to clutter_stage_active_input_foreach() - * - * Iterator function for active input. Active input counts as any pointing - * device currently known to have some form of activity on the stage: Pointers - * leaning on a widget, tablet styli in proximity, active touchpoints... - * - * Returns: %TRUE to keep iterating. %FALSE to stop. - */ -typedef gboolean (*ClutterStageInputForeachFunc) (ClutterStage *stage, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - gpointer user_data); - -CLUTTER_EXPORT -gboolean clutter_stage_pointing_input_foreach (ClutterStage *self, - ClutterStageInputForeachFunc func, - gpointer user_data); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-swipe-action.c b/mutter/clutter/clutter/clutter-swipe-action.c deleted file mode 100644 index 29bf898..0000000 --- a/mutter/clutter/clutter/clutter-swipe-action.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * Copyright (C) 2011 Robert Bosch Car Multimedia GmbH. - * - * 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 . - * - * Author: - * Tomeu Vizoso - * - * Based on ClutterDragAction, written by: - * Emmanuele Bassi - */ - -/** - * ClutterSwipeAction: - * - * Action for swipe gestures - * - * #ClutterSwipeAction is a sub-class of [class@GestureAction] that implements - * the logic for recognizing swipe gestures. - */ - -#include "config.h" - -#include "clutter/clutter-swipe-action.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-private.h" - -typedef struct _ClutterSwipeActionPrivate -{ - ClutterSwipeDirection h_direction; - ClutterSwipeDirection v_direction; - - float distance_x, distance_y; -} ClutterSwipeActionPrivate; - -enum -{ - SWIPE, - - LAST_SIGNAL -}; - -static guint swipe_signals[LAST_SIGNAL] = { 0, }; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterSwipeAction, clutter_swipe_action, CLUTTER_TYPE_GESTURE_ACTION) - -static gboolean -gesture_begin (ClutterGestureAction *action, - ClutterActor *actor) -{ - ClutterSwipeActionPrivate *priv = - clutter_swipe_action_get_instance_private (CLUTTER_SWIPE_ACTION (action)); - - /* reset the state at the beginning of a new gesture */ - priv->h_direction = 0; - priv->v_direction = 0; - - g_object_get (action, - "threshold-trigger-distance-x", &priv->distance_x, - "threshold-trigger-distance-y", &priv->distance_y, - NULL); - - return TRUE; -} - -static gboolean -gesture_progress (ClutterGestureAction *action, - ClutterActor *actor) -{ - ClutterSwipeActionPrivate *priv = - clutter_swipe_action_get_instance_private (CLUTTER_SWIPE_ACTION (action)); - gfloat press_x, press_y; - gfloat motion_x, motion_y; - gfloat delta_x, delta_y; - ClutterSwipeDirection h_direction = 0, v_direction = 0; - - clutter_gesture_action_get_press_coords (action, - 0, - &press_x, - &press_y); - - clutter_gesture_action_get_motion_coords (action, - 0, - &motion_x, - &motion_y); - - delta_x = press_x - motion_x; - delta_y = press_y - motion_y; - - if (delta_x >= priv->distance_x) - h_direction = CLUTTER_SWIPE_DIRECTION_RIGHT; - else if (delta_x < -priv->distance_x) - h_direction = CLUTTER_SWIPE_DIRECTION_LEFT; - - if (delta_y >= priv->distance_y) - v_direction = CLUTTER_SWIPE_DIRECTION_DOWN; - else if (delta_y < -priv->distance_y) - v_direction = CLUTTER_SWIPE_DIRECTION_UP; - - /* cancel gesture on direction reversal */ - if (priv->h_direction == 0) - priv->h_direction = h_direction; - - if (priv->v_direction == 0) - priv->v_direction = v_direction; - - if (priv->h_direction != h_direction) - return FALSE; - - if (priv->v_direction != v_direction) - return FALSE; - - return TRUE; -} - -static void -gesture_end (ClutterGestureAction *action, - ClutterActor *actor) -{ - ClutterSwipeActionPrivate *priv = - clutter_swipe_action_get_instance_private (CLUTTER_SWIPE_ACTION (action)); - gfloat press_x, press_y; - gfloat release_x, release_y; - ClutterSwipeDirection direction = 0; - const ClutterEvent *last_event; - - clutter_gesture_action_get_press_coords (action, - 0, - &press_x, &press_y); - - /* Check the last event instead of get_release_coords(), this - * might not be the sequence that finished on multi-finger swipes. - */ - last_event = clutter_gesture_action_get_last_event (action, 0); - clutter_event_get_coords (last_event, &release_x, &release_y); - - if (release_x - press_x > priv->distance_x) - direction |= CLUTTER_SWIPE_DIRECTION_RIGHT; - else if (press_x - release_x > priv->distance_x) - direction |= CLUTTER_SWIPE_DIRECTION_LEFT; - - if (release_y - press_y > priv->distance_y) - direction |= CLUTTER_SWIPE_DIRECTION_DOWN; - else if (press_y - release_y > priv->distance_y) - direction |= CLUTTER_SWIPE_DIRECTION_UP; - - g_signal_emit (action, swipe_signals[SWIPE], 0, actor, direction); -} - -static void -clutter_swipe_action_constructed (GObject *object) -{ - clutter_gesture_action_set_threshold_trigger_edge (CLUTTER_GESTURE_ACTION (object), - CLUTTER_GESTURE_TRIGGER_EDGE_AFTER); -} - -static void -clutter_swipe_action_class_init (ClutterSwipeActionClass *klass) -{ - ClutterGestureActionClass *gesture_class = - CLUTTER_GESTURE_ACTION_CLASS (klass); - GObjectClass *object_class = - G_OBJECT_CLASS (klass); - - object_class->constructed = clutter_swipe_action_constructed; - - gesture_class->gesture_begin = gesture_begin; - gesture_class->gesture_progress = gesture_progress; - gesture_class->gesture_end = gesture_end; - - /** - * ClutterSwipeAction::swipe: - * @action: the #ClutterSwipeAction that emitted the signal - * @actor: the #ClutterActor attached to the @action - * @direction: the main direction of the swipe gesture - * - * The signal is emitted when a swipe gesture is recognized on the - * attached actor. - * - * Return value: %TRUE if the swipe should continue, and %FALSE if - * the swipe should be cancelled. - */ - swipe_signals[SWIPE] = - g_signal_new (I_("swipe"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, g_signal_accumulator_true_handled, NULL, - _clutter_marshal_BOOLEAN__OBJECT_FLAGS, - G_TYPE_BOOLEAN, 2, - CLUTTER_TYPE_ACTOR, - CLUTTER_TYPE_SWIPE_DIRECTION); -} - -static void -clutter_swipe_action_init (ClutterSwipeAction *self) -{ -} - -/** - * clutter_swipe_action_new: - * - * Creates a new #ClutterSwipeAction instance - * - * Return value: the newly created #ClutterSwipeAction - */ -ClutterAction * -clutter_swipe_action_new (void) -{ - return g_object_new (CLUTTER_TYPE_SWIPE_ACTION, NULL); -} diff --git a/mutter/clutter/clutter/clutter-swipe-action.h b/mutter/clutter/clutter/clutter-swipe-action.h deleted file mode 100644 index f4f20c2..0000000 --- a/mutter/clutter/clutter/clutter-swipe-action.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * Copyright (C) 2011 Robert Bosch Car Multimedia GmbH. - * - * 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 . - * - * Author: - * Tomeu Vizoso - * - * Based on ClutterDragAction, written by: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-gesture-action.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_SWIPE_ACTION (clutter_swipe_action_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterSwipeAction, - clutter_swipe_action, - CLUTTER, - SWIPE_ACTION, - ClutterGestureAction) - -/** - * ClutterSwipeActionClass: - * @swipe: class handler for the #ClutterSwipeAction::swipe signal - * - * The #ClutterSwipeActionClass structure contains - * only private data. - */ -struct _ClutterSwipeActionClass -{ - /*< private >*/ - ClutterGestureActionClass parent_class; - - /*< public >*/ - void (* swipe) (ClutterSwipeAction *action, - ClutterActor *actor, - ClutterSwipeDirection direction); -}; - -CLUTTER_EXPORT -ClutterAction * clutter_swipe_action_new (void); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-tap-action.c b/mutter/clutter/clutter/clutter-tap-action.c deleted file mode 100644 index 581d254..0000000 --- a/mutter/clutter/clutter/clutter-tap-action.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * Copyright (C) 2011 Robert Bosch Car Multimedia GmbH. - * Copyright (C) 2012 Collabora Ltd. - * - * 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 . - * - * Author: - * Emanuele Aina - * - * Based on ClutterPanAction - * Based on ClutterDragAction, ClutterSwipeAction, and MxKineticScrollView, - * written by: - * Emmanuele Bassi - * Tomeu Vizoso - * Chris Lord - */ - -/** - * ClutterTapAction: - * - * Action for tap gestures - * - * #ClutterTapAction is a sub-class of [class@GestureAction] that implements - * the logic for recognizing mouse clicks and touch tap gestures. - * - * The simplest usage of #ClutterTapAction consists in adding it to - * a [class@Actor], setting it as reactive and connecting a - * callback for the [signal@TapAction::tap] signal, along the lines of the - * following code: - * - * ```c - * clutter_actor_add_action (actor, clutter_tap_action_new ()); - * clutter_actor_set_reactive (actor, TRUE); - * g_signal_connect (action, "tap", G_CALLBACK (on_tap_callback), NULL); - * ``` - */ - -#include "config.h" - -#include "clutter/clutter-tap-action.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-private.h" - -enum -{ - TAP, - - LAST_SIGNAL -}; - -static guint tap_signals[LAST_SIGNAL] = { 0, }; - -G_DEFINE_TYPE (ClutterTapAction, clutter_tap_action, - CLUTTER_TYPE_GESTURE_ACTION); - -static void -emit_tap (ClutterTapAction *self, - ClutterActor *actor) -{ - g_signal_emit (self, tap_signals[TAP], 0, actor); -} - -static void -gesture_end (ClutterGestureAction *gesture, - ClutterActor *actor) -{ - emit_tap (CLUTTER_TAP_ACTION (gesture), actor); -} - -static void -clutter_tap_action_constructed (GObject *object) -{ - clutter_gesture_action_set_threshold_trigger_edge (CLUTTER_GESTURE_ACTION (object), - CLUTTER_GESTURE_TRIGGER_EDGE_BEFORE); -} - -static void -clutter_tap_action_class_init (ClutterTapActionClass *klass) -{ - ClutterGestureActionClass *gesture_class = - CLUTTER_GESTURE_ACTION_CLASS (klass); - GObjectClass *object_class = - G_OBJECT_CLASS (klass); - - object_class->constructed = clutter_tap_action_constructed; - - gesture_class->gesture_end = gesture_end; - - /** - * ClutterTapAction::tap: - * @action: the #ClutterTapAction that emitted the signal - * @actor: the #ClutterActor attached to the @action - * - * The signal is emitted when the tap gesture is complete. - */ - tap_signals[TAP] = - g_signal_new (I_("tap"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterTapActionClass, tap), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_ACTOR); -} - -static void -clutter_tap_action_init (ClutterTapAction *self) -{ -} - -/** - * clutter_tap_action_new: - * - * Creates a new #ClutterTapAction instance - * - * Return value: the newly created #ClutterTapAction - */ -ClutterAction * -clutter_tap_action_new (void) -{ - return g_object_new (CLUTTER_TYPE_TAP_ACTION, NULL); -} diff --git a/mutter/clutter/clutter/clutter-tap-action.h b/mutter/clutter/clutter/clutter-tap-action.h deleted file mode 100644 index 1b01013..0000000 --- a/mutter/clutter/clutter/clutter-tap-action.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * Copyright (C) 2011 Robert Bosch Car Multimedia GmbH. - * Copyright (C) 2012 Collabora Ltd. - * - * 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 . - * - * Author: - * Emanuele Aina - * - * Based on ClutterPanAction - * Based on ClutterDragAction, ClutterSwipeAction, and MxKineticScrollView, - * written by: - * Emmanuele Bassi - * Tomeu Vizoso - * Chris Lord - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-gesture-action.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_TAP_ACTION (clutter_tap_action_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterTapAction, - clutter_tap_action, - CLUTTER, - TAP_ACTION, - ClutterGestureAction) - -/** - * ClutterTapActionClass: - * @tap: class handler for the #ClutterTapAction::tap signal - * - * The #ClutterTapActionClass structure contains - * only private data. - */ -struct _ClutterTapActionClass -{ - /*< private >*/ - ClutterGestureActionClass parent_class; - - /*< public >*/ - gboolean (* tap) (ClutterTapAction *action, - ClutterActor *actor); -}; - -CLUTTER_EXPORT -ClutterAction * clutter_tap_action_new (void); -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-text-buffer.c b/mutter/clutter/clutter/clutter-text-buffer.c deleted file mode 100644 index 1d6818d..0000000 --- a/mutter/clutter/clutter/clutter-text-buffer.c +++ /dev/null @@ -1,738 +0,0 @@ -/* clutter-text-buffer.c - * Copyright (C) 2011 Collabora Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, see . - * - * Author: Stef Walter - */ - -#include "config.h" - -#include "clutter/clutter-text-buffer.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-private.h" - -#include - -/** - * ClutterTextBuffer: - * - * Text buffer for [class@Text] - * - * The #ClutterTextBuffer class contains the actual text displayed in a - * [class@Text] widget. - * - * A single #ClutterTextBuffer object can be shared by multiple [class@Text] - * widgets which will then share the same text content, but not the cursor - * position, visibility attributes, icon etc. - * - * #ClutterTextBuffer may be derived from. Such a derived class might allow - * text to be stored in an alternate location, such as non-pageable memory, - * useful in the case of important passwords. Or a derived class could - * integrate with an application's concept of undo/redo. - */ - -/* Initial size of buffer, in bytes */ -#define MIN_SIZE 16 - -enum -{ - PROP_0, - PROP_TEXT, - PROP_LENGTH, - PROP_MAX_LENGTH, - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST] = { NULL, }; - -enum -{ - INSERTED_TEXT, - DELETED_TEXT, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -typedef struct _ClutterTextBufferPrivate -{ - gint max_length; - - /* Only valid if this class is not derived */ - gchar *normal_text; - gsize normal_text_size; - gsize normal_text_bytes; - guint normal_text_chars; -} ClutterTextBufferPrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterTextBuffer, clutter_text_buffer, G_TYPE_OBJECT) - -/* -------------------------------------------------------------------------------- - * DEFAULT IMPLEMENTATIONS OF TEXT BUFFER - * - * These may be overridden by a derived class, behavior may be changed etc... - * The normal_text and normal_text_xxxx fields may not be valid when - * this class is derived from. - */ - -/* Overwrite a memory that might contain sensitive information. */ -static void -trash_area (gchar *area, - gsize len) -{ - volatile gchar *varea = (volatile gchar *)area; - while (len-- > 0) - *varea++ = 0; -} - -static const gchar* -clutter_text_buffer_normal_get_text (ClutterTextBuffer *buffer, - gsize *n_bytes) -{ - ClutterTextBufferPrivate *priv = - clutter_text_buffer_get_instance_private (buffer); - if (n_bytes) - *n_bytes = priv->normal_text_bytes; - if (!priv->normal_text) - return ""; - return priv->normal_text; -} - -static guint -clutter_text_buffer_normal_get_length (ClutterTextBuffer *buffer) -{ - ClutterTextBufferPrivate *priv = - clutter_text_buffer_get_instance_private (buffer); - return priv->normal_text_chars; -} - -static guint -clutter_text_buffer_normal_insert_text (ClutterTextBuffer *buffer, - guint position, - const gchar *chars, - guint n_chars) -{ - ClutterTextBufferPrivate *pv = - clutter_text_buffer_get_instance_private (buffer);; - gsize prev_size; - gsize n_bytes; - gsize at; - - n_bytes = g_utf8_offset_to_pointer (chars, n_chars) - chars; - - /* Need more memory */ - if (n_bytes + pv->normal_text_bytes + 1 > pv->normal_text_size) - { - gchar *et_new; - - prev_size = pv->normal_text_size; - - /* Calculate our new buffer size */ - while (n_bytes + pv->normal_text_bytes + 1 > pv->normal_text_size) - { - if (pv->normal_text_size == 0) - pv->normal_text_size = MIN_SIZE; - else - { - if (2 * pv->normal_text_size < CLUTTER_TEXT_BUFFER_MAX_SIZE) - pv->normal_text_size *= 2; - else - { - pv->normal_text_size = CLUTTER_TEXT_BUFFER_MAX_SIZE; - if (n_bytes > pv->normal_text_size - pv->normal_text_bytes - 1) - { - n_bytes = pv->normal_text_size - pv->normal_text_bytes - 1; - n_bytes = g_utf8_find_prev_char (chars, chars + n_bytes + 1) - chars; - n_chars = g_utf8_strlen (chars, n_bytes); - } - break; - } - } - } - - /* Could be a password, so can't leave stuff in memory. */ - et_new = g_malloc (pv->normal_text_size); - memcpy (et_new, pv->normal_text, MIN (prev_size, pv->normal_text_size)); - trash_area (pv->normal_text, prev_size); - g_free (pv->normal_text); - pv->normal_text = et_new; - } - - /* Actual text insertion */ - at = g_utf8_offset_to_pointer (pv->normal_text, position) - pv->normal_text; - memmove (pv->normal_text + at + n_bytes, pv->normal_text + at, pv->normal_text_bytes - at); - memcpy (pv->normal_text + at, chars, n_bytes); - - /* Book keeping */ - pv->normal_text_bytes += n_bytes; - pv->normal_text_chars += n_chars; - pv->normal_text[pv->normal_text_bytes] = '\0'; - - clutter_text_buffer_emit_inserted_text (buffer, position, chars, n_chars); - return n_chars; -} - -static guint -clutter_text_buffer_normal_delete_text (ClutterTextBuffer *buffer, - guint position, - guint n_chars) -{ - ClutterTextBufferPrivate *pv = - clutter_text_buffer_get_instance_private (buffer);; - gsize start, end; - - if (position > pv->normal_text_chars) - position = pv->normal_text_chars; - if (position + n_chars > pv->normal_text_chars) - n_chars = pv->normal_text_chars - position; - - if (n_chars > 0) - { - start = g_utf8_offset_to_pointer (pv->normal_text, position) - pv->normal_text; - end = g_utf8_offset_to_pointer (pv->normal_text, position + n_chars) - pv->normal_text; - - memmove (pv->normal_text + start, pv->normal_text + end, pv->normal_text_bytes + 1 - end); - pv->normal_text_chars -= n_chars; - pv->normal_text_bytes -= (end - start); - - /* - * Could be a password, make sure we don't leave anything sensitive after - * the terminating zero. Note, that the terminating zero already trashed - * one byte. - */ - trash_area (pv->normal_text + pv->normal_text_bytes + 1, end - start - 1); - - clutter_text_buffer_emit_deleted_text (buffer, position, n_chars); - } - - return n_chars; -} - -/* -------------------------------------------------------------------------------- - * - */ - -static void -clutter_text_buffer_real_inserted_text (ClutterTextBuffer *buffer, - guint position, - const gchar *chars, - guint n_chars) -{ - g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_TEXT]); - g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_LENGTH]); -} - -static void -clutter_text_buffer_real_deleted_text (ClutterTextBuffer *buffer, - guint position, - guint n_chars) -{ - g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_TEXT]); - g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_LENGTH]); -} - -/* -------------------------------------------------------------------------------- - * - */ - -static void -clutter_text_buffer_init (ClutterTextBuffer *self) -{ - ClutterTextBufferPrivate *priv = - clutter_text_buffer_get_instance_private (self); - - priv->normal_text = NULL; - priv->normal_text_chars = 0; - priv->normal_text_bytes = 0; - priv->normal_text_size = 0; -} - -static void -clutter_text_buffer_finalize (GObject *obj) -{ - ClutterTextBuffer *buffer = CLUTTER_TEXT_BUFFER (obj); - ClutterTextBufferPrivate *pv = - clutter_text_buffer_get_instance_private (buffer); - - if (pv->normal_text) - { - trash_area (pv->normal_text, pv->normal_text_size); - g_free (pv->normal_text); - pv->normal_text = NULL; - pv->normal_text_bytes = pv->normal_text_size = 0; - pv->normal_text_chars = 0; - } - - G_OBJECT_CLASS (clutter_text_buffer_parent_class)->finalize (obj); -} - -static void -clutter_text_buffer_set_property (GObject *obj, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterTextBuffer *buffer = CLUTTER_TEXT_BUFFER (obj); - - switch (prop_id) - { - case PROP_MAX_LENGTH: - clutter_text_buffer_set_max_length (buffer, g_value_get_int (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); - break; - } -} - -static void -clutter_text_buffer_get_property (GObject *obj, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterTextBuffer *buffer = CLUTTER_TEXT_BUFFER (obj); - - switch (prop_id) - { - case PROP_TEXT: - g_value_set_string (value, clutter_text_buffer_get_text (buffer)); - break; - case PROP_LENGTH: - g_value_set_uint (value, clutter_text_buffer_get_length (buffer)); - break; - case PROP_MAX_LENGTH: - g_value_set_int (value, clutter_text_buffer_get_max_length (buffer)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); - break; - } -} - -static void -clutter_text_buffer_class_init (ClutterTextBufferClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->finalize = clutter_text_buffer_finalize; - gobject_class->set_property = clutter_text_buffer_set_property; - gobject_class->get_property = clutter_text_buffer_get_property; - - klass->get_text = clutter_text_buffer_normal_get_text; - klass->get_length = clutter_text_buffer_normal_get_length; - klass->insert_text = clutter_text_buffer_normal_insert_text; - klass->delete_text = clutter_text_buffer_normal_delete_text; - - klass->inserted_text = clutter_text_buffer_real_inserted_text; - klass->deleted_text = clutter_text_buffer_real_deleted_text; - - /** - * ClutterTextBuffer:text: - * - * The contents of the buffer. - */ - obj_props[PROP_TEXT] = - g_param_spec_string ("text", NULL, NULL, - "", - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - /** - * ClutterTextBuffer:length: - * - * The length (in characters) of the text in buffer. - */ - obj_props[PROP_LENGTH] = - g_param_spec_uint ("length", NULL, NULL, - 0, CLUTTER_TEXT_BUFFER_MAX_SIZE, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - /** - * ClutterTextBuffer:max-length: - * - * The maximum length (in characters) of the text in the buffer. - */ - obj_props[PROP_MAX_LENGTH] = - g_param_spec_int ("max-length", NULL, NULL, - 0, CLUTTER_TEXT_BUFFER_MAX_SIZE, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); - - /** - * ClutterTextBuffer::inserted-text: - * @buffer: a #ClutterTextBuffer - * @position: the position the text was inserted at. - * @chars: The text that was inserted. - * @n_chars: The number of characters that were inserted. - * - * This signal is emitted after text is inserted into the buffer. - */ - signals[INSERTED_TEXT] = - g_signal_new (I_("inserted-text"), - CLUTTER_TYPE_TEXT_BUFFER, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterTextBufferClass, inserted_text), - NULL, NULL, - _clutter_marshal_VOID__UINT_STRING_UINT, - G_TYPE_NONE, 3, - G_TYPE_UINT, - G_TYPE_STRING, - G_TYPE_UINT); - - /** - * ClutterTextBuffer::deleted-text: - * @buffer: a #ClutterTextBuffer - * @position: the position the text was deleted at. - * @n_chars: The number of characters that were deleted. - * - * This signal is emitted after text is deleted from the buffer. - */ - signals[DELETED_TEXT] = - g_signal_new (I_("deleted-text"), - CLUTTER_TYPE_TEXT_BUFFER, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterTextBufferClass, deleted_text), - NULL, NULL, - _clutter_marshal_VOID__UINT_UINT, - G_TYPE_NONE, 2, - G_TYPE_UINT, - G_TYPE_UINT); -} - -/* -------------------------------------------------------------------------------- - * - */ - -/** - * clutter_text_buffer_new: - * - * Create a new ClutterTextBuffer object. - * - * Return value: A new ClutterTextBuffer object. - **/ -ClutterTextBuffer* -clutter_text_buffer_new (void) -{ - return g_object_new (CLUTTER_TYPE_TEXT_BUFFER, NULL); -} - - -/** - * clutter_text_buffer_new_with_text: - * @text: (allow-none): initial buffer text - * @text_len: initial buffer text length, or -1 for null-terminated. - * - * Create a new ClutterTextBuffer object with some text. - * - * Return value: A new ClutterTextBuffer object. - **/ -ClutterTextBuffer* -clutter_text_buffer_new_with_text (const gchar *text, - gssize text_len) -{ - ClutterTextBuffer *buffer; - buffer = clutter_text_buffer_new (); - clutter_text_buffer_set_text (buffer, text, text_len); - return buffer; -} - - -/** - * clutter_text_buffer_get_length: - * @buffer: a #ClutterTextBuffer - * - * Retrieves the length in characters of the buffer. - * - * Return value: The number of characters in the buffer. - **/ -guint -clutter_text_buffer_get_length (ClutterTextBuffer *buffer) -{ - ClutterTextBufferClass *klass; - - g_return_val_if_fail (CLUTTER_IS_TEXT_BUFFER (buffer), 0); - - klass = CLUTTER_TEXT_BUFFER_GET_CLASS (buffer); - g_return_val_if_fail (klass->get_length != NULL, 0); - - return (*klass->get_length) (buffer); -} - -/** - * clutter_text_buffer_get_bytes: - * @buffer: a #ClutterTextBuffer - * - * Retrieves the length in bytes of the buffer. - * See [method@TextBuffer.get_length]. - * - * Return value: The byte length of the buffer. - **/ -gsize -clutter_text_buffer_get_bytes (ClutterTextBuffer *buffer) -{ - ClutterTextBufferClass *klass; - gsize bytes = 0; - - g_return_val_if_fail (CLUTTER_IS_TEXT_BUFFER (buffer), 0); - - klass = CLUTTER_TEXT_BUFFER_GET_CLASS (buffer); - g_return_val_if_fail (klass->get_text != NULL, 0); - - (*klass->get_text) (buffer, &bytes); - return bytes; -} - -/** - * clutter_text_buffer_get_text: - * @buffer: a #ClutterTextBuffer - * - * Retrieves the contents of the buffer. - * - * The memory pointer returned by this call will not change - * unless this object emits a signal, or is finalized. - * - * Return value: a pointer to the contents of the widget as a - * string. This string points to internally allocated - * storage in the buffer and must not be freed, modified or - * stored. - **/ -const gchar* -clutter_text_buffer_get_text (ClutterTextBuffer *buffer) -{ - ClutterTextBufferClass *klass; - - g_return_val_if_fail (CLUTTER_IS_TEXT_BUFFER (buffer), NULL); - - klass = CLUTTER_TEXT_BUFFER_GET_CLASS (buffer); - g_return_val_if_fail (klass->get_text != NULL, NULL); - - return (*klass->get_text) (buffer, NULL); -} - -/** - * clutter_text_buffer_set_text: - * @buffer: a #ClutterTextBuffer - * @chars: the new text - * @n_chars: the number of characters in @text, or -1 - * - * Sets the text in the buffer. - * - * This is roughly equivalent to calling [method@TextBuffer.delete_text] - * and [method@TextBuffer.insert_text]. - * - * Note that @n_chars is in characters, not in bytes. - **/ -void -clutter_text_buffer_set_text (ClutterTextBuffer *buffer, - const gchar *chars, - gint n_chars) -{ - g_return_if_fail (CLUTTER_IS_TEXT_BUFFER (buffer)); - g_return_if_fail (chars != NULL); - - g_object_freeze_notify (G_OBJECT (buffer)); - clutter_text_buffer_delete_text (buffer, 0, -1); - clutter_text_buffer_insert_text (buffer, 0, chars, n_chars); - g_object_thaw_notify (G_OBJECT (buffer)); -} - -/** - * clutter_text_buffer_set_max_length: - * @buffer: a #ClutterTextBuffer - * @max_length: the maximum length of the entry buffer, or 0 for no maximum. - * (other than the maximum length of entries.) The value passed in will - * be clamped to the range [ 0, %CLUTTER_TEXT_BUFFER_MAX_SIZE ]. - * - * Sets the maximum allowed length of the contents of the buffer. - * - * If the current contents are longer than the given length, - * then they will be truncated to fit. - **/ -void -clutter_text_buffer_set_max_length (ClutterTextBuffer *buffer, - gint max_length) -{ - ClutterTextBufferPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT_BUFFER (buffer)); - - priv = clutter_text_buffer_get_instance_private (buffer); - max_length = CLAMP (max_length, 0, CLUTTER_TEXT_BUFFER_MAX_SIZE); - - if (max_length > 0 && clutter_text_buffer_get_length (buffer) > max_length) - clutter_text_buffer_delete_text (buffer, max_length, -1); - - priv->max_length = max_length; - g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_MAX_LENGTH]); -} - -/** - * clutter_text_buffer_get_max_length: - * @buffer: a #ClutterTextBuffer - * - * Retrieves the maximum allowed length of the text in - * @buffer. See [method@TextBuffer.set_max_length]. - * - * Return value: the maximum allowed number of characters - * in #ClutterTextBuffer, or 0 if there is no maximum. - */ -gint -clutter_text_buffer_get_max_length (ClutterTextBuffer *buffer) -{ - ClutterTextBufferPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT_BUFFER (buffer), 0); - - priv = clutter_text_buffer_get_instance_private (buffer); - return priv->max_length; -} - -/** - * clutter_text_buffer_insert_text: - * @buffer: a #ClutterTextBuffer - * @position: the position at which to insert text. - * @chars: the text to insert into the buffer. - * @n_chars: the length of the text in characters, or -1 - * - * Inserts @n_chars characters of @chars into the contents of the - * buffer, at position @position. - * - * If @n_chars is negative, then characters from chars will be inserted - * until a null-terminator is found. If @position or @n_chars are out of - * bounds, or the maximum buffer text length is exceeded, then they are - * coerced to sane values. - * - * Note that the position and length are in characters, not in bytes. - * - * Returns: The number of characters actually inserted. - */ -guint -clutter_text_buffer_insert_text (ClutterTextBuffer *buffer, - guint position, - const gchar *chars, - gint n_chars) -{ - ClutterTextBufferClass *klass; - ClutterTextBufferPrivate *pv; - guint length; - - g_return_val_if_fail (CLUTTER_IS_TEXT_BUFFER (buffer), 0); - - length = clutter_text_buffer_get_length (buffer); - pv = clutter_text_buffer_get_instance_private (buffer);; - - if (n_chars < 0) - n_chars = g_utf8_strlen (chars, -1); - - /* Bring position into bounds */ - if (position > length) - position = length; - - /* Make sure not entering too much data */ - if (pv->max_length > 0) - { - if (length >= pv->max_length) - n_chars = 0; - else if (length + n_chars > pv->max_length) - n_chars -= (length + n_chars) - pv->max_length; - } - - klass = CLUTTER_TEXT_BUFFER_GET_CLASS (buffer); - g_return_val_if_fail (klass->insert_text != NULL, 0); - - return (klass->insert_text) (buffer, position, chars, n_chars); -} - -/** - * clutter_text_buffer_delete_text: - * @buffer: a #ClutterTextBuffer - * @position: position at which to delete text - * @n_chars: number of characters to delete - * - * Deletes a sequence of characters from the buffer. @n_chars characters are - * deleted starting at @position. If @n_chars is negative, then all characters - * until the end of the text are deleted. - * - * If @position or @n_chars are out of bounds, then they are coerced to sane - * values. - * - * Note that the positions are specified in characters, not bytes. - * - * Returns: The number of characters deleted. - */ -guint -clutter_text_buffer_delete_text (ClutterTextBuffer *buffer, - guint position, - gint n_chars) -{ - ClutterTextBufferClass *klass; - guint length; - - g_return_val_if_fail (CLUTTER_IS_TEXT_BUFFER (buffer), 0); - - length = clutter_text_buffer_get_length (buffer); - if (n_chars < 0) - n_chars = length; - if (position > length) - position = length; - if (position + n_chars > length) - n_chars = length - position; - - klass = CLUTTER_TEXT_BUFFER_GET_CLASS (buffer); - g_return_val_if_fail (klass->delete_text != NULL, 0); - - return (klass->delete_text) (buffer, position, n_chars); -} - -/** - * clutter_text_buffer_emit_inserted_text: - * @buffer: a #ClutterTextBuffer - * @position: position at which text was inserted - * @chars: text that was inserted - * @n_chars: number of characters inserted - * - * Emits the [signal@TextBuffer::inserted-text] signal on @buffer. - * - * Used when subclassing #ClutterTextBuffer - */ -void -clutter_text_buffer_emit_inserted_text (ClutterTextBuffer *buffer, - guint position, - const gchar *chars, - guint n_chars) -{ - g_return_if_fail (CLUTTER_IS_TEXT_BUFFER (buffer)); - g_signal_emit (buffer, signals[INSERTED_TEXT], 0, position, chars, n_chars); -} - -/** - * clutter_text_buffer_emit_deleted_text: - * @buffer: a #ClutterTextBuffer - * @position: position at which text was deleted - * @n_chars: number of characters deleted - * - * Emits the [signal@TextBuffer::deleted-text] signal on @buffer. - * - * Used when subclassing #ClutterTextBuffer - */ -void -clutter_text_buffer_emit_deleted_text (ClutterTextBuffer *buffer, - guint position, - guint n_chars) -{ - g_return_if_fail (CLUTTER_IS_TEXT_BUFFER (buffer)); - g_signal_emit (buffer, signals[DELETED_TEXT], 0, position, n_chars); -} diff --git a/mutter/clutter/clutter/clutter-text-buffer.h b/mutter/clutter/clutter/clutter-text-buffer.h deleted file mode 100644 index bbf6a45..0000000 --- a/mutter/clutter/clutter/clutter-text-buffer.h +++ /dev/null @@ -1,131 +0,0 @@ -/* clutter-text-buffer.h - * Copyright (C) 2011 Collabora Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, see . - * - * Author: Stef Walter - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_TEXT_BUFFER (clutter_text_buffer_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterTextBuffer, - clutter_text_buffer, - CLUTTER, - TEXT_BUFFER, - GObject) - -/** - * CLUTTER_TEXT_BUFFER_MAX_SIZE: - * - * Maximum size of text buffer, in bytes. - */ -#define CLUTTER_TEXT_BUFFER_MAX_SIZE G_MAXUSHORT - -/** - * ClutterTextBufferClass: - * @inserted_text: default handler for the #ClutterTextBuffer::inserted-text signal - * @deleted_text: default handler for the #ClutterTextBuffer::deleted-text signal - * @get_text: virtual function - * @get_length: virtual function - * @insert_text: virtual function - * @delete_text: virtual function - * - * The #ClutterTextBufferClass structure contains - * only private data. - */ -struct _ClutterTextBufferClass -{ - /*< private >*/ - GObjectClass parent_class; - - /*< public >*/ - /* Signals */ - void (*inserted_text) (ClutterTextBuffer *buffer, - guint position, - const gchar *chars, - guint n_chars); - - void (*deleted_text) (ClutterTextBuffer *buffer, - guint position, - guint n_chars); - - /* Virtual Methods */ - const gchar* (*get_text) (ClutterTextBuffer *buffer, - gsize *n_bytes); - - guint (*get_length) (ClutterTextBuffer *buffer); - - guint (*insert_text) (ClutterTextBuffer *buffer, - guint position, - const gchar *chars, - guint n_chars); - - guint (*delete_text) (ClutterTextBuffer *buffer, - guint position, - guint n_chars); -}; - -CLUTTER_EXPORT -ClutterTextBuffer* clutter_text_buffer_new (void); -CLUTTER_EXPORT -ClutterTextBuffer* clutter_text_buffer_new_with_text (const gchar *text, - gssize text_len); - -CLUTTER_EXPORT -gsize clutter_text_buffer_get_bytes (ClutterTextBuffer *buffer); -CLUTTER_EXPORT -guint clutter_text_buffer_get_length (ClutterTextBuffer *buffer); -CLUTTER_EXPORT -const gchar* clutter_text_buffer_get_text (ClutterTextBuffer *buffer); -CLUTTER_EXPORT -void clutter_text_buffer_set_text (ClutterTextBuffer *buffer, - const gchar *chars, - gint n_chars); -CLUTTER_EXPORT -void clutter_text_buffer_set_max_length (ClutterTextBuffer *buffer, - gint max_length); -CLUTTER_EXPORT -gint clutter_text_buffer_get_max_length (ClutterTextBuffer *buffer); - -CLUTTER_EXPORT -guint clutter_text_buffer_insert_text (ClutterTextBuffer *buffer, - guint position, - const gchar *chars, - gint n_chars); -CLUTTER_EXPORT -guint clutter_text_buffer_delete_text (ClutterTextBuffer *buffer, - guint position, - gint n_chars); -CLUTTER_EXPORT -void clutter_text_buffer_emit_inserted_text (ClutterTextBuffer *buffer, - guint position, - const gchar *chars, - guint n_chars); -CLUTTER_EXPORT -void clutter_text_buffer_emit_deleted_text (ClutterTextBuffer *buffer, - guint position, - guint n_chars); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-text.c b/mutter/clutter/clutter/clutter-text.c deleted file mode 100644 index af804a3..0000000 --- a/mutter/clutter/clutter/clutter-text.c +++ /dev/null @@ -1,6617 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2008 Intel Corporation. - * - * Authored By: Øyvind Kolås - * Emmanuele Bassi - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/** - * ClutterText: - * - * An actor for displaying and editing text - * - * #ClutterText is an actor that displays custom text using Pango - * as the text rendering engine. - * - * #ClutterText also allows inline editing of the text if the - * actor is set editable using [method@Text.set_editable]. - * - * Selection using keyboard or pointers can be enabled using - * [method@Text.set_selectable]. - */ - -#include "config.h" - -#include -#include - -#include "clutter/clutter-text.h" - -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-animatable.h" -#include "clutter/clutter-backend-private.h" -#include "clutter/clutter-binding-pool.h" -#include "clutter/clutter-color.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-keysyms.h" -#include "clutter/clutter-main.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-private.h" /* includes */ -#include "clutter/clutter-property-transition.h" -#include "clutter/clutter-text-buffer.h" -#include "clutter/clutter-paint-volume-private.h" -#include "clutter/clutter-input-focus.h" - -/* cursor width in pixels */ -#define DEFAULT_CURSOR_SIZE 2 - -/* vertical padding for the cursor */ -#define CURSOR_Y_PADDING 2 - -/* We need at least three cached layouts to run the allocation without - * regenerating a new layout. First the layout will be generated at - * full width to get the preferred width, then it will be generated at - * the preferred width to get the preferred height and then it might - * be regenerated at a different width to get the height for the - * actual allocated width - * - * since we might get multiple queries from layout managers doing a - * double-pass allocations, like tabular ones, we should use 6 slots - */ -#define N_CACHED_LAYOUTS 6 - -typedef struct _LayoutCache LayoutCache; - -struct _LayoutCache -{ - /* Cached layout. Pango internally caches the computed extents - * when they are requested so there is no need to cache that as - * well - */ - PangoLayout *layout; - - /* A number representing the age of this cache (so that when a - * new layout is needed the last used cache is replaced) - */ - guint age; -}; - -struct _ClutterTextInputFocus -{ - ClutterInputFocus parent_instance; - ClutterText *text; -}; - -typedef struct _ClutterTextPrivate -{ - PangoFontDescription *font_desc; - - /* the displayed text */ - ClutterTextBuffer *buffer; - - gchar *font_name; - - gchar *preedit_str; - - ClutterColor text_color; - - LayoutCache cached_layouts[N_CACHED_LAYOUTS]; - guint cache_age; - - /* These are the attributes set by the attributes property */ - PangoAttrList *attrs; - /* These are the attributes derived from the text when the - use-markup property is set */ - PangoAttrList *markup_attrs; - /* This is the combination of the above two lists. It is set to NULL - whenever either of them changes and then regenerated by merging - the two lists whenever a layout is needed */ - PangoAttrList *effective_attrs; - /* These are the attributes for the preedit string. These are merged - with the effective attributes into a temporary list before - creating a layout */ - PangoAttrList *preedit_attrs; - - /* current cursor position */ - gint position; - - /* current 'other end of selection' position */ - gint selection_bound; - - /* the x position in the PangoLayout, used to - * avoid drifting when repeatedly moving up|down - */ - gint x_pos; - - /* the x position of the PangoLayout (in both physical and logical pixels) - * when in single line mode, to scroll the contents of the - * text actor - */ - gint text_x; - gint text_logical_x; - - /* the y position of the PangoLayout (in both physical and logical pixels), - * fixed to 0 by default for now */ - gint text_y; - gint text_logical_y; - - /* Where to draw the cursor */ - graphene_rect_t cursor_rect; - ClutterColor cursor_color; - guint cursor_size; - - /* Box representing the paint volume. The box is lazily calculated - and cached */ - ClutterPaintVolume paint_volume; - - guint preedit_cursor_pos; - gint preedit_n_chars; - - ClutterColor selection_color; - - ClutterColor selected_text_color; - - gunichar password_char; - - guint password_hint_id; - guint password_hint_timeout; - - /* Signal handler for when the backend changes its font settings */ - gulong settings_changed_id; - - /* Signal handler for when the :text-direction changes */ - gulong direction_changed_id; - - ClutterInputFocus *input_focus; - ClutterInputContentHintFlags input_hints; - ClutterInputContentPurpose input_purpose; - - float last_click_x; - float last_click_y; - uint32_t last_click_time_ms; - int click_count; - - /* bitfields */ - guint alignment : 2; - guint wrap : 1; - guint use_underline : 1; - guint use_markup : 1; - guint ellipsize : 3; - guint single_line_mode : 1; - guint wrap_mode : 3; - guint justify : 1; - guint editable : 1; - guint cursor_visible : 1; - guint activatable : 1; - guint selectable : 1; - guint selection_color_set : 1; - guint in_select_drag : 1; - guint in_select_touch : 1; - guint cursor_color_set : 1; - guint preedit_set : 1; - guint is_default_font : 1; - guint has_focus : 1; - guint selected_text_color_set : 1; - guint paint_volume_valid : 1; - guint show_password_hint : 1; - guint password_hint_visible : 1; - guint resolved_direction : 4; -} ClutterTextPrivate; - -enum -{ - PROP_0, - - PROP_BUFFER, - PROP_FONT_NAME, - PROP_FONT_DESCRIPTION, - PROP_TEXT, - PROP_COLOR, - PROP_USE_MARKUP, - PROP_ATTRIBUTES, - PROP_LINE_ALIGNMENT, - PROP_LINE_WRAP, - PROP_LINE_WRAP_MODE, - PROP_JUSTIFY, - PROP_ELLIPSIZE, - PROP_SELECTION_BOUND, - PROP_SELECTION_COLOR, - PROP_SELECTION_COLOR_SET, - PROP_CURSOR_VISIBLE, - PROP_CURSOR_COLOR, - PROP_CURSOR_COLOR_SET, - PROP_CURSOR_SIZE, - PROP_CURSOR_POSITION, - PROP_EDITABLE, - PROP_SELECTABLE, - PROP_ACTIVATABLE, - PROP_PASSWORD_CHAR, - PROP_MAX_LENGTH, - PROP_SINGLE_LINE_MODE, - PROP_SELECTED_TEXT_COLOR, - PROP_SELECTED_TEXT_COLOR_SET, - PROP_INPUT_HINTS, - PROP_INPUT_PURPOSE, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -enum -{ - TEXT_CHANGED, - ACTIVATE, - INSERT_TEXT, - DELETE_TEXT, - CURSOR_CHANGED, - - LAST_SIGNAL -}; - -static guint text_signals[LAST_SIGNAL] = { 0, }; - -static void clutter_text_settings_changed_cb (ClutterText *text); -static void buffer_connect_signals (ClutterText *self); -static void buffer_disconnect_signals (ClutterText *self); -static ClutterTextBuffer *get_buffer (ClutterText *self); - -static const ClutterColor default_cursor_color = { 0, 0, 0, 255 }; -static const ClutterColor default_selection_color = { 0, 0, 0, 255 }; -static const ClutterColor default_text_color = { 0, 0, 0, 255 }; -static const ClutterColor default_selected_text_color = { 0, 0, 0, 255 }; - -static ClutterAnimatableInterface *parent_animatable_iface = NULL; - -/* ClutterTextInputFocus */ -#define CLUTTER_TYPE_TEXT_INPUT_FOCUS (clutter_text_input_focus_get_type ()) - -G_DECLARE_FINAL_TYPE (ClutterTextInputFocus, clutter_text_input_focus, - CLUTTER, TEXT_INPUT_FOCUS, ClutterInputFocus) -G_DEFINE_TYPE (ClutterTextInputFocus, clutter_text_input_focus, - CLUTTER_TYPE_INPUT_FOCUS) - -/* Utilities pango to (logical) pixels functions */ -static float -pixels_to_pango (float px) -{ - return ceilf (px * (float) PANGO_SCALE); -} - -static float -logical_pixels_to_pango (float px, - float scale) -{ - return pixels_to_pango (px * scale); -} - -static float -pango_to_pixels (float size) -{ - return ceilf (size / (float) PANGO_SCALE); -} - -static float -pango_to_logical_pixels (float size, - float scale) -{ - return pango_to_pixels (size / scale); -} - -static void -clutter_text_input_focus_request_surrounding (ClutterInputFocus *focus) -{ - ClutterText *clutter_text = CLUTTER_TEXT_INPUT_FOCUS (focus)->text; - ClutterTextBuffer *buffer; - const gchar *text; - gint anchor_pos, cursor_pos; - - buffer = clutter_text_get_buffer (clutter_text); - text = clutter_text_buffer_get_text (buffer); - - cursor_pos = clutter_text_get_cursor_position (clutter_text); - if (cursor_pos < 0) - cursor_pos = clutter_text_buffer_get_length (buffer); - - anchor_pos = clutter_text_get_selection_bound (clutter_text); - if (anchor_pos < 0) - anchor_pos = cursor_pos; - - clutter_input_focus_set_surrounding (focus, text, - cursor_pos, - anchor_pos); -} - -static void -clutter_text_input_focus_delete_surrounding (ClutterInputFocus *focus, - int offset, - guint len) -{ - ClutterText *clutter_text = CLUTTER_TEXT_INPUT_FOCUS (focus)->text; - ClutterTextBuffer *buffer; - int cursor; - int start; - - buffer = get_buffer (clutter_text); - - cursor = clutter_text_get_cursor_position (clutter_text); - if (cursor < 0) - cursor = clutter_text_buffer_get_length (buffer); - - start = cursor + offset; - if (start < 0) - { - g_warning ("The offset '%d' of deleting surrounding is larger than the cursor pos '%d'", - offset, cursor); - return; - } - if (clutter_text_get_editable (clutter_text)) - clutter_text_delete_text (clutter_text, start, start + len); - - clutter_text_input_focus_request_surrounding (focus); -} - -static void -clutter_text_input_focus_commit_text (ClutterInputFocus *focus, - const gchar *text) -{ - ClutterText *clutter_text = CLUTTER_TEXT_INPUT_FOCUS (focus)->text; - - if (clutter_text_get_editable (clutter_text)) - { - clutter_text_delete_selection (clutter_text); - clutter_text_insert_text (clutter_text, text, - clutter_text_get_cursor_position (clutter_text)); - clutter_text_set_preedit_string (clutter_text, NULL, NULL, 0); - clutter_text_input_focus_request_surrounding (focus); - } -} - -static void -clutter_text_input_focus_set_preedit_text (ClutterInputFocus *focus, - const gchar *preedit_text, - unsigned int cursor_pos, - unsigned int anchor_pos) -{ - ClutterText *clutter_text = CLUTTER_TEXT_INPUT_FOCUS (focus)->text; - - if (clutter_text_get_editable (clutter_text)) - { - PangoAttrList *list; - - list = pango_attr_list_new (); - pango_attr_list_insert (list, pango_attr_underline_new (PANGO_UNDERLINE_SINGLE)); - clutter_text_set_preedit_string (clutter_text, - preedit_text, list, - cursor_pos); - pango_attr_list_unref (list); - } -} - -static void -clutter_text_input_focus_class_init (ClutterTextInputFocusClass *klass) -{ - ClutterInputFocusClass *focus_class = CLUTTER_INPUT_FOCUS_CLASS (klass); - - focus_class->request_surrounding = clutter_text_input_focus_request_surrounding; - focus_class->delete_surrounding = clutter_text_input_focus_delete_surrounding; - focus_class->commit_text = clutter_text_input_focus_commit_text; - focus_class->set_preedit_text = clutter_text_input_focus_set_preedit_text; -} - -static void -clutter_text_input_focus_init (ClutterTextInputFocus *focus) -{ -} - -static ClutterInputFocus * -clutter_text_input_focus_new (ClutterText *text) -{ - ClutterTextInputFocus *focus; - - focus = g_object_new (CLUTTER_TYPE_TEXT_INPUT_FOCUS, NULL); - focus->text = text; - - return CLUTTER_INPUT_FOCUS (focus); -} - -/* ClutterText */ -static void clutter_animatable_iface_init (ClutterAnimatableInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (ClutterText, - clutter_text, - CLUTTER_TYPE_ACTOR, - G_ADD_PRIVATE (ClutterText) - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_ANIMATABLE, - clutter_animatable_iface_init)); - -static inline void -clutter_text_queue_redraw (ClutterActor *self) -{ - clutter_actor_invalidate_paint_volume (self); - clutter_actor_queue_redraw (self); -} - -static gboolean -clutter_text_should_draw_cursor (ClutterText *self) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - - return (priv->editable || priv->selectable) && - priv->cursor_visible && - priv->has_focus; -} - -#define offset_real(t,p) ((p) == -1 ? g_utf8_strlen ((t), -1) : (p)) - -static gint -offset_to_bytes (const gchar *text, - gint pos) -{ - const gchar *ptr; - - if (pos < 0) - return strlen (text); - - /* Loop over each character in the string until we either reach the - end or the requested position */ - for (ptr = text; *ptr && pos-- > 0; ptr = g_utf8_next_char (ptr)); - - return ptr - text; -} - -#define bytes_to_offset(t,p) (g_utf8_pointer_to_offset ((t), (t) + (p))) - -static inline void -clutter_text_clear_selection (ClutterText *self) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - - if (priv->selection_bound != priv->position) - { - priv->selection_bound = priv->position; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SELECTION_BOUND]); - clutter_text_queue_redraw (CLUTTER_ACTOR (self)); - } -} - -static gboolean -clutter_text_is_empty (ClutterText *self) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - if (priv->buffer == NULL) - return TRUE; - - if (clutter_text_buffer_get_length (priv->buffer) == 0) - return TRUE; - - return FALSE; -} - -static gchar * -clutter_text_get_display_text (ClutterText *self) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - ClutterTextBuffer *buffer; - const gchar *text; - - /* short-circuit the case where the buffer is unset or it's empty, - * to avoid creating a pointless TextBuffer and emitting - * notifications with it - */ - if (clutter_text_is_empty (self)) - return g_strdup (""); - - buffer = get_buffer (self); - text = clutter_text_buffer_get_text (buffer); - - /* simple short-circuit to avoid going through GString - * with an empty text and a password char set - */ - if (text[0] == '\0') - return g_strdup (""); - - if (G_LIKELY (priv->password_char == 0)) - return g_strdup (text); - else - { - GString *str; - gunichar invisible_char; - gchar buf[7]; - gint char_len, i; - guint n_chars; - - n_chars = clutter_text_buffer_get_length (buffer); - str = g_string_sized_new (clutter_text_buffer_get_bytes (buffer)); - invisible_char = priv->password_char; - - /* we need to convert the string built of invisible - * characters into UTF-8 for it to be fed to the Pango - * layout - */ - memset (buf, 0, sizeof (buf)); - char_len = g_unichar_to_utf8 (invisible_char, buf); - - if (priv->show_password_hint && priv->password_hint_visible) - { - char *last_char; - - for (i = 0; i < n_chars - 1; i++) - g_string_append_len (str, buf, char_len); - - last_char = g_utf8_offset_to_pointer (text, n_chars - 1); - g_string_append (str, last_char); - } - else - { - for (i = 0; i < n_chars; i++) - g_string_append_len (str, buf, char_len); - } - - return g_string_free (str, FALSE); - } -} - -static void -ensure_effective_pango_scale_attribute (ClutterText *self) -{ - float resource_scale; - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - - resource_scale = clutter_actor_get_resource_scale (CLUTTER_ACTOR (self)); - - if (priv->effective_attrs != NULL) - { - PangoAttrIterator *iter; - PangoAttribute *scale_attrib; - PangoAttrList *old_attributes; - - old_attributes = priv->effective_attrs; - priv->effective_attrs = pango_attr_list_copy (priv->effective_attrs); - pango_attr_list_unref (old_attributes); - - iter = pango_attr_list_get_iterator (priv->effective_attrs); - scale_attrib = pango_attr_iterator_get (iter, PANGO_ATTR_SCALE); - - if (scale_attrib != NULL) - resource_scale *= ((PangoAttrFloat *) scale_attrib)->value; - - pango_attr_iterator_destroy (iter); - } - else - priv->effective_attrs = pango_attr_list_new (); - - pango_attr_list_change (priv->effective_attrs, - pango_attr_scale_new (resource_scale)); -} - -static void -set_effective_pango_attributes (ClutterText *self, - PangoAttrList *attributes) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - - if (attributes != NULL) - { - PangoAttrList *old_attributes = priv->effective_attrs; - priv->effective_attrs = pango_attr_list_ref (attributes); - - if (old_attributes != NULL) - pango_attr_list_unref (old_attributes); - } - else - { - g_clear_pointer (&priv->effective_attrs, pango_attr_list_unref); - } - - ensure_effective_pango_scale_attribute (self); -} - -static inline void -clutter_text_ensure_effective_attributes (ClutterText *self) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - - /* If we already have the effective attributes then we don't need to - do anything */ - if (priv->effective_attrs != NULL) - return; - - /* Same as if we don't have any attribute at all. - * We also ignore markup attributes for editable. */ - if (priv->attrs == NULL && (priv->editable || priv->markup_attrs == NULL)) - { - set_effective_pango_attributes (self, NULL); - return; - } - - if (priv->attrs != NULL) - { - /* If there are no markup attributes, or if this is editable (in which - * case we ignore markup), then we can just use these attrs directly */ - if (priv->editable || priv->markup_attrs == NULL) - set_effective_pango_attributes (self, priv->attrs); - else - { - /* Otherwise we need to merge the two lists */ - PangoAttrList *effective_attrs; - PangoAttrIterator *iter; - GSList *attributes, *l; - - effective_attrs = pango_attr_list_copy (priv->markup_attrs); - - iter = pango_attr_list_get_iterator (priv->attrs); - do - { - attributes = pango_attr_iterator_get_attrs (iter); - - for (l = attributes; l != NULL; l = l->next) - { - PangoAttribute *attr = l->data; - - pango_attr_list_insert (effective_attrs, attr); - } - - g_slist_free (attributes); - } - while (pango_attr_iterator_next (iter)); - - pango_attr_iterator_destroy (iter); - - set_effective_pango_attributes (self, effective_attrs); - pango_attr_list_unref (effective_attrs); - } - } - else if (priv->markup_attrs != NULL) - { - set_effective_pango_attributes (self, priv->markup_attrs); - } -} - -static PangoLayout * -clutter_text_create_layout_no_cache (ClutterText *text, - gint width, - gint height, - PangoEllipsizeMode ellipsize) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (text); - PangoLayout *layout; - gchar *contents; - gsize contents_len; - - layout = clutter_actor_create_pango_layout (CLUTTER_ACTOR (text), NULL); - pango_layout_set_font_description (layout, priv->font_desc); - - contents = clutter_text_get_display_text (text); - contents_len = strlen (contents); - - if (priv->editable && priv->preedit_set) - { - GString *tmp = g_string_new (contents); - PangoAttrList *tmp_attrs = pango_attr_list_new (); - gint cursor_index; - - if (priv->position == 0) - cursor_index = 0; - else - cursor_index = offset_to_bytes (contents, priv->position); - - g_string_insert (tmp, cursor_index, priv->preedit_str); - - pango_layout_set_text (layout, tmp->str, tmp->len); - - if (priv->preedit_attrs != NULL) - { - pango_attr_list_splice (tmp_attrs, priv->preedit_attrs, - cursor_index, - strlen (priv->preedit_str)); - - pango_layout_set_attributes (layout, tmp_attrs); - } - - g_string_free (tmp, TRUE); - pango_attr_list_unref (tmp_attrs); - } - else - { - ClutterTextDirection dir; - PangoDirection pango_dir; - PangoContext *context; - - if (priv->password_char != 0) - dir = CLUTTER_TEXT_DIRECTION_DEFAULT; - else - dir = _clutter_find_base_dir (contents, contents_len); - - if (dir == CLUTTER_TEXT_DIRECTION_DEFAULT) - { - ClutterBackend *backend = clutter_get_default_backend (); - - if (clutter_actor_has_key_focus (CLUTTER_ACTOR (text))) - { - ClutterSeat *seat; - ClutterKeymap *keymap; - - seat = clutter_backend_get_default_seat (backend); - keymap = clutter_seat_get_keymap (seat); - dir = clutter_keymap_get_direction (keymap); - } - else - { - dir = clutter_actor_get_text_direction (CLUTTER_ACTOR (text)); - } - } - - pango_dir = clutter_text_direction_to_pango_direction (dir); - context = clutter_actor_get_pango_context (CLUTTER_ACTOR (text)); - - pango_context_set_base_dir (context, pango_dir); - - priv->resolved_direction = dir; - - pango_layout_set_text (layout, contents, contents_len); - } - - /* This will merge the markup attributes and the attributes - * property if needed */ - clutter_text_ensure_effective_attributes (text); - - if (priv->effective_attrs != NULL) - pango_layout_set_attributes (layout, priv->effective_attrs); - - pango_layout_set_alignment (layout, priv->alignment); - pango_layout_set_single_paragraph_mode (layout, priv->single_line_mode); - pango_layout_set_justify (layout, priv->justify); - pango_layout_set_wrap (layout, priv->wrap_mode); - - pango_layout_set_ellipsize (layout, ellipsize); - pango_layout_set_width (layout, width); - pango_layout_set_height (layout, height); - - g_free (contents); - - return layout; -} - -static void -clutter_text_dirty_cache (ClutterText *text) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (text); - int i; - - /* Delete the cached layouts so they will be recreated the next time - they are needed */ - for (i = 0; i < N_CACHED_LAYOUTS; i++) - if (priv->cached_layouts[i].layout) - { - g_object_unref (priv->cached_layouts[i].layout); - priv->cached_layouts[i].layout = NULL; - } - - clutter_actor_invalidate_paint_volume (CLUTTER_ACTOR (text)); -} - -/* - * clutter_text_set_font_description_internal: - * @self: a #ClutterText - * @desc: a #PangoFontDescription - * - * Sets @desc as the font description to be used by the #ClutterText - * actor. The #PangoFontDescription is copied. - * - * This function will also set the :font-name field as a side-effect - * - * This function will evict the layout cache, and queue a relayout if - * the #ClutterText actor has contents. - */ -static inline void -clutter_text_set_font_description_internal (ClutterText *self, - PangoFontDescription *desc, - gboolean is_default_font) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - - priv->is_default_font = is_default_font; - - if (priv->font_desc == desc || - pango_font_description_equal (priv->font_desc, desc)) - return; - - if (priv->font_desc != NULL) - pango_font_description_free (priv->font_desc); - - priv->font_desc = pango_font_description_copy (desc); - - /* update the font name string we use */ - g_free (priv->font_name); - priv->font_name = pango_font_description_to_string (priv->font_desc); - - clutter_text_dirty_cache (self); - - if (clutter_text_buffer_get_length (get_buffer (self)) != 0) - clutter_actor_queue_relayout (CLUTTER_ACTOR (self)); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_FONT_DESCRIPTION]); -} - -static void -clutter_text_settings_changed_cb (ClutterText *text) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (text); - guint password_hint_time = 0; - ClutterSettings *settings; - - settings = clutter_settings_get_default (); - - g_object_get (settings, "password-hint-time", &password_hint_time, NULL); - - priv->show_password_hint = password_hint_time > 0; - priv->password_hint_timeout = password_hint_time; - - if (priv->is_default_font) - { - PangoFontDescription *font_desc; - gchar *font_name = NULL; - - g_object_get (settings, "font-name", &font_name, NULL); - - CLUTTER_NOTE (ACTOR, "Text[%p]: default font changed to '%s'", - text, - font_name); - - font_desc = pango_font_description_from_string (font_name); - clutter_text_set_font_description_internal (text, font_desc, TRUE); - - pango_font_description_free (font_desc); - g_free (font_name); - } - - clutter_text_dirty_cache (text); - clutter_actor_queue_relayout (CLUTTER_ACTOR (text)); -} - -static void -clutter_text_direction_changed_cb (GObject *gobject, - GParamSpec *pspec) -{ - clutter_text_dirty_cache (CLUTTER_TEXT (gobject)); - - /* no need to queue a relayout: set_text_direction() will do that for us */ -} - -/* - * clutter_text_create_layout: - * @text: a #ClutterText - * @allocation_width: the allocation width - * @allocation_height: the allocation height - * - * Like clutter_text_create_layout_no_cache(), but will also ensure - * the glyphs cache. If a previously cached layout generated using the - * same width is available then that will be used instead of - * generating a new one. - */ -static PangoLayout * -clutter_text_create_layout (ClutterText *text, - gfloat allocation_width, - gfloat allocation_height) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (text); - LayoutCache *oldest_cache = priv->cached_layouts; - gboolean found_free_cache = FALSE; - gint width = -1; - gint height = -1; - PangoEllipsizeMode ellipsize = PANGO_ELLIPSIZE_NONE; - int i; - - /* First determine the width, height, and ellipsize mode that - * we need for the layout. The ellipsize mode depends on - * allocation_width/allocation_size as follows: - * - * Cases, assuming ellipsize != NONE on actor: - * - * Width request: ellipsization can be set or not on layout, - * doesn't matter. - * - * Height request: ellipsization must never be set on layout - * if wrap=true, because we need to measure the wrapped - * height. It must always be set if wrap=false. - * - * Allocate: ellipsization must always be set. - * - * See http://bugzilla.gnome.org/show_bug.cgi?id=560931 - */ - - if (priv->ellipsize != PANGO_ELLIPSIZE_NONE) - { - if (allocation_height < 0 && priv->wrap) - ; /* must not set ellipsization on wrap=true height request */ - else - { - if (!priv->editable) - ellipsize = priv->ellipsize; - } - } - - /* When painting, we always need to set the width, since - * we might need to align to the right. When getting the - * height, however, there are some cases where we know that - * the width won't affect the width. - * - * - editable, single-line text actors, since those can - * scroll the layout. - * - non-wrapping, non-ellipsizing actors. - */ - if (allocation_width >= 0 && - (allocation_height >= 0 || - !((priv->editable && priv->single_line_mode) || - (priv->ellipsize == PANGO_ELLIPSIZE_NONE && !priv->wrap)))) - { - width = pixels_to_pango (allocation_width); - } - - /* Pango only uses height if ellipsization is enabled, so don't set - * height if ellipsize isn't set. Pango implicitly enables wrapping - * if height is set, so don't set height if wrapping is disabled. - * In other words, only set height if we want to both wrap then - * ellipsize and we're not in single line mode. - * - * See http://bugzilla.gnome.org/show_bug.cgi?id=560931 if this - * seems odd. - */ - if (allocation_height >= 0 && - priv->wrap && - priv->ellipsize != PANGO_ELLIPSIZE_NONE && - !priv->single_line_mode) - { - height = pixels_to_pango (allocation_height); - } - - /* Search for a cached layout with the same width and keep - * track of the oldest one - */ - for (i = 0; i < N_CACHED_LAYOUTS; i++) - { - if (priv->cached_layouts[i].layout == NULL) - { - /* Always prefer free cache spaces */ - found_free_cache = TRUE; - oldest_cache = priv->cached_layouts + i; - } - else - { - PangoLayout *cached = priv->cached_layouts[i].layout; - gint cached_width = pango_layout_get_width (cached); - gint cached_height = pango_layout_get_height (cached); - gint cached_ellipsize = pango_layout_get_ellipsize (cached); - - if (cached_width == width && - cached_height == height && - cached_ellipsize == ellipsize) - { - /* If this cached layout is using the same size then we can - * just return that directly - */ - CLUTTER_NOTE (ACTOR, - "ClutterText: %p: cache hit for size %.2fx%.2f", - text, - allocation_width, - allocation_height); - - return priv->cached_layouts[i].layout; - } - - /* When getting the preferred height for a specific width, - * we might be able to reuse the layout from getting the - * preferred width. If the width that the layout gives - * unconstrained is less than the width that we are using - * than the height will be unaffected by that width. - */ - if (allocation_height < 0 && - cached_width == -1 && - cached_ellipsize == ellipsize) - { - PangoRectangle logical_rect; - - pango_layout_get_extents (priv->cached_layouts[i].layout, - NULL, - &logical_rect); - - if (logical_rect.width <= width) - { - /* We've been asked for our height for the width we gave as a result - * of a _get_preferred_width call - */ - CLUTTER_NOTE (ACTOR, - "ClutterText: %p: cache hit for size %.2fx%.2f " - "(unwrapped width narrower than given width)", - text, - allocation_width, - allocation_height); - - return priv->cached_layouts[i].layout; - } - } - - if (!found_free_cache && - (priv->cached_layouts[i].age < oldest_cache->age)) - { - oldest_cache = priv->cached_layouts + i; - } - } - } - - CLUTTER_NOTE (ACTOR, "ClutterText: %p: cache miss for size %.2fx%.2f", - text, - allocation_width, - allocation_height); - - /* If we make it here then we didn't have a cached version so we - need to recreate the layout */ - if (oldest_cache->layout) - g_object_unref (oldest_cache->layout); - - oldest_cache->layout = - clutter_text_create_layout_no_cache (text, width, height, ellipsize); - - cogl_pango_ensure_glyph_cache_for_layout (oldest_cache->layout); - - /* Mark the 'time' this cache was created and advance the time */ - oldest_cache->age = priv->cache_age++; - return oldest_cache->layout; -} - -static PangoLayout * -create_text_layout_with_scale (ClutterText *text, - gfloat allocation_width, - gfloat allocation_height, - gfloat scale) -{ - if (allocation_width > 0) - allocation_width = roundf (allocation_width * scale); - - if (allocation_height > 0) - allocation_height = roundf (allocation_height * scale); - - return clutter_text_create_layout (text, allocation_width, allocation_height); -} - -static PangoLayout * -maybe_create_text_layout_with_resource_scale (ClutterText *text, - gfloat allocation_width, - gfloat allocation_height) -{ - float resource_scale; - - resource_scale = clutter_actor_get_resource_scale (CLUTTER_ACTOR (text)); - - return create_text_layout_with_scale (text, - allocation_width, - allocation_height, - resource_scale); -} - -/** - * clutter_text_coords_to_position: - * @self: a #ClutterText - * @x: the X coordinate, relative to the actor - * @y: the Y coordinate, relative to the actor - * - * Retrieves the position of the character at the given coordinates. - * - * Return: the position of the character - */ -gint -clutter_text_coords_to_position (ClutterText *self, - gfloat x, - gfloat y) -{ - gint index_; - gint px, py; - gint trailing; - gfloat resource_scale; - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), 0); - - priv = clutter_text_get_instance_private (self); - resource_scale = clutter_actor_get_resource_scale (CLUTTER_ACTOR (self)); - - /* Take any offset due to scrolling into account, and normalize - * the coordinates to PangoScale units - */ - px = logical_pixels_to_pango (x - priv->text_logical_x, resource_scale); - py = logical_pixels_to_pango (y - priv->text_logical_y, resource_scale); - - pango_layout_xy_to_index (clutter_text_get_layout (self), - px, py, - &index_, &trailing); - - return index_ + trailing; -} - -static gboolean -clutter_text_position_to_coords_internal (ClutterText *self, - gint position, - gfloat *x, - gfloat *y, - gfloat *line_height) -{ - ClutterTextPrivate *priv; - PangoRectangle rect; - gint n_chars; - gint password_char_bytes = 1; - gint index_; - gsize n_bytes; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), FALSE); - - priv = clutter_text_get_instance_private (self); - - n_chars = clutter_text_buffer_get_length (get_buffer (self)); - if (priv->preedit_set) - n_chars += priv->preedit_n_chars; - - if (position < -1 || position > n_chars) - return FALSE; - - if (priv->password_char != 0) - password_char_bytes = g_unichar_to_utf8 (priv->password_char, NULL); - - if (position == -1) - { - if (priv->password_char == 0) - { - n_bytes = clutter_text_buffer_get_bytes (get_buffer (self)); - if (priv->editable && priv->preedit_set) - index_ = n_bytes + strlen (priv->preedit_str); - else - index_ = n_bytes; - } - else - index_ = n_chars * password_char_bytes; - } - else if (position == 0) - { - index_ = 0; - } - else - { - gchar *text = clutter_text_get_display_text (self); - GString *tmp = g_string_new (text); - gint cursor_index; - - cursor_index = offset_to_bytes (text, priv->position); - - if (priv->preedit_str != NULL) - g_string_insert (tmp, cursor_index, priv->preedit_str); - - if (priv->password_char == 0) - index_ = offset_to_bytes (tmp->str, position); - else - index_ = position * password_char_bytes; - - g_free (text); - g_string_free (tmp, TRUE); - } - - pango_layout_get_cursor_pos (clutter_text_get_layout (self), - index_, - &rect, NULL); - - if (x) - { - *x = pango_to_pixels (rect.x); - - /* Take any offset due to scrolling into account */ - if (priv->single_line_mode) - *x += priv->text_x; - } - - if (y) - *y = pango_to_pixels (rect.y); - - if (line_height) - *line_height = pango_to_pixels (rect.height); - - return TRUE; -} - -/** - * clutter_text_position_to_coords: - * @self: a #ClutterText - * @position: position in characters - * @x: (out): return location for the X coordinate, or %NULL - * @y: (out): return location for the Y coordinate, or %NULL - * @line_height: (out): return location for the line height, or %NULL - * - * Retrieves the coordinates of the given @position. - * - * Return value: %TRUE if the conversion was successful - */ -gboolean -clutter_text_position_to_coords (ClutterText *self, - gint position, - gfloat *x, - gfloat *y, - gfloat *line_height) -{ - gfloat resource_scale; - gboolean ret; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), FALSE); - - resource_scale = clutter_actor_get_resource_scale (CLUTTER_ACTOR (self)); - - ret = clutter_text_position_to_coords_internal (self, position, - x, y, line_height); - - if (x) - *x /= resource_scale; - - if (y) - *y /= resource_scale; - - if (line_height) - *line_height /= resource_scale; - - return ret; -} - -static inline void -update_cursor_location (ClutterText *self) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - graphene_rect_t rect; - float x, y; - - if (!priv->editable) - return; - - clutter_text_get_cursor_rect (self, &rect); - clutter_actor_get_transformed_position (CLUTTER_ACTOR (self), &x, &y); - graphene_rect_offset (&rect, x, y); - clutter_input_focus_set_cursor_location (priv->input_focus, &rect); - clutter_text_input_focus_request_surrounding (priv->input_focus); -} - -static inline void -clutter_text_ensure_cursor_position (ClutterText *self, - float scale) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - gfloat x, y, cursor_height; - graphene_rect_t cursor_rect = GRAPHENE_RECT_INIT_ZERO; - gint position; - - position = priv->position; - - if (priv->editable && priv->preedit_set) - { - if (position == -1) - position = clutter_text_buffer_get_length (get_buffer (self)); - - position += priv->preedit_cursor_pos; - } - - CLUTTER_NOTE (MISC, "Cursor at %d (preedit %s at pos: %d)", - position, - priv->preedit_set ? "set" : "unset", - priv->preedit_set ? priv->preedit_cursor_pos : 0); - - x = y = cursor_height = 0; - clutter_text_position_to_coords_internal (self, position, - &x, &y, - &cursor_height); - - graphene_rect_init (&cursor_rect, - x, - y + CURSOR_Y_PADDING * scale, - priv->cursor_size * scale, - cursor_height - 2 * CURSOR_Y_PADDING * scale); - - if (!graphene_rect_equal (&priv->cursor_rect, &cursor_rect)) - { - priv->cursor_rect = cursor_rect; - - g_signal_emit (self, text_signals[CURSOR_CHANGED], 0); - - update_cursor_location (self); - } -} - -/** - * clutter_text_delete_selection: - * @self: a #ClutterText - * - * Deletes the currently selected text - * - * This function is only useful in subclasses of #ClutterText - * - * Return value: %TRUE if text was deleted or if the text actor - * is empty, and %FALSE otherwise - */ -gboolean -clutter_text_delete_selection (ClutterText *self) -{ - ClutterTextPrivate *priv; - gint start_index; - gint end_index; - gint old_position, old_selection; - guint n_chars; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), FALSE); - - priv = clutter_text_get_instance_private (self); - - n_chars = clutter_text_buffer_get_length (get_buffer (self)); - if (n_chars == 0) - return TRUE; - - start_index = priv->position == -1 ? n_chars : priv->position; - end_index = priv->selection_bound == -1 ? n_chars : priv->selection_bound; - - if (end_index == start_index) - return FALSE; - - if (end_index < start_index) - { - gint temp = start_index; - start_index = end_index; - end_index = temp; - } - - old_position = priv->position; - old_selection = priv->selection_bound; - - clutter_text_delete_text (self, start_index, end_index); - - priv->position = start_index; - priv->selection_bound = start_index; - - /* Not required to be guarded by g_object_freeze/thaw_notify */ - if (priv->position != old_position) - { - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CURSOR_POSITION]); - g_signal_emit (self, text_signals[CURSOR_CHANGED], 0); - } - - if (priv->selection_bound != old_selection) - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SELECTION_BOUND]); - - return TRUE; -} - -/* - * Utility function to update both cursor position and selection bound - * at once - */ -static inline void -clutter_text_set_positions (ClutterText *self, - gint new_pos, - gint new_bound) -{ - g_object_freeze_notify (G_OBJECT (self)); - clutter_text_set_cursor_position (self, new_pos); - clutter_text_set_selection_bound (self, new_bound); - g_object_thaw_notify (G_OBJECT (self)); -} - -static inline void -clutter_text_set_markup_internal (ClutterText *self, - const gchar *str) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - GError *error; - gchar *text = NULL; - PangoAttrList *attrs = NULL; - gboolean res; - - g_assert (str != NULL); - - error = NULL; - res = pango_parse_markup (str, -1, 0, - &attrs, - &text, - NULL, - &error); - - if (!res) - { - if (G_LIKELY (error != NULL)) - { - g_warning ("Failed to set the markup of the actor '%s': %s", - _clutter_actor_get_debug_name (CLUTTER_ACTOR (self)), - error->message); - g_error_free (error); - } - else - g_warning ("Failed to set the markup of the actor '%s'", - _clutter_actor_get_debug_name (CLUTTER_ACTOR (self))); - - return; - } - - if (text) - { - clutter_text_buffer_set_text (get_buffer (self), text, -1); - g_free (text); - } - - /* Store the new markup attributes */ - if (priv->markup_attrs != NULL) - pango_attr_list_unref (priv->markup_attrs); - - priv->markup_attrs = attrs; - - /* Clear the effective attributes so they will be regenerated when a - layout is created */ - if (priv->effective_attrs != NULL) - { - pango_attr_list_unref (priv->effective_attrs); - priv->effective_attrs = NULL; - } -} - -static void -clutter_text_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterText *self = CLUTTER_TEXT (gobject); - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - - switch (prop_id) - { - case PROP_BUFFER: - clutter_text_set_buffer (self, g_value_get_object (value)); - break; - - case PROP_TEXT: - { - const char *str = g_value_get_string (value); - if (priv->use_markup) - clutter_text_set_markup_internal (self, str ? str : ""); - else - clutter_text_buffer_set_text (get_buffer (self), str ? str : "", -1); - } - break; - - case PROP_COLOR: - clutter_text_set_color (self, clutter_value_get_color (value)); - break; - - case PROP_FONT_NAME: - clutter_text_set_font_name (self, g_value_get_string (value)); - break; - - case PROP_FONT_DESCRIPTION: - clutter_text_set_font_description (self, g_value_get_boxed (value)); - break; - - case PROP_USE_MARKUP: - clutter_text_set_use_markup (self, g_value_get_boolean (value)); - break; - - case PROP_ATTRIBUTES: - clutter_text_set_attributes (self, g_value_get_boxed (value)); - break; - - case PROP_LINE_ALIGNMENT: - clutter_text_set_line_alignment (self, g_value_get_enum (value)); - break; - - case PROP_LINE_WRAP: - clutter_text_set_line_wrap (self, g_value_get_boolean (value)); - break; - - case PROP_LINE_WRAP_MODE: - clutter_text_set_line_wrap_mode (self, g_value_get_enum (value)); - break; - - case PROP_JUSTIFY: - clutter_text_set_justify (self, g_value_get_boolean (value)); - break; - - case PROP_ELLIPSIZE: - clutter_text_set_ellipsize (self, g_value_get_enum (value)); - break; - - case PROP_CURSOR_POSITION: - clutter_text_set_cursor_position (self, g_value_get_int (value)); - break; - - case PROP_SELECTION_BOUND: - clutter_text_set_selection_bound (self, g_value_get_int (value)); - break; - - case PROP_SELECTION_COLOR: - clutter_text_set_selection_color (self, g_value_get_boxed (value)); - break; - - case PROP_CURSOR_VISIBLE: - clutter_text_set_cursor_visible (self, g_value_get_boolean (value)); - break; - - case PROP_CURSOR_COLOR: - clutter_text_set_cursor_color (self, g_value_get_boxed (value)); - break; - - case PROP_CURSOR_SIZE: - clutter_text_set_cursor_size (self, g_value_get_int (value)); - break; - - case PROP_EDITABLE: - clutter_text_set_editable (self, g_value_get_boolean (value)); - break; - - case PROP_ACTIVATABLE: - clutter_text_set_activatable (self, g_value_get_boolean (value)); - break; - - case PROP_SELECTABLE: - clutter_text_set_selectable (self, g_value_get_boolean (value)); - break; - - case PROP_PASSWORD_CHAR: - clutter_text_set_password_char (self, g_value_get_uint (value)); - break; - - case PROP_MAX_LENGTH: - clutter_text_set_max_length (self, g_value_get_int (value)); - break; - - case PROP_SINGLE_LINE_MODE: - clutter_text_set_single_line_mode (self, g_value_get_boolean (value)); - break; - - case PROP_SELECTED_TEXT_COLOR: - clutter_text_set_selected_text_color (self, clutter_value_get_color (value)); - break; - - case PROP_INPUT_PURPOSE: - clutter_text_set_input_purpose (self, g_value_get_enum (value)); - break; - - case PROP_INPUT_HINTS: - clutter_text_set_input_hints (self, g_value_get_enum (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - } -} - -static void -clutter_text_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterText *self = CLUTTER_TEXT (gobject); - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - - switch (prop_id) - { - case PROP_BUFFER: - g_value_set_object (value, clutter_text_get_buffer (self)); - break; - - case PROP_TEXT: - g_value_set_string (value, clutter_text_buffer_get_text (get_buffer (self))); - break; - - case PROP_FONT_NAME: - g_value_set_string (value, priv->font_name); - break; - - case PROP_FONT_DESCRIPTION: - g_value_set_boxed (value, priv->font_desc); - break; - - case PROP_USE_MARKUP: - g_value_set_boolean (value, priv->use_markup); - break; - - case PROP_COLOR: - clutter_value_set_color (value, &priv->text_color); - break; - - case PROP_CURSOR_VISIBLE: - g_value_set_boolean (value, priv->cursor_visible); - break; - - case PROP_CURSOR_COLOR: - clutter_value_set_color (value, &priv->cursor_color); - break; - - case PROP_CURSOR_COLOR_SET: - g_value_set_boolean (value, priv->cursor_color_set); - break; - - case PROP_CURSOR_SIZE: - g_value_set_int (value, priv->cursor_size); - break; - - case PROP_CURSOR_POSITION: - g_value_set_int (value, priv->position); - break; - - case PROP_SELECTION_BOUND: - g_value_set_int (value, priv->selection_bound); - break; - - case PROP_EDITABLE: - g_value_set_boolean (value, priv->editable); - break; - - case PROP_SELECTABLE: - g_value_set_boolean (value, priv->selectable); - break; - - case PROP_SELECTION_COLOR: - clutter_value_set_color (value, &priv->selection_color); - break; - - case PROP_SELECTION_COLOR_SET: - g_value_set_boolean (value, priv->selection_color_set); - break; - - case PROP_ACTIVATABLE: - g_value_set_boolean (value, priv->activatable); - break; - - case PROP_PASSWORD_CHAR: - g_value_set_uint (value, priv->password_char); - break; - - case PROP_MAX_LENGTH: - g_value_set_int (value, clutter_text_buffer_get_max_length (get_buffer (self))); - break; - - case PROP_SINGLE_LINE_MODE: - g_value_set_boolean (value, priv->single_line_mode); - break; - - case PROP_ELLIPSIZE: - g_value_set_enum (value, priv->ellipsize); - break; - - case PROP_LINE_WRAP: - g_value_set_boolean (value, priv->wrap); - break; - - case PROP_LINE_WRAP_MODE: - g_value_set_enum (value, priv->wrap_mode); - break; - - case PROP_LINE_ALIGNMENT: - g_value_set_enum (value, priv->alignment); - break; - - case PROP_JUSTIFY: - g_value_set_boolean (value, priv->justify); - break; - - case PROP_ATTRIBUTES: - g_value_set_boxed (value, priv->attrs); - break; - - case PROP_SELECTED_TEXT_COLOR: - clutter_value_set_color (value, &priv->selected_text_color); - break; - - case PROP_SELECTED_TEXT_COLOR_SET: - g_value_set_boolean (value, priv->selected_text_color_set); - break; - - case PROP_INPUT_PURPOSE: - g_value_set_enum (value, priv->input_purpose); - break; - - case PROP_INPUT_HINTS: - g_value_set_enum (value, priv->input_hints); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - } -} - -static void -clutter_text_dispose (GObject *gobject) -{ - ClutterText *self = CLUTTER_TEXT (gobject); - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - - /* get rid of the entire cache */ - clutter_text_dirty_cache (self); - - g_clear_signal_handler (&priv->direction_changed_id, self); - g_clear_signal_handler (&priv->settings_changed_id, - clutter_get_default_backend ()); - - g_clear_handle_id (&priv->password_hint_id, g_source_remove); - - clutter_text_set_buffer (self, NULL); - - G_OBJECT_CLASS (clutter_text_parent_class)->dispose (gobject); -} - -static void -clutter_text_finalize (GObject *gobject) -{ - ClutterText *self = CLUTTER_TEXT (gobject); - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - - if (priv->font_desc) - pango_font_description_free (priv->font_desc); - - if (priv->attrs) - pango_attr_list_unref (priv->attrs); - if (priv->markup_attrs) - pango_attr_list_unref (priv->markup_attrs); - if (priv->effective_attrs) - pango_attr_list_unref (priv->effective_attrs); - if (priv->preedit_attrs) - pango_attr_list_unref (priv->preedit_attrs); - - g_free (priv->font_name); - - g_clear_object (&priv->input_focus); - - G_OBJECT_CLASS (clutter_text_parent_class)->finalize (gobject); -} - -typedef void (* ClutterTextSelectionFunc) (ClutterText *text, - const ClutterActorBox *box, - gpointer user_data); - -static void -clutter_text_foreach_selection_rectangle (ClutterText *self, - float scale, - ClutterTextSelectionFunc func, - gpointer user_data) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - PangoLayout *layout = clutter_text_get_layout (self); - gchar *utf8 = clutter_text_get_display_text (self); - gint lines; - gint start_index; - gint end_index; - gint line_no; - - if (priv->position == 0) - start_index = 0; - else - start_index = offset_to_bytes (utf8, priv->position); - - if (priv->selection_bound == 0) - end_index = 0; - else - end_index = offset_to_bytes (utf8, priv->selection_bound); - - if (start_index > end_index) - { - gint temp = start_index; - start_index = end_index; - end_index = temp; - } - - lines = pango_layout_get_line_count (layout); - - for (line_no = 0; line_no < lines; line_no++) - { - PangoLayoutLine *line; - gint n_ranges; - gint *ranges; - gint i; - gint index_; - gint maxindex; - ClutterActorBox box; - gfloat y, height; - - line = pango_layout_get_line_readonly (layout, line_no); - pango_layout_line_x_to_index (line, G_MAXINT, &maxindex, NULL); - if (maxindex < start_index) - continue; - - pango_layout_line_get_x_ranges (line, start_index, end_index, - &ranges, - &n_ranges); - pango_layout_line_x_to_index (line, 0, &index_, NULL); - - clutter_text_position_to_coords_internal (self, - bytes_to_offset (utf8, index_), - NULL, &y, &height); - - box.y1 = y; - box.y2 = y + height; - - for (i = 0; i < n_ranges; i++) - { - gfloat range_x; - gfloat range_width; - - range_x = pango_to_pixels (ranges[i * 2]); - - /* Account for any scrolling in single line mode */ - if (priv->single_line_mode) - range_x += priv->text_x; - - - range_width = pango_to_pixels (ranges[i * 2 + 1] - ranges[i * 2]); - box.x1 = range_x; - box.x2 = ceilf (range_x + range_width); - - clutter_actor_box_scale (&box, scale); - - func (self, &box, user_data); - } - - g_free (ranges); - } - - g_free (utf8); -} - -static CoglPipeline * -create_color_pipeline (void) -{ - static CoglPipelineKey color_pipeline_key = "clutter-text-color-pipeline-private"; - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - CoglPipeline *color_pipeline; - - color_pipeline = - cogl_context_get_named_pipeline (ctx, &color_pipeline_key); - - if (G_UNLIKELY (color_pipeline == NULL)) - { - color_pipeline = cogl_pipeline_new (ctx); - cogl_context_set_named_pipeline (ctx, - &color_pipeline_key, - color_pipeline); - } - - return cogl_pipeline_copy (color_pipeline); -} - -static void -clutter_text_foreach_selection_rectangle_prescaled (ClutterText *self, - ClutterTextSelectionFunc func, - gpointer user_data) -{ - clutter_text_foreach_selection_rectangle (self, 1.0f, func, user_data); -} - -static void -paint_selection_rectangle (ClutterText *self, - const ClutterActorBox *box, - gpointer user_data) -{ - CoglFramebuffer *fb = user_data; - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - ClutterActor *actor = CLUTTER_ACTOR (self); - guint8 paint_opacity = clutter_actor_get_paint_opacity (actor); - CoglPipeline *color_pipeline = create_color_pipeline (); - PangoLayout *layout = clutter_text_get_layout (self); - CoglColor cogl_color = { 0, }; - const ClutterColor *color; - - /* Paint selection background */ - if (priv->selection_color_set) - color = &priv->selection_color; - else if (priv->cursor_color_set) - color = &priv->cursor_color; - else - color = &priv->text_color; - - cogl_color_init_from_4f (&cogl_color, - color->red / 255.0, - color->green / 255.0, - color->blue / 255.0, - paint_opacity / 255.0 * color->alpha / 255.0); - cogl_color_premultiply (&cogl_color); - cogl_pipeline_set_color (color_pipeline, &cogl_color); - - cogl_framebuffer_push_rectangle_clip (fb, - box->x1, box->y1, - box->x2, box->y2); - cogl_framebuffer_draw_rectangle (fb, color_pipeline, - box->x1, box->y1, - box->x2, box->y2); - - if (priv->selected_text_color_set) - color = &priv->selected_text_color; - else - color = &priv->text_color; - - cogl_color_init_from_4f (&cogl_color, - color->red / 255.0, - color->green / 255.0, - color->blue / 255.0, - paint_opacity / 255.0 * color->alpha / 255.0); - - cogl_pango_show_layout (fb, layout, priv->text_x, 0, &cogl_color); - - cogl_framebuffer_pop_clip (fb); - g_object_unref (color_pipeline); -} - -/* Draws the selected text, its background, and the cursor */ -static void -selection_paint (ClutterText *self, - CoglFramebuffer *fb) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - ClutterActor *actor = CLUTTER_ACTOR (self); - guint8 paint_opacity = clutter_actor_get_paint_opacity (actor); - const ClutterColor *color; - - if (!clutter_text_should_draw_cursor (self)) - return; - - if (priv->position == priv->selection_bound) - { - CoglPipeline *color_pipeline = create_color_pipeline (); - CoglColor cogl_color; - - /* No selection, just draw the cursor */ - if (priv->cursor_color_set) - color = &priv->cursor_color; - else - color = &priv->text_color; - - - cogl_color_init_from_4f (&cogl_color, - color->red / 255.0, - color->green / 255.0, - color->blue / 255.0, - paint_opacity / 255.0 * color->alpha / 255.0); - cogl_color_premultiply (&cogl_color); - cogl_pipeline_set_color (color_pipeline, &cogl_color); - - cogl_framebuffer_draw_rectangle (fb, - color_pipeline, - priv->cursor_rect.origin.x, - priv->cursor_rect.origin.y, - priv->cursor_rect.origin.x + priv->cursor_rect.size.width, - priv->cursor_rect.origin.y + priv->cursor_rect.size.height); - - g_clear_object (&color_pipeline); - } - else - { - clutter_text_foreach_selection_rectangle_prescaled (self, - paint_selection_rectangle, - fb); - } -} - -static gint -clutter_text_move_word_backward (ClutterText *self, - gint start) -{ - gint retval = start; - - if (clutter_text_buffer_get_length (get_buffer (self)) > 0 && start > 0) - { - PangoLayout *layout = clutter_text_get_layout (self); - PangoLogAttr *log_attrs = NULL; - gint n_attrs = 0; - - pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs); - - retval = start - 1; - while (retval > 0 && !log_attrs[retval].is_word_start) - retval -= 1; - - g_free (log_attrs); - } - - return retval; -} - -static gint -clutter_text_move_word_forward (ClutterText *self, - gint start) -{ - gint retval = start; - guint n_chars; - - n_chars = clutter_text_buffer_get_length (get_buffer (self)); - if (n_chars > 0 && start < n_chars) - { - PangoLayout *layout = clutter_text_get_layout (self); - PangoLogAttr *log_attrs = NULL; - gint n_attrs = 0; - - pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs); - - retval = start + 1; - while (retval < n_chars && !log_attrs[retval].is_word_end) - retval += 1; - - g_free (log_attrs); - } - - return retval; -} - -static gint -clutter_text_move_line_start (ClutterText *self, - gint start) -{ - PangoLayoutLine *layout_line; - PangoLayout *layout; - gint line_no; - gint index_; - gint position; - const gchar *text; - - layout = clutter_text_get_layout (self); - text = clutter_text_buffer_get_text (get_buffer (self)); - - if (start == 0) - index_ = 0; - else - index_ = offset_to_bytes (text, start); - - pango_layout_index_to_line_x (layout, index_, - 0, - &line_no, NULL); - - layout_line = pango_layout_get_line_readonly (layout, line_no); - if (!layout_line) - return FALSE; - - pango_layout_line_x_to_index (layout_line, 0, &index_, NULL); - - position = bytes_to_offset (text, index_); - - return position; -} - -static gint -clutter_text_move_line_end (ClutterText *self, - gint start) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - PangoLayoutLine *layout_line; - PangoLayout *layout; - gint line_no; - gint index_; - gint trailing; - gint position; - const gchar *text; - - layout = clutter_text_get_layout (self); - text = clutter_text_buffer_get_text (get_buffer (self)); - - if (start == 0) - index_ = 0; - else - index_ = offset_to_bytes (text, priv->position); - - pango_layout_index_to_line_x (layout, index_, - 0, - &line_no, NULL); - - layout_line = pango_layout_get_line_readonly (layout, line_no); - if (!layout_line) - return FALSE; - - pango_layout_line_x_to_index (layout_line, G_MAXINT, &index_, &trailing); - index_ += trailing; - - position = bytes_to_offset (text, index_); - - return position; -} - -static void -clutter_text_select_word (ClutterText *self) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - gint cursor_pos = priv->position; - gint start_pos, end_pos; - - start_pos = clutter_text_move_word_backward (self, cursor_pos); - end_pos = clutter_text_move_word_forward (self, cursor_pos); - - clutter_text_set_selection (self, start_pos, end_pos); -} - -static void -clutter_text_select_line (ClutterText *self) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - gint cursor_pos = priv->position; - gint start_pos, end_pos; - - if (priv->single_line_mode) - { - start_pos = 0; - end_pos = -1; - } - else - { - start_pos = clutter_text_move_line_start (self, cursor_pos); - end_pos = clutter_text_move_line_end (self, cursor_pos); - } - - clutter_text_set_selection (self, start_pos, end_pos); -} - -static int -clutter_text_update_click_count (ClutterText *self, - const ClutterEvent *event) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - ClutterSettings *settings; - int double_click_time, double_click_distance; - uint32_t evtime; - float x, y; - - settings = clutter_settings_get_default (); - clutter_event_get_coords (event, &x, &y); - evtime = clutter_event_get_time (event); - - g_object_get (settings, - "double-click-distance", &double_click_distance, - "double-click-time", &double_click_time, - NULL); - - if (evtime > (priv->last_click_time_ms + double_click_time) || - (ABS (x - priv->last_click_x) > double_click_distance) || - (ABS (y - priv->last_click_y) > double_click_distance)) - priv->click_count = 0; - - priv->last_click_time_ms = evtime; - priv->last_click_x = x; - priv->last_click_y = y; - - priv->click_count = (priv->click_count % 3) + 1; - - return priv->click_count; -} - -static gboolean -clutter_text_press (ClutterActor *actor, - ClutterEvent *event) -{ - ClutterText *self = CLUTTER_TEXT (actor); - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - ClutterEventType type = clutter_event_type (event); - gboolean res = FALSE; - gfloat x, y; - gint index_; - - /* if a ClutterText is just used for display purposes, then we - * should ignore the events we receive - */ - if (!(priv->editable || priv->selectable)) - return CLUTTER_EVENT_PROPAGATE; - - clutter_actor_grab_key_focus (actor); - clutter_input_focus_reset (priv->input_focus); - clutter_input_focus_set_input_panel_state (priv->input_focus, - CLUTTER_INPUT_PANEL_STATE_TOGGLE); - - if (clutter_input_focus_is_focused (priv->input_focus)) - clutter_input_focus_filter_event (priv->input_focus, event); - - /* if the actor is empty we just reset everything and not - * set up the dragging of the selection since there's nothing - * to select - */ - if (clutter_text_buffer_get_length (get_buffer (self)) == 0) - { - clutter_text_set_positions (self, -1, -1); - - return CLUTTER_EVENT_STOP; - } - - clutter_event_get_coords (event, &x, &y); - - res = clutter_actor_transform_stage_point (actor, x, y, &x, &y); - if (res) - { - const char *text; - int offset; - - index_ = clutter_text_coords_to_position (self, x, y); - text = clutter_text_buffer_get_text (get_buffer (self)); - offset = bytes_to_offset (text, index_); - - /* what we select depends on the number of button clicks we - * receive, and whether we are selectable: - * - * 1: just position the cursor and the selection - * 2: select the current word - * 3: select the contents of the whole actor - */ - if (type == CLUTTER_BUTTON_PRESS) - { - gint click_count; - - click_count = clutter_text_update_click_count (self, event); - - if (click_count == 1) - { - clutter_text_set_positions (self, offset, offset); - } - else if (priv->selectable && click_count == 2) - { - clutter_text_select_word (self); - } - else if (priv->selectable && click_count == 3) - { - clutter_text_select_line (self); - } - } - else - { - /* touch events do not have click count */ - clutter_text_set_positions (self, offset, offset); - } - } - - /* we don't need to go any further if we're not selectable */ - if (!priv->selectable) - return CLUTTER_EVENT_STOP; - - /* grab the pointer */ - priv->in_select_drag = TRUE; - - if (type != CLUTTER_BUTTON_PRESS) - priv->in_select_touch = TRUE; - - return CLUTTER_EVENT_STOP; -} - -static gboolean -clutter_text_move (ClutterActor *actor, - ClutterEvent *event) -{ - ClutterText *self = CLUTTER_TEXT (actor); - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - gfloat x, y; - gint index_, offset; - gboolean res; - const gchar *text; - - if (!priv->in_select_drag) - return CLUTTER_EVENT_PROPAGATE; - - clutter_event_get_coords (event, &x, &y); - - res = clutter_actor_transform_stage_point (actor, x, y, &x, &y); - if (!res) - return CLUTTER_EVENT_PROPAGATE; - - index_ = clutter_text_coords_to_position (self, x, y); - text = clutter_text_buffer_get_text (get_buffer (self)); - offset = bytes_to_offset (text, index_); - - if (priv->selectable) - clutter_text_set_cursor_position (self, offset); - else - clutter_text_set_positions (self, offset, offset); - - return CLUTTER_EVENT_STOP; -} - -static gboolean -clutter_text_release (ClutterActor *actor, - ClutterEvent *event) -{ - ClutterText *self = CLUTTER_TEXT (actor); - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - ClutterEventType type = clutter_event_type (event); - - if (priv->in_select_drag) - { - if (type == CLUTTER_BUTTON_RELEASE) - { - if (!priv->in_select_touch) - { - priv->in_select_drag = FALSE; - - return CLUTTER_EVENT_STOP; - } - } - else - { - if (priv->in_select_touch) - { - priv->in_select_touch = FALSE; - priv->in_select_drag = FALSE; - - return CLUTTER_EVENT_STOP; - } - } - } - - return CLUTTER_EVENT_PROPAGATE; -} - -static gboolean -clutter_text_button_press (ClutterActor *actor, - ClutterEvent *event) -{ - return clutter_text_press (actor, event); -} - -static gboolean -clutter_text_motion (ClutterActor *actor, - ClutterEvent *event) -{ - return clutter_text_move (actor, event); -} - -static gboolean -clutter_text_button_release (ClutterActor *actor, - ClutterEvent *event) -{ - return clutter_text_release (actor, event); -} - -static gboolean -clutter_text_touch_event (ClutterActor *actor, - ClutterEvent *event) -{ - switch (clutter_event_type (event)) - { - case CLUTTER_TOUCH_BEGIN: - return clutter_text_press (actor, event); - - case CLUTTER_TOUCH_END: - case CLUTTER_TOUCH_CANCEL: - /* TODO: the cancel case probably need a special handler */ - return clutter_text_release (actor, event); - - case CLUTTER_TOUCH_UPDATE: - return clutter_text_move (actor, event); - - default: - break; - } - - return CLUTTER_EVENT_PROPAGATE; -} - -static gboolean -clutter_text_remove_password_hint (gpointer data) -{ - ClutterText *self = data; - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - - priv->password_hint_visible = FALSE; - priv->password_hint_id = 0; - - clutter_text_dirty_cache (data); - clutter_actor_queue_redraw (data); // paint volume was already invalidated by clutter_text_dirty_cache() - - return G_SOURCE_REMOVE; -} - -static gboolean -clutter_text_key_press (ClutterActor *actor, - ClutterEvent *event) -{ - ClutterText *self = CLUTTER_TEXT (actor); - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - ClutterBindingPool *pool; - ClutterEventFlags flags; - ClutterModifierType modifiers; - uint32_t keyval; - gboolean res; - - if (!priv->editable) - return CLUTTER_EVENT_PROPAGATE; - - /* we need to use the ClutterText type name to find our own - * key bindings; subclasses will override or chain up this - * event handler, so they can do whatever they want there - */ - pool = clutter_binding_pool_find (g_type_name (CLUTTER_TYPE_TEXT)); - g_assert (pool != NULL); - - flags = clutter_event_get_flags (event); - keyval = clutter_event_get_key_symbol (event); - modifiers = clutter_event_get_state (event); - - if (!(flags & CLUTTER_EVENT_FLAG_INPUT_METHOD) && - clutter_input_focus_is_focused (priv->input_focus) && - clutter_input_focus_filter_event (priv->input_focus, event)) - return CLUTTER_EVENT_STOP; - - /* we allow passing synthetic events that only contain - * the Unicode value and not the key symbol, unless they - * contain the input method flag. - */ - if (keyval == 0 && (flags & CLUTTER_EVENT_FLAG_SYNTHETIC) && - !(flags & CLUTTER_EVENT_FLAG_INPUT_METHOD)) - res = FALSE; - else - res = clutter_binding_pool_activate (pool, keyval, - modifiers, - G_OBJECT (actor)); - - /* if the key binding has handled the event we bail out - * as fast as we can; otherwise, we try to insert the - * Unicode character inside the key event into the text - * actor - */ - if (res) - return CLUTTER_EVENT_STOP; - else if ((modifiers & CLUTTER_CONTROL_MASK) == 0) - { - gunichar key_unichar; - - /* Skip keys when control is pressed */ - key_unichar = clutter_event_get_key_unicode (event); - - /* return is reported as CR, but we want LF */ - if (key_unichar == '\r') - key_unichar = '\n'; - - if ((key_unichar == '\n' && !priv->single_line_mode) || - (g_unichar_validate (key_unichar) && - !g_unichar_iscntrl (key_unichar))) - { - /* truncate the eventual selection so that the - * Unicode character can replace it - */ - clutter_text_delete_selection (self); - clutter_text_insert_unichar (self, key_unichar); - - if (priv->show_password_hint) - { - g_clear_handle_id (&priv->password_hint_id, g_source_remove); - - priv->password_hint_visible = TRUE; - priv->password_hint_id = - clutter_threads_add_timeout (priv->password_hint_timeout, - clutter_text_remove_password_hint, - self); - } - - return CLUTTER_EVENT_STOP; - } - } - - return CLUTTER_EVENT_PROPAGATE; -} - -static gboolean -clutter_text_key_release (ClutterActor *actor, - ClutterEvent *event) -{ - ClutterText *self = CLUTTER_TEXT (actor); - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - - if (clutter_input_focus_is_focused (priv->input_focus) && - clutter_input_focus_filter_event (priv->input_focus, event)) - return CLUTTER_EVENT_STOP; - - return CLUTTER_EVENT_PROPAGATE; -} - -static void -clutter_text_compute_layout_offsets (ClutterText *self, - PangoLayout *layout, - const ClutterActorBox *alloc, - int *text_x, - int *text_y) -{ - ClutterActor *actor = CLUTTER_ACTOR (self); - ClutterActorAlign x_align, y_align; - PangoRectangle logical_rect; - float alloc_width, alloc_height; - float x, y; - - clutter_actor_box_get_size (alloc, &alloc_width, &alloc_height); - pango_layout_get_pixel_extents (layout, NULL, &logical_rect); - - if (clutter_actor_needs_expand (actor, CLUTTER_ORIENTATION_HORIZONTAL)) - x_align = _clutter_actor_get_effective_x_align (actor); - else - x_align = CLUTTER_ACTOR_ALIGN_FILL; - - if (clutter_actor_needs_expand (actor, CLUTTER_ORIENTATION_VERTICAL)) - y_align = clutter_actor_get_y_align (actor); - else - y_align = CLUTTER_ACTOR_ALIGN_FILL; - - x = 0.f; - switch (x_align) - { - case CLUTTER_ACTOR_ALIGN_FILL: - case CLUTTER_ACTOR_ALIGN_START: - break; - - case CLUTTER_ACTOR_ALIGN_END: - if (alloc_width > logical_rect.width) - x = alloc_width - logical_rect.width; - break; - - case CLUTTER_ACTOR_ALIGN_CENTER: - if (alloc_width > logical_rect.width) - x = (alloc_width - logical_rect.width) / 2.f; - break; - } - - y = 0.f; - switch (y_align) - { - case CLUTTER_ACTOR_ALIGN_FILL: - case CLUTTER_ACTOR_ALIGN_START: - break; - - case CLUTTER_ACTOR_ALIGN_END: - if (alloc_height > logical_rect.height) - y = alloc_height - logical_rect.height; - break; - - case CLUTTER_ACTOR_ALIGN_CENTER: - if (alloc_height > logical_rect.height) - y = (alloc_height - logical_rect.height) / 2.f; - break; - } - - if (text_x != NULL) - *text_x = floorf (x); - - if (text_y != NULL) - *text_y = floorf (y); -} - -#define TEXT_PADDING 2 - -static void -clutter_text_paint (ClutterActor *self, - ClutterPaintContext *paint_context) -{ - ClutterText *text = CLUTTER_TEXT (self); - ClutterTextPrivate *priv = clutter_text_get_instance_private (text); - CoglFramebuffer *fb; - PangoLayout *layout; - ClutterActorBox alloc = { 0, }; - CoglColor color = { 0, }; - guint8 real_opacity; - gint text_x = priv->text_x; - gint text_y = priv->text_y; - gboolean clip_set = FALSE; - guint n_chars; - float alloc_width; - float alloc_height; - float resource_scale; - - fb = clutter_paint_context_get_framebuffer (paint_context); - - /* Note that if anything in this paint method changes it needs to be - reflected in the get_paint_volume implementation which is tightly - tied to the workings of this function */ - n_chars = clutter_text_buffer_get_length (get_buffer (text)); - - clutter_actor_get_allocation_box (self, &alloc); - - /* don't bother painting an empty text actor, unless it's - * editable, in which case we want to paint at least the - * cursor - */ - if (n_chars == 0 && - !clutter_text_should_draw_cursor (text)) - return; - - resource_scale = clutter_actor_get_resource_scale (CLUTTER_ACTOR (self)); - - clutter_actor_box_scale (&alloc, resource_scale); - clutter_actor_box_get_size (&alloc, &alloc_width, &alloc_height); - - if (priv->editable && priv->single_line_mode) - layout = clutter_text_create_layout (text, -1, -1); - else - { - /* the only time when we create the PangoLayout using the full - * width and height of the allocation is when we can both wrap - * and ellipsize - */ - if (priv->wrap && priv->ellipsize) - { - layout = clutter_text_create_layout (text, alloc_width, alloc_height); - } - else - { - /* if we're not wrapping we cannot set the height of the - * layout, otherwise Pango will happily wrap the text to - * fit in the rectangle - thus making the :wrap property - * useless - * - * see bug: - * - * http://bugzilla.clutter-project.org/show_bug.cgi?id=2339 - * - * in order to fix this, we create a layout that would fit - * in the assigned width, then we clip the actor if the - * logical rectangle overflows the allocation. - */ - layout = clutter_text_create_layout (text, alloc_width, -1); - } - } - - if (resource_scale != 1.0f) - { - float paint_scale = 1.0f / resource_scale; - cogl_framebuffer_push_matrix (fb); - cogl_framebuffer_scale (fb, paint_scale, paint_scale, 1.0f); - } - - if (clutter_text_should_draw_cursor (text)) - clutter_text_ensure_cursor_position (text, resource_scale); - - if (priv->editable && priv->single_line_mode) - { - PangoRectangle logical_rect = { 0, }; - gint actor_width, text_width; - gboolean rtl; - - pango_layout_get_extents (layout, NULL, &logical_rect); - - cogl_framebuffer_push_rectangle_clip (fb, 0, 0, alloc_width, alloc_height); - clip_set = TRUE; - - actor_width = alloc_width - 2 * TEXT_PADDING; - text_width = pango_to_pixels (logical_rect.width); - - rtl = priv->resolved_direction == CLUTTER_TEXT_DIRECTION_RTL; - - if (actor_width < text_width) - { - gint cursor_x = graphene_rect_get_x (&priv->cursor_rect); - - if (priv->position == -1) - { - text_x = rtl ? TEXT_PADDING : actor_width - text_width; - } - else if (priv->position == 0) - { - text_x = rtl ? actor_width - text_width : TEXT_PADDING; - } - else - { - if (cursor_x < 0) - { - text_x = text_x - cursor_x - TEXT_PADDING; - } - else if (cursor_x > actor_width) - { - text_x = text_x + (actor_width - cursor_x) - TEXT_PADDING; - } - } - } - else - { - text_x = rtl ? actor_width - text_width : TEXT_PADDING; - } - } - else if (!priv->editable && !(priv->wrap && priv->ellipsize)) - { - PangoRectangle logical_rect = { 0, }; - - pango_layout_get_pixel_extents (layout, NULL, &logical_rect); - - /* don't clip if the layout managed to fit inside our allocation */ - if (logical_rect.width > alloc_width || - logical_rect.height > alloc_height) - { - cogl_framebuffer_push_rectangle_clip (fb, 0, 0, alloc_width, alloc_height); - clip_set = TRUE; - } - - clutter_text_compute_layout_offsets (text, layout, &alloc, &text_x, &text_y); - } - else - clutter_text_compute_layout_offsets (text, layout, &alloc, &text_x, &text_y); - - if (priv->text_x != text_x || - priv->text_y != text_y) - { - priv->text_x = text_x; - priv->text_y = text_y; - priv->text_logical_x = roundf ((float) text_x / resource_scale); - priv->text_logical_y = roundf ((float) text_y / resource_scale); - - clutter_text_ensure_cursor_position (text, resource_scale); - } - - real_opacity = clutter_actor_get_paint_opacity (self) - * priv->text_color.alpha - / 255; - - CLUTTER_NOTE (PAINT, "painting text (text: '%s')", - clutter_text_buffer_get_text (get_buffer (text))); - - cogl_color_init_from_4f (&color, - priv->text_color.red / 255.0, - priv->text_color.green / 255.0, - priv->text_color.blue / 255.0, - real_opacity / 255.0); - cogl_pango_show_layout (fb, layout, priv->text_x, priv->text_y, &color); - - selection_paint (text, fb); - - if (resource_scale != 1.0f) - cogl_framebuffer_pop_matrix (fb); - - if (clip_set) - cogl_framebuffer_pop_clip (fb); -} - -static void -add_selection_to_paint_volume (ClutterText *text, - const ClutterActorBox *box, - gpointer user_data) -{ - ClutterPaintVolume *total_volume = user_data; - ClutterPaintVolume rect_volume; - graphene_point3d_t vertex; - - _clutter_paint_volume_init_static (&rect_volume, CLUTTER_ACTOR (text)); - - vertex.x = box->x1; - vertex.y = box->y1; - vertex.z = 0.0f; - clutter_paint_volume_set_origin (&rect_volume, &vertex); - clutter_paint_volume_set_width (&rect_volume, box->x2 - box->x1); - clutter_paint_volume_set_height (&rect_volume, box->y2 - box->y1); - - clutter_paint_volume_union (total_volume, &rect_volume); - - clutter_paint_volume_free (&rect_volume); -} - -static void -clutter_text_get_paint_volume_for_cursor (ClutterText *text, - float resource_scale, - ClutterPaintVolume *volume) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (text); - graphene_point3d_t origin; - - clutter_text_ensure_cursor_position (text, resource_scale); - - if (priv->position == priv->selection_bound) - { - float width, height; - - width = priv->cursor_rect.size.width / resource_scale; - height = priv->cursor_rect.size.height / resource_scale; - origin.x = priv->cursor_rect.origin.x / resource_scale; - origin.y = priv->cursor_rect.origin.y / resource_scale; - origin.z = 0; - - clutter_paint_volume_set_origin (volume, &origin); - clutter_paint_volume_set_width (volume, width); - clutter_paint_volume_set_height (volume, height); - } - else - { - clutter_text_foreach_selection_rectangle (text, - 1.0f / resource_scale, - add_selection_to_paint_volume, - volume); - } -} - -static gboolean -clutter_text_get_paint_volume (ClutterActor *self, - ClutterPaintVolume *volume) -{ - ClutterText *text = CLUTTER_TEXT (self); - ClutterTextPrivate *priv = clutter_text_get_instance_private (text); - PangoLayout *layout; - PangoRectangle ink_rect; - graphene_point3d_t origin; - float resource_scale; - - /* ClutterText uses the logical layout as the natural size of the - actor. This means that it can sometimes paint outside of its - allocation for example with italic fonts with serifs. Therefore - we should use the ink rectangle of the layout instead */ - - /* If the text is single line editable then it gets clipped to - the allocation anyway so we can just use that */ - if (priv->editable && priv->single_line_mode) - return _clutter_actor_set_default_paint_volume (self, - CLUTTER_TYPE_TEXT, - volume); - - if (G_OBJECT_TYPE (self) != CLUTTER_TYPE_TEXT) - return FALSE; - - if (!clutter_actor_has_allocation (self)) - return FALSE; - - resource_scale = clutter_actor_get_resource_scale (self); - - _clutter_paint_volume_init_static (volume, self); - - layout = clutter_text_get_layout (text); - pango_layout_get_extents (layout, &ink_rect, NULL); - - origin.x = pango_to_logical_pixels (ink_rect.x, resource_scale); - origin.y = pango_to_logical_pixels (ink_rect.y, resource_scale); - origin.z = 0; - clutter_paint_volume_set_origin (volume, &origin); - clutter_paint_volume_set_width (volume, - pango_to_logical_pixels (ink_rect.width, - resource_scale)); - clutter_paint_volume_set_height (volume, - pango_to_logical_pixels (ink_rect.height, - resource_scale)); - - /* If the cursor is visible then that will likely be drawn - outside of the ink rectangle so we should merge that in */ - if (clutter_text_should_draw_cursor (text)) - { - ClutterPaintVolume cursor_paint_volume; - - _clutter_paint_volume_init_static (&cursor_paint_volume, self); - - clutter_text_get_paint_volume_for_cursor (text, resource_scale, - &cursor_paint_volume); - - clutter_paint_volume_union (volume, - &cursor_paint_volume); - - clutter_paint_volume_free (&cursor_paint_volume); - } - - return TRUE; -} - -static void -clutter_text_get_preferred_width (ClutterActor *self, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p) -{ - ClutterText *text = CLUTTER_TEXT (self); - ClutterTextPrivate *priv = clutter_text_get_instance_private (text); - PangoRectangle logical_rect = { 0, }; - PangoLayout *layout; - gint logical_width; - gfloat layout_width; - gfloat resource_scale; - - resource_scale = clutter_actor_get_resource_scale (self); - - layout = clutter_text_create_layout (text, -1, -1); - pango_layout_get_extents (layout, NULL, &logical_rect); - - /* the X coordinate of the logical rectangle might be non-zero - * according to the Pango documentation; hence, we need to offset - * the width accordingly - */ - logical_width = logical_rect.x + logical_rect.width; - - layout_width = logical_width > 0 - ? pango_to_logical_pixels (logical_width, resource_scale) - : 1; - - if (min_width_p) - { - if (priv->wrap || priv->ellipsize || priv->editable) - *min_width_p = 1; - else - *min_width_p = layout_width; - } - - if (natural_width_p) - { - if (priv->editable && priv->single_line_mode) - *natural_width_p = layout_width + TEXT_PADDING * 2; - else - *natural_width_p = layout_width; - } -} - -static void -clutter_text_get_preferred_height (ClutterActor *self, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p) -{ - ClutterTextPrivate *priv = - clutter_text_get_instance_private (CLUTTER_TEXT (self)); - - if (for_width == 0) - { - if (min_height_p) - *min_height_p = 0; - - if (natural_height_p) - *natural_height_p = 0; - } - else - { - PangoLayout *layout; - PangoRectangle logical_rect = { 0, }; - gint logical_height; - gfloat layout_height; - gfloat resource_scale; - - resource_scale = clutter_actor_get_resource_scale (self); - - if (priv->single_line_mode) - for_width = -1; - - layout = create_text_layout_with_scale (CLUTTER_TEXT (self), - for_width, -1, resource_scale); - - pango_layout_get_extents (layout, NULL, &logical_rect); - - /* the Y coordinate of the logical rectangle might be non-zero - * according to the Pango documentation; hence, we need to offset - * the height accordingly - */ - logical_height = logical_rect.y + logical_rect.height; - layout_height = pango_to_logical_pixels (logical_height, resource_scale); - - if (min_height_p) - { - /* if we wrap and ellipsize then the minimum height is - * going to be at least the size of the first line - */ - if ((priv->ellipsize && priv->wrap) && !priv->single_line_mode) - { - PangoLayoutLine *line; - PangoRectangle logical_line_rect = { 0, }; - gfloat line_height; - - line = pango_layout_get_line_readonly (layout, 0); - pango_layout_line_get_extents (line, NULL, &logical_line_rect); - - logical_height = logical_rect.y + logical_line_rect.height; - line_height = pango_to_logical_pixels (logical_height, - resource_scale); - - *min_height_p = line_height; - } - else - *min_height_p = layout_height; - } - - if (natural_height_p) - *natural_height_p = layout_height; - } -} - -static void -clutter_text_allocate (ClutterActor *self, - const ClutterActorBox *box) -{ - ClutterText *text = CLUTTER_TEXT (self); - ClutterTextPrivate *priv = clutter_text_get_instance_private (text); - ClutterActorClass *parent_class; - - /* Ensure that there is a cached layout with the right width so - * that we don't need to create the text during the paint run - * - * if the Text is editable and in single line mode we don't want - * to have any limit on the layout size, since the paint will clip - * it to the allocation of the actor - */ - if (priv->editable && priv->single_line_mode) - clutter_text_create_layout (text, -1, -1); - else - maybe_create_text_layout_with_resource_scale (text, - box->x2 - box->x1, - box->y2 - box->y1); - - parent_class = CLUTTER_ACTOR_CLASS (clutter_text_parent_class); - parent_class->allocate (self, box); -} - -static gboolean -clutter_text_has_overlaps (ClutterActor *self) -{ - return clutter_text_should_draw_cursor ((ClutterText *) self); -} - -static float -clutter_text_calculate_resource_scale (ClutterActor *actor, - int phase) -{ - ClutterActorClass *parent_class = CLUTTER_ACTOR_CLASS (clutter_text_parent_class); - float new_resource_scale; - - new_resource_scale = parent_class->calculate_resource_scale (actor, phase); - - if (phase == 1) - return MAX (new_resource_scale, clutter_actor_get_real_resource_scale (actor)); - - return new_resource_scale; -} - -static void -clutter_text_resource_scale_changed (ClutterActor *actor) -{ - ClutterText *text = CLUTTER_TEXT (actor); - ClutterTextPrivate *priv = clutter_text_get_instance_private (text); - - g_clear_pointer (&priv->effective_attrs, pango_attr_list_unref); - clutter_text_dirty_cache (text); - - clutter_actor_queue_immediate_relayout (actor); -} - -static gboolean -clutter_text_event (ClutterActor *self, - ClutterEvent *event) -{ - ClutterText *text = CLUTTER_TEXT (self); - ClutterTextPrivate *priv = clutter_text_get_instance_private (text); - ClutterEventType event_type; - - event_type = clutter_event_type (event); - - if (clutter_input_focus_is_focused (priv->input_focus) && - (event_type == CLUTTER_IM_COMMIT || - event_type == CLUTTER_IM_DELETE || - event_type == CLUTTER_IM_PREEDIT)) - { - return clutter_input_focus_process_event (priv->input_focus, event); - } - - return CLUTTER_EVENT_PROPAGATE; -} - -static void -clutter_text_im_focus (ClutterText *text) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (text); - ClutterBackend *backend = clutter_get_default_backend (); - ClutterInputMethod *method = clutter_backend_get_input_method (backend); - - if (!method) - return; - - clutter_input_method_focus_in (method, priv->input_focus); - clutter_input_focus_set_content_purpose (priv->input_focus, - priv->input_purpose); - clutter_input_focus_set_content_hints (priv->input_focus, - priv->input_hints); - clutter_input_focus_set_can_show_preedit (priv->input_focus, TRUE); - update_cursor_location (text); -} - -static void -clutter_text_key_focus_in (ClutterActor *actor) -{ - ClutterText *text = CLUTTER_TEXT (actor); - ClutterTextPrivate *priv = clutter_text_get_instance_private (text); - - if (priv->editable) - clutter_text_im_focus (text); - - priv->has_focus = TRUE; - - clutter_text_queue_redraw (actor); -} - -static void -clutter_text_key_focus_out (ClutterActor *actor) -{ - ClutterTextPrivate *priv = - clutter_text_get_instance_private (CLUTTER_TEXT (actor)); - ClutterBackend *backend = clutter_get_default_backend (); - ClutterInputMethod *method = clutter_backend_get_input_method (backend); - - priv->has_focus = FALSE; - - if (priv->editable && clutter_input_focus_is_focused (priv->input_focus)) - { - clutter_input_focus_reset (priv->input_focus); - clutter_input_method_focus_out (method); - } - - clutter_text_queue_redraw (actor); -} - -static gboolean -clutter_text_real_move_left (ClutterText *self, - const gchar *action, - guint keyval, - ClutterModifierType modifiers) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - gint pos = priv->position; - gint new_pos = 0; - gint len; - - len = clutter_text_buffer_get_length (get_buffer (self)); - - g_object_freeze_notify (G_OBJECT (self)); - - if (pos != 0 && len != 0) - { - if (modifiers & CLUTTER_CONTROL_MASK) - { - if (pos == -1) - new_pos = clutter_text_move_word_backward (self, len); - else - new_pos = clutter_text_move_word_backward (self, pos); - } - else - { - if (pos == -1) - new_pos = len - 1; - else - new_pos = pos - 1; - } - - clutter_text_set_cursor_position (self, new_pos); - } - - if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK))) - clutter_text_clear_selection (self); - - g_object_thaw_notify (G_OBJECT (self)); - - return TRUE; -} - -static gboolean -clutter_text_real_move_right (ClutterText *self, - const gchar *action, - guint keyval, - ClutterModifierType modifiers) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - gint pos = priv->position; - gint len = clutter_text_buffer_get_length (get_buffer (self)); - gint new_pos = 0; - - g_object_freeze_notify (G_OBJECT (self)); - - if (pos != -1 && len !=0) - { - if (modifiers & CLUTTER_CONTROL_MASK) - { - if (pos != len) - new_pos = clutter_text_move_word_forward (self, pos); - } - else - { - if (pos != len) - new_pos = pos + 1; - } - - clutter_text_set_cursor_position (self, new_pos); - } - - if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK))) - clutter_text_clear_selection (self); - - g_object_thaw_notify (G_OBJECT (self)); - - return TRUE; -} - -static gboolean -clutter_text_real_move_up (ClutterText *self, - const gchar *action, - guint keyval, - ClutterModifierType modifiers) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - PangoLayoutLine *layout_line; - PangoLayout *layout; - gint line_no; - gint index_, trailing; - gint pos; - gint x; - const gchar *text; - - layout = clutter_text_get_layout (self); - text = clutter_text_buffer_get_text (get_buffer (self)); - - if (priv->position == 0) - index_ = 0; - else - index_ = offset_to_bytes (text, priv->position); - - pango_layout_index_to_line_x (layout, index_, - 0, - &line_no, &x); - - line_no -= 1; - if (line_no < 0) - return FALSE; - - if (priv->x_pos != -1) - x = priv->x_pos; - - layout_line = pango_layout_get_line_readonly (layout, line_no); - if (!layout_line) - return FALSE; - - pango_layout_line_x_to_index (layout_line, x, &index_, &trailing); - - g_object_freeze_notify (G_OBJECT (self)); - - pos = bytes_to_offset (text, index_); - clutter_text_set_cursor_position (self, pos + trailing); - - /* Store the target x position to avoid drifting left and right when - moving the cursor up and down */ - priv->x_pos = x; - - if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK))) - clutter_text_clear_selection (self); - - g_object_thaw_notify (G_OBJECT (self)); - - return TRUE; -} - -static gboolean -clutter_text_real_move_down (ClutterText *self, - const gchar *action, - guint keyval, - ClutterModifierType modifiers) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - PangoLayoutLine *layout_line; - PangoLayout *layout; - gint line_no; - gint index_, trailing; - gint x; - gint pos; - const gchar *text; - - layout = clutter_text_get_layout (self); - text = clutter_text_buffer_get_text (get_buffer (self)); - - if (priv->position == 0) - index_ = 0; - else - index_ = offset_to_bytes (text, priv->position); - - pango_layout_index_to_line_x (layout, index_, - 0, - &line_no, &x); - - if (priv->x_pos != -1) - x = priv->x_pos; - - layout_line = pango_layout_get_line_readonly (layout, line_no + 1); - if (!layout_line) - return FALSE; - - pango_layout_line_x_to_index (layout_line, x, &index_, &trailing); - - g_object_freeze_notify (G_OBJECT (self)); - - pos = bytes_to_offset (text, index_); - clutter_text_set_cursor_position (self, pos + trailing); - - /* Store the target x position to avoid drifting left and right when - moving the cursor up and down */ - priv->x_pos = x; - - if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK))) - clutter_text_clear_selection (self); - - g_object_thaw_notify (G_OBJECT (self)); - - return TRUE; -} - -static gboolean -clutter_text_real_line_start (ClutterText *self, - const gchar *action, - guint keyval, - ClutterModifierType modifiers) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - gint position; - - g_object_freeze_notify (G_OBJECT (self)); - - position = clutter_text_move_line_start (self, priv->position); - clutter_text_set_cursor_position (self, position); - - if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK))) - clutter_text_clear_selection (self); - - g_object_thaw_notify (G_OBJECT (self)); - - return TRUE; -} - -static gboolean -clutter_text_real_line_end (ClutterText *self, - const gchar *action, - guint keyval, - ClutterModifierType modifiers) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - gint position; - - g_object_freeze_notify (G_OBJECT (self)); - - position = clutter_text_move_line_end (self, priv->position); - clutter_text_set_cursor_position (self, position); - - if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK))) - clutter_text_clear_selection (self); - - g_object_thaw_notify (G_OBJECT (self)); - - return TRUE; -} - -static gboolean -clutter_text_real_select_all (ClutterText *self, - const gchar *action, - guint keyval, - ClutterModifierType modifiers) -{ - guint n_chars = clutter_text_buffer_get_length (get_buffer (self)); - clutter_text_set_positions (self, 0, n_chars); - - return TRUE; -} - -static gboolean -clutter_text_real_del_next (ClutterText *self, - const gchar *action, - guint keyval, - ClutterModifierType modifiers) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - gint pos; - gint len; - - if (clutter_text_delete_selection (self)) - return TRUE; - - pos = priv->position; - len = clutter_text_buffer_get_length (get_buffer (self)); - - if (len && pos != -1 && pos < len) - clutter_text_delete_text (self, pos, pos + 1); - - return TRUE; -} - -static gboolean -clutter_text_real_del_word_next (ClutterText *self, - const gchar *action, - guint keyval, - ClutterModifierType modifiers) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - gint pos; - gint len; - - pos = priv->position; - len = clutter_text_buffer_get_length (get_buffer (self)); - - if (len && pos != -1 && pos < len) - { - gint end; - - end = clutter_text_move_word_forward (self, pos); - clutter_text_delete_text (self, pos, end); - - if (priv->selection_bound >= end) - { - gint new_bound; - - new_bound = priv->selection_bound - (end - pos); - clutter_text_set_selection_bound (self, new_bound); - } - else if (priv->selection_bound > pos) - { - clutter_text_set_selection_bound (self, pos); - } - } - - return TRUE; -} - -static gboolean -clutter_text_real_del_prev (ClutterText *self, - const gchar *action, - guint keyval, - ClutterModifierType modifiers) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - gint pos; - gint len; - - if (clutter_text_delete_selection (self)) - return TRUE; - - pos = priv->position; - len = clutter_text_buffer_get_length (get_buffer (self)); - - if (pos != 0 && len != 0) - { - if (pos == -1) - { - clutter_text_delete_text (self, len - 1, len); - - clutter_text_set_positions (self, -1, -1); - } - else - { - clutter_text_delete_text (self, pos - 1, pos); - - clutter_text_set_positions (self, pos - 1, pos - 1); - } - } - - return TRUE; -} - -static gboolean -clutter_text_real_del_word_prev (ClutterText *self, - const gchar *action, - guint keyval, - ClutterModifierType modifiers) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - gint pos; - gint len; - - pos = priv->position; - len = clutter_text_buffer_get_length (get_buffer (self)); - - if (pos != 0 && len != 0) - { - gint new_pos; - - if (pos == -1) - { - new_pos = clutter_text_move_word_backward (self, len); - clutter_text_delete_text (self, new_pos, len); - - clutter_text_set_positions (self, -1, -1); - } - else - { - new_pos = clutter_text_move_word_backward (self, pos); - clutter_text_delete_text (self, new_pos, pos); - - clutter_text_set_cursor_position (self, new_pos); - if (priv->selection_bound >= pos) - { - gint new_bound; - - new_bound = priv->selection_bound - (pos - new_pos); - clutter_text_set_selection_bound (self, new_bound); - } - else if (priv->selection_bound >= new_pos) - { - clutter_text_set_selection_bound (self, new_pos); - } - } - } - - return TRUE; -} - -static gboolean -clutter_text_real_activate (ClutterText *self, - const gchar *action, - guint keyval, - ClutterModifierType modifiers) -{ - return clutter_text_activate (self); -} - -static inline void -clutter_text_add_move_binding (ClutterBindingPool *pool, - const gchar *action, - guint key_val, - ClutterModifierType additional_modifiers, - GCallback callback) -{ - clutter_binding_pool_install_action (pool, action, - key_val, - 0, - callback, - NULL, NULL); - clutter_binding_pool_install_action (pool, action, - key_val, - CLUTTER_SHIFT_MASK, - callback, - NULL, NULL); - - if (additional_modifiers != 0) - { - clutter_binding_pool_install_action (pool, action, - key_val, - additional_modifiers, - callback, - NULL, NULL); - clutter_binding_pool_install_action (pool, action, - key_val, - CLUTTER_SHIFT_MASK | - additional_modifiers, - callback, - NULL, NULL); - } -} - -static void -clutter_text_set_color_internal (ClutterText *self, - GParamSpec *pspec, - const ClutterColor *color) -{ - ClutterTextPrivate *priv = - clutter_text_get_instance_private (self); - GParamSpec *other = NULL; - - switch (pspec->param_id) - { - case PROP_COLOR: - priv->text_color = *color; - break; - - case PROP_CURSOR_COLOR: - if (color) - { - priv->cursor_color = *color; - priv->cursor_color_set = TRUE; - } - else - priv->cursor_color_set = FALSE; - - other = obj_props[PROP_CURSOR_COLOR_SET]; - break; - - case PROP_SELECTION_COLOR: - if (color) - { - priv->selection_color = *color; - priv->selection_color_set = TRUE; - } - else - priv->selection_color_set = FALSE; - - other = obj_props[PROP_SELECTION_COLOR_SET]; - break; - - case PROP_SELECTED_TEXT_COLOR: - if (color) - { - priv->selected_text_color = *color; - priv->selected_text_color_set = TRUE; - } - else - priv->selected_text_color_set = FALSE; - - other = obj_props[PROP_SELECTED_TEXT_COLOR_SET]; - break; - - default: - g_assert_not_reached (); - break; - } - - clutter_text_queue_redraw (CLUTTER_ACTOR (self)); - - g_object_notify_by_pspec (G_OBJECT (self), pspec); - if (other) - g_object_notify_by_pspec (G_OBJECT (self), other); -} - -static void -clutter_text_set_color_animated (ClutterText *self, - GParamSpec *pspec, - const ClutterColor *color) -{ - ClutterActor *actor = CLUTTER_ACTOR (self); - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - const ClutterAnimationInfo *info; - ClutterTransition *transition; - - info = _clutter_actor_get_animation_info (actor); - transition = clutter_actor_get_transition (actor, pspec->name); - - /* jump to the end if there is no easing state, or if the easing - * state has a duration of 0 msecs - */ - if (info->cur_state == NULL || - info->cur_state->easing_duration == 0) - { - /* ensure that we remove any currently running transition */ - if (transition != NULL) - { - clutter_actor_remove_transition (actor, pspec->name); - transition = NULL; - } - - clutter_text_set_color_internal (self, pspec, color); - - return; - } - - if (transition == NULL) - { - transition = clutter_property_transition_new (pspec->name); - clutter_transition_set_animatable (transition, - CLUTTER_ANIMATABLE (self)); - clutter_transition_set_remove_on_complete (transition, TRUE); - - /* delay only makes sense if the transition has just been created */ - clutter_timeline_set_delay (CLUTTER_TIMELINE (transition), - info->cur_state->easing_delay); - - clutter_actor_add_transition (actor, pspec->name, transition); - - /* the actor now owns the transition */ - g_object_unref (transition); - } - - /* if a transition already exist, update its bounds */ - switch (pspec->param_id) - { - case PROP_COLOR: - clutter_transition_set_from (transition, CLUTTER_TYPE_COLOR, - &priv->text_color); - break; - - case PROP_CURSOR_COLOR: - clutter_transition_set_from (transition, CLUTTER_TYPE_COLOR, - &priv->cursor_color); - break; - - case PROP_SELECTION_COLOR: - clutter_transition_set_from (transition, CLUTTER_TYPE_COLOR, - &priv->selection_color); - break; - - case PROP_SELECTED_TEXT_COLOR: - clutter_transition_set_from (transition, CLUTTER_TYPE_COLOR, - &priv->selected_text_color); - break; - - default: - g_assert_not_reached (); - } - - clutter_transition_set_to (transition, CLUTTER_TYPE_COLOR, color); - - /* always use the current easing state */ - clutter_timeline_set_duration (CLUTTER_TIMELINE (transition), - info->cur_state->easing_duration); - clutter_timeline_set_progress_mode (CLUTTER_TIMELINE (transition), - info->cur_state->easing_mode); - - /* ensure that we start from the beginning */ - clutter_timeline_rewind (CLUTTER_TIMELINE (transition)); - clutter_timeline_start (CLUTTER_TIMELINE (transition)); -} - -static void -clutter_text_set_final_state (ClutterAnimatable *animatable, - const char *property_name, - const GValue *value) -{ - if (strcmp (property_name, "color") == 0) - { - const ClutterColor *color = clutter_value_get_color (value); - clutter_text_set_color_internal (CLUTTER_TEXT (animatable), - obj_props[PROP_COLOR], color); - } - else if (strcmp (property_name, "cursor-color") == 0) - { - const ClutterColor *color = clutter_value_get_color (value); - clutter_text_set_color_internal (CLUTTER_TEXT (animatable), - obj_props[PROP_CURSOR_COLOR], - color); - } - else if (strcmp (property_name, "selected-text-color") == 0) - { - const ClutterColor *color = clutter_value_get_color (value); - clutter_text_set_color_internal (CLUTTER_TEXT (animatable), - obj_props[PROP_SELECTED_TEXT_COLOR], - color); - } - else if (strcmp (property_name, "selection-color") == 0) - { - const ClutterColor *color = clutter_value_get_color (value); - clutter_text_set_color_internal (CLUTTER_TEXT (animatable), - obj_props[PROP_SELECTION_COLOR], - color); - } - else - parent_animatable_iface->set_final_state (animatable, property_name, value); -} - -static void -clutter_animatable_iface_init (ClutterAnimatableInterface *iface) -{ - parent_animatable_iface = g_type_interface_peek_parent (iface); - - iface->set_final_state = clutter_text_set_final_state; -} - -static void -clutter_text_class_init (ClutterTextClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - ClutterBindingPool *binding_pool; - GParamSpec *pspec; - - gobject_class->set_property = clutter_text_set_property; - gobject_class->get_property = clutter_text_get_property; - gobject_class->dispose = clutter_text_dispose; - gobject_class->finalize = clutter_text_finalize; - - actor_class->paint = clutter_text_paint; - actor_class->get_paint_volume = clutter_text_get_paint_volume; - actor_class->get_preferred_width = clutter_text_get_preferred_width; - actor_class->get_preferred_height = clutter_text_get_preferred_height; - actor_class->allocate = clutter_text_allocate; - actor_class->key_press_event = clutter_text_key_press; - actor_class->key_release_event = clutter_text_key_release; - actor_class->button_press_event = clutter_text_button_press; - actor_class->button_release_event = clutter_text_button_release; - actor_class->motion_event = clutter_text_motion; - actor_class->touch_event = clutter_text_touch_event; - actor_class->key_focus_in = clutter_text_key_focus_in; - actor_class->key_focus_out = clutter_text_key_focus_out; - actor_class->has_overlaps = clutter_text_has_overlaps; - actor_class->calculate_resource_scale = clutter_text_calculate_resource_scale; - actor_class->resource_scale_changed = clutter_text_resource_scale_changed; - actor_class->event = clutter_text_event; - - /** - * ClutterText:buffer: - * - * The buffer which stores the text for this #ClutterText. - * - * If set to %NULL, a default buffer will be created. - */ - pspec = g_param_spec_object ("buffer", NULL, NULL, - CLUTTER_TYPE_TEXT_BUFFER, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_BUFFER] = pspec; - g_object_class_install_property (gobject_class, PROP_BUFFER, pspec); - - /** - * ClutterText:font-name: - * - * The font to be used by the #ClutterText, as a string - * that can be parsed by [func@Pango.FontDescription.from_string]. - * - * If set to %NULL, the default system font will be used instead. - */ - pspec = g_param_spec_string ("font-name", NULL, NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_FONT_NAME] = pspec; - g_object_class_install_property (gobject_class, PROP_FONT_NAME, pspec); - - /** - * ClutterText:font-description: - * - * The [struct@Pango.FontDescription] that should be used by the #ClutterText - * - * If you have a string describing the font then you should look at - * [property@Text:font-name] instead - */ - pspec = g_param_spec_boxed ("font-description", NULL, NULL, - PANGO_TYPE_FONT_DESCRIPTION, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_FONT_DESCRIPTION] = pspec; - g_object_class_install_property (gobject_class, - PROP_FONT_DESCRIPTION, - pspec); - - /** - * ClutterText:text: - * - * The text to render inside the actor. - */ - pspec = g_param_spec_string ("text", NULL, NULL, - "", - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_TEXT] = pspec; - g_object_class_install_property (gobject_class, PROP_TEXT, pspec); - - /** - * ClutterText:color: - * - * The color used to render the text. - */ - pspec = clutter_param_spec_color ("color", NULL, NULL, - &default_text_color, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - CLUTTER_PARAM_ANIMATABLE); - obj_props[PROP_COLOR] = pspec; - g_object_class_install_property (gobject_class, PROP_COLOR, pspec); - - /** - * ClutterText:editable: - * - * Whether key events delivered to the actor causes editing. - */ - pspec = g_param_spec_boolean ("editable", NULL, NULL, - FALSE, - G_PARAM_READWRITE); - obj_props[PROP_EDITABLE] = pspec; - g_object_class_install_property (gobject_class, PROP_EDITABLE, pspec); - - /** - * ClutterText:selectable: - * - * Whether it is possible to select text, either using the pointer - * or the keyboard. - * - * This property depends on the [property@Actor:reactive] property being - * set to %TRUE. - */ - pspec = g_param_spec_boolean ("selectable", NULL, NULL, - TRUE, - G_PARAM_READWRITE); - obj_props[PROP_SELECTABLE] = pspec; - g_object_class_install_property (gobject_class, PROP_SELECTABLE, pspec); - - /** - * ClutterText:activatable: - * - * Toggles whether return invokes the activate signal or not. - */ - pspec = g_param_spec_boolean ("activatable", NULL, NULL, - TRUE, - G_PARAM_READWRITE); - obj_props[PROP_ACTIVATABLE] = pspec; - g_object_class_install_property (gobject_class, PROP_ACTIVATABLE, pspec); - - /** - * ClutterText:cursor-visible: - * - * Whether the input cursor is visible or not. - * - * The cursor will only be visible if this property and either - * the [property@Text:editable] or the [property@Text:selectable] properties - * are set to %TRUE. - */ - pspec = g_param_spec_boolean ("cursor-visible", NULL, NULL, - TRUE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_CURSOR_VISIBLE] = pspec; - g_object_class_install_property (gobject_class, PROP_CURSOR_VISIBLE, pspec); - - /** - * ClutterText:cursor-color: - * - * The color of the cursor. - */ - pspec = clutter_param_spec_color ("cursor-color", NULL, NULL, - &default_cursor_color, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - CLUTTER_PARAM_ANIMATABLE); - obj_props[PROP_CURSOR_COLOR] = pspec; - g_object_class_install_property (gobject_class, PROP_CURSOR_COLOR, pspec); - - /** - * ClutterText:cursor-color-set: - * - * Will be set to %TRUE if [property@Text:cursor-color] has been set. - */ - pspec = g_param_spec_boolean ("cursor-color-set", NULL, NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_CURSOR_COLOR_SET] = pspec; - g_object_class_install_property (gobject_class, PROP_CURSOR_COLOR_SET, pspec); - - /** - * ClutterText:cursor-size: - * - * The size of the cursor, in pixels. If set to -1 the size used will - * be the default cursor size of 2 pixels. - */ - pspec = g_param_spec_int ("cursor-size", NULL, NULL, - -1, G_MAXINT, DEFAULT_CURSOR_SIZE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_CURSOR_SIZE] = pspec; - g_object_class_install_property (gobject_class, PROP_CURSOR_SIZE, pspec); - - /** - * ClutterText:cursor-position: - * - * The current input cursor position. -1 is taken to be the end of the text - */ - pspec = g_param_spec_int ("cursor-position", NULL, NULL, - -1, G_MAXINT, - -1, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_CURSOR_POSITION] = pspec; - g_object_class_install_property (gobject_class, PROP_CURSOR_POSITION, pspec); - - /** - * ClutterText:selection-bound: - * - * The current input cursor position. -1 is taken to be the end of the text - */ - pspec = g_param_spec_int ("selection-bound", NULL, NULL, - -1, G_MAXINT, - -1, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_SELECTION_BOUND] = pspec; - g_object_class_install_property (gobject_class, PROP_SELECTION_BOUND, pspec); - - /** - * ClutterText:selection-color: - * - * The color of the selection. - */ - pspec = clutter_param_spec_color ("selection-color", NULL, NULL, - &default_selection_color, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - CLUTTER_PARAM_ANIMATABLE); - obj_props[PROP_SELECTION_COLOR] = pspec; - g_object_class_install_property (gobject_class, PROP_SELECTION_COLOR, pspec); - - /** - * ClutterText:selection-color-set: - * - * Will be set to %TRUE if [property@Text:selection-color] has been set. - */ - pspec = g_param_spec_boolean ("selection-color-set", NULL, NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_SELECTION_COLOR_SET] = pspec; - g_object_class_install_property (gobject_class, PROP_SELECTION_COLOR_SET, pspec); - - /** - * ClutterText:attributes: - * - * A list of `PangoStyleAttribute`s to be applied to the - * contents of the #ClutterText actor. - */ - pspec = g_param_spec_boxed ("attributes", NULL, NULL, - PANGO_TYPE_ATTR_LIST, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_ATTRIBUTES] = pspec; - g_object_class_install_property (gobject_class, PROP_ATTRIBUTES, pspec); - - /** - * ClutterText:use-markup: - * - * Whether the text includes Pango markup. - * - * For more information about the Pango markup format, see - * [method@Pango.Layout.set_markup] in the Pango documentation. - * - * It is not possible to round-trip this property between - * %TRUE and %FALSE. Once a string with markup has been set on - * a #ClutterText actor with [property@Text:use-markup] set to %TRUE, the markup - * is stripped from the string. - */ - pspec = g_param_spec_boolean ("use-markup", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_USE_MARKUP] = pspec; - g_object_class_install_property (gobject_class, PROP_USE_MARKUP, pspec); - - /** - * ClutterText:line-wrap: - * - * Whether to wrap the lines of [property@Text:text] if the contents - * exceed the available allocation. The wrapping strategy is - * controlled by the [property@Text:line-wrap-mode] property. - */ - pspec = g_param_spec_boolean ("line-wrap", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_LINE_WRAP] = pspec; - g_object_class_install_property (gobject_class, PROP_LINE_WRAP, pspec); - - /** - * ClutterText:line-wrap-mode: - * - * If [property@Text:line-wrap] is set to %TRUE, this property will - * control how the text is wrapped. - */ - pspec = g_param_spec_enum ("line-wrap-mode", NULL, NULL, - PANGO_TYPE_WRAP_MODE, - PANGO_WRAP_WORD, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_LINE_WRAP_MODE] = pspec; - g_object_class_install_property (gobject_class, PROP_LINE_WRAP_MODE, pspec); - - /** - * ClutterText:ellipsize: - * - * The preferred place to ellipsize the contents of the #ClutterText actor - */ - pspec = g_param_spec_enum ("ellipsize", NULL, NULL, - PANGO_TYPE_ELLIPSIZE_MODE, - PANGO_ELLIPSIZE_NONE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_ELLIPSIZE] = pspec; - g_object_class_install_property (gobject_class, PROP_ELLIPSIZE, pspec); - - /** - * ClutterText:line-alignment: - * - * The preferred alignment for the text. This property controls - * the alignment of multi-line paragraphs. - */ - pspec = g_param_spec_enum ("line-alignment", NULL, NULL, - PANGO_TYPE_ALIGNMENT, - PANGO_ALIGN_LEFT, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_LINE_ALIGNMENT] = pspec; - g_object_class_install_property (gobject_class, PROP_LINE_ALIGNMENT, pspec); - - /** - * ClutterText:justify: - * - * Whether the contents of the #ClutterText should be justified - * on both margins. - */ - pspec = g_param_spec_boolean ("justify", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_JUSTIFY] = pspec; - g_object_class_install_property (gobject_class, PROP_JUSTIFY, pspec); - - /** - * ClutterText:password-char: - * - * If non-zero, the character that should be used in place of - * the actual text in a password text actor. - */ - pspec = g_param_spec_unichar ("password-char", NULL, NULL, - 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_PASSWORD_CHAR] = pspec; - g_object_class_install_property (gobject_class, PROP_PASSWORD_CHAR, pspec); - - /** - * ClutterText:max-length: - * - * The maximum length of the contents of the #ClutterText actor. - */ - pspec = g_param_spec_int ("max-length", NULL, NULL, - -1, G_MAXINT, 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_MAX_LENGTH] = pspec; - g_object_class_install_property (gobject_class, PROP_MAX_LENGTH, pspec); - - /** - * ClutterText:single-line-mode: - * - * Whether the #ClutterText actor should be in single line mode - * or not. A single line #ClutterText actor will only contain a - * single line of text, scrolling it in case its length is bigger - * than the allocated size. - * - * Setting this property will also set the [property@Text:activatable] - * property as a side-effect. - * - * The [property@Text:single-line-mode] property is used only if the - * [property@Text:editable] property is set to %TRUE. - */ - pspec = g_param_spec_boolean ("single-line-mode", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_SINGLE_LINE_MODE] = pspec; - g_object_class_install_property (gobject_class, PROP_SINGLE_LINE_MODE, pspec); - - /** - * ClutterText:selected-text-color: - * - * The color of selected text. - */ - pspec = clutter_param_spec_color ("selected-text-color", NULL, NULL, - &default_selected_text_color, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - CLUTTER_PARAM_ANIMATABLE); - obj_props[PROP_SELECTED_TEXT_COLOR] = pspec; - g_object_class_install_property (gobject_class, PROP_SELECTED_TEXT_COLOR, pspec); - - /** - * ClutterText:selected-text-color-set: - * - * Will be set to %TRUE if [property@Text:selected-text-color] has been set. - */ - pspec = g_param_spec_boolean ("selected-text-color-set", NULL, NULL, - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_SELECTED_TEXT_COLOR_SET] = pspec; - g_object_class_install_property (gobject_class, PROP_SELECTED_TEXT_COLOR_SET, pspec); - - pspec = g_param_spec_flags ("input-hints", NULL, NULL, - CLUTTER_TYPE_INPUT_CONTENT_HINT_FLAGS, - 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_INPUT_HINTS] = pspec; - g_object_class_install_property (gobject_class, PROP_INPUT_HINTS, pspec); - - pspec = g_param_spec_enum ("input-purpose", NULL, NULL, - CLUTTER_TYPE_INPUT_CONTENT_PURPOSE, - 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_INPUT_PURPOSE] = pspec; - g_object_class_install_property (gobject_class, PROP_INPUT_PURPOSE, pspec); - - /** - * ClutterText::text-changed: - * @self: the #ClutterText that emitted the signal - * - * The signal is emitted after @actor's text changes - */ - text_signals[TEXT_CHANGED] = - g_signal_new (I_("text-changed"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterTextClass, text_changed), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - /** - * ClutterText::insert-text: - * @self: the #ClutterText that emitted the signal - * @new_text: the new text to insert - * @new_text_length: the length of the new text, in bytes, or -1 if - * new_text is nul-terminated - * @position: the position, in characters, at which to insert the - * new text. this is an in-out parameter. After the signal - * emission is finished, it should point after the newly - * inserted text. - * - * This signal is emitted when text is inserted into the actor by - * the user. It is emitted before @self text changes. - */ - text_signals[INSERT_TEXT] = - g_signal_new (I_("insert-text"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - 0, - NULL, NULL, - _clutter_marshal_VOID__STRING_INT_POINTER, - G_TYPE_NONE, 3, - G_TYPE_STRING, - G_TYPE_INT, - G_TYPE_POINTER); - - /** - * ClutterText::delete-text: - * @self: the #ClutterText that emitted the signal - * @start_pos: the starting position - * @end_pos: the end position - * - * This signal is emitted when text is deleted from the actor by - * the user. It is emitted before @self text changes. - */ - text_signals[DELETE_TEXT] = - g_signal_new (I_("delete-text"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - 0, - NULL, NULL, - _clutter_marshal_VOID__INT_INT, - G_TYPE_NONE, 2, - G_TYPE_INT, - G_TYPE_INT); - - /** - * ClutterText::cursor-changed: - * @self: the #ClutterText that emitted the signal - * - * The signal is emitted whenever the cursor - * position or size changes. - */ - text_signals[CURSOR_CHANGED] = - g_signal_new (I_("cursor-changed"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterTextClass, cursor_changed), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - /** - * ClutterText::activate: - * @self: the #ClutterText that emitted the signal - * - * The signal is emitted each time the actor is 'activated' - * by the user, normally by pressing the 'Enter' key. The signal is - * emitted only if [property@Text:activatable] is set to %TRUE. - */ - text_signals[ACTIVATE] = - g_signal_new (I_("activate"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterTextClass, activate), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - binding_pool = clutter_binding_pool_get_for_class (klass); - - clutter_text_add_move_binding (binding_pool, "move-left", - CLUTTER_KEY_Left, CLUTTER_CONTROL_MASK, - G_CALLBACK (clutter_text_real_move_left)); - clutter_text_add_move_binding (binding_pool, "move-left", - CLUTTER_KEY_KP_Left, CLUTTER_CONTROL_MASK, - G_CALLBACK (clutter_text_real_move_left)); - clutter_text_add_move_binding (binding_pool, "move-right", - CLUTTER_KEY_Right, CLUTTER_CONTROL_MASK, - G_CALLBACK (clutter_text_real_move_right)); - clutter_text_add_move_binding (binding_pool, "move-right", - CLUTTER_KEY_KP_Right, CLUTTER_CONTROL_MASK, - G_CALLBACK (clutter_text_real_move_right)); - clutter_text_add_move_binding (binding_pool, "move-up", - CLUTTER_KEY_Up, 0, - G_CALLBACK (clutter_text_real_move_up)); - clutter_text_add_move_binding (binding_pool, "move-up", - CLUTTER_KEY_KP_Up, 0, - G_CALLBACK (clutter_text_real_move_up)); - clutter_text_add_move_binding (binding_pool, "move-down", - CLUTTER_KEY_Down, 0, - G_CALLBACK (clutter_text_real_move_down)); - clutter_text_add_move_binding (binding_pool, "move-down", - CLUTTER_KEY_KP_Down, 0, - G_CALLBACK (clutter_text_real_move_down)); - - clutter_text_add_move_binding (binding_pool, "line-start", - CLUTTER_KEY_Home, 0, - G_CALLBACK (clutter_text_real_line_start)); - clutter_text_add_move_binding (binding_pool, "line-start", - CLUTTER_KEY_KP_Home, 0, - G_CALLBACK (clutter_text_real_line_start)); - clutter_text_add_move_binding (binding_pool, "line-start", - CLUTTER_KEY_Begin, 0, - G_CALLBACK (clutter_text_real_line_start)); - clutter_text_add_move_binding (binding_pool, "line-end", - CLUTTER_KEY_End, 0, - G_CALLBACK (clutter_text_real_line_end)); - clutter_text_add_move_binding (binding_pool, "line-end", - CLUTTER_KEY_KP_End, 0, - G_CALLBACK (clutter_text_real_line_end)); - - clutter_binding_pool_install_action (binding_pool, "select-all", - CLUTTER_KEY_a, CLUTTER_CONTROL_MASK, - G_CALLBACK (clutter_text_real_select_all), - NULL, NULL); - clutter_binding_pool_install_action (binding_pool, "select-all", - CLUTTER_KEY_A, CLUTTER_CONTROL_MASK, - G_CALLBACK (clutter_text_real_select_all), - NULL, NULL); - - clutter_binding_pool_install_action (binding_pool, "delete-next", - CLUTTER_KEY_Delete, 0, - G_CALLBACK (clutter_text_real_del_next), - NULL, NULL); - clutter_binding_pool_install_action (binding_pool, "delete-next", - CLUTTER_KEY_Delete, CLUTTER_CONTROL_MASK, - G_CALLBACK (clutter_text_real_del_word_next), - NULL, NULL); - clutter_binding_pool_install_action (binding_pool, "delete-next", - CLUTTER_KEY_KP_Delete, 0, - G_CALLBACK (clutter_text_real_del_next), - NULL, NULL); - clutter_binding_pool_install_action (binding_pool, "delete-next", - CLUTTER_KEY_KP_Delete, CLUTTER_CONTROL_MASK, - G_CALLBACK (clutter_text_real_del_word_next), - NULL, NULL); - clutter_binding_pool_install_action (binding_pool, "delete-prev", - CLUTTER_KEY_BackSpace, 0, - G_CALLBACK (clutter_text_real_del_prev), - NULL, NULL); - clutter_binding_pool_install_action (binding_pool, "delete-prev", - CLUTTER_KEY_BackSpace, CLUTTER_SHIFT_MASK, - G_CALLBACK (clutter_text_real_del_prev), - NULL, NULL); - clutter_binding_pool_install_action (binding_pool, "delete-prev", - CLUTTER_KEY_BackSpace, CLUTTER_CONTROL_MASK, - G_CALLBACK (clutter_text_real_del_word_prev), - NULL, NULL); - - clutter_binding_pool_install_action (binding_pool, "activate", - CLUTTER_KEY_Return, 0, - G_CALLBACK (clutter_text_real_activate), - NULL, NULL); - clutter_binding_pool_install_action (binding_pool, "activate", - CLUTTER_KEY_KP_Enter, 0, - G_CALLBACK (clutter_text_real_activate), - NULL, NULL); - clutter_binding_pool_install_action (binding_pool, "activate", - CLUTTER_KEY_ISO_Enter, 0, - G_CALLBACK (clutter_text_real_activate), - NULL, NULL); -} - -static void -clutter_text_init (ClutterText *self) -{ - ClutterSettings *settings; - ClutterTextPrivate *priv; - gchar *font_name; - int i, password_hint_time; - - priv = clutter_text_get_instance_private (self); - - priv->alignment = PANGO_ALIGN_LEFT; - priv->wrap = FALSE; - priv->wrap_mode = PANGO_WRAP_WORD; - priv->ellipsize = PANGO_ELLIPSIZE_NONE; - priv->use_underline = FALSE; - priv->use_markup = FALSE; - priv->justify = FALSE; - - for (i = 0; i < N_CACHED_LAYOUTS; i++) - priv->cached_layouts[i].layout = NULL; - - /* default to "" so that clutter_text_get_text() will - * return a valid string and we can safely call strlen() - * or strcmp() on it - */ - priv->buffer = NULL; - - priv->text_color = default_text_color; - priv->cursor_color = default_cursor_color; - priv->selection_color = default_selection_color; - priv->selected_text_color = default_selected_text_color; - - /* get the default font name from the context; we don't use - * set_font_description() here because we are initializing - * the Text and we don't need notifications and sanity checks - */ - settings = clutter_settings_get_default (); - g_object_get (settings, - "font-name", &font_name, - "password-hint-time", &password_hint_time, - NULL); - - priv->font_name = font_name; /* font_name is allocated */ - priv->font_desc = pango_font_description_from_string (font_name); - priv->is_default_font = TRUE; - - priv->position = -1; - priv->selection_bound = -1; - - priv->x_pos = -1; - priv->cursor_visible = TRUE; - priv->editable = FALSE; - priv->selectable = TRUE; - - priv->selection_color_set = FALSE; - priv->cursor_color_set = FALSE; - priv->selected_text_color_set = FALSE; - priv->preedit_set = FALSE; - - priv->password_char = 0; - priv->show_password_hint = password_hint_time > 0; - priv->password_hint_timeout = password_hint_time; - - priv->text_y = 0; - - priv->cursor_size = DEFAULT_CURSOR_SIZE; - - priv->settings_changed_id = - g_signal_connect_swapped (clutter_get_default_backend (), - "settings-changed", - G_CALLBACK (clutter_text_settings_changed_cb), - self); - - priv->direction_changed_id = - g_signal_connect (self, "notify::text-direction", - G_CALLBACK (clutter_text_direction_changed_cb), - NULL); - - priv->input_focus = clutter_text_input_focus_new (self); -} - -/** - * clutter_text_new: - * - * Creates a new #ClutterText actor. This actor can be used to - * display and edit text. - * - * Return value: the newly created #ClutterText actor - */ -ClutterActor * -clutter_text_new (void) -{ - return g_object_new (CLUTTER_TYPE_TEXT, NULL); -} - -/** - * clutter_text_new_full: - * @font_name: a string with a font description - * @text: the contents of the actor - * @color: the color to be used to render @text - * - * Creates a new #ClutterText actor, using @font_name as the font - * description; @text will be used to set the contents of the actor; - * and @color will be used as the color to render @text. - * - * This function is equivalent to calling [ctor@Text.new], - * [method@Text.set_font_name], [method@Text.set_text] and - * [method@Text.set_color]. - * - * Return value: the newly created #ClutterText actor - */ -ClutterActor * -clutter_text_new_full (const gchar *font_name, - const gchar *text, - const ClutterColor *color) -{ - return g_object_new (CLUTTER_TYPE_TEXT, - "font-name", font_name, - "text", text, - "color", color, - NULL); -} - -/** - * clutter_text_new_with_text: - * @font_name: (allow-none): a string with a font description - * @text: the contents of the actor - * - * Creates a new #ClutterText actor, using @font_name as the font - * description; @text will be used to set the contents of the actor. - * - * This function is equivalent to calling [ctor@Text.new], - * [method@Text.set_font_name], and [method@Text.set_text]. - * - * Return value: the newly created #ClutterText actor - */ -ClutterActor * -clutter_text_new_with_text (const gchar *font_name, - const gchar *text) -{ - return g_object_new (CLUTTER_TYPE_TEXT, - "font-name", font_name, - "text", text, - NULL); -} - -static ClutterTextBuffer* -get_buffer (ClutterText *self) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - - if (priv->buffer == NULL) - { - ClutterTextBuffer *buffer; - buffer = clutter_text_buffer_new (); - clutter_text_set_buffer (self, buffer); - g_object_unref (buffer); - } - - return priv->buffer; -} - -/* GtkEntryBuffer signal handlers - */ -static void -buffer_inserted_text (ClutterTextBuffer *buffer, - guint position, - const gchar *chars, - guint n_chars, - ClutterText *self) -{ - ClutterTextPrivate *priv; - gint new_position; - gint new_selection_bound; - - priv = clutter_text_get_instance_private (self); - if (priv->position >= 0 || priv->selection_bound >= 0) - { - new_position = priv->position; - new_selection_bound = priv->selection_bound; - - if (position <= new_position) - new_position += n_chars; - if (position <= new_selection_bound) - new_selection_bound += n_chars; - - if (priv->position != new_position || priv->selection_bound != new_selection_bound) - clutter_text_set_positions (self, new_position, new_selection_bound); - } - - /* TODO: What are we supposed to with the out value of position? */ -} - -static void -buffer_deleted_text (ClutterTextBuffer *buffer, - guint position, - guint n_chars, - ClutterText *self) -{ - ClutterTextPrivate *priv; - gint new_position; - gint new_selection_bound; - - priv = clutter_text_get_instance_private (self); - if (priv->position >= 0 || priv->selection_bound >= 0) - { - new_position = priv->position; - new_selection_bound = priv->selection_bound; - - if (position < new_position) - new_position -= n_chars; - if (position < new_selection_bound) - new_selection_bound -= n_chars; - - if (priv->position != new_position || priv->selection_bound != new_selection_bound) - clutter_text_set_positions (self, new_position, new_selection_bound); - } -} - -static void -clutter_text_queue_redraw_or_relayout (ClutterText *self) -{ - ClutterActor *actor = CLUTTER_ACTOR (self); - float preferred_width = -1.; - float preferred_height = -1.; - - clutter_text_dirty_cache (self); - - if (clutter_actor_has_allocation (actor)) - { - /* we're using our private implementations here to avoid the caching done by ClutterActor */ - clutter_text_get_preferred_width (actor, -1, NULL, &preferred_width); - clutter_text_get_preferred_height (actor, preferred_width, NULL, - &preferred_height); - } - - if (preferred_width > 0 && - preferred_height > 0 && - fabsf (preferred_width - clutter_actor_get_width (actor)) <= 0.001 && - fabsf (preferred_height - clutter_actor_get_height (actor)) <= 0.001) - clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); // paint volume was already invalidated by clutter_text_dirty_cache() - else - clutter_actor_queue_relayout (actor); -} - -static void -buffer_notify_text (ClutterTextBuffer *buffer, - GParamSpec *spec, - ClutterText *self) -{ - g_object_freeze_notify (G_OBJECT (self)); - - clutter_text_queue_redraw_or_relayout (self); - - g_signal_emit (self, text_signals[TEXT_CHANGED], 0); - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_TEXT]); - - g_object_thaw_notify (G_OBJECT (self)); -} - -static void -buffer_notify_max_length (ClutterTextBuffer *buffer, - GParamSpec *spec, - ClutterText *self) -{ - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_MAX_LENGTH]); -} - -static void -buffer_connect_signals (ClutterText *self) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - g_signal_connect (priv->buffer, "inserted-text", G_CALLBACK (buffer_inserted_text), self); - g_signal_connect (priv->buffer, "deleted-text", G_CALLBACK (buffer_deleted_text), self); - g_signal_connect (priv->buffer, "notify::text", G_CALLBACK (buffer_notify_text), self); - g_signal_connect (priv->buffer, "notify::max-length", G_CALLBACK (buffer_notify_max_length), self); -} - -static void -buffer_disconnect_signals (ClutterText *self) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - g_signal_handlers_disconnect_by_func (priv->buffer, buffer_inserted_text, self); - g_signal_handlers_disconnect_by_func (priv->buffer, buffer_deleted_text, self); - g_signal_handlers_disconnect_by_func (priv->buffer, buffer_notify_text, self); - g_signal_handlers_disconnect_by_func (priv->buffer, buffer_notify_max_length, self); -} - -/** - * clutter_text_new_with_buffer: - * @buffer: The buffer to use for the new #ClutterText. - * - * Creates a new entry with the specified text buffer. - * - * Return value: a new #ClutterText - */ -ClutterActor * -clutter_text_new_with_buffer (ClutterTextBuffer *buffer) -{ - g_return_val_if_fail (CLUTTER_IS_TEXT_BUFFER (buffer), NULL); - return g_object_new (CLUTTER_TYPE_TEXT, "buffer", buffer, NULL); -} - -/** - * clutter_text_get_buffer: - * @self: a #ClutterText - * - * Get the #ClutterTextBuffer object which holds the text for - * this widget. - * - * Returns: (transfer none): A #GtkEntryBuffer object. - */ -ClutterTextBuffer* -clutter_text_get_buffer (ClutterText *self) -{ - g_return_val_if_fail (CLUTTER_IS_TEXT (self), NULL); - - return get_buffer (self); -} - -/** - * clutter_text_set_buffer: - * @self: a #ClutterText - * @buffer: a #ClutterTextBuffer - * - * Set the [class@TextBuffer] object which holds the text for - * this widget. - */ -void -clutter_text_set_buffer (ClutterText *self, - ClutterTextBuffer *buffer) -{ - ClutterTextPrivate *priv; - GObject *obj; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - if (buffer) - { - g_return_if_fail (CLUTTER_IS_TEXT_BUFFER (buffer)); - g_object_ref (buffer); - } - - if (priv->buffer) - { - buffer_disconnect_signals (self); - g_object_unref (priv->buffer); - } - - priv->buffer = buffer; - - if (priv->buffer) - buffer_connect_signals (self); - - obj = G_OBJECT (self); - g_object_freeze_notify (obj); - g_object_notify_by_pspec (obj, obj_props[PROP_BUFFER]); - g_object_notify_by_pspec (obj, obj_props[PROP_TEXT]); - g_object_notify_by_pspec (obj, obj_props[PROP_MAX_LENGTH]); - g_object_thaw_notify (obj); -} - -/** - * clutter_text_set_editable: - * @self: a #ClutterText - * @editable: whether the #ClutterText should be editable - * - * Sets whether the #ClutterText actor should be editable. - * - * An editable #ClutterText with key focus set using - * [method@Actor.grab_key_focus] or [method@Stage.set_key_focus] - * will receive key events and will update its contents accordingly. - */ -void -clutter_text_set_editable (ClutterText *self, - gboolean editable) -{ - ClutterBackend *backend = clutter_get_default_backend (); - ClutterInputMethod *method = clutter_backend_get_input_method (backend); - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - if (priv->editable != editable) - { - priv->editable = editable; - - if (method) - { - if (!priv->editable && clutter_input_focus_is_focused (priv->input_focus)) - clutter_input_method_focus_out (method); - else if (priv->has_focus) - clutter_text_im_focus (self); - } - - clutter_text_queue_redraw (CLUTTER_ACTOR (self)); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_EDITABLE]); - } -} - -/** - * clutter_text_get_editable: - * @self: a #ClutterText - * - * Retrieves whether a #ClutterText is editable or not. - * - * Return value: %TRUE if the actor is editable - */ -gboolean -clutter_text_get_editable (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), FALSE); - - priv = clutter_text_get_instance_private (self); - return priv->editable; -} - -/** - * clutter_text_set_selectable: - * @self: a #ClutterText - * @selectable: whether the #ClutterText actor should be selectable - * - * Sets whether a #ClutterText actor should be selectable. - * - * A selectable #ClutterText will allow selecting its contents using - * the pointer or the keyboard. - */ -void -clutter_text_set_selectable (ClutterText *self, - gboolean selectable) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - if (priv->selectable != selectable) - { - priv->selectable = selectable; - - clutter_text_queue_redraw (CLUTTER_ACTOR (self)); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SELECTABLE]); - } -} - -/** - * clutter_text_get_selectable: - * @self: a #ClutterText - * - * Retrieves whether a #ClutterText is selectable or not. - * - * Return value: %TRUE if the actor is selectable - */ -gboolean -clutter_text_get_selectable (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), TRUE); - - priv = clutter_text_get_instance_private (self); - return priv->selectable; -} - -/** - * clutter_text_set_activatable: - * @self: a #ClutterText - * @activatable: whether the #ClutterText actor should be activatable - * - * Sets whether a #ClutterText actor should be activatable. - * - * An activatable #ClutterText actor will emit the [signal@Text::activate] - * signal whenever the 'Enter' (or 'Return') key is pressed; if it is not - * activatable, a new line will be appended to the current content. - * - * An activatable #ClutterText must also be set as editable using - * [method@Text.set_editable]. - */ -void -clutter_text_set_activatable (ClutterText *self, - gboolean activatable) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - if (priv->activatable != activatable) - { - priv->activatable = activatable; - - clutter_text_queue_redraw (CLUTTER_ACTOR (self)); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ACTIVATABLE]); - } -} - -/** - * clutter_text_get_activatable: - * @self: a #ClutterText - * - * Retrieves whether a #ClutterText is activatable or not. - * - * Return value: %TRUE if the actor is activatable - */ -gboolean -clutter_text_get_activatable (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), TRUE); - - priv = clutter_text_get_instance_private (self); - return priv->activatable; -} - -/** - * clutter_text_activate: - * @self: a #ClutterText - * - * Emits the [signal@Text::activate] signal, if @self has been set - * as activatable using [method@Text.set_activatable]. - * - * This function can be used to emit the [signal@Text::activate] signal inside - * a [signal@Actor::captured-event] or [signal@Actor::key-press-event] - * signal handlers before the default signal handler for the - * #ClutterText is invoked. - * - * Return value: %TRUE if the [signal@Text::activate] signal has been emitted, - * and %FALSE otherwise - */ -gboolean -clutter_text_activate (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), FALSE); - - priv = clutter_text_get_instance_private (self); - - if (priv->activatable) - { - g_signal_emit (self, text_signals[ACTIVATE], 0); - return TRUE; - } - - return FALSE; -} - -/** - * clutter_text_set_cursor_visible: - * @self: a #ClutterText - * @cursor_visible: whether the cursor should be visible - * - * Sets whether the cursor of a #ClutterText actor should be - * visible or not. - * - * The color of the cursor will be the same as the text color - * unless [method@Text.set_cursor_color] has been called. - * - * The size of the cursor can be set using [method@Text.set_cursor_size]. - * - * The position of the cursor can be changed programmatically using - * [method@Text.set_cursor_position]. - */ -void -clutter_text_set_cursor_visible (ClutterText *self, - gboolean cursor_visible) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - cursor_visible = !!cursor_visible; - - if (priv->cursor_visible != cursor_visible) - { - priv->cursor_visible = cursor_visible; - - clutter_text_queue_redraw_or_relayout (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CURSOR_VISIBLE]); - } -} - -/** - * clutter_text_get_cursor_visible: - * @self: a #ClutterText - * - * Retrieves whether the cursor of a #ClutterText actor is visible. - * - * Return value: %TRUE if the cursor is visible - */ -gboolean -clutter_text_get_cursor_visible (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), TRUE); - - priv = clutter_text_get_instance_private (self); - return priv->cursor_visible; -} - -/** - * clutter_text_set_cursor_color: - * @self: a #ClutterText - * @color: (allow-none): the color of the cursor, or %NULL to unset it - * - * Sets the color of the cursor of a #ClutterText actor. - * - * If @color is %NULL, the cursor color will be the same as the - * text color. - */ -void -clutter_text_set_cursor_color (ClutterText *self, - const ClutterColor *color) -{ - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - clutter_text_set_color_animated (self, obj_props[PROP_CURSOR_COLOR], color); -} - -/** - * clutter_text_get_cursor_color: - * @self: a #ClutterText - * @color: (out): return location for a #ClutterColor - * - * Retrieves the color of the cursor of a #ClutterText actor. - */ -void -clutter_text_get_cursor_color (ClutterText *self, - ClutterColor *color) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - g_return_if_fail (color != NULL); - - priv = clutter_text_get_instance_private (self); - - *color = priv->cursor_color; -} - -/** - * clutter_text_set_selection: - * @self: a #ClutterText - * @start_pos: start of the selection, in characters - * @end_pos: end of the selection, in characters - * - * Selects the region of text between @start_pos and @end_pos. - * - * This function changes the position of the cursor to match - * @start_pos and the selection bound to match @end_pos. - */ -void -clutter_text_set_selection (ClutterText *self, - gssize start_pos, - gssize end_pos) -{ - guint n_chars; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - n_chars = clutter_text_buffer_get_length (get_buffer (self)); - if (end_pos < 0) - end_pos = n_chars; - - start_pos = MIN (n_chars, start_pos); - end_pos = MIN (n_chars, end_pos); - - clutter_text_set_positions (self, start_pos, end_pos); -} - -/** - * clutter_text_get_selection: - * @self: a #ClutterText - * - * Retrieves the currently selected text. - * - * Return value: a newly allocated string containing the currently - * selected text, or %NULL. Use [func@GLib.free] to free the returned - * string. - */ -gchar * -clutter_text_get_selection (ClutterText *self) -{ - ClutterTextPrivate *priv; - gchar *str; - gint len; - gint start_index, end_index; - gint start_offset, end_offset; - const gchar *text; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), NULL); - - priv = clutter_text_get_instance_private (self); - - start_index = priv->position; - end_index = priv->selection_bound; - - if (end_index == start_index) - return g_strdup (""); - - if ((end_index != -1 && end_index < start_index) || - start_index == -1) - { - gint temp = start_index; - start_index = end_index; - end_index = temp; - } - - text = clutter_text_buffer_get_text (get_buffer (self)); - start_offset = offset_to_bytes (text, start_index); - end_offset = offset_to_bytes (text, end_index); - len = end_offset - start_offset; - - str = g_malloc (len + 1); - g_utf8_strncpy (str, text + start_offset, end_index - start_index); - - return str; -} - -/** - * clutter_text_set_selection_bound: - * @self: a #ClutterText - * @selection_bound: the position of the end of the selection, in characters - * - * Sets the other end of the selection, starting from the current - * cursor position. - * - * If @selection_bound is -1, the selection unset. - */ -void -clutter_text_set_selection_bound (ClutterText *self, - gint selection_bound) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - if (priv->selection_bound != selection_bound) - { - gint len = clutter_text_buffer_get_length (get_buffer (self)); - - if (selection_bound < 0 || selection_bound >= len) - priv->selection_bound = -1; - else - priv->selection_bound = selection_bound; - - clutter_text_queue_redraw (CLUTTER_ACTOR (self)); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SELECTION_BOUND]); - } -} - -/** - * clutter_text_get_selection_bound: - * @self: a #ClutterText - * - * Retrieves the other end of the selection of a #ClutterText actor, - * in characters from the current cursor position. - * - * Return value: the position of the other end of the selection - */ -gint -clutter_text_get_selection_bound (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), -1); - - priv = clutter_text_get_instance_private (self); - return priv->selection_bound; -} - -/** - * clutter_text_set_selection_color: - * @self: a #ClutterText - * @color: (allow-none): the color of the selection, or %NULL to unset it - * - * Sets the color of the selection of a #ClutterText actor. - * - * If @color is %NULL, the selection color will be the same as the - * cursor color, or if no cursor color is set either then it will be - * the same as the text color. - */ -void -clutter_text_set_selection_color (ClutterText *self, - const ClutterColor *color) -{ - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - clutter_text_set_color_animated (self, obj_props[PROP_SELECTION_COLOR], - color); -} - -/** - * clutter_text_get_selection_color: - * @self: a #ClutterText - * @color: (out caller-allocates): return location for a #ClutterColor - * - * Retrieves the color of the selection of a #ClutterText actor. - */ -void -clutter_text_get_selection_color (ClutterText *self, - ClutterColor *color) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - g_return_if_fail (color != NULL); - - priv = clutter_text_get_instance_private (self); - - *color = priv->selection_color; -} - -/** - * clutter_text_set_selected_text_color: - * @self: a #ClutterText - * @color: (allow-none): the selected text color, or %NULL to unset it - * - * Sets the selected text color of a #ClutterText actor. - * - * If @color is %NULL, the selected text color will be the same as the - * selection color, which then falls back to cursor, and then text color. - */ -void -clutter_text_set_selected_text_color (ClutterText *self, - const ClutterColor *color) -{ - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - clutter_text_set_color_animated (self, obj_props[PROP_SELECTED_TEXT_COLOR], - color); -} - -/** - * clutter_text_get_selected_text_color: - * @self: a #ClutterText - * @color: (out caller-allocates): return location for a [struct@Color] - * - * Retrieves the color of selected text of a #ClutterText actor. - */ -void -clutter_text_get_selected_text_color (ClutterText *self, - ClutterColor *color) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - g_return_if_fail (color != NULL); - - priv = clutter_text_get_instance_private (self); - - *color = priv->selected_text_color; -} - -/** - * clutter_text_set_font_description: - * @self: a #ClutterText - * @font_desc: a #PangoFontDescription - * - * Sets @font_desc as the font description for a #ClutterText - * - * The #PangoFontDescription is copied by the #ClutterText actor - * so you can safely call [method@Pango.FontDescription.free] on it after - * calling this function. - */ -void -clutter_text_set_font_description (ClutterText *self, - PangoFontDescription *font_desc) -{ - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - clutter_text_set_font_description_internal (self, font_desc, - font_desc == NULL); -} - -/** - * clutter_text_get_font_description: - * @self: a #ClutterText - * - * Retrieves the [struct@Pango.FontDescription] used by @self - * - * Return value: a #PangoFontDescription. The returned value is owned - * by the #ClutterText actor and it should not be modified or freed - */ -PangoFontDescription * -clutter_text_get_font_description (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), NULL); - - priv = clutter_text_get_instance_private (self); - return priv->font_desc; -} - -/** - * clutter_text_get_font_name: - * @self: a #ClutterText - * - * Retrieves the font name as set by [method@Text.set_font_name]. - * - * Return value: a string containing the font name. The returned - * string is owned by the #ClutterText actor and should not be - * modified or freed - */ -const gchar * -clutter_text_get_font_name (ClutterText *text) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (text), NULL); - - priv = clutter_text_get_instance_private (text); - return priv->font_name; -} - -/** - * clutter_text_set_font_name: - * @self: a #ClutterText - * @font_name: (allow-none): a font name, or %NULL to set the default font name - * - * Sets the font used by a #ClutterText. The @font_name string - * must either be %NULL, which means that the font name from the - * default [class@Backend] will be used; or be something that can - * be parsed by the [func@Pango.FontDescription.from_string] function, - * like: - * - * ```c - * // Set the font to the system's Sans, 10 points - * clutter_text_set_font_name (text, "Sans 10"); - * - * // Set the font to the system's Serif, 16 pixels - * clutter_text_set_font_name (text, "Serif 16px"); - * - * // Set the font to Helvetica, 10 points - * clutter_text_set_font_name (text, "Helvetica 10"); - * ``` - */ -void -clutter_text_set_font_name (ClutterText *self, - const gchar *font_name) -{ - ClutterTextPrivate *priv; - PangoFontDescription *desc; - gboolean is_default_font; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - /* get the default font name from the backend */ - if (font_name == NULL || font_name[0] == '\0') - { - ClutterSettings *settings = clutter_settings_get_default (); - gchar *default_font_name = NULL; - - g_object_get (settings, "font-name", &default_font_name, NULL); - - if (default_font_name != NULL) - font_name = default_font_name; - else - { - /* last fallback */ - font_name = g_strdup ("Sans 12"); - } - - is_default_font = TRUE; - } - else - is_default_font = FALSE; - - priv = clutter_text_get_instance_private (self); - - if (g_strcmp0 (priv->font_name, font_name) == 0) - goto out; - - desc = pango_font_description_from_string (font_name); - if (desc == NULL) - { - g_warning ("Attempting to create a PangoFontDescription for " - "font name '%s', but failed.", - font_name); - goto out; - } - - /* this will set the font_name field as well */ - clutter_text_set_font_description_internal (self, desc, is_default_font); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_FONT_NAME]); - - pango_font_description_free (desc); - -out: - if (is_default_font) - g_free ((gchar *) font_name); -} - -/** - * clutter_text_get_text: - * @self: a #ClutterText - * - * Retrieves a pointer to the current contents of a #ClutterText - * actor. - * - * If you need a copy of the contents for manipulating, either - * use [func@GLib.strdup] on the returned string, or use: - * - * ```c - * copy = clutter_text_get_chars (text, 0, -1); - * ``` - * - * Which will return a newly allocated string. - * - * If the #ClutterText actor is empty, this function will return - * an empty string, and not %NULL. - * - * Return value: (transfer none): the contents of the actor. The returned - * string is owned by the #ClutterText actor and should never be modified - * or freed - */ -const gchar * -clutter_text_get_text (ClutterText *self) -{ - g_return_val_if_fail (CLUTTER_IS_TEXT (self), NULL); - - return clutter_text_buffer_get_text (get_buffer (self)); -} - -static inline void -clutter_text_set_use_markup_internal (ClutterText *self, - gboolean use_markup) -{ - ClutterTextPrivate *priv = clutter_text_get_instance_private (self); - - if (priv->use_markup != use_markup) - { - priv->use_markup = use_markup; - - /* reset the attributes lists so that they can be - * re-generated - */ - if (priv->effective_attrs != NULL) - { - pango_attr_list_unref (priv->effective_attrs); - priv->effective_attrs = NULL; - } - - if (priv->markup_attrs) - { - pango_attr_list_unref (priv->markup_attrs); - priv->markup_attrs = NULL; - } - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_USE_MARKUP]); - } -} - -/** - * clutter_text_set_text: - * @self: a #ClutterText - * @text: (allow-none): the text to set. Passing %NULL is the same - * as passing "" (the empty string) - * - * Sets the contents of a #ClutterText actor. - * - * If the [property@Text:use-markup] property was set to %TRUE it - * will be reset to %FALSE as a side effect. If you want to - * maintain the [property@Text:use-markup] you should use the - * [method@Text.set_markup] function instead - */ -void -clutter_text_set_text (ClutterText *self, - const gchar *text) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - /* if the text is editable (i.e. there is not markup flag to reset) then - * changing the contents will result in selection and cursor changes that - * we should avoid - */ - priv = clutter_text_get_instance_private (self); - if (priv->editable) - { - if (g_strcmp0 (clutter_text_buffer_get_text (get_buffer (self)), text) == 0) - return; - } - - clutter_text_set_use_markup_internal (self, FALSE); - clutter_text_buffer_set_text (get_buffer (self), text ? text : "", -1); -} - -/** - * clutter_text_set_markup: - * @self: a #ClutterText - * @markup: (allow-none): a string containing Pango markup. - * Passing %NULL is the same as passing "" (the empty string) - * - * Sets @markup as the contents of a #ClutterText. - * - * This is a convenience function for setting a string containing - * Pango markup, and it is logically equivalent to: - * - * ```c - * /* the order is important */ - * clutter_text_set_text (CLUTTER_TEXT (actor), markup); - * clutter_text_set_use_markup (CLUTTER_TEXT (actor), TRUE); - * ``` - */ -void -clutter_text_set_markup (ClutterText *self, - const gchar *markup) -{ - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - clutter_text_set_use_markup_internal (self, TRUE); - if (markup != NULL && *markup != '\0') - clutter_text_set_markup_internal (self, markup); - else - clutter_text_buffer_set_text (get_buffer (self), "", 0); -} - -/** - * clutter_text_get_layout: - * @self: a #ClutterText - * - * Retrieves the current #PangoLayout used by a #ClutterText actor. - * - * Return value: (transfer none): a #PangoLayout. The returned object is owned by - * the #ClutterText actor and should not be modified or freed - */ -PangoLayout * -clutter_text_get_layout (ClutterText *self) -{ - PangoLayout *layout; - gfloat width, height; - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), NULL); - - priv = clutter_text_get_instance_private (self); - if (priv->editable && priv->single_line_mode) - return clutter_text_create_layout (self, -1, -1); - - clutter_actor_get_size (CLUTTER_ACTOR (self), &width, &height); - layout = maybe_create_text_layout_with_resource_scale (self, width, height); - - if (!layout) - layout = clutter_text_create_layout (self, width, height); - - return layout; -} - -/** - * clutter_text_set_color: - * @self: a #ClutterText - * @color: a #ClutterColor - * - * Sets the color of the contents of a #ClutterText actor. - * - * The overall opacity of the #ClutterText actor will be the - * result of the alpha value of @color and the composited - * opacity of the actor itself on the scenegraph, as returned - * by [method@Actor.get_paint_opacity]. - */ -void -clutter_text_set_color (ClutterText *self, - const ClutterColor *color) -{ - g_return_if_fail (CLUTTER_IS_TEXT (self)); - g_return_if_fail (color != NULL); - - clutter_text_set_color_animated (self, obj_props[PROP_COLOR], color); -} - -/** - * clutter_text_get_color: - * @self: a #ClutterText - * @color: (out caller-allocates): return location for a [struct@Color] - * - * Retrieves the text color as set by [method@Text.set_color]. - */ -void -clutter_text_get_color (ClutterText *self, - ClutterColor *color) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - g_return_if_fail (color != NULL); - - priv = clutter_text_get_instance_private (self); - - *color = priv->text_color; -} - -/** - * clutter_text_set_ellipsize: - * @self: a #ClutterText - * @mode: a #PangoEllipsizeMode - * - * Sets the mode used to ellipsize (add an ellipsis: "...") to the - * text if there is not enough space to render the entire contents - * of a #ClutterText actor - */ -void -clutter_text_set_ellipsize (ClutterText *self, - PangoEllipsizeMode mode) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - g_return_if_fail (mode >= PANGO_ELLIPSIZE_NONE && - mode <= PANGO_ELLIPSIZE_END); - - priv = clutter_text_get_instance_private (self); - - if ((PangoEllipsizeMode) priv->ellipsize != mode) - { - priv->ellipsize = mode; - - clutter_text_dirty_cache (self); - - clutter_actor_queue_relayout (CLUTTER_ACTOR (self)); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ELLIPSIZE]); - } -} - -/** - * clutter_text_get_ellipsize: - * @self: a #ClutterText - * - * Returns the ellipsizing position of a #ClutterText actor, as - * set by [method@Text.set_ellipsize]. - * - * Return value: #PangoEllipsizeMode - */ -PangoEllipsizeMode -clutter_text_get_ellipsize (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), PANGO_ELLIPSIZE_NONE); - - priv = clutter_text_get_instance_private (self); - return priv->ellipsize; -} - -/** - * clutter_text_get_line_wrap: - * @self: a #ClutterText - * - * Retrieves the value set using [method@Text.set_line_wrap]. - * - * Return value: %TRUE if the #ClutterText actor should wrap - * its contents - */ -gboolean -clutter_text_get_line_wrap (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), FALSE); - - priv = clutter_text_get_instance_private (self); - return priv->wrap; -} - -/** - * clutter_text_set_line_wrap: - * @self: a #ClutterText - * @line_wrap: whether the contents should wrap - * - * Sets whether the contents of a #ClutterText actor should wrap, - * if they don't fit the size assigned to the actor. - */ -void -clutter_text_set_line_wrap (ClutterText *self, - gboolean line_wrap) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - if (priv->wrap != line_wrap) - { - priv->wrap = line_wrap; - - clutter_text_dirty_cache (self); - - clutter_actor_queue_relayout (CLUTTER_ACTOR (self)); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_LINE_WRAP]); - } -} - -/** - * clutter_text_set_line_wrap_mode: - * @self: a #ClutterText - * @wrap_mode: the line wrapping mode - * - * If line wrapping is enabled (see [method@Text.set_line_wrap]) this - * function controls how the line wrapping is performed. The default is - * %PANGO_WRAP_WORD which means wrap on word boundaries. - */ -void -clutter_text_set_line_wrap_mode (ClutterText *self, - PangoWrapMode wrap_mode) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - if (priv->wrap_mode != wrap_mode) - { - priv->wrap_mode = wrap_mode; - - clutter_text_dirty_cache (self); - - clutter_actor_queue_relayout (CLUTTER_ACTOR (self)); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_LINE_WRAP_MODE]); - } -} - -/** - * clutter_text_get_line_wrap_mode: - * @self: a #ClutterText - * - * Retrieves the line wrap mode used by the #ClutterText actor. - * - * See [method@Text.set_line_wrap_mode]. - * - * Return value: the wrap mode used by the #ClutterText - */ -PangoWrapMode -clutter_text_get_line_wrap_mode (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), PANGO_WRAP_WORD); - - priv = clutter_text_get_instance_private (self); - return priv->wrap_mode; -} - -/** - * clutter_text_set_attributes: - * @self: a #ClutterText - * @attrs: (allow-none): a #PangoAttrList or %NULL to unset the attributes - * - * Sets the attributes list that are going to be applied to the - * #ClutterText contents. - * - * The #ClutterText actor will take a reference on the [struct@Pango.AttrList] - * passed to this function. - */ -void -clutter_text_set_attributes (ClutterText *self, - PangoAttrList *attrs) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - if (pango_attr_list_equal (priv->attrs, attrs)) - return; - - if (attrs) - pango_attr_list_ref (attrs); - - if (priv->attrs) - pango_attr_list_unref (priv->attrs); - - priv->attrs = attrs; - - /* Clear the effective attributes so they will be regenerated when a - layout is created */ - if (priv->effective_attrs) - { - pango_attr_list_unref (priv->effective_attrs); - priv->effective_attrs = NULL; - } - - clutter_text_queue_redraw_or_relayout (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ATTRIBUTES]); -} - -/** - * clutter_text_get_attributes: - * @self: a #ClutterText - * - * Gets the attribute list that was set on the #ClutterText actor - * [method@Text.set_attributes], if any. - * - * Return value: (transfer none): the attribute list, or %NULL if none was set. The - * returned value is owned by the #ClutterText and should not be unreferenced. - */ -PangoAttrList * -clutter_text_get_attributes (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), NULL); - - priv = clutter_text_get_instance_private (self); - return priv->attrs; -} - -/** - * clutter_text_set_line_alignment: - * @self: a #ClutterText - * @alignment: A #PangoAlignment - * - * Sets the way that the lines of a wrapped label are aligned with - * respect to each other. This does not affect the overall alignment - * of the label within its allocated or specified width. - * - * To align a #ClutterText actor you should add it to a container - * that supports alignment, or use the anchor point. - */ -void -clutter_text_set_line_alignment (ClutterText *self, - PangoAlignment alignment) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - if (priv->alignment != alignment) - { - priv->alignment = alignment; - - clutter_text_queue_redraw_or_relayout (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_LINE_ALIGNMENT]); - } -} - -/** - * clutter_text_get_line_alignment: - * @self: a #ClutterText - * - * Retrieves the alignment of a #ClutterText, as set by - * [method@Text.set_line_alignment]. - * - * Return value: a [enum@Pango.Alignment] - */ -PangoAlignment -clutter_text_get_line_alignment (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), PANGO_ALIGN_LEFT); - - priv = clutter_text_get_instance_private (self); - return priv->alignment; -} - -/** - * clutter_text_set_use_markup: - * @self: a #ClutterText - * @setting: %TRUE if the text should be parsed for markup. - * - * Sets whether the contents of the #ClutterText actor contains markup - * in [Pango's text markup language](https://docs.gtk.org/Pango/pango_markup.html#pango-markup). - * - * Setting [property@Text:use-markup] on an editable #ClutterText will - * not have any effect except hiding the markup. - * - * See also [property@Text:use-markup]. - */ -void -clutter_text_set_use_markup (ClutterText *self, - gboolean setting) -{ - const gchar *text; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - text = clutter_text_buffer_get_text (get_buffer (self)); - - clutter_text_set_use_markup_internal (self, setting); - - if (setting) - clutter_text_set_markup_internal (self, text); - - clutter_text_queue_redraw_or_relayout (self); -} - -/** - * clutter_text_get_use_markup: - * @self: a #ClutterText - * - * Retrieves whether the contents of the #ClutterText actor should be - * parsed for the Pango text markup. - * - * Return value: %TRUE if the contents will be parsed for markup - */ -gboolean -clutter_text_get_use_markup (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), FALSE); - - priv = clutter_text_get_instance_private (self); - return priv->use_markup; -} - -/** - * clutter_text_set_justify: - * @self: a #ClutterText - * @justify: whether the text should be justified - * - * Sets whether the text of the #ClutterText actor should be justified - * on both margins. This setting is ignored if Clutter is compiled - * against Pango < 1.18. - */ -void -clutter_text_set_justify (ClutterText *self, - gboolean justify) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - if (priv->justify != justify) - { - priv->justify = justify; - - clutter_text_queue_redraw_or_relayout (self); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_JUSTIFY]); - } -} - -/** - * clutter_text_get_justify: - * @self: a #ClutterText - * - * Retrieves whether the #ClutterText actor should justify its contents - * on both margins. - * - * Return value: %TRUE if the text should be justified - */ -gboolean -clutter_text_get_justify (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), FALSE); - - priv = clutter_text_get_instance_private (self); - return priv->justify; -} - -/** - * clutter_text_get_cursor_position: - * @self: a #ClutterText - * - * Retrieves the cursor position. - * - * Return value: the cursor position, in characters - */ -gint -clutter_text_get_cursor_position (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), -1); - - priv = clutter_text_get_instance_private (self); - return priv->position; -} - -/** - * clutter_text_set_cursor_position: - * @self: a #ClutterText - * @position: the new cursor position, in characters - * - * Sets the cursor of a #ClutterText actor at @position. - * - * The position is expressed in characters, not in bytes. - */ -void -clutter_text_set_cursor_position (ClutterText *self, - gint position) -{ - ClutterTextPrivate *priv; - gint len; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - if (priv->position == position) - return; - - len = clutter_text_buffer_get_length (get_buffer (self)); - - if (position < 0 || position >= len) - priv->position = -1; - else - priv->position = position; - - /* Forget the target x position so that it will be recalculated next - time the cursor is moved up or down */ - priv->x_pos = -1; - - clutter_text_queue_redraw (CLUTTER_ACTOR (self)); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CURSOR_POSITION]); - g_signal_emit (self, text_signals[CURSOR_CHANGED], 0); -} - -/** - * clutter_text_set_cursor_size: - * @self: a #ClutterText - * @size: the size of the cursor, in pixels, or -1 to use the - * default value - * - * Sets the size of the cursor of a #ClutterText. The cursor - * will only be visible if the [property@Text:cursor-visible] property - * is set to %TRUE. - */ -void -clutter_text_set_cursor_size (ClutterText *self, - gint size) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - if (priv->cursor_size != size) - { - if (size < 0) - size = DEFAULT_CURSOR_SIZE; - - priv->cursor_size = size; - - clutter_text_queue_redraw (CLUTTER_ACTOR (self)); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CURSOR_SIZE]); - } -} - -/** - * clutter_text_get_cursor_size: - * @self: a #ClutterText - * - * Retrieves the size of the cursor of a #ClutterText actor. - * - * Return value: the size of the cursor, in pixels - */ -guint -clutter_text_get_cursor_size (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), DEFAULT_CURSOR_SIZE); - - priv = clutter_text_get_instance_private (self); - return priv->cursor_size; -} - -/** - * clutter_text_set_password_char: - * @self: a #ClutterText - * @wc: a Unicode character, or 0 to unset the password character - * - * Sets the character to use in place of the actual text in a - * password text actor. - * - * If @wc is 0 the text will be displayed as it is entered in the - * #ClutterText actor. - */ -void -clutter_text_set_password_char (ClutterText *self, - gunichar wc) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - if (priv->password_char != wc) - { - priv->password_char = wc; - - clutter_text_dirty_cache (self); - clutter_actor_queue_relayout (CLUTTER_ACTOR (self)); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_PASSWORD_CHAR]); - } -} - -/** - * clutter_text_get_password_char: - * @self: a #ClutterText - * - * Retrieves the character to use in place of the actual text - * as set by [method@Text.set_password_char]. - * - * Return value: a Unicode character or 0 if the password - * character is not set - */ -gunichar -clutter_text_get_password_char (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), 0); - - priv = clutter_text_get_instance_private (self); - return priv->password_char; -} - -/** - * clutter_text_set_max_length: - * @self: a #ClutterText - * @max: the maximum number of characters allowed in the text actor; 0 - * to disable or -1 to set the length of the current string - * - * Sets the maximum allowed length of the contents of the actor. If the - * current contents are longer than the given length, then they will be - * truncated to fit. - */ -void -clutter_text_set_max_length (ClutterText *self, - gint max) -{ - g_return_if_fail (CLUTTER_IS_TEXT (self)); - clutter_text_buffer_set_max_length (get_buffer (self), max); -} - -/** - * clutter_text_get_max_length: - * @self: a #ClutterText - * - * Gets the maximum length of text that can be set into a text actor. - * - * See [method@Text.set_max_length]. - * - * Return value: the maximum number of characters. - */ -gint -clutter_text_get_max_length (ClutterText *self) -{ - g_return_val_if_fail (CLUTTER_IS_TEXT (self), 0); - - return clutter_text_buffer_get_max_length (get_buffer (self)); -} - -static void -clutter_text_real_insert_text (ClutterText *self, - guint start_pos, - const gchar *chars, - guint n_chars) -{ - gsize n_bytes; - - n_bytes = g_utf8_offset_to_pointer (chars, n_chars) - chars; - - /* - * insert-text is emitted here instead of as part of a - * buffer_inserted_text() callback because that should be emitted - * before the buffer changes, while ClutterTextBuffer::deleted-text - * is emitter after. See BG#722220 for more info. - */ - g_signal_emit (self, text_signals[INSERT_TEXT], 0, chars, - n_bytes, &start_pos); - - /* - * The actual insertion from the buffer. This will end firing the - * following signal handlers: buffer_inserted_text(), - * buffer_notify_text(), buffer_notify_max_length() - */ - clutter_text_buffer_insert_text (get_buffer (self), start_pos, chars, n_chars); -} - -/** - * clutter_text_insert_unichar: - * @self: a #ClutterText - * @wc: a Unicode character - * - * Inserts @wc at the current cursor position of a - * #ClutterText actor. - */ -void -clutter_text_insert_unichar (ClutterText *self, - gunichar wc) -{ - ClutterTextPrivate *priv; - GString *new; - - priv = clutter_text_get_instance_private (self); - - new = g_string_new (""); - g_string_append_unichar (new, wc); - - clutter_text_real_insert_text (self, priv->position, new->str, 1); - - g_string_free (new, TRUE); -} - - -/** - * clutter_text_insert_text: - * @self: a #ClutterText - * @text: the text to be inserted - * @position: the position of the insertion, or -1 - * - * Inserts @text into a [class@Actor] at the given position. - * - * If @position is a negative number, the text will be appended - * at the end of the current contents of the #ClutterText. - * - * The position is expressed in characters, not in bytes. - */ -void -clutter_text_insert_text (ClutterText *self, - const gchar *text, - gssize position) -{ - g_return_if_fail (CLUTTER_IS_TEXT (self)); - g_return_if_fail (text != NULL); - - clutter_text_real_insert_text (self, position, text, g_utf8_strlen (text, -1)); -} - -static -void clutter_text_real_delete_text (ClutterText *self, - gssize start_pos, - gssize end_pos) -{ - /* - * delete-text is emitted here instead of as part of a - * buffer_deleted_text() callback because that should be emitted - * before the buffer changes, while ClutterTextBuffer::deleted-text - * is emitter after. See BG#722220 for more info. - */ - g_signal_emit (self, text_signals[DELETE_TEXT], 0, start_pos, end_pos); - - /* - * The actual deletion from the buffer. This will end firing the - * following signal handlers: buffer_deleted_text(), - * buffer_notify_text(), buffer_notify_max_length() - */ - clutter_text_buffer_delete_text (get_buffer (self), start_pos, end_pos - start_pos); -} - - - -/** - * clutter_text_delete_text: - * @self: a #ClutterText - * @start_pos: starting position - * @end_pos: ending position - * - * Deletes the text inside a #ClutterText actor between @start_pos - * and @end_pos. - * - * The starting and ending positions are expressed in characters, - * not in bytes. - */ -void -clutter_text_delete_text (ClutterText *self, - gssize start_pos, - gssize end_pos) -{ - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - clutter_text_real_delete_text (self, start_pos, end_pos); -} - -/** - * clutter_text_delete_chars: - * @self: a #ClutterText - * @n_chars: the number of characters to delete - * - * Deletes @n_chars inside a #ClutterText actor, starting from the - * current cursor position. - * - * Somewhat awkwardly, the cursor position is decremented by the same - * number of characters you've deleted. - */ -void -clutter_text_delete_chars (ClutterText *self, - guint n_chars) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - clutter_text_real_delete_text (self, priv->position, priv->position + n_chars); - - if (priv->position > 0) - clutter_text_set_cursor_position (self, priv->position - n_chars); -} - -/** - * clutter_text_get_chars: - * @self: a #ClutterText - * @start_pos: start of text, in characters - * @end_pos: end of text, in characters - * - * Retrieves the contents of the #ClutterText actor between - * @start_pos and @end_pos, but not including @end_pos. - * - * The positions are specified in characters, not in bytes. - * - * Return value: a newly allocated string with the contents of - * the text actor between the specified positions. Use [func@GLib.free] - * to free the resources when done - */ -gchar * -clutter_text_get_chars (ClutterText *self, - gssize start_pos, - gssize end_pos) -{ - gint start_index, end_index; - guint n_chars; - const gchar *text; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), NULL); - - n_chars = clutter_text_buffer_get_length (get_buffer (self)); - text = clutter_text_buffer_get_text (get_buffer (self)); - - if (end_pos < 0) - end_pos = n_chars; - - start_pos = MIN (n_chars, start_pos); - end_pos = MIN (n_chars, end_pos); - - start_index = g_utf8_offset_to_pointer (text, start_pos) - text; - end_index = g_utf8_offset_to_pointer (text, end_pos) - text; - - return g_strndup (text + start_index, end_index - start_index); -} - -/** - * clutter_text_set_single_line_mode: - * @self: a #ClutterText - * @single_line: whether to enable single line mode - * - * Sets whether a #ClutterText actor should be in single line mode - * or not. Only editable `ClutterText`s can be in single line - * mode. - * - * A text actor in single line mode will not wrap text and will clip - * the visible area to the predefined size. The contents of the - * text actor will scroll to display the end of the text if its length - * is bigger than the allocated width. - * - * When setting the single line mode the [property@Text:activatable] - * property is also set as a side effect. Instead of entering a new - * line character, the text actor will emit the [signal@Text::activate] - * signal. - */ -void -clutter_text_set_single_line_mode (ClutterText *self, - gboolean single_line) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - if (priv->single_line_mode != single_line) - { - g_object_freeze_notify (G_OBJECT (self)); - - priv->single_line_mode = single_line; - - if (priv->single_line_mode) - { - priv->activatable = TRUE; - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ACTIVATABLE]); - } - - clutter_text_dirty_cache (self); - clutter_actor_queue_relayout (CLUTTER_ACTOR (self)); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SINGLE_LINE_MODE]); - - g_object_thaw_notify (G_OBJECT (self)); - } -} - -/** - * clutter_text_get_single_line_mode: - * @self: a #ClutterText - * - * Retrieves whether the #ClutterText actor is in single line mode. - * - * Return value: %TRUE if the #ClutterText actor is in single line mode - */ -gboolean -clutter_text_get_single_line_mode (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), FALSE); - - priv = clutter_text_get_instance_private (self); - return priv->single_line_mode; -} - -/** - * clutter_text_set_preedit_string: - * @self: a #ClutterText - * @preedit_str: (allow-none): the pre-edit string, or %NULL to unset it - * @preedit_attrs: (allow-none): the pre-edit string attributes - * @cursor_pos: the cursor position for the pre-edit string - * - * Sets, or unsets, the pre-edit string. This function is useful - * for input methods to display a string (with eventual specific - * Pango attributes) before it is entered inside the #ClutterText - * buffer. - * - * The preedit string and attributes are ignored if the #ClutterText - * actor is not editable. - * - * This function should not be used by applications - */ -void -clutter_text_set_preedit_string (ClutterText *self, - const gchar *preedit_str, - PangoAttrList *preedit_attrs, - guint cursor_pos) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - g_free (priv->preedit_str); - priv->preedit_str = NULL; - - if (priv->preedit_attrs != NULL) - { - pango_attr_list_unref (priv->preedit_attrs); - priv->preedit_attrs = NULL; - } - - priv->preedit_n_chars = 0; - priv->preedit_cursor_pos = 0; - - if (preedit_str == NULL || *preedit_str == '\0') - priv->preedit_set = FALSE; - else - { - priv->preedit_str = g_strdup (preedit_str); - - if (priv->preedit_str != NULL) - priv->preedit_n_chars = g_utf8_strlen (priv->preedit_str, -1); - else - priv->preedit_n_chars = 0; - - if (preedit_attrs != NULL) - priv->preedit_attrs = pango_attr_list_ref (preedit_attrs); - - priv->preedit_cursor_pos = - CLAMP (cursor_pos, 0, priv->preedit_n_chars); - - priv->preedit_set = TRUE; - } - - clutter_text_queue_redraw_or_relayout (self); -} - - -/** - * clutter_text_get_layout_offsets: - * @self: a #ClutterText - * @x: (out): location to store X offset of layout, or %NULL - * @y: (out): location to store Y offset of layout, or %NULL - * - * Obtains the coordinates where the #ClutterText will draw the [class@Pango.Layout] - * representing the text. - */ -void -clutter_text_get_layout_offsets (ClutterText *self, - gint *x, - gint *y) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - - if (x != NULL) - *x = priv->text_logical_x; - - if (y != NULL) - *y = priv->text_logical_y; -} - -/** - * clutter_text_get_cursor_rect: - * @self: a #ClutterText - * @rect: (out caller-allocates): return location of a #ClutterRect - * - * Retrieves the rectangle that contains the cursor. - * - * The coordinates of the rectangle's origin are in actor-relative - * coordinates. - */ -void -clutter_text_get_cursor_rect (ClutterText *self, - graphene_rect_t *rect) -{ - float inverse_scale; - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - g_return_if_fail (rect != NULL); - - inverse_scale = 1.f / clutter_actor_get_resource_scale (CLUTTER_ACTOR (self)); - priv = clutter_text_get_instance_private (self); - - graphene_rect_scale (&priv->cursor_rect, - inverse_scale, - inverse_scale, - rect); -} - -void -clutter_text_set_input_hints (ClutterText *self, - ClutterInputContentHintFlags hints) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - priv->input_hints = hints; - - if (clutter_input_focus_is_focused (priv->input_focus)) - clutter_input_focus_set_content_hints (priv->input_focus, hints); - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_INPUT_HINTS]); -} - -ClutterInputContentHintFlags -clutter_text_get_input_hints (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), 0); - - priv = clutter_text_get_instance_private (self); - return priv->input_hints; -} - -void -clutter_text_set_input_purpose (ClutterText *self, - ClutterInputContentPurpose purpose) -{ - ClutterTextPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXT (self)); - - priv = clutter_text_get_instance_private (self); - priv->input_purpose = purpose; - - if (clutter_input_focus_is_focused (priv->input_focus)) - clutter_input_focus_set_content_purpose (priv->input_focus, purpose); - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_INPUT_PURPOSE]); -} - -ClutterInputContentPurpose -clutter_text_get_input_purpose (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), 0); - - priv = clutter_text_get_instance_private (self); - return priv->input_purpose; -} - -gboolean -clutter_text_has_preedit (ClutterText *self) -{ - ClutterTextPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TEXT (self), FALSE); - - priv = clutter_text_get_instance_private (self); - return priv->preedit_set; -} diff --git a/mutter/clutter/clutter/clutter-text.h b/mutter/clutter/clutter/clutter-text.h deleted file mode 100644 index d69b461..0000000 --- a/mutter/clutter/clutter/clutter-text.h +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2008 Intel Corporation. - * - * Authored By: Øyvind Kolås - * Emmanuele Bassi - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-actor.h" -#include "clutter/clutter-text-buffer.h" -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_TEXT (clutter_text_get_type ()) - -/** - * ClutterTextClass: - * @text_changed: class handler for the #ClutterText::text-changed signal - * @activate: class handler for the #ClutterText::activate signal - * @cursor_changed: class handler for the #ClutterText::cursor-changed signal - * - * The #ClutterTextClass struct contains only private data. - */ -struct _ClutterTextClass -{ - /*< private >*/ - ClutterActorClass parent_class; - - /*< public >*/ - /* signals, not vfuncs */ - void (* text_changed) (ClutterText *self); - void (* activate) (ClutterText *self); - void (* cursor_changed) (ClutterText *self); -}; - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterText, - clutter_text, - CLUTTER, TEXT, - ClutterActor) - -CLUTTER_EXPORT -ClutterActor * clutter_text_new (void); -CLUTTER_EXPORT -ClutterActor * clutter_text_new_full (const gchar *font_name, - const gchar *text, - const ClutterColor *color); -CLUTTER_EXPORT -ClutterActor * clutter_text_new_with_text (const gchar *font_name, - const gchar *text); -CLUTTER_EXPORT -ClutterActor * clutter_text_new_with_buffer (ClutterTextBuffer *buffer); -CLUTTER_EXPORT -ClutterTextBuffer * clutter_text_get_buffer (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_buffer (ClutterText *self, - ClutterTextBuffer *buffer); -CLUTTER_EXPORT -const gchar * clutter_text_get_text (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_text (ClutterText *self, - const gchar *text); -CLUTTER_EXPORT -void clutter_text_set_markup (ClutterText *self, - const gchar *markup); -CLUTTER_EXPORT -void clutter_text_set_color (ClutterText *self, - const ClutterColor *color); -CLUTTER_EXPORT -void clutter_text_get_color (ClutterText *self, - ClutterColor *color); -CLUTTER_EXPORT -void clutter_text_set_font_name (ClutterText *self, - const gchar *font_name); -CLUTTER_EXPORT -const gchar * clutter_text_get_font_name (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_font_description (ClutterText *self, - PangoFontDescription *font_desc); -CLUTTER_EXPORT -PangoFontDescription *clutter_text_get_font_description (ClutterText *self); - -CLUTTER_EXPORT -void clutter_text_set_ellipsize (ClutterText *self, - PangoEllipsizeMode mode); -CLUTTER_EXPORT -PangoEllipsizeMode clutter_text_get_ellipsize (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_line_wrap (ClutterText *self, - gboolean line_wrap); -CLUTTER_EXPORT -gboolean clutter_text_get_line_wrap (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_line_wrap_mode (ClutterText *self, - PangoWrapMode wrap_mode); -CLUTTER_EXPORT -PangoWrapMode clutter_text_get_line_wrap_mode (ClutterText *self); -CLUTTER_EXPORT -PangoLayout * clutter_text_get_layout (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_attributes (ClutterText *self, - PangoAttrList *attrs); -CLUTTER_EXPORT -PangoAttrList * clutter_text_get_attributes (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_use_markup (ClutterText *self, - gboolean setting); -CLUTTER_EXPORT -gboolean clutter_text_get_use_markup (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_line_alignment (ClutterText *self, - PangoAlignment alignment); -CLUTTER_EXPORT -PangoAlignment clutter_text_get_line_alignment (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_justify (ClutterText *self, - gboolean justify); -CLUTTER_EXPORT -gboolean clutter_text_get_justify (ClutterText *self); - -CLUTTER_EXPORT -void clutter_text_insert_unichar (ClutterText *self, - gunichar wc); -CLUTTER_EXPORT -void clutter_text_delete_chars (ClutterText *self, - guint n_chars); -CLUTTER_EXPORT -void clutter_text_insert_text (ClutterText *self, - const gchar *text, - gssize position); -CLUTTER_EXPORT -void clutter_text_delete_text (ClutterText *self, - gssize start_pos, - gssize end_pos); -CLUTTER_EXPORT -gchar * clutter_text_get_chars (ClutterText *self, - gssize start_pos, - gssize end_pos); -CLUTTER_EXPORT -void clutter_text_set_editable (ClutterText *self, - gboolean editable); -CLUTTER_EXPORT -gboolean clutter_text_get_editable (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_activatable (ClutterText *self, - gboolean activatable); -CLUTTER_EXPORT -gboolean clutter_text_get_activatable (ClutterText *self); - -CLUTTER_EXPORT -gint clutter_text_get_cursor_position (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_cursor_position (ClutterText *self, - gint position); -CLUTTER_EXPORT -void clutter_text_set_cursor_visible (ClutterText *self, - gboolean cursor_visible); -CLUTTER_EXPORT -gboolean clutter_text_get_cursor_visible (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_cursor_color (ClutterText *self, - const ClutterColor *color); -CLUTTER_EXPORT -void clutter_text_get_cursor_color (ClutterText *self, - ClutterColor *color); -CLUTTER_EXPORT -void clutter_text_set_cursor_size (ClutterText *self, - gint size); -CLUTTER_EXPORT -guint clutter_text_get_cursor_size (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_get_cursor_rect (ClutterText *self, - graphene_rect_t *rect); -CLUTTER_EXPORT -void clutter_text_set_selectable (ClutterText *self, - gboolean selectable); -CLUTTER_EXPORT -gboolean clutter_text_get_selectable (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_selection_bound (ClutterText *self, - gint selection_bound); -CLUTTER_EXPORT -gint clutter_text_get_selection_bound (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_selection (ClutterText *self, - gssize start_pos, - gssize end_pos); -CLUTTER_EXPORT -gchar * clutter_text_get_selection (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_selection_color (ClutterText *self, - const ClutterColor *color); -CLUTTER_EXPORT -void clutter_text_get_selection_color (ClutterText *self, - ClutterColor *color); -CLUTTER_EXPORT -gboolean clutter_text_delete_selection (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_password_char (ClutterText *self, - gunichar wc); -CLUTTER_EXPORT -gunichar clutter_text_get_password_char (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_max_length (ClutterText *self, - gint max); -CLUTTER_EXPORT -gint clutter_text_get_max_length (ClutterText *self); -CLUTTER_EXPORT -void clutter_text_set_single_line_mode (ClutterText *self, - gboolean single_line); -CLUTTER_EXPORT -gboolean clutter_text_get_single_line_mode (ClutterText *self); - -CLUTTER_EXPORT -void clutter_text_set_selected_text_color (ClutterText *self, - const ClutterColor *color); -CLUTTER_EXPORT -void clutter_text_get_selected_text_color (ClutterText *self, - ClutterColor *color); - -CLUTTER_EXPORT -gboolean clutter_text_activate (ClutterText *self); -CLUTTER_EXPORT -gint clutter_text_coords_to_position (ClutterText *self, - gfloat x, - gfloat y); -CLUTTER_EXPORT -gboolean clutter_text_position_to_coords (ClutterText *self, - gint position, - gfloat *x, - gfloat *y, - gfloat *line_height); - -CLUTTER_EXPORT -void clutter_text_set_preedit_string (ClutterText *self, - const gchar *preedit_str, - PangoAttrList *preedit_attrs, - guint cursor_pos); - -CLUTTER_EXPORT -void clutter_text_get_layout_offsets (ClutterText *self, - gint *x, - gint *y); - -CLUTTER_EXPORT -void clutter_text_set_input_hints (ClutterText *self, - ClutterInputContentHintFlags hints); -CLUTTER_EXPORT -void clutter_text_set_input_purpose (ClutterText *self, - ClutterInputContentPurpose purpose); -CLUTTER_EXPORT -ClutterInputContentHintFlags clutter_text_get_input_hints (ClutterText *self); -CLUTTER_EXPORT -ClutterInputContentPurpose clutter_text_get_input_purpose (ClutterText *self); - -CLUTTER_EXPORT -gboolean clutter_text_has_preedit (ClutterText *self); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-texture-content.c b/mutter/clutter/clutter/clutter-texture-content.c deleted file mode 100644 index 1ce8e5d..0000000 --- a/mutter/clutter/clutter/clutter-texture-content.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive image' library. - * - * Copyright (C) 2012 Intel Corporation. - * Copyright (C) 2021 Robert Mader. - * - * 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 . - * - * Author: - * Emmanuele Bassi - * Robert Mader - */ - -#include "config.h" - -#include "clutter/clutter-texture-content.h" - -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-content-private.h" -#include "clutter/clutter-paint-node.h" - -struct _ClutterTextureContent -{ - GObject parent_instance; - - CoglTexture *texture; -}; - -static void clutter_content_iface_init (ClutterContentInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (ClutterTextureContent, clutter_texture_content, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT, - clutter_content_iface_init)) - -static void -clutter_texture_content_finalize (GObject *gobject) -{ - ClutterTextureContent *texture_content = CLUTTER_TEXTURE_CONTENT (gobject); - - g_clear_object (&texture_content->texture); - - G_OBJECT_CLASS (clutter_texture_content_parent_class)->finalize (gobject); -} - -static void -clutter_texture_content_class_init (ClutterTextureContentClass *klass) -{ - G_OBJECT_CLASS (klass)->finalize = clutter_texture_content_finalize; -} - -static void -clutter_texture_content_init (ClutterTextureContent *texture_content) -{ -} - -static void -clutter_texture_content_paint_content (ClutterContent *content, - ClutterActor *actor, - ClutterPaintNode *root, - ClutterPaintContext *paint_context) -{ - ClutterTextureContent *texture_content = CLUTTER_TEXTURE_CONTENT (content); - ClutterPaintNode *node; - - node = clutter_actor_create_texture_paint_node (actor, - texture_content->texture); - clutter_paint_node_set_static_name (node, "Texture Content"); - clutter_paint_node_add_child (root, node); - clutter_paint_node_unref (node); -} - -static gboolean -clutter_texture_content_get_preferred_size (ClutterContent *content, - float *width, - float *height) -{ - ClutterTextureContent *texture_content = CLUTTER_TEXTURE_CONTENT (content); - - if (width != NULL) - *width = cogl_texture_get_width (texture_content->texture); - - if (height != NULL) - *height = cogl_texture_get_height (texture_content->texture); - - return TRUE; -} - -static void -clutter_content_iface_init (ClutterContentInterface *iface) -{ - iface->get_preferred_size = clutter_texture_content_get_preferred_size; - iface->paint_content = clutter_texture_content_paint_content; -} - -/** - * clutter_texture_content_new_from_texture: - * @texture: a #CoglTexture - * @clip: (nullable): A clipping rectangle - * - * Creates a new [class@TextureContent] instance for @texture, taking an - * internal reference to @texture. - * - * If you change the contents of the [class@Cogl.Texture] you will need - * to manually invalidate the @texture_content with [method@Content.invalidate] - * in order to update the actors using @texture_content as their content. - * - * Return value: (transfer full): the newly created #ClutterTextureContent instance. - * Use [method@GObject.Object.unref] when done. - */ -ClutterContent * -clutter_texture_content_new_from_texture (CoglTexture *texture, - MtkRectangle *clip) -{ - ClutterTextureContent *texture_content; - CoglContext *cogl_context = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - - g_return_val_if_fail (texture != NULL, NULL); - - texture_content = g_object_new (CLUTTER_TYPE_TEXTURE_CONTENT, NULL); - - if (clip) - { - texture_content->texture = cogl_sub_texture_new (cogl_context, - texture, - clip->x, - clip->y, - clip->width, - clip->height); - } - else - { - texture_content->texture = g_object_ref (texture); - } - - return CLUTTER_CONTENT (texture_content); -} - -/** - * clutter_texture_content_get_texture: - * @texture_content: a #ClutterTextureContent - * - * Retrieves a pointer to the [class@Cogl.Texture] used by @texture_content. - * - * If you change the contents of the returned [class@Cogl.Texture] you will need - * to manually invalidate the @texture_content with [method@Content.invalidate] - * in order to update the actors using @texture_content as their content. - * - * Return value: (transfer none): a pointer to the [class@Cogl.Texture] - */ -CoglTexture * -clutter_texture_content_get_texture (ClutterTextureContent *texture_content) -{ - g_return_val_if_fail (CLUTTER_IS_TEXTURE_CONTENT (texture_content), NULL); - - return texture_content->texture; -} diff --git a/mutter/clutter/clutter/clutter-texture-content.h b/mutter/clutter/clutter/clutter-texture-content.h deleted file mode 100644 index f9313ce..0000000 --- a/mutter/clutter/clutter/clutter-texture-content.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive image' library. - * - * Copyright (C) 2012 Intel Corporation. - * Copyright (C) 2021 Robert Mader. - * - * 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 . - * - * Author: - * Emmanuele Bassi - * Robert Mader - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl.h" -#include "clutter/clutter-types.h" -#include "mtk/mtk.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_TEXTURE_CONTENT (clutter_texture_content_get_type ()) -CLUTTER_EXPORT -G_DECLARE_FINAL_TYPE (ClutterTextureContent, clutter_texture_content, - CLUTTER, TEXTURE_CONTENT, GObject) - -CLUTTER_EXPORT -ClutterContent * clutter_texture_content_new_from_texture (CoglTexture *texture, - MtkRectangle *clip); - -CLUTTER_EXPORT -CoglTexture * clutter_texture_content_get_texture (ClutterTextureContent *texture_content); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-timeline-private.h b/mutter/clutter/clutter/clutter-timeline-private.h deleted file mode 100644 index f01a2d0..0000000 --- a/mutter/clutter/clutter/clutter-timeline-private.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By: Emmanuele Bassi - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -void _clutter_timeline_advance (ClutterTimeline *timeline, - int64_t tick_time); -void _clutter_timeline_do_tick (ClutterTimeline *timeline, - int64_t tick_time); diff --git a/mutter/clutter/clutter/clutter-timeline.c b/mutter/clutter/clutter/clutter-timeline.c deleted file mode 100644 index 75bf68f..0000000 --- a/mutter/clutter/clutter/clutter-timeline.c +++ /dev/null @@ -1,2594 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * 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 . - */ - -/** - * ClutterTimeline: - * - * A class for time-based events - * - * #ClutterTimeline is a base class for managing time-based event that cause - * Clutter to redraw a stage, such as animations. - * - * Each #ClutterTimeline instance has a duration: once a timeline has been - * started, using [method@Timeline.start], it will emit a signal that can - * be used to update the state of the actors. - * - * It is important to note that #ClutterTimeline is not a generic API for - * calling closures after an interval; each Timeline is tied into a frame - * clock used to drive the frame cycle. If you need to schedule a closure - * after an interval, see [func@threads_add_timeout] instead. - * - * Users of #ClutterTimeline should connect to the [signal@Timeline::new-frame] - * signal, which is emitted each time a timeline is advanced during the maste - * clock iteration. The [signal@Timeline::new-frame] signal provides the time - * elapsed since the beginning of the timeline, in milliseconds. A normalized - * progress value can be obtained by calling [method@Timeline.get_progress]. - * By using [method@Timeline.get_delta] it is possible to obtain the wallclock - * time elapsed since the last emission of the [signal@Timeline::new-frame] - * signal. - * - * Initial state can be set up by using the [signal@Timeline::started] signal, - * while final state can be set up by using the [signal@Timeline::stopped] - * signal. The #ClutterTimeline guarantees the emission of at least a single - * [signal@Timeline::new-frame] signal, as well as the emission of the - * [signal@Timeline::completed] signal every time the #ClutterTimeline reaches - * its [property@Timeline:duration]. - * - * It is possible to connect to specific points in the timeline progress by - * adding markers using [method@Timeline.add_marker_at_time] and connecting - * to the [signal@Timeline::marker-reached] signal. - * - * Timelines can be made to loop once they reach the end of their duration, by - * using clutter_timeline_set_repeat_count(); a looping timeline will still - * emit the [signal@Timeline::completed] signal once it reaches the end of its - * duration at each repeat. If you want to be notified of the end of the last - * repeat, use the [signal@Timeline::stopped] signal. - * - * Timelines have a [property@Timeline:direction]: the default direction is - * %CLUTTER_TIMELINE_FORWARD, and goes from 0 to the duration; it is possible - * to change the direction to %CLUTTER_TIMELINE_BACKWARD, and have the timeline - * go from the duration to 0. The direction can be automatically reversed - * when reaching completion by using the [property@Timeline:auto-reverse] property. - * - * Timelines are used in the Clutter animation framework by classes like - * [class@Transition]. - */ - -#include "config.h" - -#include "clutter/clutter-timeline.h" - -#include "clutter/clutter-actor-private.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-easing.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-frame-clock.h" -#include "clutter/clutter-main.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-mutter.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-timeline-private.h" - -typedef struct _ClutterTimelinePrivate -{ - ClutterTimelineDirection direction; - - ClutterFrameClock *custom_frame_clock; - ClutterFrameClock *frame_clock; - ClutterActor *frame_clock_actor; - gulong frame_clock_actor_stage_views_handler_id; - - ClutterActor *actor; - gulong actor_destroy_handler_id; - gulong actor_stage_views_handler_id; - gulong stage_stage_views_handler_id; - ClutterActor *stage; - - guint delay_id; - - /* The total length in milliseconds of this timeline */ - guint duration; - guint delay; - - /* The current amount of elapsed time */ - gint64 elapsed_time; - - /* The elapsed time since the last frame was fired */ - gint64 msecs_delta; - - GHashTable *markers_by_name; - - /* Time we last advanced the elapsed time and showed a frame */ - gint64 last_frame_time; - - /* How many times the timeline should repeat */ - gint repeat_count; - - /* The number of times the timeline has repeated */ - gint current_repeat; - - ClutterTimelineProgressFunc progress_func; - gpointer progress_data; - GDestroyNotify progress_notify; - ClutterAnimationMode progress_mode; - - /* step() parameters */ - gint n_steps; - ClutterStepMode step_mode; - - /* cubic-bezier() parameters */ - graphene_point_t cb_1; - graphene_point_t cb_2; - - guint is_playing : 1; - - /* If we've just started playing and haven't yet gotten - * a tick from the frame clock - */ - guint waiting_first_tick : 1; - guint auto_reverse : 1; -} ClutterTimelinePrivate; - -typedef struct { - gchar *name; - GQuark quark; - - union { - guint msecs; - gdouble progress; - } data; - - guint is_relative : 1; -} TimelineMarker; - -enum -{ - PROP_0, - - PROP_ACTOR, - PROP_DELAY, - PROP_DURATION, - PROP_DIRECTION, - PROP_AUTO_REVERSE, - PROP_REPEAT_COUNT, - PROP_PROGRESS_MODE, - PROP_FRAME_CLOCK, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST] = { NULL, }; - -enum -{ - NEW_FRAME, - STARTED, - PAUSED, - COMPLETED, - MARKER_REACHED, - STOPPED, - - LAST_SIGNAL -}; - -static guint timeline_signals[LAST_SIGNAL] = { 0, }; - -static void update_frame_clock (ClutterTimeline *timeline); - - -G_DEFINE_TYPE_WITH_CODE (ClutterTimeline, clutter_timeline, G_TYPE_OBJECT, - G_ADD_PRIVATE (ClutterTimeline)) - -static TimelineMarker * -timeline_marker_new_time (const gchar *name, - guint msecs) -{ - TimelineMarker *marker = g_new0 (TimelineMarker, 1); - - marker->name = g_strdup (name); - marker->quark = g_quark_from_string (marker->name); - marker->is_relative = FALSE; - marker->data.msecs = msecs; - - return marker; -} - -static TimelineMarker * -timeline_marker_new_progress (const gchar *name, - gdouble progress) -{ - TimelineMarker *marker = g_new0 (TimelineMarker, 1); - - marker->name = g_strdup (name); - marker->quark = g_quark_from_string (marker->name); - marker->is_relative = TRUE; - marker->data.progress = CLAMP (progress, 0.0, 1.0); - - return marker; -} - -static void -timeline_marker_free (gpointer data) -{ - if (G_LIKELY (data)) - { - TimelineMarker *marker = data; - - g_free (marker->name); - g_free (marker); - } -} - -/*< private > - * clutter_timeline_add_marker_internal: - * @timeline: a #ClutterTimeline - * @marker: a TimelineMarker - * - * Adds @marker into the hash table of markers for @timeline. - * - * The TimelineMarker will either be added or, in case of collisions - * with another existing marker, freed. In any case, this function - * assumes the ownership of the passed @marker. - */ -static inline void -clutter_timeline_add_marker_internal (ClutterTimeline *timeline, - TimelineMarker *marker) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - TimelineMarker *old_marker; - - /* create the hash table that will hold the markers */ - if (G_UNLIKELY (priv->markers_by_name == NULL)) - priv->markers_by_name = g_hash_table_new_full (g_str_hash, g_str_equal, - NULL, - timeline_marker_free); - - old_marker = g_hash_table_lookup (priv->markers_by_name, marker->name); - if (old_marker != NULL) - { - guint msecs; - - if (old_marker->is_relative) - msecs = old_marker->data.progress * priv->duration; - else - msecs = old_marker->data.msecs; - - g_warning ("A marker named '%s' already exists at time %d", - old_marker->name, - msecs); - timeline_marker_free (marker); - return; - } - - g_hash_table_insert (priv->markers_by_name, marker->name, marker); -} - -static void -on_actor_destroyed (ClutterActor *actor, - ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - - g_clear_signal_handler (&priv->stage_stage_views_handler_id, priv->stage); - priv->actor = NULL; -} - -/** - * clutter_timeline_get_actor: - * @timeline: a #ClutterTimeline - * - * Get the actor the timeline is associated with. - * - * Returns: (transfer none): the associated #ClutterActor - */ -ClutterActor * -clutter_timeline_get_actor (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - - return priv->actor; -} - -static void -maybe_add_timeline (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - - if (!priv->frame_clock) - return; - - clutter_frame_clock_add_timeline (priv->frame_clock, timeline); -} - -static void -maybe_remove_timeline (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - - if (!priv->frame_clock) - return; - - clutter_frame_clock_remove_timeline (priv->frame_clock, timeline); -} - -static void -set_frame_clock_internal (ClutterTimeline *timeline, - ClutterFrameClock *frame_clock) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - - if (priv->frame_clock == frame_clock) - return; - - if (priv->frame_clock && priv->is_playing) - maybe_remove_timeline (timeline); - - g_set_object (&priv->frame_clock, frame_clock); - - g_object_notify_by_pspec (G_OBJECT (timeline), - obj_props[PROP_FRAME_CLOCK]); - - if (priv->is_playing) - maybe_add_timeline (timeline); -} - -static void -on_stage_stage_views_changed (ClutterActor *stage, - ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - - g_clear_signal_handler (&priv->stage_stage_views_handler_id, priv->stage); - priv->stage = NULL; - - update_frame_clock (timeline); -} - -static void -on_frame_clock_actor_stage_views_changed (ClutterActor *frame_clock_actor, - ClutterTimeline *timeline) -{ - update_frame_clock (timeline); -} - -static void -update_frame_clock (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - ClutterFrameClock *frame_clock = NULL; - ClutterActor *stage; - ClutterActor *frame_clock_actor; - - if (!priv->actor) - goto out; - - if (priv->frame_clock_actor) - { - g_clear_signal_handler (&priv->frame_clock_actor_stage_views_handler_id, - priv->frame_clock_actor); - g_clear_weak_pointer (&priv->frame_clock_actor); - } - - frame_clock = clutter_actor_pick_frame_clock (priv->actor, &frame_clock_actor); - if (frame_clock) - { - g_set_weak_pointer (&priv->frame_clock_actor, frame_clock_actor); - priv->frame_clock_actor_stage_views_handler_id = - g_signal_connect (frame_clock_actor, "stage-views-changed", - G_CALLBACK (on_frame_clock_actor_stage_views_changed), - timeline); - - g_clear_signal_handler (&priv->stage_stage_views_handler_id, priv->stage); - goto out; - } - - stage = clutter_actor_get_stage (priv->actor); - if (!stage) - { - if (priv->is_playing) - g_warning ("Timelines with detached actors are not supported. " - "%s in animation of duration %ums but not on stage.", - _clutter_actor_get_debug_name (priv->actor), - priv->duration); - goto out; - } - - if (priv->stage_stage_views_handler_id > 0) - goto out; - - priv->stage_stage_views_handler_id = - g_signal_connect (stage, "stage-views-changed", - G_CALLBACK (on_stage_stage_views_changed), - timeline); - priv->stage = stage; - -out: - set_frame_clock_internal (timeline, frame_clock); -} - -static void -on_actor_stage_views_changed (ClutterActor *actor, - ClutterTimeline *timeline) -{ - update_frame_clock (timeline); -} - -/** - * clutter_timeline_set_actor: - * @timeline: a #ClutterTimeline - * @actor: (nullable): a #ClutterActor - * - * Set the actor the timeline is associated with. - */ -void -clutter_timeline_set_actor (ClutterTimeline *timeline, - ClutterActor *actor) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - - g_return_if_fail (!actor || (actor && !priv->custom_frame_clock)); - - if (priv->actor) - { - g_clear_signal_handler (&priv->actor_destroy_handler_id, priv->actor); - g_clear_signal_handler (&priv->actor_stage_views_handler_id, priv->actor); - g_clear_signal_handler (&priv->stage_stage_views_handler_id, priv->stage); - priv->stage = NULL; - priv->actor = NULL; - } - - priv->actor = actor; - - if (priv->actor) - { - priv->actor_destroy_handler_id = - g_signal_connect (priv->actor, "destroy", - G_CALLBACK (on_actor_destroyed), - timeline); - priv->actor_stage_views_handler_id = - g_signal_connect (priv->actor, "stage-views-changed", - G_CALLBACK (on_actor_stage_views_changed), - timeline); - } - - update_frame_clock (timeline); -} - -void -clutter_timeline_cancel_delay (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - - g_clear_handle_id (&priv->delay_id, g_source_remove); -} - -/* Object */ - -static void -clutter_timeline_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterTimeline *timeline = CLUTTER_TIMELINE (object); - - switch (prop_id) - { - case PROP_ACTOR: - clutter_timeline_set_actor (timeline, g_value_get_object (value)); - break; - - case PROP_DELAY: - clutter_timeline_set_delay (timeline, g_value_get_uint (value)); - break; - - case PROP_DURATION: - clutter_timeline_set_duration (timeline, g_value_get_uint (value)); - break; - - case PROP_DIRECTION: - clutter_timeline_set_direction (timeline, g_value_get_enum (value)); - break; - - case PROP_AUTO_REVERSE: - clutter_timeline_set_auto_reverse (timeline, g_value_get_boolean (value)); - break; - - case PROP_REPEAT_COUNT: - clutter_timeline_set_repeat_count (timeline, g_value_get_int (value)); - break; - - case PROP_PROGRESS_MODE: - clutter_timeline_set_progress_mode (timeline, g_value_get_enum (value)); - break; - - case PROP_FRAME_CLOCK: - clutter_timeline_set_frame_clock (timeline, g_value_get_object (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_timeline_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterTimeline *timeline = CLUTTER_TIMELINE (object); - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - - switch (prop_id) - { - case PROP_ACTOR: - g_value_set_object (value, priv->actor); - break; - - case PROP_DELAY: - g_value_set_uint (value, priv->delay); - break; - - case PROP_DURATION: - g_value_set_uint (value, clutter_timeline_get_duration (timeline)); - break; - - case PROP_DIRECTION: - g_value_set_enum (value, priv->direction); - break; - - case PROP_AUTO_REVERSE: - g_value_set_boolean (value, priv->auto_reverse); - break; - - case PROP_REPEAT_COUNT: - g_value_set_int (value, priv->repeat_count); - break; - - case PROP_PROGRESS_MODE: - g_value_set_enum (value, priv->progress_mode); - break; - - case PROP_FRAME_CLOCK: - g_value_set_object (value, priv->frame_clock); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_timeline_finalize (GObject *object) -{ - ClutterTimeline *self = CLUTTER_TIMELINE (object); - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (self); - - if (priv->markers_by_name) - g_hash_table_destroy (priv->markers_by_name); - - if (priv->is_playing) - maybe_remove_timeline (self); - - g_clear_object (&priv->frame_clock); - - G_OBJECT_CLASS (clutter_timeline_parent_class)->finalize (object); -} - -static void -clutter_timeline_dispose (GObject *object) -{ - ClutterTimeline *self = CLUTTER_TIMELINE (object); - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (self); - - clutter_timeline_cancel_delay (self); - - if (priv->actor) - { - g_clear_signal_handler (&priv->actor_destroy_handler_id, priv->actor); - g_clear_signal_handler (&priv->actor_stage_views_handler_id, priv->actor); - g_clear_signal_handler (&priv->stage_stage_views_handler_id, priv->stage); - priv->actor = NULL; - } - - if (priv->frame_clock_actor) - { - g_clear_signal_handler (&priv->frame_clock_actor_stage_views_handler_id, - priv->frame_clock_actor); - g_clear_weak_pointer (&priv->frame_clock_actor); - } - - if (priv->progress_notify != NULL) - { - priv->progress_notify (priv->progress_data); - priv->progress_func = NULL; - priv->progress_data = NULL; - priv->progress_notify = NULL; - } - - G_OBJECT_CLASS (clutter_timeline_parent_class)->dispose (object); -} - -static void -clutter_timeline_class_init (ClutterTimelineClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - /** - * ClutterTimeline::actor: - * - * The actor the timeline is associated with. This will determine what frame - * clock will drive it. - */ - obj_props[PROP_ACTOR] = - g_param_spec_object ("actor", NULL, NULL, - CLUTTER_TYPE_ACTOR, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT); - /** - * ClutterTimeline:delay: - * - * A delay, in milliseconds, that should be observed by the - * timeline before actually starting. - */ - obj_props[PROP_DELAY] = - g_param_spec_uint ("delay", NULL, NULL, - 0, G_MAXUINT, - 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterTimeline:duration: - * - * Duration of the timeline in milliseconds, depending on the - * [property@Timeline:frame-clock] value. - */ - obj_props[PROP_DURATION] = - g_param_spec_uint ("duration", NULL, NULL, - 0, G_MAXUINT, - 1000, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterTimeline:direction: - * - * The direction of the timeline, either %CLUTTER_TIMELINE_FORWARD or - * %CLUTTER_TIMELINE_BACKWARD. - */ - obj_props[PROP_DIRECTION] = - g_param_spec_enum ("direction", NULL, NULL, - CLUTTER_TYPE_TIMELINE_DIRECTION, - CLUTTER_TIMELINE_FORWARD, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterTimeline:auto-reverse: - * - * If the direction of the timeline should be automatically reversed - * when reaching the end. - */ - obj_props[PROP_AUTO_REVERSE] = - g_param_spec_boolean ("auto-reverse", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterTimeline:repeat-count: - * - * Defines how many times the timeline should repeat. - * - * If the repeat count is 0, the timeline does not repeat. - * - * If the repeat count is set to -1, the timeline will repeat until it is - * stopped. - */ - obj_props[PROP_REPEAT_COUNT] = - g_param_spec_int ("repeat-count", NULL, NULL, - -1, G_MAXINT, - 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterTimeline:progress-mode: - * - * Controls the way a #ClutterTimeline computes the normalized progress. - */ - obj_props[PROP_PROGRESS_MODE] = - g_param_spec_enum ("progress-mode", NULL, NULL, - CLUTTER_TYPE_ANIMATION_MODE, - CLUTTER_LINEAR, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterTimeline:frame-clock: - * - * The frame clock driving the timeline. - */ - obj_props[PROP_FRAME_CLOCK] = - g_param_spec_object ("frame-clock", NULL, NULL, - CLUTTER_TYPE_FRAME_CLOCK, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT); - - object_class->dispose = clutter_timeline_dispose; - object_class->finalize = clutter_timeline_finalize; - object_class->set_property = clutter_timeline_set_property; - object_class->get_property = clutter_timeline_get_property; - g_object_class_install_properties (object_class, PROP_LAST, obj_props); - - /** - * ClutterTimeline::new-frame: - * @timeline: the timeline which received the signal - * @msecs: the elapsed time between 0 and duration - * - * The signal is emitted for each timeline running - * timeline before a new frame is drawn to give animations a chance - * to update the scene. - */ - timeline_signals[NEW_FRAME] = - g_signal_new (I_("new-frame"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterTimelineClass, new_frame), - NULL, NULL, NULL, - G_TYPE_NONE, - 1, G_TYPE_INT); - /** - * ClutterTimeline::completed: - * @timeline: the #ClutterTimeline which received the signal - * - * The signal is emitted when the timeline's - * elapsed time reaches the value of the [property@Timeline:duration] - * property. - * - * This signal will be emitted even if the #ClutterTimeline is set to be - * repeating. - * - * If you want to get notification on whether the #ClutterTimeline has - * been stopped or has finished its run, including its eventual repeats, - * you should use the [signal@Timeline::stopped] signal instead. - */ - timeline_signals[COMPLETED] = - g_signal_new (I_("completed"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterTimelineClass, completed), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - /** - * ClutterTimeline::started: - * @timeline: the #ClutterTimeline which received the signal - * - * The signal is emitted when the timeline starts its run. - * This might be as soon as [method@Timeline.start] is invoked or - * after the delay set in the [property@Timeline:delay] property has - * expired. - */ - timeline_signals[STARTED] = - g_signal_new (I_("started"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterTimelineClass, started), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - /** - * ClutterTimeline::paused: - * @timeline: the #ClutterTimeline which received the signal - * - * The signal is emitted when [method@Timeline.pause] is invoked. - */ - timeline_signals[PAUSED] = - g_signal_new (I_("paused"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterTimelineClass, paused), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - /** - * ClutterTimeline::marker-reached: - * @timeline: the #ClutterTimeline which received the signal - * @marker_name: the name of the marker reached - * @msecs: the elapsed time - * - * The signal is emitted each time a timeline - * reaches a marker set with [method@Timeline.add_marker_at_time]. - * - * This signal is detailed with the name of the marker as well, - * so it is possible to connect a callback to the [signal@Timeline::marker-reached] - * signal for a specific marker with: - * - * ```c - * clutter_timeline_add_marker_at_time (timeline, "foo", 500); - * clutter_timeline_add_marker_at_time (timeline, "bar", 750); - * - * g_signal_connect (timeline, "marker-reached", - * G_CALLBACK (each_marker_reached), NULL); - * g_signal_connect (timeline, "marker-reached::foo", - * G_CALLBACK (foo_marker_reached), NULL); - * g_signal_connect (timeline, "marker-reached::bar", - * G_CALLBACK (bar_marker_reached), NULL); - * ``` - * - * In the example, the first callback will be invoked for both - * the "foo" and "bar" marker, while the second and third callbacks - * will be invoked for the "foo" or "bar" markers, respectively. - */ - timeline_signals[MARKER_REACHED] = - g_signal_new (I_("marker-reached"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | - G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS, - G_STRUCT_OFFSET (ClutterTimelineClass, marker_reached), - NULL, NULL, - _clutter_marshal_VOID__STRING_INT, - G_TYPE_NONE, 2, - G_TYPE_STRING, - G_TYPE_INT); - /** - * ClutterTimeline::stopped: - * @timeline: the #ClutterTimeline that emitted the signal - * @is_finished: %TRUE if the signal was emitted at the end of the - * timeline. - * - * The signal is emitted when the timeline - * has been stopped, either because [method@Timeline.stop] has been - * called, or because it has been exhausted. - * - * This is different from the [signal@Timeline::completed] signal, - * which gets emitted after every repeat finishes. - * - * If the #ClutterTimeline has is marked as infinitely repeating, - * this signal will never be emitted. - */ - timeline_signals[STOPPED] = - g_signal_new (I_("stopped"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterTimelineClass, stopped), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - G_TYPE_BOOLEAN); -} - -static void -clutter_timeline_init (ClutterTimeline *self) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (self); - - priv->progress_mode = CLUTTER_LINEAR; - - /* default steps() parameters are 1, end */ - priv->n_steps = 1; - priv->step_mode = CLUTTER_STEP_MODE_END; - - /* default cubic-bezier() paramereters are (0, 0, 1, 1) */ - graphene_point_init (&priv->cb_1, 0, 0); - graphene_point_init (&priv->cb_2, 1, 1); -} - -struct CheckIfMarkerHitClosure -{ - ClutterTimeline *timeline; - ClutterTimelineDirection direction; - gint new_time; - gint duration; - gint delta; -}; - -static gboolean -have_passed_time (const struct CheckIfMarkerHitClosure *data, - gint msecs) -{ - /* Ignore markers that are outside the duration of the timeline */ - if (msecs < 0 || msecs > data->duration) - return FALSE; - - if (data->direction == CLUTTER_TIMELINE_FORWARD) - { - /* We need to special case when a marker is added at the - beginning of the timeline */ - if (msecs == 0 && - data->delta > 0 && - data->new_time - data->delta <= 0) - return TRUE; - - /* Otherwise it's just a simple test if the time is in range of - the previous time and the new time */ - return (msecs > data->new_time - data->delta && - msecs <= data->new_time); - } - else - { - /* We need to special case when a marker is added at the - end of the timeline */ - if (msecs == data->duration && - data->delta > 0 && - data->new_time + data->delta >= data->duration) - return TRUE; - - /* Otherwise it's just a simple test if the time is in range of - the previous time and the new time */ - return (msecs >= data->new_time && - msecs < data->new_time + data->delta); - } -} - -static void -check_if_marker_hit (const gchar *name, - TimelineMarker *marker, - struct CheckIfMarkerHitClosure *data) -{ - gint msecs; - - if (marker->is_relative) - msecs = (gdouble) data->duration * marker->data.progress; - else - msecs = marker->data.msecs; - - if (have_passed_time (data, msecs)) - { - CLUTTER_NOTE (SCHEDULER, "Marker '%s' reached", name); - - g_signal_emit (data->timeline, timeline_signals[MARKER_REACHED], - marker->quark, - name, - msecs); - } -} - -static void -check_markers (ClutterTimeline *timeline, - gint delta) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - struct CheckIfMarkerHitClosure data; - - /* shortcircuit here if we don't have any marker installed */ - if (priv->markers_by_name == NULL) - return; - - /* store the details of the timeline so that changing them in a - marker signal handler won't affect which markers are hit */ - data.timeline = timeline; - data.direction = priv->direction; - data.new_time = priv->elapsed_time; - data.duration = priv->duration; - data.delta = delta; - - g_hash_table_foreach (priv->markers_by_name, - (GHFunc) check_if_marker_hit, - &data); -} - -static void -emit_frame_signal (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - - COGL_TRACE_BEGIN_SCOPED (Emit, "Clutter::Timeline::emit_frame_signal()"); - - /* see bug https://bugzilla.gnome.org/show_bug.cgi?id=654066 */ - gint elapsed = (gint) priv->elapsed_time; - - CLUTTER_NOTE (SCHEDULER, "Emitting ::new-frame signal on timeline[%p]", timeline); - - g_signal_emit (timeline, timeline_signals[NEW_FRAME], 0, elapsed); -} - -static gboolean -is_complete (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - - return (priv->direction == CLUTTER_TIMELINE_FORWARD - ? priv->elapsed_time >= priv->duration - : priv->elapsed_time <= 0); -} - -static void -set_is_playing (ClutterTimeline *timeline, - gboolean is_playing) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - - is_playing = !!is_playing; - - if (is_playing == priv->is_playing) - return; - - priv->is_playing = is_playing; - - if (priv->is_playing) - { - priv->waiting_first_tick = TRUE; - priv->current_repeat = 0; - - maybe_add_timeline (timeline); - } - else - { - maybe_remove_timeline (timeline); - } -} - -static gboolean -clutter_timeline_do_frame (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - priv = clutter_timeline_get_instance_private (timeline); - - g_object_ref (timeline); - - CLUTTER_NOTE (SCHEDULER, "Timeline [%p] activated (elapsed time: %ld, " - "duration: %ld, msecs_delta: %ld)\n", - timeline, - (long) priv->elapsed_time, - (long) priv->duration, - (long) priv->msecs_delta); - - /* Advance time */ - if (priv->direction == CLUTTER_TIMELINE_FORWARD) - priv->elapsed_time += priv->msecs_delta; - else - priv->elapsed_time -= priv->msecs_delta; - - /* If we have not reached the end of the timeline: */ - if (!is_complete (timeline)) - { - /* Emit the signal */ - emit_frame_signal (timeline); - check_markers (timeline, priv->msecs_delta); - - g_object_unref (timeline); - - return priv->is_playing; - } - else - { - /* Handle loop or stop */ - ClutterTimelineDirection saved_direction = priv->direction; - gint elapsed_time_delta = priv->msecs_delta; - guint overflow_msecs = priv->elapsed_time; - gint end_msecs; - - /* Update the current elapsed time in case the signal handlers - * want to take a peek. If we clamp elapsed time, then we need - * to correpondingly reduce elapsed_time_delta to reflect the correct - * range of times */ - if (priv->direction == CLUTTER_TIMELINE_FORWARD) - { - elapsed_time_delta -= (priv->elapsed_time - priv->duration); - priv->elapsed_time = priv->duration; - } - else if (priv->direction == CLUTTER_TIMELINE_BACKWARD) - { - elapsed_time_delta -= -priv->elapsed_time; - priv->elapsed_time = 0; - } - - end_msecs = priv->elapsed_time; - - /* Emit the signal */ - emit_frame_signal (timeline); - check_markers (timeline, elapsed_time_delta); - - /* Did the signal handler modify the elapsed time? */ - if (priv->elapsed_time != end_msecs) - { - g_object_unref (timeline); - return TRUE; - } - - /* Note: If the new-frame signal handler paused the timeline - * on the last frame we will still go ahead and send the - * completed signal */ - CLUTTER_NOTE (SCHEDULER, - "Timeline [%p] completed (cur: %ld, tot: %ld)", - timeline, - (long) priv->elapsed_time, - (long) priv->msecs_delta); - - if (priv->is_playing && - (priv->repeat_count == 0 || - priv->repeat_count == priv->current_repeat)) - { - /* We stop the timeline now, so that the completed signal handler - * may choose to re-start the timeline - * - * XXX Perhaps we should do this earlier, and regardless of - * priv->repeat_count. Are we limiting the things that could be - * done in the above new-frame signal handler? - */ - set_is_playing (timeline, FALSE); - - g_signal_emit (timeline, timeline_signals[COMPLETED], 0); - g_signal_emit (timeline, timeline_signals[STOPPED], 0, TRUE); - } - else - g_signal_emit (timeline, timeline_signals[COMPLETED], 0); - - priv->current_repeat += 1; - - if (priv->auto_reverse) - { - /* :auto-reverse changes the direction of the timeline */ - if (priv->direction == CLUTTER_TIMELINE_FORWARD) - priv->direction = CLUTTER_TIMELINE_BACKWARD; - else - priv->direction = CLUTTER_TIMELINE_FORWARD; - - g_object_notify_by_pspec (G_OBJECT (timeline), - obj_props[PROP_DIRECTION]); - } - - /* Again check to see if the user has manually played with - * the elapsed time, before we finally stop or loop the timeline */ - - if (priv->elapsed_time != end_msecs && - !(/* Except allow changing time from 0 -> duration (or vice-versa) - since these are considered equivalent */ - (priv->elapsed_time == 0 && end_msecs == priv->duration) || - (priv->elapsed_time == priv->duration && end_msecs == 0) - )) - { - g_object_unref (timeline); - return TRUE; - } - - if (priv->repeat_count != 0) - { - /* We try and interpolate smoothly around a loop */ - if (saved_direction == CLUTTER_TIMELINE_FORWARD) - priv->elapsed_time = overflow_msecs - priv->duration; - else - priv->elapsed_time = priv->duration + overflow_msecs; - - /* Or if the direction changed, we try and bounce */ - if (priv->direction != saved_direction) - priv->elapsed_time = priv->duration - priv->elapsed_time; - - /* If we have overflowed then we are changing the elapsed - time without emitting the new frame signal so we need to - check for markers again */ - check_markers (timeline, - priv->direction == CLUTTER_TIMELINE_FORWARD - ? priv->elapsed_time - : priv->duration - priv->elapsed_time); - - g_object_unref (timeline); - return TRUE; - } - else - { - clutter_timeline_rewind (timeline); - - g_object_unref (timeline); - return FALSE; - } - } -} - -static gboolean -delay_timeout_func (gpointer data) -{ - ClutterTimeline *timeline = data; - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - - priv->delay_id = 0; - priv->msecs_delta = 0; - set_is_playing (timeline, TRUE); - - g_signal_emit (timeline, timeline_signals[STARTED], 0); - - return FALSE; -} - -/** - * clutter_timeline_start: - * @timeline: A #ClutterTimeline - * - * Starts the #ClutterTimeline playing. - **/ -void -clutter_timeline_start (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - - priv = clutter_timeline_get_instance_private (timeline); - - if (priv->delay_id || priv->is_playing) - return; - - if (priv->duration == 0) - return; - - g_warn_if_fail ((priv->actor && clutter_actor_get_stage (priv->actor)) || - priv->frame_clock); - - if (priv->delay) - priv->delay_id = clutter_threads_add_timeout (priv->delay, - delay_timeout_func, - timeline); - else - { - priv->msecs_delta = 0; - set_is_playing (timeline, TRUE); - - g_signal_emit (timeline, timeline_signals[STARTED], 0); - } -} - -/** - * clutter_timeline_pause: - * @timeline: A #ClutterTimeline - * - * Pauses the #ClutterTimeline on current frame - **/ -void -clutter_timeline_pause (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - - priv = clutter_timeline_get_instance_private (timeline); - - clutter_timeline_cancel_delay (timeline); - - if (!priv->is_playing) - return; - - priv->msecs_delta = 0; - set_is_playing (timeline, FALSE); - - g_signal_emit (timeline, timeline_signals[PAUSED], 0); -} - -/** - * clutter_timeline_stop: - * @timeline: A #ClutterTimeline - * - * Stops the #ClutterTimeline and moves to frame 0 - **/ -void -clutter_timeline_stop (ClutterTimeline *timeline) -{ - gboolean was_playing; - ClutterTimelinePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - - /* we check the is_playing here because pause() will return immediately - * if the timeline wasn't playing, so we don't know if it was actually - * stopped, and yet we still don't want to emit a ::stopped signal if - * the timeline was not playing in the first place. - */ - - priv = clutter_timeline_get_instance_private (timeline); - was_playing = priv->is_playing; - - clutter_timeline_pause (timeline); - clutter_timeline_rewind (timeline); - - if (was_playing) - g_signal_emit (timeline, timeline_signals[STOPPED], 0, FALSE); -} - -/** - * clutter_timeline_rewind: - * @timeline: A #ClutterTimeline - * - * Rewinds #ClutterTimeline to the first frame if its direction is - * %CLUTTER_TIMELINE_FORWARD and the last frame if it is - * %CLUTTER_TIMELINE_BACKWARD. - */ -void -clutter_timeline_rewind (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - - priv = clutter_timeline_get_instance_private (timeline); - - if (priv->direction == CLUTTER_TIMELINE_FORWARD) - clutter_timeline_advance (timeline, 0); - else if (priv->direction == CLUTTER_TIMELINE_BACKWARD) - clutter_timeline_advance (timeline, priv->duration); -} - -/** - * clutter_timeline_skip: - * @timeline: A #ClutterTimeline - * @msecs: Amount of time to skip - * - * Advance timeline by the requested time in milliseconds - */ -void -clutter_timeline_skip (ClutterTimeline *timeline, - guint msecs) -{ - ClutterTimelinePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - - priv = clutter_timeline_get_instance_private (timeline); - - if (priv->direction == CLUTTER_TIMELINE_FORWARD) - { - priv->elapsed_time += msecs; - - if (priv->elapsed_time > priv->duration) - priv->elapsed_time = 1; - } - else if (priv->direction == CLUTTER_TIMELINE_BACKWARD) - { - priv->elapsed_time -= msecs; - - if (priv->elapsed_time < 1) - priv->elapsed_time = priv->duration - 1; - } - - priv->msecs_delta = 0; -} - -/** - * clutter_timeline_advance: - * @timeline: A #ClutterTimeline - * @msecs: Time to advance to - * - * Advance timeline to the requested point. The point is given as a - * time in milliseconds since the timeline started. - * - * The @timeline will not emit the [signal@Timeline::new-frame] - * signal for the given time. The first [signal@Timeline::new-frame] signal - * after the call to [method@Timeline.advance] will be emit the skipped markers. - */ -void -clutter_timeline_advance (ClutterTimeline *timeline, - guint msecs) -{ - ClutterTimelinePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - - priv = clutter_timeline_get_instance_private (timeline); - - priv->elapsed_time = CLAMP (msecs, 0, priv->duration); -} - -/** - * clutter_timeline_get_elapsed_time: - * @timeline: A #ClutterTimeline - * - * Request the current time position of the timeline. - * - * Return value: current elapsed time in milliseconds. - */ -guint -clutter_timeline_get_elapsed_time (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0); - - priv = clutter_timeline_get_instance_private (timeline); - - return priv->elapsed_time; -} - -/** - * clutter_timeline_is_playing: - * @timeline: A #ClutterTimeline - * - * Queries state of a #ClutterTimeline. - * - * Return value: %TRUE if timeline is currently playing - */ -gboolean -clutter_timeline_is_playing (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), FALSE); - - priv = clutter_timeline_get_instance_private (timeline); - - return priv->is_playing; -} - -/** - * clutter_timeline_new_for_actor: - * @actor: The #ClutterActor the timeline is associated with - * @duration_ms: Duration of the timeline in milliseconds - * - * Creates a new #ClutterTimeline with a duration of @duration milli seconds. - * - * Return value: the newly created #ClutterTimeline instance. Use - * [method@GObject.Object.unref] when done using it - */ -ClutterTimeline * -clutter_timeline_new_for_actor (ClutterActor *actor, - unsigned int duration_ms) -{ - return g_object_new (CLUTTER_TYPE_TIMELINE, - "duration", duration_ms, - "actor", actor, - NULL); -} - -/** - * clutter_timeline_new_for_frame_clock: - * @frame_clock: The #ClutterFrameClock the timeline is driven by - * @duration_ms: Duration of the timeline in milliseconds - * - * Creates a new #ClutterTimeline with a duration of @duration_ms milli seconds. - * - * Return value: the newly created #ClutterTimeline instance. Use - * [method@GObject.Object.unref] when done using it - */ -ClutterTimeline * -clutter_timeline_new_for_frame_clock (ClutterFrameClock *frame_clock, - unsigned int duration_ms) -{ - return g_object_new (CLUTTER_TYPE_TIMELINE, - "duration", duration_ms, - "frame-clock", frame_clock, - NULL); -} - -/** - * clutter_timeline_get_delay: - * @timeline: a #ClutterTimeline - * - * Retrieves the delay set using [method@Timeline.set_delay]. - * - * Return value: the delay in milliseconds. - */ -guint -clutter_timeline_get_delay (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0); - - priv = clutter_timeline_get_instance_private (timeline); - - return priv->delay; -} - -/** - * clutter_timeline_set_delay: - * @timeline: a #ClutterTimeline - * @msecs: delay in milliseconds - * - * Sets the delay, in milliseconds, before @timeline should start. - */ -void -clutter_timeline_set_delay (ClutterTimeline *timeline, - guint msecs) -{ - ClutterTimelinePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - - priv = clutter_timeline_get_instance_private (timeline); - - if (priv->delay != msecs) - { - priv->delay = msecs; - g_object_notify_by_pspec (G_OBJECT (timeline), obj_props[PROP_DELAY]); - } -} - -/** - * clutter_timeline_get_duration: - * @timeline: a #ClutterTimeline - * - * Retrieves the duration of a #ClutterTimeline in milliseconds. - * See [method@Timeline.set_duration]. - * - * Return value: the duration of the timeline, in milliseconds. - */ -guint -clutter_timeline_get_duration (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0); - - priv = clutter_timeline_get_instance_private (timeline); - - return priv->duration; -} - -/** - * clutter_timeline_set_duration: - * @timeline: a #ClutterTimeline - * @msecs: duration of the timeline in milliseconds - * - * Sets the duration of the timeline, in milliseconds. The speed - * of the timeline depends on the [property@Timeline:frame-clock] setting. - */ -void -clutter_timeline_set_duration (ClutterTimeline *timeline, - guint msecs) -{ - ClutterTimelinePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - g_return_if_fail (msecs > 0); - - priv = clutter_timeline_get_instance_private (timeline); - - if (priv->duration != msecs) - { - priv->duration = msecs; - - g_object_notify_by_pspec (G_OBJECT (timeline), obj_props[PROP_DURATION]); - } -} - -/** - * clutter_timeline_get_progress: - * @timeline: a #ClutterTimeline - * - * The position of the timeline in a normalized [-1, 2] interval. - * - * The return value of this function is determined by the progress - * mode set using [method@Timeline.set_progress_mode], or by the - * progress function set using [method@Timeline.set_progress_func]. - * - * Return value: the normalized current position in the timeline. - */ -gdouble -clutter_timeline_get_progress (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0.0); - - priv = clutter_timeline_get_instance_private (timeline); - - /* short-circuit linear progress */ - if (priv->progress_func == NULL) - return (gdouble) priv->elapsed_time / (gdouble) priv->duration; - else - return priv->progress_func (timeline, - (gdouble) priv->elapsed_time, - (gdouble) priv->duration, - priv->progress_data); -} - -/** - * clutter_timeline_get_direction: - * @timeline: a #ClutterTimeline - * - * Retrieves the direction of the timeline set with - * [method@Timeline.set_direction]. - * - * Return value: the direction of the timeline - */ -ClutterTimelineDirection -clutter_timeline_get_direction (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), - CLUTTER_TIMELINE_FORWARD); - - priv = clutter_timeline_get_instance_private (timeline); - - return priv->direction; -} - -/** - * clutter_timeline_set_direction: - * @timeline: a #ClutterTimeline - * @direction: the direction of the timeline - * - * Sets the direction of @timeline, either %CLUTTER_TIMELINE_FORWARD or - * %CLUTTER_TIMELINE_BACKWARD. - */ -void -clutter_timeline_set_direction (ClutterTimeline *timeline, - ClutterTimelineDirection direction) -{ - ClutterTimelinePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - - priv = clutter_timeline_get_instance_private (timeline); - - if (priv->direction != direction) - { - priv->direction = direction; - - if (priv->elapsed_time == 0) - priv->elapsed_time = priv->duration; - - g_object_notify_by_pspec (G_OBJECT (timeline), obj_props[PROP_DIRECTION]); - } -} - -/** - * clutter_timeline_get_delta: - * @timeline: a #ClutterTimeline - * - * Retrieves the amount of time elapsed since the last - * [signal@Timeline::new-frame] signal. - * - * This function is only useful inside handlers for the ::new-frame - * signal, and its behaviour is undefined if the timeline is not - * playing. - * - * Return value: the amount of time in milliseconds elapsed since the - * last frame - */ -guint -clutter_timeline_get_delta (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0); - - priv = clutter_timeline_get_instance_private (timeline); - if (!clutter_timeline_is_playing (timeline)) - return 0; - - return priv->msecs_delta; -} - -void -_clutter_timeline_advance (ClutterTimeline *timeline, - gint64 tick_time) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - - g_object_ref (timeline); - - CLUTTER_NOTE (SCHEDULER, - "Timeline [%p] advancing (cur: %ld, tot: %ld, " - "tick_time: %lu)", - timeline, - (long) priv->elapsed_time, - (long) priv->msecs_delta, - (long) tick_time); - - priv->msecs_delta = tick_time; - priv->is_playing = TRUE; - - clutter_timeline_do_frame (timeline); - - priv->is_playing = FALSE; - - g_object_unref (timeline); -} - -/*< private > - * clutter_timeline_do_tick - * @timeline: a #ClutterTimeline - * @tick_time: time of advance - * - * Advances @timeline based on the time passed in @tick_time. This - * function is called by the frame clock and ideally passes the next - * presentation time in which consequences of our timeline will be visible. - * Otherwise an estimate using the current monotonic time is also acceptable. - * The @timeline will use this interval to emit the #ClutterTimeline::new-frame - * signal and eventually skip frames. - */ -void -_clutter_timeline_do_tick (ClutterTimeline *timeline, - gint64 tick_time) -{ - ClutterTimelinePrivate *priv; - - COGL_TRACE_BEGIN_SCOPED (DoTick, "Clutter::Timeline::do_tick()"); - - priv = clutter_timeline_get_instance_private (timeline); - - CLUTTER_NOTE (SCHEDULER, - "Timeline [%p] ticked (elapsed_time: %ld, msecs_delta: %ld, " - "last_frame_time: %ld, tick_time: %ld)", - timeline, - (long) priv->elapsed_time, - (long) priv->msecs_delta, - (long) priv->last_frame_time, - (long) tick_time); - - /* Check the is_playing variable before performing the timeline tick. - * This is necessary, as if a timeline is stopped in response to a - * frame clock generated signal of a different timeline, this code can - * still be reached. - */ - if (!priv->is_playing) - return; - - if (priv->waiting_first_tick) - { - priv->last_frame_time = tick_time; - priv->msecs_delta = 0; - priv->waiting_first_tick = FALSE; - clutter_timeline_do_frame (timeline); - } - else - { - gint64 msecs; - - msecs = tick_time - priv->last_frame_time; - - /* if the clock rolled back between ticks we need to - * account for it; the best course of action, since the - * clock roll back can happen by any arbitrary amount - * of milliseconds, is to drop a frame here - */ - if (msecs < 0) - { - priv->last_frame_time = tick_time; - return; - } - - if (msecs != 0) - { - /* Avoid accumulating error */ - priv->last_frame_time += msecs; - priv->msecs_delta = msecs; - clutter_timeline_do_frame (timeline); - } - } -} - -/** - * clutter_timeline_add_marker: - * @timeline: a #ClutterTimeline - * @marker_name: the unique name for this marker - * @progress: the normalized value of the position of the martke - * - * Adds a named marker that will be hit when the timeline has reached - * the specified @progress. - * - * Markers are unique string identifiers for a given position on the - * timeline. Once @timeline reaches the given @progress of its duration, - * if will emit a [signal@Timeline::marker-reached] signal for each marker - * attached to that particular point. - * - * A marker can be removed with [method@Timeline.remove_marker]. The - * timeline can be advanced to a marker using - * [method@Timeline.advance_to_marker]. - * - * See also: [method@Timeline.add_marker_at_time] - */ -void -clutter_timeline_add_marker (ClutterTimeline *timeline, - const gchar *marker_name, - gdouble progress) -{ - TimelineMarker *marker; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - g_return_if_fail (marker_name != NULL); - - marker = timeline_marker_new_progress (marker_name, progress); - clutter_timeline_add_marker_internal (timeline, marker); -} - -/** - * clutter_timeline_add_marker_at_time: - * @timeline: a #ClutterTimeline - * @marker_name: the unique name for this marker - * @msecs: position of the marker in milliseconds - * - * Adds a named marker that will be hit when the timeline has been - * running for @msecs milliseconds. - * - * Markers are unique string identifiers for a given position on the - * timeline. Once @timeline reaches the given @msecs, it will emit - * a [signal@Timeline::marker-reached] signal for each marker attached to that position. - * - * A marker can be removed with [method@Timeline.remove_marker]. The - * timeline can be advanced to a marker using - * [method@Timeline.advance_to_marker]. - * - * See also: [method@Timeline.add_marker] - */ -void -clutter_timeline_add_marker_at_time (ClutterTimeline *timeline, - const gchar *marker_name, - guint msecs) -{ - TimelineMarker *marker; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - g_return_if_fail (marker_name != NULL); - g_return_if_fail (msecs <= clutter_timeline_get_duration (timeline)); - - marker = timeline_marker_new_time (marker_name, msecs); - clutter_timeline_add_marker_internal (timeline, marker); -} - -struct CollectMarkersClosure -{ - guint duration; - guint msecs; - GArray *markers; -}; - -static void -collect_markers (const gchar *key, - TimelineMarker *marker, - struct CollectMarkersClosure *data) -{ - guint msecs; - - if (marker->is_relative) - msecs = marker->data.progress * data->duration; - else - msecs = marker->data.msecs; - - if (msecs == data->msecs) - { - gchar *name_copy = g_strdup (key); - g_array_append_val (data->markers, name_copy); - } -} - -/** - * clutter_timeline_list_markers: - * @timeline: a #ClutterTimeline - * @msecs: the time to check, or -1 - * @n_markers: the number of markers returned - * - * Retrieves the list of markers at time @msecs. If @msecs is a - * negative integer, all the markers attached to @timeline will be - * returned. - * - * Return value: (transfer full) (array zero-terminated=1 length=n_markers): - * a newly allocated, %NULL terminated string array containing the names - * of the markers. Use [func@GLib.strfreev] when done. - */ -gchar ** -clutter_timeline_list_markers (ClutterTimeline *timeline, - gint msecs, - gsize *n_markers) -{ - ClutterTimelinePrivate *priv; - gchar **retval = NULL; - gsize i; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL); - - priv = clutter_timeline_get_instance_private (timeline); - - if (G_UNLIKELY (priv->markers_by_name == NULL)) - { - if (n_markers) - *n_markers = 0; - - return NULL; - } - - if (msecs < 0) - { - GList *markers, *l; - - markers = g_hash_table_get_keys (priv->markers_by_name); - retval = g_new0 (gchar*, g_list_length (markers) + 1); - - for (i = 0, l = markers; l != NULL; i++, l = l->next) - retval[i] = g_strdup (l->data); - - g_list_free (markers); - } - else - { - struct CollectMarkersClosure data; - - data.duration = priv->duration; - data.msecs = msecs; - data.markers = g_array_new (TRUE, FALSE, sizeof (gchar *)); - - g_hash_table_foreach (priv->markers_by_name, - (GHFunc) collect_markers, - &data); - - i = data.markers->len; - retval = (gchar **) (void *) g_array_free (data.markers, FALSE); - } - - if (n_markers) - *n_markers = i; - - return retval; -} - -/** - * clutter_timeline_advance_to_marker: - * @timeline: a #ClutterTimeline - * @marker_name: the name of the marker - * - * Advances @timeline to the time of the given @marker_name. - * - * Like [method@Timeline.advance], this function will not - * emit the [signal@Timeline::new-frame] for the time where @marker_name - * is set, nor it will emit [signal@Timeline::marker-reached] for - * @marker_name. - */ -void -clutter_timeline_advance_to_marker (ClutterTimeline *timeline, - const gchar *marker_name) -{ - ClutterTimelinePrivate *priv; - TimelineMarker *marker; - guint msecs; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - g_return_if_fail (marker_name != NULL); - - priv = clutter_timeline_get_instance_private (timeline); - - if (G_UNLIKELY (priv->markers_by_name == NULL)) - { - g_warning ("No marker named '%s' found.", marker_name); - return; - } - - marker = g_hash_table_lookup (priv->markers_by_name, marker_name); - if (marker == NULL) - { - g_warning ("No marker named '%s' found.", marker_name); - return; - } - - if (marker->is_relative) - msecs = marker->data.progress * priv->duration; - else - msecs = marker->data.msecs; - - clutter_timeline_advance (timeline, msecs); -} - -/** - * clutter_timeline_remove_marker: - * @timeline: a #ClutterTimeline - * @marker_name: the name of the marker to remove - * - * Removes @marker_name, if found, from @timeline. - */ -void -clutter_timeline_remove_marker (ClutterTimeline *timeline, - const gchar *marker_name) -{ - ClutterTimelinePrivate *priv; - TimelineMarker *marker; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - g_return_if_fail (marker_name != NULL); - - priv = clutter_timeline_get_instance_private (timeline); - - if (G_UNLIKELY (priv->markers_by_name == NULL)) - { - g_warning ("No marker named '%s' found.", marker_name); - return; - } - - marker = g_hash_table_lookup (priv->markers_by_name, marker_name); - if (!marker) - { - g_warning ("No marker named '%s' found.", marker_name); - return; - } - - /* this will take care of freeing the marker as well */ - g_hash_table_remove (priv->markers_by_name, marker_name); -} - -/** - * clutter_timeline_has_marker: - * @timeline: a #ClutterTimeline - * @marker_name: the name of the marker - * - * Checks whether @timeline has a marker set with the given name. - * - * Return value: %TRUE if the marker was found - */ -gboolean -clutter_timeline_has_marker (ClutterTimeline *timeline, - const gchar *marker_name) -{ - ClutterTimelinePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), FALSE); - g_return_val_if_fail (marker_name != NULL, FALSE); - - priv = clutter_timeline_get_instance_private (timeline); - if (G_UNLIKELY (priv->markers_by_name == NULL)) - return FALSE; - - return NULL != g_hash_table_lookup (priv->markers_by_name, - marker_name); -} - -/** - * clutter_timeline_set_auto_reverse: - * @timeline: a #ClutterTimeline - * @reverse: %TRUE if the @timeline should reverse the direction - * - * Sets whether @timeline should reverse the direction after the - * emission of the [signal@Timeline::completed] signal. - * - * Setting the [property@Timeline:auto-reverse] property to %TRUE is the - * equivalent of connecting a callback to the [signal@Timeline::completed] - * signal and changing the direction of the timeline from that callback; - * for instance, this code: - * - * ```c - * static void - * reverse_timeline (ClutterTimeline *timeline) - * { - * ClutterTimelineDirection dir = clutter_timeline_get_direction (timeline); - * - * if (dir == CLUTTER_TIMELINE_FORWARD) - * dir = CLUTTER_TIMELINE_BACKWARD; - * else - * dir = CLUTTER_TIMELINE_FORWARD; - * - * clutter_timeline_set_direction (timeline, dir); - * } - * ... - * timeline = clutter_timeline_new_for_actor (some_actor, 1000); - * clutter_timeline_set_repeat_count (timeline, -1); - * g_signal_connect (timeline, "completed", - * G_CALLBACK (reverse_timeline), - * NULL); - * ``` - * - * can be effectively replaced by: - * - * ```c - * timeline = clutter_timeline_new_for_actor (some_actor, 1000); - * clutter_timeline_set_repeat_count (timeline, -1); - * clutter_timeline_set_auto_reverse (timeline); - * ``` - */ -void -clutter_timeline_set_auto_reverse (ClutterTimeline *timeline, - gboolean reverse) -{ - ClutterTimelinePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - - reverse = !!reverse; - - priv = clutter_timeline_get_instance_private (timeline); - - if (priv->auto_reverse != reverse) - { - priv->auto_reverse = reverse; - - g_object_notify_by_pspec (G_OBJECT (timeline), - obj_props[PROP_AUTO_REVERSE]); - } -} - -/** - * clutter_timeline_get_auto_reverse: - * @timeline: a #ClutterTimeline - * - * Retrieves the value set by [method@Timeline.set_auto_reverse]. - * - * Return value: %TRUE if the timeline should automatically reverse, and - * %FALSE otherwise - */ -gboolean -clutter_timeline_get_auto_reverse (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), FALSE); - - priv = clutter_timeline_get_instance_private (timeline); - - return priv->auto_reverse; -} - -/** - * clutter_timeline_set_repeat_count: - * @timeline: a #ClutterTimeline - * @count: the number of times the timeline should repeat - * - * Sets the number of times the @timeline should repeat. - * - * If @count is 0, the timeline never repeats. - * - * If @count is -1, the timeline will always repeat until - * it's stopped. - */ -void -clutter_timeline_set_repeat_count (ClutterTimeline *timeline, - gint count) -{ - ClutterTimelinePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - g_return_if_fail (count >= -1); - - priv = clutter_timeline_get_instance_private (timeline); - - if (priv->repeat_count != count) - { - priv->repeat_count = count; - - g_object_notify_by_pspec (G_OBJECT (timeline), - obj_props[PROP_REPEAT_COUNT]); - } -} - -/** - * clutter_timeline_get_repeat_count: - * @timeline: a #ClutterTimeline - * - * Retrieves the number set using [method@Timeline.set_repeat_count]. - * - * Return value: the number of repeats - */ -gint -clutter_timeline_get_repeat_count (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0); - - priv = clutter_timeline_get_instance_private (timeline); - - return priv->repeat_count; -} - -/** - * clutter_timeline_set_progress_func: - * @timeline: a #ClutterTimeline - * @func: (scope notified) (allow-none): a progress function, or %NULL - * @data: (closure): data to pass to @func - * @notify: a function to be called when the progress function is removed - * or the timeline is disposed - * - * Sets a custom progress function for @timeline. The progress function will - * be called by [method@Timeline.get_progress] and will be used to compute - * the progress value based on the elapsed time and the total duration of the - * timeline. - * - * If @func is not %NULL, the [property@Timeline:progress-mode] property will - * be set to %CLUTTER_CUSTOM_MODE. - * - * If @func is %NULL, any previously set progress function will be unset, and - * the [property@Timeline:progress-mode] property will be set to %CLUTTER_LINEAR. - */ -void -clutter_timeline_set_progress_func (ClutterTimeline *timeline, - ClutterTimelineProgressFunc func, - gpointer data, - GDestroyNotify notify) -{ - ClutterTimelinePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - - priv = clutter_timeline_get_instance_private (timeline); - - if (priv->progress_notify != NULL) - priv->progress_notify (priv->progress_data); - - priv->progress_func = func; - priv->progress_data = data; - priv->progress_notify = notify; - - if (priv->progress_func != NULL) - priv->progress_mode = CLUTTER_CUSTOM_MODE; - else - priv->progress_mode = CLUTTER_LINEAR; - - g_object_notify_by_pspec (G_OBJECT (timeline), obj_props[PROP_PROGRESS_MODE]); -} - -static gdouble -clutter_timeline_progress_func (ClutterTimeline *timeline, - gdouble elapsed, - gdouble duration, - gpointer user_data G_GNUC_UNUSED) -{ - ClutterTimelinePrivate *priv = - clutter_timeline_get_instance_private (timeline); - - /* parametrized easing functions need to be handled separately */ - switch (priv->progress_mode) - { - case CLUTTER_STEPS: - if (priv->step_mode == CLUTTER_STEP_MODE_START) - return clutter_ease_steps_start (elapsed, duration, priv->n_steps); - else if (priv->step_mode == CLUTTER_STEP_MODE_END) - return clutter_ease_steps_end (elapsed, duration, priv->n_steps); - else - g_assert_not_reached (); - break; - - case CLUTTER_STEP_START: - return clutter_ease_steps_start (elapsed, duration, 1); - - case CLUTTER_STEP_END: - return clutter_ease_steps_end (elapsed, duration, 1); - - case CLUTTER_CUBIC_BEZIER: - return clutter_ease_cubic_bezier (elapsed, duration, - priv->cb_1.x, priv->cb_1.y, - priv->cb_2.x, priv->cb_2.y); - - case CLUTTER_EASE: - return clutter_ease_cubic_bezier (elapsed, duration, - 0.25, 0.1, 0.25, 1.0); - - case CLUTTER_EASE_IN: - return clutter_ease_cubic_bezier (elapsed, duration, - 0.42, 0.0, 1.0, 1.0); - - case CLUTTER_EASE_OUT: - return clutter_ease_cubic_bezier (elapsed, duration, - 0.0, 0.0, 0.58, 1.0); - - case CLUTTER_EASE_IN_OUT: - return clutter_ease_cubic_bezier (elapsed, duration, - 0.42, 0.0, 0.58, 1.0); - - default: - break; - } - - return clutter_easing_for_mode (priv->progress_mode, elapsed, duration); -} - -/** - * clutter_timeline_set_progress_mode: - * @timeline: a #ClutterTimeline - * @mode: the progress mode, as a #ClutterAnimationMode - * - * Sets the progress function using a value from the [enum@AnimationMode] - * enumeration. The @mode cannot be %CLUTTER_CUSTOM_MODE or bigger than - * %CLUTTER_ANIMATION_LAST. - */ -void -clutter_timeline_set_progress_mode (ClutterTimeline *timeline, - ClutterAnimationMode mode) -{ - ClutterTimelinePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - g_return_if_fail (mode < CLUTTER_ANIMATION_LAST); - g_return_if_fail (mode != CLUTTER_CUSTOM_MODE); - - priv = clutter_timeline_get_instance_private (timeline); - - if (priv->progress_mode == mode) - return; - - if (priv->progress_notify != NULL) - priv->progress_notify (priv->progress_data); - - priv->progress_mode = mode; - - /* short-circuit linear progress */ - if (priv->progress_mode != CLUTTER_LINEAR) - priv->progress_func = clutter_timeline_progress_func; - else - priv->progress_func = NULL; - - priv->progress_data = NULL; - priv->progress_notify = NULL; - - g_object_notify_by_pspec (G_OBJECT (timeline), obj_props[PROP_PROGRESS_MODE]); -} - -/** - * clutter_timeline_get_progress_mode: - * @timeline: a #ClutterTimeline - * - * Retrieves the progress mode set using [method@Timeline.set_progress_mode] - * or [method@Timeline.set_progress_func]. - * - * Return value: a #ClutterAnimationMode - */ -ClutterAnimationMode -clutter_timeline_get_progress_mode (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), CLUTTER_LINEAR); - - priv = clutter_timeline_get_instance_private (timeline); - - return priv->progress_mode; -} - -/** - * clutter_timeline_get_duration_hint: - * @timeline: a #ClutterTimeline - * - * Retrieves the full duration of the @timeline, taking into account the - * current value of the [property@Timeline:repeat-count] property. - * - * If the [property@Timeline:repeat-count] property is set to -1, this function - * will return %G_MAXINT64. - * - * The returned value is to be considered a hint, and it's only valid - * as long as the @timeline hasn't been changed. - * - * Return value: the full duration of the #ClutterTimeline - */ -gint64 -clutter_timeline_get_duration_hint (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0); - - priv = clutter_timeline_get_instance_private (timeline); - - if (priv->repeat_count == 0) - return priv->duration; - else if (priv->repeat_count < 0) - return G_MAXINT64; - else - return priv->repeat_count * priv->duration; -} - -/** - * clutter_timeline_get_current_repeat: - * @timeline: a #ClutterTimeline - * - * Retrieves the current repeat for a timeline. - * - * Repeats start at 0. - * - * Return value: the current repeat - */ -gint -clutter_timeline_get_current_repeat (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0); - - priv = clutter_timeline_get_instance_private (timeline); - - return priv->current_repeat; -} - -/** - * clutter_timeline_set_step_progress: - * @timeline: a #ClutterTimeline - * @n_steps: the number of steps - * @step_mode: whether the change should happen at the start - * or at the end of the step - * - * Sets the [property@Timeline:progress-mode] of the @timeline to %CLUTTER_STEPS - * and provides the parameters of the step function. - */ -void -clutter_timeline_set_step_progress (ClutterTimeline *timeline, - gint n_steps, - ClutterStepMode step_mode) -{ - ClutterTimelinePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - g_return_if_fail (n_steps > 0); - - priv = clutter_timeline_get_instance_private (timeline); - - if (priv->progress_mode == CLUTTER_STEPS && - priv->n_steps == n_steps && - priv->step_mode == step_mode) - return; - - priv->n_steps = n_steps; - priv->step_mode = step_mode; - clutter_timeline_set_progress_mode (timeline, CLUTTER_STEPS); -} - -/** - * clutter_timeline_get_step_progress: - * @timeline: a #ClutterTimeline - * @n_steps: (out): return location for the number of steps, or %NULL - * @step_mode: (out): return location for the value change policy, - * or %NULL - * - * Retrieves the parameters of the step progress mode used by @timeline. - * - * Return value: %TRUE if the @timeline is using a step progress - * mode, and %FALSE otherwise - */ -gboolean -clutter_timeline_get_step_progress (ClutterTimeline *timeline, - gint *n_steps, - ClutterStepMode *step_mode) -{ - ClutterTimelinePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), FALSE); - - priv = clutter_timeline_get_instance_private (timeline); - - if (!(priv->progress_mode == CLUTTER_STEPS || - priv->progress_mode == CLUTTER_STEP_START || - priv->progress_mode == CLUTTER_STEP_END)) - return FALSE; - - if (n_steps != NULL) - *n_steps = priv->n_steps; - - if (step_mode != NULL) - *step_mode = priv->step_mode; - - return TRUE; -} - -/** - * clutter_timeline_set_cubic_bezier_progress: - * @timeline: a #ClutterTimeline - * @c_1: the first control point for the cubic bezier - * @c_2: the second control point for the cubic bezier - * - * Sets the [property@Timeline:progress-mode] of @timeline - * to %CLUTTER_CUBIC_BEZIER, and sets the two control - * points for the cubic bezier. - * - * The cubic bezier curve is between (0, 0) and (1, 1). The X coordinate - * of the two control points must be in the [ 0, 1 ] range, while the - * Y coordinate of the two control points can exceed this range. - */ -void -clutter_timeline_set_cubic_bezier_progress (ClutterTimeline *timeline, - const graphene_point_t *c_1, - const graphene_point_t *c_2) -{ - ClutterTimelinePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - g_return_if_fail (c_1 != NULL && c_2 != NULL); - - priv = clutter_timeline_get_instance_private (timeline); - - priv->cb_1 = *c_1; - priv->cb_2 = *c_2; - - /* ensure the range on the X coordinate */ - priv->cb_1.x = CLAMP (priv->cb_1.x, 0.f, 1.f); - priv->cb_2.x = CLAMP (priv->cb_2.x, 0.f, 1.f); - - clutter_timeline_set_progress_mode (timeline, CLUTTER_CUBIC_BEZIER); -} - -/** - * clutter_timeline_get_cubic_bezier_progress: - * @timeline: a #ClutterTimeline - * @c_1: (out caller-allocates): return location for the first control - * point of the cubic bezier, or %NULL - * @c_2: (out caller-allocates): return location for the second control - * point of the cubic bezier, or %NULL - * - * Retrieves the control points for the cubic bezier progress mode. - * - * Return value: %TRUE if the @timeline is using a cubic bezier progress - * more, and %FALSE otherwise - */ -gboolean -clutter_timeline_get_cubic_bezier_progress (ClutterTimeline *timeline, - graphene_point_t *c_1, - graphene_point_t *c_2) -{ - ClutterTimelinePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), FALSE); - - priv = clutter_timeline_get_instance_private (timeline); - if (!(priv->progress_mode == CLUTTER_CUBIC_BEZIER || - priv->progress_mode == CLUTTER_EASE || - priv->progress_mode == CLUTTER_EASE_IN || - priv->progress_mode == CLUTTER_EASE_OUT || - priv->progress_mode == CLUTTER_EASE_IN_OUT)) - return FALSE; - - if (c_1 != NULL) - *c_1 = priv->cb_1; - - if (c_2 != NULL) - *c_2 = priv->cb_2; - - return TRUE; -} - -/** - * clutter_timeline_get_frame_clock: (skip) - */ -ClutterFrameClock * -clutter_timeline_get_frame_clock (ClutterTimeline *timeline) -{ - ClutterTimelinePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL); - - priv = clutter_timeline_get_instance_private (timeline); - - return priv->frame_clock; -} - -void -clutter_timeline_set_frame_clock (ClutterTimeline *timeline, - ClutterFrameClock *frame_clock) -{ - ClutterTimelinePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - - priv = clutter_timeline_get_instance_private (timeline); - - g_assert (!frame_clock || (frame_clock && !priv->actor)); - g_return_if_fail (!frame_clock || (frame_clock && !priv->actor)); - - priv->custom_frame_clock = frame_clock; - if (!priv->actor) - set_frame_clock_internal (timeline, frame_clock); -} diff --git a/mutter/clutter/clutter/clutter-timeline.h b/mutter/clutter/clutter/clutter-timeline.h deleted file mode 100644 index 4f78b39..0000000 --- a/mutter/clutter/clutter/clutter-timeline.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * 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 . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_TIMELINE (clutter_timeline_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterTimeline, - clutter_timeline, - CLUTTER, - TIMELINE, - GObject) - -/** - * ClutterTimelineProgressFunc: - * @timeline: a #ClutterTimeline - * @elapsed: the elapsed time, in milliseconds - * @total: the total duration of the timeline, in milliseconds, - * @user_data: data passed to the function - * - * A function for defining a custom progress. - * - * Return value: the progress, as a floating point value between -1.0 and 2.0. - */ -typedef gdouble (* ClutterTimelineProgressFunc) (ClutterTimeline *timeline, - gdouble elapsed, - gdouble total, - gpointer user_data); - - -/** - * ClutterTimelineClass: - * @started: class handler for the #ClutterTimeline::started signal - * @completed: class handler for the #ClutterTimeline::completed signal - * @paused: class handler for the #ClutterTimeline::paused signal - * @new_frame: class handler for the #ClutterTimeline::new-frame signal - * @marker_reached: class handler for the #ClutterTimeline::marker-reached signal - * @stopped: class handler for the #ClutterTimeline::stopped signal - * - * The #ClutterTimelineClass structure contains only private data - */ -struct _ClutterTimelineClass -{ - /*< private >*/ - GObjectClass parent_class; - - /*< public >*/ - void (*started) (ClutterTimeline *timeline); - void (*completed) (ClutterTimeline *timeline); - void (*paused) (ClutterTimeline *timeline); - - void (*new_frame) (ClutterTimeline *timeline, - gint msecs); - - void (*marker_reached) (ClutterTimeline *timeline, - const gchar *marker_name, - gint msecs); - void (*stopped) (ClutterTimeline *timeline, - gboolean is_finished); -}; - -CLUTTER_EXPORT -ClutterTimeline * clutter_timeline_new_for_actor (ClutterActor *actor, - unsigned int duration_ms); - -CLUTTER_EXPORT -ClutterTimeline * clutter_timeline_new_for_frame_clock (ClutterFrameClock *frame_clock, - unsigned int duration_ms); - -CLUTTER_EXPORT -ClutterActor * clutter_timeline_get_actor (ClutterTimeline *timeline); - -CLUTTER_EXPORT -void clutter_timeline_set_actor (ClutterTimeline *timeline, - ClutterActor *actor); - -CLUTTER_EXPORT -guint clutter_timeline_get_duration (ClutterTimeline *timeline); -CLUTTER_EXPORT -void clutter_timeline_set_duration (ClutterTimeline *timeline, - guint msecs); -CLUTTER_EXPORT -ClutterTimelineDirection clutter_timeline_get_direction (ClutterTimeline *timeline); -CLUTTER_EXPORT -void clutter_timeline_set_direction (ClutterTimeline *timeline, - ClutterTimelineDirection direction); -CLUTTER_EXPORT -void clutter_timeline_start (ClutterTimeline *timeline); -CLUTTER_EXPORT -void clutter_timeline_pause (ClutterTimeline *timeline); -CLUTTER_EXPORT -void clutter_timeline_stop (ClutterTimeline *timeline); -CLUTTER_EXPORT -void clutter_timeline_set_auto_reverse (ClutterTimeline *timeline, - gboolean reverse); -CLUTTER_EXPORT -gboolean clutter_timeline_get_auto_reverse (ClutterTimeline *timeline); -CLUTTER_EXPORT -void clutter_timeline_set_repeat_count (ClutterTimeline *timeline, - gint count); -CLUTTER_EXPORT -gint clutter_timeline_get_repeat_count (ClutterTimeline *timeline); -CLUTTER_EXPORT -void clutter_timeline_rewind (ClutterTimeline *timeline); -CLUTTER_EXPORT -void clutter_timeline_skip (ClutterTimeline *timeline, - guint msecs); -CLUTTER_EXPORT -void clutter_timeline_advance (ClutterTimeline *timeline, - guint msecs); -CLUTTER_EXPORT -guint clutter_timeline_get_elapsed_time (ClutterTimeline *timeline); -CLUTTER_EXPORT -gdouble clutter_timeline_get_progress (ClutterTimeline *timeline); -CLUTTER_EXPORT -gboolean clutter_timeline_is_playing (ClutterTimeline *timeline); -CLUTTER_EXPORT -void clutter_timeline_set_delay (ClutterTimeline *timeline, - guint msecs); -CLUTTER_EXPORT -guint clutter_timeline_get_delay (ClutterTimeline *timeline); -CLUTTER_EXPORT -guint clutter_timeline_get_delta (ClutterTimeline *timeline); -CLUTTER_EXPORT -void clutter_timeline_add_marker (ClutterTimeline *timeline, - const gchar *marker_name, - gdouble progress); -CLUTTER_EXPORT -void clutter_timeline_add_marker_at_time (ClutterTimeline *timeline, - const gchar *marker_name, - guint msecs); -CLUTTER_EXPORT -void clutter_timeline_remove_marker (ClutterTimeline *timeline, - const gchar *marker_name); -CLUTTER_EXPORT -gchar ** clutter_timeline_list_markers (ClutterTimeline *timeline, - gint msecs, - gsize *n_markers) G_GNUC_MALLOC; -CLUTTER_EXPORT -gboolean clutter_timeline_has_marker (ClutterTimeline *timeline, - const gchar *marker_name); -CLUTTER_EXPORT -void clutter_timeline_advance_to_marker (ClutterTimeline *timeline, - const gchar *marker_name); -CLUTTER_EXPORT -void clutter_timeline_set_progress_func (ClutterTimeline *timeline, - ClutterTimelineProgressFunc func, - gpointer data, - GDestroyNotify notify); -CLUTTER_EXPORT -void clutter_timeline_set_progress_mode (ClutterTimeline *timeline, - ClutterAnimationMode mode); -CLUTTER_EXPORT -ClutterAnimationMode clutter_timeline_get_progress_mode (ClutterTimeline *timeline); -CLUTTER_EXPORT -void clutter_timeline_set_step_progress (ClutterTimeline *timeline, - gint n_steps, - ClutterStepMode step_mode); -CLUTTER_EXPORT -gboolean clutter_timeline_get_step_progress (ClutterTimeline *timeline, - gint *n_steps, - ClutterStepMode *step_mode); -CLUTTER_EXPORT -void clutter_timeline_set_cubic_bezier_progress (ClutterTimeline *timeline, - const graphene_point_t *c_1, - const graphene_point_t *c_2); -CLUTTER_EXPORT -gboolean clutter_timeline_get_cubic_bezier_progress (ClutterTimeline *timeline, - graphene_point_t *c_1, - graphene_point_t *c_2); - -CLUTTER_EXPORT -gint64 clutter_timeline_get_duration_hint (ClutterTimeline *timeline); -CLUTTER_EXPORT -gint clutter_timeline_get_current_repeat (ClutterTimeline *timeline); - -CLUTTER_EXPORT -ClutterFrameClock * clutter_timeline_get_frame_clock (ClutterTimeline *timeline); - -CLUTTER_EXPORT -void clutter_timeline_set_frame_clock (ClutterTimeline *timeline, - ClutterFrameClock *frame_clock); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-transition-group.c b/mutter/clutter/clutter/clutter-transition-group.c deleted file mode 100644 index 0c2da08..0000000 --- a/mutter/clutter/clutter/clutter-transition-group.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -/** - * ClutterTransitionGroup: - * - * Group transitions together - * - * The #ClutterTransitionGroup allows running multiple [class@Transition] - * instances concurrently. - * - * The transitions inside a group will run within the boundaries of the - * group; for instance, if a transition has a duration of 10 seconds, and - * the group that contains it has a duration of 5 seconds, only the first - * 5 seconds of the transition will be played. - */ - -#include "config.h" - -#include "clutter/clutter-transition-group.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-timeline-private.h" - -struct _ClutterTransitionGroup -{ - ClutterTransition parent_instance; - - GHashTable *transitions; -}; - -G_DEFINE_FINAL_TYPE (ClutterTransitionGroup, clutter_transition_group, CLUTTER_TYPE_TRANSITION) - -static void -clutter_transition_group_new_frame (ClutterTimeline *timeline, - gint elapsed) -{ - ClutterTransitionGroup *transition = CLUTTER_TRANSITION_GROUP (timeline); - GHashTableIter iter; - gpointer element; - gint64 msecs; - - /* get the time elapsed since the last ::new-frame... */ - msecs = clutter_timeline_get_delta (timeline); - - g_hash_table_iter_init (&iter, transition->transitions); - while (g_hash_table_iter_next (&iter, &element, NULL)) - { - ClutterTimeline *t = element; - - /* ... and advance every timeline */ - clutter_timeline_set_direction (t, clutter_timeline_get_direction (timeline)); - clutter_timeline_set_duration (t, clutter_timeline_get_duration (timeline)); - - _clutter_timeline_advance (t, msecs); - } -} - -static void -clutter_transition_group_attached (ClutterTransition *transition, - ClutterAnimatable *animatable) -{ - ClutterTransitionGroup *group = CLUTTER_TRANSITION_GROUP (transition); - GHashTableIter iter; - gpointer element; - - g_hash_table_iter_init (&iter, group->transitions); - while (g_hash_table_iter_next (&iter, &element, NULL)) - { - ClutterTransition *t = element; - - clutter_transition_set_animatable (t, animatable); - } -} - -static void -clutter_transition_group_detached (ClutterTransition *transition, - ClutterAnimatable *animatable) -{ - ClutterTransitionGroup *group = CLUTTER_TRANSITION_GROUP (transition); - GHashTableIter iter; - gpointer element; - - g_hash_table_iter_init (&iter, group->transitions); - while (g_hash_table_iter_next (&iter, &element, NULL)) - { - ClutterTransition *t = element; - - clutter_transition_set_animatable (t, NULL); - } -} - -static void -clutter_transition_group_started (ClutterTimeline *timeline) -{ - ClutterTransitionGroup *transition = CLUTTER_TRANSITION_GROUP (timeline); - GHashTableIter iter; - gpointer element; - - g_hash_table_iter_init (&iter, transition->transitions); - while (g_hash_table_iter_next (&iter, &element, NULL)) - { - ClutterTransition *t = element; - - g_signal_emit_by_name (t, "started"); - } -} - -static void -clutter_transition_group_finalize (GObject *gobject) -{ - ClutterTransitionGroup *transition = CLUTTER_TRANSITION_GROUP (gobject); - - g_hash_table_unref (transition->transitions); - - G_OBJECT_CLASS (clutter_transition_group_parent_class)->finalize (gobject); -} - -static void -clutter_transition_group_class_init (ClutterTransitionGroupClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterTimelineClass *timeline_class = CLUTTER_TIMELINE_CLASS (klass); - ClutterTransitionClass *transition_class = CLUTTER_TRANSITION_CLASS (klass); - - gobject_class->finalize = clutter_transition_group_finalize; - - timeline_class->started = clutter_transition_group_started; - timeline_class->new_frame = clutter_transition_group_new_frame; - - transition_class->attached = clutter_transition_group_attached; - transition_class->detached = clutter_transition_group_detached; -} - -static void -clutter_transition_group_init (ClutterTransitionGroup *self) -{ - self->transitions = - g_hash_table_new_full (NULL, NULL, (GDestroyNotify) g_object_unref, NULL); -} - -/** - * clutter_transition_group_new: - * - * Creates a new #ClutterTransitionGroup instance. - * - * Return value: the newly created #ClutterTransitionGroup. Use - * [method@GObject.Object.unref] when done to deallocate the resources it - * uses - */ -ClutterTransition * -clutter_transition_group_new (void) -{ - return g_object_new (CLUTTER_TYPE_TRANSITION_GROUP, NULL); -} - -/** - * clutter_transition_group_add_transition: - * @group: a #ClutterTransitionGroup - * @transition: a #ClutterTransition - * - * Adds @transition to @group. - * - * This function acquires a reference on @transition that will be released - * when calling [method@TransitionGroup.remove_transition]. - */ -void -clutter_transition_group_add_transition (ClutterTransitionGroup *group, - ClutterTransition *transition) -{ - g_return_if_fail (CLUTTER_IS_TRANSITION_GROUP (group)); - g_return_if_fail (CLUTTER_IS_TRANSITION (transition)); - - g_hash_table_add (group->transitions, g_object_ref (transition)); -} - -/** - * clutter_transition_group_remove_transition: - * @group: a #ClutterTransitionGroup - * @transition: a #ClutterTransition - * - * Removes @transition from @group. - * - * This function releases the reference acquired on @transition when - * calling [method@TransitionGroup.add_transition]. - */ -void -clutter_transition_group_remove_transition (ClutterTransitionGroup *group, - ClutterTransition *transition) -{ - g_return_if_fail (CLUTTER_IS_TRANSITION_GROUP (group)); - - g_hash_table_remove (group->transitions, transition); -} - -/** - * clutter_transition_group_remove_all: - * @group: a #ClutterTransitionGroup - * - * Removes all transitions from @group. - * - * This function releases the reference acquired when calling - * [method@TransitionGroup.add_transition]. - */ -void -clutter_transition_group_remove_all (ClutterTransitionGroup *group) -{ - g_return_if_fail (CLUTTER_IS_TRANSITION_GROUP (group)); - - g_hash_table_remove_all (group->transitions); -} diff --git a/mutter/clutter/clutter/clutter-transition-group.h b/mutter/clutter/clutter/clutter-transition-group.h deleted file mode 100644 index b50b91c..0000000 --- a/mutter/clutter/clutter/clutter-transition-group.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" -#include "clutter/clutter-transition.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_TRANSITION_GROUP (clutter_transition_group_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_FINAL_TYPE (ClutterTransitionGroup, - clutter_transition_group, - CLUTTER, - TRANSITION_GROUP, - ClutterTransition) - -CLUTTER_EXPORT -ClutterTransition * clutter_transition_group_new (void); - -CLUTTER_EXPORT -void clutter_transition_group_add_transition (ClutterTransitionGroup *group, - ClutterTransition *transition); -CLUTTER_EXPORT -void clutter_transition_group_remove_transition (ClutterTransitionGroup *group, - ClutterTransition *transition); -CLUTTER_EXPORT -void clutter_transition_group_remove_all (ClutterTransitionGroup *group); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-transition.c b/mutter/clutter/clutter/clutter-transition.c deleted file mode 100644 index 06e5e2f..0000000 --- a/mutter/clutter/clutter/clutter-transition.c +++ /dev/null @@ -1,673 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -/** - * ClutterTransition: - * - * Transition between two values - * - * #ClutterTransition is an abstract subclass of [class@Timeline] that - * computes the interpolation between two values, stored by a [class@Interval]. - */ - -#include "config.h" - -#include "clutter/clutter-transition.h" - -#include "clutter/clutter-animatable.h" -#include "clutter/clutter-debug.h" -#include "clutter/clutter-interval.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-timeline.h" - -#include - -typedef struct _ClutterTransitionPrivate -{ - ClutterInterval *interval; - ClutterAnimatable *animatable; - - guint remove_on_complete : 1; -} ClutterTransitionPrivate; - -enum -{ - PROP_0, - - PROP_INTERVAL, - PROP_ANIMATABLE, - PROP_REMOVE_ON_COMPLETE, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST] = { NULL, }; - -static GQuark quark_animatable_set = 0; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterTransition, clutter_transition, CLUTTER_TYPE_TIMELINE) - -static void -clutter_transition_attach (ClutterTransition *transition, - ClutterAnimatable *animatable) -{ - CLUTTER_TRANSITION_GET_CLASS (transition)->attached (transition, animatable); -} - -static void -clutter_transition_detach (ClutterTransition *transition, - ClutterAnimatable *animatable) -{ - CLUTTER_TRANSITION_GET_CLASS (transition)->detached (transition, animatable); -} - -static void -clutter_transition_real_compute_value (ClutterTransition *transition, - ClutterAnimatable *animatable, - ClutterInterval *interval, - gdouble progress) -{ -} - -static void -clutter_transition_real_attached (ClutterTransition *transition, - ClutterAnimatable *animatable) -{ -} - -static void -clutter_transition_real_detached (ClutterTransition *transition, - ClutterAnimatable *animatable) -{ -} - -static void -clutter_transition_new_frame (ClutterTimeline *timeline, - gint elapsed G_GNUC_UNUSED) -{ - ClutterTransition *transition = CLUTTER_TRANSITION (timeline); - ClutterTransitionPrivate *priv = - clutter_transition_get_instance_private (transition); - gdouble progress; - - if (priv->interval == NULL || - priv->animatable == NULL) - return; - - progress = clutter_timeline_get_progress (timeline); - - CLUTTER_TRANSITION_GET_CLASS (timeline)->compute_value (transition, - priv->animatable, - priv->interval, - progress); -} - -static void -clutter_transition_stopped (ClutterTimeline *timeline, - gboolean is_finished) -{ - ClutterTransition *transition = CLUTTER_TRANSITION (timeline); - ClutterTransitionPrivate *priv = - clutter_transition_get_instance_private (transition); - - if (is_finished && - priv->animatable != NULL && - priv->remove_on_complete) - { - clutter_transition_detach (CLUTTER_TRANSITION (timeline), - priv->animatable); - g_clear_object (&priv->animatable); - } -} - -static void -clutter_transition_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterTransition *transition = CLUTTER_TRANSITION (gobject); - - switch (prop_id) - { - case PROP_INTERVAL: - clutter_transition_set_interval (transition, g_value_get_object (value)); - break; - - case PROP_ANIMATABLE: - clutter_transition_set_animatable (transition, g_value_get_object (value)); - break; - - case PROP_REMOVE_ON_COMPLETE: - clutter_transition_set_remove_on_complete (transition, g_value_get_boolean (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_transition_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterTransition *transition = CLUTTER_TRANSITION (gobject); - ClutterTransitionPrivate *priv = - clutter_transition_get_instance_private (transition); - - switch (prop_id) - { - case PROP_INTERVAL: - g_value_set_object (value, priv->interval); - break; - - case PROP_ANIMATABLE: - g_value_set_object (value, priv->animatable); - break; - - case PROP_REMOVE_ON_COMPLETE: - g_value_set_boolean (value, priv->remove_on_complete); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_transition_dispose (GObject *gobject) -{ - ClutterTransition *transition = CLUTTER_TRANSITION (gobject); - ClutterTransitionPrivate *priv = - clutter_transition_get_instance_private (transition); - if (priv->animatable != NULL) - clutter_transition_detach (CLUTTER_TRANSITION (gobject), - priv->animatable); - - g_clear_object (&priv->interval); - g_clear_object (&priv->animatable); - - G_OBJECT_CLASS (clutter_transition_parent_class)->dispose (gobject); -} - -static void -clutter_transition_class_init (ClutterTransitionClass *klass) -{ - ClutterTimelineClass *timeline_class = CLUTTER_TIMELINE_CLASS (klass); - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - quark_animatable_set = - g_quark_from_static_string ("-clutter-transition-animatable-set"); - - klass->compute_value = clutter_transition_real_compute_value; - klass->attached = clutter_transition_real_attached; - klass->detached = clutter_transition_real_detached; - - timeline_class->new_frame = clutter_transition_new_frame; - timeline_class->stopped = clutter_transition_stopped; - - gobject_class->set_property = clutter_transition_set_property; - gobject_class->get_property = clutter_transition_get_property; - gobject_class->dispose = clutter_transition_dispose; - - /** - * ClutterTransition:interval: - * - * The [class@Interval] used to describe the initial and final states - * of the transition. - */ - obj_props[PROP_INTERVAL] = - g_param_spec_object ("interval", NULL, NULL, - CLUTTER_TYPE_INTERVAL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterTransition:animatable: - * - * The [iface@Animatable] instance currently being animated. - */ - obj_props[PROP_ANIMATABLE] = - g_param_spec_object ("animatable", NULL, NULL, - CLUTTER_TYPE_ANIMATABLE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterTransition:remove-on-complete: - * - * Whether the #ClutterTransition should be automatically detached - * from the [property@Transition:animatable] instance whenever the - * [signal@Timeline::stopped] signal is emitted. - * - * The [property@Transition:remove-on-complete] property takes into - * account the value of the [property@Timeline:repeat-count] property, - * and it only detaches the transition if the transition is not - * repeating. - */ - obj_props[PROP_REMOVE_ON_COMPLETE] = - g_param_spec_boolean ("remove-on-complete", NULL, NULL, - FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); -} - -static void -clutter_transition_init (ClutterTransition *self) -{ -} - -/** - * clutter_transition_set_interval: - * @transition: a #ClutterTransition - * @interval: (allow-none): a #ClutterInterval, or %NULL - * - * Sets the [property@Transition:interval] property using @interval. - * - * The @transition will acquire a reference on the @interval, sinking - * the floating flag on it if necessary. - */ -void -clutter_transition_set_interval (ClutterTransition *transition, - ClutterInterval *interval) -{ - ClutterTransitionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TRANSITION (transition)); - g_return_if_fail (interval == NULL || CLUTTER_IS_INTERVAL (interval)); - - priv = clutter_transition_get_instance_private (transition); - - if (priv->interval == interval) - return; - - g_clear_object (&priv->interval); - - if (interval != NULL) - priv->interval = g_object_ref_sink (interval); - - g_object_notify_by_pspec (G_OBJECT (transition), obj_props[PROP_INTERVAL]); -} - -/** - * clutter_transition_get_interval: - * @transition: a #ClutterTransition - * - * Retrieves the interval set using [method@Transition.set_interval] - * - * Return value: (transfer none): a [class@Interval], or %NULL; the returned - * interval is owned by the #ClutterTransition and it should not be freed - * directly - */ -ClutterInterval * -clutter_transition_get_interval (ClutterTransition *transition) -{ - ClutterTransitionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TRANSITION (transition), NULL); - - priv = clutter_transition_get_instance_private (transition); - - return priv->interval; -} - -/** - * clutter_transition_set_animatable: - * @transition: a #ClutterTransition - * @animatable: (allow-none): a #ClutterAnimatable, or %NULL - * - * Sets the [property@Transition:animatable] property. - * - * The @transition will acquire a reference to the @animatable instance, - * and will call the [vfunc@Transition.attached] virtual function. - * - * If an existing [iface@Animatable] is attached to @transition, the - * reference will be released, and the [vfunc@Transition.detached] - * virtual function will be called. - */ -void -clutter_transition_set_animatable (ClutterTransition *transition, - ClutterAnimatable *animatable) -{ - ClutterTransitionPrivate *priv; - ClutterActor *actor = NULL; - - g_return_if_fail (CLUTTER_IS_TRANSITION (transition)); - g_return_if_fail (animatable == NULL || CLUTTER_IS_ANIMATABLE (animatable)); - - priv = clutter_transition_get_instance_private (transition); - - if (priv->animatable == animatable) - return; - - if (priv->animatable != NULL) - clutter_transition_detach (transition, priv->animatable); - - g_clear_object (&priv->animatable); - - if (animatable != NULL) - { - priv->animatable = g_object_ref (animatable); - clutter_transition_attach (transition, priv->animatable); - actor = clutter_animatable_get_actor (animatable); - } - - clutter_timeline_set_actor (CLUTTER_TIMELINE (transition), actor); -} - -/** - * clutter_transition_get_animatable: - * @transition: a #ClutterTransition - * - * Retrieves the [iface@Animatable] set using [method@Transition.set_animatable]. - * - * Return value: (transfer none): a [iface@Animatable], or %NULL; the returned - * animatable is owned by the #ClutterTransition, and it should not be freed - * directly. - */ -ClutterAnimatable * -clutter_transition_get_animatable (ClutterTransition *transition) -{ - ClutterTransitionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TRANSITION (transition), NULL); - - priv = clutter_transition_get_instance_private (transition); - - return priv->animatable; -} - -/** - * clutter_transition_set_remove_on_complete: - * @transition: a #ClutterTransition - * @remove_complete: whether to detach @transition when complete - * - * Sets whether @transition should be detached from the [iface@Animatable] - * set using [method@Transition.set_animatable] when the - * [signal@Timeline::completed] signal is emitted. - */ -void -clutter_transition_set_remove_on_complete (ClutterTransition *transition, - gboolean remove_complete) -{ - ClutterTransitionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TRANSITION (transition)); - - priv = clutter_transition_get_instance_private (transition); - remove_complete = !!remove_complete; - - if (priv->remove_on_complete == remove_complete) - return; - - priv->remove_on_complete = remove_complete; - - g_object_notify_by_pspec (G_OBJECT (transition), - obj_props[PROP_REMOVE_ON_COMPLETE]); -} - -/** - * clutter_transition_get_remove_on_complete: - * @transition: a #ClutterTransition - * - * Retrieves the value of the [property@Transition:remove-on-complete] property. - * - * Return value: %TRUE if the @transition should be detached when complete, - * and %FALSE otherwise - */ -gboolean -clutter_transition_get_remove_on_complete (ClutterTransition *transition) -{ - ClutterTransitionPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_TRANSITION (transition), FALSE); - - priv = clutter_transition_get_instance_private (transition); - - return priv->remove_on_complete; -} - -typedef void (* IntervalSetFunc) (ClutterInterval *interval, - const GValue *value); - -static inline void -clutter_transition_set_value (ClutterTransition *transition, - IntervalSetFunc interval_set_func, - const GValue *value) -{ - ClutterTransitionPrivate *priv = - clutter_transition_get_instance_private (transition); - GType interval_type; - - if (priv->interval == NULL) - { - priv->interval = clutter_interval_new_with_values (G_VALUE_TYPE (value), - NULL, - NULL); - g_object_ref_sink (priv->interval); - } - - interval_type = clutter_interval_get_value_type (priv->interval); - - if (!g_type_is_a (G_VALUE_TYPE (value), interval_type)) - { - if (g_value_type_compatible (G_VALUE_TYPE (value), interval_type)) - { - interval_set_func (priv->interval, value); - return; - } - - if (g_value_type_transformable (G_VALUE_TYPE (value), interval_type)) - { - GValue transform = G_VALUE_INIT; - - g_value_init (&transform, interval_type); - if (g_value_transform (value, &transform)) - interval_set_func (priv->interval, &transform); - else - { - g_warning ("%s: Unable to convert a value of type '%s' into " - "the value type '%s' of the interval used by the " - "transition.", - G_STRLOC, - g_type_name (G_VALUE_TYPE (value)), - g_type_name (interval_type)); - } - - g_value_unset (&transform); - } - } - else - interval_set_func (priv->interval, value); -} - -/** - * clutter_transition_set_from_value: (rename-to clutter_transition_set_from) - * @transition: a #ClutterTransition - * @value: a #GValue with the initial value of the transition - * - * Sets the initial value of the transition. - * - * This is a convenience function that will either create the - * [class@Interval] used by @transition, or will update it if - * the [property@Transition:interval] is already set. - * - * This function will copy the contents of @value, so it is - * safe to call [method@GObject.Value.unset] after it returns. - * - * If @transition already has a [property@Transition:interval] set, - * then @value must hold the same type, or a transformable type, - * as the interval's [property@Interval:value-type] property. - * - * This function is meant to be used by language bindings. - */ -void -clutter_transition_set_from_value (ClutterTransition *transition, - const GValue *value) -{ - g_return_if_fail (CLUTTER_IS_TRANSITION (transition)); - g_return_if_fail (G_IS_VALUE (value)); - - clutter_transition_set_value (transition, - clutter_interval_set_initial_value, - value); -} - -/** - * clutter_transition_set_to_value: (rename-to clutter_transition_set_to) - * @transition: a #ClutterTransition - * @value: a #GValue with the final value of the transition - * - * Sets the final value of the transition. - * - * This is a convenience function that will either create the - * #ClutterInterval used by @transition, or will update it if - * the [property@Transition:interval] is already set. - * - * This function will copy the contents of @value, so it is - * safe to call [method@GObject.Value.unset] after it returns. - * - * If @transition already has a [property@Transition:interval] set, - * then @value must hold the same type, or a transformable type, - * as the interval's [property@Interval:value-type] property. - * - * This function is meant to be used by language bindings. - */ -void -clutter_transition_set_to_value (ClutterTransition *transition, - const GValue *value) -{ - g_return_if_fail (CLUTTER_IS_TRANSITION (transition)); - g_return_if_fail (G_IS_VALUE (value)); - - clutter_transition_set_value (transition, - clutter_interval_set_final_value, - value); -} - -/** - * clutter_transition_set_from: (skip) - * @transition: a #ClutterTransition - * @value_type: the type of the value to set - * @...: the initial value - * - * Sets the initial value of the transition. - * - * This is a convenience function that will either create the - * #ClutterInterval used by @transition, or will update it if - * the [property@Transition:interval] is already set. - * - * If @transition already has a [property@Transition:interval] set, - * then @value must hold the same type, or a transformable type, - * as the interval's [property@Interval:value-type] property. - * - * This is a convenience function for the C API; language bindings - * should use [method@Transition.set_from_value] instead. - */ -void -clutter_transition_set_from (ClutterTransition *transition, - GType value_type, - ...) -{ - GValue value = G_VALUE_INIT; - gchar *error = NULL; - va_list args; - - g_return_if_fail (CLUTTER_IS_TRANSITION (transition)); - g_return_if_fail (value_type != G_TYPE_INVALID); - - va_start (args, value_type); - - G_VALUE_COLLECT_INIT (&value, value_type, args, 0, &error); - - va_end (args); - - if (error != NULL) - { - g_warning ("%s: %s", G_STRLOC, error); - g_free (error); - return; - } - - clutter_transition_set_value (transition, - clutter_interval_set_initial_value, - &value); - - g_value_unset (&value); -} - -/** - * clutter_transition_set_to: (skip) - * @transition: a #ClutterTransition - * @value_type: the type of the value to set - * @...: the final value - * - * Sets the final value of the transition. - * - * This is a convenience function that will either create the - * #ClutterInterval used by @transition, or will update it if - * the [property@Transition:interval] is already set. - * - * If @transition already has a [property@Transition:interval] set, - * then @value must hold the same type, or a transformable type, - * as the interval's [property@Interval:value-type] property. - * - * This is a convenience function for the C API; language bindings - * should use [method@Transition.set_to_value] instead. - */ -void -clutter_transition_set_to (ClutterTransition *transition, - GType value_type, - ...) -{ - GValue value = G_VALUE_INIT; - gchar *error = NULL; - va_list args; - - g_return_if_fail (CLUTTER_IS_TRANSITION (transition)); - g_return_if_fail (value_type != G_TYPE_INVALID); - - va_start (args, value_type); - - G_VALUE_COLLECT_INIT (&value, value_type, args, 0, &error); - - va_end (args); - - if (error != NULL) - { - g_warning ("%s: %s", G_STRLOC, error); - g_free (error); - return; - } - - clutter_transition_set_value (transition, - clutter_interval_set_final_value, - &value); - - g_value_unset (&value); -} diff --git a/mutter/clutter/clutter/clutter-transition.h b/mutter/clutter/clutter/clutter-transition.h deleted file mode 100644 index e4c6305..0000000 --- a/mutter/clutter/clutter/clutter-transition.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" -#include "clutter/clutter-timeline.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_TRANSITION (clutter_transition_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterTransition, - clutter_transition, - CLUTTER, - TRANSITION, - ClutterTimeline) - -/** - * ClutterTransitionClass: - * @attached: virtual function; called when a transition is attached to - * a #ClutterAnimatable instance - * @detached: virtual function; called when a transition is detached from - * a #ClutterAnimatable instance - * @compute_value: virtual function; called each frame to compute and apply - * the interpolation of the interval - * - * The #ClutterTransitionClass structure contains - * private data. - */ -struct _ClutterTransitionClass -{ - /*< private >*/ - ClutterTimelineClass parent_class; - - /*< public >*/ - void (* attached) (ClutterTransition *transition, - ClutterAnimatable *animatable); - void (* detached) (ClutterTransition *transition, - ClutterAnimatable *animatable); - - void (* compute_value) (ClutterTransition *transition, - ClutterAnimatable *animatable, - ClutterInterval *interval, - gdouble progress); -}; - -CLUTTER_EXPORT -void clutter_transition_set_interval (ClutterTransition *transition, - ClutterInterval *interval); -CLUTTER_EXPORT -ClutterInterval * clutter_transition_get_interval (ClutterTransition *transition); -CLUTTER_EXPORT -void clutter_transition_set_from_value (ClutterTransition *transition, - const GValue *value); -CLUTTER_EXPORT -void clutter_transition_set_to_value (ClutterTransition *transition, - const GValue *value); -CLUTTER_EXPORT -void clutter_transition_set_from (ClutterTransition *transition, - GType value_type, - ...); -CLUTTER_EXPORT -void clutter_transition_set_to (ClutterTransition *transition, - GType value_type, - ...); - -CLUTTER_EXPORT -void clutter_transition_set_animatable (ClutterTransition *transition, - ClutterAnimatable *animatable); -CLUTTER_EXPORT -ClutterAnimatable * clutter_transition_get_animatable (ClutterTransition *transition); -CLUTTER_EXPORT -void clutter_transition_set_remove_on_complete (ClutterTransition *transition, - gboolean remove_complete); -CLUTTER_EXPORT -gboolean clutter_transition_get_remove_on_complete (ClutterTransition *transition); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-types.h b/mutter/clutter/clutter/clutter-types.h deleted file mode 100644 index 20bd499..0000000 --- a/mutter/clutter/clutter/clutter-types.h +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * 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 . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -#include "cogl/cogl.h" -#include "clutter/clutter-macros.h" -#include "clutter/clutter-enums.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_ACTOR_BOX (clutter_actor_box_get_type ()) -#define CLUTTER_TYPE_MARGIN (clutter_margin_get_type ()) -#define CLUTTER_TYPE_PAINT_VOLUME (clutter_paint_volume_get_type ()) -#define CLUTTER_TYPE_PERSPECTIVE (clutter_perspective_get_type ()) - -typedef struct _ClutterActor ClutterActor; - -typedef struct _ClutterContext ClutterContext; -typedef struct _ClutterStage ClutterStage; -typedef struct _ClutterFrame ClutterFrame; -typedef struct _ClutterFrameInfo ClutterFrameInfo; -typedef struct _ClutterLayoutMeta ClutterLayoutMeta; -typedef struct _ClutterActorMeta ClutterActorMeta; -typedef struct _ClutterLayoutManager ClutterLayoutManager; -typedef struct _ClutterActorIter ClutterActorIter; -typedef struct _ClutterPaintContext ClutterPaintContext; -typedef struct _ClutterPaintNode ClutterPaintNode; -typedef struct _ClutterContent ClutterContent; /* dummy */ -typedef struct _ClutterScrollActor ClutterScrollActor; -typedef struct _ClutterFrameClock ClutterFrameClock; - -typedef struct _ClutterInterval ClutterInterval; -typedef struct _ClutterAnimatable ClutterAnimatable; /* dummy */ -typedef struct _ClutterTimeline ClutterTimeline; -typedef struct _ClutterTransition ClutterTransition; -typedef struct _ClutterPropertyTransition ClutterPropertyTransition; -typedef struct _ClutterKeyframeTransition ClutterKeyframeTransition; -typedef struct _ClutterTransitionGroup ClutterTransitionGroup; -typedef struct _ClutterText ClutterText; - -typedef struct _ClutterAction ClutterAction; -typedef struct _ClutterConstraint ClutterConstraint; -typedef struct _ClutterEffect ClutterEffect; - -typedef struct _ClutterActorBox ClutterActorBox; -typedef struct _ClutterColor ClutterColor; -typedef struct _ClutterColorState ClutterColorState; -typedef struct _ClutterMargin ClutterMargin; -typedef struct _ClutterPerspective ClutterPerspective; - -typedef struct _ClutterInputDeviceTool ClutterInputDeviceTool; -typedef struct _ClutterInputDevice ClutterInputDevice; -typedef struct _ClutterVirtualInputDevice ClutterVirtualInputDevice; - -typedef struct _ClutterInputMethod ClutterInputMethod; -typedef struct _ClutterInputFocus ClutterInputFocus; - -typedef union _ClutterEvent ClutterEvent; - -typedef enum _ClutterPaintFlag ClutterPaintFlag; - -/** - * ClutterEventSequence: - * - * The #ClutterEventSequence structure is an opaque - * type used to denote the event sequence of a touch event. - */ -typedef struct _ClutterEventSequence ClutterEventSequence; - -/** - * ClutterPaintVolume: - * - * A #ClutterPaintVolume represents a bounding volume whose internal - * representation isn't defined but can be set and queried in terms - * of an axis aligned bounding box. - * - * A #ClutterPaintVolume for a [class@Actor] - * is defined to be relative from the current actor modelview matrix. - * - * Other internal representation and methods for describing the - * bounding volume may be added in the future. - */ -typedef struct _ClutterPaintVolume ClutterPaintVolume; - -/** - * ClutterActorBox: - * @x1: X coordinate of the top left corner - * @y1: Y coordinate of the top left corner - * @x2: X coordinate of the bottom right corner - * @y2: Y coordinate of the bottom right corner - * - * Bounding box of an actor. - * - * The coordinates of the top left and right bottom corners - * of an actor. The coordinates of the two points are expressed in - * pixels with sub-pixel precision - */ -struct _ClutterActorBox -{ - gfloat x1; - gfloat y1; - - gfloat x2; - gfloat y2; -}; - -/** - * CLUTTER_ACTOR_BOX_INIT: - * @x_1: the X coordinate of the top left corner - * @y_1: the Y coordinate of the top left corner - * @x_2: the X coordinate of the bottom right corner - * @y_2: the Y coordinate of the bottom right corner - * - * A simple macro for initializing a #ClutterActorBox when declaring - * it, e.g.: - * - * ```c - * ClutterActorBox box = CLUTTER_ACTOR_BOX_INIT (0, 0, 400, 600); - * ``` - */ -#define CLUTTER_ACTOR_BOX_INIT(x_1,y_1,x_2,y_2) { (x_1), (y_1), (x_2), (y_2) } - -/** - * CLUTTER_ACTOR_BOX_INIT_ZERO: - * - * A simple macro for initializing a #ClutterActorBox to 0 when - * declaring it, e.g.: - * - * ```c - * ClutterActorBox box = CLUTTER_ACTOR_BOX_INIT_ZERO; - * ``` - */ -#define CLUTTER_ACTOR_BOX_INIT_ZERO CLUTTER_ACTOR_BOX_INIT (0.f, 0.f, 0.f, 0.f) - -/** - * CLUTTER_ACTOR_BOX_UNINITIALIZED: - * - * A simple macro for creating a #ClutterActorBox with a size of -1 when - * declaring it, e.g.: - * - * ```c - * ClutterActorBox box = CLUTTER_ACTOR_BOX_UNINITIALIZED; - * ``` - */ - - -#define CLUTTER_ACTOR_BOX_UNINITIALIZED { .x1 = INFINITY, .y1 = INFINITY, .x2 = -INFINITY, .y2 = -INFINITY } - -CLUTTER_EXPORT -GType clutter_actor_box_get_type (void) G_GNUC_CONST; -CLUTTER_EXPORT -ClutterActorBox *clutter_actor_box_new (gfloat x_1, - gfloat y_1, - gfloat x_2, - gfloat y_2); -CLUTTER_EXPORT -ClutterActorBox *clutter_actor_box_alloc (void); -CLUTTER_EXPORT -ClutterActorBox *clutter_actor_box_init (ClutterActorBox *box, - gfloat x_1, - gfloat y_1, - gfloat x_2, - gfloat y_2); -CLUTTER_EXPORT -void clutter_actor_box_init_rect (ClutterActorBox *box, - gfloat x, - gfloat y, - gfloat width, - gfloat height); -CLUTTER_EXPORT -ClutterActorBox *clutter_actor_box_copy (const ClutterActorBox *box); -CLUTTER_EXPORT -void clutter_actor_box_free (ClutterActorBox *box); -CLUTTER_EXPORT -gboolean clutter_actor_box_equal (const ClutterActorBox *box_a, - const ClutterActorBox *box_b); -CLUTTER_EXPORT -gfloat clutter_actor_box_get_x (const ClutterActorBox *box); -CLUTTER_EXPORT -gfloat clutter_actor_box_get_y (const ClutterActorBox *box); -CLUTTER_EXPORT -gfloat clutter_actor_box_get_width (const ClutterActorBox *box); -CLUTTER_EXPORT -gfloat clutter_actor_box_get_height (const ClutterActorBox *box); -CLUTTER_EXPORT -void clutter_actor_box_get_origin (const ClutterActorBox *box, - gfloat *x, - gfloat *y); -CLUTTER_EXPORT -void clutter_actor_box_get_size (const ClutterActorBox *box, - gfloat *width, - gfloat *height); -CLUTTER_EXPORT -gfloat clutter_actor_box_get_area (const ClutterActorBox *box); -CLUTTER_EXPORT -gboolean clutter_actor_box_contains (const ClutterActorBox *box, - gfloat x, - gfloat y); -CLUTTER_EXPORT -void clutter_actor_box_from_vertices (ClutterActorBox *box, - const graphene_point3d_t verts[]); -CLUTTER_EXPORT -void clutter_actor_box_interpolate (const ClutterActorBox *initial, - const ClutterActorBox *final, - gdouble progress, - ClutterActorBox *result); -CLUTTER_EXPORT -void clutter_actor_box_clamp_to_pixel (ClutterActorBox *box); -CLUTTER_EXPORT -void clutter_actor_box_union (const ClutterActorBox *a, - const ClutterActorBox *b, - ClutterActorBox *result); - -CLUTTER_EXPORT -void clutter_actor_box_set_origin (ClutterActorBox *box, - gfloat x, - gfloat y); -CLUTTER_EXPORT -void clutter_actor_box_set_size (ClutterActorBox *box, - gfloat width, - gfloat height); - -CLUTTER_EXPORT -void clutter_actor_box_scale (ClutterActorBox *box, - gfloat scale); - -CLUTTER_EXPORT -gboolean clutter_actor_box_is_initialized (ClutterActorBox *box); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorBox, clutter_actor_box_free) - -/* - * ClutterPaintVolume - */ - -CLUTTER_EXPORT -GType clutter_paint_volume_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterPaintVolume *clutter_paint_volume_copy (const ClutterPaintVolume *pv); -CLUTTER_EXPORT -void clutter_paint_volume_free (ClutterPaintVolume *pv); - -CLUTTER_EXPORT -void clutter_paint_volume_set_origin (ClutterPaintVolume *pv, - const graphene_point3d_t *origin); -CLUTTER_EXPORT -void clutter_paint_volume_get_origin (const ClutterPaintVolume *pv, - graphene_point3d_t *vertex); -CLUTTER_EXPORT -void clutter_paint_volume_set_width (ClutterPaintVolume *pv, - gfloat width); -CLUTTER_EXPORT -gfloat clutter_paint_volume_get_width (const ClutterPaintVolume *pv); -CLUTTER_EXPORT -void clutter_paint_volume_set_height (ClutterPaintVolume *pv, - gfloat height); -CLUTTER_EXPORT -gfloat clutter_paint_volume_get_height (const ClutterPaintVolume *pv); -CLUTTER_EXPORT -void clutter_paint_volume_set_depth (ClutterPaintVolume *pv, - gfloat depth); -CLUTTER_EXPORT -gfloat clutter_paint_volume_get_depth (const ClutterPaintVolume *pv); -CLUTTER_EXPORT -void clutter_paint_volume_union (ClutterPaintVolume *pv, - const ClutterPaintVolume *another_pv); -CLUTTER_EXPORT -void clutter_paint_volume_union_box (ClutterPaintVolume *pv, - const ClutterActorBox *box); - -CLUTTER_EXPORT -gboolean clutter_paint_volume_set_from_allocation (ClutterPaintVolume *pv, - ClutterActor *actor); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintVolume, clutter_paint_volume_free) - -/** - * ClutterMargin: - * @left: the margin from the left - * @right: the margin from the right - * @top: the margin from the top - * @bottom: the margin from the bottom - * - * A representation of the components of a margin. - */ -struct _ClutterMargin -{ - float left; - float right; - float top; - float bottom; -}; - -CLUTTER_EXPORT -GType clutter_margin_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterMargin * clutter_margin_new (void) G_GNUC_MALLOC; -CLUTTER_EXPORT -ClutterMargin * clutter_margin_copy (const ClutterMargin *margin_); -CLUTTER_EXPORT -void clutter_margin_free (ClutterMargin *margin_); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMargin, clutter_margin_free) - -/** - * ClutterProgressFunc: - * @a: the initial value of an interval - * @b: the final value of an interval - * @progress: the progress factor, between 0 and 1 - * @retval: the value used to store the progress - * - * Prototype of the progress function used to compute the value - * between the two ends @a and @b of an interval depending on - * the value of @progress. - * - * The #GValue in @retval is already initialized with the same - * type as @a and @b. - * - * This function will be called by #ClutterInterval if the - * type of the values of the interval was registered using - * [func@Clutter.Interval.register_progress_func]. - * - * Return value: %TRUE if the function successfully computed - * the value and stored it inside @retval - */ -typedef gboolean (* ClutterProgressFunc) (const GValue *a, - const GValue *b, - gdouble progress, - GValue *retval); - -CLUTTER_EXPORT -void clutter_interval_register_progress_func (GType value_type, - ClutterProgressFunc func); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter-util.c b/mutter/clutter/clutter/clutter-util.c deleted file mode 100644 index 26f38f0..0000000 --- a/mutter/clutter/clutter/clutter-util.c +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * 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 . - * - * - */ -#include "config.h" - -#include -#include - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-main.h" -#include "clutter/clutter-interval.h" -#include "clutter/clutter-private.h" - -/* Help macros to scale from OpenGL <-1,1> coordinates system to - * window coordinates ranging [0,window-size] - */ -#define MTX_GL_SCALE_X(x,w,v1,v2) ((((((x) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2)) -#define MTX_GL_SCALE_Y(y,w,v1,v2) ((v1) - (((((y) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2)) -#define MTX_GL_SCALE_Z(z,w,v1,v2) (MTX_GL_SCALE_X ((z), (w), (v1), (v2))) - -typedef struct -{ - float x; - float y; - float z; - float w; -} ClutterVertex4; - -void -_clutter_util_fully_transform_vertices (const graphene_matrix_t *modelview, - const graphene_matrix_t *projection, - const float *viewport, - const graphene_point3d_t *vertices_in, - graphene_point3d_t *vertices_out, - int n_vertices) -{ - graphene_matrix_t modelview_projection; - ClutterVertex4 *vertices_tmp; - int i; - - vertices_tmp = g_alloca (sizeof (ClutterVertex4) * n_vertices); - - if (n_vertices >= 4) - { - /* XXX: we should find a way to cache this per actor */ - graphene_matrix_multiply (modelview, projection, &modelview_projection); - - cogl_graphene_matrix_project_points (&modelview_projection, - 3, - sizeof (graphene_point3d_t), - vertices_in, - sizeof (ClutterVertex4), - vertices_tmp, - n_vertices); - } - else - { - cogl_graphene_matrix_transform_points (modelview, - 3, - sizeof (graphene_point3d_t), - vertices_in, - sizeof (ClutterVertex4), - vertices_tmp, - n_vertices); - - cogl_graphene_matrix_project_points (projection, - 3, - sizeof (ClutterVertex4), - vertices_tmp, - sizeof (ClutterVertex4), - vertices_tmp, - n_vertices); - } - - for (i = 0; i < n_vertices; i++) - { - ClutterVertex4 vertex_tmp = vertices_tmp[i]; - graphene_point3d_t *vertex_out = &vertices_out[i]; - /* Finally translate from OpenGL coords to window coords */ - vertex_out->x = MTX_GL_SCALE_X (vertex_tmp.x, - vertex_tmp.w, - viewport[2], - viewport[0]); - vertex_out->y = MTX_GL_SCALE_Y (vertex_tmp.y, - vertex_tmp.w, - viewport[3], - viewport[1]); - clutter_round_to_256ths (&vertex_out->x); - clutter_round_to_256ths (&vertex_out->y); - } -} - -typedef struct -{ - GType value_type; - ClutterProgressFunc func; -} ProgressData; - -G_LOCK_DEFINE_STATIC (progress_funcs); -static GHashTable *progress_funcs = NULL; - -gboolean -_clutter_has_progress_function (GType gtype) -{ - const char *type_name = g_type_name (gtype); - - if (progress_funcs == NULL) - return FALSE; - - return g_hash_table_lookup (progress_funcs, type_name) != NULL; -} - -gboolean -_clutter_run_progress_function (GType gtype, - const GValue *initial, - const GValue *final, - gdouble progress, - GValue *retval) -{ - ProgressData *pdata; - gboolean res; - - G_LOCK (progress_funcs); - - if (G_UNLIKELY (progress_funcs == NULL)) - { - res = FALSE; - goto out; - } - - pdata = g_hash_table_lookup (progress_funcs, g_type_name (gtype)); - if (G_UNLIKELY (pdata == NULL)) - { - res = FALSE; - goto out; - } - - res = pdata->func (initial, final, progress, retval); - -out: - G_UNLOCK (progress_funcs); - - return res; -} - -static void -progress_data_destroy (gpointer data_) -{ - g_free (data_); -} - -/** - * clutter_interval_register_progress_func: (skip) - * @value_type: a #GType - * @func: a #ClutterProgressFunc, or %NULL to unset a previously - * set progress function - * - * Sets the progress function for a given @value_type, like: - * - * ```c - * clutter_interval_register_progress_func (MY_TYPE_FOO, - * my_foo_progress); - * ``` - * - * Whenever a [class@Interval] instance using the default - * [method@Interval.compute_value] implementation is set as an - * interval between two [struct@GObject.Value] of type @value_type, it will call - * @func to establish the value depending on the given progress, - * for instance: - * - * ```c - * static gboolean - * my_int_progress (const GValue *a, - * const GValue *b, - * gdouble progress, - * GValue *retval) - * { - * gint ia = g_value_get_int (a); - * gint ib = g_value_get_int (b); - * gint res = factor * (ib - ia) + ia; - * - * g_value_set_int (retval, res); - * - * return TRUE; - * } - * - * clutter_interval_register_progress_func (G_TYPE_INT, my_int_progress); - * ``` - * - * To unset a previously set progress function of a [alias@GObject.Type], pass %NULL - * for @func. - */ -void -clutter_interval_register_progress_func (GType value_type, - ClutterProgressFunc func) -{ - ProgressData *progress_func; - const char *type_name; - - g_return_if_fail (value_type != G_TYPE_INVALID); - - type_name = g_type_name (value_type); - - G_LOCK (progress_funcs); - - if (G_UNLIKELY (progress_funcs == NULL)) - progress_funcs = g_hash_table_new_full (NULL, NULL, - NULL, - progress_data_destroy); - - progress_func = - g_hash_table_lookup (progress_funcs, type_name); - - if (G_UNLIKELY (progress_func)) - { - if (func == NULL) - { - g_hash_table_remove (progress_funcs, type_name); - g_free (progress_func); - } - else - progress_func->func = func; - } - else - { - progress_func = g_new0 (ProgressData, 1); - progress_func->value_type = value_type; - progress_func->func = func; - - g_hash_table_replace (progress_funcs, - (gpointer) type_name, - progress_func); - } - - G_UNLOCK (progress_funcs); -} - -ClutterTextDirection -clutter_unichar_direction (gunichar ch) -{ - FriBidiCharType fribidi_ch_type; - - G_STATIC_ASSERT (sizeof (FriBidiChar) == sizeof (gunichar)); - - fribidi_ch_type = fribidi_get_bidi_type (ch); - - if (!FRIBIDI_IS_STRONG (fribidi_ch_type)) - return CLUTTER_TEXT_DIRECTION_DEFAULT; - else if (FRIBIDI_IS_RTL (fribidi_ch_type)) - return CLUTTER_TEXT_DIRECTION_RTL; - else - return CLUTTER_TEXT_DIRECTION_LTR; -} - -ClutterTextDirection -_clutter_find_base_dir (const gchar *text, - gint length) -{ - ClutterTextDirection dir = CLUTTER_TEXT_DIRECTION_DEFAULT; - const gchar *p; - - g_return_val_if_fail (text != NULL || length == 0, CLUTTER_TEXT_DIRECTION_DEFAULT); - - p = text; - while ((length < 0 || p < text + length) && *p) - { - gunichar wc = g_utf8_get_char (p); - - dir = clutter_unichar_direction (wc); - - if (dir != CLUTTER_TEXT_DIRECTION_DEFAULT) - break; - - p = g_utf8_next_char (p); - } - - return dir; -} - -PangoDirection -clutter_text_direction_to_pango_direction (ClutterTextDirection dir) -{ - switch (dir) - { - case CLUTTER_TEXT_DIRECTION_RTL: - return PANGO_DIRECTION_RTL; - case CLUTTER_TEXT_DIRECTION_LTR: - return PANGO_DIRECTION_LTR; - default: - case CLUTTER_TEXT_DIRECTION_DEFAULT: - return PANGO_DIRECTION_NEUTRAL; - } -} diff --git a/mutter/clutter/clutter/clutter-virtual-input-device.c b/mutter/clutter/clutter/clutter-virtual-input-device.c deleted file mode 100644 index 4ebefff..0000000 --- a/mutter/clutter/clutter/clutter-virtual-input-device.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2016 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 . - * - * Author: Jonas Ådahl - */ - -#include "config.h" - -#include - -#include "clutter/clutter-virtual-input-device.h" - -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-seat.h" - -enum -{ - PROP_0, - - PROP_SEAT, - PROP_DEVICE_TYPE, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -typedef struct _ClutterVirtualInputDevicePrivate -{ - ClutterSeat *seat; - ClutterInputDeviceType device_type; -} ClutterVirtualInputDevicePrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterVirtualInputDevice, - clutter_virtual_input_device, - G_TYPE_OBJECT) - -void -clutter_virtual_input_device_notify_relative_motion (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - double dx, - double dy) -{ - ClutterVirtualInputDeviceClass *klass = - CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device); - - klass->notify_relative_motion (virtual_device, time_us, dx, dy); -} - -void -clutter_virtual_input_device_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - double x, - double y) -{ - ClutterVirtualInputDeviceClass *klass = - CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device); - - klass->notify_absolute_motion (virtual_device, time_us, x, y); -} - -void -clutter_virtual_input_device_notify_button (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t button, - ClutterButtonState button_state) -{ - ClutterVirtualInputDeviceClass *klass = - CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device); - - klass->notify_button (virtual_device, time_us, button, button_state); -} - -void -clutter_virtual_input_device_notify_key (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t key, - ClutterKeyState key_state) -{ - ClutterVirtualInputDeviceClass *klass = - CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device); - - klass->notify_key (virtual_device, time_us, key, key_state); -} - -void -clutter_virtual_input_device_notify_keyval (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t keyval, - ClutterKeyState key_state) -{ - ClutterVirtualInputDeviceClass *klass = - CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device); - - klass->notify_keyval (virtual_device, time_us, keyval, key_state); -} - -void -clutter_virtual_input_device_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - ClutterScrollDirection direction, - ClutterScrollSource scroll_source) -{ - ClutterVirtualInputDeviceClass *klass = - CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device); - - klass->notify_discrete_scroll (virtual_device, time_us, - direction, scroll_source); -} - -void -clutter_virtual_input_device_notify_scroll_continuous (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - double dx, - double dy, - ClutterScrollSource scroll_source, - ClutterScrollFinishFlags finish_flags) -{ - ClutterVirtualInputDeviceClass *klass = - CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device); - - klass->notify_scroll_continuous (virtual_device, time_us, - dx, dy, scroll_source, finish_flags); -} - -void -clutter_virtual_input_device_notify_touch_down (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - int slot, - double x, - double y) -{ - ClutterVirtualInputDeviceClass *klass = - CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device); - - g_return_if_fail (CLUTTER_IS_VIRTUAL_INPUT_DEVICE (virtual_device)); - g_return_if_fail (slot >= 0 && - slot < CLUTTER_VIRTUAL_INPUT_DEVICE_MAX_TOUCH_SLOTS); - - klass->notify_touch_down (virtual_device, time_us, - slot, x, y); -} - -void -clutter_virtual_input_device_notify_touch_motion (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - int slot, - double x, - double y) -{ - ClutterVirtualInputDeviceClass *klass = - CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device); - - g_return_if_fail (CLUTTER_IS_VIRTUAL_INPUT_DEVICE (virtual_device)); - g_return_if_fail (slot >= 0 && - slot < CLUTTER_VIRTUAL_INPUT_DEVICE_MAX_TOUCH_SLOTS); - - klass->notify_touch_motion (virtual_device, time_us, - slot, x, y); -} - -void -clutter_virtual_input_device_notify_touch_up (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - int slot) -{ - ClutterVirtualInputDeviceClass *klass = - CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device); - - g_return_if_fail (CLUTTER_IS_VIRTUAL_INPUT_DEVICE (virtual_device)); - g_return_if_fail (slot >= 0 && - slot < CLUTTER_VIRTUAL_INPUT_DEVICE_MAX_TOUCH_SLOTS); - - klass->notify_touch_up (virtual_device, time_us, - slot); -} - -int -clutter_virtual_input_device_get_device_type (ClutterVirtualInputDevice *virtual_device) -{ - ClutterVirtualInputDevicePrivate *priv = - clutter_virtual_input_device_get_instance_private (virtual_device); - - return priv->device_type; -} - -/** - * clutter_virtual_input_device_get_seat: - * - * Returns: (transfer none): The seat of the virtual input device - */ -ClutterSeat * -clutter_virtual_input_device_get_seat (ClutterVirtualInputDevice *virtual_device) -{ - ClutterVirtualInputDevicePrivate *priv = - clutter_virtual_input_device_get_instance_private (virtual_device); - - return priv->seat; -} - -static void -clutter_virtual_input_device_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterVirtualInputDevice *virtual_device = - CLUTTER_VIRTUAL_INPUT_DEVICE (object); - ClutterVirtualInputDevicePrivate *priv = - clutter_virtual_input_device_get_instance_private (virtual_device); - - switch (prop_id) - { - case PROP_SEAT: - g_value_set_object (value, priv->seat); - break; - case PROP_DEVICE_TYPE: - g_value_set_enum (value, priv->device_type); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_virtual_input_device_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterVirtualInputDevice *virtual_device = - CLUTTER_VIRTUAL_INPUT_DEVICE (object); - ClutterVirtualInputDevicePrivate *priv = - clutter_virtual_input_device_get_instance_private (virtual_device); - - switch (prop_id) - { - case PROP_SEAT: - priv->seat = g_value_get_object (value); - break; - case PROP_DEVICE_TYPE: - priv->device_type = g_value_get_enum (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_virtual_input_device_init (ClutterVirtualInputDevice *virtual_device) -{ -} - -static void -clutter_virtual_input_device_class_init (ClutterVirtualInputDeviceClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->get_property = clutter_virtual_input_device_get_property; - object_class->set_property = clutter_virtual_input_device_set_property; - - obj_props[PROP_SEAT] = - g_param_spec_object ("seat", NULL, NULL, - CLUTTER_TYPE_SEAT, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - obj_props[PROP_DEVICE_TYPE] = - g_param_spec_enum ("device-type", NULL, NULL, - CLUTTER_TYPE_INPUT_DEVICE_TYPE, - CLUTTER_POINTER_DEVICE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - g_object_class_install_properties (object_class, PROP_LAST, obj_props); -} diff --git a/mutter/clutter/clutter/clutter-virtual-input-device.h b/mutter/clutter/clutter/clutter-virtual-input-device.h deleted file mode 100644 index 2799ade..0000000 --- a/mutter/clutter/clutter/clutter-virtual-input-device.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2016 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 . - * - * Author: Jonas Ådahl - */ - -#pragma once - -#include -#include - -#include "clutter/clutter-seat.h" - -#define CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE (clutter_virtual_input_device_get_type ()) - -#define CLUTTER_VIRTUAL_INPUT_DEVICE_MAX_TOUCH_SLOTS 32u - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterVirtualInputDevice, - clutter_virtual_input_device, - CLUTTER, VIRTUAL_INPUT_DEVICE, - GObject) - -typedef enum _ClutterButtonState -{ - CLUTTER_BUTTON_STATE_RELEASED, - CLUTTER_BUTTON_STATE_PRESSED -} ClutterButtonState; - -typedef enum _ClutterKeyState -{ - CLUTTER_KEY_STATE_RELEASED, - CLUTTER_KEY_STATE_PRESSED -} ClutterKeyState; - -struct _ClutterVirtualInputDeviceClass -{ - GObjectClass parent_class; - - void (*notify_relative_motion) (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - double dx, - double dy); - - void (*notify_absolute_motion) (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - double x, - double y); - - void (*notify_button) (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t button, - ClutterButtonState button_state); - - void (*notify_key) (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t key, - ClutterKeyState key_state); - void (*notify_keyval) (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t keyval, - ClutterKeyState key_state); - - void (*notify_discrete_scroll) (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - ClutterScrollDirection direction, - ClutterScrollSource scroll_source); - - void (*notify_scroll_continuous) (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - double dx, - double dy, - ClutterScrollSource scroll_source, - ClutterScrollFinishFlags finish_flags); - - void (*notify_touch_down) (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - int slot, - double x, - double y); - - void (*notify_touch_motion) (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - int slot, - double x, - double y); - - void (*notify_touch_up) (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - int slot); -}; - -CLUTTER_EXPORT -void clutter_virtual_input_device_notify_relative_motion (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - double dx, - double dy); - -CLUTTER_EXPORT -void clutter_virtual_input_device_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - double x, - double y); - -CLUTTER_EXPORT -void clutter_virtual_input_device_notify_button (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t button, - ClutterButtonState button_state); - -CLUTTER_EXPORT -void clutter_virtual_input_device_notify_key (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t key, - ClutterKeyState key_state); - -CLUTTER_EXPORT -void clutter_virtual_input_device_notify_keyval (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t keyval, - ClutterKeyState key_state); - -CLUTTER_EXPORT -void clutter_virtual_input_device_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - ClutterScrollDirection direction, - ClutterScrollSource scroll_source); - -CLUTTER_EXPORT -void clutter_virtual_input_device_notify_scroll_continuous (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - double dx, - double dy, - ClutterScrollSource scroll_source, - ClutterScrollFinishFlags finish_flags); - -CLUTTER_EXPORT -void clutter_virtual_input_device_notify_touch_down (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - int slot, - double x, - double y); - -CLUTTER_EXPORT -void clutter_virtual_input_device_notify_touch_motion (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - int slot, - double x, - double y); - -CLUTTER_EXPORT -void clutter_virtual_input_device_notify_touch_up (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - int slot); - -CLUTTER_EXPORT -int clutter_virtual_input_device_get_device_type (ClutterVirtualInputDevice *virtual_device); - -CLUTTER_EXPORT -ClutterSeat * clutter_virtual_input_device_get_seat (ClutterVirtualInputDevice *virtual_device); diff --git a/mutter/clutter/clutter/clutter-zoom-action.c b/mutter/clutter/clutter/clutter-zoom-action.c deleted file mode 100644 index 4de4aa5..0000000 --- a/mutter/clutter/clutter/clutter-zoom-action.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Lionel Landwerlin - */ - -/** - * ClutterZoomAction: - * - * Action enabling zooming on actors - * - * #ClutterZoomAction is a sub-class of [class@GestureAction] that - * implements all the necessary logic for zooming actors using a "pinch" - * gesture between two touch points. - * - * The simplest usage of [class@ZoomAction] consists in adding it to - * a [class@Actor] and setting it as reactive; for instance, the following - * code: - * - * ```c - * clutter_actor_add_action (actor, clutter_zoom_action_new ()); - * clutter_actor_set_reactive (actor, TRUE); - * ``` - * - * will automatically result in the actor to be scale according to the - * distance between two touch points. - */ - -#include "config.h" - -#include - -#include "clutter/clutter-zoom-action.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-private.h" -#include "clutter/clutter-stage-private.h" - -typedef struct -{ - gfloat start_x; - gfloat start_y; - gfloat transformed_start_x; - gfloat transformed_start_y; - - gfloat update_x; - gfloat update_y; - gfloat transformed_update_x; - gfloat transformed_update_y; -} ZoomPoint; - -typedef struct _ClutterZoomActionPrivate -{ - ClutterStage *stage; - - ZoomPoint points[2]; - - graphene_point_t initial_focal_point; - graphene_point_t focal_point; - graphene_point_t transformed_focal_point; - - gfloat initial_x; - gfloat initial_y; - gfloat initial_z; - - gdouble initial_scale_x; - gdouble initial_scale_y; - - gdouble zoom_initial_distance; -} ClutterZoomActionPrivate; - -enum -{ - ZOOM, - - LAST_SIGNAL -}; - -static guint zoom_signals[LAST_SIGNAL] = { 0, }; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterZoomAction, clutter_zoom_action, CLUTTER_TYPE_GESTURE_ACTION) - -static void -capture_point_initial_position (ClutterGestureAction *action, - ClutterActor *actor, - gint index, - ZoomPoint *point) -{ - clutter_gesture_action_get_motion_coords (action, index, - &point->start_x, - &point->start_y); - - point->transformed_start_x = point->update_x = point->start_x; - point->transformed_start_y = point->update_x = point->start_y; - clutter_actor_transform_stage_point (actor, - point->start_x, point->start_y, - &point->transformed_start_x, - &point->transformed_start_y); - point->transformed_update_x = point->transformed_start_x; - point->transformed_update_y = point->transformed_start_y; -} - -static void -capture_point_update_position (ClutterGestureAction *action, - ClutterActor *actor, - gint index, - ZoomPoint *point) -{ - clutter_gesture_action_get_motion_coords (action, index, - &point->update_x, - &point->update_y); - - point->transformed_update_x = point->update_x; - point->transformed_update_y = point->update_y; - clutter_actor_transform_stage_point (actor, - point->update_x, point->update_y, - &point->transformed_update_x, - &point->transformed_update_y); -} - -static gboolean -clutter_zoom_action_gesture_begin (ClutterGestureAction *action, - ClutterActor *actor) -{ - ClutterZoomActionPrivate *priv = - clutter_zoom_action_get_instance_private (CLUTTER_ZOOM_ACTION (action)); - gfloat dx, dy; - - capture_point_initial_position (action, actor, 0, &priv->points[0]); - capture_point_initial_position (action, actor, 1, &priv->points[1]); - - dx = priv->points[1].transformed_start_x - priv->points[0].transformed_start_x; - dy = priv->points[1].transformed_start_y - priv->points[0].transformed_start_y; - priv->zoom_initial_distance = sqrt (dx * dx + dy * dy); - - clutter_actor_get_translation (actor, - &priv->initial_x, - &priv->initial_y, - &priv->initial_z); - clutter_actor_get_scale (actor, - &priv->initial_scale_x, - &priv->initial_scale_y); - - priv->initial_focal_point.x = (priv->points[0].start_x + priv->points[1].start_x) / 2; - priv->initial_focal_point.y = (priv->points[0].start_y + priv->points[1].start_y) / 2; - clutter_actor_transform_stage_point (actor, - priv->initial_focal_point.x, - priv->initial_focal_point.y, - &priv->transformed_focal_point.x, - &priv->transformed_focal_point.y); - - clutter_actor_set_pivot_point (actor, - priv->transformed_focal_point.x / clutter_actor_get_width (actor), - priv->transformed_focal_point.y / clutter_actor_get_height (actor)); - - return TRUE; -} - -static gboolean -clutter_zoom_action_gesture_progress (ClutterGestureAction *action, - ClutterActor *actor) -{ - ClutterZoomActionPrivate *priv = - clutter_zoom_action_get_instance_private (CLUTTER_ZOOM_ACTION (action)); - gdouble distance, new_scale; - gfloat dx, dy; - gboolean retval; - - capture_point_update_position (action, actor, 0, &priv->points[0]); - capture_point_update_position (action, actor, 1, &priv->points[1]); - - dx = priv->points[1].update_x - priv->points[0].update_x; - dy = priv->points[1].update_y - priv->points[0].update_y; - distance = sqrt (dx * dx + dy * dy); - - if (distance == 0) - return TRUE; - - priv->focal_point.x = (priv->points[0].update_x + priv->points[1].update_x) / 2; - priv->focal_point.y = (priv->points[0].update_y + priv->points[1].update_y) / 2; - - new_scale = distance / priv->zoom_initial_distance; - - g_signal_emit (action, zoom_signals[ZOOM], 0, - actor, &priv->focal_point, new_scale, - &retval); - - return TRUE; -} - -static void -clutter_zoom_action_gesture_cancel (ClutterGestureAction *action, - ClutterActor *actor) -{ - ClutterZoomActionPrivate *priv = - clutter_zoom_action_get_instance_private (CLUTTER_ZOOM_ACTION (action)); - - clutter_actor_set_translation (actor, - priv->initial_x, - priv->initial_y, - priv->initial_z); - clutter_actor_set_scale (actor, priv->initial_scale_x, priv->initial_scale_y); -} - -static void -clutter_zoom_action_constructed (GObject *gobject) -{ - ClutterGestureAction *gesture; - - gesture = CLUTTER_GESTURE_ACTION (gobject); - clutter_gesture_action_set_threshold_trigger_edge (gesture, CLUTTER_GESTURE_TRIGGER_EDGE_NONE); -} - -static void -clutter_zoom_action_class_init (ClutterZoomActionClass *klass) -{ - ClutterGestureActionClass *gesture_class = - CLUTTER_GESTURE_ACTION_CLASS (klass); - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->constructed = clutter_zoom_action_constructed; - - gesture_class->gesture_begin = clutter_zoom_action_gesture_begin; - gesture_class->gesture_progress = clutter_zoom_action_gesture_progress; - gesture_class->gesture_cancel = clutter_zoom_action_gesture_cancel; - - /** - * ClutterZoomAction::zoom: - * @action: the #ClutterZoomAction that emitted the signal - * @actor: the #ClutterActor attached to the action - * @focal_point: the focal point of the zoom - * @factor: the initial distance between the 2 touch points - * - * The signal is emitted for each series of touch events that - * change the distance and focal point between the touch points. - * - * The default handler of the signal will call - * [method@Actor.set_scale] on @actor using the ratio of the first - * distance between the touch points and the current distance. To - * override the default behaviour, connect to this signal and return - * %FALSE. - * - * Return value: %TRUE if the zoom should continue, and %FALSE if - * the zoom should be cancelled. - */ - zoom_signals[ZOOM] = - g_signal_new (I_("zoom"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, g_signal_accumulator_true_handled, NULL, - _clutter_marshal_BOOLEAN__OBJECT_BOXED_DOUBLE, - G_TYPE_BOOLEAN, 3, - CLUTTER_TYPE_ACTOR, - GRAPHENE_TYPE_POINT, - G_TYPE_DOUBLE); -} - -static void -clutter_zoom_action_init (ClutterZoomAction *self) -{ - clutter_gesture_action_set_n_touch_points (CLUTTER_GESTURE_ACTION (self), - 2); -} - -/** - * clutter_zoom_action_new: - * - * Creates a new #ClutterZoomAction instance - * - * Return value: the newly created #ClutterZoomAction - */ -ClutterAction * -clutter_zoom_action_new (void) -{ - return g_object_new (CLUTTER_TYPE_ZOOM_ACTION, NULL); -} - -/** - * clutter_zoom_action_get_focal_point: - * @action: a #ClutterZoomAction - * @point: (out): a #graphene_point_t - * - * Retrieves the focal point of the current zoom - */ -void -clutter_zoom_action_get_focal_point (ClutterZoomAction *action, - graphene_point_t *point) -{ - ClutterZoomActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ZOOM_ACTION (action)); - g_return_if_fail (point != NULL); - - priv = clutter_zoom_action_get_instance_private (action); - - *point = priv->focal_point; -} - -/** - * clutter_zoom_action_get_transformed_focal_point: - * @action: a #ClutterZoomAction - * @point: (out): a #graphene_point_t - * - * Retrieves the focal point relative to the actor's coordinates of - * the current zoom - */ -void -clutter_zoom_action_get_transformed_focal_point (ClutterZoomAction *action, - graphene_point_t *point) -{ - ClutterZoomActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ZOOM_ACTION (action)); - g_return_if_fail (point != NULL); - - priv = clutter_zoom_action_get_instance_private (action); - - *point = priv->transformed_focal_point; -} diff --git a/mutter/clutter/clutter/clutter-zoom-action.h b/mutter/clutter/clutter/clutter-zoom-action.h deleted file mode 100644 index acc0199..0000000 --- a/mutter/clutter/clutter/clutter-zoom-action.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Lionel Landwerlin - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-event.h" -#include "clutter/clutter-gesture-action.h" -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_ZOOM_ACTION (clutter_zoom_action_get_type ()) - -CLUTTER_EXPORT -G_DECLARE_DERIVABLE_TYPE (ClutterZoomAction, - clutter_zoom_action, - CLUTTER, - ZOOM_ACTION, - ClutterGestureAction) - -/** - * ClutterZoomActionClass: - * @zoom: class handler of the #ClutterZoomAction::zoom signal - * - * The #ClutterZoomActionClass structure contains - * only private data - */ -struct _ClutterZoomActionClass -{ - /*< private >*/ - ClutterGestureActionClass parent_class; -}; - -CLUTTER_EXPORT -ClutterAction * clutter_zoom_action_new (void); - -CLUTTER_EXPORT -void clutter_zoom_action_get_focal_point (ClutterZoomAction *action, - graphene_point_t *point); -CLUTTER_EXPORT -void clutter_zoom_action_get_transformed_focal_point (ClutterZoomAction *action, - graphene_point_t *point); - -G_END_DECLS diff --git a/mutter/clutter/clutter/clutter.h b/mutter/clutter/clutter/clutter.h deleted file mode 100644 index 69cc986..0000000 --- a/mutter/clutter/clutter/clutter.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * 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 . - * - * - */ - -#pragma once - -#define __CLUTTER_H_INSIDE__ - -#include "clutter/clutter-types.h" - -#include "clutter/clutter-action.h" -#include "clutter/clutter-actor.h" -#include "clutter/clutter-actor-meta.h" -#include "clutter/clutter-align-constraint.h" -#include "clutter/clutter-animatable.h" -#include "clutter/clutter-backend.h" -#include "clutter/clutter-bind-constraint.h" -#include "clutter/clutter-binding-pool.h" -#include "clutter/clutter-bin-layout.h" -#include "clutter/clutter-blur-effect.h" -#include "clutter/clutter-box-layout.h" -#include "clutter/clutter-brightness-contrast-effect.h" -#include "clutter/clutter-click-action.h" -#include "clutter/clutter-clone.h" -#include "clutter/clutter-color.h" -#include "clutter/clutter-color-state.h" -#include "clutter/clutter-colorize-effect.h" -#include "clutter/clutter-constraint.h" -#include "clutter/clutter-content.h" -#include "clutter/clutter-deform-effect.h" -#include "clutter/clutter-desaturate-effect.h" -#include "clutter/clutter-effect.h" -#include "clutter/clutter-enums.h" -#include "clutter/clutter-enum-types.h" -#include "clutter/clutter-event.h" -#include "clutter/clutter-fixed-layout.h" -#include "clutter/clutter-flow-layout.h" -#include "clutter/clutter-frame-clock.h" -#include "clutter/clutter-frame.h" -#include "clutter/clutter-gesture-action.h" -#include "clutter/clutter-gesture.h" -#include "clutter/clutter-grab.h" -#include "clutter/clutter-grid-layout.h" -#include "clutter/clutter-image.h" -#include "clutter/clutter-input-device.h" -#include "clutter/clutter-input-device-tool.h" -#include "clutter/clutter-input-method.h" -#include "clutter/clutter-input-focus.h" -#include "clutter/clutter-interval.h" -#include "clutter/clutter-keyframe-transition.h" -#include "clutter/clutter-keymap.h" -#include "clutter/clutter-keysyms.h" -#include "clutter/clutter-keyval.h" -#include "clutter/clutter-layout-manager.h" -#include "clutter/clutter-layout-meta.h" -#include "clutter/clutter-macros.h" -#include "clutter/clutter-main.h" -#include "clutter/clutter-offscreen-effect.h" -#include "clutter/clutter-page-turn-effect.h" -#include "clutter/clutter-paint-nodes.h" -#include "clutter/clutter-paint-node.h" -#include "clutter/clutter-pan-action.h" -#include "clutter/clutter-property-transition.h" -#include "clutter/clutter-rotate-action.h" -#include "clutter/clutter-scroll-actor.h" -#include "clutter/clutter-settings.h" -#include "clutter/clutter-shader-effect.h" -#include "clutter/clutter-shader-types.h" -#include "clutter/clutter-swipe-action.h" -#include "clutter/clutter-snap-constraint.h" -#include "clutter/clutter-stage.h" -#include "clutter/clutter-stage-manager.h" -#include "clutter/clutter-stage-view.h" -#include "clutter/clutter-tap-action.h" -#include "clutter/clutter-text.h" -#include "clutter/clutter-texture-content.h" -#include "clutter/clutter-timeline.h" -#include "clutter/clutter-transition-group.h" -#include "clutter/clutter-transition.h" -#include "clutter/clutter-virtual-input-device.h" -#include "clutter/clutter-zoom-action.h" - -#undef __CLUTTER_H_INSIDE__ diff --git a/mutter/clutter/clutter/gen-keyname-table.pl b/mutter/clutter/clutter/gen-keyname-table.pl deleted file mode 100644 index 612c745..0000000 --- a/mutter/clutter/clutter/gen-keyname-table.pl +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/perl -w -# Slightly modified version of - -if (@ARGV != 1) { - die "Usage: gen-keyname-table.pl keynames.txt > keyname-table.h\n"; -} - -open IN, $ARGV[0] || die "Cannot open $ARGV[0]: $!\n"; - -@keys = (); -@translate = (); -while (defined($_ = )) { - next if /^!/; - if (!/^\s*(0x[0-9a-f]+)\s+([\w_]*\S)\s+(1)?\s*$/) { - die "Cannot parse line $_"; - } - - push @keys, [$1, $2]; - - if (defined ($3)) { - push @translate, $2; - } -} -close IN; - -$offset = 0; - -$date = gmtime; - -print <[1]; - - if ($offset != 0) { - print qq(\n); - } - print qq( "$name\\0"); - - $key->[3] = $offset; - $offset += length($name) + 1; -} - -print ";\n\n"; - -print <[0]; - $name = $key->[1]; - $offset = $key->[3]; - - if ($i != 0) { - print ",\n"; - } - print " { $keyval, $offset }"; - $i++; -} - -print "\n};\n\n"; - -@keys = sort { $a->[1] cmp $b->[1] } @keys; - - -print <[0]; - $name = $key->[1]; - $offset = $key->[3]; - - if ($i != 0) { - print ",\n"; - } - print " { $keyval, $offset }"; - $i++; -} - -print < -#include - -#include "cogl-pango/cogl-pango-display-list.h" -#include "cogl-pango/cogl-pango-pipeline-cache.h" -#include "cogl/cogl-context-private.h" - -typedef enum -{ - COGL_PANGO_DISPLAY_LIST_TEXTURE, - COGL_PANGO_DISPLAY_LIST_RECTANGLE, - COGL_PANGO_DISPLAY_LIST_TRAPEZOID -} CoglPangoDisplayListNodeType; - -typedef struct _CoglPangoDisplayListNode CoglPangoDisplayListNode; -typedef struct _CoglPangoDisplayListRectangle CoglPangoDisplayListRectangle; - -struct _CoglPangoDisplayList -{ - gboolean color_override; - CoglColor color; - GSList *nodes; - GSList *last_node; - CoglPangoPipelineCache *pipeline_cache; -}; - -/* This matches the format expected by cogl_rectangles_with_texture_coords */ -struct _CoglPangoDisplayListRectangle -{ - float x_1, y_1, x_2, y_2; - float s_1, t_1, s_2, t_2; -}; - -struct _CoglPangoDisplayListNode -{ - CoglPangoDisplayListNodeType type; - - gboolean color_override; - CoglColor color; - - CoglPipeline *pipeline; - - union - { - struct - { - /* The texture to render these coords from */ - CoglTexture *texture; - /* Array of rectangles in the format expected by - cogl_rectangles_with_texture_coords */ - GArray *rectangles; - /* A primitive representing those vertices */ - CoglPrimitive *primitive; - guint has_color : 1; - } texture; - - struct - { - float x_1, y_1; - float x_2, y_2; - } rectangle; - - struct - { - CoglPrimitive *primitive; - } trapezoid; - } d; -}; - -CoglPangoDisplayList * -_cogl_pango_display_list_new (CoglPangoPipelineCache *pipeline_cache) -{ - CoglPangoDisplayList *dl = g_new0 (CoglPangoDisplayList, 1); - - dl->pipeline_cache = pipeline_cache; - - return dl; -} - -static void -_cogl_pango_display_list_append_node (CoglPangoDisplayList *dl, - CoglPangoDisplayListNode *node) -{ - if (dl->last_node) - dl->last_node = dl->last_node->next = g_slist_prepend (NULL, node); - else - dl->last_node = dl->nodes = g_slist_prepend (NULL, node); -} - -void -_cogl_pango_display_list_set_color_override (CoglPangoDisplayList *dl, - const CoglColor *color) -{ - dl->color_override = TRUE; - dl->color = *color; -} - -void -_cogl_pango_display_list_remove_color_override (CoglPangoDisplayList *dl) -{ - dl->color_override = FALSE; -} - -void -_cogl_pango_display_list_add_texture (CoglPangoDisplayList *dl, - CoglTexture *texture, - float x_1, float y_1, - float x_2, float y_2, - float tx_1, float ty_1, - float tx_2, float ty_2) -{ - CoglPangoDisplayListNode *node; - CoglPangoDisplayListRectangle *rectangle; - - /* Add to the last node if it is a texture node with the same - target texture */ - if (dl->last_node - && (node = dl->last_node->data)->type == COGL_PANGO_DISPLAY_LIST_TEXTURE - && node->d.texture.texture == texture - && (dl->color_override - ? (node->color_override && cogl_color_equal (&dl->color, &node->color)) - : !node->color_override)) - { - /* Get rid of the vertex buffer so that it will be recreated */ - if (node->d.texture.primitive != NULL) - { - g_object_unref (node->d.texture.primitive); - node->d.texture.primitive = NULL; - } - } - else - { - /* Otherwise create a new node */ - node = g_new0 (CoglPangoDisplayListNode, 1); - - node->type = COGL_PANGO_DISPLAY_LIST_TEXTURE; - node->color_override = dl->color_override; - node->color = dl->color; - node->pipeline = NULL; - node->d.texture.texture = g_object_ref (texture); - node->d.texture.rectangles - = g_array_new (FALSE, FALSE, sizeof (CoglPangoDisplayListRectangle)); - node->d.texture.primitive = NULL; - - _cogl_pango_display_list_append_node (dl, node); - } - - g_array_set_size (node->d.texture.rectangles, - node->d.texture.rectangles->len + 1); - rectangle = &g_array_index (node->d.texture.rectangles, - CoglPangoDisplayListRectangle, - node->d.texture.rectangles->len - 1); - rectangle->x_1 = x_1; - rectangle->y_1 = y_1; - rectangle->x_2 = x_2; - rectangle->y_2 = y_2; - rectangle->s_1 = tx_1; - rectangle->t_1 = ty_1; - rectangle->s_2 = tx_2; - rectangle->t_2 = ty_2; -} - -void -_cogl_pango_display_list_add_rectangle (CoglPangoDisplayList *dl, - float x_1, float y_1, - float x_2, float y_2) -{ - CoglPangoDisplayListNode *node = g_new0 (CoglPangoDisplayListNode, 1); - - node->type = COGL_PANGO_DISPLAY_LIST_RECTANGLE; - node->color_override = dl->color_override; - node->color = dl->color; - node->d.rectangle.x_1 = x_1; - node->d.rectangle.y_1 = y_1; - node->d.rectangle.x_2 = x_2; - node->d.rectangle.y_2 = y_2; - node->pipeline = NULL; - - _cogl_pango_display_list_append_node (dl, node); -} - -void -_cogl_pango_display_list_add_trapezoid (CoglPangoDisplayList *dl, - float y_1, - float x_11, - float x_21, - float y_2, - float x_12, - float x_22) -{ - CoglContext *ctx = dl->pipeline_cache->ctx; - CoglPangoDisplayListNode *node = g_new0 (CoglPangoDisplayListNode, 1); - CoglVertexP2 vertices[4] = { - { x_11, y_1 }, - { x_12, y_2 }, - { x_22, y_2 }, - { x_21, y_1 } - }; - - node->type = COGL_PANGO_DISPLAY_LIST_TRAPEZOID; - node->color_override = dl->color_override; - node->color = dl->color; - node->pipeline = NULL; - - node->d.trapezoid.primitive = - cogl_primitive_new_p2 (ctx, - COGL_VERTICES_MODE_TRIANGLE_FAN, - 4, - vertices); - - _cogl_pango_display_list_append_node (dl, node); -} - -static void -emit_rectangles_through_journal (CoglFramebuffer *fb, - CoglPipeline *pipeline, - CoglPangoDisplayListNode *node) -{ - const float *rectangles = (const float *)node->d.texture.rectangles->data; - - cogl_framebuffer_draw_textured_rectangles (fb, - pipeline, - rectangles, - node->d.texture.rectangles->len); -} - -static void -emit_vertex_buffer_geometry (CoglFramebuffer *fb, - CoglPipeline *pipeline, - CoglPangoDisplayListNode *node) -{ - CoglContext *ctx = cogl_framebuffer_get_context (fb); - - /* It's expensive to go through the Cogl journal for large runs - * of text in part because the journal transforms the quads in software - * to avoid changing the modelview matrix. So for larger runs of text - * we load the vertices into a VBO, and this has the added advantage - * that if the text doesn't change from frame to frame the VBO can - * be re-used avoiding the repeated cost of validating the data and - * mapping it into the GPU... */ - - if (node->d.texture.primitive == NULL) - { - CoglAttributeBuffer *buffer; - CoglVertexP2T2 *verts, *v; - int n_verts; - gboolean allocated = FALSE; - CoglAttribute *attributes[2]; - CoglPrimitive *prim; - CoglIndices *indices; - int i; - - n_verts = node->d.texture.rectangles->len * 4; - - buffer - = cogl_attribute_buffer_new_with_size (ctx, - n_verts * - sizeof (CoglVertexP2T2)); - - if ((verts = cogl_buffer_map (COGL_BUFFER (buffer), - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD)) == NULL) - { - verts = g_new (CoglVertexP2T2, n_verts); - allocated = TRUE; - } - - v = verts; - - /* Copy the rectangles into the buffer and expand into four - vertices instead of just two */ - for (i = 0; i < node->d.texture.rectangles->len; i++) - { - const CoglPangoDisplayListRectangle *rectangle - = &g_array_index (node->d.texture.rectangles, - CoglPangoDisplayListRectangle, i); - - v->x = rectangle->x_1; - v->y = rectangle->y_1; - v->s = rectangle->s_1; - v->t = rectangle->t_1; - v++; - v->x = rectangle->x_1; - v->y = rectangle->y_2; - v->s = rectangle->s_1; - v->t = rectangle->t_2; - v++; - v->x = rectangle->x_2; - v->y = rectangle->y_2; - v->s = rectangle->s_2; - v->t = rectangle->t_2; - v++; - v->x = rectangle->x_2; - v->y = rectangle->y_1; - v->s = rectangle->s_2; - v->t = rectangle->t_1; - v++; - } - - if (allocated) - { - cogl_buffer_set_data (COGL_BUFFER (buffer), - 0, /* offset */ - verts, - sizeof (CoglVertexP2T2) * n_verts); - g_free (verts); - } - else - cogl_buffer_unmap (COGL_BUFFER (buffer)); - - attributes[0] = cogl_attribute_new (buffer, - "cogl_position_in", - sizeof (CoglVertexP2T2), - G_STRUCT_OFFSET (CoglVertexP2T2, x), - 2, /* n_components */ - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (buffer, - "cogl_tex_coord0_in", - sizeof (CoglVertexP2T2), - G_STRUCT_OFFSET (CoglVertexP2T2, s), - 2, /* n_components */ - COGL_ATTRIBUTE_TYPE_FLOAT); - - prim = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES, - n_verts, - attributes, - 2 /* n_attributes */); - - indices = - cogl_get_rectangle_indices (ctx, node->d.texture.rectangles->len); - - cogl_primitive_set_indices (prim, indices, - node->d.texture.rectangles->len * 6); - - node->d.texture.primitive = prim; - - g_object_unref (buffer); - g_object_unref (attributes[0]); - g_object_unref (attributes[1]); - } - - cogl_primitive_draw (node->d.texture.primitive, - fb, - pipeline); -} - -static void -_cogl_framebuffer_draw_display_list_texture (CoglFramebuffer *fb, - CoglPipeline *pipeline, - CoglPangoDisplayListNode *node) -{ - /* For small runs of text like icon labels, we can get better performance - * going through the Cogl journal since text may then be batched together - * with other geometry. */ - /* FIXME: 25 is a number I plucked out of thin air; it would be good - * to determine this empirically! */ - if (node->d.texture.rectangles->len < 25) - emit_rectangles_through_journal (fb, pipeline, node); - else - emit_vertex_buffer_geometry (fb, pipeline, node); -} - -void -_cogl_pango_display_list_render (CoglFramebuffer *fb, - CoglPangoDisplayList *dl, - const CoglColor *color) -{ - GSList *l; - - for (l = dl->nodes; l; l = l->next) - { - CoglPangoDisplayListNode *node = l->data; - CoglColor draw_color; - - if (node->pipeline == NULL) - { - if (node->type == COGL_PANGO_DISPLAY_LIST_TEXTURE) - node->pipeline = - _cogl_pango_pipeline_cache_get (dl->pipeline_cache, - node->d.texture.texture); - else - node->pipeline = - _cogl_pango_pipeline_cache_get (dl->pipeline_cache, - NULL); - } - - if (node->color_override) - /* Use the override color but preserve the alpha from the - draw color */ - cogl_color_init_from_4f (&draw_color, - cogl_color_get_red (&node->color), - cogl_color_get_green (&node->color), - cogl_color_get_blue (&node->color), - (cogl_color_get_alpha (&node->color) * - cogl_color_get_alpha (color))); - else - draw_color = *color; - cogl_color_premultiply (&draw_color); - - cogl_pipeline_set_color (node->pipeline, &draw_color); - - switch (node->type) - { - case COGL_PANGO_DISPLAY_LIST_TEXTURE: - _cogl_framebuffer_draw_display_list_texture (fb, node->pipeline, node); - break; - - case COGL_PANGO_DISPLAY_LIST_RECTANGLE: - cogl_framebuffer_draw_rectangle (fb, - node->pipeline, - node->d.rectangle.x_1, - node->d.rectangle.y_1, - node->d.rectangle.x_2, - node->d.rectangle.y_2); - break; - - case COGL_PANGO_DISPLAY_LIST_TRAPEZOID: - cogl_primitive_draw (node->d.trapezoid.primitive, - fb, - node->pipeline); - break; - } - } -} - -static void -_cogl_pango_display_list_node_free (CoglPangoDisplayListNode *node) -{ - if (node->type == COGL_PANGO_DISPLAY_LIST_TEXTURE) - { - g_array_free (node->d.texture.rectangles, TRUE); - if (node->d.texture.texture != NULL) - g_object_unref (node->d.texture.texture); - if (node->d.texture.primitive != NULL) - g_object_unref (node->d.texture.primitive); - } - else if (node->type == COGL_PANGO_DISPLAY_LIST_TRAPEZOID) - g_object_unref (node->d.trapezoid.primitive); - - if (node->pipeline) - g_object_unref (node->pipeline); - - g_free (node); -} - -void -_cogl_pango_display_list_clear (CoglPangoDisplayList *dl) -{ - g_slist_free_full (dl->nodes, (GDestroyNotify) - _cogl_pango_display_list_node_free); - dl->nodes = NULL; - dl->last_node = NULL; -} - -void -_cogl_pango_display_list_free (CoglPangoDisplayList *dl) -{ - _cogl_pango_display_list_clear (dl); - g_free (dl); -} diff --git a/mutter/cogl/cogl-pango/cogl-pango-display-list.h b/mutter/cogl/cogl-pango/cogl-pango-display-list.h deleted file mode 100644 index c186124..0000000 --- a/mutter/cogl/cogl-pango/cogl-pango-display-list.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#include - -#include "cogl-pango/cogl-pango-pipeline-cache.h" - -G_BEGIN_DECLS - -typedef struct _CoglPangoDisplayList CoglPangoDisplayList; - -CoglPangoDisplayList * -_cogl_pango_display_list_new (CoglPangoPipelineCache *); - -void -_cogl_pango_display_list_set_color_override (CoglPangoDisplayList *dl, - const CoglColor *color); - -void -_cogl_pango_display_list_remove_color_override (CoglPangoDisplayList *dl); - -void -_cogl_pango_display_list_add_texture (CoglPangoDisplayList *dl, - CoglTexture *texture, - float x_1, float y_1, - float x_2, float y_2, - float tx_1, float ty_1, - float tx_2, float ty_2); - -void -_cogl_pango_display_list_add_rectangle (CoglPangoDisplayList *dl, - float x_1, float y_1, - float x_2, float y_2); - -void -_cogl_pango_display_list_add_trapezoid (CoglPangoDisplayList *dl, - float y_1, - float x_11, - float x_21, - float y_2, - float x_12, - float x_22); - -void -_cogl_pango_display_list_render (CoglFramebuffer *framebuffer, - CoglPangoDisplayList *dl, - const CoglColor *color); - -void -_cogl_pango_display_list_clear (CoglPangoDisplayList *dl); - -void -_cogl_pango_display_list_free (CoglPangoDisplayList *dl); - -G_END_DECLS diff --git a/mutter/cogl/cogl-pango/cogl-pango-fontmap.c b/mutter/cogl/cogl-pango/cogl-pango-fontmap.c deleted file mode 100644 index ebfea6c..0000000 --- a/mutter/cogl/cogl-pango/cogl-pango-fontmap.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008 OpenedHand - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "config.h" - -#include -#include -#include - -#include "cogl-pango/cogl-pango.h" -#include "cogl-pango/cogl-pango-private.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-context-private.h" - -static GQuark cogl_pango_font_map_get_priv_key (void) G_GNUC_CONST; - -typedef struct _CoglPangoFontMapPriv -{ - CoglContext *ctx; - PangoRenderer *renderer; -} CoglPangoFontMapPriv; - -static void -free_priv (gpointer data) -{ - CoglPangoFontMapPriv *priv = data; - - g_object_unref (priv->ctx); - g_object_unref (priv->renderer); - - g_free (priv); -} - -PangoFontMap * -cogl_pango_font_map_new (void) -{ - PangoFontMap *fm = pango_cairo_font_map_new (); - g_autofree CoglPangoFontMapPriv *priv = g_new0 (CoglPangoFontMapPriv, 1); - - _COGL_GET_CONTEXT (context, NULL); - - priv->ctx = g_object_ref (context); - - /* XXX: The public pango api doesn't let us sub-class - * PangoCairoFontMap so we attach our own private data using qdata - * for now. */ - g_object_set_qdata_full (G_OBJECT (fm), - cogl_pango_font_map_get_priv_key (), - g_steal_pointer (&priv), - free_priv); - - return fm; -} - -PangoContext * -cogl_pango_font_map_create_context (CoglPangoFontMap *fm) -{ - g_return_val_if_fail (COGL_PANGO_IS_FONT_MAP (fm), NULL); - - return pango_font_map_create_context (PANGO_FONT_MAP (fm)); -} - -static CoglPangoFontMapPriv * -_cogl_pango_font_map_get_priv (CoglPangoFontMap *fm) -{ - return g_object_get_qdata (G_OBJECT (fm), - cogl_pango_font_map_get_priv_key ()); -} - -PangoRenderer * -_cogl_pango_font_map_get_renderer (CoglPangoFontMap *fm) -{ - CoglPangoFontMapPriv *priv = _cogl_pango_font_map_get_priv (fm); - if (G_UNLIKELY (!priv->renderer)) - priv->renderer = _cogl_pango_renderer_new (priv->ctx); - return priv->renderer; -} - -PangoRenderer * -cogl_pango_font_map_get_renderer (CoglPangoFontMap *fm) -{ - return _cogl_pango_font_map_get_renderer (fm); -} - -CoglContext * -_cogl_pango_font_map_get_cogl_context (CoglPangoFontMap *fm) -{ - CoglPangoFontMapPriv *priv = _cogl_pango_font_map_get_priv (fm); - return priv->ctx; -} - -void -cogl_pango_font_map_set_resolution (CoglPangoFontMap *font_map, - double dpi) -{ - g_return_if_fail (COGL_PANGO_IS_FONT_MAP (font_map)); - - pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (font_map), dpi); -} - -void -cogl_pango_font_map_clear_glyph_cache (CoglPangoFontMap *fm) -{ - PangoRenderer *renderer = _cogl_pango_font_map_get_renderer (fm); - - _cogl_pango_renderer_clear_glyph_cache (COGL_PANGO_RENDERER (renderer)); -} - -void -cogl_pango_font_map_set_use_mipmapping (CoglPangoFontMap *fm, - gboolean value) -{ - PangoRenderer *renderer = _cogl_pango_font_map_get_renderer (fm); - - _cogl_pango_renderer_set_use_mipmapping (COGL_PANGO_RENDERER (renderer), - value); -} - -gboolean -cogl_pango_font_map_get_use_mipmapping (CoglPangoFontMap *fm) -{ - PangoRenderer *renderer = _cogl_pango_font_map_get_renderer (fm); - - return - _cogl_pango_renderer_get_use_mipmapping (COGL_PANGO_RENDERER (renderer)); -} - -static GQuark -cogl_pango_font_map_get_priv_key (void) -{ - static GQuark priv_key = 0; - - if (G_UNLIKELY (priv_key == 0)) - priv_key = g_quark_from_static_string ("CoglPangoFontMap"); - - return priv_key; -} diff --git a/mutter/cogl/cogl-pango/cogl-pango-glyph-cache.c b/mutter/cogl/cogl-pango/cogl-pango-glyph-cache.c deleted file mode 100644 index 13ffa6b..0000000 --- a/mutter/cogl/cogl-pango/cogl-pango-glyph-cache.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008 OpenedHand - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "config.h" - -#include - -#include "cogl-pango/cogl-pango-glyph-cache.h" -#include "cogl-pango/cogl-pango-private.h" -#include "cogl/cogl-atlas.h" -#include "cogl/cogl-atlas-texture-private.h" - -typedef struct _CoglPangoGlyphCacheKey CoglPangoGlyphCacheKey; - -struct _CoglPangoGlyphCache -{ - CoglContext *ctx; - - /* Hash table to quickly check whether a particular glyph in a - particular font is already cached */ - GHashTable *hash_table; - - /* List of CoglAtlases */ - GSList *atlases; - - /* List of callbacks to invoke when an atlas is reorganized */ - GHookList reorganize_callbacks; - - /* TRUE if we've ever stored a texture in the global atlas. This is - used to make sure we only register one callback to listen for - global atlas reorganizations */ - gboolean using_global_atlas; - - /* True if some of the glyphs are dirty. This is used as an - optimization in _cogl_pango_glyph_cache_set_dirty_glyphs to avoid - iterating the hash table if we know none of them are dirty */ - gboolean has_dirty_glyphs; - - /* Whether mipmapping is being used for this cache. This only - affects whether we decide to put the glyph in the global atlas */ - gboolean use_mipmapping; -}; - -struct _CoglPangoGlyphCacheKey -{ - PangoFont *font; - PangoGlyph glyph; -}; - -static void -cogl_pango_glyph_cache_value_free (CoglPangoGlyphCacheValue *value) -{ - if (value->texture) - g_object_unref (value->texture); - g_free (value); -} - -static void -cogl_pango_glyph_cache_key_free (CoglPangoGlyphCacheKey *key) -{ - g_object_unref (key->font); - g_free (key); -} - -static unsigned int -cogl_pango_glyph_cache_hash_func (const void *key) -{ - const CoglPangoGlyphCacheKey *cache_key - = (const CoglPangoGlyphCacheKey *) key; - - /* Generate a number affected by both the font and the glyph - number. We can safely directly compare the pointers because the - key holds a reference to the font so it is not possible that a - different font will have the same memory address */ - return GPOINTER_TO_UINT (cache_key->font) ^ cache_key->glyph; -} - -static gboolean -cogl_pango_glyph_cache_equal_func (const void *a, const void *b) -{ - const CoglPangoGlyphCacheKey *key_a - = (const CoglPangoGlyphCacheKey *) a; - const CoglPangoGlyphCacheKey *key_b - = (const CoglPangoGlyphCacheKey *) b; - - /* We can safely directly compare the pointers for the fonts because - the key holds a reference to the font so it is not possible that - a different font will have the same memory address */ - return key_a->font == key_b->font - && key_a->glyph == key_b->glyph; -} - -CoglPangoGlyphCache * -cogl_pango_glyph_cache_new (CoglContext *ctx, - gboolean use_mipmapping) -{ - CoglPangoGlyphCache *cache; - - cache = g_malloc (sizeof (CoglPangoGlyphCache)); - - /* Note: as a rule we don't take references to a CoglContext - * internally since */ - cache->ctx = ctx; - - cache->hash_table = g_hash_table_new_full - (cogl_pango_glyph_cache_hash_func, - cogl_pango_glyph_cache_equal_func, - (GDestroyNotify) cogl_pango_glyph_cache_key_free, - (GDestroyNotify) cogl_pango_glyph_cache_value_free); - - cache->atlases = NULL; - g_hook_list_init (&cache->reorganize_callbacks, sizeof (GHook)); - - cache->has_dirty_glyphs = FALSE; - - cache->using_global_atlas = FALSE; - - cache->use_mipmapping = use_mipmapping; - - return cache; -} - -static void -cogl_pango_glyph_cache_reorganize_cb (void *user_data) -{ - CoglPangoGlyphCache *cache = user_data; - - g_hook_list_invoke (&cache->reorganize_callbacks, FALSE); -} - -void -cogl_pango_glyph_cache_clear (CoglPangoGlyphCache *cache) -{ - g_slist_foreach (cache->atlases, (GFunc) g_object_unref, NULL); - g_slist_free (cache->atlases); - cache->atlases = NULL; - cache->has_dirty_glyphs = FALSE; - - g_hash_table_remove_all (cache->hash_table); -} - -void -cogl_pango_glyph_cache_free (CoglPangoGlyphCache *cache) -{ - if (cache->using_global_atlas) - { - _cogl_atlas_texture_remove_reorganize_callback ( - cache->ctx, - cogl_pango_glyph_cache_reorganize_cb, cache); - } - - cogl_pango_glyph_cache_clear (cache); - - g_hash_table_unref (cache->hash_table); - - g_hook_list_clear (&cache->reorganize_callbacks); - - g_free (cache); -} - -static void -cogl_pango_glyph_cache_update_position_cb (void *user_data, - CoglTexture *new_texture, - const CoglRectangleMapEntry *rect) -{ - CoglPangoGlyphCacheValue *value = user_data; - float tex_width, tex_height; - - if (value->texture) - g_object_unref (value->texture); - value->texture = g_object_ref (new_texture); - - tex_width = cogl_texture_get_width (new_texture); - tex_height = cogl_texture_get_height (new_texture); - - value->tx1 = rect->x / tex_width; - value->ty1 = rect->y / tex_height; - value->tx2 = (rect->x + value->draw_width) / tex_width; - value->ty2 = (rect->y + value->draw_height) / tex_height; - - value->tx_pixel = rect->x; - value->ty_pixel = rect->y; - - /* The glyph has changed position so it will need to be redrawn */ - value->dirty = TRUE; -} - -static gboolean -cogl_pango_glyph_cache_add_to_global_atlas (CoglPangoGlyphCache *cache, - PangoFont *font, - PangoGlyph glyph, - CoglPangoGlyphCacheValue *value) -{ - CoglTexture *texture; - GError *ignore_error = NULL; - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SHARED_ATLAS)) - return FALSE; - - /* If the cache is using mipmapping then we can't use the global - atlas because it would just get migrated back out */ - if (cache->use_mipmapping) - return FALSE; - - texture = cogl_atlas_texture_new_with_size (cache->ctx, - value->draw_width, - value->draw_height); - if (!cogl_texture_allocate (texture, &ignore_error)) - { - g_error_free (ignore_error); - return FALSE; - } - - value->texture = texture; - value->tx1 = 0; - value->ty1 = 0; - value->tx2 = 1; - value->ty2 = 1; - value->tx_pixel = 0; - value->ty_pixel = 0; - - /* The first time we store a texture in the global atlas we'll - register for notifications when the global atlas is reorganized - so we can forward the notification on as a glyph - reorganization */ - if (!cache->using_global_atlas) - { - _cogl_atlas_texture_add_reorganize_callback - (cache->ctx, - cogl_pango_glyph_cache_reorganize_cb, cache); - cache->using_global_atlas = TRUE; - } - - return TRUE; -} - -static gboolean -cogl_pango_glyph_cache_add_to_local_atlas (CoglPangoGlyphCache *cache, - PangoFont *font, - PangoGlyph glyph, - CoglPangoGlyphCacheValue *value) -{ - CoglAtlas *atlas = NULL; - GSList *l; - - /* Look for an atlas that can reserve the space */ - for (l = cache->atlases; l; l = l->next) - if (_cogl_atlas_reserve_space (l->data, - value->draw_width + 1, - value->draw_height + 1, - value)) - { - atlas = l->data; - break; - } - - /* If we couldn't find one then start a new atlas */ - if (atlas == NULL) - { - atlas = _cogl_atlas_new (COGL_PIXEL_FORMAT_A_8, - COGL_ATLAS_CLEAR_TEXTURE | - COGL_ATLAS_DISABLE_MIGRATION, - cogl_pango_glyph_cache_update_position_cb); - COGL_NOTE (ATLAS, "Created new atlas for glyphs: %p", atlas); - /* If we still can't reserve space then something has gone - seriously wrong so we'll just give up */ - if (!_cogl_atlas_reserve_space (atlas, - value->draw_width + 1, - value->draw_height + 1, - value)) - { - g_object_unref (atlas); - return FALSE; - } - - _cogl_atlas_add_reorganize_callback - (atlas, cogl_pango_glyph_cache_reorganize_cb, NULL, cache); - - cache->atlases = g_slist_prepend (cache->atlases, atlas); - } - - return TRUE; -} - -CoglPangoGlyphCacheValue * -cogl_pango_glyph_cache_lookup (CoglPangoGlyphCache *cache, - gboolean create, - PangoFont *font, - PangoGlyph glyph) -{ - CoglPangoGlyphCacheKey lookup_key; - CoglPangoGlyphCacheValue *value; - - lookup_key.font = font; - lookup_key.glyph = glyph; - - value = g_hash_table_lookup (cache->hash_table, &lookup_key); - - if (create && value == NULL) - { - CoglPangoGlyphCacheKey *key; - PangoRectangle ink_rect; - - value = g_new0 (CoglPangoGlyphCacheValue, 1); - value->texture = NULL; - - pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL); - pango_extents_to_pixels (&ink_rect, NULL); - - value->draw_x = ink_rect.x; - value->draw_y = ink_rect.y; - value->draw_width = ink_rect.width; - value->draw_height = ink_rect.height; - - /* If the glyph is zero-sized then we don't need to reserve any - space for it and we can just avoid painting anything */ - if (ink_rect.width < 1 || ink_rect.height < 1) - value->dirty = FALSE; - else - { - /* Try adding the glyph to the global atlas... */ - if (!cogl_pango_glyph_cache_add_to_global_atlas (cache, - font, - glyph, - value) && - /* If it fails try the local atlas */ - !cogl_pango_glyph_cache_add_to_local_atlas (cache, - font, - glyph, - value)) - { - cogl_pango_glyph_cache_value_free (value); - return NULL; - } - - value->dirty = TRUE; - cache->has_dirty_glyphs = TRUE; - } - - key = g_new0 (CoglPangoGlyphCacheKey, 1); - key->font = g_object_ref (font); - key->glyph = glyph; - - g_hash_table_insert (cache->hash_table, key, value); - } - - return value; -} - -static void -_cogl_pango_glyph_cache_set_dirty_glyphs_cb (void *key_ptr, - void *value_ptr, - void *user_data) -{ - CoglPangoGlyphCacheKey *key = key_ptr; - CoglPangoGlyphCacheValue *value = value_ptr; - CoglPangoGlyphCacheDirtyFunc func = user_data; - - if (value->dirty) - { - func (key->font, key->glyph, value); - - value->dirty = FALSE; - } -} - -void -_cogl_pango_glyph_cache_set_dirty_glyphs (CoglPangoGlyphCache *cache, - CoglPangoGlyphCacheDirtyFunc func) -{ - /* If we know that there are no dirty glyphs then we can shortcut - out early */ - if (!cache->has_dirty_glyphs) - return; - - g_hash_table_foreach (cache->hash_table, - _cogl_pango_glyph_cache_set_dirty_glyphs_cb, - func); - - cache->has_dirty_glyphs = FALSE; -} - -void -_cogl_pango_glyph_cache_add_reorganize_callback (CoglPangoGlyphCache *cache, - GHookFunc func, - void *user_data) -{ - GHook *hook = g_hook_alloc (&cache->reorganize_callbacks); - hook->func = func; - hook->data = user_data; - g_hook_prepend (&cache->reorganize_callbacks, hook); -} - -void -_cogl_pango_glyph_cache_remove_reorganize_callback (CoglPangoGlyphCache *cache, - GHookFunc func, - void *user_data) -{ - GHook *hook = g_hook_find_func_data (&cache->reorganize_callbacks, - FALSE, - func, - user_data); - - if (hook) - g_hook_destroy_link (&cache->reorganize_callbacks, hook); -} diff --git a/mutter/cogl/cogl-pango/cogl-pango-glyph-cache.h b/mutter/cogl/cogl-pango/cogl-pango-glyph-cache.h deleted file mode 100644 index 8739c23..0000000 --- a/mutter/cogl/cogl-pango/cogl-pango-glyph-cache.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008 OpenedHand - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#include -#include - -#include "cogl/cogl-texture.h" - -G_BEGIN_DECLS - -typedef struct _CoglPangoGlyphCache CoglPangoGlyphCache; -typedef struct _CoglPangoGlyphCacheValue CoglPangoGlyphCacheValue; - -struct _CoglPangoGlyphCacheValue -{ - CoglTexture *texture; - - float tx1; - float ty1; - float tx2; - float ty2; - - int tx_pixel; - int ty_pixel; - - int draw_x; - int draw_y; - int draw_width; - int draw_height; - - /* This will be set to TRUE when the glyph atlas is reorganized - which means the glyph will need to be redrawn */ - guint dirty : 1; - /* Set to TRUE if the glyph has colors (eg. emoji) */ - guint has_color : 1; -}; - -typedef void (* CoglPangoGlyphCacheDirtyFunc) (PangoFont *font, - PangoGlyph glyph, - CoglPangoGlyphCacheValue *value); - -COGL_EXPORT CoglPangoGlyphCache * -cogl_pango_glyph_cache_new (CoglContext *ctx, - gboolean use_mipmapping); - -COGL_EXPORT void -cogl_pango_glyph_cache_free (CoglPangoGlyphCache *cache); - -COGL_EXPORT CoglPangoGlyphCacheValue * -cogl_pango_glyph_cache_lookup (CoglPangoGlyphCache *cache, - gboolean create, - PangoFont *font, - PangoGlyph glyph); - -COGL_EXPORT void -cogl_pango_glyph_cache_clear (CoglPangoGlyphCache *cache); - -void -_cogl_pango_glyph_cache_add_reorganize_callback (CoglPangoGlyphCache *cache, - GHookFunc func, - void *user_data); - -void -_cogl_pango_glyph_cache_remove_reorganize_callback (CoglPangoGlyphCache *cache, - GHookFunc func, - void *user_data); - -void -_cogl_pango_glyph_cache_set_dirty_glyphs (CoglPangoGlyphCache *cache, - CoglPangoGlyphCacheDirtyFunc func); - -G_END_DECLS diff --git a/mutter/cogl/cogl-pango/cogl-pango-pipeline-cache.c b/mutter/cogl/cogl-pango/cogl-pango-pipeline-cache.c deleted file mode 100644 index 81237f4..0000000 --- a/mutter/cogl/cogl-pango/cogl-pango-pipeline-cache.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#include "config.h" - -#include - -#include "cogl-pango/cogl-pango-pipeline-cache.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-texture-private.h" - -typedef struct _CoglPangoPipelineCacheEntry CoglPangoPipelineCacheEntry; - -static GQuark pipeline_destroy_notify_key = 0; - -struct _CoglPangoPipelineCacheEntry -{ - /* This will take a reference or it can be NULL to represent the - pipeline used to render colors */ - CoglTexture *texture; - - /* This will only take a weak reference */ - CoglPipeline *pipeline; -}; - -static void -_cogl_pango_pipeline_cache_key_destroy (void *data) -{ - if (data) - g_object_unref (data); -} - -static void -_cogl_pango_pipeline_cache_value_destroy (void *data) -{ - CoglPangoPipelineCacheEntry *cache_entry = data; - - if (cache_entry->texture) - g_object_unref (cache_entry->texture); - - /* We don't need to unref the pipeline because it only takes a weak - reference */ - - g_free (cache_entry); -} - -CoglPangoPipelineCache * -_cogl_pango_pipeline_cache_new (CoglContext *ctx, - gboolean use_mipmapping) -{ - CoglPangoPipelineCache *cache = g_new (CoglPangoPipelineCache, 1); - - cache->ctx = g_object_ref (ctx); - - /* The key is the pipeline pointer. A reference is taken when the - pipeline is used as a key so we should unref it again in the - destroy function */ - cache->hash_table = - g_hash_table_new_full (g_direct_hash, - g_direct_equal, - _cogl_pango_pipeline_cache_key_destroy, - _cogl_pango_pipeline_cache_value_destroy); - - cache->base_texture_rgba_pipeline = NULL; - cache->base_texture_alpha_pipeline = NULL; - - cache->use_mipmapping = use_mipmapping; - - return cache; -} - -static CoglPipeline * -get_base_texture_rgba_pipeline (CoglPangoPipelineCache *cache) -{ - if (cache->base_texture_rgba_pipeline == NULL) - { - CoglPipeline *pipeline; - - pipeline = cache->base_texture_rgba_pipeline = - cogl_pipeline_new (cache->ctx); - - cogl_pipeline_set_layer_wrap_mode (pipeline, 0, - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); - - if (cache->use_mipmapping) - cogl_pipeline_set_layer_filters - (pipeline, 0, - COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR, - COGL_PIPELINE_FILTER_LINEAR); - } - - return cache->base_texture_rgba_pipeline; -} - -static CoglPipeline * -get_base_texture_alpha_pipeline (CoglPangoPipelineCache *cache) -{ - if (cache->base_texture_alpha_pipeline == NULL) - { - CoglPipeline *pipeline; - - pipeline = cogl_pipeline_copy (get_base_texture_rgba_pipeline (cache)); - cache->base_texture_alpha_pipeline = pipeline; - - /* The default combine mode of materials is to modulate (A x B) - * the texture RGBA channels with the RGBA channels of the - * previous layer (which in our case is just the font color) - * - * Since the RGB for an alpha texture is defined as 0, this gives us: - * - * result.rgb = color.rgb * 0 - * result.a = color.a * texture.a - * - * What we want is premultiplied rgba values: - * - * result.rgba = color.rgb * texture.a - * result.a = color.a * texture.a - */ - cogl_pipeline_set_layer_combine (pipeline, 0, /* layer */ - "RGBA = MODULATE (PREVIOUS, TEXTURE[A])", - NULL); - } - - return cache->base_texture_alpha_pipeline; -} - -typedef struct -{ - CoglPangoPipelineCache *cache; - CoglTexture *texture; -} PipelineDestroyNotifyData; - -static void -pipeline_destroy_notify_cb (void *user_data) -{ - PipelineDestroyNotifyData *data = user_data; - - g_hash_table_remove (data->cache->hash_table, data->texture); - g_free (data); -} - -CoglPipeline * -_cogl_pango_pipeline_cache_get (CoglPangoPipelineCache *cache, - CoglTexture *texture) -{ - CoglPangoPipelineCacheEntry *entry; - PipelineDestroyNotifyData *destroy_data; - pipeline_destroy_notify_key = g_quark_from_static_string ("-cogl-pango-pipeline-cache-key"); - - /* Look for an existing entry */ - entry = g_hash_table_lookup (cache->hash_table, texture); - - if (entry) - return g_object_ref (entry->pipeline); - - /* No existing pipeline was found so let's create another */ - entry = g_new0 (CoglPangoPipelineCacheEntry, 1); - - if (texture) - { - CoglPipeline *base; - - entry->texture = g_object_ref (texture); - - if (_cogl_texture_get_format (entry->texture) == COGL_PIXEL_FORMAT_A_8) - base = get_base_texture_alpha_pipeline (cache); - else - base = get_base_texture_rgba_pipeline (cache); - - entry->pipeline = cogl_pipeline_copy (base); - - cogl_pipeline_set_layer_texture (entry->pipeline, 0 /* layer */, texture); - } - else - { - entry->texture = NULL; - entry->pipeline = cogl_pipeline_new (cache->ctx); - } - - /* Add a weak reference to the pipeline so we can remove it from the - hash table when it is destroyed */ - destroy_data = g_new0 (PipelineDestroyNotifyData, 1); - destroy_data->cache = cache; - destroy_data->texture = texture; - g_object_set_qdata_full (G_OBJECT (entry->pipeline), - pipeline_destroy_notify_key, - destroy_data, - pipeline_destroy_notify_cb); - - g_hash_table_insert (cache->hash_table, - texture ? g_object_ref (texture) : NULL, - entry); - - /* This doesn't take a reference on the pipeline so that it will use - the newly created reference */ - return entry->pipeline; -} - -void -_cogl_pango_pipeline_cache_free (CoglPangoPipelineCache *cache) -{ - if (cache->base_texture_rgba_pipeline) - g_object_unref (cache->base_texture_rgba_pipeline); - if (cache->base_texture_alpha_pipeline) - g_object_unref (cache->base_texture_alpha_pipeline); - - g_hash_table_destroy (cache->hash_table); - - g_object_unref (cache->ctx); - - g_free (cache); -} diff --git a/mutter/cogl/cogl-pango/cogl-pango-pipeline-cache.h b/mutter/cogl/cogl-pango/cogl-pango-pipeline-cache.h deleted file mode 100644 index f7441f0..0000000 --- a/mutter/cogl/cogl-pango/cogl-pango-pipeline-cache.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#pragma once - -#include - -#include "cogl/cogl-context-private.h" - -G_BEGIN_DECLS - -typedef struct _CoglPangoPipelineCache -{ - CoglContext *ctx; - - GHashTable *hash_table; - - CoglPipeline *base_texture_alpha_pipeline; - CoglPipeline *base_texture_rgba_pipeline; - - gboolean use_mipmapping; -} CoglPangoPipelineCache; - - -CoglPangoPipelineCache * -_cogl_pango_pipeline_cache_new (CoglContext *ctx, - gboolean use_mipmapping); - -/* Returns a pipeline that can be used to render glyphs in the given - texture. The pipeline has a new reference so it is up to the caller - to unref it */ -CoglPipeline * -_cogl_pango_pipeline_cache_get (CoglPangoPipelineCache *cache, - CoglTexture *texture); - -void -_cogl_pango_pipeline_cache_free (CoglPangoPipelineCache *cache); - -G_END_DECLS diff --git a/mutter/cogl/cogl-pango/cogl-pango-private.h b/mutter/cogl/cogl-pango/cogl-pango-private.h deleted file mode 100644 index a58417a..0000000 --- a/mutter/cogl/cogl-pango/cogl-pango-private.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008 OpenedHand - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Neil Roberts - * Robert Bragg - * Matthew Allum - */ - -#pragma once - -#include "cogl-pango/cogl-pango.h" - -G_BEGIN_DECLS - -PangoRenderer * -_cogl_pango_renderer_new (CoglContext *context); - -void -_cogl_pango_renderer_clear_glyph_cache (CoglPangoRenderer *renderer); - -void -_cogl_pango_renderer_set_use_mipmapping (CoglPangoRenderer *renderer, - gboolean value); -gboolean -_cogl_pango_renderer_get_use_mipmapping (CoglPangoRenderer *renderer); - - - -CoglContext * -_cogl_pango_font_map_get_cogl_context (CoglPangoFontMap *fm); - -PangoRenderer * -_cogl_pango_font_map_get_renderer (CoglPangoFontMap *fm); - -G_END_DECLS diff --git a/mutter/cogl/cogl-pango/cogl-pango-render.c b/mutter/cogl/cogl-pango/cogl-pango-render.c deleted file mode 100644 index 8b96b2a..0000000 --- a/mutter/cogl/cogl-pango/cogl-pango-render.c +++ /dev/null @@ -1,915 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008 OpenedHand - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Neil Roberts - * Robert Bragg - * Matthew Allum - */ - -#include "config.h" - -#include -#include -#include -#include -#include - -#include "cogl/cogl-debug.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl-pango/cogl-pango-private.h" -#include "cogl-pango/cogl-pango-glyph-cache.h" -#include "cogl-pango/cogl-pango-display-list.h" - -#define PANGO_UNKNOWN_GLYPH_WIDTH 10 -#define PANGO_UNKNOWN_GLYPH_HEIGHT 14 - -enum -{ - PROP_0, - - PROP_COGL_CONTEXT, - PROP_LAST -}; - -typedef struct -{ - CoglPangoGlyphCache *glyph_cache; - CoglPangoPipelineCache *pipeline_cache; -} CoglPangoRendererCaches; - -struct _CoglPangoRenderer -{ - PangoRenderer parent_instance; - - CoglContext *ctx; - - /* Two caches of glyphs as textures and their corresponding pipeline - caches, one with mipmapped textures and one without */ - CoglPangoRendererCaches no_mipmap_caches; - CoglPangoRendererCaches mipmap_caches; - - gboolean use_mipmapping; - - /* The current display list that is being built */ - CoglPangoDisplayList *display_list; -}; - -struct _CoglPangoRendererClass -{ - PangoRendererClass class_instance; -}; - -typedef struct _CoglPangoLayoutQdata CoglPangoLayoutQdata; - -/* An instance of this struct gets attached to each PangoLayout to - cache the VBO and to detect changes to the layout */ -struct _CoglPangoLayoutQdata -{ - CoglPangoRenderer *renderer; - /* The cache of the geometry for the layout */ - CoglPangoDisplayList *display_list; - /* A reference to the first line of the layout. This is just used to - detect changes */ - PangoLayoutLine *first_line; - /* Whether mipmapping was previously used to render this layout. We - need to regenerate the display list if the mipmapping value is - changed because it will be using a different set of textures */ - gboolean mipmapping_used; -}; - -static void -_cogl_pango_ensure_glyph_cache_for_layout_line (PangoLayoutLine *line); - -typedef struct -{ - CoglPangoDisplayList *display_list; - float x1, y1, x2, y2; -} CoglPangoRendererSliceCbData; - -PangoRenderer * -_cogl_pango_renderer_new (CoglContext *context) -{ - return PANGO_RENDERER (g_object_new (COGL_PANGO_TYPE_RENDERER, - "context", context, NULL)); -} - -static void -cogl_pango_renderer_slice_cb (CoglTexture *texture, - const float *slice_coords, - const float *virtual_coords, - void *user_data) -{ - CoglPangoRendererSliceCbData *data = user_data; - - /* Note: this assumes that there is only one slice containing the - whole texture and it doesn't attempt to split up the vertex - coordinates based on the virtual_coords */ - - _cogl_pango_display_list_add_texture (data->display_list, - texture, - data->x1, - data->y1, - data->x2, - data->y2, - slice_coords[0], - slice_coords[1], - slice_coords[2], - slice_coords[3]); -} - -static void -cogl_pango_renderer_draw_glyph (CoglPangoRenderer *priv, - CoglPangoGlyphCacheValue *cache_value, - float x1, - float y1) -{ - CoglPangoRendererSliceCbData data; - - g_return_if_fail (priv->display_list != NULL); - - data.display_list = priv->display_list; - data.x1 = x1; - data.y1 = y1; - data.x2 = x1 + (float) cache_value->draw_width; - data.y2 = y1 + (float) cache_value->draw_height; - - /* We iterate the internal sub textures of the texture so that we - can get a pointer to the base texture even if the texture is in - the global atlas. That way the display list can recognise that - the neighbouring glyphs are coming from the same atlas and bundle - them together into a single VBO */ - - cogl_meta_texture_foreach_in_region (cache_value->texture, - cache_value->tx1, - cache_value->ty1, - cache_value->tx2, - cache_value->ty2, - COGL_PIPELINE_WRAP_MODE_REPEAT, - COGL_PIPELINE_WRAP_MODE_REPEAT, - cogl_pango_renderer_slice_cb, - &data); -} - -static void cogl_pango_renderer_dispose (GObject *object); -static void cogl_pango_renderer_finalize (GObject *object); -static void cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer, - PangoFont *font, - PangoGlyphString *glyphs, - int x, - int y); -static void cogl_pango_renderer_draw_rectangle (PangoRenderer *renderer, - PangoRenderPart part, - int x, - int y, - int width, - int height); -static void cogl_pango_renderer_draw_trapezoid (PangoRenderer *renderer, - PangoRenderPart part, - double y1, - double x11, - double x21, - double y2, - double x12, - double x22); - -G_DEFINE_TYPE (CoglPangoRenderer, cogl_pango_renderer, PANGO_TYPE_RENDERER); - -static void -cogl_pango_renderer_init (CoglPangoRenderer *priv) -{ -} - -static void -_cogl_pango_renderer_constructed (GObject *gobject) -{ - CoglPangoRenderer *renderer = COGL_PANGO_RENDERER (gobject); - CoglContext *ctx = renderer->ctx; - - renderer->no_mipmap_caches.pipeline_cache = - _cogl_pango_pipeline_cache_new (ctx, FALSE); - renderer->mipmap_caches.pipeline_cache = - _cogl_pango_pipeline_cache_new (ctx, TRUE); - - renderer->no_mipmap_caches.glyph_cache = - cogl_pango_glyph_cache_new (ctx, FALSE); - renderer->mipmap_caches.glyph_cache = - cogl_pango_glyph_cache_new (ctx, TRUE); - - _cogl_pango_renderer_set_use_mipmapping (renderer, FALSE); - - if (G_OBJECT_CLASS (cogl_pango_renderer_parent_class)->constructed) - G_OBJECT_CLASS (cogl_pango_renderer_parent_class)->constructed (gobject); -} - -static void -cogl_pango_renderer_set_property (GObject *object, - unsigned int prop_id, - const GValue *value, - GParamSpec *pspec) -{ - CoglPangoRenderer *renderer = COGL_PANGO_RENDERER (object); - - switch (prop_id) - { - case PROP_COGL_CONTEXT: - renderer->ctx = g_value_get_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -cogl_pango_renderer_class_init (CoglPangoRendererClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass); - GParamSpec *pspec; - - object_class->set_property = cogl_pango_renderer_set_property; - object_class->constructed = _cogl_pango_renderer_constructed; - object_class->dispose = cogl_pango_renderer_dispose; - object_class->finalize = cogl_pango_renderer_finalize; - - pspec = g_param_spec_object ("context", NULL, NULL, - COGL_TYPE_CONTEXT, - G_PARAM_WRITABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - g_object_class_install_property (object_class, PROP_COGL_CONTEXT, pspec); - - renderer_class->draw_glyphs = cogl_pango_renderer_draw_glyphs; - renderer_class->draw_rectangle = cogl_pango_renderer_draw_rectangle; - renderer_class->draw_trapezoid = cogl_pango_renderer_draw_trapezoid; -} - -static void -cogl_pango_renderer_dispose (GObject *object) -{ - CoglPangoRenderer *priv = COGL_PANGO_RENDERER (object); - - g_clear_object (&priv->ctx); - - G_OBJECT_CLASS (cogl_pango_renderer_parent_class)->dispose (object); -} - -static void -cogl_pango_renderer_finalize (GObject *object) -{ - CoglPangoRenderer *priv = COGL_PANGO_RENDERER (object); - - cogl_pango_glyph_cache_free (priv->no_mipmap_caches.glyph_cache); - cogl_pango_glyph_cache_free (priv->mipmap_caches.glyph_cache); - - _cogl_pango_pipeline_cache_free (priv->no_mipmap_caches.pipeline_cache); - _cogl_pango_pipeline_cache_free (priv->mipmap_caches.pipeline_cache); - - G_OBJECT_CLASS (cogl_pango_renderer_parent_class)->finalize (object); -} - -static CoglPangoRenderer * -cogl_pango_get_renderer_from_context (PangoContext *context) -{ - PangoFontMap *font_map; - CoglPangoFontMap *cogl_font_map; - PangoRenderer *renderer; - - font_map = pango_context_get_font_map (context); - g_return_val_if_fail (COGL_PANGO_IS_FONT_MAP (font_map), NULL); - - cogl_font_map = COGL_PANGO_FONT_MAP (font_map); - - renderer = _cogl_pango_font_map_get_renderer (cogl_font_map); - - g_return_val_if_fail (COGL_PANGO_IS_RENDERER (renderer), NULL); - - return COGL_PANGO_RENDERER (renderer); -} - -static GQuark -cogl_pango_layout_get_qdata_key (void) -{ - static GQuark key = 0; - - if (G_UNLIKELY (key == 0)) - key = g_quark_from_static_string ("CoglPangoDisplayList"); - - return key; -} - -static void -cogl_pango_layout_qdata_forget_display_list (CoglPangoLayoutQdata *qdata) -{ - if (qdata->display_list) - { - CoglPangoRendererCaches *caches = qdata->mipmapping_used ? - &qdata->renderer->mipmap_caches : - &qdata->renderer->no_mipmap_caches; - - _cogl_pango_glyph_cache_remove_reorganize_callback - (caches->glyph_cache, - (GHookFunc) cogl_pango_layout_qdata_forget_display_list, - qdata); - - _cogl_pango_display_list_free (qdata->display_list); - - qdata->display_list = NULL; - } -} - -static void -cogl_pango_render_qdata_destroy (CoglPangoLayoutQdata *qdata) -{ - cogl_pango_layout_qdata_forget_display_list (qdata); - if (qdata->first_line) - pango_layout_line_unref (qdata->first_line); - g_free (qdata); -} - -void -cogl_pango_show_layout (CoglFramebuffer *fb, - PangoLayout *layout, - float x, - float y, - const CoglColor *color) -{ - PangoContext *context; - CoglPangoRenderer *priv; - CoglPangoLayoutQdata *qdata; - - context = pango_layout_get_context (layout); - priv = cogl_pango_get_renderer_from_context (context); - if (G_UNLIKELY (!priv)) - return; - - qdata = g_object_get_qdata (G_OBJECT (layout), - cogl_pango_layout_get_qdata_key ()); - - if (qdata == NULL) - { - qdata = g_new0 (CoglPangoLayoutQdata, 1); - qdata->renderer = priv; - g_object_set_qdata_full (G_OBJECT (layout), - cogl_pango_layout_get_qdata_key (), - qdata, - (GDestroyNotify) - cogl_pango_render_qdata_destroy); - } - - /* Check if the layout has changed since the last build of the - display list. This trick was suggested by Behdad Esfahbod here: - http://mail.gnome.org/archives/gtk-i18n-list/2009-May/msg00019.html */ - if (qdata->display_list && - ((qdata->first_line && - qdata->first_line->layout != layout) || - qdata->mipmapping_used != priv->use_mipmapping)) - cogl_pango_layout_qdata_forget_display_list (qdata); - - if (qdata->display_list == NULL) - { - CoglPangoRendererCaches *caches = priv->use_mipmapping ? - &priv->mipmap_caches : - &priv->no_mipmap_caches; - - cogl_pango_ensure_glyph_cache_for_layout (layout); - - qdata->display_list = - _cogl_pango_display_list_new (caches->pipeline_cache); - - /* Register for notification of when the glyph cache changes so - we can rebuild the display list */ - _cogl_pango_glyph_cache_add_reorganize_callback - (caches->glyph_cache, - (GHookFunc) cogl_pango_layout_qdata_forget_display_list, - qdata); - - priv->display_list = qdata->display_list; - pango_renderer_draw_layout (PANGO_RENDERER (priv), layout, 0, 0); - priv->display_list = NULL; - - qdata->mipmapping_used = priv->use_mipmapping; - } - - cogl_framebuffer_push_matrix (fb); - cogl_framebuffer_translate (fb, x, y, 0); - - _cogl_pango_display_list_render (fb, - qdata->display_list, - color); - - cogl_framebuffer_pop_matrix (fb); - - /* Keep a reference to the first line of the layout so we can detect - changes */ - if (qdata->first_line) - { - pango_layout_line_unref (qdata->first_line); - qdata->first_line = NULL; - } - if (pango_layout_get_line_count (layout) > 0) - { - qdata->first_line = pango_layout_get_line (layout, 0); - pango_layout_line_ref (qdata->first_line); - } -} - -void -cogl_pango_show_layout_line (CoglFramebuffer *fb, - PangoLayoutLine *line, - float x, - float y, - const CoglColor *color) -{ - PangoContext *context; - CoglPangoRenderer *priv; - CoglPangoRendererCaches *caches; - int pango_x = x * PANGO_SCALE; - int pango_y = y * PANGO_SCALE; - - context = pango_layout_get_context (line->layout); - priv = cogl_pango_get_renderer_from_context (context); - if (G_UNLIKELY (!priv)) - return; - - caches = (priv->use_mipmapping ? - &priv->mipmap_caches : - &priv->no_mipmap_caches); - - priv->display_list = _cogl_pango_display_list_new (caches->pipeline_cache); - - _cogl_pango_ensure_glyph_cache_for_layout_line (line); - - pango_renderer_draw_layout_line (PANGO_RENDERER (priv), line, - pango_x, pango_y); - - _cogl_pango_display_list_render (fb, - priv->display_list, - color); - - _cogl_pango_display_list_free (priv->display_list); - priv->display_list = NULL; -} - -void -_cogl_pango_renderer_clear_glyph_cache (CoglPangoRenderer *renderer) -{ - cogl_pango_glyph_cache_clear (renderer->mipmap_caches.glyph_cache); - cogl_pango_glyph_cache_clear (renderer->no_mipmap_caches.glyph_cache); -} - -void -_cogl_pango_renderer_set_use_mipmapping (CoglPangoRenderer *renderer, - gboolean value) -{ - renderer->use_mipmapping = value; -} - -gboolean -_cogl_pango_renderer_get_use_mipmapping (CoglPangoRenderer *renderer) -{ - return renderer->use_mipmapping; -} - -static CoglPangoGlyphCacheValue * -cogl_pango_renderer_get_cached_glyph (PangoRenderer *renderer, - gboolean create, - PangoFont *font, - PangoGlyph glyph) -{ - CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); - CoglPangoRendererCaches *caches = (priv->use_mipmapping ? - &priv->mipmap_caches : - &priv->no_mipmap_caches); - - return cogl_pango_glyph_cache_lookup (caches->glyph_cache, - create, font, glyph); -} - -static gboolean -font_has_color_glyphs (const PangoFont *font) -{ - cairo_scaled_font_t *scaled_font; - gboolean has_color = FALSE; - - scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *) font); - - if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_FT) - { - FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font); - has_color = (FT_HAS_COLOR (ft_face) != 0); - cairo_ft_scaled_font_unlock_face (scaled_font); - } - - return has_color; -} - -static void -cogl_pango_renderer_set_dirty_glyph (PangoFont *font, - PangoGlyph glyph, - CoglPangoGlyphCacheValue *value) -{ - cairo_surface_t *surface; - cairo_t *cr; - cairo_scaled_font_t *scaled_font; - cairo_glyph_t cairo_glyph; - cairo_format_t format_cairo; - CoglPixelFormat format_cogl; - - COGL_NOTE (PANGO, "redrawing glyph %i", glyph); - - /* Glyphs that don't take up any space will end up without a - texture. These should never become dirty so they shouldn't end up - here */ - g_return_if_fail (value->texture != NULL); - - if (_cogl_texture_get_format (value->texture) == COGL_PIXEL_FORMAT_A_8) - { - format_cairo = CAIRO_FORMAT_A8; - format_cogl = COGL_PIXEL_FORMAT_A_8; - } - else - { - format_cairo = CAIRO_FORMAT_ARGB32; - - /* Cairo stores the data in native byte order as ARGB but Cogl's - pixel formats specify the actual byte order. Therefore we - need to use a different format depending on the - architecture */ -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - format_cogl = COGL_PIXEL_FORMAT_BGRA_8888_PRE; -#else - format_cogl = COGL_PIXEL_FORMAT_ARGB_8888_PRE; -#endif - } - - surface = cairo_image_surface_create (format_cairo, - value->draw_width, - value->draw_height); - cr = cairo_create (surface); - - scaled_font = pango_cairo_font_get_scaled_font (PANGO_CAIRO_FONT (font)); - cairo_set_scaled_font (cr, scaled_font); - - cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0); - - cairo_glyph.x = -value->draw_x; - cairo_glyph.y = -value->draw_y; - /* The PangoCairo glyph numbers directly map to Cairo glyph - numbers */ - cairo_glyph.index = glyph; - cairo_show_glyphs (cr, &cairo_glyph, 1); - - cairo_destroy (cr); - cairo_surface_flush (surface); - - /* Copy the glyph to the texture */ - cogl_texture_set_region (value->texture, - 0, /* src_x */ - 0, /* src_y */ - value->tx_pixel, /* dst_x */ - value->ty_pixel, /* dst_y */ - value->draw_width, /* dst_width */ - value->draw_height, /* dst_height */ - value->draw_width, /* width */ - value->draw_height, /* height */ - format_cogl, - cairo_image_surface_get_stride (surface), - cairo_image_surface_get_data (surface)); - - cairo_surface_destroy (surface); - - value->has_color = font_has_color_glyphs (font); -} - -static void -_cogl_pango_ensure_glyph_cache_for_layout_line_internal (PangoLayoutLine *line) -{ - PangoContext *context; - PangoRenderer *renderer; - GSList *l; - - context = pango_layout_get_context (line->layout); - renderer = - PANGO_RENDERER (cogl_pango_get_renderer_from_context (context)); - - for (l = line->runs; l; l = l->next) - { - PangoLayoutRun *run = l->data; - PangoGlyphString *glyphs = run->glyphs; - int i; - - for (i = 0; i < glyphs->num_glyphs; i++) - { - PangoGlyphInfo *gi = &glyphs->glyphs[i]; - - /* If the glyph isn't cached then this will reserve - space for it now. We won't actually draw the glyph - yet because reserving space could cause all of the - other glyphs to be moved so we might as well redraw - them all later once we know that the position is - settled */ - cogl_pango_renderer_get_cached_glyph (renderer, TRUE, - run->item->analysis.font, - gi->glyph); - } - } -} - -static void -_cogl_pango_set_dirty_glyphs (CoglPangoRenderer *priv) -{ - _cogl_pango_glyph_cache_set_dirty_glyphs - (priv->mipmap_caches.glyph_cache, cogl_pango_renderer_set_dirty_glyph); - _cogl_pango_glyph_cache_set_dirty_glyphs - (priv->no_mipmap_caches.glyph_cache, cogl_pango_renderer_set_dirty_glyph); -} - -static void -_cogl_pango_ensure_glyph_cache_for_layout_line (PangoLayoutLine *line) -{ - PangoContext *context; - CoglPangoRenderer *priv; - - context = pango_layout_get_context (line->layout); - priv = cogl_pango_get_renderer_from_context (context); - - _cogl_pango_ensure_glyph_cache_for_layout_line_internal (line); - - /* Now that we know all of the positions are settled we'll fill in - any dirty glyphs */ - _cogl_pango_set_dirty_glyphs (priv); -} - -void -cogl_pango_ensure_glyph_cache_for_layout (PangoLayout *layout) -{ - PangoContext *context; - CoglPangoRenderer *priv; - PangoLayoutIter *iter; - - context = pango_layout_get_context (layout); - priv = cogl_pango_get_renderer_from_context (context); - - g_return_if_fail (PANGO_IS_LAYOUT (layout)); - - if ((iter = pango_layout_get_iter (layout)) == NULL) - return; - - do - { - PangoLayoutLine *line; - - line = pango_layout_iter_get_line_readonly (iter); - - _cogl_pango_ensure_glyph_cache_for_layout_line_internal (line); - } - while (pango_layout_iter_next_line (iter)); - - pango_layout_iter_free (iter); - - /* Now that we know all of the positions are settled we'll fill in - any dirty glyphs */ - _cogl_pango_set_dirty_glyphs (priv); -} - -static void -cogl_pango_renderer_set_color_for_part (PangoRenderer *renderer, - PangoRenderPart part) -{ - PangoColor *pango_color = pango_renderer_get_color (renderer, part); - uint16_t alpha = pango_renderer_get_alpha (renderer, part); - CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); - - if (pango_color) - { - CoglColor color; - - cogl_color_init_from_4f (&color, - pango_color->red / 65535.0, - pango_color->green / 65535.0, - pango_color->blue / 65535.0, - alpha ? alpha / 65535.0 : 1.0); - - _cogl_pango_display_list_set_color_override (priv->display_list, &color); - } - else - _cogl_pango_display_list_remove_color_override (priv->display_list); -} - -static void -cogl_pango_renderer_draw_box (PangoRenderer *renderer, - int x, - int y, - int width, - int height) -{ - CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); - - g_return_if_fail (priv->display_list != NULL); - - _cogl_pango_display_list_add_rectangle (priv->display_list, - x, - y - height, - x + width, - y); -} - -static void -cogl_pango_renderer_get_device_units (PangoRenderer *renderer, - int xin, - int yin, - float *xout, - float *yout) -{ - const PangoMatrix *matrix; - - if ((matrix = pango_renderer_get_matrix (renderer))) - { - /* Convert user-space coords to device coords */ - *xout = ((xin * matrix->xx + yin * matrix->xy) - / PANGO_SCALE + matrix->x0); - *yout = ((yin * matrix->yy + xin * matrix->yx) - / PANGO_SCALE + matrix->y0); - } - else - { - *xout = PANGO_PIXELS (xin); - *yout = PANGO_PIXELS (yin); - } -} - -static void -cogl_pango_renderer_draw_rectangle (PangoRenderer *renderer, - PangoRenderPart part, - int x, - int y, - int width, - int height) -{ - CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); - float x1, x2, y1, y2; - - g_return_if_fail (priv->display_list != NULL); - - cogl_pango_renderer_set_color_for_part (renderer, part); - - cogl_pango_renderer_get_device_units (renderer, - x, y, - &x1, &y1); - cogl_pango_renderer_get_device_units (renderer, - x + width, y + height, - &x2, &y2); - - _cogl_pango_display_list_add_rectangle (priv->display_list, - x1, y1, x2, y2); -} - -static void -cogl_pango_renderer_draw_trapezoid (PangoRenderer *renderer, - PangoRenderPart part, - double y1, - double x11, - double x21, - double y2, - double x12, - double x22) -{ - CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); - - g_return_if_fail (priv->display_list != NULL); - - cogl_pango_renderer_set_color_for_part (renderer, part); - - _cogl_pango_display_list_add_trapezoid (priv->display_list, - y1, - x11, - x21, - y2, - x12, - x22); -} - -static void -cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer, - PangoFont *font, - PangoGlyphString *glyphs, - int xi, - int yi) -{ - CoglPangoRenderer *priv = (CoglPangoRenderer *) renderer; - CoglPangoGlyphCacheValue *cache_value; - int i; - - for (i = 0; i < glyphs->num_glyphs; i++) - { - PangoGlyphInfo *gi = glyphs->glyphs + i; - float x, y; - - cogl_pango_renderer_set_color_for_part (renderer, - PANGO_RENDER_PART_FOREGROUND); - cogl_pango_renderer_get_device_units (renderer, - xi + gi->geometry.x_offset, - yi + gi->geometry.y_offset, - &x, &y); - - if ((gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG)) - { - if (font == NULL) - { - cogl_pango_renderer_draw_box (renderer, - x, - y, - PANGO_UNKNOWN_GLYPH_WIDTH, - PANGO_UNKNOWN_GLYPH_HEIGHT); - } - else - { - PangoRectangle ink_rect; - - pango_font_get_glyph_extents (font, gi->glyph, &ink_rect, NULL); - pango_extents_to_pixels (&ink_rect, NULL); - - cogl_pango_renderer_draw_box (renderer, - x + ink_rect.x, - y + ink_rect.y + ink_rect.height, - ink_rect.width, - ink_rect.height); - } - } - else - { - /* Get the texture containing the glyph */ - cache_value = - cogl_pango_renderer_get_cached_glyph (renderer, - FALSE, - font, - gi->glyph); - - /* cogl_pango_ensure_glyph_cache_for_layout should always be - called before rendering a layout so we should never have - a dirty glyph here */ - g_assert (cache_value == NULL || !cache_value->dirty); - - if (cache_value == NULL) - { - cogl_pango_renderer_draw_box (renderer, - x, - y, - PANGO_UNKNOWN_GLYPH_WIDTH, - PANGO_UNKNOWN_GLYPH_HEIGHT); - } - else if (cache_value->texture) - { - x += (float)(cache_value->draw_x); - y += (float)(cache_value->draw_y); - - /* Do not override color if the glyph/font provide its own */ - if (cache_value->has_color) - { - CoglColor color; - uint16_t alpha; - - alpha = pango_renderer_get_alpha (renderer, - PANGO_RENDER_PART_FOREGROUND); - cogl_color_init_from_4f (&color, 1.0, 1.0, 1.0, - alpha ? (alpha >> 8) / 255.0 : 1.0); - _cogl_pango_display_list_set_color_override (priv->display_list, &color); - } - - cogl_pango_renderer_draw_glyph (priv, cache_value, x, y); - } - } - - xi += gi->geometry.width; - } -} diff --git a/mutter/cogl/cogl-pango/cogl-pango.h b/mutter/cogl/cogl-pango/cogl-pango.h deleted file mode 100644 index 78b8816..0000000 --- a/mutter/cogl/cogl-pango/cogl-pango.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008 OpenedHand - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Neil Roberts - * Robert Bragg - * Matthew Allum - */ - -#pragma once - -#include -#include -#include - -/* XXX: Currently this header may be included both as an internal - * header (within the cogl-pango implementation) and as a public - * header. - * - * Since should not be included for internal use we - * determine the current context and switch between including cogl.h - * or specific internal cogl headers here... - */ -#ifndef COGL_COMPILATION -#include "cogl/cogl.h" -#else -#include "cogl/cogl-context.h" -#include "cogl/cogl-macros.h" -#endif - -G_BEGIN_DECLS - -/* It's too difficult to actually subclass the pango cairo font - * map. Instead we just make a fake set of macros that actually just - * directly use the original type - */ -#define COGL_PANGO_TYPE_FONT_MAP PANGO_TYPE_CAIRO_FONT_MAP -#define COGL_PANGO_FONT_MAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_PANGO_TYPE_FONT_MAP, CoglPangoFontMap)) -#define COGL_PANGO_IS_FONT_MAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_PANGO_TYPE_FONT_MAP)) - -typedef PangoCairoFontMap CoglPangoFontMap; - -/** - * cogl_pango_font_map_new: - * - * Creates a new font map. - * - * Return value: (transfer full): the newly created #PangoFontMap - */ -COGL_EXPORT PangoFontMap * -cogl_pango_font_map_new (void); - -/** - * cogl_pango_font_map_create_context: - * @font_map: a #CoglPangoFontMap - * - * Create a [class@Pango.Context] for the given @font_map. - * - * Returns: (transfer full): the newly created context: free with [method@GObject.Object.unref]. - */ -COGL_EXPORT PangoContext * -cogl_pango_font_map_create_context (CoglPangoFontMap *font_map); - -/** - * cogl_pango_font_map_set_resolution: - * @font_map: a #CoglPangoFontMap - * @dpi: The resolution in "dots per inch". (Physical inches aren't - * actually involved; the terminology is conventional.) - * - * Sets the resolution for the @font_map. - * - * This is a scale factor between points specified in a - * [struct@Pango.FontDescription] and Cogl units. - * The default value is %96, meaning that a 10 point font will be 13 - * units high. (10 * 96. / 72. = 13.3). - */ -COGL_EXPORT void -cogl_pango_font_map_set_resolution (CoglPangoFontMap *font_map, - double dpi); - -/** - * cogl_pango_font_map_clear_glyph_cache: - * @font_map: a #CoglPangoFontMap - * - * Clears the glyph cache for @font_map. - */ -COGL_EXPORT void -cogl_pango_font_map_clear_glyph_cache (CoglPangoFontMap *font_map); - -/** - * cogl_pango_ensure_glyph_cache_for_layout: - * @layout: A #PangoLayout - * - * This updates any internal glyph cache textures as necessary to be - * able to render the given @layout. - * - * This api should be used to avoid mid-scene modifications of - * glyph-cache textures which can lead to undefined rendering results. - */ -COGL_EXPORT void -cogl_pango_ensure_glyph_cache_for_layout (PangoLayout *layout); - -/** - * cogl_pango_font_map_set_use_mipmapping: - * @font_map: a #CoglPangoFontMap - * @value: %TRUE to enable the use of mipmapping - * - * Sets whether the renderer for the passed font map should use - * mipmapping when rendering a [class@Pango.Layout]. - */ -COGL_EXPORT void -cogl_pango_font_map_set_use_mipmapping (CoglPangoFontMap *font_map, - gboolean value); - -/** - * cogl_pango_font_map_get_use_mipmapping: - * @font_map: a #CoglPangoFontMap - * - * Retrieves whether the [class@CoglPango.Renderer] used by @font_map will use - * mipmapping when rendering the glyphs. - * - * Return value: %TRUE if mipmapping is used, %FALSE otherwise. - */ -COGL_EXPORT gboolean -cogl_pango_font_map_get_use_mipmapping (CoglPangoFontMap *font_map); - -/** - * cogl_pango_font_map_get_renderer: - * @font_map: a #CoglPangoFontMap - * - * Retrieves the [class@CoglPango.Renderer] for the passed @font_map. - * - * Return value: (transfer none): a #PangoRenderer - */ -COGL_EXPORT PangoRenderer * -cogl_pango_font_map_get_renderer (CoglPangoFontMap *font_map); - -/** - * cogl_pango_show_layout: (skip) - * @framebuffer: A #CoglFramebuffer to draw too. - * @layout: a #PangoLayout - * @x: X coordinate to render the layout at - * @y: Y coordinate to render the layout at - * @color: color to use when rendering the layout - * - * Draws a solidly coloured @layout on the given @framebuffer at (@x, - * @y) within the `framebuffer`'s current model-view coordinate space. - */ -COGL_EXPORT void -cogl_pango_show_layout (CoglFramebuffer *framebuffer, - PangoLayout *layout, - float x, - float y, - const CoglColor *color); - -/** - * cogl_pango_show_layout_line: (skip) - * @framebuffer: A #CoglFramebuffer to draw too. - * @line: a #PangoLayoutLine - * @x: X coordinate to render the line at - * @y: Y coordinate to render the line at - * @color: color to use when rendering the line - * - * Draws a solidly coloured @line on the given @framebuffer at (@x, - * @y) within the `framebuffer`'s current model-view coordinate space. - */ -COGL_EXPORT void -cogl_pango_show_layout_line (CoglFramebuffer *framebuffer, - PangoLayoutLine *line, - float x, - float y, - const CoglColor *color); - - -#define COGL_PANGO_TYPE_RENDERER (cogl_pango_renderer_get_type ()) -#define COGL_PANGO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_PANGO_TYPE_RENDERER, CoglPangoRenderer)) -#define COGL_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_PANGO_TYPE_RENDERER, CoglPangoRendererClass)) -#define COGL_PANGO_IS_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_PANGO_TYPE_RENDERER)) -#define COGL_PANGO_IS_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_PANGO_TYPE_RENDERER)) -#define COGL_PANGO_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COGL_PANGO_TYPE_RENDERER, CoglPangoRendererClass)) - -/* opaque types */ -typedef struct _CoglPangoRenderer CoglPangoRenderer; -typedef struct _CoglPangoRendererClass CoglPangoRendererClass; - -COGL_EXPORT GType cogl_pango_renderer_get_type (void) G_GNUC_CONST; - -G_END_DECLS diff --git a/mutter/cogl/cogl-pango/meson.build b/mutter/cogl/cogl-pango/meson.build deleted file mode 100644 index 90775f4..0000000 --- a/mutter/cogl/cogl-pango/meson.build +++ /dev/null @@ -1,83 +0,0 @@ -cogl_pango_sources = [ - 'cogl-pango-display-list.c', - 'cogl-pango-display-list.h', - 'cogl-pango-fontmap.c', - 'cogl-pango-glyph-cache.c', - 'cogl-pango-glyph-cache.h', - 'cogl-pango-pipeline-cache.c', - 'cogl-pango-pipeline-cache.h', - 'cogl-pango-private.h', - 'cogl-pango-render.c', -] - -cogl_pango_public_headers = [ - 'cogl-pango.h', -] - -cogl_pango_deps = [ - cairo_dep, - pango_dep, - pangocairo_dep, - libmutter_cogl_dep, -] - -libmutter_cogl_pango_name = 'mutter-cogl-pango-' + libmutter_api_version -libmutter_cogl_pango = shared_library(libmutter_cogl_pango_name, - sources: [cogl_pango_sources, cogl_pango_public_headers], - version: '0.0.0', - soversion: 0, - c_args: cogl_c_args, - include_directories: [cogl_includepath, top_includepath], - gnu_symbol_visibility: 'hidden', - dependencies: [cogl_pango_deps], - install_rpath: pkglibdir, - install_dir: pkglibdir, - install: true, -) - -libmutter_cogl_pango_dep = declare_dependency( - link_with: libmutter_cogl_pango, -) - -if have_introspection - libmutter_cogl_pango_gir = gnome.generate_gir(libmutter_cogl_pango, - sources: cogl_pango_public_headers, - nsversion: libmutter_api_version, - namespace: 'CoglPango', - symbol_prefix: 'cogl_pango', - header: 'cogl-pango.h', - includes: [ - libmutter_mtk_gir[0], - libmutter_cogl_gir[0], - 'Pango-1.0', - 'PangoCairo-1.0' - ], - dependencies: [ - cogl_deps, - pango_dep, - libmutter_cogl_pango_dep, - ], - export_packages: [libmutter_cogl_pango_name], - extra_args: introspection_args + [ - '-UCOGL_COMPILATION', - '-DG_LOG_DOMAIN="CoglPango"', - ], - kwargs: introspection_common, - ) -endif - -cogl_pango_includesubdir = cogl_includesubdir / 'cogl-pango' -install_headers(cogl_pango_public_headers, subdir: cogl_pango_includesubdir) - -pkg.generate(libmutter_cogl_pango, - name: 'CoglPango', - filebase: libmutter_cogl_pango_name, - description: 'A text rendering for Cogl in mutter', - subdirs: pkgname / 'cogl', - requires: [cogl_pkg_deps, libmutter_cogl_name, pango_dep, pangocairo_dep], - version: meson.project_version(), - variables: [ - 'apiversion=' + libmutter_api_version, - ], - install_dir: pcdir, -) diff --git a/mutter/cogl/cogl/cogl-atlas-texture-private.h b/mutter/cogl/cogl/cogl-atlas-texture-private.h deleted file mode 100644 index 251a2c3..0000000 --- a/mutter/cogl/cogl/cogl-atlas-texture-private.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-rectangle-map.h" -#include "cogl/cogl-atlas.h" -#include "cogl/cogl-atlas-texture.h" - -struct _CoglAtlasTexture -{ - CoglTexture parent_instance; - - /* The format that the texture is in. This isn't necessarily the - same format as the atlas texture because we can store - pre-multiplied and non-pre-multiplied textures together */ - CoglPixelFormat internal_format; - - /* The rectangle that was used to add this texture to the - atlas. This includes the 1-pixel border */ - CoglRectangleMapEntry rectangle; - - /* The atlas that this texture is in. If the texture is no longer in - an atlas then this will be NULL. A reference is taken on the - atlas by the texture (but not vice versa so there is no cycle) */ - CoglAtlas *atlas; - - /* Either a CoglSubTexture representing the atlas region for easy - * rendering or if the texture has been migrated out of the atlas it - * may be some other texture type such as CoglTexture2D */ - CoglTexture *sub_texture; -}; - -struct _CoglAtlasTextureClass -{ - CoglTextureClass parent_class; -}; - -COGL_EXPORT void -_cogl_atlas_texture_add_reorganize_callback (CoglContext *ctx, - GHookFunc callback, - void *user_data); - -COGL_EXPORT void -_cogl_atlas_texture_remove_reorganize_callback (CoglContext *ctx, - GHookFunc callback, - void *user_data); diff --git a/mutter/cogl/cogl/cogl-atlas-texture.c b/mutter/cogl/cogl/cogl-atlas-texture.c deleted file mode 100644 index 6d380e3..0000000 --- a/mutter/cogl/cogl/cogl-atlas-texture.c +++ /dev/null @@ -1,995 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009,2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#include "config.h" - -#include "cogl/cogl-debug.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-atlas-texture-private.h" -#include "cogl/cogl-texture-2d-private.h" -#include "cogl/cogl-sub-texture-private.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-texture-driver.h" -#include "cogl/cogl-rectangle-map.h" -#include "cogl/cogl-journal-private.h" -#include "cogl/cogl-atlas.h" -#include "cogl/cogl1-context.h" -#include "cogl/cogl-sub-texture.h" -#include "cogl/driver/gl/cogl-texture-gl-private.h" - -#include - -static GQuark atlas_private_key = 0; - -G_DEFINE_FINAL_TYPE (CoglAtlasTexture, cogl_atlas_texture, COGL_TYPE_TEXTURE) - -static void -_cogl_atlas_texture_remove_from_atlas (CoglAtlasTexture *atlas_tex) -{ - if (atlas_tex->atlas) - { - _cogl_atlas_remove (atlas_tex->atlas, - &atlas_tex->rectangle); - - g_object_unref (atlas_tex->atlas); - atlas_tex->atlas = NULL; - } -} - -static void -cogl_atlas_texture_dispose (GObject *object) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (object); - - _cogl_atlas_texture_remove_from_atlas (atlas_tex); - if (atlas_tex->sub_texture) - g_object_unref (atlas_tex->sub_texture); - - G_OBJECT_CLASS (cogl_atlas_texture_parent_class)->dispose (object); -} - -static CoglTexture * -_cogl_atlas_texture_create_sub_texture (CoglTexture *full_texture, - const CoglRectangleMapEntry *rectangle) -{ - CoglContext *ctx = cogl_texture_get_context (full_texture); - /* Create a subtexture for the given rectangle not including the - 1-pixel border */ - return cogl_sub_texture_new (ctx, - full_texture, - rectangle->x + 1, - rectangle->y + 1, - rectangle->width - 2, - rectangle->height - 2); -} - -static void -_cogl_atlas_texture_update_position_cb (void *user_data, - CoglTexture *new_texture, - const CoglRectangleMapEntry *rectangle) -{ - CoglAtlasTexture *atlas_tex = user_data; - - /* Update the sub texture */ - if (atlas_tex->sub_texture) - g_object_unref (atlas_tex->sub_texture); - atlas_tex->sub_texture = - _cogl_atlas_texture_create_sub_texture (new_texture, rectangle); - - /* Update the position */ - atlas_tex->rectangle = *rectangle; -} - -static void -_cogl_atlas_texture_pre_reorganize_foreach_cb - (const CoglRectangleMapEntry *entry, - void *rectangle_data, - void *user_data) -{ - CoglAtlasTexture *atlas_tex = rectangle_data; - - /* Keep a reference to the texture because we don't want it to be - destroyed during the reorganization */ - g_object_ref (atlas_tex); - - /* Notify cogl-pipeline.c that the texture's underlying GL texture - * storage is changing so it knows it may need to bind a new texture - * if the CoglTexture is reused with the same texture unit. */ - _cogl_pipeline_texture_storage_change_notify (COGL_TEXTURE (atlas_tex)); -} - -static void -_cogl_atlas_texture_pre_reorganize_cb (void *data) -{ - CoglAtlas *atlas = data; - - /* We don't know if any journal entries currently depend on OpenGL - * texture coordinates that would be invalidated by reorganizing - * this atlas so we flush all journals before migrating. - * - * We are assuming that texture atlas migration never happens - * during a flush so we don't have to consider recursion here. - */ - cogl_flush (); - - if (atlas->map) - _cogl_rectangle_map_foreach (atlas->map, - _cogl_atlas_texture_pre_reorganize_foreach_cb, - NULL); -} - -typedef struct -{ - CoglAtlasTexture **textures; - /* Number of textures found so far */ - unsigned int n_textures; -} CoglAtlasTextureGetRectanglesData; - -static void -_cogl_atlas_texture_get_rectangles_cb (const CoglRectangleMapEntry *entry, - void *rectangle_data, - void *user_data) -{ - CoglAtlasTextureGetRectanglesData *data = user_data; - - data->textures[data->n_textures++] = rectangle_data; -} - -static void -_cogl_atlas_texture_post_reorganize_cb (void *user_data) -{ - CoglAtlas *atlas = user_data; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (atlas->map) - { - CoglAtlasTextureGetRectanglesData data; - unsigned int i; - - data.textures = g_new (CoglAtlasTexture *, - _cogl_rectangle_map_get_n_rectangles (atlas->map)); - data.n_textures = 0; - - /* We need to remove all of the references that we took during - the preorganize callback. We have to get a separate array of - the textures because CoglRectangleMap doesn't support - removing rectangles during iteration */ - _cogl_rectangle_map_foreach (atlas->map, - _cogl_atlas_texture_get_rectangles_cb, - &data); - - for (i = 0; i < data.n_textures; i++) - { - /* Ignore textures that don't have an atlas yet. This will - happen when a new texture is added because we allocate - the structure for the texture so that it can get stored - in the atlas but it isn't a valid object yet */ - if (data.textures[i]->atlas) - g_object_unref (data.textures[i]); - } - - g_free (data.textures); - } - - /* Notify any listeners that an atlas has changed */ - g_hook_list_invoke (&ctx->atlas_reorganize_callbacks, FALSE); -} - -static void -_cogl_atlas_texture_atlas_destroyed_cb (void *user_data) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Remove the atlas from the global list */ - ctx->atlases = g_slist_remove (ctx->atlases, user_data); -} - -static CoglAtlas * -_cogl_atlas_texture_create_atlas (CoglContext *ctx) -{ - atlas_private_key = g_quark_from_static_string ("-cogl-atlas-texture-create-key"); - - CoglAtlas *atlas = _cogl_atlas_new (COGL_PIXEL_FORMAT_RGBA_8888, - 0, - _cogl_atlas_texture_update_position_cb); - - _cogl_atlas_add_reorganize_callback (atlas, - _cogl_atlas_texture_pre_reorganize_cb, - _cogl_atlas_texture_post_reorganize_cb, - atlas); - - ctx->atlases = g_slist_prepend (ctx->atlases, atlas); - - /* Set some data on the atlas so we can get notification when it is - destroyed in order to remove it from the list. ctx->atlases - effectively holds a weak reference. We don't need a strong - reference because the atlas textures take a reference on the - atlas so it will stay alive */ - g_object_set_qdata_full (G_OBJECT (atlas), - atlas_private_key, - atlas, - _cogl_atlas_texture_atlas_destroyed_cb); - - return atlas; -} - -static void -_cogl_atlas_texture_foreach_sub_texture_in_region ( - CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglMetaTextureCallback callback, - void *user_data) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - cogl_meta_texture_foreach_in_region (atlas_tex->sub_texture, - virtual_tx_1, - virtual_ty_1, - virtual_tx_2, - virtual_ty_2, - COGL_PIPELINE_WRAP_MODE_REPEAT, - COGL_PIPELINE_WRAP_MODE_REPEAT, - callback, - user_data); -} - -static void -_cogl_atlas_texture_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - _cogl_texture_gl_flush_legacy_texobj_wrap_modes (atlas_tex->sub_texture, - wrap_mode_s, - wrap_mode_t); -} - -static int -_cogl_atlas_texture_get_max_waste (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return cogl_texture_get_max_waste (atlas_tex->sub_texture); -} - -static gboolean -_cogl_atlas_texture_is_sliced (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return cogl_texture_is_sliced (atlas_tex->sub_texture); -} - -static gboolean -_cogl_atlas_texture_can_hardware_repeat (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return _cogl_texture_can_hardware_repeat (atlas_tex->sub_texture); -} - -static void -_cogl_atlas_texture_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - _cogl_texture_transform_coords_to_gl (atlas_tex->sub_texture, s, t); -} - -static CoglTransformResult -_cogl_atlas_texture_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return _cogl_texture_transform_quad_coords_to_gl (atlas_tex->sub_texture, - coords); -} - -static gboolean -_cogl_atlas_texture_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return cogl_texture_get_gl_texture (atlas_tex->sub_texture, - out_gl_handle, - out_gl_target); -} - -static void -_cogl_atlas_texture_gl_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - _cogl_texture_gl_flush_legacy_texobj_filters (atlas_tex->sub_texture, - min_filter, mag_filter); -} - -static void -_cogl_atlas_texture_migrate_out_of_atlas (CoglAtlasTexture *atlas_tex) -{ - CoglTexture *standalone_tex; - - /* Make sure this texture is not in the atlas */ - if (!atlas_tex->atlas) - return; - - COGL_NOTE (ATLAS, "Migrating texture out of the atlas"); - - /* We don't know if any journal entries currently depend on - * OpenGL texture coordinates that would be invalidated by - * migrating textures in this atlas so we flush all journals - * before migrating. - * - * We are assuming that texture atlas migration never happens - * during a flush so we don't have to consider recursion here. - */ - cogl_flush (); - - standalone_tex = - _cogl_atlas_copy_rectangle (atlas_tex->atlas, - atlas_tex->rectangle.x + 1, - atlas_tex->rectangle.y + 1, - atlas_tex->rectangle.width - 2, - atlas_tex->rectangle.height - 2, - atlas_tex->internal_format); - /* Note: we simply silently ignore failures to migrate a texture - * out (most likely due to lack of memory) and hope for the - * best. - * - * Maybe we should find a way to report the problem back to the - * app. - */ - if (!standalone_tex) - return; - - /* Notify cogl-pipeline.c that the texture's underlying GL texture - * storage is changing so it knows it may need to bind a new texture - * if the CoglTexture is reused with the same texture unit. */ - _cogl_pipeline_texture_storage_change_notify (COGL_TEXTURE (atlas_tex)); - - /* We need to unref the sub texture after doing the copy because - the copy can involve rendering which might cause the texture - to be used if it is used from a layer that is left in a - texture unit */ - g_object_unref (atlas_tex->sub_texture); - atlas_tex->sub_texture = standalone_tex; - - _cogl_atlas_texture_remove_from_atlas (atlas_tex); -} - -static void -_cogl_atlas_texture_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - if ((flags & COGL_TEXTURE_NEEDS_MIPMAP)) - /* Mipmaps do not work well with the current atlas so instead - we'll just migrate the texture out and use a regular texture */ - _cogl_atlas_texture_migrate_out_of_atlas (atlas_tex); - - /* Forward on to the sub texture */ - _cogl_texture_pre_paint (atlas_tex->sub_texture, flags); -} - -static void -_cogl_atlas_texture_ensure_non_quad_rendering (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Sub textures can't support non-quad rendering so we'll just - migrate the texture out */ - _cogl_atlas_texture_migrate_out_of_atlas (atlas_tex); - - /* Forward on to the sub texture */ - _cogl_texture_ensure_non_quad_rendering (atlas_tex->sub_texture); -} - -static gboolean -_cogl_atlas_texture_set_region_with_border (CoglAtlasTexture *atlas_tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int dst_width, - int dst_height, - CoglBitmap *bmp, - GError **error) -{ - CoglAtlas *atlas = atlas_tex->atlas; - - /* Copy the central data */ - if (!_cogl_texture_set_region_from_bitmap (atlas->texture, - src_x, src_y, - dst_width, - dst_height, - bmp, - dst_x + atlas_tex->rectangle.x + 1, - dst_y + atlas_tex->rectangle.y + 1, - 0, /* level 0 */ - error)) - return FALSE; - - /* Update the left edge pixels */ - if (dst_x == 0 && - !_cogl_texture_set_region_from_bitmap (atlas->texture, - src_x, src_y, - 1, dst_height, - bmp, - atlas_tex->rectangle.x, - dst_y + atlas_tex->rectangle.y + 1, - 0, /* level 0 */ - error)) - return FALSE; - /* Update the right edge pixels */ - if (dst_x + dst_width == atlas_tex->rectangle.width - 2 && - !_cogl_texture_set_region_from_bitmap (atlas->texture, - src_x + dst_width - 1, src_y, - 1, dst_height, - bmp, - atlas_tex->rectangle.x + - atlas_tex->rectangle.width - 1, - dst_y + atlas_tex->rectangle.y + 1, - 0, /* level 0 */ - error)) - return FALSE; - /* Update the top edge pixels */ - if (dst_y == 0 && - !_cogl_texture_set_region_from_bitmap (atlas->texture, - src_x, src_y, - dst_width, 1, - bmp, - dst_x + atlas_tex->rectangle.x + 1, - atlas_tex->rectangle.y, - 0, /* level 0 */ - error)) - return FALSE; - /* Update the bottom edge pixels */ - if (dst_y + dst_height == atlas_tex->rectangle.height - 2 && - !_cogl_texture_set_region_from_bitmap (atlas->texture, - src_x, src_y + dst_height - 1, - dst_width, 1, - bmp, - dst_x + atlas_tex->rectangle.x + 1, - atlas_tex->rectangle.y + - atlas_tex->rectangle.height - 1, - 0, /* level 0 */ - error)) - return FALSE; - - return TRUE; -} - -static CoglBitmap * -_cogl_atlas_texture_convert_bitmap_for_upload (CoglAtlasTexture *atlas_tex, - CoglBitmap *bmp, - CoglPixelFormat internal_format, - GError **error) -{ - CoglBitmap *upload_bmp; - CoglBitmap *override_bmp; - - /* We'll prepare to upload using the format of the actual texture of - the atlas texture instead of the format reported by - _cogl_texture_get_format which would be the original internal - format specified when the texture was created. However we'll - preserve the premult status of the internal format because the - images are all stored in the original premult format of the - original format so we do need to trigger the conversion */ - - internal_format = (COGL_PIXEL_FORMAT_RGBA_8888 | - (internal_format & COGL_PREMULT_BIT)); - - upload_bmp = _cogl_bitmap_convert_for_upload (bmp, - internal_format, - error); - if (upload_bmp == NULL) - return NULL; - - /* We'll create another bitmap which uses the same data but - overrides the format to remove the premult flag so that uploads - to the atlas texture won't trigger the conversion again */ - - override_bmp = - _cogl_bitmap_new_shared (upload_bmp, - cogl_bitmap_get_format (upload_bmp) & - ~COGL_PREMULT_BIT, - cogl_bitmap_get_width (upload_bmp), - cogl_bitmap_get_height (upload_bmp), - cogl_bitmap_get_rowstride (upload_bmp)); - - g_object_unref (upload_bmp); - - return override_bmp; -} - -static gboolean -_cogl_atlas_texture_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int dst_width, - int dst_height, - int level, - CoglBitmap *bmp, - GError **error) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - if (level != 0 && atlas_tex->atlas) - _cogl_atlas_texture_migrate_out_of_atlas (atlas_tex); - - /* If the texture is in the atlas then we need to copy the edge - pixels to the border */ - if (atlas_tex->atlas) - { - gboolean ret; - CoglBitmap *upload_bmp = - _cogl_atlas_texture_convert_bitmap_for_upload (atlas_tex, - bmp, - atlas_tex->internal_format, - error); - if (!upload_bmp) - return FALSE; - - /* Upload the data ignoring the premult bit */ - ret = _cogl_atlas_texture_set_region_with_border (atlas_tex, - src_x, src_y, - dst_x, dst_y, - dst_width, dst_height, - upload_bmp, - error); - - g_object_unref (upload_bmp); - - return ret; - } - else - /* Otherwise we can just forward on to the sub texture */ - return _cogl_texture_set_region_from_bitmap (atlas_tex->sub_texture, - src_x, src_y, - dst_width, dst_height, - bmp, - dst_x, dst_y, - level, - error); -} - -static CoglPixelFormat -_cogl_atlas_texture_get_format (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* We don't want to forward this on the sub-texture because it isn't - the necessarily the same format. This will happen if the texture - isn't pre-multiplied */ - return atlas_tex->internal_format; -} - -static GLenum -_cogl_atlas_texture_get_gl_format (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return _cogl_texture_gl_get_format (atlas_tex->sub_texture); -} - -static gboolean -_cogl_atlas_texture_can_use_format (CoglPixelFormat format) -{ - /* We don't care about the ordering or the premult status and we can - accept RGBA or RGB textures. Although we could also accept - luminance and alpha only textures or 16-bit formats it seems that - if the application is explicitly using these formats then they've - got a reason to want the lower memory requirements so putting - them in the atlas might not be a good idea */ - format &= ~(COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT); - return (format == COGL_PIXEL_FORMAT_RGB_888 || - format == COGL_PIXEL_FORMAT_RGBA_8888); -} - -static gboolean -allocate_space (CoglAtlasTexture *atlas_tex, - int width, - int height, - CoglPixelFormat internal_format, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (atlas_tex); - CoglContext *ctx = cogl_texture_get_context (tex); - CoglAtlas *atlas; - GSList *l; - - /* If the texture is in a strange format then we won't use it */ - if (!_cogl_atlas_texture_can_use_format (internal_format)) - { - COGL_NOTE (ATLAS, "Texture can not be added because the " - "format is unsupported"); - g_set_error_literal (error, - COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_FORMAT, - "Texture format unsuitable for atlasing"); - return FALSE; - } - - /* Look for an existing atlas that can hold the texture */ - for (l = ctx->atlases; l; l = l->next) - { - /* We need to take a reference on the atlas before trying to - * reserve space because in some circumstances atlas migration - * can cause the atlas to be freed */ - atlas = g_object_ref (l->data); - /* Try to make some space in the atlas for the texture */ - if (_cogl_atlas_reserve_space (atlas, - /* Add two pixels for the border */ - width + 2, height + 2, - atlas_tex)) - { - /* keep the atlas reference */ - break; - } - else - { - g_object_unref (atlas); - } - } - - /* If we couldn't find a suitable atlas then start another */ - if (l == NULL) - { - atlas = _cogl_atlas_texture_create_atlas (ctx); - COGL_NOTE (ATLAS, "Created new atlas for textures: %p", atlas); - if (!_cogl_atlas_reserve_space (atlas, - /* Add two pixels for the border */ - width + 2, height + 2, - atlas_tex)) - { - /* Ok, this means we really can't add it to the atlas */ - g_object_unref (atlas); - - g_set_error_literal (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_NO_MEMORY, - "Not enough memory to atlas texture"); - return FALSE; - } - } - - atlas_tex->internal_format = internal_format; - - atlas_tex->atlas = atlas; - - return TRUE; -} - -static gboolean -allocate_with_size (CoglAtlasTexture *atlas_tex, - CoglTextureLoader *loader, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (atlas_tex); - CoglPixelFormat internal_format; - - g_warn_if_fail (loader->src.sized.format == COGL_PIXEL_FORMAT_ANY); - - internal_format = - _cogl_texture_determine_internal_format (tex, COGL_PIXEL_FORMAT_ANY); - - if (allocate_space (atlas_tex, - loader->src.sized.width, - loader->src.sized.height, - internal_format, - error)) - { - _cogl_texture_set_allocated (tex, - internal_format, - loader->src.sized.width, - loader->src.sized.height); - return TRUE; - } - else - return FALSE; -} - -static gboolean -allocate_from_bitmap (CoglAtlasTexture *atlas_tex, - CoglTextureLoader *loader, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (atlas_tex); - CoglBitmap *bmp = loader->src.bitmap.bitmap; - CoglPixelFormat bmp_format = cogl_bitmap_get_format (bmp); - int width = cogl_bitmap_get_width (bmp); - int height = cogl_bitmap_get_height (bmp); - CoglPixelFormat internal_format; - CoglBitmap *upload_bmp; - - g_return_val_if_fail (atlas_tex->atlas == NULL, FALSE); - - internal_format = _cogl_texture_determine_internal_format (tex, bmp_format); - - upload_bmp = - _cogl_atlas_texture_convert_bitmap_for_upload (atlas_tex, - bmp, - internal_format, - error); - if (upload_bmp == NULL) - return FALSE; - - if (!allocate_space (atlas_tex, - width, - height, - internal_format, - error)) - { - g_object_unref (upload_bmp); - return FALSE; - } - - /* Defer to set_region so that we can share the code for copying the - edge pixels to the border. */ - if (!_cogl_atlas_texture_set_region_with_border (atlas_tex, - 0, /* src_x */ - 0, /* src_y */ - 0, /* dst_x */ - 0, /* dst_y */ - width, /* dst_width */ - height, /* dst_height */ - upload_bmp, - error)) - { - _cogl_atlas_texture_remove_from_atlas (atlas_tex); - g_object_unref (upload_bmp); - return FALSE; - } - - g_object_unref (upload_bmp); - - _cogl_texture_set_allocated (tex, internal_format, width, height); - - return TRUE; -} - -static gboolean -_cogl_atlas_texture_allocate (CoglTexture *tex, - GError **error) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - CoglTextureLoader *loader = cogl_texture_get_loader (tex); - - g_return_val_if_fail (loader, FALSE); - - switch (loader->src_type) - { - case COGL_TEXTURE_SOURCE_TYPE_SIZE: - return allocate_with_size (atlas_tex, loader, error); - case COGL_TEXTURE_SOURCE_TYPE_BITMAP: - return allocate_from_bitmap (atlas_tex, loader, error); - default: - break; - } - - g_return_val_if_reached (FALSE); -} - -static void -cogl_atlas_texture_class_init (CoglAtlasTextureClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - CoglTextureClass *texture_class = COGL_TEXTURE_CLASS (klass); - - object_class->dispose = cogl_atlas_texture_dispose; - - texture_class->allocate = _cogl_atlas_texture_allocate; - texture_class->set_region = _cogl_atlas_texture_set_region; - texture_class->foreach_sub_texture_in_region = _cogl_atlas_texture_foreach_sub_texture_in_region; - texture_class->get_max_waste = _cogl_atlas_texture_get_max_waste; - texture_class->is_sliced = _cogl_atlas_texture_is_sliced; - texture_class->can_hardware_repeat = _cogl_atlas_texture_can_hardware_repeat; - - texture_class->transform_coords_to_gl = _cogl_atlas_texture_transform_coords_to_gl; - texture_class->transform_quad_coords_to_gl = _cogl_atlas_texture_transform_quad_coords_to_gl; - texture_class->get_gl_texture = _cogl_atlas_texture_get_gl_texture; - texture_class->gl_flush_legacy_texobj_filters = _cogl_atlas_texture_gl_flush_legacy_texobj_filters; - texture_class->pre_paint = _cogl_atlas_texture_pre_paint; - texture_class->ensure_non_quad_rendering = _cogl_atlas_texture_ensure_non_quad_rendering; - texture_class->gl_flush_legacy_texobj_wrap_modes = _cogl_atlas_texture_gl_flush_legacy_texobj_wrap_modes; - texture_class->get_format = _cogl_atlas_texture_get_format; - texture_class->get_gl_format = _cogl_atlas_texture_get_gl_format; -} - -static void -cogl_atlas_texture_init (CoglAtlasTexture *self) -{ - CoglTexture *texture = COGL_TEXTURE (self); - - texture->is_primitive = FALSE; -} - -static CoglTexture * -_cogl_atlas_texture_create_base (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format, - CoglTextureLoader *loader) -{ - CoglAtlasTexture *atlas_tex; - - COGL_NOTE (ATLAS, "Adding texture of size %ix%i", width, height); - - /* We need to allocate the texture now because we need the pointer - to set as the data for the rectangle in the atlas */ - atlas_tex = g_object_new (COGL_TYPE_ATLAS_TEXTURE, - "context", ctx, - "width", width, - "height", height, - "loader", loader, - "format", internal_format, - NULL); - /* Mark it as having no atlas so we don't try to unref it in - _cogl_atlas_texture_post_reorganize_cb */ - atlas_tex->atlas = NULL; - atlas_tex->sub_texture = NULL; - atlas_tex->atlas = NULL; - - return COGL_TEXTURE (atlas_tex); -} - -CoglTexture * -cogl_atlas_texture_new_with_size (CoglContext *ctx, - int width, - int height) -{ - CoglTextureLoader *loader; - - /* We can't atlas zero-sized textures because it breaks the atlas - * data structure */ - g_return_val_if_fail (width > 0 && height > 0, NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_SIZE; - loader->src.sized.width = width; - loader->src.sized.height = height; - loader->src.sized.format = COGL_PIXEL_FORMAT_ANY; - - return _cogl_atlas_texture_create_base (ctx, width, height, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - loader); -} - -CoglTexture * -cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp) -{ - CoglTextureLoader *loader; - - g_return_val_if_fail (COGL_IS_BITMAP (bmp), NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_BITMAP; - loader->src.bitmap.bitmap = g_object_ref (bmp); - - return _cogl_atlas_texture_create_base (_cogl_bitmap_get_context (bmp), - cogl_bitmap_get_width (bmp), - cogl_bitmap_get_height (bmp), - cogl_bitmap_get_format (bmp), - loader); -} - -CoglTexture * -cogl_atlas_texture_new_from_data (CoglContext *ctx, - int width, - int height, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - GError **error) -{ - CoglBitmap *bmp; - CoglTexture *atlas_tex; - - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); - g_return_val_if_fail (data != NULL, NULL); - - /* Rowstride from width if not given */ - if (rowstride == 0) - rowstride = width * cogl_pixel_format_get_bytes_per_pixel (format, 0); - - /* Wrap the data into a bitmap */ - bmp = cogl_bitmap_new_for_data (ctx, - width, height, - format, - rowstride, - (uint8_t *) data); - - atlas_tex = cogl_atlas_texture_new_from_bitmap (bmp); - - g_object_unref (bmp); - - if (atlas_tex && - !cogl_texture_allocate (COGL_TEXTURE (atlas_tex), error)) - { - g_object_unref (atlas_tex); - return NULL; - } - - return atlas_tex; -} - -void -_cogl_atlas_texture_add_reorganize_callback (CoglContext *ctx, - GHookFunc callback, - void *user_data) -{ - GHook *hook = g_hook_alloc (&ctx->atlas_reorganize_callbacks); - hook->func = callback; - hook->data = user_data; - g_hook_prepend (&ctx->atlas_reorganize_callbacks, hook); -} - -void -_cogl_atlas_texture_remove_reorganize_callback (CoglContext *ctx, - GHookFunc callback, - void *user_data) -{ - GHook *hook = g_hook_find_func_data (&ctx->atlas_reorganize_callbacks, - FALSE, - callback, - user_data); - - if (hook) - g_hook_destroy_link (&ctx->atlas_reorganize_callbacks, hook); -} diff --git a/mutter/cogl/cogl/cogl-atlas-texture.h b/mutter/cogl/cogl/cogl-atlas-texture.h deleted file mode 100644 index 086db3c..0000000 --- a/mutter/cogl/cogl/cogl-atlas-texture.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-context.h" - -#include - -G_BEGIN_DECLS - -/** - * CoglAtlasTexture: - * - * Functions for managing textures in Cogl's global - * set of texture atlases - * - * A texture atlas is a texture that contains many smaller images that - * an application is interested in. These are packed together as a way - * of optimizing drawing with those images by avoiding the costs of - * repeatedly telling the hardware to change what texture it should - * sample from. This can enable more geometry to be batched together - * into few draw calls. - * - * Each #CoglContext has an shared, pool of texture atlases that are - * are managed by Cogl. - * - * This api lets applications upload texture data into one of Cogl's - * shared texture atlases using a high-level #CoglAtlasTexture which - * represents a sub-region of one of these atlases. - * - * A #CoglAtlasTexture is a high-level meta texture which has - * some limitations to be aware of. Please see the documentation for - * #CoglMetaTexture for more details. - */ -#define COGL_TYPE_ATLAS_TEXTURE (cogl_atlas_texture_get_type ()) -#define COGL_ATLAS_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_ATLAS_TEXTURE, CoglAtlasTexture)) -#define COGL_ATLAS_TEXTURE_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_ATLAS_TEXTURE, CoglAtlasTexture const)) -#define COGL_ATLAS_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_TYPE_ATLAS_TEXTURE, CoglAtlasTextureClass)) -#define COGL_IS_ATLAS_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_TYPE_ATLAS_TEXTURE)) -#define COGL_IS_ATLAS_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_TYPE_ATLAS_TEXTURE)) -#define COGL_ATLAS_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COGL_TYPE_ATLAS_TEXTURE, CoglAtlasTextureClass)) - -typedef struct _CoglAtlasTextureClass CoglAtlasTextureClass; -typedef struct _CoglAtlasTexture CoglAtlasTexture; - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (CoglAtlasTexture, g_object_unref) - -COGL_EXPORT -GType cogl_atlas_texture_get_type (void) G_GNUC_CONST; - -/** - * cogl_atlas_texture_new_with_size: - * @ctx: A #CoglContext - * @width: The width of your atlased texture. - * @height: The height of your atlased texture. - * - * Creates a #CoglAtlasTexture with a given @width and @height. A - * #CoglAtlasTexture represents a sub-region within one of Cogl's - * shared texture atlases. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or let Cogl automatically allocate - * storage lazily. - * - * The texture is still configurable until it has been allocated so - * for example you can influence the internal format of the texture - * using cogl_texture_set_components() and - * cogl_texture_set_premultiplied(). - * - * Allocate call can fail if Cogl considers the internal - * format to be incompatible with the format of its internal - * atlases. - * - * The returned #CoglAtlasTexture is a high-level meta-texture - * with some limitations. See the documentation for #CoglMetaTexture - * for more details. - * - * Returns: (transfer full): A new #CoglAtlasTexture object. - */ -COGL_EXPORT CoglTexture * -cogl_atlas_texture_new_with_size (CoglContext *ctx, - int width, - int height); - -/** - * cogl_atlas_texture_new_from_data: - * @ctx: A #CoglContext - * @width: width of texture in pixels - * @height: height of texture in pixels - * @format: the #CoglPixelFormat the buffer is stored in in RAM - * @rowstride: the memory offset in bytes between the start of each - * row in @data. A value of 0 will make Cogl automatically - * calculate @rowstride from @width and @format. - * @data: pointer to the memory region where the source buffer resides - * @error: A #GError to catch exceptional errors or %NULL - * - * Creates a new #CoglAtlasTexture texture based on data residing in - * memory. A #CoglAtlasTexture represents a sub-region within one of - * Cogl's shared texture atlases. - * - * This api will always immediately allocate GPU memory for the - * texture and upload the given data so that the @data pointer does - * not need to remain valid once this function returns. This means it - * is not possible to configure the texture before it is allocated. If - * you do need to configure the texture before allocation (to specify - * constraints on the internal format for example) then you can - * instead create a #CoglBitmap for your data and use - * cogl_atlas_texture_new_from_bitmap() or use - * cogl_atlas_texture_new_with_size() and then upload data using - * cogl_texture_set_data() - * - * Allocate call can fail if Cogl considers the internal - * format to be incompatible with the format of its internal - * atlases. - * - * The returned #CoglAtlasTexture is a high-level - * meta-texture with some limitations. See the documentation for - * #CoglMetaTexture for more details. - * - * Return value: (transfer full): A new #CoglAtlasTexture object or - * %NULL on failure and @error will be updated. - */ -COGL_EXPORT CoglTexture * -cogl_atlas_texture_new_from_data (CoglContext *ctx, - int width, - int height, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - GError **error); - -/** - * cogl_atlas_texture_new_from_bitmap: - * @bmp: A #CoglBitmap - * - * Creates a new #CoglAtlasTexture texture based on data residing in a - * @bmp. A #CoglAtlasTexture represents a sub-region within one of - * Cogl's shared texture atlases. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or preferably let Cogl - * automatically allocate storage lazily when it may know more about - * how the texture is being used and can optimize how it is allocated. - * - * The texture is still configurable until it has been allocated so - * for example you can influence the internal format of the texture - * using cogl_texture_set_components() and - * cogl_texture_set_premultiplied(). - * - * Allocate call can fail if Cogl considers the internal - * format to be incompatible with the format of its internal - * atlases. - * - * The returned #CoglAtlasTexture is a high-level meta-texture - * with some limitations. See the documentation for #CoglMetaTexture - * for more details. - * - * Returns: (transfer full): A new #CoglAtlasTexture object. - */ -COGL_EXPORT CoglTexture * -cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-atlas.c b/mutter/cogl/cogl/cogl-atlas.c deleted file mode 100644 index cb8c8a5..0000000 --- a/mutter/cogl/cogl/cogl-atlas.c +++ /dev/null @@ -1,696 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Neil Roberts - */ - -#include "config.h" - -#include "cogl/cogl-atlas.h" -#include "cogl/cogl-rectangle-map.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-texture-2d-private.h" -#include "cogl/cogl-texture-2d-sliced.h" -#include "cogl/cogl-texture-driver.h" -#include "cogl/cogl-debug.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-blit.h" -#include "cogl/cogl-private.h" - -#include - -G_DEFINE_TYPE (CoglAtlas, cogl_atlas, G_TYPE_OBJECT); - -static void -cogl_atlas_dispose (GObject *object) -{ - CoglAtlas *atlas = COGL_ATLAS (object); - - COGL_NOTE (ATLAS, "%p: Atlas destroyed", atlas); - - if (atlas->texture) - g_object_unref (atlas->texture); - if (atlas->map) - _cogl_rectangle_map_free (atlas->map); - - g_hook_list_clear (&atlas->pre_reorganize_callbacks); - g_hook_list_clear (&atlas->post_reorganize_callbacks); - - G_OBJECT_CLASS (cogl_atlas_parent_class)->dispose (object); -} - -static void -cogl_atlas_init (CoglAtlas *atlas) -{ -} - -static void -cogl_atlas_class_init (CoglAtlasClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = cogl_atlas_dispose; -} - -CoglAtlas * -_cogl_atlas_new (CoglPixelFormat texture_format, - CoglAtlasFlags flags, - CoglAtlasUpdatePositionCallback update_position_cb) -{ - CoglAtlas *atlas = g_object_new (COGL_TYPE_ATLAS, NULL); - - atlas->update_position_cb = update_position_cb; - atlas->map = NULL; - atlas->texture = NULL; - atlas->flags = flags; - atlas->texture_format = texture_format; - g_hook_list_init (&atlas->pre_reorganize_callbacks, sizeof (GHook)); - g_hook_list_init (&atlas->post_reorganize_callbacks, sizeof (GHook)); - - return atlas; -} - -typedef struct _CoglAtlasRepositionData -{ - /* The current user data for this texture */ - void *user_data; - /* The old and new positions of the texture */ - CoglRectangleMapEntry old_position; - CoglRectangleMapEntry new_position; -} CoglAtlasRepositionData; - -static void -_cogl_atlas_migrate (CoglAtlas *atlas, - unsigned int n_textures, - CoglAtlasRepositionData *textures, - CoglTexture *old_texture, - CoglTexture *new_texture, - void *skip_user_data) -{ - unsigned int i; - CoglBlitData blit_data; - - /* If the 'disable migrate' flag is set then we won't actually copy - the textures to their new location. Instead we'll just invoke the - callback to update the position */ - if ((atlas->flags & COGL_ATLAS_DISABLE_MIGRATION)) - for (i = 0; i < n_textures; i++) - /* Update the texture position */ - atlas->update_position_cb (textures[i].user_data, - new_texture, - &textures[i].new_position); - else - { - _cogl_blit_begin (&blit_data, new_texture, old_texture); - - for (i = 0; i < n_textures; i++) - { - /* Skip the texture that is being added because it doesn't contain - any data yet */ - if (textures[i].user_data != skip_user_data) - _cogl_blit (&blit_data, - textures[i].old_position.x, - textures[i].old_position.y, - textures[i].new_position.x, - textures[i].new_position.y, - textures[i].new_position.width, - textures[i].new_position.height); - - /* Update the texture position */ - atlas->update_position_cb (textures[i].user_data, - new_texture, - &textures[i].new_position); - } - - _cogl_blit_end (&blit_data); - } -} - -typedef struct _CoglAtlasGetRectanglesData -{ - CoglAtlasRepositionData *textures; - /* Number of textures found so far */ - unsigned int n_textures; -} CoglAtlasGetRectanglesData; - -static void -_cogl_atlas_get_rectangles_cb (const CoglRectangleMapEntry *rectangle, - void *rect_data, - void *user_data) -{ - CoglAtlasGetRectanglesData *data = user_data; - - data->textures[data->n_textures].old_position = *rectangle; - data->textures[data->n_textures++].user_data = rect_data; -} - -static void -_cogl_atlas_get_next_size (unsigned int *map_width, - unsigned int *map_height) -{ - /* Double the size of the texture by increasing whichever dimension - is smaller */ - if (*map_width < *map_height) - *map_width <<= 1; - else - *map_height <<= 1; -} - -static void -_cogl_atlas_get_initial_size (CoglPixelFormat format, - unsigned int *map_width, - unsigned int *map_height) -{ - unsigned int size; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (cogl_pixel_format_get_n_planes (format) == 1); - - ctx->driver_vtable->pixel_format_to_gl (ctx, - format, - &gl_intformat, - &gl_format, - &gl_type); - - /* At least on Intel hardware, the texture size will be rounded up - to at least 1MB so we might as well try to aim for that as an - initial minimum size. If the format is only 1 byte per pixel we - can use 1024x1024, otherwise we'll assume it will take 4 bytes - per pixel and use 512x512. */ - if (cogl_pixel_format_get_bytes_per_pixel (format, 0) == 1) - size = 1024; - else - size = 512; - - /* Some platforms might not support this large size so we'll - decrease the size until it can */ - while (size > 1 && - !ctx->texture_driver->size_supported (ctx, - GL_TEXTURE_2D, - gl_intformat, - gl_format, - gl_type, - size, size)) - size >>= 1; - - *map_width = size; - *map_height = size; -} - -static CoglRectangleMap * -_cogl_atlas_create_map (CoglPixelFormat format, - unsigned int map_width, - unsigned int map_height, - unsigned int n_textures, - CoglAtlasRepositionData *textures) -{ - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - - _COGL_GET_CONTEXT (ctx, NULL); - - ctx->driver_vtable->pixel_format_to_gl (ctx, - format, - &gl_intformat, - &gl_format, - &gl_type); - - /* Keep trying increasingly larger atlases until we can fit all of - the textures */ - while (ctx->texture_driver->size_supported (ctx, - GL_TEXTURE_2D, - gl_intformat, - gl_format, - gl_type, - map_width, map_height)) - { - CoglRectangleMap *new_atlas = _cogl_rectangle_map_new (map_width, - map_height, - NULL); - unsigned int i; - - COGL_NOTE (ATLAS, "Trying to resize the atlas to %ux%u", - map_width, map_height); - - /* Add all of the textures and keep track of the new position */ - for (i = 0; i < n_textures; i++) - if (!_cogl_rectangle_map_add (new_atlas, - textures[i].old_position.width, - textures[i].old_position.height, - textures[i].user_data, - &textures[i].new_position)) - break; - - /* If the atlas can contain all of the textures then we have a - winner */ - if (i >= n_textures) - return new_atlas; - else - COGL_NOTE (ATLAS, "Atlas size abandoned after trying " - "%u out of %u textures", - i, n_textures); - - _cogl_rectangle_map_free (new_atlas); - _cogl_atlas_get_next_size (&map_width, &map_height); - } - - /* If we get here then there's no atlas that can accommodate all of - the rectangles */ - - return NULL; -} - -static CoglTexture * -_cogl_atlas_create_texture (CoglAtlas *atlas, - int width, - int height) -{ - CoglTexture *tex; - GError *ignore_error = NULL; - - _COGL_GET_CONTEXT (ctx, NULL); - - g_return_val_if_fail ( - cogl_pixel_format_get_n_planes (atlas->texture_format) == 1, - NULL); - - if ((atlas->flags & COGL_ATLAS_CLEAR_TEXTURE)) - { - uint8_t *clear_data; - CoglBitmap *clear_bmp; - int bpp = cogl_pixel_format_get_bytes_per_pixel (atlas->texture_format, - 0); - - /* Create a buffer of zeroes to initially clear the texture */ - clear_data = g_malloc0 (width * height * bpp); - clear_bmp = cogl_bitmap_new_for_data (ctx, - width, - height, - atlas->texture_format, - width * bpp, - clear_data); - - tex = cogl_texture_2d_new_from_bitmap (clear_bmp); - - _cogl_texture_set_internal_format (tex, - atlas->texture_format); - - if (!cogl_texture_allocate (tex, &ignore_error)) - { - g_error_free (ignore_error); - g_object_unref (tex); - tex = NULL; - } - - g_object_unref (clear_bmp); - - g_free (clear_data); - } - else - { - tex = cogl_texture_2d_new_with_size (ctx, width, height); - - _cogl_texture_set_internal_format (tex, - atlas->texture_format); - - if (!cogl_texture_allocate (tex, &ignore_error)) - { - g_error_free (ignore_error); - g_object_unref (tex); - tex = NULL; - } - } - - return tex; -} - -static int -_cogl_atlas_compare_size_cb (const void *a, - const void *b) -{ - const CoglAtlasRepositionData *ta = a; - const CoglAtlasRepositionData *tb = b; - unsigned int a_size, b_size; - - a_size = ta->old_position.width * ta->old_position.height; - b_size = tb->old_position.width * tb->old_position.height; - - return a_size < b_size ? 1 : a_size > b_size ? -1 : 0; -} - -static void -_cogl_atlas_notify_pre_reorganize (CoglAtlas *atlas) -{ - g_hook_list_invoke (&atlas->pre_reorganize_callbacks, FALSE); -} - -static void -_cogl_atlas_notify_post_reorganize (CoglAtlas *atlas) -{ - g_hook_list_invoke (&atlas->post_reorganize_callbacks, FALSE); -} - -gboolean -_cogl_atlas_reserve_space (CoglAtlas *atlas, - unsigned int width, - unsigned int height, - void *user_data) -{ - CoglAtlasGetRectanglesData data; - CoglRectangleMap *new_map; - CoglTexture *new_tex; - unsigned int map_width = 0, map_height = 0; - gboolean ret; - CoglRectangleMapEntry new_position; - - /* Check if we can fit the rectangle into the existing map */ - if (atlas->map && - _cogl_rectangle_map_add (atlas->map, width, height, - user_data, - &new_position)) - { - COGL_NOTE (ATLAS, "%p: Atlas is %ix%i, has %i textures and is %i%% waste", - atlas, - _cogl_rectangle_map_get_width (atlas->map), - _cogl_rectangle_map_get_height (atlas->map), - _cogl_rectangle_map_get_n_rectangles (atlas->map), - /* waste as a percentage */ - _cogl_rectangle_map_get_remaining_space (atlas->map) * - 100 / (_cogl_rectangle_map_get_width (atlas->map) * - _cogl_rectangle_map_get_height (atlas->map))); - - atlas->update_position_cb (user_data, - atlas->texture, - &new_position); - - return TRUE; - } - - /* If we make it here then we need to reorganize the atlas. First - we'll notify any users of the atlas that this is going to happen - so that for example in CoglAtlasTexture it can notify that the - storage has changed and cause a flush */ - _cogl_atlas_notify_pre_reorganize (atlas); - - /* Get an array of all the textures currently in the atlas. */ - data.n_textures = 0; - if (atlas->map == NULL) - data.textures = g_malloc (sizeof (CoglAtlasRepositionData)); - else - { - unsigned int n_rectangles = - _cogl_rectangle_map_get_n_rectangles (atlas->map); - data.textures = g_malloc (sizeof (CoglAtlasRepositionData) * - (n_rectangles + 1)); - _cogl_rectangle_map_foreach (atlas->map, - _cogl_atlas_get_rectangles_cb, - &data); - } - - /* Add the new rectangle as a dummy texture so that it can be - positioned with the rest */ - data.textures[data.n_textures].old_position.x = 0; - data.textures[data.n_textures].old_position.y = 0; - data.textures[data.n_textures].old_position.width = width; - data.textures[data.n_textures].old_position.height = height; - data.textures[data.n_textures++].user_data = user_data; - - /* The atlasing algorithm works a lot better if the rectangles are - added in decreasing order of size so we'll first sort the - array */ - qsort (data.textures, data.n_textures, - sizeof (CoglAtlasRepositionData), - _cogl_atlas_compare_size_cb); - - /* Try to create a new atlas that can contain all of the textures */ - if (atlas->map) - { - map_width = _cogl_rectangle_map_get_width (atlas->map); - map_height = _cogl_rectangle_map_get_height (atlas->map); - - /* If there is enough space in for the new rectangle in the - existing atlas with at least 6% waste we'll start with the - same size, otherwise we'll immediately double it */ - if ((map_width * map_height - - _cogl_rectangle_map_get_remaining_space (atlas->map) + - width * height) * 53 / 50 > - map_width * map_height) - _cogl_atlas_get_next_size (&map_width, &map_height); - } - else - _cogl_atlas_get_initial_size (atlas->texture_format, - &map_width, &map_height); - - new_map = _cogl_atlas_create_map (atlas->texture_format, - map_width, map_height, - data.n_textures, data.textures); - - /* If we can't create a map with the texture then give up */ - if (new_map == NULL) - { - COGL_NOTE (ATLAS, "%p: Could not fit texture in the atlas", atlas); - ret = FALSE; - } - /* We need to migrate the existing textures into a new texture */ - else if ((new_tex = _cogl_atlas_create_texture - (atlas, - _cogl_rectangle_map_get_width (new_map), - _cogl_rectangle_map_get_height (new_map))) == NULL) - { - COGL_NOTE (ATLAS, "%p: Could not create a CoglTexture2D", atlas); - _cogl_rectangle_map_free (new_map); - ret = FALSE; - } - else - { - int waste; - - COGL_NOTE (ATLAS, - "%p: Atlas %s with size %ix%i", - atlas, - atlas->map == NULL || - _cogl_rectangle_map_get_width (atlas->map) != - _cogl_rectangle_map_get_width (new_map) || - _cogl_rectangle_map_get_height (atlas->map) != - _cogl_rectangle_map_get_height (new_map) ? - "resized" : "reorganized", - _cogl_rectangle_map_get_width (new_map), - _cogl_rectangle_map_get_height (new_map)); - - if (atlas->map) - { - /* Move all the textures to the right position in the new - texture. This will also update the texture's rectangle */ - _cogl_atlas_migrate (atlas, - data.n_textures, - data.textures, - atlas->texture, - new_tex, - user_data); - _cogl_rectangle_map_free (atlas->map); - g_object_unref (atlas->texture); - } - else - /* We know there's only one texture so we can just directly - update the rectangle from its new position */ - atlas->update_position_cb (data.textures[0].user_data, - new_tex, - &data.textures[0].new_position); - - atlas->map = new_map; - atlas->texture = new_tex; - - waste = (_cogl_rectangle_map_get_remaining_space (atlas->map) * - 100 / (_cogl_rectangle_map_get_width (atlas->map) * - _cogl_rectangle_map_get_height (atlas->map))); - - COGL_NOTE (ATLAS, "%p: Atlas is %ix%i, has %i textures and is %i%% waste", - atlas, - _cogl_rectangle_map_get_width (atlas->map), - _cogl_rectangle_map_get_height (atlas->map), - _cogl_rectangle_map_get_n_rectangles (atlas->map), - waste); - - ret = TRUE; - } - - g_free (data.textures); - - _cogl_atlas_notify_post_reorganize (atlas); - - return ret; -} - -void -_cogl_atlas_remove (CoglAtlas *atlas, - const CoglRectangleMapEntry *rectangle) -{ - _cogl_rectangle_map_remove (atlas->map, rectangle); - - COGL_NOTE (ATLAS, "%p: Removed rectangle sized %ix%i", - atlas, - rectangle->width, - rectangle->height); - COGL_NOTE (ATLAS, "%p: Atlas is %ix%i, has %i textures and is %i%% waste", - atlas, - _cogl_rectangle_map_get_width (atlas->map), - _cogl_rectangle_map_get_height (atlas->map), - _cogl_rectangle_map_get_n_rectangles (atlas->map), - _cogl_rectangle_map_get_remaining_space (atlas->map) * - 100 / (_cogl_rectangle_map_get_width (atlas->map) * - _cogl_rectangle_map_get_height (atlas->map))); -}; - -static CoglTexture * -create_migration_texture (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format) -{ - CoglTexture *tex; - GError *skip_error = NULL; - - /* First try creating a fast-path non-sliced texture */ - tex = cogl_texture_2d_new_with_size (ctx, width, height); - - _cogl_texture_set_internal_format (tex, internal_format); - - /* TODO: instead of allocating storage here it would be better - * if we had some api that let us just check that the size is - * supported by the hardware so storage could be allocated - * lazily when uploading data. */ - if (!cogl_texture_allocate (tex, &skip_error)) - { - g_error_free (skip_error); - g_object_unref (tex); - tex = NULL; - } - - if (!tex) - { - tex = cogl_texture_2d_sliced_new_with_size (ctx, - width, - height, - COGL_TEXTURE_MAX_WASTE); - - _cogl_texture_set_internal_format (tex, - internal_format); - } - - return tex; -} - -CoglTexture * -_cogl_atlas_copy_rectangle (CoglAtlas *atlas, - int x, - int y, - int width, - int height, - CoglPixelFormat internal_format) -{ - CoglTexture *tex; - CoglBlitData blit_data; - GError *ignore_error = NULL; - - _COGL_GET_CONTEXT (ctx, NULL); - - /* Create a new texture at the right size */ - tex = create_migration_texture (ctx, width, height, internal_format); - if (!cogl_texture_allocate (tex, &ignore_error)) - { - g_error_free (ignore_error); - g_object_unref (tex); - return NULL; - } - - /* Blit the data out of the atlas to the new texture. If FBOs - aren't available this will end up having to copy the entire - atlas texture */ - _cogl_blit_begin (&blit_data, tex, atlas->texture); - _cogl_blit (&blit_data, - x, y, - 0, 0, - width, height); - _cogl_blit_end (&blit_data); - - return tex; -} - -void -_cogl_atlas_add_reorganize_callback (CoglAtlas *atlas, - GHookFunc pre_callback, - GHookFunc post_callback, - void *user_data) -{ - if (pre_callback) - { - GHook *hook = g_hook_alloc (&atlas->post_reorganize_callbacks); - hook->func = pre_callback; - hook->data = user_data; - g_hook_prepend (&atlas->pre_reorganize_callbacks, hook); - } - if (post_callback) - { - GHook *hook = g_hook_alloc (&atlas->pre_reorganize_callbacks); - hook->func = post_callback; - hook->data = user_data; - g_hook_prepend (&atlas->post_reorganize_callbacks, hook); - } -} - -void -_cogl_atlas_remove_reorganize_callback (CoglAtlas *atlas, - GHookFunc pre_callback, - GHookFunc post_callback, - void *user_data) -{ - if (pre_callback) - { - GHook *hook = g_hook_find_func_data (&atlas->pre_reorganize_callbacks, - FALSE, - pre_callback, - user_data); - if (hook) - g_hook_destroy_link (&atlas->pre_reorganize_callbacks, hook); - } - if (post_callback) - { - GHook *hook = g_hook_find_func_data (&atlas->post_reorganize_callbacks, - FALSE, - post_callback, - user_data); - if (hook) - g_hook_destroy_link (&atlas->post_reorganize_callbacks, hook); - } -} diff --git a/mutter/cogl/cogl/cogl-atlas.h b/mutter/cogl/cogl/cogl-atlas.h deleted file mode 100644 index ac5c8df..0000000 --- a/mutter/cogl/cogl/cogl-atlas.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#include "cogl/cogl-rectangle-map.h" -#include "cogl/cogl-texture.h" - -typedef void -(* CoglAtlasUpdatePositionCallback) (void *user_data, - CoglTexture *new_texture, - const CoglRectangleMapEntry *rect); - -typedef enum -{ - COGL_ATLAS_CLEAR_TEXTURE = (1 << 0), - COGL_ATLAS_DISABLE_MIGRATION = (1 << 1) -} CoglAtlasFlags; - -typedef struct _CoglAtlas CoglAtlas; - -#define COGL_TYPE_ATLAS (cogl_atlas_get_type ()) - -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglAtlas, - cogl_atlas, - COGL, - ATLAS, - GObject) - -struct _CoglAtlas -{ - GObject parent_instance; - - CoglRectangleMap *map; - - CoglTexture *texture; - CoglPixelFormat texture_format; - CoglAtlasFlags flags; - - CoglAtlasUpdatePositionCallback update_position_cb; - - GHookList pre_reorganize_callbacks; - GHookList post_reorganize_callbacks; -}; - -COGL_EXPORT CoglAtlas * -_cogl_atlas_new (CoglPixelFormat texture_format, - CoglAtlasFlags flags, - CoglAtlasUpdatePositionCallback update_position_cb); - -COGL_EXPORT gboolean -_cogl_atlas_reserve_space (CoglAtlas *atlas, - unsigned int width, - unsigned int height, - void *user_data); - -void -_cogl_atlas_remove (CoglAtlas *atlas, - const CoglRectangleMapEntry *rectangle); - -CoglTexture * -_cogl_atlas_copy_rectangle (CoglAtlas *atlas, - int x, - int y, - int width, - int height, - CoglPixelFormat format); - -COGL_EXPORT void -_cogl_atlas_add_reorganize_callback (CoglAtlas *atlas, - GHookFunc pre_callback, - GHookFunc post_callback, - void *user_data); - -void -_cogl_atlas_remove_reorganize_callback (CoglAtlas *atlas, - GHookFunc pre_callback, - GHookFunc post_callback, - void *user_data); diff --git a/mutter/cogl/cogl/cogl-attribute-buffer-private.h b/mutter/cogl/cogl/cogl-attribute-buffer-private.h deleted file mode 100644 index bd17a28..0000000 --- a/mutter/cogl/cogl/cogl-attribute-buffer-private.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-buffer-private.h" - -struct _CoglAttributeBuffer -{ - CoglBuffer parent_instance; -}; - -struct _CoglAttributeBufferClass -{ - CoglBufferClass parent_class; -}; diff --git a/mutter/cogl/cogl/cogl-attribute-buffer.c b/mutter/cogl/cogl/cogl-attribute-buffer.c deleted file mode 100644 index ee89e50..0000000 --- a/mutter/cogl/cogl/cogl-attribute-buffer.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-attribute-buffer.h" -#include "cogl/cogl-attribute-buffer-private.h" -#include "cogl/cogl-context-private.h" - -G_DEFINE_FINAL_TYPE (CoglAttributeBuffer, cogl_attribute_buffer, COGL_TYPE_BUFFER) - -static void -cogl_attribute_buffer_class_init (CoglAttributeBufferClass *klass) -{ -} - -static void -cogl_attribute_buffer_init (CoglAttributeBuffer *buffer) -{ -} - -CoglAttributeBuffer * -cogl_attribute_buffer_new_with_size (CoglContext *context, - size_t bytes) -{ - CoglAttributeBuffer *buffer; - - buffer = g_object_new (COGL_TYPE_ATTRIBUTE_BUFFER, - "context", context, - "size", (uint64_t) bytes, - "default-target", COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER, - "update-hint", COGL_BUFFER_UPDATE_HINT_STATIC, - NULL); - - return buffer; -} - -CoglAttributeBuffer * -cogl_attribute_buffer_new (CoglContext *context, - size_t bytes, - const void *data) -{ - CoglAttributeBuffer *buffer; - - buffer = cogl_attribute_buffer_new_with_size (context, bytes); - - /* Note: to keep the common cases simple this API doesn't throw - * GErrors, so developers can assume this function never returns - * NULL and we will simply abort on error. - * - * Developers wanting to catch errors can use - * cogl_attribute_buffer_new_with_size() and catch errors when later - * calling cogl_buffer_set_data() or cogl_buffer_map(). - */ - - /* XXX: NB: for Cogl 2.0 we don't allow NULL data here but we can't - * break the api for 1.x and so we keep the check for now. */ - if (data) - _cogl_buffer_set_data (COGL_BUFFER (buffer), - 0, - data, - bytes, - NULL); - - return buffer; -} diff --git a/mutter/cogl/cogl/cogl-attribute-buffer.h b/mutter/cogl/cogl/cogl-attribute-buffer.h deleted file mode 100644 index 59876a1..0000000 --- a/mutter/cogl/cogl/cogl-attribute-buffer.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -/* We forward declare the CoglAttributeBuffer type here to avoid some circular - * dependency issues with the following headers. - */ -typedef struct _CoglAttributeBuffer CoglAttributeBuffer; - -#include "cogl/cogl-context.h" - -#include - -G_BEGIN_DECLS - -/** - * CoglAttributeBuffer: - * - * Functions for creating and manipulating attribute buffers - */ -#define COGL_TYPE_ATTRIBUTE_BUFFER (cogl_attribute_buffer_get_type ()) -#define COGL_ATTRIBUTE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_ATTRIBUTE_BUFFER, CoglAttributeBuffer)) -#define COGL_ATTRIBUTE_BUFFER_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_ATTRIBUTE_BUFFER, CoglAttributeBuffer const)) -#define COGL_ATTRIBUTE_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_TYPE_ATTRIBUTE_BUFFER, CoglAttributeBufferClass)) -#define COGL_IS_ATTRIBUTE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_TYPE_ATTRIBUTE_BUFFER)) -#define COGL_IS_ATTRIBUTE_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_TYPE_ATTRIBUTE_BUFFER)) -#define COGL_ATTRIBUTE_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COGL_TYPE_ATTRIBUTE_BUFFER, CoglAttributeBufferClass)) - -typedef struct _CoglAttributeBufferClass CoglAttributeBufferClass; -typedef struct _CoglAttributeBuffer CoglAttributeBuffer; - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (CoglAttributeBuffer, g_object_unref) - -COGL_EXPORT -GType cogl_attribute_buffer_get_type (void) G_GNUC_CONST; - -/** - * cogl_attribute_buffer_new_with_size: - * @context: A #CoglContext - * @bytes: The number of bytes to allocate for vertex attribute data. - * - * Describes a new #CoglAttributeBuffer of @size bytes to contain - * arrays of vertex attribute data. Afterwards data can be set using - * cogl_buffer_set_data() or by mapping it into the application's - * address space using cogl_buffer_map(). - * - * The underlying storage of this buffer isn't allocated by this - * function so that you have an opportunity to use the - * cogl_buffer_set_update_hint() - * functions which may influence how the storage is allocated. The - * storage will be allocated once you upload data to the buffer. - * - * Note: You can assume this function always succeeds and won't return - * %NULL - * - * Return value: (transfer full): A newly allocated #CoglAttributeBuffer. Never %NULL. - */ -COGL_EXPORT CoglAttributeBuffer * -cogl_attribute_buffer_new_with_size (CoglContext *context, - size_t bytes); - -/** - * cogl_attribute_buffer_new: - * @context: A #CoglContext - * @bytes: The number of bytes to allocate for vertex attribute data. - * @data: (array length=bytes) (element-type guint8): An optional - * pointer to vertex data to upload immediately. - * - * Describes a new #CoglAttributeBuffer of @size bytes to contain - * arrays of vertex attribute data and also uploads @size bytes read - * from @data to the new buffer. - * - * You should never pass a %NULL data pointer. - * - * This function does not report out-of-memory errors back to - * the caller by returning %NULL and so you can assume this function - * always succeeds. - * - * In the unlikely case that there is an out of memory problem - * then Cogl will abort the application with a message. If your - * application needs to gracefully handle out-of-memory errors then - * you can use cogl_attribute_buffer_new_with_size() and then - * explicitly catch errors with cogl_buffer_set_data() or - * cogl_buffer_map(). - * - * Return value: (transfer full): A newly allocated #CoglAttributeBuffer (never %NULL) - */ -COGL_EXPORT CoglAttributeBuffer * -cogl_attribute_buffer_new (CoglContext *context, - size_t bytes, - const void *data); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-attribute-private.h b/mutter/cogl/cogl/cogl-attribute-private.h deleted file mode 100644 index ffb0596..0000000 --- a/mutter/cogl/cogl/cogl-attribute-private.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-attribute.h" -#include "cogl/cogl-framebuffer.h" -#include "cogl/cogl-pipeline-private.h" - -typedef enum -{ - COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY, - COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY, - COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY, - COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY, - COGL_ATTRIBUTE_NAME_ID_POINT_SIZE_ARRAY, - COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY -} CoglAttributeNameID; - -typedef struct _CoglAttributeNameState -{ - const char *name; - CoglAttributeNameID name_id; - int name_index; - gboolean normalized_default; - int layer_number; -} CoglAttributeNameState; - -struct _CoglAttribute -{ - GObject parent_instance; - - const CoglAttributeNameState *name_state; - gboolean normalized; - - gboolean is_buffered; - - union { - struct { - CoglAttributeBuffer *attribute_buffer; - size_t stride; - size_t offset; - int n_components; - CoglAttributeType type; - } buffered; - struct { - CoglContext *context; - CoglBoxedValue boxed; - } constant; - } d; - - int immutable_ref; -}; - -typedef enum -{ - COGL_DRAW_SKIP_JOURNAL_FLUSH = 1 << 0, - COGL_DRAW_SKIP_PIPELINE_VALIDATION = 1 << 1, - COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH = 1 << 2, - /* By default the vertex attribute drawing code will assume that if - there is a color attribute array enabled then we can't determine - if the colors will be opaque so we need to enabling - blending. However when drawing from the journal we know what the - contents of the color array is so we can override this by passing - this flag. */ - COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE = 1 << 3, - /* This forcibly disables the debug option to divert all drawing to - * wireframes */ - COGL_DRAW_SKIP_DEBUG_WIREFRAME = 1 << 4 -} CoglDrawFlags; - -/* During CoglContext initialization we register the "cogl_color_in" - * attribute name so it gets a global name_index of 0. We need to know - * the name_index for "cogl_color_in" in - * _cogl_pipeline_flush_gl_state() */ -#define COGL_ATTRIBUTE_COLOR_NAME_INDEX 0 - -CoglAttributeNameState * -_cogl_attribute_register_attribute_name (CoglContext *context, - const char *name); - -CoglAttribute * -_cogl_attribute_immutable_ref (CoglAttribute *attribute); - -void -_cogl_attribute_immutable_unref (CoglAttribute *attribute); - -typedef struct -{ - int unit; - CoglPipelineFlushOptions options; - uint32_t fallback_layers; -} CoglFlushLayerState; - -void -_cogl_flush_attributes_state (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglDrawFlags flags, - CoglAttribute **attributes, - int n_attributes); - -int -_cogl_attribute_get_n_components (CoglAttribute *attribute); diff --git a/mutter/cogl/cogl/cogl-attribute.c b/mutter/cogl/cogl/cogl-attribute.c deleted file mode 100644 index b86d2b8..0000000 --- a/mutter/cogl/cogl/cogl-attribute.c +++ /dev/null @@ -1,655 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-util.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-journal-private.h" -#include "cogl/cogl-attribute.h" -#include "cogl/cogl-attribute-private.h" -#include "cogl/cogl-pipeline.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-indices-private.h" -#include "cogl/cogl-private.h" - -#include -#include -#include - -G_DEFINE_TYPE (CoglAttribute, cogl_attribute, G_TYPE_OBJECT); - -static void -cogl_attribute_dispose (GObject *object) -{ - CoglAttribute *attribute = COGL_ATTRIBUTE (object); - - if (attribute->is_buffered) - g_object_unref (attribute->d.buffered.attribute_buffer); - else - _cogl_boxed_value_destroy (&attribute->d.constant.boxed); - - - G_OBJECT_CLASS (cogl_attribute_parent_class)->dispose (object); -} - -static void -cogl_attribute_init (CoglAttribute *attribute) -{ -} - -static void -cogl_attribute_class_init (CoglAttributeClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = cogl_attribute_dispose; -} - -static gboolean -validate_cogl_attribute_name (const char *name, - const char **real_attribute_name, - CoglAttributeNameID *name_id, - gboolean *normalized, - int *layer_number) -{ - name = name + 5; /* skip "cogl_" */ - - *normalized = FALSE; - *layer_number = 0; - - if (strcmp (name, "position_in") == 0) - *name_id = COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY; - else if (strcmp (name, "color_in") == 0) - { - *name_id = COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY; - *normalized = TRUE; - } - else if (strcmp (name, "tex_coord_in") == 0) - { - *real_attribute_name = "cogl_tex_coord0_in"; - *name_id = COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY; - } - else if (strncmp (name, "tex_coord", strlen ("tex_coord")) == 0) - { - char *endptr; - *layer_number = strtoul (name + 9, &endptr, 10); - if (strcmp (endptr, "_in") != 0) - { - g_warning ("Texture coordinate attributes should either be named " - "\"cogl_tex_coord_in\" or named with a texture unit index " - "like \"cogl_tex_coord2_in\"\n"); - return FALSE; - } - *name_id = COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY; - } - else if (strcmp (name, "normal_in") == 0) - { - *name_id = COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY; - *normalized = TRUE; - } - else if (strcmp (name, "point_size_in") == 0) - *name_id = COGL_ATTRIBUTE_NAME_ID_POINT_SIZE_ARRAY; - else - { - g_warning ("Unknown cogl_* attribute name cogl_%s\n", name); - return FALSE; - } - - return TRUE; -} - -CoglAttributeNameState * -_cogl_attribute_register_attribute_name (CoglContext *context, - const char *name) -{ - CoglAttributeNameState *name_state = g_new (CoglAttributeNameState, 1); - int name_index = context->n_attribute_names++; - char *name_copy = g_strdup (name); - - name_state->name = NULL; - name_state->name_index = name_index; - if (strncmp (name, "cogl_", 5) == 0) - { - if (!validate_cogl_attribute_name (name, - &name_state->name, - &name_state->name_id, - &name_state->normalized_default, - &name_state->layer_number)) - goto error; - } - else - { - name_state->name_id = COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY; - name_state->normalized_default = FALSE; - name_state->layer_number = 0; - } - - if (name_state->name == NULL) - name_state->name = name_copy; - - g_hash_table_insert (context->attribute_name_states_hash, - name_copy, name_state); - - if (G_UNLIKELY (context->attribute_name_index_map == NULL)) - context->attribute_name_index_map = - g_array_new (FALSE, FALSE, sizeof (void *)); - - g_array_set_size (context->attribute_name_index_map, name_index + 1); - - g_array_index (context->attribute_name_index_map, - CoglAttributeNameState *, name_index) = name_state; - - return name_state; - -error: - g_free (name_state); - return NULL; -} - -static gboolean -validate_n_components (const CoglAttributeNameState *name_state, - int n_components) -{ - switch (name_state->name_id) - { - case COGL_ATTRIBUTE_NAME_ID_POINT_SIZE_ARRAY: - if (G_UNLIKELY (n_components != 1)) - { - g_critical ("The point size attribute can only have one " - "component"); - return FALSE; - } - break; - case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY: - case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY: - case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY: - case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY: - case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY: - return TRUE; - } - - return TRUE; -} - -CoglAttribute * -cogl_attribute_new (CoglAttributeBuffer *attribute_buffer, - const char *name, - size_t stride, - size_t offset, - int n_components, - CoglAttributeType type) -{ - CoglAttribute *attribute = g_object_new (COGL_TYPE_ATTRIBUTE, NULL); - CoglBuffer *buffer = COGL_BUFFER (attribute_buffer); - CoglContext *ctx = buffer->context; - - attribute->is_buffered = TRUE; - - attribute->name_state = - g_hash_table_lookup (ctx->attribute_name_states_hash, name); - if (!attribute->name_state) - { - CoglAttributeNameState *name_state = - _cogl_attribute_register_attribute_name (ctx, name); - if (!name_state) - goto error; - attribute->name_state = name_state; - } - - attribute->d.buffered.attribute_buffer = g_object_ref (attribute_buffer); - attribute->d.buffered.stride = stride; - attribute->d.buffered.offset = offset; - attribute->d.buffered.n_components = n_components; - attribute->d.buffered.type = type; - - attribute->immutable_ref = 0; - - if (attribute->name_state->name_id != COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY) - { - if (!validate_n_components (attribute->name_state, n_components)) - return NULL; - attribute->normalized = - attribute->name_state->normalized_default; - } - else - attribute->normalized = FALSE; - - return attribute; - -error: - g_object_unref (attribute); - return NULL; -} - -static CoglAttribute * -_cogl_attribute_new_const (CoglContext *context, - const char *name, - int n_components, - int n_columns, - gboolean transpose, - const float *value) -{ - CoglAttribute *attribute = g_object_new (COGL_TYPE_ATTRIBUTE, NULL); - - attribute->name_state = - g_hash_table_lookup (context->attribute_name_states_hash, name); - if (!attribute->name_state) - { - CoglAttributeNameState *name_state = - _cogl_attribute_register_attribute_name (context, name); - if (!name_state) - goto error; - attribute->name_state = name_state; - } - - if (!validate_n_components (attribute->name_state, n_components)) - goto error; - - attribute->is_buffered = FALSE; - attribute->normalized = FALSE; - - attribute->d.constant.context = g_object_ref (context); - - attribute->d.constant.boxed.v.array = NULL; - - if (n_columns == 1) - { - _cogl_boxed_value_set_float (&attribute->d.constant.boxed, - n_components, - 1, - value); - } - else - { - /* FIXME: Up until GL[ES] 3 only square matrices were supported - * and we don't currently expose non-square matrices in Cogl. - */ - g_return_val_if_fail (n_columns == n_components, NULL); - _cogl_boxed_value_set_matrix (&attribute->d.constant.boxed, - n_columns, - 1, - transpose, - value); - } - - return attribute; - -error: - g_object_unref (attribute); - return NULL; -} - -CoglAttribute * -cogl_attribute_new_const_1f (CoglContext *context, - const char *name, - float value) -{ - return _cogl_attribute_new_const (context, - name, - 1, /* n_components */ - 1, /* 1 column vector */ - FALSE, /* no transpose */ - &value); -} - -CoglAttribute * -cogl_attribute_new_const_2fv (CoglContext *context, - const char *name, - const float *value) -{ - return _cogl_attribute_new_const (context, - name, - 2, /* n_components */ - 1, /* 1 column vector */ - FALSE, /* no transpose */ - value); -} - -CoglAttribute * -cogl_attribute_new_const_3fv (CoglContext *context, - const char *name, - const float *value) -{ - return _cogl_attribute_new_const (context, - name, - 3, /* n_components */ - 1, /* 1 column vector */ - FALSE, /* no transpose */ - value); -} - -CoglAttribute * -cogl_attribute_new_const_4fv (CoglContext *context, - const char *name, - const float *value) -{ - return _cogl_attribute_new_const (context, - name, - 4, /* n_components */ - 1, /* 1 column vector */ - FALSE, /* no transpose */ - value); -} - -CoglAttribute * -cogl_attribute_new_const_2f (CoglContext *context, - const char *name, - float component0, - float component1) -{ - float vec2[2] = { component0, component1 }; - return _cogl_attribute_new_const (context, - name, - 2, /* n_components */ - 1, /* 1 column vector */ - FALSE, /* no transpose */ - vec2); -} - -CoglAttribute * -cogl_attribute_new_const_3f (CoglContext *context, - const char *name, - float component0, - float component1, - float component2) -{ - float vec3[3] = { component0, component1, component2 }; - return _cogl_attribute_new_const (context, - name, - 3, /* n_components */ - 1, /* 1 column vector */ - FALSE, /* no transpose */ - vec3); -} - -CoglAttribute * -cogl_attribute_new_const_4f (CoglContext *context, - const char *name, - float component0, - float component1, - float component2, - float component3) -{ - float vec4[4] = { component0, component1, component2, component3 }; - return _cogl_attribute_new_const (context, - name, - 4, /* n_components */ - 1, /* 1 column vector */ - FALSE, /* no transpose */ - vec4); -} - -CoglAttribute * -cogl_attribute_new_const_2x2fv (CoglContext *context, - const char *name, - const float *matrix2x2, - gboolean transpose) -{ - return _cogl_attribute_new_const (context, - name, - 2, /* n_components */ - 2, /* 2 column vector */ - FALSE, /* no transpose */ - matrix2x2); -} - -CoglAttribute * -cogl_attribute_new_const_3x3fv (CoglContext *context, - const char *name, - const float *matrix3x3, - gboolean transpose) -{ - return _cogl_attribute_new_const (context, - name, - 3, /* n_components */ - 3, /* 3 column vector */ - FALSE, /* no transpose */ - matrix3x3); -} - -CoglAttribute * -cogl_attribute_new_const_4x4fv (CoglContext *context, - const char *name, - const float *matrix4x4, - gboolean transpose) -{ - return _cogl_attribute_new_const (context, - name, - 4, /* n_components */ - 4, /* 4 column vector */ - FALSE, /* no transpose */ - matrix4x4); -} - -gboolean -cogl_attribute_get_normalized (CoglAttribute *attribute) -{ - g_return_val_if_fail (COGL_IS_ATTRIBUTE (attribute), FALSE); - - return attribute->normalized; -} - -static void -warn_about_midscene_changes (void) -{ - static gboolean seen = FALSE; - if (!seen) - { - g_warning ("Mid-scene modification of attributes has " - "undefined results\n"); - seen = TRUE; - } -} - -void -cogl_attribute_set_normalized (CoglAttribute *attribute, - gboolean normalized) -{ - g_return_if_fail (COGL_IS_ATTRIBUTE (attribute)); - - if (G_UNLIKELY (attribute->immutable_ref)) - warn_about_midscene_changes (); - - attribute->normalized = normalized; -} - -CoglAttributeBuffer * -cogl_attribute_get_buffer (CoglAttribute *attribute) -{ - g_return_val_if_fail (COGL_IS_ATTRIBUTE (attribute), NULL); - g_return_val_if_fail (attribute->is_buffered, NULL); - - return attribute->d.buffered.attribute_buffer; -} - -void -cogl_attribute_set_buffer (CoglAttribute *attribute, - CoglAttributeBuffer *attribute_buffer) -{ - g_return_if_fail (COGL_IS_ATTRIBUTE (attribute)); - g_return_if_fail (attribute->is_buffered); - - if (G_UNLIKELY (attribute->immutable_ref)) - warn_about_midscene_changes (); - - g_object_ref (attribute_buffer); - - g_object_unref (attribute->d.buffered.attribute_buffer); - attribute->d.buffered.attribute_buffer = attribute_buffer; -} - -CoglAttribute * -_cogl_attribute_immutable_ref (CoglAttribute *attribute) -{ - CoglBuffer *buffer = COGL_BUFFER (attribute->d.buffered.attribute_buffer); - - g_return_val_if_fail (COGL_IS_ATTRIBUTE (attribute), NULL); - - attribute->immutable_ref++; - _cogl_buffer_immutable_ref (buffer); - return attribute; -} - -void -_cogl_attribute_immutable_unref (CoglAttribute *attribute) -{ - CoglBuffer *buffer = COGL_BUFFER (attribute->d.buffered.attribute_buffer); - - g_return_if_fail (COGL_IS_ATTRIBUTE (attribute)); - g_return_if_fail (attribute->immutable_ref > 0); - - attribute->immutable_ref--; - _cogl_buffer_immutable_unref (buffer); -} - -static gboolean -validate_layer_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - CoglTexture *texture = - cogl_pipeline_get_layer_texture (pipeline, layer_index); - CoglFlushLayerState *state = user_data; - gboolean status = TRUE; - - /* invalid textures will be handled correctly in - * _cogl_pipeline_flush_layers_gl_state */ - if (texture == NULL) - goto validated; - - _cogl_texture_flush_journal_rendering (texture); - - /* Give the texture a chance to know that we're rendering - non-quad shaped primitives. If the texture is in an atlas it - will be migrated */ - _cogl_texture_ensure_non_quad_rendering (texture); - - /* We need to ensure the mipmaps are ready before deciding - * anything else about the texture because the texture storate - * could completely change if it needs to be migrated out of the - * atlas and will affect how we validate the layer. - */ - _cogl_pipeline_pre_paint_for_layer (pipeline, layer_index); - - if (!_cogl_texture_can_hardware_repeat (texture)) - { - g_warning ("Disabling layer %d of the current source material, " - "because texturing with the vertex buffer API is not " - "currently supported using sliced textures, or textures " - "with waste\n", layer_index); - - /* XXX: maybe we can add a mechanism for users to forcibly use - * textures with waste where it would be their responsibility to use - * texture coords in the range [0,1] such that sampling outside isn't - * required. We can then use a texture matrix (or a modification of - * the users own matrix) to map 1 to the edge of the texture data. - * - * Potentially, given the same guarantee as above we could also - * support a single sliced layer too. We would have to redraw the - * vertices once for each layer, each time with a fiddled texture - * matrix. - */ - state->fallback_layers |= (1 << state->unit); - state->options.flags |= COGL_PIPELINE_FLUSH_FALLBACK_MASK; - } - -validated: - state->unit++; - return status; -} - -void -_cogl_flush_attributes_state (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglDrawFlags flags, - CoglAttribute **attributes, - int n_attributes) -{ - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglFlushLayerState layers_state; - CoglPipeline *copy = NULL; - - if (!(flags & COGL_DRAW_SKIP_JOURNAL_FLUSH)) - _cogl_framebuffer_flush_journal (framebuffer); - - layers_state.unit = 0; - layers_state.options.flags = 0; - layers_state.fallback_layers = 0; - - if (!(flags & COGL_DRAW_SKIP_PIPELINE_VALIDATION)) - cogl_pipeline_foreach_layer (pipeline, - validate_layer_cb, - &layers_state); - - /* NB: cogl_context_flush_framebuffer_state may disrupt various state (such - * as the pipeline state) when flushing the clip stack, so should - * always be done first when preparing to draw. We need to do this - * before setting up the array pointers because setting up the clip - * stack can cause some drawing which would change the array - * pointers. */ - if (!(flags & COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH)) - { - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_ALL); - } - - /* In cogl_read_pixels we have a fast-path when reading a single - * pixel and the scene is just comprised of simple rectangles still - * in the journal. For this optimization to work we need to track - * when the framebuffer really does get drawn to. */ - _cogl_framebuffer_mark_clear_clip_dirty (framebuffer); - - ctx->driver_vtable->flush_attributes_state (framebuffer, - pipeline, - &layers_state, - flags, - attributes, - n_attributes); - - if (copy) - g_object_unref (copy); -} - -int -_cogl_attribute_get_n_components (CoglAttribute *attribute) -{ - if (attribute->is_buffered) - return attribute->d.buffered.n_components; - else - return attribute->d.constant.boxed.size; -} diff --git a/mutter/cogl/cogl/cogl-attribute.h b/mutter/cogl/cogl/cogl-attribute.h deleted file mode 100644 index 7d3d2e9..0000000 --- a/mutter/cogl/cogl/cogl-attribute.h +++ /dev/null @@ -1,515 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -/* We forward declare the CoglAttribute type here to avoid some circular - * dependency issues with the following headers. - */ -typedef struct _CoglAttribute CoglAttribute; - -#include "cogl/cogl-attribute-buffer.h" -#include "cogl/cogl-indices.h" - -#include - -G_BEGIN_DECLS - -#define COGL_TYPE_ATTRIBUTE (cogl_attribute_get_type ()) - -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglAttribute, - cogl_attribute, - COGL, - ATTRIBUTE, - GObject) - -/** - * cogl_attribute_new: (constructor) - * @attribute_buffer: The #CoglAttributeBuffer containing the actual - * attribute data - * @name: The name of the attribute (used to reference it from GLSL) - * @stride: The number of bytes to jump to get to the next attribute - * value for the next vertex. (Usually - * `sizeof (MyVertex)`) - * @offset: The byte offset from the start of @attribute_buffer for - * the first attribute value. (Usually - * `offsetof (MyVertex, component0)` - * @components: The number of components (e.g. 4 for an rgba color or - * 3 for and (x,y,z) position) - * @type: FIXME - * - * Describes the layout for a list of vertex attribute values (For - * example, a list of texture coordinates or colors). - * - * The @name is used to access the attribute inside a GLSL vertex - * shader and there are some special names you should use if they are - * applicable: - * - * - "cogl_position_in" (used for vertex positions) - * - "cogl_color_in" (used for vertex colors) - * - "cogl_tex_coord0_in", "cogl_tex_coord1", ... - * (used for vertex texture coordinates) - * - "cogl_normal_in" (used for vertex normals) - * - "cogl_point_size_in" (used to set the size of points - * per-vertex. Note this can only be used if - * %COGL_FEATURE_ID_POINT_SIZE_ATTRIBUTE is advertised and - * cogl_pipeline_set_per_vertex_point_size() is called on the pipeline. - * - * The attribute values corresponding to different vertices can either - * be tightly packed or interleaved with other attribute values. For - * example it's common to define a structure for a single vertex like: - * ```c - * typedef struct - * { - * float x, y, z; /* position attribute */ - * float s, t; /* texture coordinate attribute */ - * } MyVertex; - * ``` - * - * And then create an array of vertex data something like: - * ```c - * MyVertex vertices[100] = { .... } - * ``` - * - * In this case, to describe either the position or texture coordinate - * attribute you have to move `sizeof (MyVertex)` bytes to - * move from one vertex to the next. This is called the attribute - * @stride. If you weren't interleving attributes and you instead had - * a packed array of float x, y pairs then the attribute stride would - * be `(2 * sizeof (float))`. So the @stride is the number of - * bytes to move to find the attribute value of the next vertex. - * - * Normally a list of attributes starts at the beginning of an array. - * So for the `MyVertex` example above the @offset is the - * offset inside the `MyVertex` structure to the first - * component of the attribute. For the texture coordinate attribute - * the offset would be `offsetof (MyVertex, s)` or instead of - * using the offsetof macro you could use `sizeof (float) * - * 3`. If you've divided your @array into blocks of non-interleved - * attributes then you will need to calculate the @offset as the number of - * bytes in blocks preceding the attribute you're describing. - * - * An attribute often has more than one component. For example a color - * is often comprised of 4 red, green, blue and alpha @components, and a - * position may be comprised of 2 x and y @components. You should aim - * to keep the number of components to a minimum as more components - * means more data needs to be mapped into the GPU which can be a - * bottleneck when dealing with a large number of vertices. - * - * Finally you need to specify the component data type. Here you - * should aim to use the smallest type that meets your precision - * requirements. Again the larger the type then more data needs to be - * mapped into the GPU which can be a bottleneck when dealing with - * a large number of vertices. - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * describing the layout for a list of attribute values - * stored in @array. - */ -/* XXX: look for a precedent to see if the stride/offset args should - * have a different order. */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new (CoglAttributeBuffer *attribute_buffer, - const char *name, - size_t stride, - size_t offset, - int components, - CoglAttributeType type); - -/** - * cogl_attribute_new_const_1f: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @value: The constant value for the attribute - * - * Creates a new, single component, attribute whose value remains - * constant across all the vertices of a primitive without needing to - * duplicate the value for each vertex. - * - * The constant @value is a single precision floating point scalar - * which should have a corresponding declaration in GLSL code like: - * - * [| - * attribute float name; - * |] - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant @value. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_1f (CoglContext *context, - const char *name, - float value); - -/** - * cogl_attribute_new_const_2f: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @component0: The first component of a 2 component vector - * @component1: The second component of a 2 component vector - * - * Creates a new, 2 component, attribute whose value remains - * constant across all the vertices of a primitive without needing to - * duplicate the value for each vertex. - * - * The constants (@component0, @component1) represent a 2 component - * float vector which should have a corresponding declaration in GLSL - * code like: - * - * [| - * attribute vec2 name; - * |] - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant vector. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_2f (CoglContext *context, - const char *name, - float component0, - float component1); - -/** - * cogl_attribute_new_const_3f: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @component0: The first component of a 3 component vector - * @component1: The second component of a 3 component vector - * @component2: The third component of a 3 component vector - * - * Creates a new, 3 component, attribute whose value remains - * constant across all the vertices of a primitive without needing to - * duplicate the value for each vertex. - * - * The constants (@component0, @component1, @component2) represent a 3 - * component float vector which should have a corresponding - * declaration in GLSL code like: - * - * [| - * attribute vec3 name; - * |] - * - * unless the built in name "cogl_normal_in" is being used where no - * explicit GLSL declaration need be made. - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant vector. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_3f (CoglContext *context, - const char *name, - float component0, - float component1, - float component2); - -/** - * cogl_attribute_new_const_4f: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @component0: The first component of a 4 component vector - * @component1: The second component of a 4 component vector - * @component2: The third component of a 4 component vector - * @component3: The fourth component of a 4 component vector - * - * Creates a new, 4 component, attribute whose value remains - * constant across all the vertices of a primitive without needing to - * duplicate the value for each vertex. - * - * The constants (@component0, @component1, @component2, @constant3) - * represent a 4 component float vector which should have a - * corresponding declaration in GLSL code like: - * - * [| - * attribute vec4 name; - * |] - * - * unless one of the built in names "cogl_color_in", - * "cogl_tex_coord0_in or "cogl_tex_coord1_in" etc is being used where - * no explicit GLSL declaration need be made. - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant vector. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_4f (CoglContext *context, - const char *name, - float component0, - float component1, - float component2, - float component3); - -/** - * cogl_attribute_new_const_2fv: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @value: A pointer to a 2 component float vector - * - * Creates a new, 2 component, attribute whose value remains - * constant across all the vertices of a primitive without needing to - * duplicate the value for each vertex. - * - * The constants (value[0], value[1]) represent a 2 component float - * vector which should have a corresponding declaration in GLSL code - * like: - * - * [| - * attribute vec2 name; - * |] - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant vector. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_2fv (CoglContext *context, - const char *name, - const float *value); - -/** - * cogl_attribute_new_const_3fv: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @value: A pointer to a 3 component float vector - * - * Creates a new, 3 component, attribute whose value remains - * constant across all the vertices of a primitive without needing to - * duplicate the value for each vertex. - * - * The constants (value[0], value[1], value[2]) represent a 3 - * component float vector which should have a corresponding - * declaration in GLSL code like: - * - * [| - * attribute vec3 name; - * |] - * - * unless the built in name "cogl_normal_in" is being used where no - * explicit GLSL declaration need be made. - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant vector. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_3fv (CoglContext *context, - const char *name, - const float *value); - -/** - * cogl_attribute_new_const_4fv: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @value: A pointer to a 4 component float vector - * - * Creates a new, 4 component, attribute whose value remains - * constant across all the vertices of a primitive without needing to - * duplicate the value for each vertex. - * - * The constants (value[0], value[1], value[2], value[3]) represent a - * 4 component float vector which should have a corresponding - * declaration in GLSL code like: - * - * [| - * attribute vec4 name; - * |] - * - * unless one of the built in names "cogl_color_in", - * "cogl_tex_coord0_in or "cogl_tex_coord1_in" etc is being used where - * no explicit GLSL declaration need be made. - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant vector. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_4fv (CoglContext *context, - const char *name, - const float *value); - -/** - * cogl_attribute_new_const_2x2fv: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @matrix2x2: A pointer to a 2 by 2 matrix - * @transpose: Whether the matrix should be transposed on upload or - * not - * - * Creates a new matrix attribute whose value remains constant - * across all the vertices of a primitive without needing to duplicate - * the value for each vertex. - * - * @matrix2x2 represent a square 2 by 2 matrix specified in - * column-major order (each pair of consecutive numbers represents a - * column) which should have a corresponding declaration in GLSL code - * like: - * - * [| - * attribute mat2 name; - * |] - * - * If @transpose is %TRUE then all matrix components are rotated - * around the diagonal of the matrix such that the first column - * becomes the first row and the second column becomes the second row. - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant matrix. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_2x2fv (CoglContext *context, - const char *name, - const float *matrix2x2, - gboolean transpose); - -/** - * cogl_attribute_new_const_3x3fv: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @matrix3x3: A pointer to a 3 by 3 matrix - * @transpose: Whether the matrix should be transposed on upload or - * not - * - * Creates a new matrix attribute whose value remains constant - * across all the vertices of a primitive without needing to duplicate - * the value for each vertex. - * - * @matrix3x3 represent a square 3 by 3 matrix specified in - * column-major order (each triple of consecutive numbers represents a - * column) which should have a corresponding declaration in GLSL code - * like: - * - * [| - * attribute mat3 name; - * |] - * - * If @transpose is %TRUE then all matrix components are rotated - * around the diagonal of the matrix such that the first column - * becomes the first row and the second column becomes the second row - * etc. - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant matrix. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_3x3fv (CoglContext *context, - const char *name, - const float *matrix3x3, - gboolean transpose); - -/** - * cogl_attribute_new_const_4x4fv: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @matrix4x4: A pointer to a 4 by 4 matrix - * @transpose: Whether the matrix should be transposed on upload or - * not - * - * Creates a new matrix attribute whose value remains constant - * across all the vertices of a primitive without needing to duplicate - * the value for each vertex. - * - * @matrix4x4 represent a square 4 by 4 matrix specified in - * column-major order (each 4-tuple of consecutive numbers represents a - * column) which should have a corresponding declaration in GLSL code - * like: - * - * [| - * attribute mat4 name; - * |] - * - * If @transpose is %TRUE then all matrix components are rotated - * around the diagonal of the matrix such that the first column - * becomes the first row and the second column becomes the second row - * etc. - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant matrix. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_4x4fv (CoglContext *context, - const char *name, - const float *matrix4x4, - gboolean transpose); - -/** - * cogl_attribute_set_normalized: - * @attribute: A #CoglAttribute - * @normalized: The new value for the normalized property. - * - * Sets whether fixed point attribute types are mapped to the range - * 0→1. For example when this property is TRUE and a - * %COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE type is used then the value 255 - * will be mapped to 1.0. - * - * The default value of this property depends on the name of the - * attribute. For the builtin properties cogl_color_in and - * cogl_normal_in it will default to TRUE and for all other names it - * will default to FALSE. - */ -COGL_EXPORT void -cogl_attribute_set_normalized (CoglAttribute *attribute, - gboolean normalized); - -/** - * cogl_attribute_get_normalized: - * @attribute: A #CoglAttribute - * - * Return value: the value of the normalized property set with - * cogl_attribute_set_normalized(). - */ -COGL_EXPORT gboolean -cogl_attribute_get_normalized (CoglAttribute *attribute); - -/** - * cogl_attribute_get_buffer: - * @attribute: A #CoglAttribute - * - * Return value: (transfer none): the #CoglAttributeBuffer that was - * set with cogl_attribute_set_buffer() or cogl_attribute_new(). - */ -COGL_EXPORT CoglAttributeBuffer * -cogl_attribute_get_buffer (CoglAttribute *attribute); - -/** - * cogl_attribute_set_buffer: - * @attribute: A #CoglAttribute - * @attribute_buffer: A #CoglAttributeBuffer - * - * Sets a new #CoglAttributeBuffer for the attribute. - */ -COGL_EXPORT void -cogl_attribute_set_buffer (CoglAttribute *attribute, - CoglAttributeBuffer *attribute_buffer); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-bitmap-conversion.c b/mutter/cogl/cogl/cogl-bitmap-conversion.c deleted file mode 100644 index 948e633..0000000 --- a/mutter/cogl/cogl/cogl-bitmap-conversion.c +++ /dev/null @@ -1,961 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include "cogl/cogl-private.h" -#include "cogl/cogl-bitmap-private.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-half-float.h" - -#include - -typedef enum -{ - MEDIUM_TYPE_8, - MEDIUM_TYPE_16, - MEDIUM_TYPE_FLOAT, -} MediumType; - -G_STATIC_ASSERT (sizeof (uint32_t) == sizeof (GLfloat)); - -inline static uint32_t -pack_flt (GLfloat b) -{ - uint32_t ret; - memcpy (&ret, &b, sizeof (uint32_t)); - return ret; -} - -inline static GLfloat -unpack_flt (uint32_t b) -{ - GLfloat ret; - memcpy (&ret, &b, sizeof (GLfloat)); - return ret; -} - -#define CLAMP_NORM(b) (MAX (MIN ((b), 1.0), 0.0)) - -#define UNPACK_1(b) ((b) * ((1 << (sizeof (component_type) * 8)) - 1)) -#define UNPACK_2(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \ - 1) / 3) -#define UNPACK_4(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \ - 7) / 0xf) -#define UNPACK_5(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \ - 0xf) / 0x1f) -#define UNPACK_6(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \ - 0x1f) / 0x3f) -#define UNPACK_10(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \ - 0x1ff) / 0x3ff) -#define UNPACK_16(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \ - 0x7fff) / 0xffff) -#define UNPACK_SHORT(b) (CLAMP_NORM (cogl_half_to_float (b)) * \ - ((1 << (sizeof (component_type) * 8)) - 1)) -#define UNPACK_FLOAT(b) (CLAMP_NORM (unpack_flt (b)) * \ - ((1 << (sizeof (component_type) * 8)) - 1)) - -/* Pack and round to nearest */ -#define PACK_SIZE(b, max) \ - (((b) * (max) + (1 << (sizeof (component_type) * 8 - 1)) - 1) / \ - ((1 << (sizeof (component_type) * 8)) - 1)) - -#define PACK_1(b) PACK_SIZE (b, 1) -#define PACK_2(b) PACK_SIZE (b, 3) -#define PACK_4(b) PACK_SIZE (b, 0xf) -#define PACK_5(b) PACK_SIZE (b, 0x1f) -#define PACK_6(b) PACK_SIZE (b, 0x3f) -#define PACK_10(b) PACK_SIZE (b, 0x3ff) -#define PACK_16(b) PACK_SIZE (b, 0xffff) -#define PACK_SHORT(b) cogl_float_to_half ( \ - (b) / ((1 << (sizeof (component_type) * 8)) - 1)) -#define PACK_FLOAT(b) pack_flt ((b) / ((1 << (sizeof (component_type) * 8)) - 1)) - -#define component_type uint8_t -#define component_size 8 -/* We want to specially optimise the packing when we are converting - to/from an 8-bit type so that it won't do anything. That way for - example if we are just doing a swizzle conversion then the inner - loop for the conversion will be really simple */ -#define UNPACK_BYTE(b) (b) -#define PACK_BYTE(b) (b) -#include "cogl/cogl-bitmap-packing.h" -#undef PACK_BYTE -#undef UNPACK_BYTE -#undef component_type -#undef component_size - -#define component_type uint16_t -#define component_size 16 -#define UNPACK_BYTE(b) (((b) * 65535 + 127) / 255) -#define PACK_BYTE(b) (((b) * 255 + 32767) / 65535) -#include "cogl/cogl-bitmap-packing.h" -#undef PACK_BYTE -#undef UNPACK_BYTE -#undef component_type -#undef component_size - -#undef CLAMP_NORM -#undef UNPACK_1 -#undef UNPACK_2 -#undef UNPACK_4 -#undef UNPACK_5 -#undef UNPACK_6 -#undef UNPACK_10 -#undef UNPACK_16 -#undef UNPACK_SHORT -#undef UNPACK_FLOAT -#undef PACK_SIZE -#undef PACK_1 -#undef PACK_2 -#undef PACK_4 -#undef PACK_5 -#undef PACK_6 -#undef PACK_10 -#undef PACK_16 -#undef PACK_SHORT -#undef PACK_FLOAT - -#define UNPACK_1(b) ((b) / 1.0f) -#define UNPACK_2(b) ((b) / 3.0f) -#define UNPACK_4(b) ((b) / 15.0f) -#define UNPACK_5(b) ((b) / 31.0f) -#define UNPACK_6(b) ((b) / 63.0f) -#define UNPACK_BYTE(b) ((b) / 255.0f) -#define UNPACK_10(b) ((b) / 1023.0f) -#define UNPACK_16(b) ((b) / 65535.0f) -#define UNPACK_SHORT(b) cogl_half_to_float (b) -#define UNPACK_FLOAT(b) unpack_flt (b) -#define PACK_1(b) ((uint32_t) (b)) -#define PACK_2(b) ((uint32_t) ((b) * 3.5f)) -#define PACK_4(b) ((uint32_t) ((b) * 15.5f)) -#define PACK_5(b) ((uint32_t) ((b) * 31.5f)) -#define PACK_6(b) ((uint32_t) ((b) * 63.5f)) -#define PACK_BYTE(b) ((uint32_t) ((b) * 255.5f)) -#define PACK_10(b) ((uint32_t) ((b) * 1023.5f)) -#define PACK_16(b) ((uint32_t) ((b) * 65535.0f)) -#define PACK_SHORT(b) cogl_float_to_half (b) -#define PACK_FLOAT(b) pack_flt((b) / 1.0) - -#define component_type float -#define component_size float -#include "cogl-bitmap-packing.h" -#undef PACK_BYTE -#undef UNPACK_BYTE -#undef component_type -#undef component_size - -#undef UNPACK_1 -#undef UNPACK_2 -#undef UNPACK_4 -#undef UNPACK_5 -#undef UNPACK_6 -#undef UNPACK_10 -#undef UNPACK_16 -#undef UNPACK_SHORT -#undef UNPACK_FLOAT -#undef PACK_1 -#undef PACK_2 -#undef PACK_4 -#undef PACK_5 -#undef PACK_6 -#undef PACK_10 -#undef PACK_16 -#undef PACK_SHORT -#undef PACK_FLOAT - -/* (Un)Premultiplication */ - -inline static void -_cogl_unpremult_alpha_0 (uint8_t *dst) -{ - dst[0] = 0; - dst[1] = 0; - dst[2] = 0; - dst[3] = 0; -} - -inline static void -_cogl_unpremult_alpha_last (uint8_t *dst) -{ - uint8_t alpha = dst[3]; - - dst[0] = (dst[0] * 255) / alpha; - dst[1] = (dst[1] * 255) / alpha; - dst[2] = (dst[2] * 255) / alpha; -} - -inline static void -_cogl_unpremult_alpha_first (uint8_t *dst) -{ - uint8_t alpha = dst[0]; - - dst[1] = (dst[1] * 255) / alpha; - dst[2] = (dst[2] * 255) / alpha; - dst[3] = (dst[3] * 255) / alpha; -} - -/* No division form of floor((c*a + 128)/255) (I first encountered - * this in the RENDER implementation in the X server.) Being exact - * is important for a == 255 - we want to get exactly c. - */ -#define MULT(d,a,t) \ - G_STMT_START { \ - t = d * a + 128; \ - d = ((t >> 8) + t) >> 8; \ - } G_STMT_END - -inline static void -_cogl_premult_alpha_last (uint8_t *dst) -{ - uint8_t alpha = dst[3]; - /* Using a separate temporary per component has given slightly better - * code generation with GCC in the past; it shouldn't do any worse in - * any case. - */ - unsigned int t1, t2, t3; - MULT(dst[0], alpha, t1); - MULT(dst[1], alpha, t2); - MULT(dst[2], alpha, t3); -} - -inline static void -_cogl_premult_alpha_first (uint8_t *dst) -{ - uint8_t alpha = dst[0]; - unsigned int t1, t2, t3; - - MULT(dst[1], alpha, t1); - MULT(dst[2], alpha, t2); - MULT(dst[3], alpha, t3); -} - -#undef MULT - -/* Use the SSE optimized version to premult four pixels at once when - it is available. The same assembler code works for x86 and x86-64 - because it doesn't refer to any non-SSE registers directly */ -#if defined(__SSE2__) && defined(__GNUC__) \ - && (defined(__x86_64) || defined(__i386)) -#define COGL_USE_PREMULT_SSE2 -#endif - -#ifdef COGL_USE_PREMULT_SSE2 - -inline static void -_cogl_premult_alpha_last_four_pixels_sse2 (uint8_t *p) -{ - /* 8 copies of 128 used below */ - static const int16_t eight_halves[8] __attribute__ ((aligned (16))) = - { 128, 128, 128, 128, 128, 128, 128, 128 }; - /* Mask of the rgb components of the four pixels */ - static const int8_t just_rgb[16] __attribute__ ((aligned (16))) = - { 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, - 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00 }; - /* Each SSE register only holds two pixels because we need to work - with 16-bit intermediate values. We still do four pixels by - interleaving two registers in the hope that it will pipeline - better */ - asm (/* Load eight_halves into xmm5 for later */ - "movdqa (%1), %%xmm5\n" - /* Clear xmm3 */ - "pxor %%xmm3, %%xmm3\n" - /* Load two pixels from p into the low half of xmm0 */ - "movlps (%0), %%xmm0\n" - /* Load the next set of two pixels from p into the low half of xmm1 */ - "movlps 8(%0), %%xmm1\n" - /* Unpack 8 bytes from the low quad-words in each register to 8 - 16-bit values */ - "punpcklbw %%xmm3, %%xmm0\n" - "punpcklbw %%xmm3, %%xmm1\n" - /* Copy alpha values of the first pixel in xmm0 to all - components of the first pixel in xmm2 */ - "pshuflw $255, %%xmm0, %%xmm2\n" - /* same for xmm1 and xmm3 */ - "pshuflw $255, %%xmm1, %%xmm3\n" - /* The above also copies the second pixel directly so we now - want to replace the RGB components with copies of the alpha - components */ - "pshufhw $255, %%xmm2, %%xmm2\n" - "pshufhw $255, %%xmm3, %%xmm3\n" - /* Multiply the rgb components by the alpha */ - "pmullw %%xmm2, %%xmm0\n" - "pmullw %%xmm3, %%xmm1\n" - /* Add 128 to each component */ - "paddw %%xmm5, %%xmm0\n" - "paddw %%xmm5, %%xmm1\n" - /* Copy the results to temporary registers xmm4 and xmm5 */ - "movdqa %%xmm0, %%xmm4\n" - "movdqa %%xmm1, %%xmm5\n" - /* Divide the results by 256 */ - "psrlw $8, %%xmm0\n" - "psrlw $8, %%xmm1\n" - /* Add the temporaries back in */ - "paddw %%xmm4, %%xmm0\n" - "paddw %%xmm5, %%xmm1\n" - /* Divide again */ - "psrlw $8, %%xmm0\n" - "psrlw $8, %%xmm1\n" - /* Pack the results back as bytes */ - "packuswb %%xmm1, %%xmm0\n" - /* Load just_rgb into xmm3 for later */ - "movdqa (%2), %%xmm3\n" - /* Reload all four pixels into xmm2 */ - "movups (%0), %%xmm2\n" - /* Mask out the alpha from the results */ - "andps %%xmm3, %%xmm0\n" - /* Mask out the RGB from the original four pixels */ - "andnps %%xmm2, %%xmm3\n" - /* Combine the two to get the right alpha values */ - "orps %%xmm3, %%xmm0\n" - /* Write to memory */ - "movdqu %%xmm0, (%0)\n" - : /* no outputs */ - : "r" (p), "r" (eight_halves), "r" (just_rgb) - : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} - -#endif /* COGL_USE_PREMULT_SSE2 */ - -static void -_cogl_bitmap_premult_unpacked_span_8 (uint8_t *data, - int width) -{ -#ifdef COGL_USE_PREMULT_SSE2 - - /* Process 4 pixels at a time */ - while (width >= 4) - { - _cogl_premult_alpha_last_four_pixels_sse2 (data); - data += 4 * 4; - width -= 4; - } - - /* If there are any pixels left we will fall through and - handle them below */ - -#endif /* COGL_USE_PREMULT_SSE2 */ - - while (width-- > 0) - { - _cogl_premult_alpha_last (data); - data += 4; - } -} - -static void -_cogl_bitmap_unpremult_unpacked_span_8 (uint8_t *data, - int width) -{ - int x; - - for (x = 0; x < width; x++) - { - if (data[3] == 0) - _cogl_unpremult_alpha_0 (data); - else - _cogl_unpremult_alpha_last (data); - data += 4; - } -} - -static void -_cogl_bitmap_unpremult_unpacked_span_16 (uint16_t *data, - int width) -{ - while (width-- > 0) - { - uint16_t alpha = data[3]; - - if (alpha == 0) - memset (data, 0, sizeof (uint16_t) * 3); - else - { - data[0] = (data[0] * 65535) / alpha; - data[1] = (data[1] * 65535) / alpha; - data[2] = (data[2] * 65535) / alpha; - } - } -} - -static void -_cogl_bitmap_premult_unpacked_span_16 (uint16_t *data, - int width) -{ - while (width-- > 0) - { - uint16_t alpha = data[3]; - - data[0] = (data[0] * alpha) / 65535; - data[1] = (data[1] * alpha) / 65535; - data[2] = (data[2] * alpha) / 65535; - } -} - -static void -_cogl_bitmap_unpremult_unpacked_span_float (float *data, - int width) -{ - while (width-- > 0) - { - float alpha = data[3]; - - if (alpha == 0.0) - memset (data, 0, sizeof (float) * 3); - else - { - data[0] = data[0] / alpha; - data[1] = data[1] / alpha; - data[2] = data[2] / alpha; - } - } -} - -static void -_cogl_bitmap_premult_unpacked_span_float (float *data, - int width) -{ - while (width-- > 0) - { - float alpha = data[3]; - - data[0] = data[0] * alpha; - data[1] = data[1] * alpha; - data[2] = data[2] * alpha; - } -} - -static gboolean -_cogl_bitmap_can_fast_premult (CoglPixelFormat format) -{ - switch (format & ~COGL_PREMULT_BIT) - { - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ABGR_8888: - return TRUE; - - default: - return FALSE; - } -} - -static gboolean -determine_medium_size (CoglPixelFormat format) -{ - switch (format) - { - case COGL_PIXEL_FORMAT_DEPTH_16: - case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: - case COGL_PIXEL_FORMAT_ANY: - case COGL_PIXEL_FORMAT_YUV: - g_assert_not_reached (); - - case COGL_PIXEL_FORMAT_A_8: - case COGL_PIXEL_FORMAT_RG_88: - case COGL_PIXEL_FORMAT_RGB_565: - case COGL_PIXEL_FORMAT_RGBA_4444: - case COGL_PIXEL_FORMAT_RGBA_5551: - case COGL_PIXEL_FORMAT_R_8: - case COGL_PIXEL_FORMAT_RGB_888: - case COGL_PIXEL_FORMAT_BGR_888: - case COGL_PIXEL_FORMAT_RGBX_8888: - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_BGRX_8888: - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_XRGB_8888: - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_XBGR_8888: - case COGL_PIXEL_FORMAT_ABGR_8888: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - case COGL_PIXEL_FORMAT_ABGR_8888_PRE: - case COGL_PIXEL_FORMAT_RGBA_4444_PRE: - case COGL_PIXEL_FORMAT_RGBA_5551_PRE: - return MEDIUM_TYPE_8; - - case COGL_PIXEL_FORMAT_RGBA_1010102: - case COGL_PIXEL_FORMAT_BGRA_1010102: - case COGL_PIXEL_FORMAT_XRGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010: - case COGL_PIXEL_FORMAT_XBGR_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010: - case COGL_PIXEL_FORMAT_RGBA_1010102_PRE: - case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: - case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: - case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: - case COGL_PIXEL_FORMAT_R_16: - case COGL_PIXEL_FORMAT_RG_1616: - case COGL_PIXEL_FORMAT_RGBA_16161616: - case COGL_PIXEL_FORMAT_RGBA_16161616_PRE: - return MEDIUM_TYPE_16; - - case COGL_PIXEL_FORMAT_RGBX_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616: - case COGL_PIXEL_FORMAT_BGRX_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616: - case COGL_PIXEL_FORMAT_XRGB_FP_16161616: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616: - case COGL_PIXEL_FORMAT_XBGR_FP_16161616: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_RGBA_FP_32323232: - case COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE: - return MEDIUM_TYPE_FLOAT; - } - - g_assert_not_reached (); - return FALSE; -} - -static size_t -calculate_medium_size_pixel_size (MediumType medium_type) -{ - switch (medium_type) - { - case MEDIUM_TYPE_8: - return sizeof (uint8_t) * 4; - case MEDIUM_TYPE_16: - return sizeof (uint16_t) * 4; - case MEDIUM_TYPE_FLOAT: - return sizeof (float) * 4; - } - - g_assert_not_reached (); -} - -gboolean -_cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp, - CoglBitmap *dst_bmp, - GError **error) -{ - uint8_t *src_data; - uint8_t *dst_data; - uint8_t *src; - uint8_t *dst; - void *tmp_row; - int src_rowstride; - int dst_rowstride; - int y; - int width, height; - CoglPixelFormat src_format; - CoglPixelFormat dst_format; - MediumType medium_type; - gboolean need_premult; - - src_format = cogl_bitmap_get_format (src_bmp); - src_rowstride = cogl_bitmap_get_rowstride (src_bmp); - dst_format = cogl_bitmap_get_format (dst_bmp); - dst_rowstride = cogl_bitmap_get_rowstride (dst_bmp); - width = cogl_bitmap_get_width (src_bmp); - height = cogl_bitmap_get_height (src_bmp); - - g_return_val_if_fail (width == cogl_bitmap_get_width (dst_bmp), FALSE); - g_return_val_if_fail (height == cogl_bitmap_get_height (dst_bmp), FALSE); - - need_premult - = ((src_format & COGL_PREMULT_BIT) != (dst_format & COGL_PREMULT_BIT) && - src_format != COGL_PIXEL_FORMAT_A_8 && - dst_format != COGL_PIXEL_FORMAT_A_8 && - (src_format & dst_format & COGL_A_BIT)); - - /* If the base format is the same then we can just copy the bitmap - instead */ - if ((src_format & ~COGL_PREMULT_BIT) == (dst_format & ~COGL_PREMULT_BIT) && - (!need_premult || _cogl_bitmap_can_fast_premult (dst_format))) - { - if (!_cogl_bitmap_copy_subregion (src_bmp, dst_bmp, - 0, 0, /* src_x / src_y */ - 0, 0, /* dst_x / dst_y */ - width, height, - error)) - return FALSE; - - if (need_premult) - { - if ((dst_format & COGL_PREMULT_BIT)) - { - if (!_cogl_bitmap_premult (dst_bmp, error)) - return FALSE; - } - else - { - if (!_cogl_bitmap_unpremult (dst_bmp, error)) - return FALSE; - } - } - - return TRUE; - } - - src_data = _cogl_bitmap_map (src_bmp, COGL_BUFFER_ACCESS_READ, 0, error); - if (src_data == NULL) - return FALSE; - dst_data = _cogl_bitmap_map (dst_bmp, - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD, - error); - if (dst_data == NULL) - { - _cogl_bitmap_unmap (src_bmp); - return FALSE; - } - - medium_type = determine_medium_size (dst_format); - - /* Allocate a buffer to hold a temporary RGBA row */ - tmp_row = g_malloc (width * calculate_medium_size_pixel_size (medium_type)); - - /* FIXME: Optimize */ - for (y = 0; y < height; y++) - { - src = src_data + y * src_rowstride; - dst = dst_data + y * dst_rowstride; - - switch (medium_type) - { - case MEDIUM_TYPE_8: - _cogl_unpack_8 (src_format, src, tmp_row, width); - break; - case MEDIUM_TYPE_16: - _cogl_unpack_16 (src_format, src, tmp_row, width); - break; - case MEDIUM_TYPE_FLOAT: - _cogl_unpack_float (src_format, src, tmp_row, width); - break; - } - - /* Handle premultiplication */ - if (need_premult) - { - if (dst_format & COGL_PREMULT_BIT) - { - switch (medium_type) - { - case MEDIUM_TYPE_8: - _cogl_bitmap_premult_unpacked_span_8 (tmp_row, width); - break; - case MEDIUM_TYPE_16: - _cogl_bitmap_premult_unpacked_span_16 (tmp_row, width); - break; - case MEDIUM_TYPE_FLOAT: - _cogl_bitmap_premult_unpacked_span_float (tmp_row, width); - break; - } - } - else - { - switch (medium_type) - { - case MEDIUM_TYPE_8: - _cogl_bitmap_unpremult_unpacked_span_8 (tmp_row, width); - break; - case MEDIUM_TYPE_16: - _cogl_bitmap_unpremult_unpacked_span_16 (tmp_row, width); - break; - case MEDIUM_TYPE_FLOAT: - _cogl_bitmap_unpremult_unpacked_span_float (tmp_row, width); - break; - } - } - } - - switch (medium_type) - { - case MEDIUM_TYPE_8: - _cogl_pack_8 (dst_format, tmp_row, dst, width); - break; - case MEDIUM_TYPE_16: - _cogl_pack_16 (dst_format, tmp_row, dst, width); - break; - case MEDIUM_TYPE_FLOAT: - _cogl_pack_float (dst_format, tmp_row, dst, width); - break; - } - } - - _cogl_bitmap_unmap (src_bmp); - _cogl_bitmap_unmap (dst_bmp); - - g_free (tmp_row); - - return TRUE; -} - -CoglBitmap * -_cogl_bitmap_convert (CoglBitmap *src_bmp, - CoglPixelFormat dst_format, - GError **error) -{ - CoglBitmap *dst_bmp; - int width, height; - CoglContext *ctx; - - ctx = _cogl_bitmap_get_context (src_bmp); - width = cogl_bitmap_get_width (src_bmp); - height = cogl_bitmap_get_height (src_bmp); - - dst_bmp = _cogl_bitmap_new_with_malloc_buffer (ctx, - width, height, - dst_format, - error); - if (!dst_bmp) - return NULL; - - if (!_cogl_bitmap_convert_into_bitmap (src_bmp, dst_bmp, error)) - { - g_object_unref (dst_bmp); - return NULL; - } - - return dst_bmp; -} - -static gboolean -driver_can_convert (CoglContext *ctx, - CoglPixelFormat src_format, - CoglPixelFormat internal_format) -{ - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_FORMAT_CONVERSION)) - return FALSE; - - if (src_format == internal_format) - return TRUE; - - /* If the driver doesn't natively support alpha textures then it - * won't work correctly to convert to/from component-alpha - * textures */ - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) && - (src_format == COGL_PIXEL_FORMAT_A_8 || - internal_format == COGL_PIXEL_FORMAT_A_8)) - return FALSE; - - /* Same for red-green textures. If red-green textures aren't - * supported then the internal format should never be RG_88 but we - * should still be able to convert from an RG source image */ - if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_RG) && - src_format == COGL_PIXEL_FORMAT_RG_88) - return FALSE; - - return TRUE; -} - -CoglBitmap * -_cogl_bitmap_convert_for_upload (CoglBitmap *src_bmp, - CoglPixelFormat internal_format, - GError **error) -{ - CoglContext *ctx = _cogl_bitmap_get_context (src_bmp); - CoglPixelFormat src_format = cogl_bitmap_get_format (src_bmp); - CoglBitmap *dst_bmp; - - g_return_val_if_fail (internal_format != COGL_PIXEL_FORMAT_ANY, NULL); - - /* OpenGL supports specifying a different format for the internal - format when uploading texture data. We should use this to convert - formats because it is likely to be faster and support more types - than the Cogl bitmap code. However under GLES the internal format - must be the same as the bitmap format and it only supports a - limited number of formats so we must convert using the Cogl - bitmap code instead */ - - if (driver_can_convert (ctx, src_format, internal_format)) - { - /* If the source format does not have the same premult flag as the - internal_format then we need to copy and convert it */ - if (_cogl_texture_needs_premult_conversion (src_format, - internal_format)) - { - dst_bmp = _cogl_bitmap_convert (src_bmp, - src_format ^ COGL_PREMULT_BIT, - error); - if (dst_bmp == NULL) - return NULL; - } - else - dst_bmp = g_object_ref (src_bmp); - } - else - { - CoglPixelFormat closest_format; - - closest_format = - ctx->driver_vtable->pixel_format_to_gl (ctx, - internal_format, - NULL, /* ignore gl intformat */ - NULL, /* ignore gl format */ - NULL); /* ignore gl type */ - - if (closest_format != src_format) - dst_bmp = _cogl_bitmap_convert (src_bmp, closest_format, error); - else - dst_bmp = g_object_ref (src_bmp); - } - - return dst_bmp; -} - -gboolean -_cogl_bitmap_unpremult (CoglBitmap *bmp, - GError **error) -{ - uint8_t *p, *data; - uint16_t *tmp_row; - int x,y; - CoglPixelFormat format; - int width, height; - int rowstride; - - format = cogl_bitmap_get_format (bmp); - width = cogl_bitmap_get_width (bmp); - height = cogl_bitmap_get_height (bmp); - rowstride = cogl_bitmap_get_rowstride (bmp); - - if ((data = _cogl_bitmap_map (bmp, - COGL_BUFFER_ACCESS_READ | - COGL_BUFFER_ACCESS_WRITE, - 0, - error)) == NULL) - return FALSE; - - /* If we can't directly unpremult the data inline then we'll - allocate a temporary row and unpack the data. This assumes if we - can fast premult then we can also fast unpremult */ - if (_cogl_bitmap_can_fast_premult (format)) - tmp_row = NULL; - else - tmp_row = g_malloc (sizeof (uint16_t) * 4 * width); - - for (y = 0; y < height; y++) - { - p = (uint8_t*) data + y * rowstride; - - if (tmp_row) - { - _cogl_unpack_16 (format, p, tmp_row, width); - _cogl_bitmap_unpremult_unpacked_span_16 (tmp_row, width); - _cogl_pack_16 (format, tmp_row, p, width); - } - else - { - if (format & COGL_AFIRST_BIT) - { - for (x = 0; x < width; x++) - { - if (p[0] == 0) - _cogl_unpremult_alpha_0 (p); - else - _cogl_unpremult_alpha_first (p); - p += 4; - } - } - else - _cogl_bitmap_unpremult_unpacked_span_8 (p, width); - } - } - - g_free (tmp_row); - - _cogl_bitmap_unmap (bmp); - - _cogl_bitmap_set_format (bmp, format & ~COGL_PREMULT_BIT); - - return TRUE; -} - -gboolean -_cogl_bitmap_premult (CoglBitmap *bmp, - GError **error) -{ - uint8_t *p, *data; - uint16_t *tmp_row; - int x,y; - CoglPixelFormat format; - int width, height; - int rowstride; - - format = cogl_bitmap_get_format (bmp); - width = cogl_bitmap_get_width (bmp); - height = cogl_bitmap_get_height (bmp); - rowstride = cogl_bitmap_get_rowstride (bmp); - - if ((data = _cogl_bitmap_map (bmp, - COGL_BUFFER_ACCESS_READ | - COGL_BUFFER_ACCESS_WRITE, - 0, - error)) == NULL) - return FALSE; - - /* If we can't directly premult the data inline then we'll allocate - a temporary row and unpack the data. */ - if (_cogl_bitmap_can_fast_premult (format)) - tmp_row = NULL; - else - tmp_row = g_malloc (sizeof (uint16_t) * 4 * width); - - for (y = 0; y < height; y++) - { - p = (uint8_t*) data + y * rowstride; - - if (tmp_row) - { - _cogl_unpack_16 (format, p, tmp_row, width); - _cogl_bitmap_premult_unpacked_span_16 (tmp_row, width); - _cogl_pack_16 (format, tmp_row, p, width); - } - else - { - if (format & COGL_AFIRST_BIT) - { - for (x = 0; x < width; x++) - { - _cogl_premult_alpha_first (p); - p += 4; - } - } - else - _cogl_bitmap_premult_unpacked_span_8 (p, width); - } - } - - g_free (tmp_row); - - _cogl_bitmap_unmap (bmp); - - _cogl_bitmap_set_format (bmp, format | COGL_PREMULT_BIT); - - return TRUE; -} diff --git a/mutter/cogl/cogl/cogl-bitmap-packing.h b/mutter/cogl/cogl/cogl-bitmap-packing.h deleted file mode 100644 index 720fe06..0000000 --- a/mutter/cogl/cogl/cogl-bitmap-packing.h +++ /dev/null @@ -1,1476 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This file is included multiple times with different definitions for - the component_type type (either uint8_t or uint16_t). The code ends - up exactly the same for both but we only want to end up hitting the - 16-bit path when one of the types in the conversion is > 8 bits per - component. */ - -/* Unpacking to RGBA */ - -inline static void -G_PASTE (_cogl_unpack_a_8_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = 0; - dst[1] = 0; - dst[2] = 0; - dst[3] = UNPACK_BYTE (*src); - dst += 4; - src++; - } -} - -inline static void -G_PASTE (_cogl_unpack_r_8_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - /* FIXME: I'm not sure if this is right. It looks like Nvidia and - Mesa handle luminance textures differently. Maybe we should - consider just removing luminance textures for Cogl 2.0 because - they have been removed in GL 3.0 */ - while (width-- > 0) - { - component_type v = UNPACK_BYTE (src[0]); - dst[0] = v; - dst[1] = v; - dst[2] = v; - dst[3] = UNPACK_BYTE (255); - dst += 4; - src++; - } -} - -inline static void -G_PASTE (_cogl_unpack_rg_88_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[0]); - dst[1] = UNPACK_BYTE (src[1]); - dst[2] = 0; - dst[3] = UNPACK_BYTE (255); - dst += 4; - src += 2; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgb_888_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[0]); - dst[1] = UNPACK_BYTE (src[1]); - dst[2] = UNPACK_BYTE (src[2]); - dst[3] = UNPACK_BYTE (255); - dst += 4; - src += 3; - } -} - -inline static void -G_PASTE (_cogl_unpack_bgr_888_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[2]); - dst[1] = UNPACK_BYTE (src[1]); - dst[2] = UNPACK_BYTE (src[0]); - dst[3] = UNPACK_BYTE (255); - dst += 4; - src += 3; - } -} - -inline static void -G_PASTE (_cogl_unpack_bgrx_8888_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[2]); - dst[1] = UNPACK_BYTE (src[1]); - dst[2] = UNPACK_BYTE (src[0]); - dst[3] = UNPACK_BYTE (255); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_bgra_8888_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[2]); - dst[1] = UNPACK_BYTE (src[1]); - dst[2] = UNPACK_BYTE (src[0]); - dst[3] = UNPACK_BYTE (src[3]); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_xrgb_8888_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[1]); - dst[1] = UNPACK_BYTE (src[2]); - dst[2] = UNPACK_BYTE (src[3]); - dst[3] = UNPACK_BYTE (255); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_argb_8888_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[1]); - dst[1] = UNPACK_BYTE (src[2]); - dst[2] = UNPACK_BYTE (src[3]); - dst[3] = UNPACK_BYTE (src[0]); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_xbgr_8888_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[3]); - dst[1] = UNPACK_BYTE (src[2]); - dst[2] = UNPACK_BYTE (src[1]); - dst[3] = UNPACK_BYTE (255); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_abgr_8888_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[3]); - dst[1] = UNPACK_BYTE (src[2]); - dst[2] = UNPACK_BYTE (src[1]); - dst[3] = UNPACK_BYTE (src[0]); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgbx_8888_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[0]); - dst[1] = UNPACK_BYTE (src[1]); - dst[2] = UNPACK_BYTE (src[2]); - dst[3] = UNPACK_BYTE (255); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgba_8888_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[0]); - dst[1] = UNPACK_BYTE (src[1]); - dst[2] = UNPACK_BYTE (src[2]); - dst[3] = UNPACK_BYTE (src[3]); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgb_565_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - uint16_t v = *(const uint16_t *) src; - - dst[0] = UNPACK_5 (v >> 11); - dst[1] = UNPACK_6 ((v >> 5) & 0x3f); - dst[2] = UNPACK_5 (v & 0x1f); - dst[3] = UNPACK_BYTE (255); - dst += 4; - src += 2; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgba_4444_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - uint16_t v = *(const uint16_t *) src; - - dst[0] = UNPACK_4 (v >> 12); - dst[1] = UNPACK_4 ((v >> 8) & 0xf); - dst[2] = UNPACK_4 ((v >> 4) & 0xf); - dst[3] = UNPACK_4 (v & 0xf); - dst += 4; - src += 2; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgba_5551_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - uint16_t v = *(const uint16_t *) src; - - dst[0] = UNPACK_5 (v >> 11); - dst[1] = UNPACK_5 ((v >> 6) & 0x1f); - dst[2] = UNPACK_5 ((v >> 1) & 0x1f); - dst[3] = UNPACK_1 (v & 1); - dst += 4; - src += 2; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgba_1010102_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - uint32_t v = *(const uint32_t *) src; - - dst[0] = UNPACK_10 (v >> 22); - dst[1] = UNPACK_10 ((v >> 12) & 0x3ff); - dst[2] = UNPACK_10 ((v >> 2) & 0x3ff); - dst[3] = UNPACK_2 (v & 3); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_bgra_1010102_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - uint32_t v = *(const uint32_t *) src; - - dst[2] = UNPACK_10 (v >> 22); - dst[1] = UNPACK_10 ((v >> 12) & 0x3ff); - dst[0] = UNPACK_10 ((v >> 2) & 0x3ff); - dst[3] = UNPACK_2 (v & 3); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_xrgb_2101010_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - uint32_t v = *(const uint32_t *) src; - - dst[3] = UNPACK_2 (0x3); - dst[0] = UNPACK_10 ((v >> 20) & 0x3ff); - dst[1] = UNPACK_10 ((v >> 10) & 0x3ff); - dst[2] = UNPACK_10 (v & 0x3ff); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_argb_2101010_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - uint32_t v = *(const uint32_t *) src; - - dst[3] = UNPACK_2 (v >> 30); - dst[0] = UNPACK_10 ((v >> 20) & 0x3ff); - dst[1] = UNPACK_10 ((v >> 10) & 0x3ff); - dst[2] = UNPACK_10 (v & 0x3ff); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_xbgr_2101010_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - uint32_t v = *(const uint32_t *) src; - - dst[3] = UNPACK_2 (0x3); - dst[2] = UNPACK_10 ((v >> 20) & 0x3ff); - dst[1] = UNPACK_10 ((v >> 10) & 0x3ff); - dst[0] = UNPACK_10 (v & 0x3ff); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_abgr_2101010_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - uint32_t v = *(const uint32_t *) src; - - dst[3] = UNPACK_2 (v >> 30); - dst[2] = UNPACK_10 ((v >> 20) & 0x3ff); - dst[1] = UNPACK_10 ((v >> 10) & 0x3ff); - dst[0] = UNPACK_10 (v & 0x3ff); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgbx_fp_16161616_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - const uint16_t *src16 = (const uint16_t *) src; - - dst[0] = UNPACK_SHORT (src16[0]); - dst[1] = UNPACK_SHORT (src16[1]); - dst[2] = UNPACK_SHORT (src16[2]); - dst[3] = UNPACK_SHORT (0x3C00); - dst += 4; - src += 8; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgba_fp_16161616_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - const uint16_t *src16 = (const uint16_t *) src; - - dst[0] = UNPACK_SHORT (src16[0]); - dst[1] = UNPACK_SHORT (src16[1]); - dst[2] = UNPACK_SHORT (src16[2]); - dst[3] = UNPACK_SHORT (src16[3]); - dst += 4; - src += 8; - } -} - -inline static void -G_PASTE (_cogl_unpack_bgrx_fp_16161616_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - const uint16_t *src16 = (const uint16_t *) src; - - dst[0] = UNPACK_SHORT (src16[2]); - dst[1] = UNPACK_SHORT (src16[1]); - dst[2] = UNPACK_SHORT (src16[0]); - dst[3] = UNPACK_SHORT (0x3C00); - dst += 4; - src += 8; - } -} - -inline static void -G_PASTE (_cogl_unpack_bgra_fp_16161616_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - const uint16_t *src16 = (const uint16_t *) src; - - dst[0] = UNPACK_SHORT (src16[2]); - dst[1] = UNPACK_SHORT (src16[1]); - dst[2] = UNPACK_SHORT (src16[0]); - dst[3] = UNPACK_SHORT (src16[3]); - dst += 4; - src += 8; - } -} - -inline static void -G_PASTE (_cogl_unpack_xrgb_fp_16161616_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - const uint16_t *src16 = (const uint16_t *) src; - - dst[0] = UNPACK_SHORT (src16[1]); - dst[1] = UNPACK_SHORT (src16[2]); - dst[2] = UNPACK_SHORT (src16[3]); - dst[3] = UNPACK_SHORT (0x3C00); - dst += 4; - src += 8; - } -} - -inline static void -G_PASTE (_cogl_unpack_argb_fp_16161616_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - const uint16_t *src16 = (const uint16_t *) src; - - dst[0] = UNPACK_SHORT (src16[1]); - dst[1] = UNPACK_SHORT (src16[2]); - dst[2] = UNPACK_SHORT (src16[3]); - dst[3] = UNPACK_SHORT (src16[0]); - dst += 4; - src += 8; - } -} - -inline static void -G_PASTE (_cogl_unpack_xbgr_fp_16161616_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - const uint16_t *src16 = (const uint16_t *) src; - - dst[0] = UNPACK_SHORT (src16[3]); - dst[1] = UNPACK_SHORT (src16[2]); - dst[2] = UNPACK_SHORT (src16[1]); - dst[3] = UNPACK_SHORT (0x3C00); - dst += 4; - src += 8; - } -} - -inline static void -G_PASTE (_cogl_unpack_abgr_fp_16161616_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - const uint16_t *src16 = (const uint16_t *) src; - - dst[0] = UNPACK_SHORT (src16[3]); - dst[1] = UNPACK_SHORT (src16[2]); - dst[2] = UNPACK_SHORT (src16[1]); - dst[3] = UNPACK_SHORT (src16[0]); - dst += 4; - src += 8; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgba_fp_32323232_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - const uint32_t *src32 = (const uint32_t *) src; - - dst[0] = UNPACK_FLOAT (src32[0]); - dst[1] = UNPACK_FLOAT (src32[1]); - dst[2] = UNPACK_FLOAT (src32[2]); - dst[3] = UNPACK_FLOAT (src32[3]); - dst += 4; - src += 16; - } -} - -inline static void -G_PASTE (_cogl_unpack_r_16_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - const uint16_t *v = (const uint16_t *) src; - - dst[0] = UNPACK_16 (v[0]); - dst[1] = 0; - dst[2] = 0; - dst[3] = UNPACK_BYTE (255); - dst += 4; - src += 2; - } -} - -inline static void -G_PASTE (_cogl_unpack_rg_1616_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - const uint16_t *v = (const uint16_t *) src; - - dst[0] = UNPACK_16 (v[0]); - dst[1] = UNPACK_16 (v[1]); - dst[2] = 0; - dst[3] = UNPACK_BYTE (255); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgba_16161616_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - const uint16_t *v = (const uint16_t *) src; - - dst[0] = UNPACK_16 (v[0]); - dst[1] = UNPACK_16 (v[1]); - dst[2] = UNPACK_16 (v[2]); - dst[3] = UNPACK_16 (v[3]); - dst += 4; - src += 8; - } -} - -inline static void -G_PASTE (_cogl_unpack_, component_size) (CoglPixelFormat format, - const uint8_t *src, - component_type *dst, - int width) -{ - switch (format) - { - case COGL_PIXEL_FORMAT_A_8: - G_PASTE (_cogl_unpack_a_8_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_R_8: - G_PASTE (_cogl_unpack_r_8_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RG_88: - G_PASTE (_cogl_unpack_rg_88_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGB_888: - G_PASTE (_cogl_unpack_rgb_888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGR_888: - G_PASTE (_cogl_unpack_bgr_888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBX_8888: - G_PASTE (_cogl_unpack_rgbx_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - G_PASTE (_cogl_unpack_rgba_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGRX_8888: - G_PASTE (_cogl_unpack_bgrx_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - G_PASTE (_cogl_unpack_bgra_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_XRGB_8888: - G_PASTE (_cogl_unpack_xrgb_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - G_PASTE (_cogl_unpack_argb_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_XBGR_8888: - G_PASTE (_cogl_unpack_xbgr_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ABGR_8888: - case COGL_PIXEL_FORMAT_ABGR_8888_PRE: - G_PASTE (_cogl_unpack_abgr_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGB_565: - G_PASTE (_cogl_unpack_rgb_565_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_4444: - case COGL_PIXEL_FORMAT_RGBA_4444_PRE: - G_PASTE (_cogl_unpack_rgba_4444_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_5551: - case COGL_PIXEL_FORMAT_RGBA_5551_PRE: - G_PASTE (_cogl_unpack_rgba_5551_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_1010102: - case COGL_PIXEL_FORMAT_RGBA_1010102_PRE: - G_PASTE (_cogl_unpack_rgba_1010102_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGRA_1010102: - case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: - G_PASTE (_cogl_unpack_bgra_1010102_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_XRGB_2101010: - G_PASTE (_cogl_unpack_xrgb_2101010_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ARGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: - G_PASTE (_cogl_unpack_argb_2101010_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_XBGR_2101010: - G_PASTE (_cogl_unpack_xbgr_2101010_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ABGR_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: - G_PASTE (_cogl_unpack_abgr_2101010_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBX_FP_16161616: - G_PASTE (_cogl_unpack_rgbx_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: - G_PASTE (_cogl_unpack_rgba_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGRX_FP_16161616: - G_PASTE (_cogl_unpack_bgrx_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGRA_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: - G_PASTE (_cogl_unpack_bgra_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_XRGB_FP_16161616: - G_PASTE (_cogl_unpack_xrgb_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ARGB_FP_16161616: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: - G_PASTE (_cogl_unpack_argb_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_XBGR_FP_16161616: - G_PASTE (_cogl_unpack_xbgr_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ABGR_FP_16161616: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: - G_PASTE (_cogl_unpack_abgr_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_FP_32323232: - case COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE: - G_PASTE (_cogl_unpack_rgba_fp_32323232_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_R_16: - G_PASTE (_cogl_unpack_r_16_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RG_1616: - G_PASTE (_cogl_unpack_rg_1616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_16161616: - case COGL_PIXEL_FORMAT_RGBA_16161616_PRE: - G_PASTE (_cogl_unpack_rgba_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_DEPTH_16: - case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: - case COGL_PIXEL_FORMAT_ANY: - case COGL_PIXEL_FORMAT_YUV: - g_assert_not_reached (); - } -} - -/* Packing from RGBA */ - -inline static void -G_PASTE (_cogl_pack_a_8_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - *dst = PACK_BYTE (src[3]); - src += 4; - dst++; - } -} - -inline static void -G_PASTE (_cogl_pack_r_8_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - /* FIXME: I'm not sure if this is right. It looks like Nvidia and - Mesa handle luminance textures differently. Maybe we should - consider just removing luminance textures for Cogl 2.0 because - they have been removed in GL 3.0 */ - while (width-- > 0) - { - component_type v = (src[0] + src[1] + src[2]) / 3; - *dst = PACK_BYTE (v); - src += 4; - dst++; - } -} - -inline static void -G_PASTE (_cogl_pack_rg_88_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = PACK_BYTE (src[0]); - dst[1] = PACK_BYTE (src[1]); - src += 4; - dst += 2; - } -} - -inline static void -G_PASTE (_cogl_pack_rgb_888_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = PACK_BYTE (src[0]); - dst[1] = PACK_BYTE (src[1]); - dst[2] = PACK_BYTE (src[2]); - src += 4; - dst += 3; - } -} - -inline static void -G_PASTE (_cogl_pack_bgr_888_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[2] = PACK_BYTE (src[0]); - dst[1] = PACK_BYTE (src[1]); - dst[0] = PACK_BYTE (src[2]); - src += 4; - dst += 3; - } -} - -inline static void -G_PASTE (_cogl_pack_bgrx_8888_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[2] = PACK_BYTE (src[0]); - dst[1] = PACK_BYTE (src[1]); - dst[0] = PACK_BYTE (src[2]); - dst[3] = 255; - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_bgra_8888_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[2] = PACK_BYTE (src[0]); - dst[1] = PACK_BYTE (src[1]); - dst[0] = PACK_BYTE (src[2]); - dst[3] = PACK_BYTE (src[3]); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_xrgb_8888_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[1] = PACK_BYTE (src[0]); - dst[2] = PACK_BYTE (src[1]); - dst[3] = PACK_BYTE (src[2]); - dst[0] = 255; - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_argb_8888_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[1] = PACK_BYTE (src[0]); - dst[2] = PACK_BYTE (src[1]); - dst[3] = PACK_BYTE (src[2]); - dst[0] = PACK_BYTE (src[3]); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_xbgr_8888_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[3] = PACK_BYTE (src[0]); - dst[2] = PACK_BYTE (src[1]); - dst[1] = PACK_BYTE (src[2]); - dst[0] = 255; - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_abgr_8888_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[3] = PACK_BYTE (src[0]); - dst[2] = PACK_BYTE (src[1]); - dst[1] = PACK_BYTE (src[2]); - dst[0] = PACK_BYTE (src[3]); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_rgbx_8888_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = PACK_BYTE (src[0]); - dst[1] = PACK_BYTE (src[1]); - dst[2] = PACK_BYTE (src[2]); - dst[3] = 255; - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_rgba_8888_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = PACK_BYTE (src[0]); - dst[1] = PACK_BYTE (src[1]); - dst[2] = PACK_BYTE (src[2]); - dst[3] = PACK_BYTE (src[3]); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_rgb_565_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *v = (uint16_t *) dst; - - *v = ((PACK_5 (src[0]) << 11) | - (PACK_6 (src[1]) << 5) | - PACK_5 (src[2])); - src += 4; - dst += 2; - } -} - -inline static void -G_PASTE (_cogl_pack_rgba_4444_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *v = (uint16_t *) dst; - - *v = ((PACK_4 (src[0]) << 12) | - (PACK_4 (src[1]) << 8) | - (PACK_4 (src[2]) << 4) | - PACK_4 (src[3])); - src += 4; - dst += 2; - } -} - -inline static void -G_PASTE (_cogl_pack_rgba_5551_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *v = (uint16_t *) dst; - - *v = ((PACK_5 (src[0]) << 11) | - (PACK_5 (src[1]) << 6) | - (PACK_5 (src[2]) << 1) | - PACK_1 (src[3])); - src += 4; - dst += 2; - } -} - -inline static void -G_PASTE (_cogl_pack_rgba_1010102_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint32_t *v = (uint32_t *) dst; - - *v = ((PACK_10 (src[0]) << 22) | - (PACK_10 (src[1]) << 12) | - (PACK_10 (src[2]) << 2) | - PACK_2 (src[3])); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_bgra_1010102_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint32_t *v = (uint32_t *) dst; - - *v = ((PACK_10 (src[2]) << 22) | - (PACK_10 (src[1]) << 12) | - (PACK_10 (src[0]) << 2) | - PACK_2 (src[3])); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_xrgb_2101010_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint32_t *v = (uint32_t *) dst; - - *v = ((0x3 << 30) | - (PACK_10 (src[0]) << 20) | - (PACK_10 (src[1]) << 10) | - PACK_10 (src[2])); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_argb_2101010_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint32_t *v = (uint32_t *) dst; - - *v = ((PACK_2 (src[3]) << 30) | - (PACK_10 (src[0]) << 20) | - (PACK_10 (src[1]) << 10) | - PACK_10 (src[2])); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_xbgr_2101010_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint32_t *v = (uint32_t *) dst; - - *v = ((0x3 << 30) | - (PACK_10 (src[2]) << 20) | - (PACK_10 (src[1]) << 10) | - PACK_10 (src[0])); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_abgr_2101010_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint32_t *v = (uint32_t *) dst; - - *v = ((PACK_2 (src[3]) << 30) | - (PACK_10 (src[2]) << 20) | - (PACK_10 (src[1]) << 10) | - PACK_10 (src[0])); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_rgbx_fp_16161616_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *dst16 = (uint16_t *) dst; - - dst16[0] = PACK_SHORT (src[0]); - dst16[1] = PACK_SHORT (src[1]); - dst16[2] = PACK_SHORT (src[2]); - dst16[3] = 0x3C00; - src += 4; - dst += 8; - } -} - -inline static void -G_PASTE (_cogl_pack_rgba_fp_16161616_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *dst16 = (uint16_t *) dst; - - dst16[0] = PACK_SHORT (src[0]); - dst16[1] = PACK_SHORT (src[1]); - dst16[2] = PACK_SHORT (src[2]); - dst16[3] = PACK_SHORT (src[3]); - src += 4; - dst += 8; - } -} - -inline static void -G_PASTE (_cogl_pack_bgrx_fp_16161616_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *dst16 = (uint16_t *) dst; - - dst16[0] = PACK_SHORT (src[2]); - dst16[1] = PACK_SHORT (src[1]); - dst16[2] = PACK_SHORT (src[0]); - dst16[3] = 0x3C00; - src += 4; - dst += 8; - } -} - -inline static void -G_PASTE (_cogl_pack_bgra_fp_16161616_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *dst16 = (uint16_t *) dst; - - dst16[0] = PACK_SHORT (src[2]); - dst16[1] = PACK_SHORT (src[1]); - dst16[2] = PACK_SHORT (src[0]); - dst16[3] = PACK_SHORT (src[3]); - src += 4; - dst += 8; - } -} - -inline static void -G_PASTE (_cogl_pack_xrgb_fp_16161616_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *dst16 = (uint16_t *) dst; - - dst16[0] = 0x3C00; - dst16[1] = PACK_SHORT (src[0]); - dst16[2] = PACK_SHORT (src[1]); - dst16[3] = PACK_SHORT (src[2]); - src += 4; - dst += 8; - } -} - -inline static void -G_PASTE (_cogl_pack_argb_fp_16161616_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *dst16 = (uint16_t *) dst; - - dst16[0] = PACK_SHORT (src[3]); - dst16[1] = PACK_SHORT (src[0]); - dst16[2] = PACK_SHORT (src[1]); - dst16[3] = PACK_SHORT (src[2]); - src += 4; - dst += 8; - } -} - -inline static void -G_PASTE (_cogl_pack_xbgr_fp_16161616_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *dst16 = (uint16_t *) dst; - - dst16[0] = 0x3C00; - dst16[1] = PACK_SHORT (src[2]); - dst16[2] = PACK_SHORT (src[1]); - dst16[3] = PACK_SHORT (src[0]); - src += 4; - dst += 8; - } -} - -inline static void -G_PASTE (_cogl_pack_abgr_fp_16161616_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *dst16 = (uint16_t *) dst; - - dst16[0] = PACK_SHORT (src[3]); - dst16[1] = PACK_SHORT (src[2]); - dst16[2] = PACK_SHORT (src[1]); - dst16[3] = PACK_SHORT (src[0]); - src += 4; - dst += 8; - } -} - -inline static void -G_PASTE (_cogl_pack_rgba_fp_32323232_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint32_t *dst32 = (uint32_t *) dst; - - dst32[0] = PACK_FLOAT (src[0]); - dst32[1] = PACK_FLOAT (src[1]); - dst32[2] = PACK_FLOAT (src[2]); - dst32[3] = PACK_FLOAT (src[3]); - src += 4; - dst += 16; - } -} - -inline static void -G_PASTE (_cogl_pack_r_16_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *v = (uint16_t *) dst; - - v[0] = PACK_16 (src[0]); - - src += 4; - dst += 2; - } -} - -inline static void -G_PASTE (_cogl_pack_rg_1616_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *v = (uint16_t *) dst; - - v[0] = PACK_16 (src[0]); - v[1] = PACK_16 (src[1]); - - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_rgba_16161616_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *v = (uint16_t *) dst; - - v[0] = PACK_16 (src[0]); - v[1] = PACK_16 (src[1]); - v[2] = PACK_16 (src[2]); - v[3] = PACK_16 (src[3]); - - src += 4; - dst += 8; - } -} - -inline static void -G_PASTE (_cogl_pack_, component_size) (CoglPixelFormat format, - const component_type *src, - uint8_t *dst, - int width) -{ - switch (format) - { - case COGL_PIXEL_FORMAT_A_8: - G_PASTE (_cogl_pack_a_8_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_R_8: - G_PASTE (_cogl_pack_r_8_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RG_88: - G_PASTE (_cogl_pack_rg_88_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGB_888: - G_PASTE (_cogl_pack_rgb_888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGR_888: - G_PASTE (_cogl_pack_bgr_888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBX_8888: - G_PASTE (_cogl_pack_rgbx_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - G_PASTE (_cogl_pack_rgba_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGRX_8888: - G_PASTE (_cogl_pack_bgrx_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - G_PASTE (_cogl_pack_bgra_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_XRGB_8888: - G_PASTE (_cogl_pack_xrgb_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - G_PASTE (_cogl_pack_argb_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_XBGR_8888: - G_PASTE (_cogl_pack_xbgr_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ABGR_8888: - case COGL_PIXEL_FORMAT_ABGR_8888_PRE: - G_PASTE (_cogl_pack_abgr_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGB_565: - G_PASTE (_cogl_pack_rgb_565_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_4444: - case COGL_PIXEL_FORMAT_RGBA_4444_PRE: - G_PASTE (_cogl_pack_rgba_4444_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_5551: - case COGL_PIXEL_FORMAT_RGBA_5551_PRE: - G_PASTE (_cogl_pack_rgba_5551_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_1010102: - case COGL_PIXEL_FORMAT_RGBA_1010102_PRE: - G_PASTE (_cogl_pack_rgba_1010102_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGRA_1010102: - case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: - G_PASTE (_cogl_pack_bgra_1010102_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_XRGB_2101010: - G_PASTE (_cogl_pack_xrgb_2101010_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ARGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: - G_PASTE (_cogl_pack_argb_2101010_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_XBGR_2101010: - G_PASTE (_cogl_pack_xbgr_2101010_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ABGR_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: - G_PASTE (_cogl_pack_abgr_2101010_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBX_FP_16161616: - G_PASTE (_cogl_pack_rgbx_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: - G_PASTE (_cogl_pack_rgba_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGRX_FP_16161616: - G_PASTE (_cogl_pack_bgrx_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGRA_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: - G_PASTE (_cogl_pack_bgra_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_XRGB_FP_16161616: - G_PASTE (_cogl_pack_xrgb_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ARGB_FP_16161616: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: - G_PASTE (_cogl_pack_argb_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_XBGR_FP_16161616: - G_PASTE (_cogl_pack_xbgr_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ABGR_FP_16161616: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: - G_PASTE (_cogl_pack_abgr_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_FP_32323232: - case COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE: - G_PASTE (_cogl_pack_rgba_fp_32323232_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_R_16: - G_PASTE (_cogl_pack_r_16_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RG_1616: - G_PASTE (_cogl_pack_rg_1616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_16161616: - case COGL_PIXEL_FORMAT_RGBA_16161616_PRE: - G_PASTE (_cogl_pack_rgba_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_DEPTH_16: - case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: - case COGL_PIXEL_FORMAT_ANY: - case COGL_PIXEL_FORMAT_YUV: - g_assert_not_reached (); - } -} diff --git a/mutter/cogl/cogl/cogl-bitmap-private.h b/mutter/cogl/cogl/cogl-bitmap-private.h deleted file mode 100644 index 916fe97..0000000 --- a/mutter/cogl/cogl/cogl-bitmap-private.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007 OpenedHand - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include - -#include "cogl/cogl-buffer.h" -#include "cogl/cogl-bitmap.h" - -struct _CoglBitmap -{ - GObject parent_instance; - - /* Pointer back to the context that this bitmap was created with */ - CoglContext *context; - - CoglPixelFormat format; - int width; - int height; - int rowstride; - - uint8_t *data; - - gboolean mapped; - gboolean bound; - - /* If this is non-null then 'data' is ignored and instead it is - fetched from this shared bitmap. */ - CoglBitmap *shared_bmp; - - /* If this is non-null then 'data' is treated as an offset into the - buffer and map will divert to mapping the buffer */ - CoglBuffer *buffer; -}; - - -/* - * _cogl_bitmap_new_with_malloc_buffer: - * @context: A #CoglContext - * @width: width of the bitmap in pixels - * @height: height of the bitmap in pixels - * @format: the format of the pixels the array will store - * @error: A #GError for catching exceptional errors or %NULL - * - * This is equivalent to cogl_bitmap_new_with_size() except that it - * allocated the buffer using g_malloc() instead of creating a - * #CoglPixelBuffer. The buffer will be automatically destroyed when - * the bitmap is freed. - * - * Return value: a #CoglPixelBuffer representing the newly created array - */ -CoglBitmap * -_cogl_bitmap_new_with_malloc_buffer (CoglContext *context, - unsigned int width, - unsigned int height, - CoglPixelFormat format, - GError **error); - -/* The idea of this function is that it will create a bitmap that - shares the actual data with another bitmap. This is needed for the - atlas texture backend because it needs upload a bitmap to a sub - texture but override the format so that it ignores the premult - flag. */ -CoglBitmap * -_cogl_bitmap_new_shared (CoglBitmap *shared_bmp, - CoglPixelFormat format, - int width, - int height, - int rowstride); - -CoglBitmap * -_cogl_bitmap_convert (CoglBitmap *bmp, - CoglPixelFormat dst_format, - GError **error); - -CoglBitmap * -_cogl_bitmap_convert_for_upload (CoglBitmap *src_bmp, - CoglPixelFormat internal_format, - GError **error); - -gboolean -_cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp, - CoglBitmap *dst_bmp, - GError **error); - -gboolean -_cogl_bitmap_unpremult (CoglBitmap *dst_bmp, - GError **error); - -gboolean -_cogl_bitmap_premult (CoglBitmap *dst_bmp, - GError **error); - -gboolean -_cogl_bitmap_convert_premult_status (CoglBitmap *bmp, - CoglPixelFormat dst_format, - GError **error); - -gboolean -_cogl_bitmap_copy_subregion (CoglBitmap *src, - CoglBitmap *dst, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - GError **error); - -/* Creates a deep copy of the source bitmap */ -CoglBitmap * -_cogl_bitmap_copy (CoglBitmap *src_bmp, - GError **error); - -void -_cogl_bitmap_set_format (CoglBitmap *bitmap, - CoglPixelFormat format); - -/* Maps the bitmap so that the pixels can be accessed directly or if - the bitmap is just a memory bitmap then it just returns the pointer - to memory. Note that the bitmap isn't guaranteed to allocated to - the full size of rowstride*height so it is not safe to read up to - the rowstride of the last row. This will be the case if the user - uploads data using gdk_pixbuf_new_subpixbuf with a sub region - containing the last row of the pixbuf because in that case the - rowstride can be much larger than the width of the image */ -uint8_t * -_cogl_bitmap_map (CoglBitmap *bitmap, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error); - -void -_cogl_bitmap_unmap (CoglBitmap *bitmap); - -CoglContext * -_cogl_bitmap_get_context (CoglBitmap *bitmap); diff --git a/mutter/cogl/cogl/cogl-bitmap.c b/mutter/cogl/cogl/cogl-bitmap.c deleted file mode 100644 index 7c8d274..0000000 --- a/mutter/cogl/cogl/cogl-bitmap.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include "cogl/cogl-util.h" -#include "cogl/cogl-debug.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl-bitmap-private.h" -#include "cogl/cogl-buffer-private.h" -#include "cogl/cogl-pixel-buffer.h" -#include "cogl/cogl-context-private.h" - -#include - -static GQuark bitmap_free_key = 0; - -G_DEFINE_TYPE (CoglBitmap, cogl_bitmap, G_TYPE_OBJECT); - -static void -cogl_bitmap_dispose (GObject *object) -{ - CoglBitmap *bmp = COGL_BITMAP (object); - - g_assert (!bmp->mapped); - g_assert (!bmp->bound); - - if (bmp->shared_bmp) - g_object_unref (bmp->shared_bmp); - - if (bmp->buffer) - g_object_unref (bmp->buffer); - - G_OBJECT_CLASS (cogl_bitmap_parent_class)->dispose (object); -} - -static void -cogl_bitmap_init (CoglBitmap *bitmap) -{ -} - -static void -cogl_bitmap_class_init (CoglBitmapClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = cogl_bitmap_dispose; -} - -gboolean -_cogl_bitmap_convert_premult_status (CoglBitmap *bmp, - CoglPixelFormat dst_format, - GError **error) -{ - /* Do we need to unpremultiply? */ - if ((bmp->format & COGL_PREMULT_BIT) > 0 && - (dst_format & COGL_PREMULT_BIT) == 0 && - COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (dst_format)) - return _cogl_bitmap_unpremult (bmp, error); - - /* Do we need to premultiply? */ - if ((bmp->format & COGL_PREMULT_BIT) == 0 && - COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (bmp->format) && - (dst_format & COGL_PREMULT_BIT) > 0) - /* Try premultiplying using imaging library */ - return _cogl_bitmap_premult (bmp, error); - - return TRUE; -} - -CoglBitmap * -_cogl_bitmap_copy (CoglBitmap *src_bmp, - GError **error) -{ - CoglBitmap *dst_bmp; - CoglPixelFormat src_format = cogl_bitmap_get_format (src_bmp); - int width = cogl_bitmap_get_width (src_bmp); - int height = cogl_bitmap_get_height (src_bmp); - - dst_bmp = - _cogl_bitmap_new_with_malloc_buffer (src_bmp->context, - width, height, - src_format, - error); - if (!dst_bmp) - return NULL; - - if (!_cogl_bitmap_copy_subregion (src_bmp, - dst_bmp, - 0, 0, /* src_x/y */ - 0, 0, /* dst_x/y */ - width, height, - error)) - { - g_object_unref (dst_bmp); - return NULL; - } - - return dst_bmp; -} - -gboolean -_cogl_bitmap_copy_subregion (CoglBitmap *src, - CoglBitmap *dst, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - GError **error) -{ - uint8_t *srcdata; - uint8_t *dstdata; - int bpp; - int line; - gboolean succeeded = FALSE; - - /* Intended only for fast copies when format is equal! */ - g_return_val_if_fail ((src->format & ~COGL_PREMULT_BIT) == - (dst->format & ~COGL_PREMULT_BIT), - FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (src->format) == 1, - FALSE); - - bpp = cogl_pixel_format_get_bytes_per_pixel (src->format, 0); - - if ((srcdata = _cogl_bitmap_map (src, COGL_BUFFER_ACCESS_READ, 0, error))) - { - if ((dstdata = - _cogl_bitmap_map (dst, COGL_BUFFER_ACCESS_WRITE, 0, error))) - { - srcdata += src_y * src->rowstride + src_x * bpp; - dstdata += dst_y * dst->rowstride + dst_x * bpp; - - for (line = 0; line < height; ++line) - { - memcpy (dstdata, srcdata, width * bpp); - srcdata += src->rowstride; - dstdata += dst->rowstride; - } - - succeeded = TRUE; - - _cogl_bitmap_unmap (dst); - } - - _cogl_bitmap_unmap (src); - } - - return succeeded; -} - -CoglBitmap * -cogl_bitmap_new_for_data (CoglContext *context, - int width, - int height, - CoglPixelFormat format, - int rowstride, - uint8_t *data) -{ - CoglBitmap *bmp; - - g_return_val_if_fail (COGL_IS_CONTEXT (context), NULL); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); - - /* Rowstride from width if not given */ - if (rowstride == 0) - rowstride = width * cogl_pixel_format_get_bytes_per_pixel (format, 0); - - bmp = g_object_new (COGL_TYPE_BITMAP, NULL); - bmp->context = context; - bmp->format = format; - bmp->width = width; - bmp->height = height; - bmp->rowstride = rowstride; - bmp->data = data; - bmp->mapped = FALSE; - bmp->bound = FALSE; - bmp->shared_bmp = NULL; - bmp->buffer = NULL; - - return bmp; -} - -CoglBitmap * -_cogl_bitmap_new_with_malloc_buffer (CoglContext *context, - unsigned int width, - unsigned int height, - CoglPixelFormat format, - GError **error) -{ - bitmap_free_key = g_quark_from_static_string ("-cogl-bitmap-malloc-buffer-key"); - int bpp; - int rowstride; - uint8_t *data; - CoglBitmap *bitmap; - - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); - - /* Try to malloc the data */ - bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); - rowstride = ((width * bpp) + 3) & ~3; - data = g_try_malloc (rowstride * height); - - if (!data) - { - g_set_error_literal (error, COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_NO_MEMORY, - "Failed to allocate memory for bitmap"); - return NULL; - } - - /* Now create the bitmap */ - bitmap = cogl_bitmap_new_for_data (context, - width, height, - format, - rowstride, - data); - g_object_set_qdata_full (G_OBJECT (bitmap), - bitmap_free_key, - data, - g_free); - - return bitmap; -} - -CoglBitmap * -_cogl_bitmap_new_shared (CoglBitmap *shared_bmp, - CoglPixelFormat format, - int width, - int height, - int rowstride) -{ - CoglBitmap *bmp; - - bmp = cogl_bitmap_new_for_data (shared_bmp->context, - width, height, - format, - rowstride, - NULL /* data */); - - bmp->shared_bmp = g_object_ref (shared_bmp); - - return bmp; -} - -CoglBitmap * -cogl_bitmap_new_from_buffer (CoglBuffer *buffer, - CoglPixelFormat format, - int width, - int height, - int rowstride, - int offset) -{ - CoglBitmap *bmp; - - g_return_val_if_fail (COGL_IS_BUFFER (buffer), NULL); - - bmp = cogl_bitmap_new_for_data (buffer->context, - width, height, - format, - rowstride, - NULL /* data */); - - bmp->buffer = g_object_ref (buffer); - bmp->data = GINT_TO_POINTER (offset); - - return bmp; -} - -CoglBitmap * -cogl_bitmap_new_with_size (CoglContext *context, - unsigned int width, - unsigned int height, - CoglPixelFormat format) -{ - CoglPixelBuffer *pixel_buffer; - CoglBitmap *bitmap; - unsigned int rowstride; - - /* creating a buffer to store "any" format does not make sense */ - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); - - /* for now we fallback to cogl_pixel_buffer_new, later, we could ask - * libdrm a tiled buffer for instance */ - rowstride = width * cogl_pixel_format_get_bytes_per_pixel (format, 0); - - pixel_buffer = - cogl_pixel_buffer_new (context, - height * rowstride, - NULL); /* data */ - - g_return_val_if_fail (pixel_buffer != NULL, NULL); - - bitmap = cogl_bitmap_new_from_buffer (COGL_BUFFER (pixel_buffer), - format, - width, height, - rowstride, - 0 /* offset */); - - g_object_unref (pixel_buffer); - - return bitmap; -} - -CoglPixelFormat -cogl_bitmap_get_format (CoglBitmap *bitmap) -{ - return bitmap->format; -} - -void -_cogl_bitmap_set_format (CoglBitmap *bitmap, - CoglPixelFormat format) -{ - bitmap->format = format; -} - -int -cogl_bitmap_get_width (CoglBitmap *bitmap) -{ - return bitmap->width; -} - -int -cogl_bitmap_get_height (CoglBitmap *bitmap) -{ - return bitmap->height; -} - -int -cogl_bitmap_get_rowstride (CoglBitmap *bitmap) -{ - return bitmap->rowstride; -} - -CoglPixelBuffer * -cogl_bitmap_get_buffer (CoglBitmap *bitmap) -{ - while (bitmap->shared_bmp) - bitmap = bitmap->shared_bmp; - - return COGL_PIXEL_BUFFER (bitmap->buffer); -} - -uint32_t -cogl_bitmap_error_quark (void) -{ - return g_quark_from_static_string ("cogl-bitmap-error-quark"); -} - -uint8_t * -_cogl_bitmap_map (CoglBitmap *bitmap, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error) -{ - /* Divert to another bitmap if this data is shared */ - if (bitmap->shared_bmp) - return _cogl_bitmap_map (bitmap->shared_bmp, access, hints, error); - - g_assert (!bitmap->mapped); - - if (bitmap->buffer) - { - uint8_t *data = _cogl_buffer_map (bitmap->buffer, - access, - hints, - error); - - COGL_NOTE (BITMAP, "A pixel array is being mapped from a bitmap. This " - "usually means that some conversion on the pixel array is " - "needed so a sub-optimal format is being used."); - - if (data) - { - bitmap->mapped = TRUE; - - return data + GPOINTER_TO_INT (bitmap->data); - } - else - return NULL; - } - else - { - bitmap->mapped = TRUE; - - return bitmap->data; - } -} - -void -_cogl_bitmap_unmap (CoglBitmap *bitmap) -{ - /* Divert to another bitmap if this data is shared */ - if (bitmap->shared_bmp) - { - _cogl_bitmap_unmap (bitmap->shared_bmp); - return; - } - - g_assert (bitmap->mapped); - bitmap->mapped = FALSE; - - if (bitmap->buffer) - cogl_buffer_unmap (bitmap->buffer); -} - -CoglContext * -_cogl_bitmap_get_context (CoglBitmap *bitmap) -{ - return bitmap->context; -} diff --git a/mutter/cogl/cogl/cogl-bitmap.h b/mutter/cogl/cogl/cogl-bitmap.h deleted file mode 100644 index c9a35f6..0000000 --- a/mutter/cogl/cogl/cogl-bitmap.h +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -/* XXX: We forward declare CoglBitmap here to allow for circular - * dependencies between some headers */ -typedef struct _CoglBitmap CoglBitmap; - -#include "cogl/cogl-types.h" -#include "cogl/cogl-buffer.h" -#include "cogl/cogl-context.h" -#include "cogl/cogl-pixel-buffer.h" -#include "cogl/cogl-pixel-format.h" - -#include - -G_BEGIN_DECLS - -/** - * CoglBitmap: - * - * Functions for loading images - * - * Cogl allows loading image data into memory as CoglBitmaps without - * loading them immediately into GPU textures. - */ - -#define COGL_TYPE_BITMAP (cogl_bitmap_get_type ()) - -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglBitmap, - cogl_bitmap, - COGL, - BITMAP, - GObject) - -/** - * cogl_bitmap_new_from_buffer: - * @buffer: A #CoglBuffer containing image data - * @format: The #CoglPixelFormat defining the format of the image data - * in the given @buffer. - * @width: The width of the image data in the given @buffer. - * @height: The height of the image data in the given @buffer. - * @rowstride: The rowstride in bytes of the image data in the given @buffer. - * @offset: The offset into the given @buffer to the first pixel that - * should be considered part of the #CoglBitmap. - * - * Wraps some image data that has been uploaded into a #CoglBuffer as - * a #CoglBitmap. The data is not copied in this process. - * - * Return value: (transfer full): a #CoglBitmap encapsulating the given @buffer. - */ -COGL_EXPORT CoglBitmap * -cogl_bitmap_new_from_buffer (CoglBuffer *buffer, - CoglPixelFormat format, - int width, - int height, - int rowstride, - int offset); - -/** - * cogl_bitmap_new_with_size: - * @context: A #CoglContext - * @width: width of the bitmap in pixels - * @height: height of the bitmap in pixels - * @format: the format of the pixels the array will store - * - * Creates a new #CoglBitmap with the given width, height and format. - * The initial contents of the bitmap are undefined. - * - * The data for the bitmap will be stored in a newly created - * #CoglPixelBuffer. You can get a pointer to the pixel buffer using - * [method@Cogl.Bitmap.get_buffer]. The #CoglBuffer API can then be - * used to fill the bitmap with data. - * - * Cogl will try its best to provide a hardware array you can - * map, write into and effectively do a zero copy upload when creating - * a texture from it with cogl_texture_new_from_bitmap(). For various - * reasons, such arrays are likely to have a stride larger than width - * * bytes_per_pixel. The user must take the stride into account when - * writing into it. The stride can be retrieved with - * [method@Cogl.Bitmap.get_rowstride]. - * - * Return value: (transfer full): a #CoglPixelBuffer representing the - * newly created array or %NULL on failure - */ -COGL_EXPORT CoglBitmap * -cogl_bitmap_new_with_size (CoglContext *context, - unsigned int width, - unsigned int height, - CoglPixelFormat format); - -/** - * cogl_bitmap_new_for_data: - * @context: A #CoglContext - * @width: The width of the bitmap. - * @height: The height of the bitmap. - * @format: The format of the pixel data. - * @rowstride: The rowstride of the bitmap (the number of bytes from - * the start of one row of the bitmap to the next). - * @data: (array) (transfer full): A pointer to the data. The bitmap will take - * ownership of this data. - * - * Creates a bitmap using some existing data. The data is not copied - * so the application must keep the buffer alive for the lifetime of - * the #CoglBitmap. This can be used for example with - * [method@Cogl.Framebuffer.read_pixels_into_bitmap] to read data directly - * into an application buffer with the specified rowstride. - * - * Return value: (transfer full): A new #CoglBitmap. - */ -COGL_EXPORT CoglBitmap * -cogl_bitmap_new_for_data (CoglContext *context, - int width, - int height, - CoglPixelFormat format, - int rowstride, - uint8_t *data); - -/** - * cogl_bitmap_get_format: - * @bitmap: A #CoglBitmap - * - * Return value: the #CoglPixelFormat that the data for the bitmap is in. - */ -COGL_EXPORT CoglPixelFormat -cogl_bitmap_get_format (CoglBitmap *bitmap); - -/** - * cogl_bitmap_get_width: - * @bitmap: A #CoglBitmap - * - * Return value: the width of the bitmap - */ -COGL_EXPORT int -cogl_bitmap_get_width (CoglBitmap *bitmap); - -/** - * cogl_bitmap_get_height: - * @bitmap: A #CoglBitmap - * - * Return value: the height of the bitmap - */ -COGL_EXPORT int -cogl_bitmap_get_height (CoglBitmap *bitmap); - -/** - * cogl_bitmap_get_rowstride: - * @bitmap: A #CoglBitmap - * - * Return value: the rowstride of the bitmap. This is the number of - * bytes between the address of start of one row to the address of the - * next row in the image. - */ -COGL_EXPORT int -cogl_bitmap_get_rowstride (CoglBitmap *bitmap); - -/** - * cogl_bitmap_get_buffer: - * @bitmap: A #CoglBitmap - * - * Return value: (transfer none): the #CoglPixelBuffer that this - * buffer uses for storage. - */ -COGL_EXPORT CoglPixelBuffer * -cogl_bitmap_get_buffer (CoglBitmap *bitmap); - -/** - * COGL_BITMAP_ERROR: - * - * #GError domain for bitmap errors. - */ -#define COGL_BITMAP_ERROR (cogl_bitmap_error_quark ()) - -/** - * CoglBitmapError: - * @COGL_BITMAP_ERROR_FAILED: Generic failure code, something went - * wrong. - * @COGL_BITMAP_ERROR_UNKNOWN_TYPE: Unknown image type. - * @COGL_BITMAP_ERROR_CORRUPT_IMAGE: An image file was broken somehow. - * - * Error codes that can be thrown when performing bitmap - * operations. - */ -typedef enum -{ - COGL_BITMAP_ERROR_FAILED, - COGL_BITMAP_ERROR_UNKNOWN_TYPE, - COGL_BITMAP_ERROR_CORRUPT_IMAGE -} CoglBitmapError; - -COGL_EXPORT -uint32_t cogl_bitmap_error_quark (void); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-bitmask.c b/mutter/cogl/cogl/cogl-bitmask.c deleted file mode 100644 index 17a6ed8..0000000 --- a/mutter/cogl/cogl/cogl-bitmask.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#include "config.h" - -#include -#include - -#include "cogl/cogl-bitmask.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-flags.h" - -/* This code assumes that we can cast an unsigned long to a pointer - and back without losing any data */ -_COGL_STATIC_ASSERT (sizeof (unsigned long) <= sizeof (void *), - "This toolchain breaks Cogl's assumption that it can " - "safely cast an unsigned long to a pointer without " - "losing data"); - -#define ARRAY_INDEX(bit_num) \ - ((bit_num) / (sizeof (unsigned long) * 8)) -#define BIT_INDEX(bit_num) \ - ((bit_num) & (sizeof (unsigned long) * 8 - 1)) -#define BIT_MASK(bit_num) \ - (1UL << BIT_INDEX (bit_num)) - -gboolean -_cogl_bitmask_get_from_array (const CoglBitmask *bitmask, - unsigned int bit_num) -{ - GArray *array = (GArray *) *bitmask; - - /* If the index is off the end of the array then assume the bit is - not set */ - if (bit_num >= sizeof (unsigned long) * 8 * array->len) - return FALSE; - else - return !!(g_array_index (array, unsigned long, ARRAY_INDEX (bit_num)) & - BIT_MASK (bit_num)); -} - -static void -_cogl_bitmask_convert_to_array (CoglBitmask *bitmask) -{ - GArray *array; - /* Fetch the old values */ - unsigned long old_values = _cogl_bitmask_to_bits (bitmask); - - array = g_array_new (FALSE, /* not zero-terminated */ - TRUE, /* do clear new entries */ - sizeof (unsigned long)); - /* Copy the old values back in */ - g_array_append_val (array, old_values); - - *bitmask = (struct _CoglBitmaskImaginaryType *) array; -} - -void -_cogl_bitmask_set_in_array (CoglBitmask *bitmask, - unsigned int bit_num, - gboolean value) -{ - GArray *array; - unsigned int array_index; - unsigned long new_value_mask; - - /* If the bitmask is not already an array then we need to allocate one */ - if (!_cogl_bitmask_has_array (bitmask)) - _cogl_bitmask_convert_to_array (bitmask); - - array = (GArray *) *bitmask; - - array_index = ARRAY_INDEX (bit_num); - /* Grow the array if necessary. This will clear the new data */ - if (array_index >= array->len) - g_array_set_size (array, array_index + 1); - - new_value_mask = BIT_MASK (bit_num); - - if (value) - g_array_index (array, unsigned long, array_index) |= new_value_mask; - else - g_array_index (array, unsigned long, array_index) &= ~new_value_mask; -} - -void -_cogl_bitmask_set_bits (CoglBitmask *dst, - const CoglBitmask *src) -{ - if (_cogl_bitmask_has_array (src)) - { - GArray *src_array, *dst_array; - int i; - - if (!_cogl_bitmask_has_array (dst)) - _cogl_bitmask_convert_to_array (dst); - - dst_array = (GArray *) *dst; - src_array = (GArray *) *src; - - if (dst_array->len < src_array->len) - g_array_set_size (dst_array, src_array->len); - - for (i = 0; i < src_array->len; i++) - g_array_index (dst_array, unsigned long, i) |= - g_array_index (src_array, unsigned long, i); - } - else if (_cogl_bitmask_has_array (dst)) - { - GArray *dst_array; - - dst_array = (GArray *) *dst; - - g_array_index (dst_array, unsigned long, 0) |= - _cogl_bitmask_to_bits (src); - } - else - *dst = _cogl_bitmask_from_bits (_cogl_bitmask_to_bits (dst) | - _cogl_bitmask_to_bits (src)); -} - -void -_cogl_bitmask_set_range_in_array (CoglBitmask *bitmask, - unsigned int n_bits, - gboolean value) -{ - GArray *array; - unsigned int array_index, bit_index; - - if (n_bits == 0) - return; - - /* If the bitmask is not already an array then we need to allocate one */ - if (!_cogl_bitmask_has_array (bitmask)) - _cogl_bitmask_convert_to_array (bitmask); - - array = (GArray *) *bitmask; - - /* Get the array index of the top most value that will be touched */ - array_index = ARRAY_INDEX (n_bits - 1); - /* Get the bit index of the top most value */ - bit_index = BIT_INDEX (n_bits - 1); - /* Grow the array if necessary. This will clear the new data */ - if (array_index >= array->len) - g_array_set_size (array, array_index + 1); - - if (value) - { - /* Set the bits that are touching this index */ - g_array_index (array, unsigned long, array_index) |= - ~0UL >> (sizeof (unsigned long) * 8 - 1 - bit_index); - - /* Set all of the bits in any lesser indices */ - memset (array->data, 0xff, sizeof (unsigned long) * array_index); - } - else - { - /* Clear the bits that are touching this index */ - g_array_index (array, unsigned long, array_index) &= ~1UL << bit_index; - - /* Clear all of the bits in any lesser indices */ - memset (array->data, 0x00, sizeof (unsigned long) * array_index); - } -} - -void -_cogl_bitmask_xor_bits (CoglBitmask *dst, - const CoglBitmask *src) -{ - if (_cogl_bitmask_has_array (src)) - { - GArray *src_array, *dst_array; - int i; - - if (!_cogl_bitmask_has_array (dst)) - _cogl_bitmask_convert_to_array (dst); - - dst_array = (GArray *) *dst; - src_array = (GArray *) *src; - - if (dst_array->len < src_array->len) - g_array_set_size (dst_array, src_array->len); - - for (i = 0; i < src_array->len; i++) - g_array_index (dst_array, unsigned long, i) ^= - g_array_index (src_array, unsigned long, i); - } - else if (_cogl_bitmask_has_array (dst)) - { - GArray *dst_array; - - dst_array = (GArray *) *dst; - - g_array_index (dst_array, unsigned long, 0) ^= - _cogl_bitmask_to_bits (src); - } - else - *dst = _cogl_bitmask_from_bits (_cogl_bitmask_to_bits (dst) ^ - _cogl_bitmask_to_bits (src)); -} - -void -_cogl_bitmask_clear_all_in_array (CoglBitmask *bitmask) -{ - GArray *array = (GArray *) *bitmask; - - memset (array->data, 0, sizeof (unsigned long) * array->len); -} - -void -_cogl_bitmask_foreach (const CoglBitmask *bitmask, - CoglBitmaskForeachFunc func, - void *user_data) -{ - if (_cogl_bitmask_has_array (bitmask)) - { - GArray *array = (GArray *) *bitmask; - const unsigned long *values = &g_array_index (array, unsigned long, 0); - int bit_num; - - COGL_FLAGS_FOREACH_START (values, array->len, bit_num) - { - if (!func (bit_num, user_data)) - return; - } - COGL_FLAGS_FOREACH_END; - } - else - { - unsigned long mask = _cogl_bitmask_to_bits (bitmask); - int bit_num; - - COGL_FLAGS_FOREACH_START (&mask, 1, bit_num) - { - if (!func (bit_num, user_data)) - return; - } - COGL_FLAGS_FOREACH_END; - } -} - -void -_cogl_bitmask_set_flags_array (const CoglBitmask *bitmask, - unsigned long *flags) -{ - const GArray *array = (const GArray *) *bitmask; - int i; - - for (i = 0; i < array->len; i++) - flags[i] |= g_array_index (array, unsigned long, i); -} - -int -_cogl_bitmask_popcount_in_array (const CoglBitmask *bitmask) -{ - const GArray *array = (const GArray *) *bitmask; - int pop = 0; - int i; - - for (i = 0; i < array->len; i++) - pop += _cogl_util_popcountl (g_array_index (array, unsigned long, i)); - - return pop; -} - -int -_cogl_bitmask_popcount_upto_in_array (const CoglBitmask *bitmask, - int upto) -{ - const GArray *array = (const GArray *) *bitmask; - - if (upto >= array->len * sizeof (unsigned long) * 8) - return _cogl_bitmask_popcount_in_array (bitmask); - else - { - unsigned long top_mask; - int array_index = ARRAY_INDEX (upto); - int bit_index = BIT_INDEX (upto); - int pop = 0; - int i; - - for (i = 0; i < array_index; i++) - pop += _cogl_util_popcountl (g_array_index (array, unsigned long, i)); - - top_mask = g_array_index (array, unsigned long, array_index); - - return pop + _cogl_util_popcountl (top_mask & ((1UL << bit_index) - 1)); - } -} diff --git a/mutter/cogl/cogl/cogl-bitmask.h b/mutter/cogl/cogl/cogl-bitmask.h deleted file mode 100644 index a73e68e..0000000 --- a/mutter/cogl/cogl/cogl-bitmask.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Neil Roberts - */ - -#pragma once - -#include - -#include "cogl/cogl-util.h" - -G_BEGIN_DECLS - -/* - * CoglBitmask implements a growable array of bits. A CoglBitmask can - * be allocated on the stack but it must be initialised with - * _cogl_bitmask_init() before use and then destroyed with - * _cogl_bitmask_destroy(). A CoglBitmask will try to avoid allocating - * any memory unless more than the number of bits in a long - 1 bits - * are needed. - * - * Internally a CoglBitmask is a pointer. If the least significant bit - * of the pointer is 1 then the rest of the bits are directly used as - * part of the bitmask, otherwise it is a pointer to a GArray of - * unsigned ints. This relies on the fact the g_malloc will return a - * pointer aligned to at least two bytes (so that the least - * significant bit of the address is always 0). It also assumes that - * the size of a pointer is always greater than or equal to the size - * of a long (although there is a compile time assert to verify this). - * - * If the maximum possible bit number in the set is known at compile - * time, it may make more sense to use the macros in cogl-flags.h - * instead of this type. - */ - -typedef struct _CoglBitmaskImaginaryType *CoglBitmask; - -/* These are internal helper macros */ -#define _cogl_bitmask_to_number(bitmask) \ - ((unsigned long) (*bitmask)) -#define _cogl_bitmask_to_bits(bitmask) \ - (_cogl_bitmask_to_number (bitmask) >> 1UL) -/* The least significant bit is set to mark that no array has been - allocated yet */ -#define _cogl_bitmask_from_bits(bits) \ - ((void *) ((((unsigned long) (bits)) << 1UL) | 1UL)) - -/* Internal helper macro to determine whether this bitmask has a - GArray allocated or whether the pointer is just used directly */ -#define _cogl_bitmask_has_array(bitmask) \ - (!(_cogl_bitmask_to_number (bitmask) & 1UL)) - -/* Number of bits we can use before needing to allocate an array */ -#define COGL_BITMASK_MAX_DIRECT_BITS (sizeof (unsigned long) * 8 - 1) - -/* - * _cogl_bitmask_init: - * @bitmask: A pointer to a bitmask - * - * Initialises the cogl bitmask. This must be called before any other - * bitmask functions are called. Initially all of the values are - * zero - */ -#define _cogl_bitmask_init(bitmask) \ - G_STMT_START { *(bitmask) = _cogl_bitmask_from_bits (0); } G_STMT_END - -COGL_EXPORT_TEST gboolean -_cogl_bitmask_get_from_array (const CoglBitmask *bitmask, - unsigned int bit_num); - -COGL_EXPORT_TEST void -_cogl_bitmask_set_in_array (CoglBitmask *bitmask, - unsigned int bit_num, - gboolean value); - -COGL_EXPORT_TEST void -_cogl_bitmask_set_range_in_array (CoglBitmask *bitmask, - unsigned int n_bits, - gboolean value); - -COGL_EXPORT_TEST void -_cogl_bitmask_clear_all_in_array (CoglBitmask *bitmask); - -void -_cogl_bitmask_set_flags_array (const CoglBitmask *bitmask, - unsigned long *flags); - -COGL_EXPORT_TEST int -_cogl_bitmask_popcount_in_array (const CoglBitmask *bitmask); - -COGL_EXPORT_TEST int -_cogl_bitmask_popcount_upto_in_array (const CoglBitmask *bitmask, - int upto); - -/* - * cogl_bitmask_set_bits: - * @dst: The bitmask to modify - * @src: The bitmask to copy bits from - * - * This makes sure that all of the bits that are set in @src are also - * set in @dst. Any unset bits in @src are left alone in @dst. - */ -COGL_EXPORT_TEST void -_cogl_bitmask_set_bits (CoglBitmask *dst, - const CoglBitmask *src); - -/* - * cogl_bitmask_xor_bits: - * @dst: The bitmask to modify - * @src: The bitmask to copy bits from - * - * For every bit that is set in src, the corresponding bit in dst is - * inverted. - */ -COGL_EXPORT_TEST void -_cogl_bitmask_xor_bits (CoglBitmask *dst, - const CoglBitmask *src); - -/* The foreach function can return FALSE to stop iteration */ -typedef gboolean (* CoglBitmaskForeachFunc) (int bit_num, void *user_data); - -/* - * cogl_bitmask_foreach: - * @bitmask: A pointer to a bitmask - * @func: A callback function - * @user_data: A pointer to pass to the callback - * - * This calls @func for each bit that is set in @bitmask. - */ -COGL_EXPORT_TEST void -_cogl_bitmask_foreach (const CoglBitmask *bitmask, - CoglBitmaskForeachFunc func, - void *user_data); - -/* - * _cogl_bitmask_get: - * @bitmask: A pointer to a bitmask - * @bit_num: A bit number - * - * Return value: whether bit number @bit_num is set in @bitmask - */ -static inline gboolean -_cogl_bitmask_get (const CoglBitmask *bitmask, unsigned int bit_num) -{ - if (_cogl_bitmask_has_array (bitmask)) - return _cogl_bitmask_get_from_array (bitmask, bit_num); - else if (bit_num >= COGL_BITMASK_MAX_DIRECT_BITS) - return FALSE; - else - return !!(_cogl_bitmask_to_bits (bitmask) & (1UL << bit_num)); -} - -/* - * _cogl_bitmask_set: - * @bitmask: A pointer to a bitmask - * @bit_num: A bit number - * @value: The new value - * - * Sets or resets a bit number @bit_num in @bitmask according to @value. - */ -static inline void -_cogl_bitmask_set (CoglBitmask *bitmask, unsigned int bit_num, gboolean value) -{ - if (_cogl_bitmask_has_array (bitmask) || - bit_num >= COGL_BITMASK_MAX_DIRECT_BITS) - _cogl_bitmask_set_in_array (bitmask, bit_num, value); - else if (value) - *bitmask = _cogl_bitmask_from_bits (_cogl_bitmask_to_bits (bitmask) | - (1UL << bit_num)); - else - *bitmask = _cogl_bitmask_from_bits (_cogl_bitmask_to_bits (bitmask) & - ~(1UL << bit_num)); -} - -/* - * _cogl_bitmask_set_range: - * @bitmask: A pointer to a bitmask - * @n_bits: The number of bits to set - * @value: The value to set - * - * Sets the first @n_bits in @bitmask to @value. - */ -static inline void -_cogl_bitmask_set_range (CoglBitmask *bitmask, - unsigned int n_bits, - gboolean value) -{ - if (_cogl_bitmask_has_array (bitmask) || - n_bits > COGL_BITMASK_MAX_DIRECT_BITS) - _cogl_bitmask_set_range_in_array (bitmask, n_bits, value); - else if (value) - *bitmask = _cogl_bitmask_from_bits (_cogl_bitmask_to_bits (bitmask) | - ~(~0UL << n_bits)); - else - *bitmask = _cogl_bitmask_from_bits (_cogl_bitmask_to_bits (bitmask) & - (~0UL << n_bits)); -} - -/* - * _cogl_bitmask_destroy: - * @bitmask: A pointer to a bitmask - * - * Destroys any resources allocated by the bitmask - */ -static inline void -_cogl_bitmask_destroy (CoglBitmask *bitmask) -{ - if (_cogl_bitmask_has_array (bitmask)) - g_array_free ((GArray *) *bitmask, TRUE); -} - -/* - * _cogl_bitmask_clear_all: - * @bitmask: A pointer to a bitmask - * - * Clears all the bits in a bitmask without destroying any resources. - */ -static inline void -_cogl_bitmask_clear_all (CoglBitmask *bitmask) -{ - if (_cogl_bitmask_has_array (bitmask)) - _cogl_bitmask_clear_all_in_array (bitmask); - else - *bitmask = _cogl_bitmask_from_bits (0); -} - -/* - * _cogl_bitmask_set_flags: - * @bitmask: A pointer to a bitmask - * @flags: An array of flags - * - * Bitwise or's the bits from @bitmask into the flags array (see - * cogl-flags) pointed to by @flags. - */ -static inline void -_cogl_bitmask_set_flags (const CoglBitmask *bitmask, - unsigned long *flags) -{ - if (_cogl_bitmask_has_array (bitmask)) - _cogl_bitmask_set_flags_array (bitmask, flags); - else - flags[0] |= _cogl_bitmask_to_bits (bitmask); -} - -/* - * _cogl_bitmask_popcount: - * @bitmask: A pointer to a bitmask - * - * Counts the number of bits that are set in the bitmask. - * - * Return value: the number of bits set in @bitmask. - */ -static inline int -_cogl_bitmask_popcount (const CoglBitmask *bitmask) -{ - return (_cogl_bitmask_has_array (bitmask) ? - _cogl_bitmask_popcount_in_array (bitmask) : - _cogl_util_popcountl (_cogl_bitmask_to_bits (bitmask))); -} - -/* - * _cogl_bitmask_popcount: - * @Bitmask: A pointer to a bitmask - * @upto: The maximum bit index to consider - * - * Counts the number of bits that are set and have an index which is - * less than @upto. - * - * Return value: the number of bits set in @bitmask that are less than @upto. - */ -static inline int -_cogl_bitmask_popcount_upto (const CoglBitmask *bitmask, - int upto) -{ - if (_cogl_bitmask_has_array (bitmask)) - return _cogl_bitmask_popcount_upto_in_array (bitmask, upto); - else if (upto >= (int) COGL_BITMASK_MAX_DIRECT_BITS) - return _cogl_util_popcountl (_cogl_bitmask_to_bits (bitmask)); - else - return _cogl_util_popcountl (_cogl_bitmask_to_bits (bitmask) & - ((1UL << upto) - 1)); -} - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-blend-string.c b/mutter/cogl/cogl/cogl-blend-string.c deleted file mode 100644 index 50af350..0000000 --- a/mutter/cogl/cogl/cogl-blend-string.c +++ /dev/null @@ -1,972 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include -#include - -#include - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-debug.h" -#include "cogl/cogl-blend-string.h" - -typedef enum _ParserState -{ - PARSER_STATE_EXPECT_DEST_CHANNELS, - PARSER_STATE_SCRAPING_DEST_CHANNELS, - PARSER_STATE_EXPECT_FUNCTION_NAME, - PARSER_STATE_SCRAPING_FUNCTION_NAME, - PARSER_STATE_EXPECT_ARG_START, - PARSER_STATE_EXPECT_STATEMENT_END -} ParserState; - -typedef enum _ParserArgState -{ - PARSER_ARG_STATE_START, - PARSER_ARG_STATE_EXPECT_MINUS, - PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME, - PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME, - PARSER_ARG_STATE_MAYBE_COLOR_MASK, - PARSER_ARG_STATE_SCRAPING_MASK, - PARSER_ARG_STATE_MAYBE_MULT, - PARSER_ARG_STATE_EXPECT_OPEN_PAREN, - PARSER_ARG_STATE_EXPECT_FACTOR, - PARSER_ARG_STATE_MAYBE_SRC_ALPHA_SATURATE, - PARSER_ARG_STATE_MAYBE_MINUS, - PARSER_ARG_STATE_EXPECT_CLOSE_PAREN, - PARSER_ARG_STATE_EXPECT_END -} ParserArgState; - - -#define DEFINE_COLOR_SOURCE(NAME, NAME_LEN) \ - {/*.type = */COGL_BLEND_STRING_COLOR_SOURCE_ ## NAME, \ - /*.name = */#NAME, \ - /*.name_len = */NAME_LEN} - -static CoglBlendStringColorSourceInfo blending_color_sources[] = { - DEFINE_COLOR_SOURCE (SRC_COLOR, 9), - DEFINE_COLOR_SOURCE (DST_COLOR, 9), - DEFINE_COLOR_SOURCE (CONSTANT, 8) -}; - -static CoglBlendStringColorSourceInfo tex_combine_color_sources[] = { - DEFINE_COLOR_SOURCE (TEXTURE, 7), - /* DEFINE_COLOR_SOURCE (TEXTURE_N, *) - handled manually */ - DEFINE_COLOR_SOURCE (PRIMARY, 7), - DEFINE_COLOR_SOURCE (CONSTANT, 8), - DEFINE_COLOR_SOURCE (PREVIOUS, 8) -}; - -static CoglBlendStringColorSourceInfo tex_combine_texture_n_color_source = { - /*.type = */COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N, - /*.name = */"TEXTURE_N", - /*.name_len = */0 -}; - -#undef DEFINE_COLOR_SOURCE - -#define DEFINE_FUNCTION(NAME, NAME_LEN, ARGC) \ - { /*.type = */COGL_BLEND_STRING_FUNCTION_ ## NAME, \ - /*.name = */#NAME, \ - /*.name_len = */NAME_LEN, \ - /*.argc = */ARGC } - -/* NB: These must be sorted so any name that's a subset of another - * comes later than the longer name. */ -static CoglBlendStringFunctionInfo tex_combine_functions[] = { - DEFINE_FUNCTION (REPLACE, 7, 1), - DEFINE_FUNCTION (MODULATE, 8, 2), - DEFINE_FUNCTION (ADD_SIGNED, 10, 2), - DEFINE_FUNCTION (ADD, 3, 2), - DEFINE_FUNCTION (INTERPOLATE, 11, 3), - DEFINE_FUNCTION (SUBTRACT, 8, 2), - DEFINE_FUNCTION (DOT3_RGBA, 9, 2), - DEFINE_FUNCTION (DOT3_RGB, 8, 2) -}; - -static CoglBlendStringFunctionInfo blend_functions[] = { - DEFINE_FUNCTION (ADD, 3, 2) -}; - -#undef DEFINE_FUNCTION - -uint32_t -cogl_blend_string_error_quark (void) -{ - return g_quark_from_static_string ("cogl-blend-string-error-quark"); -} - -void -_cogl_blend_string_split_rgba_statement (CoglBlendStringStatement *statement, - CoglBlendStringStatement *rgb, - CoglBlendStringStatement *a) -{ - int i; - - memcpy (rgb, statement, sizeof (CoglBlendStringStatement)); - memcpy (a, statement, sizeof (CoglBlendStringStatement)); - - rgb->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB; - a->mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA; - - for (i = 0; i < statement->function->argc; i++) - { - CoglBlendStringArgument *arg = &statement->args[i]; - CoglBlendStringArgument *rgb_arg = &rgb->args[i]; - CoglBlendStringArgument *a_arg = &a->args[i]; - - if (arg->source.mask == COGL_BLEND_STRING_CHANNEL_MASK_RGBA) - { - rgb_arg->source.mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB; - a_arg->source.mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA; - } - - if (arg->factor.is_color && - arg->factor.source.mask == COGL_BLEND_STRING_CHANNEL_MASK_RGBA) - { - rgb_arg->factor.source.mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB; - a_arg->factor.source.mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA; - } - } -} - -static gboolean -validate_tex_combine_statements (CoglBlendStringStatement *statements, - int n_statements, - GError **error) -{ - int i, j; - const char *error_string; - CoglBlendStringError detail = COGL_BLEND_STRING_ERROR_INVALID_ERROR; - - for (i = 0; i < n_statements; i++) - { - for (j = 0; j < statements[i].function->argc; j++) - { - CoglBlendStringArgument *arg = &statements[i].args[j]; - if (arg->source.is_zero) - { - error_string = "You can't use the constant '0' as a texture " - "combine argument"; - goto error; - } - if (!arg->factor.is_one) - { - error_string = "Argument factors are only relevant to blending " - "not texture combining"; - goto error; - } - } - } - - return TRUE; - -error: - g_set_error (error, COGL_BLEND_STRING_ERROR, detail, - "Invalid texture combine string: %s", error_string); - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - g_debug ("Invalid texture combine string: %s", - error_string); - } - return FALSE; -} - -static gboolean -validate_blend_statements (CoglBlendStringStatement *statements, - int n_statements, - GError **error) -{ - int i, j; - const char *error_string; - CoglBlendStringError detail = COGL_BLEND_STRING_ERROR_INVALID_ERROR; - - _COGL_GET_CONTEXT (ctx, 0); - - for (i = 0; i < n_statements; i++) - for (j = 0; j < statements[i].function->argc; j++) - { - CoglBlendStringArgument *arg = &statements[i].args[j]; - - if (arg->source.is_zero) - continue; - - if ((j == 0 && - arg->source.info->type != - COGL_BLEND_STRING_COLOR_SOURCE_SRC_COLOR) - || (j == 1 && - arg->source.info->type != - COGL_BLEND_STRING_COLOR_SOURCE_DST_COLOR)) - { - error_string = "For blending you must always use SRC_COLOR " - "for arg0 and DST_COLOR for arg1"; - goto error; - } - } - - return TRUE; - -error: - g_set_error (error, COGL_BLEND_STRING_ERROR, detail, - "Invalid blend string: %s", error_string); - return FALSE; -} - -static gboolean -validate_statements_for_context (CoglBlendStringStatement *statements, - int n_statements, - CoglBlendStringContext context, - GError **error) -{ - const char *error_string; - - if (n_statements == 1) - { - if (statements[0].mask == COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) - { - error_string = "You need to also give a blend statement for the RGB" - "channels"; - goto error; - } - else if (statements[0].mask == COGL_BLEND_STRING_CHANNEL_MASK_RGB) - { - error_string = "You need to also give a blend statement for the " - "Alpha channel"; - goto error; - } - } - - if (context == COGL_BLEND_STRING_CONTEXT_BLENDING) - return validate_blend_statements (statements, n_statements, error); - else - return validate_tex_combine_statements (statements, n_statements, error); - -error: - g_set_error (error, COGL_BLEND_STRING_ERROR, - COGL_BLEND_STRING_ERROR_INVALID_ERROR, - "Invalid %s string: %s", - context == COGL_BLEND_STRING_CONTEXT_BLENDING ? - "blend" : "texture combine", - error_string); - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - g_debug ("Invalid %s string: %s", - context == COGL_BLEND_STRING_CONTEXT_BLENDING ? - "blend" : "texture combine", - error_string); - } - - return FALSE; -} - -static void -print_argument (CoglBlendStringArgument *arg) -{ - const char *mask_names[] = { - "RGB", - "A", - "RGBA" - }; - - g_print (" Arg:\n"); - g_print (" is zero = %s\n", arg->source.is_zero ? "yes" : "no"); - if (!arg->source.is_zero) - { - g_print (" color source = %s\n", arg->source.info->name); - g_print (" one minus = %s\n", arg->source.one_minus ? "yes" : "no"); - g_print (" mask = %s\n", mask_names[arg->source.mask]); - g_print (" texture = %d\n", arg->source.texture); - g_print ("\n"); - g_print (" factor is_one = %s\n", arg->factor.is_one ? "yes" : "no"); - g_print (" factor is_src_alpha_saturate = %s\n", - arg->factor.is_src_alpha_saturate ? "yes" : "no"); - g_print (" factor is_color = %s\n", arg->factor.is_color ? "yes" : "no"); - if (arg->factor.is_color) - { - g_print (" factor color:is zero = %s\n", - arg->factor.source.is_zero ? "yes" : "no"); - g_print (" factor color:color source = %s\n", - arg->factor.source.info->name); - g_print (" factor color:one minus = %s\n", - arg->factor.source.one_minus ? "yes" : "no"); - g_print (" factor color:mask = %s\n", - mask_names[arg->factor.source.mask]); - g_print (" factor color:texture = %d\n", - arg->factor.source.texture); - } - } -} - -static void -print_statement (int num, CoglBlendStringStatement *statement) -{ - const char *mask_names[] = { - "RGB", - "A", - "RGBA" - }; - int i; - g_print ("Statement %d:\n", num); - g_print (" Destination channel mask = %s\n", - mask_names[statement->mask]); - g_print (" Function = %s\n", statement->function->name); - for (i = 0; i < statement->function->argc; i++) - print_argument (&statement->args[i]); -} - -static const CoglBlendStringFunctionInfo * -get_function_info (const char *mark, - const char *p, - CoglBlendStringContext context) -{ - size_t len = p - mark; - CoglBlendStringFunctionInfo *functions; - size_t array_len; - int i; - - if (context == COGL_BLEND_STRING_CONTEXT_BLENDING) - { - functions = blend_functions; - array_len = G_N_ELEMENTS (blend_functions); - } - else - { - functions = tex_combine_functions; - array_len = G_N_ELEMENTS (tex_combine_functions); - } - - for (i = 0; i < array_len; i++) - { - if (len >= functions[i].name_len - && strncmp (mark, functions[i].name, functions[i].name_len) == 0) - return &functions[i]; - } - return NULL; -} - -static const CoglBlendStringColorSourceInfo * -get_color_src_info (const char *mark, - const char *p, - CoglBlendStringContext context) -{ - size_t len = p - mark; - CoglBlendStringColorSourceInfo *sources; - size_t array_len; - int i; - - if (context == COGL_BLEND_STRING_CONTEXT_BLENDING) - { - sources = blending_color_sources; - array_len = G_N_ELEMENTS (blending_color_sources); - } - else - { - sources = tex_combine_color_sources; - array_len = G_N_ELEMENTS (tex_combine_color_sources); - } - - if (len >= 8 && - strncmp (mark, "TEXTURE_", 8) == 0 && - g_ascii_isdigit (mark[8])) - { - return &tex_combine_texture_n_color_source; - } - - for (i = 0; i < array_len; i++) - { - if (len >= sources[i].name_len - && strncmp (mark, sources[i].name, sources[i].name_len) == 0) - return &sources[i]; - } - - return NULL; -} - -static gboolean -is_symbol_char (const char c) -{ - return (g_ascii_isalpha (c) || c == '_') ? TRUE : FALSE; -} - -static gboolean -is_alphanum_char (const char c) -{ - return (g_ascii_isalnum (c) || c == '_') ? TRUE : FALSE; -} - -static gboolean -parse_argument (const char *string, /* original user string */ - const char **ret_p, /* start of argument IN:OUT */ - const CoglBlendStringStatement *statement, - int current_arg, - CoglBlendStringArgument *arg, /* OUT */ - CoglBlendStringContext context, - GError **error) -{ - const char *p = *ret_p; - const char *mark = NULL; - const char *error_string = NULL; - ParserArgState state = PARSER_ARG_STATE_START; - gboolean parsing_factor = FALSE; - gboolean implicit_factor_brace = FALSE; - - arg->source.is_zero = FALSE; - arg->source.info = NULL; - arg->source.texture = 0; - arg->source.one_minus = FALSE; - arg->source.mask = statement->mask; - - arg->factor.is_one = FALSE; - arg->factor.is_color = FALSE; - arg->factor.is_src_alpha_saturate = FALSE; - - arg->factor.source.is_zero = FALSE; - arg->factor.source.info = NULL; - arg->factor.source.texture = 0; - arg->factor.source.one_minus = FALSE; - arg->factor.source.mask = statement->mask; - - do - { - if (g_ascii_isspace (*p)) - continue; - - if (*p == '\0') - { - error_string = "Unexpected end of string while parsing argument"; - goto error; - } - - switch (state) - { - case PARSER_ARG_STATE_START: - if (*p == '1') - state = PARSER_ARG_STATE_EXPECT_MINUS; - else if (*p == '0') - { - arg->source.is_zero = TRUE; - state = PARSER_ARG_STATE_EXPECT_END; - } - else - { - p--; /* backtrack */ - state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; - } - continue; - - case PARSER_ARG_STATE_EXPECT_MINUS: - if (*p != '-') - { - error_string = "expected a '-' following the 1"; - goto error; - } - arg->source.one_minus = TRUE; - state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; - continue; - - case PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME: - if (!is_symbol_char (*p)) - { - error_string = "expected a color source name"; - goto error; - } - state = PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME; - mark = p; - if (parsing_factor) - arg->factor.is_color = TRUE; - - G_GNUC_FALLTHROUGH; - case PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME: - if (!is_symbol_char (*p)) - { - CoglBlendStringColorSource *source = - parsing_factor ? &arg->factor.source : &arg->source; - source->info = get_color_src_info (mark, p, context); - if (!source->info) - { - error_string = "Unknown color source name"; - goto error; - } - if (source->info->type == - COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N) - { - char *endp; - source->texture = - strtoul (&mark[strlen ("TEXTURE_")], &endp, 10); - if (mark == endp) - { - error_string = "invalid texture number given with " - "TEXTURE_N color source"; - goto error; - } - p = endp; - } - state = PARSER_ARG_STATE_MAYBE_COLOR_MASK; - } - else - continue; - - G_GNUC_FALLTHROUGH; - case PARSER_ARG_STATE_MAYBE_COLOR_MASK: - if (*p != '[') - { - p--; /* backtrack */ - if (!parsing_factor) - state = PARSER_ARG_STATE_MAYBE_MULT; - else - state = PARSER_ARG_STATE_EXPECT_END; - continue; - } - state = PARSER_ARG_STATE_SCRAPING_MASK; - mark = p; - - G_GNUC_FALLTHROUGH; - case PARSER_ARG_STATE_SCRAPING_MASK: - if (*p == ']') - { - size_t len = p - mark; - CoglBlendStringColorSource *source = - parsing_factor ? &arg->factor.source : &arg->source; - - if (len == 5 && strncmp (mark, "[RGBA", len) == 0) - { - if (statement->mask != COGL_BLEND_STRING_CHANNEL_MASK_RGBA) - { - error_string = "You can't use an RGBA color mask if the " - "statement hasn't also got an RGBA= mask"; - goto error; - } - source->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGBA; - } - else if (len == 4 && strncmp (mark, "[RGB", len) == 0) - source->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB; - else if (len == 2 && strncmp (mark, "[A", len) == 0) - source->mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA; - else - { - error_string = "Expected a channel mask of [RGBA]" - "[RGB] or [A]"; - goto error; - } - if (parsing_factor) - state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; - else - state = PARSER_ARG_STATE_MAYBE_MULT; - } - continue; - - case PARSER_ARG_STATE_EXPECT_OPEN_PAREN: - if (*p != '(') - { - if (is_alphanum_char (*p)) - { - p--; /* compensate for implicit brace and ensure this - * char gets considered part of the blend factor */ - implicit_factor_brace = TRUE; - } - else - { - error_string = "Expected '(' around blend factor or alpha " - "numeric character for blend factor name"; - goto error; - } - } - else - implicit_factor_brace = FALSE; - parsing_factor = TRUE; - state = PARSER_ARG_STATE_EXPECT_FACTOR; - continue; - - case PARSER_ARG_STATE_EXPECT_FACTOR: - if (*p == '1') - state = PARSER_ARG_STATE_MAYBE_MINUS; - else if (*p == '0') - { - arg->source.is_zero = TRUE; - state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; - } - else - { - state = PARSER_ARG_STATE_MAYBE_SRC_ALPHA_SATURATE; - mark = p; - } - continue; - - case PARSER_ARG_STATE_MAYBE_SRC_ALPHA_SATURATE: - if (!is_symbol_char (*p)) - { - size_t len = p - mark; - if (len >= strlen ("SRC_ALPHA_SATURATE") && - strncmp (mark, "SRC_ALPHA_SATURATE", len) == 0) - { - arg->factor.is_src_alpha_saturate = TRUE; - state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; - } - else - { - state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; - p = mark - 1; /* backtrack */ - } - } - continue; - - case PARSER_ARG_STATE_MAYBE_MINUS: - if (*p == '-') - { - if (implicit_factor_brace) - { - error_string = "Expected ( ) braces around blend factor with " - "a subtraction"; - goto error; - } - arg->factor.source.one_minus = TRUE; - state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; - } - else - { - arg->factor.is_one = TRUE; - state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; - } - continue; - - case PARSER_ARG_STATE_EXPECT_CLOSE_PAREN: - if (implicit_factor_brace) - { - p--; - state = PARSER_ARG_STATE_EXPECT_END; - continue; - } - if (*p != ')') - { - error_string = "Expected closing parenthesis after blend factor"; - goto error; - } - state = PARSER_ARG_STATE_EXPECT_END; - continue; - - case PARSER_ARG_STATE_MAYBE_MULT: - if (*p == '*') - { - state = PARSER_ARG_STATE_EXPECT_OPEN_PAREN; - continue; - } - arg->factor.is_one = TRUE; - state = PARSER_ARG_STATE_EXPECT_END; - - G_GNUC_FALLTHROUGH; - case PARSER_ARG_STATE_EXPECT_END: - if (*p != ',' && *p != ')') - { - error_string = "expected , or )"; - goto error; - } - - *ret_p = p - 1; - return TRUE; - } - } - while (p++); - -error: - { - int offset = p - string; - g_set_error (error, - COGL_BLEND_STRING_ERROR, - COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR, - "Syntax error for argument %d at offset %d: %s", - current_arg, - offset, - error_string); - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - g_debug ("Syntax error for argument %d at offset %d: %s", - current_arg, offset, error_string); - } - return FALSE; - } -} - -int -_cogl_blend_string_compile (const char *string, - CoglBlendStringContext context, - CoglBlendStringStatement *statements, - GError **error) -{ - const char *p = string; - const char *mark = NULL; - const char *error_string; - ParserState state = PARSER_STATE_EXPECT_DEST_CHANNELS; - CoglBlendStringStatement *statement = statements; - int current_statement = 0; - int current_arg = 0; - int remaining_argc = 0; - -#if 0 - COGL_DEBUG_SET_FLAG (COGL_DEBUG_BLEND_STRINGS); -#endif - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - COGL_NOTE (BLEND_STRINGS, "Compiling %s string:\n%s\n", - context == COGL_BLEND_STRING_CONTEXT_BLENDING ? - "blend" : "texture combine", - string); - } - - do - { - if (g_ascii_isspace (*p)) - continue; - - if (*p == '\0') - { - switch (state) - { - case PARSER_STATE_EXPECT_DEST_CHANNELS: - if (current_statement != 0) - goto finished; - error_string = "Empty statement"; - goto error; - case PARSER_STATE_SCRAPING_DEST_CHANNELS: - error_string = "Expected an '=' following the destination " - "channel mask"; - goto error; - case PARSER_STATE_EXPECT_FUNCTION_NAME: - error_string = "Expected a function name"; - goto error; - case PARSER_STATE_SCRAPING_FUNCTION_NAME: - error_string = "Expected parenthesis after the function name"; - goto error; - case PARSER_STATE_EXPECT_ARG_START: - error_string = "Expected to find the start of an argument"; - goto error; - case PARSER_STATE_EXPECT_STATEMENT_END: - error_string = "Expected closing parenthesis for statement"; - goto error; - } - } - - switch (state) - { - case PARSER_STATE_EXPECT_DEST_CHANNELS: - mark = p; - state = PARSER_STATE_SCRAPING_DEST_CHANNELS; - - G_GNUC_FALLTHROUGH; - case PARSER_STATE_SCRAPING_DEST_CHANNELS: - if (*p != '=') - continue; - if (strncmp (mark, "RGBA", 4) == 0) - statement->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGBA; - else if (strncmp (mark, "RGB", 3) == 0) - statement->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB; - else if (strncmp (mark, "A", 1) == 0) - statement->mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA; - else - { - error_string = "Unknown destination channel mask; " - "expected RGBA=, RGB= or A="; - goto error; - } - state = PARSER_STATE_EXPECT_FUNCTION_NAME; - continue; - - case PARSER_STATE_EXPECT_FUNCTION_NAME: - mark = p; - state = PARSER_STATE_SCRAPING_FUNCTION_NAME; - - G_GNUC_FALLTHROUGH; - case PARSER_STATE_SCRAPING_FUNCTION_NAME: - if (*p != '(') - { - if (!is_alphanum_char (*p)) - { - error_string = "non alpha numeric character in function" - "name"; - goto error; - } - continue; - } - statement->function = get_function_info (mark, p, context); - if (!statement->function) - { - error_string = "Unknown function name"; - goto error; - } - remaining_argc = statement->function->argc; - current_arg = 0; - state = PARSER_STATE_EXPECT_ARG_START; - - G_GNUC_FALLTHROUGH; - case PARSER_STATE_EXPECT_ARG_START: - if (*p != '(' && *p != ',') - continue; - if (remaining_argc) - { - p++; /* parse_argument expects to see the first char of the arg */ - if (!parse_argument (string, &p, statement, - current_arg, &statement->args[current_arg], - context, error)) - return 0; - current_arg++; - remaining_argc--; - } - if (!remaining_argc) - state = PARSER_STATE_EXPECT_STATEMENT_END; - continue; - - case PARSER_STATE_EXPECT_STATEMENT_END: - if (*p != ')') - { - error_string = "Expected end of statement"; - goto error; - } - state = PARSER_STATE_EXPECT_DEST_CHANNELS; - if (current_statement++ == 1) - goto finished; - statement = &statements[current_statement]; - } - } - while (p++); - -finished: - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - if (current_statement > 0) - print_statement (0, &statements[0]); - if (current_statement > 1) - print_statement (1, &statements[1]); - } - - if (!validate_statements_for_context (statements, - current_statement, - context, - error)) - return 0; - - return current_statement; - -error: - { - int offset = p - string; - g_set_error (error, - COGL_BLEND_STRING_ERROR, - COGL_BLEND_STRING_ERROR_PARSE_ERROR, - "Syntax error at offset %d: %s", - offset, - error_string); - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - g_debug ("Syntax error at offset %d: %s", - offset, error_string); - } - return 0; - } -} - -/* - * INTERNAL TESTING CODE ... - */ - -struct _TestString -{ - const char *string; - CoglBlendStringContext context; -}; - -/* FIXME: this should probably be moved to a unit test */ -int -_cogl_blend_string_test (void); - -int -_cogl_blend_string_test (void) -{ - struct _TestString strings[] = { - {" A = MODULATE ( TEXTURE[RGB], PREVIOUS[A], PREVIOUS[A] ) ", - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE }, - {" RGB = MODULATE ( TEXTURE[RGB], PREVIOUS[A] ) ", - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE }, - {"A=ADD(TEXTURE[A],PREVIOUS[RGB])", - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE }, - {"A=ADD(TEXTURE[A],PREVIOUS[RGB])", - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE }, - - {"RGBA = ADD(SRC_COLOR*(SRC_COLOR[A]), DST_COLOR*(1-SRC_COLOR[A]))", - COGL_BLEND_STRING_CONTEXT_BLENDING }, - {"RGB = ADD(SRC_COLOR, DST_COLOR*(0))", - COGL_BLEND_STRING_CONTEXT_BLENDING }, - {"RGB = ADD(SRC_COLOR, 0)", - COGL_BLEND_STRING_CONTEXT_BLENDING }, - {"RGB = ADD()", - COGL_BLEND_STRING_CONTEXT_BLENDING }, - {"RGB = ADD(SRC_COLOR, 0, DST_COLOR)", - COGL_BLEND_STRING_CONTEXT_BLENDING }, - {NULL} - }; - int i; - - GError *error = NULL; - for (i = 0; strings[i].string; i++) - { - CoglBlendStringStatement statements[2]; - int count = _cogl_blend_string_compile (strings[i].string, - strings[i].context, - statements, - &error); - if (!count) - { - g_print ("Failed to parse string:\n%s\n%s\n", - strings[i].string, - error->message); - g_error_free (error); - error = NULL; - continue; - } - g_print ("Original:\n"); - g_print ("%s\n", strings[i].string); - if (count > 0) - print_statement (0, &statements[0]); - if (count > 1) - print_statement (1, &statements[1]); - } - - return 0; -} - diff --git a/mutter/cogl/cogl/cogl-blend-string.h b/mutter/cogl/cogl/cogl-blend-string.h deleted file mode 100644 index 08f6ab2..0000000 --- a/mutter/cogl/cogl/cogl-blend-string.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include -#include - -typedef enum _CoglBlendStringContext -{ - COGL_BLEND_STRING_CONTEXT_BLENDING, - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE -} CoglBlendStringContext; - -/* NB: debug stringify code will get upset if these - * are re-ordered */ -typedef enum _CoglBlendStringChannelMask -{ - COGL_BLEND_STRING_CHANNEL_MASK_RGB, - COGL_BLEND_STRING_CHANNEL_MASK_ALPHA, - COGL_BLEND_STRING_CHANNEL_MASK_RGBA -} CoglBlendStringChannelMask; - -typedef enum _CoglBlendStringColorSourceType -{ - /* blending */ - COGL_BLEND_STRING_COLOR_SOURCE_SRC_COLOR, - COGL_BLEND_STRING_COLOR_SOURCE_DST_COLOR, - - /* shared */ - COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT, - - /* texture combining */ - COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE, - COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N, - COGL_BLEND_STRING_COLOR_SOURCE_PRIMARY, - COGL_BLEND_STRING_COLOR_SOURCE_PREVIOUS -} CoglBlendStringColorSourceType; - -typedef struct _CoglBlendStringColorSourceInfo -{ - CoglBlendStringColorSourceType type; - const char *name; - size_t name_len; -} CoglBlendStringColorSourceInfo; - -typedef struct _CoglBlendStringColorSource -{ - gboolean is_zero; - const CoglBlendStringColorSourceInfo *info; - int texture; /* for the TEXTURE_N color source */ - gboolean one_minus; - CoglBlendStringChannelMask mask; -} CoglBlendStringColorSource; - -typedef struct _CoglBlendStringFactor -{ - gboolean is_one; - gboolean is_src_alpha_saturate; - gboolean is_color; - CoglBlendStringColorSource source; -} CoglBlendStringFactor; - -typedef struct _CoglBlendStringArgument -{ - CoglBlendStringColorSource source; - CoglBlendStringFactor factor; -} CoglBlendStringArgument; - -typedef enum _CoglBlendStringFunctionType -{ - /* shared */ - COGL_BLEND_STRING_FUNCTION_ADD, - - /* texture combine only */ - COGL_BLEND_STRING_FUNCTION_REPLACE, - COGL_BLEND_STRING_FUNCTION_MODULATE, - COGL_BLEND_STRING_FUNCTION_ADD_SIGNED, - COGL_BLEND_STRING_FUNCTION_INTERPOLATE, - COGL_BLEND_STRING_FUNCTION_SUBTRACT, - COGL_BLEND_STRING_FUNCTION_DOT3_RGB, - COGL_BLEND_STRING_FUNCTION_DOT3_RGBA -} CoglBlendStringFunctionType; - -typedef struct _CoglBlendStringFunctionInfo -{ - enum _CoglBlendStringFunctionType type; - const char *name; - size_t name_len; - int argc; -} CoglBlendStringFunctionInfo; - -typedef struct _CoglBlendStringStatement -{ - CoglBlendStringChannelMask mask; - const CoglBlendStringFunctionInfo *function; - CoglBlendStringArgument args[3]; -} CoglBlendStringStatement; - - -gboolean -_cogl_blend_string_compile (const char *string, - CoglBlendStringContext context, - CoglBlendStringStatement *statements, - GError **error); - -void -_cogl_blend_string_split_rgba_statement (CoglBlendStringStatement *statement, - CoglBlendStringStatement *rgb, - CoglBlendStringStatement *a); diff --git a/mutter/cogl/cogl/cogl-blit.c b/mutter/cogl/cogl/cogl-blit.c deleted file mode 100644 index 735f82a..0000000 --- a/mutter/cogl/cogl/cogl-blit.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Neil Roberts - */ - -#include "config.h" - -#include - -#include "cogl/cogl-util.h" -#include "cogl/cogl-blit.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-texture-2d-private.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl1-context.h" - -static const CoglBlitMode *_cogl_blit_default_mode = NULL; - -static gboolean -_cogl_blit_texture_render_begin (CoglBlitData *data) -{ - CoglContext *ctx = cogl_texture_get_context (data->src_tex); - CoglOffscreen *offscreen; - CoglFramebuffer *fb; - CoglPipeline *pipeline; - unsigned int dst_width, dst_height; - GError *ignore_error = NULL; - - offscreen = _cogl_offscreen_new_with_texture_full - (data->dst_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */); - - fb = COGL_FRAMEBUFFER (offscreen); - if (!cogl_framebuffer_allocate (fb, &ignore_error)) - { - g_error_free (ignore_error); - g_object_unref (fb); - return FALSE; - } - - data->dest_fb = fb; - - dst_width = cogl_texture_get_width (data->dst_tex); - dst_height = cogl_texture_get_height (data->dst_tex); - - /* Set up an orthographic projection so we can use pixel - coordinates to render to the texture */ - cogl_framebuffer_orthographic (fb, - 0, 0, dst_width, dst_height, - -1 /* near */, 1 /* far */); - - /* We cache a pipeline used for migrating on to the context so - that it doesn't have to continuously regenerate a shader - program */ - if (ctx->blit_texture_pipeline == NULL) - { - ctx->blit_texture_pipeline = cogl_pipeline_new (ctx); - - cogl_pipeline_set_layer_filters (ctx->blit_texture_pipeline, 0, - COGL_PIPELINE_FILTER_NEAREST, - COGL_PIPELINE_FILTER_NEAREST); - - /* Disable blending by just directly taking the contents of the - source texture */ - cogl_pipeline_set_blend (ctx->blit_texture_pipeline, - "RGBA = ADD(SRC_COLOR, 0)", - NULL); - } - - pipeline = ctx->blit_texture_pipeline; - - cogl_pipeline_set_layer_texture (pipeline, 0, data->src_tex); - - data->pipeline = pipeline; - - return TRUE; -} - -static void -_cogl_blit_texture_render_blit (CoglBlitData *data, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height) -{ - cogl_framebuffer_draw_textured_rectangle (data->dest_fb, - data->pipeline, - dst_x, dst_y, - dst_x + width, - dst_y + height, - src_x / (float) data->src_width, - src_y / (float) data->src_height, - (src_x + width) / - (float) data->src_width, - (src_y + height) / - (float) data->src_height); -} - -static void -_cogl_blit_texture_render_end (CoglBlitData *data) -{ - CoglContext *ctx = cogl_texture_get_context (data->src_tex); - - /* Attach the target texture to the texture render pipeline so that - we don't keep a reference to the source texture forever. This is - assuming that the destination texture will live for a long time - which is currently the case when cogl_blit_* is used from the - atlas code. It may be better in future to keep around a set of - dummy 1x1 textures for each texture target that we could bind - instead. This would also be useful when using a pipeline as a - hash table key such as for the ARBfp program cache. */ - cogl_pipeline_set_layer_texture (ctx->blit_texture_pipeline, 0, - data->dst_tex); - - g_object_unref (data->dest_fb); -} - -static gboolean -_cogl_blit_framebuffer_begin (CoglBlitData *data) -{ - CoglContext *ctx = cogl_texture_get_context (data->src_tex); - CoglOffscreen *dst_offscreen = NULL, *src_offscreen = NULL; - CoglFramebuffer *dst_fb, *src_fb; - GError *ignore_error = NULL; - - /* We can only blit between FBOs if both textures have the same - premult convention and the blit framebuffer extension is - supported. */ - if ((_cogl_texture_get_format (data->src_tex) & COGL_PREMULT_BIT) != - (_cogl_texture_get_format (data->dst_tex) & COGL_PREMULT_BIT) || - !cogl_has_feature (ctx, COGL_FEATURE_ID_BLIT_FRAMEBUFFER)) - return FALSE; - - dst_offscreen = _cogl_offscreen_new_with_texture_full - (data->dst_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */); - - dst_fb = COGL_FRAMEBUFFER (dst_offscreen); - if (!cogl_framebuffer_allocate (dst_fb, &ignore_error)) - { - g_error_free (ignore_error); - goto error; - } - - src_offscreen= _cogl_offscreen_new_with_texture_full - (data->src_tex, - COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, - 0 /* level */); - - src_fb = COGL_FRAMEBUFFER (src_offscreen); - if (!cogl_framebuffer_allocate (src_fb, &ignore_error)) - { - g_error_free (ignore_error); - goto error; - } - - data->src_fb = src_fb; - data->dest_fb = dst_fb; - - return TRUE; - -error: - - g_clear_object (&dst_offscreen); - g_clear_object (&src_offscreen); - - return FALSE; -} - -static void -_cogl_blit_framebuffer_blit (CoglBlitData *data, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height) -{ - cogl_blit_framebuffer (data->src_fb, - data->dest_fb, - src_x, src_y, - dst_x, dst_y, - width, height, - NULL); -} - -static void -_cogl_blit_framebuffer_end (CoglBlitData *data) -{ - g_object_unref (data->src_fb); - g_object_unref (data->dest_fb); -} - -static gboolean -_cogl_blit_copy_tex_sub_image_begin (CoglBlitData *data) -{ - CoglOffscreen *offscreen; - CoglFramebuffer *fb; - GError *ignore_error = NULL; - - /* This will only work if the target texture is a CoglTexture2D */ - if (!COGL_IS_TEXTURE_2D (data->dst_tex)) - return FALSE; - - offscreen = _cogl_offscreen_new_with_texture_full - (data->src_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */); - - fb = COGL_FRAMEBUFFER (offscreen); - if (!cogl_framebuffer_allocate (fb, &ignore_error)) - { - g_error_free (ignore_error); - g_object_unref (fb); - return FALSE; - } - - data->src_fb = fb; - - return TRUE; -} - -static void -_cogl_blit_copy_tex_sub_image_blit (CoglBlitData *data, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height) -{ - _cogl_texture_2d_copy_from_framebuffer (COGL_TEXTURE_2D (data->dst_tex), - src_x, src_y, - width, height, - data->src_fb, - dst_x, dst_y, - 0); /* level */ -} - -static void -_cogl_blit_copy_tex_sub_image_end (CoglBlitData *data) -{ - g_object_unref (data->src_fb); -} - -static gboolean -_cogl_blit_get_tex_data_begin (CoglBlitData *data) -{ - data->format = _cogl_texture_get_format (data->src_tex); - - g_return_val_if_fail (cogl_pixel_format_get_n_planes (data->format) == 1, - FALSE); - - data->bpp = cogl_pixel_format_get_bytes_per_pixel (data->format, 0); - - data->image_data = g_malloc (data->bpp * data->src_width * - data->src_height); - cogl_texture_get_data (data->src_tex, data->format, - data->src_width * data->bpp, data->image_data); - - return TRUE; -} - -static void -_cogl_blit_get_tex_data_blit (CoglBlitData *data, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height) -{ - GError *ignore = NULL; - int rowstride = data->src_width * data->bpp; - int offset = rowstride * src_y + src_x * data->bpp; - - _cogl_texture_set_region (data->dst_tex, - width, height, - data->format, - rowstride, - data->image_data + offset, - dst_x, dst_y, - 0, /* level */ - &ignore); - /* TODO: support chaining up errors during the blit */ -} - -static void -_cogl_blit_get_tex_data_end (CoglBlitData *data) -{ - g_free (data->image_data); -} - -/* These should be specified in order of preference */ -static const CoglBlitMode -_cogl_blit_modes[] = - { - { - "texture-render", - _cogl_blit_texture_render_begin, - _cogl_blit_texture_render_blit, - _cogl_blit_texture_render_end - }, - { - "framebuffer", - _cogl_blit_framebuffer_begin, - _cogl_blit_framebuffer_blit, - _cogl_blit_framebuffer_end - }, - { - "copy-tex-sub-image", - _cogl_blit_copy_tex_sub_image_begin, - _cogl_blit_copy_tex_sub_image_blit, - _cogl_blit_copy_tex_sub_image_end - }, - { - "get-tex-data", - _cogl_blit_get_tex_data_begin, - _cogl_blit_get_tex_data_blit, - _cogl_blit_get_tex_data_end - } - }; - -void -_cogl_blit_begin (CoglBlitData *data, - CoglTexture *dst_tex, - CoglTexture *src_tex) -{ - int i; - - if (_cogl_blit_default_mode == NULL) - { - const char *default_mode_string; - - /* Allow the default to be specified with an environment - variable. For the time being these functions are only used - when blitting between atlas textures so the environment - variable is named to be specific to the atlas code. If we - want to use the code in other places we should create another - environment variable for each specific use case */ - if ((default_mode_string = g_getenv ("COGL_ATLAS_DEFAULT_BLIT_MODE"))) - { - for (i = 0; i < G_N_ELEMENTS (_cogl_blit_modes); i++) - if (!strcmp (_cogl_blit_modes[i].name, default_mode_string)) - { - _cogl_blit_default_mode = _cogl_blit_modes + i; - break; - } - - if (i >= G_N_ELEMENTS (_cogl_blit_modes)) - { - g_warning ("Unknown blit mode %s", default_mode_string); - _cogl_blit_default_mode = _cogl_blit_modes; - } - } - else - /* Default to the first blit mode */ - _cogl_blit_default_mode = _cogl_blit_modes; - } - - memset (data, 0, sizeof (CoglBlitData)); - - data->dst_tex = dst_tex; - data->src_tex = src_tex; - - data->src_width = cogl_texture_get_width (src_tex); - data->src_height = cogl_texture_get_height (src_tex); - - /* Try the default blit mode first */ - if (!_cogl_blit_default_mode->begin_func (data)) - { - COGL_NOTE (ATLAS, "Failed to set up blit mode %s", - _cogl_blit_default_mode->name); - - /* Try all of the other modes in order */ - for (i = 0; i < G_N_ELEMENTS (_cogl_blit_modes); i++) - if (_cogl_blit_modes + i != _cogl_blit_default_mode && - _cogl_blit_modes[i].begin_func (data)) - { - /* Use this mode as the default from now on */ - _cogl_blit_default_mode = _cogl_blit_modes + i; - break; - } - else - COGL_NOTE (ATLAS, - "Failed to set up blit mode %s", - _cogl_blit_modes[i].name); - - /* The last blit mode can't fail so this should never happen */ - g_return_if_fail (i < G_N_ELEMENTS (_cogl_blit_modes)); - } - - data->blit_mode = _cogl_blit_default_mode; - - COGL_NOTE (ATLAS, "Setup blit using %s", _cogl_blit_default_mode->name); -} - -void -_cogl_blit (CoglBlitData *data, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height) -{ - data->blit_mode->blit_func (data, src_x, src_y, dst_x, dst_y, width, height); -} - -void -_cogl_blit_end (CoglBlitData *data) -{ - data->blit_mode->end_func (data); -} diff --git a/mutter/cogl/cogl/cogl-blit.h b/mutter/cogl/cogl/cogl-blit.h deleted file mode 100644 index 6a98735..0000000 --- a/mutter/cogl/cogl/cogl-blit.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#include - -#include "cogl/cogl-texture.h" -#include "cogl/cogl-framebuffer.h" - -/* This structures and functions are used when a series of blits needs - to be performed between two textures. In this case there are - multiple methods we can use, most of which involve transferring - between an FBO bound to the texture. */ - -typedef struct _CoglBlitData CoglBlitData; - -typedef gboolean (* CoglBlitBeginFunc) (CoglBlitData *data); -typedef void (* CoglBlitEndFunc) (CoglBlitData *data); - -typedef void (* CoglBlitFunc) (CoglBlitData *data, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height); - -typedef struct -{ - const char *name; - CoglBlitBeginFunc begin_func; - CoglBlitFunc blit_func; - CoglBlitEndFunc end_func; -} CoglBlitMode; - -struct _CoglBlitData -{ - CoglTexture *src_tex, *dst_tex; - - unsigned int src_width; - unsigned int src_height; - - const CoglBlitMode *blit_mode; - - /* If we're not using an FBO then we g_malloc a buffer and copy the - complete texture data in */ - unsigned char *image_data; - CoglPixelFormat format; - - int bpp; - - CoglFramebuffer *src_fb; - CoglFramebuffer *dest_fb; - CoglPipeline *pipeline; -}; - -void -_cogl_blit_begin (CoglBlitData *data, - CoglTexture *dst_tex, - CoglTexture *src_tex); - -void -_cogl_blit (CoglBlitData *data, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height); - -void -_cogl_blit_end (CoglBlitData *data); diff --git a/mutter/cogl/cogl/cogl-boxed-value.c b/mutter/cogl/cogl/cogl-boxed-value.c deleted file mode 100644 index 6e13eee..0000000 --- a/mutter/cogl/cogl/cogl-boxed-value.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include - -#include "cogl/cogl-boxed-value.h" -#include "cogl/cogl-context-private.h" - -gboolean -_cogl_boxed_value_equal (const CoglBoxedValue *bva, - const CoglBoxedValue *bvb) -{ - const void *pa, *pb; - - if (bva->type != bvb->type) - return FALSE; - - switch (bva->type) - { - case COGL_BOXED_NONE: - return TRUE; - - case COGL_BOXED_INT: - if (bva->size != bvb->size || bva->count != bvb->count) - return FALSE; - - if (bva->count == 1) - { - pa = bva->v.int_value; - pb = bvb->v.int_value; - } - else - { - pa = bva->v.int_array; - pb = bvb->v.int_array; - } - - return !memcmp (pa, pb, sizeof (int) * bva->size * bva->count); - - case COGL_BOXED_FLOAT: - if (bva->size != bvb->size || bva->count != bvb->count) - return FALSE; - - if (bva->count == 1) - { - pa = bva->v.float_value; - pb = bvb->v.float_value; - } - else - { - pa = bva->v.float_array; - pb = bvb->v.float_array; - } - - return !memcmp (pa, pb, sizeof (float) * bva->size * bva->count); - - case COGL_BOXED_MATRIX: - if (bva->size != bvb->size || - bva->count != bvb->count) - return FALSE; - - if (bva->count == 1) - { - pa = bva->v.matrix; - pb = bvb->v.matrix; - } - else - { - pa = bva->v.array; - pb = bvb->v.array; - } - - return !memcmp (pa, pb, - sizeof (float) * bva->size * bva->size * bva->count); - } - - g_warn_if_reached (); - - return FALSE; -} - -static void -_cogl_boxed_value_transpose (float *dst, - int size, - const float *src) -{ - int y, x; - - /* If the value is transposed we'll just transpose it now as it - * is copied into the boxed value instead of passing TRUE to - * glUniformMatrix because that is not supported on GLES and it - * doesn't seem like the GL driver would be able to do anything - * much smarter than this anyway */ - - for (y = 0; y < size; y++) - for (x = 0; x < size; x++) - *(dst++) = src[y + x * size]; -} - -static void -_cogl_boxed_value_set_x (CoglBoxedValue *bv, - int size, - int count, - CoglBoxedType type, - size_t value_size, - const void *value, - gboolean transpose) -{ - if (count == 1) - { - if (bv->count > 1) - g_free (bv->v.array); - - if (transpose) - _cogl_boxed_value_transpose (bv->v.float_value, - size, - value); - else - memcpy (bv->v.float_value, value, value_size); - } - else - { - if (bv->count > 1) - { - if (bv->count != count || - bv->size != size || - bv->type != type) - { - g_free (bv->v.array); - bv->v.array = g_malloc (count * value_size); - } - } - else - bv->v.array = g_malloc (count * value_size); - - if (transpose) - { - int value_num; - - for (value_num = 0; value_num < count; value_num++) - _cogl_boxed_value_transpose (bv->v.float_array + - value_num * size * size, - size, - (const float *) value + - value_num * size * size); - } - else - memcpy (bv->v.array, value, count * value_size); - } - - bv->type = type; - bv->size = size; - bv->count = count; -} - -void -_cogl_boxed_value_set_1f (CoglBoxedValue *bv, - float value) -{ - _cogl_boxed_value_set_x (bv, - 1, 1, COGL_BOXED_FLOAT, - sizeof (float), &value, FALSE); -} - -void -_cogl_boxed_value_set_1i (CoglBoxedValue *bv, - int value) -{ - _cogl_boxed_value_set_x (bv, - 1, 1, COGL_BOXED_INT, - sizeof (int), &value, FALSE); -} - -void -_cogl_boxed_value_set_float (CoglBoxedValue *bv, - int n_components, - int count, - const float *value) -{ - _cogl_boxed_value_set_x (bv, - n_components, count, - COGL_BOXED_FLOAT, - sizeof (float) * n_components, value, FALSE); -} - -void -_cogl_boxed_value_set_int (CoglBoxedValue *bv, - int n_components, - int count, - const int *value) -{ - _cogl_boxed_value_set_x (bv, - n_components, count, - COGL_BOXED_INT, - sizeof (int) * n_components, value, FALSE); -} - -void -_cogl_boxed_value_set_matrix (CoglBoxedValue *bv, - int dimensions, - int count, - gboolean transpose, - const float *value) -{ - _cogl_boxed_value_set_x (bv, - dimensions, count, - COGL_BOXED_MATRIX, - sizeof (float) * dimensions * dimensions, - value, - transpose); -} - -void -_cogl_boxed_value_copy (CoglBoxedValue *dst, - const CoglBoxedValue *src) -{ - *dst = *src; - - if (src->count > 1) - { - switch (src->type) - { - case COGL_BOXED_NONE: - break; - - case COGL_BOXED_INT: - dst->v.int_array = g_memdup2 (src->v.int_array, - src->size * src->count * sizeof (int)); - break; - - case COGL_BOXED_FLOAT: - dst->v.float_array = g_memdup2 (src->v.float_array, - src->size * - src->count * - sizeof (float)); - break; - - case COGL_BOXED_MATRIX: - dst->v.float_array = g_memdup2 (src->v.float_array, - src->size * src->size * - src->count * sizeof (float)); - break; - } - } -} - -void -_cogl_boxed_value_destroy (CoglBoxedValue *bv) -{ - if (bv->count > 1) - g_free (bv->v.array); -} - -void -_cogl_boxed_value_set_uniform (CoglContext *ctx, - GLint location, - const CoglBoxedValue *value) -{ - ctx->driver_vtable->set_uniform (ctx, location, value); -} diff --git a/mutter/cogl/cogl/cogl-boxed-value.h b/mutter/cogl/cogl/cogl-boxed-value.h deleted file mode 100644 index 297bffd..0000000 --- a/mutter/cogl/cogl/cogl-boxed-value.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include - -#include "cogl/cogl-context.h" - -typedef enum -{ - COGL_BOXED_NONE, - COGL_BOXED_INT, - COGL_BOXED_FLOAT, - COGL_BOXED_MATRIX -} CoglBoxedType; - -typedef struct _CoglBoxedValue -{ - CoglBoxedType type; - int size, count; - - union { - float float_value[4]; - int int_value[4]; - float matrix[16]; - float *float_array; - int *int_array; - void *array; - } v; -} CoglBoxedValue; - -#define _cogl_boxed_value_init(bv) \ - G_STMT_START { \ - CoglBoxedValue *_bv = (bv); \ - _bv->type = COGL_BOXED_NONE; \ - _bv->count = 1; \ - } G_STMT_END - -gboolean -_cogl_boxed_value_equal (const CoglBoxedValue *bva, - const CoglBoxedValue *bvb); - -void -_cogl_boxed_value_set_1f (CoglBoxedValue *bv, - float value); - -void -_cogl_boxed_value_set_1i (CoglBoxedValue *bv, - int value); - -void -_cogl_boxed_value_set_float (CoglBoxedValue *bv, - int n_components, - int count, - const float *value); - -void -_cogl_boxed_value_set_int (CoglBoxedValue *bv, - int n_components, - int count, - const int *value); - -void -_cogl_boxed_value_set_matrix (CoglBoxedValue *bv, - int dimensions, - int count, - gboolean transpose, - const float *value); - -/* - * _cogl_boxed_value_copy: - * @dst: The destination boxed value - * @src: The source boxed value - * - * This copies @src to @dst. It is assumed that @dst is initialised. - */ -void -_cogl_boxed_value_copy (CoglBoxedValue *dst, - const CoglBoxedValue *src); - -void -_cogl_boxed_value_destroy (CoglBoxedValue *bv); - -void -_cogl_boxed_value_set_uniform (CoglContext *ctx, - int location, - const CoglBoxedValue *value); diff --git a/mutter/cogl/cogl/cogl-buffer-private.h b/mutter/cogl/cogl/cogl-buffer-private.h deleted file mode 100644 index 6d37368..0000000 --- a/mutter/cogl/cogl/cogl-buffer-private.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Damien Lespiau - * Robert Bragg - */ - -#pragma once - -#include - -#include "cogl/cogl-buffer.h" -#include "cogl/cogl-context.h" -#include "cogl/cogl-gl-header.h" - -G_BEGIN_DECLS - -typedef enum _CoglBufferFlags -{ - COGL_BUFFER_FLAG_NONE = 0, - COGL_BUFFER_FLAG_BUFFER_OBJECT = 1UL << 0, /* real openGL buffer object */ - COGL_BUFFER_FLAG_MAPPED = 1UL << 1, - COGL_BUFFER_FLAG_MAPPED_FALLBACK = 1UL << 2 -} CoglBufferFlags; - -struct _CoglBuffer -{ - GObject parent_instance; - - CoglContext *context; - - CoglBufferBindTarget last_target; - - CoglBufferFlags flags; - - GLuint gl_handle; /* OpenGL handle */ - unsigned int size; /* size of the buffer, in bytes */ - CoglBufferUpdateHint update_hint; - - /* points to the mapped memory when the CoglBuffer is a VBO, PBO, - * ... or points to allocated memory in the fallback paths */ - uint8_t *data; - - int immutable_ref; - - unsigned int store_created : 1; - - void * (* map_range) (CoglBuffer *buffer, - size_t offset, - size_t size, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error); - - void (* unmap) (CoglBuffer *buffer); - - gboolean (* set_data) (CoglBuffer *buffer, - unsigned int offset, - const void *data, - unsigned int size, - GError **error); -}; -struct _CoglBufferClass -{ - GObjectClass parent_class; -}; - -CoglBuffer * -_cogl_buffer_immutable_ref (CoglBuffer *buffer); - -void -_cogl_buffer_immutable_unref (CoglBuffer *buffer); - -gboolean -_cogl_buffer_set_data (CoglBuffer *buffer, - size_t offset, - const void *data, - size_t size, - GError **error); - -void * -_cogl_buffer_map (CoglBuffer *buffer, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error); - -/* This is a wrapper around cogl_buffer_map_range for internal use - when we want to map the buffer for write only to replace the entire - contents. If the map fails then it will fallback to writing to a - temporary buffer. When _cogl_buffer_unmap_for_fill_or_fallback is - called the temporary buffer will be copied into the array. Note - that these calls share a global array so they can not be nested. */ -void * -_cogl_buffer_map_range_for_fill_or_fallback (CoglBuffer *buffer, - size_t offset, - size_t size); - -void -_cogl_buffer_unmap_for_fill_or_fallback (CoglBuffer *buffer); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-buffer.c b/mutter/cogl/cogl/cogl-buffer.c deleted file mode 100644 index 807382c..0000000 --- a/mutter/cogl/cogl/cogl-buffer.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Damien Lespiau - * Robert Bragg - */ - -/* For an overview of the functionality implemented here, please see - * cogl-buffer.h, which contains the gtk-doc section overview for the - * Pixel Buffers API. - */ - -#include "config.h" - -#include -#include -#include - -#include "cogl/cogl-enum-types.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-pixel-buffer-private.h" - - -G_DEFINE_ABSTRACT_TYPE (CoglBuffer, cogl_buffer, G_TYPE_OBJECT) - -enum -{ - PROP_0, - - PROP_CONTEXT, - PROP_SIZE, - PROP_DEFAULT_TARGET, - PROP_UPDATE_HINT, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -/* - * Fallback path, buffer->data points to a malloc'ed buffer. - */ - -static void * -malloc_map_range (CoglBuffer *buffer, - size_t offset, - size_t size, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error) -{ - buffer->flags |= COGL_BUFFER_FLAG_MAPPED; - return buffer->data + offset; -} - -static void -malloc_unmap (CoglBuffer *buffer) -{ - buffer->flags &= ~COGL_BUFFER_FLAG_MAPPED; -} - -static gboolean -malloc_set_data (CoglBuffer *buffer, - unsigned int offset, - const void *data, - unsigned int size, - GError **error) -{ - memcpy (buffer->data + offset, data, size); - return TRUE; -} - -static void -cogl_buffer_dispose (GObject *object) -{ - CoglBuffer *buffer = COGL_BUFFER (object); - - g_return_if_fail (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED)); - g_return_if_fail (buffer->immutable_ref == 0); - - if (buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT) - buffer->context->driver_vtable->buffer_destroy (buffer); - else - g_free (buffer->data); - - G_OBJECT_CLASS (cogl_buffer_parent_class)->dispose (object); -} - -static void -cogl_buffer_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - CoglBuffer *buffer = COGL_BUFFER (gobject); - - switch (prop_id) - { - case PROP_CONTEXT: - buffer->context = g_value_get_object (value); - break; - - case PROP_SIZE: - buffer->size = g_value_get_uint64 (value); - break; - - case PROP_DEFAULT_TARGET: - { - gboolean use_malloc = FALSE; - - buffer->last_target = g_value_get_enum (value); - if (buffer->last_target == COGL_BUFFER_BIND_TARGET_PIXEL_PACK || - buffer->last_target == COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK) - { - if (!_cogl_has_private_feature (buffer->context, COGL_PRIVATE_FEATURE_PBOS)) - use_malloc = TRUE; - } - - if (use_malloc) - { - buffer->map_range = malloc_map_range; - buffer->unmap = malloc_unmap; - buffer->set_data = malloc_set_data; - - buffer->data = g_malloc (buffer->size); - } - else - { - buffer->map_range = buffer->context->driver_vtable->buffer_map_range; - buffer->unmap = buffer->context->driver_vtable->buffer_unmap; - buffer->set_data = buffer->context->driver_vtable->buffer_set_data; - - buffer->context->driver_vtable->buffer_create (buffer); - - buffer->flags |= COGL_BUFFER_FLAG_BUFFER_OBJECT; - } - } - break; - - case PROP_UPDATE_HINT: - buffer->update_hint = g_value_get_enum (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -cogl_buffer_class_init (CoglBufferClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->dispose = cogl_buffer_dispose; - gobject_class->set_property = cogl_buffer_set_property; - - obj_props[PROP_CONTEXT] = - g_param_spec_object ("context", NULL, NULL, - COGL_TYPE_CONTEXT, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_SIZE] = - g_param_spec_uint64 ("size", NULL, NULL, - 0, G_MAXINT64, 0, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_DEFAULT_TARGET] = - g_param_spec_enum ("default-target", NULL, NULL, - COGL_TYPE_BUFFER_BIND_TARGET, - COGL_BUFFER_BIND_TARGET_PIXEL_PACK, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_UPDATE_HINT] = - g_param_spec_enum ("update-hint", NULL, NULL, - COGL_TYPE_BUFFER_UPDATE_HINT, - COGL_BUFFER_UPDATE_HINT_STATIC, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (gobject_class, - PROP_LAST, - obj_props); -} - -static void -cogl_buffer_init (CoglBuffer *buffer) -{ - buffer->flags = COGL_BUFFER_FLAG_NONE; - buffer->store_created = FALSE; - buffer->data = NULL; - buffer->immutable_ref = 0; -} - -unsigned int -cogl_buffer_get_size (CoglBuffer *buffer) -{ - g_return_val_if_fail (COGL_IS_BUFFER (buffer), 0); - - return buffer->size; -} - -void -cogl_buffer_set_update_hint (CoglBuffer *buffer, - CoglBufferUpdateHint hint) -{ - g_return_if_fail (COGL_IS_BUFFER (buffer)); - - if (G_UNLIKELY (hint > COGL_BUFFER_UPDATE_HINT_STREAM)) - hint = COGL_BUFFER_UPDATE_HINT_STATIC; - - buffer->update_hint = hint; -} - -CoglBufferUpdateHint -cogl_buffer_get_update_hint (CoglBuffer *buffer) -{ - if (!COGL_IS_BUFFER (buffer)) - return FALSE; - - return buffer->update_hint; -} - -static void -warn_about_midscene_changes (void) -{ - static gboolean seen = FALSE; - if (!seen) - { - g_warning ("Mid-scene modification of buffers has " - "undefined results\n"); - seen = TRUE; - } -} - -void * -_cogl_buffer_map (CoglBuffer *buffer, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error) -{ - g_return_val_if_fail (COGL_IS_BUFFER (buffer), NULL); - - return cogl_buffer_map_range (buffer, 0, buffer->size, access, hints, error); -} - -void * -cogl_buffer_map (CoglBuffer *buffer, - CoglBufferAccess access, - CoglBufferMapHint hints) -{ - GError *ignore_error = NULL; - void *ptr = - cogl_buffer_map_range (buffer, 0, buffer->size, access, hints, - &ignore_error); - g_clear_error (&ignore_error); - return ptr; -} - -void * -cogl_buffer_map_range (CoglBuffer *buffer, - size_t offset, - size_t size, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error) -{ - g_return_val_if_fail (COGL_IS_BUFFER (buffer), NULL); - g_return_val_if_fail (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED), NULL); - - if (G_UNLIKELY (buffer->immutable_ref)) - warn_about_midscene_changes (); - - buffer->data = buffer->map_range (buffer, - offset, - size, - access, - hints, - error); - - return buffer->data; -} - -void -cogl_buffer_unmap (CoglBuffer *buffer) -{ - g_return_if_fail (COGL_IS_BUFFER (buffer)); - - if (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED)) - return; - - buffer->unmap (buffer); -} - -void * -_cogl_buffer_map_range_for_fill_or_fallback (CoglBuffer *buffer, - size_t offset, - size_t size) -{ - CoglContext *ctx = buffer->context; - void *ret; - GError *ignore_error = NULL; - - g_return_val_if_fail (!ctx->buffer_map_fallback_in_use, NULL); - - ctx->buffer_map_fallback_in_use = TRUE; - - ret = cogl_buffer_map_range (buffer, - offset, - size, - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD, - &ignore_error); - - if (ret) - return ret; - - g_error_free (ignore_error); - - /* If the map fails then we'll use a temporary buffer to fill - the data and then upload it using cogl_buffer_set_data when - the buffer is unmapped. The temporary buffer is shared to - avoid reallocating it every time */ - g_byte_array_set_size (ctx->buffer_map_fallback_array, size); - ctx->buffer_map_fallback_offset = offset; - - buffer->flags |= COGL_BUFFER_FLAG_MAPPED_FALLBACK; - - return ctx->buffer_map_fallback_array->data; -} - -void -_cogl_buffer_unmap_for_fill_or_fallback (CoglBuffer *buffer) -{ - CoglContext *ctx = buffer->context; - - g_return_if_fail (ctx->buffer_map_fallback_in_use); - - ctx->buffer_map_fallback_in_use = FALSE; - - if ((buffer->flags & COGL_BUFFER_FLAG_MAPPED_FALLBACK)) - { - /* Note: don't try to catch OOM errors here since the use cases - * we currently have for this api (the journal and path stroke - * tessellator) don't have anything particularly sensible they - * can do in response to a failure anyway so it seems better to - * simply abort instead. - * - * If we find this is a problem for real world applications - * then in the path tessellation case we could potentially add an - * explicit cogl_path_tessellate_stroke() api that can throw an - * error for the app to cache. For the journal we could - * potentially flush the journal in smaller batches so we use - * smaller buffers, though that would probably not help for - * deferred renderers. - */ - _cogl_buffer_set_data (buffer, - ctx->buffer_map_fallback_offset, - ctx->buffer_map_fallback_array->data, - ctx->buffer_map_fallback_array->len, - NULL); - buffer->flags &= ~COGL_BUFFER_FLAG_MAPPED_FALLBACK; - } - else - cogl_buffer_unmap (buffer); -} - -gboolean -_cogl_buffer_set_data (CoglBuffer *buffer, - size_t offset, - const void *data, - size_t size, - GError **error) -{ - g_return_val_if_fail (COGL_IS_BUFFER (buffer), FALSE); - g_return_val_if_fail ((offset + size) <= buffer->size, FALSE); - - if (G_UNLIKELY (buffer->immutable_ref)) - warn_about_midscene_changes (); - - return buffer->set_data (buffer, offset, data, size, error); -} - -gboolean -cogl_buffer_set_data (CoglBuffer *buffer, - size_t offset, - const void *data, - size_t size) -{ - GError *ignore_error = NULL; - gboolean status = - _cogl_buffer_set_data (buffer, offset, data, size, &ignore_error); - g_clear_error (&ignore_error); - return status; -} - -CoglBuffer * -_cogl_buffer_immutable_ref (CoglBuffer *buffer) -{ - g_return_val_if_fail (COGL_IS_BUFFER (buffer), NULL); - - buffer->immutable_ref++; - return buffer; -} - -void -_cogl_buffer_immutable_unref (CoglBuffer *buffer) -{ - g_return_if_fail (COGL_IS_BUFFER (buffer)); - g_return_if_fail (buffer->immutable_ref > 0); - - buffer->immutable_ref--; -} - diff --git a/mutter/cogl/cogl/cogl-buffer.h b/mutter/cogl/cogl/cogl-buffer.h deleted file mode 100644 index c73cfad..0000000 --- a/mutter/cogl/cogl/cogl-buffer.h +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C)2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Damien Lespiau - * Robert Bragg - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-types.h" - -G_BEGIN_DECLS - -/** - * CoglBuffer: - * - * Common buffer functions, including data upload APIs - * - * The CoglBuffer API provides a common interface to manipulate - * buffers that have been allocated either via `cogl_pixel_buffer_new()` - * or `cogl_attribute_buffer_new()`. The API allows you to upload data - * to these buffers and define usage hints that help Cogl manage your - * buffer optimally. - * - * Data can either be uploaded by supplying a pointer and size so Cogl - * can copy your data, or you can mmap() a CoglBuffer and then you can - * copy data to the buffer directly. - * - * One of the most common uses for CoglBuffers is to upload texture - * data asynchronously since the ability to mmap the buffers into - * the CPU makes it possible for another thread to handle the IO - * of loading an image file and unpacking it into the mapped buffer - * without blocking other Cogl operations. - */ -#define COGL_TYPE_BUFFER (cogl_buffer_get_type ()) -#define COGL_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_BUFFER, CoglBuffer)) -#define COGL_BUFFER_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_BUFFER, CoglBuffer const)) -#define COGL_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_TYPE_BUFFER, CoglBufferClass)) -#define COGL_IS_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_TYPE_BUFFER)) -#define COGL_IS_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_TYPE_BUFFER)) -#define COGL_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COGL_TYPE_BUFFER, CoglBufferClass)) - -typedef struct _CoglBufferClass CoglBufferClass; -typedef struct _CoglBuffer CoglBuffer; - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (CoglBuffer, g_object_unref) - -COGL_EXPORT -GType cogl_buffer_get_type (void) G_GNUC_CONST; - -#define COGL_BUFFER_ERROR (_cogl_buffer_error_domain ()) - -/** - * CoglBufferError: - * @COGL_BUFFER_ERROR_MAP: A buffer could not be mapped either - * because the feature isn't supported or because a system - * limitation was hit. - * - * Error enumeration for #CoglBuffer - */ -typedef enum /*< prefix=COGL_BUFFER_ERROR >*/ -{ - COGL_BUFFER_ERROR_MAP -} CoglBufferError; - -uint32_t -_cogl_buffer_error_domain (void); - -/** - * cogl_buffer_get_size: - * @buffer: a buffer object - * - * Retrieves the size of buffer - * - * Return value: the size of the buffer in bytes - */ -COGL_EXPORT unsigned int -cogl_buffer_get_size (CoglBuffer *buffer); - -/** - * CoglBufferUpdateHint: - * @COGL_BUFFER_UPDATE_HINT_STATIC: the buffer will not change over time - * @COGL_BUFFER_UPDATE_HINT_DYNAMIC: the buffer will change from time to time - * @COGL_BUFFER_UPDATE_HINT_STREAM: the buffer will be used once or a couple of - * times - * - * The update hint on a buffer allows the user to give some detail on how often - * the buffer data is going to be updated. - */ -typedef enum /*< prefix=COGL_BUFFER_UPDATE_HINT >*/ -{ - COGL_BUFFER_UPDATE_HINT_STATIC, - COGL_BUFFER_UPDATE_HINT_DYNAMIC, - COGL_BUFFER_UPDATE_HINT_STREAM -} CoglBufferUpdateHint; - -/** - * cogl_buffer_set_update_hint: - * @buffer: a buffer object - * @hint: the new hint - * - * Sets the update hint on a buffer. See #CoglBufferUpdateHint for a description - * of the available hints. - */ -COGL_EXPORT void -cogl_buffer_set_update_hint (CoglBuffer *buffer, - CoglBufferUpdateHint hint); - -/** - * cogl_buffer_get_update_hint: - * @buffer: a buffer object - * - * Retrieves the update hints set using [method@Cogl.Buffer.set_update_hint] - * - * Return value: the #CoglBufferUpdateHint currently used by the buffer - */ -COGL_EXPORT CoglBufferUpdateHint -cogl_buffer_get_update_hint (CoglBuffer *buffer); - -/** - * CoglBufferAccess: - * @COGL_BUFFER_ACCESS_READ: the buffer will be read - * @COGL_BUFFER_ACCESS_WRITE: the buffer will written to - * @COGL_BUFFER_ACCESS_READ_WRITE: the buffer will be used for both reading and - * writing - * - * The access hints for [method@Cogl.Buffer.set_update_hint] - */ -typedef enum /*< prefix=COGL_BUFFER_ACCESS >*/ -{ - COGL_BUFFER_ACCESS_READ = 1 << 0, - COGL_BUFFER_ACCESS_WRITE = 1 << 1, - COGL_BUFFER_ACCESS_READ_WRITE = COGL_BUFFER_ACCESS_READ | COGL_BUFFER_ACCESS_WRITE -} CoglBufferAccess; - - -/** - * CoglBufferMapHint: - * @COGL_BUFFER_MAP_HINT_DISCARD: Tells Cogl that you plan to replace - * all the buffer's contents. When this flag is used to map a - * buffer, the entire contents of the buffer become undefined, even - * if only a subregion of the buffer is mapped. - * @COGL_BUFFER_MAP_HINT_DISCARD_RANGE: Tells Cogl that you plan to - * replace all the contents of the mapped region. The contents of - * the region specified are undefined after this flag is used to - * map a buffer. - * - * Hints to Cogl about how you are planning to modify the data once it - * is mapped. - */ -typedef enum /*< prefix=COGL_BUFFER_MAP_HINT >*/ -{ - COGL_BUFFER_MAP_HINT_DISCARD = 1 << 0, - COGL_BUFFER_MAP_HINT_DISCARD_RANGE = 1 << 1 -} CoglBufferMapHint; - -/** - * CoglBufferBindTarget: - */ -typedef enum /*< prefix=COGL_BUFFER_BIND_TARGET >*/ -{ - COGL_BUFFER_BIND_TARGET_PIXEL_PACK, - COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK, - COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER, - COGL_BUFFER_BIND_TARGET_INDEX_BUFFER, - - COGL_BUFFER_BIND_TARGET_COUNT -} CoglBufferBindTarget; - -/** - * cogl_buffer_map: - * @buffer: a buffer object - * @access: how the mapped buffer will be used by the application - * @hints: A mask of `CoglBufferMapHint`s that tell Cogl how - * the data will be modified once mapped. - * - * Maps the buffer into the application address space for direct - * access. This is equivalent to calling [method@Cogl.Buffer.map_range] with - * zero as the offset and the size of the entire buffer as the size. - * - * It is strongly recommended that you pass - * %COGL_BUFFER_MAP_HINT_DISCARD as a hint if you are going to replace - * all the buffer's data. This way if the buffer is currently being - * used by the GPU then the driver won't have to stall the CPU and - * wait for the hardware to finish because it can instead allocate a - * new buffer to map. - * - * The behaviour is undefined if you access the buffer in a way - * conflicting with the @access mask you pass. It is also an error to - * release your last reference while the buffer is mapped. - * - * Return value: (transfer none): A pointer to the mapped memory or - * %NULL is the call fails - */ -COGL_EXPORT void * -cogl_buffer_map (CoglBuffer *buffer, - CoglBufferAccess access, - CoglBufferMapHint hints); - -/** - * cogl_buffer_map_range: - * @buffer: a buffer object - * @offset: Offset within the buffer to start the mapping - * @size: The size of data to map - * @access: how the mapped buffer will be used by the application - * @hints: A mask of `CoglBufferMapHint`s that tell Cogl how - * the data will be modified once mapped. - * @error: A #GError for catching exceptional errors - * - * Maps a sub-region of the buffer into the application's address space - * for direct access. - * - * It is strongly recommended that you pass - * %COGL_BUFFER_MAP_HINT_DISCARD as a hint if you are going to replace - * all the buffer's data. This way if the buffer is currently being - * used by the GPU then the driver won't have to stall the CPU and - * wait for the hardware to finish because it can instead allocate a - * new buffer to map. You can pass - * %COGL_BUFFER_MAP_HINT_DISCARD_RANGE instead if you want the - * regions outside of the mapping to be retained. - * - * The behaviour is undefined if you access the buffer in a way - * conflicting with the @access mask you pass. It is also an error to - * release your last reference while the buffer is mapped. - * - * Return value: (transfer none): A pointer to the mapped memory or - * %NULL is the call fails - */ -COGL_EXPORT void * -cogl_buffer_map_range (CoglBuffer *buffer, - size_t offset, - size_t size, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error); - -/** - * cogl_buffer_unmap: - * @buffer: a buffer object - * - * Unmaps a buffer previously mapped by [method@Cogl.Buffer.map]. - */ -COGL_EXPORT void -cogl_buffer_unmap (CoglBuffer *buffer); - -/** - * cogl_buffer_set_data: - * @buffer: a buffer object - * @offset: destination offset (in bytes) in the buffer - * @data: (array) (element-type guint8): a pointer to the data to be copied - * into the buffer - * @size: number of bytes to copy - * - * Updates part of the buffer with new data from @data. Where to put this new - * data is controlled by @offset and @offset + @data should be less than the - * buffer size. - * - * Return value: %TRUE is the operation succeeded, %FALSE otherwise - */ -COGL_EXPORT gboolean -cogl_buffer_set_data (CoglBuffer *buffer, - size_t offset, - const void *data, - size_t size); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-clip-stack.c b/mutter/cogl/cogl/cogl-clip-stack.c deleted file mode 100644 index 019ec74..0000000 --- a/mutter/cogl/cogl/cogl-clip-stack.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include -#include - -#include - -#include "cogl/cogl-clip-stack.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-journal-private.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-primitives-private.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl-attribute-private.h" -#include "cogl/cogl-primitive-private.h" -#include "cogl/cogl1-context.h" -#include "cogl/cogl-offscreen.h" -#include "cogl/cogl-matrix-stack.h" -#include "mtk/mtk.h" - -static void * -_cogl_clip_stack_push_entry (CoglClipStack *clip_stack, - size_t size, - CoglClipStackType type) -{ - CoglClipStack *entry = g_malloc0 (size); - - /* The new entry starts with a ref count of 1 because the stack - holds a reference to it as it is the top entry */ - entry->ref_count = 1; - entry->type = type; - entry->parent = clip_stack; - - /* We don't need to take a reference to the parent from the entry - because the we are stealing the ref in the new stack top */ - - return entry; -} - -static void -get_transformed_corners (float x_1, - float y_1, - float x_2, - float y_2, - graphene_matrix_t *modelview, - graphene_matrix_t *projection, - const float *viewport, - float *transformed_corners) -{ - int i; - - transformed_corners[0] = x_1; - transformed_corners[1] = y_1; - transformed_corners[2] = x_2; - transformed_corners[3] = y_1; - transformed_corners[4] = x_2; - transformed_corners[5] = y_2; - transformed_corners[6] = x_1; - transformed_corners[7] = y_2; - - - /* Project the coordinates to window space coordinates */ - for (i = 0; i < 4; i++) - { - float *v = transformed_corners + i * 2; - _cogl_transform_point (modelview, projection, viewport, v, v + 1); - } -} - -/* Sets the window-space bounds of the entry based on the projected - coordinates of the given rectangle */ -static void -_cogl_clip_stack_entry_set_bounds (CoglClipStack *entry, - float *transformed_corners) -{ - float min_x = G_MAXFLOAT, min_y = G_MAXFLOAT; - float max_x = -G_MAXFLOAT, max_y = -G_MAXFLOAT; - int i; - - for (i = 0; i < 4; i++) - { - float *v = transformed_corners + i * 2; - - if (v[0] > max_x) - max_x = v[0]; - if (v[0] < min_x) - min_x = v[0]; - if (v[1] > max_y) - max_y = v[1]; - if (v[1] < min_y) - min_y = v[1]; - } - - entry->bounds_x0 = floorf (min_x); - entry->bounds_x1 = ceilf (max_x); - entry->bounds_y0 = floorf (min_y); - entry->bounds_y1 = ceilf (max_y); -} - -CoglClipStack * -_cogl_clip_stack_push_rectangle (CoglClipStack *stack, - float x_1, - float y_1, - float x_2, - float y_2, - CoglMatrixEntry *modelview_entry, - CoglMatrixEntry *projection_entry, - const float *viewport) -{ - CoglClipStackRect *entry; - graphene_matrix_t modelview; - graphene_matrix_t projection; - graphene_matrix_t modelview_projection; - - /* Corners of the given rectangle in an clockwise order: - * (0, 1) (2, 3) - * - * - * - * (6, 7) (4, 5) - */ - float rect[] = { - x_1, y_1, - x_2, y_1, - x_2, y_2, - x_1, y_2 - }; - - /* Make a new entry */ - entry = _cogl_clip_stack_push_entry (stack, - sizeof (CoglClipStackRect), - COGL_CLIP_STACK_RECT); - - entry->x0 = x_1; - entry->y0 = y_1; - entry->x1 = x_2; - entry->y1 = y_2; - - entry->matrix_entry = cogl_matrix_entry_ref (modelview_entry); - - cogl_matrix_entry_get (modelview_entry, &modelview); - cogl_matrix_entry_get (projection_entry, &projection); - - graphene_matrix_multiply (&modelview, &projection, &modelview_projection); - - /* Technically we could avoid the viewport transform at this point - * if we want to make this a bit faster. */ - _cogl_transform_point (&modelview, &projection, viewport, &rect[0], &rect[1]); - _cogl_transform_point (&modelview, &projection, viewport, &rect[2], &rect[3]); - _cogl_transform_point (&modelview, &projection, viewport, &rect[4], &rect[5]); - _cogl_transform_point (&modelview, &projection, viewport, &rect[6], &rect[7]); - - /* If the fully transformed rectangle isn't still axis aligned we - * can't handle it using a scissor. - * - * We don't use an epsilon here since we only really aim to catch - * simple cases where the transform doesn't leave the rectangle screen - * aligned and don't mind some false positives. - */ - if (rect[0] != rect[6] || - rect[1] != rect[3] || - rect[2] != rect[4] || - rect[7] != rect[5]) - { - entry->can_be_scissor = FALSE; - - _cogl_clip_stack_entry_set_bounds ((CoglClipStack *) entry, - rect); - } - else - { - CoglClipStack *base_entry = (CoglClipStack *) entry; - x_1 = rect[0]; - y_1 = rect[1]; - x_2 = rect[4]; - y_2 = rect[5]; - - /* Consider that the modelview matrix may flip the rectangle - * along the x or y axis... */ -#define SWAP(A,B) do { float tmp = B; B = A; A = tmp; } while (0) - if (x_1 > x_2) - SWAP (x_1, x_2); - if (y_1 > y_2) - SWAP (y_1, y_2); -#undef SWAP - - base_entry->bounds_x0 = COGL_UTIL_NEARBYINT (x_1); - base_entry->bounds_y0 = COGL_UTIL_NEARBYINT (y_1); - base_entry->bounds_x1 = COGL_UTIL_NEARBYINT (x_2); - base_entry->bounds_y1 = COGL_UTIL_NEARBYINT (y_2); - entry->can_be_scissor = TRUE; - } - - return (CoglClipStack *) entry; -} - -CoglClipStack * -_cogl_clip_stack_push_primitive (CoglClipStack *stack, - CoglPrimitive *primitive, - float bounds_x1, - float bounds_y1, - float bounds_x2, - float bounds_y2, - CoglMatrixEntry *modelview_entry, - CoglMatrixEntry *projection_entry, - const float *viewport) -{ - CoglClipStackPrimitive *entry; - graphene_matrix_t modelview; - graphene_matrix_t projection; - float transformed_corners[8]; - - entry = _cogl_clip_stack_push_entry (stack, - sizeof (CoglClipStackPrimitive), - COGL_CLIP_STACK_PRIMITIVE); - - entry->primitive = g_object_ref (primitive); - - entry->matrix_entry = cogl_matrix_entry_ref (modelview_entry); - - entry->bounds_x1 = bounds_x1; - entry->bounds_y1 = bounds_y1; - entry->bounds_x2 = bounds_x2; - entry->bounds_y2 = bounds_y2; - - cogl_matrix_entry_get (modelview_entry, &modelview); - cogl_matrix_entry_get (projection_entry, &projection); - - get_transformed_corners (bounds_x1, bounds_y1, bounds_x2, bounds_y2, - &modelview, - &projection, - viewport, - transformed_corners); - - /* NB: this is referring to the bounds in window coordinates as opposed - * to the bounds above in primitive local coordinates. */ - _cogl_clip_stack_entry_set_bounds ((CoglClipStack *) entry, - transformed_corners); - - return (CoglClipStack *) entry; -} - -CoglClipStack * -cogl_clip_stack_push_region (CoglClipStack *stack, - MtkRegion *region) -{ - CoglClipStack *entry; - CoglClipStackRegion *entry_region; - MtkRectangle bounds; - - entry_region = _cogl_clip_stack_push_entry (stack, - sizeof (CoglClipStackRegion), - COGL_CLIP_STACK_REGION); - entry = (CoglClipStack *) entry_region; - - bounds = mtk_region_get_extents (region); - entry->bounds_x0 = bounds.x; - entry->bounds_x1 = bounds.x + bounds.width; - entry->bounds_y0 = bounds.y; - entry->bounds_y1 = bounds.y + bounds.height; - - entry_region->region = mtk_region_ref (region); - - return entry; -} - -CoglClipStack * -_cogl_clip_stack_ref (CoglClipStack *entry) -{ - /* A NULL pointer is considered a valid stack so we should accept - that as an argument */ - if (entry) - entry->ref_count++; - - return entry; -} - -void -_cogl_clip_stack_unref (CoglClipStack *entry) -{ - /* Unref all of the entries until we hit the root of the list or the - entry still has a remaining reference */ - while (entry && --entry->ref_count <= 0) - { - CoglClipStack *parent = entry->parent; - - switch (entry->type) - { - case COGL_CLIP_STACK_RECT: - { - CoglClipStackRect *rect = (CoglClipStackRect *) entry; - cogl_matrix_entry_unref (rect->matrix_entry); - g_free (entry); - break; - } - case COGL_CLIP_STACK_PRIMITIVE: - { - CoglClipStackPrimitive *primitive_entry = - (CoglClipStackPrimitive *) entry; - cogl_matrix_entry_unref (primitive_entry->matrix_entry); - g_object_unref (primitive_entry->primitive); - g_free (entry); - break; - } - case COGL_CLIP_STACK_REGION: - { - CoglClipStackRegion *region = (CoglClipStackRegion *) entry; - g_clear_pointer (®ion->region, mtk_region_unref); - g_free (entry); - break; - } - default: - g_assert_not_reached (); - } - - entry = parent; - } -} - -CoglClipStack * -_cogl_clip_stack_pop (CoglClipStack *stack) -{ - CoglClipStack *new_top; - - g_return_val_if_fail (stack != NULL, NULL); - - /* To pop we are moving the top of the stack to the old top's parent - node. The stack always needs to have a reference to the top entry - so we must take a reference to the new top. The stack would have - previously had a reference to the old top so we need to decrease - the ref count on that. We need to ref the new head first in case - this stack was the only thing referencing the old top. In that - case the call to _cogl_clip_stack_entry_unref will unref the - parent. */ - new_top = stack->parent; - - _cogl_clip_stack_ref (new_top); - - _cogl_clip_stack_unref (stack); - - return new_top; -} - -void -_cogl_clip_stack_get_bounds (CoglClipStack *stack, - int *scissor_x0, - int *scissor_y0, - int *scissor_x1, - int *scissor_y1) -{ - CoglClipStack *entry; - - *scissor_x0 = 0; - *scissor_y0 = 0; - *scissor_x1 = G_MAXINT; - *scissor_y1 = G_MAXINT; - - for (entry = stack; entry; entry = entry->parent) - { - /* Get the intersection of the current scissor and the bounding - box of this clip */ - _cogl_util_scissor_intersect (entry->bounds_x0, - entry->bounds_y0, - entry->bounds_x1, - entry->bounds_y1, - scissor_x0, - scissor_y0, - scissor_x1, - scissor_y1); - } -} - -void -_cogl_clip_stack_flush (CoglClipStack *stack, - CoglFramebuffer *framebuffer) -{ - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - ctx->driver_vtable->clip_stack_flush (stack, framebuffer); -} diff --git a/mutter/cogl/cogl/cogl-clip-stack.h b/mutter/cogl/cogl/cogl-clip-stack.h deleted file mode 100644 index e66f0dd..0000000 --- a/mutter/cogl/cogl/cogl-clip-stack.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-primitive.h" -#include "cogl/cogl-framebuffer.h" -#include "cogl/cogl-matrix-stack.h" - -/* The clip stack works like a GSList where only a pointer to the top - of the stack is stored. The empty clip stack is represented simply - by the NULL pointer. When an entry is added to or removed from the - stack the new top of the stack is returned. When an entry is pushed - a new clip stack entry is created which effectively takes ownership - of the reference on the old entry. Therefore unrefing the top entry - effectively loses ownership of all entries in the stack */ - -typedef struct _CoglClipStack CoglClipStack; -typedef struct _CoglClipStackRect CoglClipStackRect; -typedef struct _CoglClipStackWindowRect CoglClipStackWindowRect; -typedef struct _CoglClipStackPrimitive CoglClipStackPrimitive; -typedef struct _CoglClipStackRegion CoglClipStackRegion; - -typedef enum - { - COGL_CLIP_STACK_RECT, - COGL_CLIP_STACK_PRIMITIVE, - COGL_CLIP_STACK_REGION, - } CoglClipStackType; - -/* A clip stack consists a list of entries. Each entry has a reference - * count and a link to its parent node. The child takes a reference on - * the parent and the CoglClipStack holds a reference to the top of - * the stack. There are no links back from the parent to the - * children. This allows stacks that have common ancestry to share the - * entries. - * - * For example, the following sequence of operations would generate - * the tree below: - * - * CoglClipStack *stack_a = NULL; - * stack_a = _cogl_clip_stack_push_rectangle (stack_a, ...); - * stack_a = _cogl_clip_stack_push_rectangle (stack_a, ...); - * stack_a = _cogl_clip_stack_push_primitive (stack_a, ...); - * CoglClipStack *stack_b = NULL; - * stack_b = cogl_clip_stack_push_window_rectangle (stack_b, ...); - * - * stack_a - * \ holds a ref to - * +-----------+ - * | prim node | - * |ref count 1| - * +-----------+ - * \ - * +-----------+ +-----------+ - * both tops hold | rect node | | rect node | - * a ref to the |ref count 2|--|ref count 1| - * same rect node +-----------+ +-----------+ - * / - * +-----------+ - * | win. rect | - * |ref count 1| - * +-----------+ - * / holds a ref to - * stack_b - * - */ - -struct _CoglClipStack -{ - /* This will be null if there is no parent. If it is not null then - this node must be holding a reference to the parent */ - CoglClipStack *parent; - - CoglClipStackType type; - - /* All clip entries have a window-space bounding box which we can - use to calculate a scissor. The scissor limits the clip so that - we don't need to do a full stencil clear if the stencil buffer is - needed. This is stored in Cogl's coordinate space (ie, 0,0 is the - top left) */ - int bounds_x0; - int bounds_y0; - int bounds_x1; - int bounds_y1; - - unsigned int ref_count; -}; - -struct _CoglClipStackRect -{ - CoglClipStack _parent_data; - - /* The rectangle for this clip */ - float x0; - float y0; - float x1; - float y1; - - /* The matrix that was current when the clip was set */ - CoglMatrixEntry *matrix_entry; - - /* If this is true then the clip for this rectangle is entirely - described by the scissor bounds. This implies that the rectangle - is screen aligned and we don't need to use the stencil buffer to - set the clip. We keep the entry as a rect entry rather than a - window rect entry so that it will be easier to detect if the - modelview matrix is that same as when a rectangle is added to the - journal. In that case we can use the original clip coordinates - and modify the rectangle instead. */ - gboolean can_be_scissor; -}; - -struct _CoglClipStackPrimitive -{ - CoglClipStack _parent_data; - - /* The matrix that was current when the clip was set */ - CoglMatrixEntry *matrix_entry; - - CoglPrimitive *primitive; - - float bounds_x1; - float bounds_y1; - float bounds_x2; - float bounds_y2; -}; - -struct _CoglClipStackRegion -{ - CoglClipStack _parent_data; - - MtkRegion *region; -}; - -COGL_EXPORT CoglClipStack * -_cogl_clip_stack_push_rectangle (CoglClipStack *stack, - float x_1, - float y_1, - float x_2, - float y_2, - CoglMatrixEntry *modelview_entry, - CoglMatrixEntry *projection_entry, - const float *viewport); - -COGL_EXPORT CoglClipStack * -_cogl_clip_stack_push_primitive (CoglClipStack *stack, - CoglPrimitive *primitive, - float bounds_x1, - float bounds_y1, - float bounds_x2, - float bounds_y2, - CoglMatrixEntry *modelview_entry, - CoglMatrixEntry *projection_entry, - const float *viewport); -CoglClipStack * -cogl_clip_stack_push_region (CoglClipStack *stack, - MtkRegion *region); - -CoglClipStack * -_cogl_clip_stack_pop (CoglClipStack *stack); - -void -_cogl_clip_stack_get_bounds (CoglClipStack *stack, - int *scissor_x0, - int *scissor_y0, - int *scissor_x1, - int *scissor_y1); - -void -_cogl_clip_stack_flush (CoglClipStack *stack, - CoglFramebuffer *framebuffer); - -CoglClipStack * -_cogl_clip_stack_ref (CoglClipStack *stack); - -void -_cogl_clip_stack_unref (CoglClipStack *stack); diff --git a/mutter/cogl/cogl/cogl-closure-list-private.h b/mutter/cogl/cogl/cogl-closure-list-private.h deleted file mode 100644 index df08311..0000000 --- a/mutter/cogl/cogl/cogl-closure-list-private.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#pragma once - -#include "cogl/cogl-list.h" -#include "cogl/cogl-macros.h" - -/* - * This implements a list of callbacks that can be used a bit like - * signals in GObject, but that don't have any marshalling overhead. - * - * The idea is that any Cogl code that wants to provide a callback - * point will provide api to add a callback for that particular point. - * The function can take a function pointer with the correct - * signature. Internally the Cogl code can use _cogl_closure_list_add, - * _cogl_closure_disconnect and _cogl_closure_list_disconnect_all - * - * In the future we could consider exposing the CoglClosure type which - * would allow applications to use _cogl_closure_disconnect() directly - * so we don't need to expose new disconnect apis for each callback - * point. - */ - -typedef struct _CoglClosure -{ - CoglList link; - - void *function; - void *user_data; - GDestroyNotify destroy_cb; -} CoglClosure; - -/* - * _cogl_closure_disconnect: - * @closure: A closure connected to a Cogl closure list - * - * Removes the given closure from the callback list it is connected to - * and destroys it. If the closure was created with a destroy function - * then it will be invoked. */ -void -_cogl_closure_disconnect (CoglClosure *closure); - -void -_cogl_closure_list_disconnect_all (CoglList *list); - -CoglClosure * -_cogl_closure_list_add (CoglList *list, - void *function, - void *user_data, - GDestroyNotify destroy_cb); - -/* - * _cogl_closure_list_invoke: - * @list: A pointer to a CoglList containing CoglClosures - * @cb_type: The name of a typedef for the closure callback function signature - * @...: The the arguments to pass to the callback - * - * A convenience macro to invoke a closure list with a variable number - * of arguments that will be passed to the closure callback functions. - * - * Note that the arguments will be evaluated multiple times so it is - * not safe to pass expressions that have side-effects. - * - * Note also that this function ignores the return value from the - * callbacks. If you want to handle the return value you should - * manually iterate the list and invoke the callbacks yourself. - */ -#define _cogl_closure_list_invoke(list, cb_type, ...) \ - G_STMT_START { \ - CoglClosure *_c, *_tmp; \ - \ - _cogl_list_for_each_safe (_c, _tmp, (list), link) \ - { \ - cb_type _cb = _c->function; \ - _cb (__VA_ARGS__, _c->user_data); \ - } \ - } G_STMT_END - -#define _cogl_closure_list_invoke_no_args(list) \ - G_STMT_START { \ - CoglClosure *_c, *_tmp; \ - \ - _cogl_list_for_each_safe (_c, _tmp, (list), link) \ - { \ - void (*_cb)(void *) = _c->function; \ - _cb (_c->user_data); \ - } \ - } G_STMT_END diff --git a/mutter/cogl/cogl/cogl-closure-list.c b/mutter/cogl/cogl/cogl-closure-list.c deleted file mode 100644 index d146d0e..0000000 --- a/mutter/cogl/cogl/cogl-closure-list.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "config.h" - -#include - -#include "cogl/cogl-closure-list-private.h" - -void -_cogl_closure_disconnect (CoglClosure *closure) -{ - _cogl_list_remove (&closure->link); - - if (closure->destroy_cb) - closure->destroy_cb (closure->user_data); - - g_free (closure); -} - -void -_cogl_closure_list_disconnect_all (CoglList *list) -{ - CoglClosure *closure, *next; - - _cogl_list_for_each_safe (closure, next, list, link) - _cogl_closure_disconnect (closure); -} - -CoglClosure * -_cogl_closure_list_add (CoglList *list, - void *function, - void *user_data, - GDestroyNotify destroy_cb) -{ - CoglClosure *closure = g_new0 (CoglClosure, 1); - - closure->function = function; - closure->user_data = user_data; - closure->destroy_cb = destroy_cb; - - _cogl_list_insert (list, &closure->link); - - return closure; -} diff --git a/mutter/cogl/cogl/cogl-color-private.h b/mutter/cogl/cogl/cogl-color-private.h deleted file mode 100644 index 3dfe862..0000000 --- a/mutter/cogl/cogl/cogl-color-private.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-color.h" - -#include - -/* cogl-pipeline.c wants to be able to hash CoglColor data so it needs - * the exact data size to be able to avoid reading the padding bytes. - */ -#define _COGL_COLOR_DATA_SIZE 4 - -void -_cogl_color_get_rgba_4ubv (const CoglColor *color, - uint8_t *dest); - diff --git a/mutter/cogl/cogl/cogl-color.c b/mutter/cogl/cogl/cogl-color.c deleted file mode 100644 index 310243a..0000000 --- a/mutter/cogl/cogl/cogl-color.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include - -#include "cogl/cogl-util.h" -#include "cogl/cogl-color.h" -#include "cogl/cogl-color-private.h" - -G_DEFINE_BOXED_TYPE (CoglColor, - cogl_color, - cogl_color_copy, - cogl_color_free) - -CoglColor * -cogl_color_copy (const CoglColor *color) -{ - if (G_LIKELY (color)) - return g_memdup2 (color, sizeof (CoglColor)); - - return NULL; -} - -void -cogl_color_free (CoglColor *color) -{ - if (G_LIKELY (color)) - g_free (color); -} - -void -cogl_color_init_from_4f (CoglColor *color, - float red, - float green, - float blue, - float alpha) -{ - g_return_if_fail (color != NULL); - - color->red = (red * 255); - color->green = (green * 255); - color->blue = (blue * 255); - color->alpha = (alpha * 255); -} - -float -cogl_color_get_red (const CoglColor *color) -{ - return ((float) color->red / 255.0); -} - -float -cogl_color_get_green (const CoglColor *color) -{ - return ((float) color->green / 255.0); -} - -float -cogl_color_get_blue (const CoglColor *color) -{ - return ((float) color->blue / 255.0); -} - -float -cogl_color_get_alpha (const CoglColor *color) -{ - return ((float) color->alpha / 255.0); -} - -void -cogl_color_premultiply (CoglColor *color) -{ - color->red = (color->red * color->alpha + 128) / 255; - color->green = (color->green * color->alpha + 128) / 255; - color->blue = (color->blue * color->alpha + 128) / 255; -} - -gboolean -cogl_color_equal (const void *v1, const void *v2) -{ - const uint32_t *c1 = v1, *c2 = v2; - - g_return_val_if_fail (v1 != NULL, FALSE); - g_return_val_if_fail (v2 != NULL, FALSE); - - /* XXX: We don't compare the padding */ - return *c1 == *c2 ? TRUE : FALSE; -} - -void -_cogl_color_get_rgba_4ubv (const CoglColor *color, - uint8_t *dest) -{ - memcpy (dest, color, 4); -} - -void -cogl_color_to_hsl (const CoglColor *color, - float *hue, - float *saturation, - float *luminance) -{ - float red, green, blue; - float min, max, delta; - float h, l, s; - - red = color->red / 255.0; - green = color->green / 255.0; - blue = color->blue / 255.0; - - if (red > green) - { - if (red > blue) - max = red; - else - max = blue; - - if (green < blue) - min = green; - else - min = blue; - } - else - { - if (green > blue) - max = green; - else - max = blue; - - if (red < blue) - min = red; - else - min = blue; - } - - l = (max + min) / 2; - s = 0; - h = 0; - - if (max != min) - { - if (l <= 0.5) - s = (max - min) / (max + min); - else - s = (max - min) / (2.0 - max - min); - - delta = max - min; - - if (red == max) - h = (green - blue) / delta; - else if (green == max) - h = 2.0 + (blue - red) / delta; - else if (blue == max) - h = 4.0 + (red - green) / delta; - - h *= 60; - - if (h < 0) - h += 360.0; - } - - if (hue) - *hue = h; - - if (luminance) - *luminance = l; - - if (saturation) - *saturation = s; -} - -void -cogl_color_init_from_hsl (CoglColor *color, - float hue, - float saturation, - float luminance) -{ - float tmp1, tmp2; - float tmp3[3]; - float clr[3]; - int i; - - hue /= 360.0; - - if (saturation == 0) - { - cogl_color_init_from_4f (color, luminance, luminance, luminance, 1.0f); - return; - } - - if (luminance <= 0.5) - tmp2 = luminance * (1.0 + saturation); - else - tmp2 = luminance + saturation - (luminance * saturation); - - tmp1 = 2.0 * luminance - tmp2; - - tmp3[0] = hue + 1.0 / 3.0; - tmp3[1] = hue; - tmp3[2] = hue - 1.0 / 3.0; - - for (i = 0; i < 3; i++) - { - if (tmp3[i] < 0) - tmp3[i] += 1.0; - - if (tmp3[i] > 1) - tmp3[i] -= 1.0; - - if (6.0 * tmp3[i] < 1.0) - clr[i] = tmp1 + (tmp2 - tmp1) * tmp3[i] * 6.0; - else if (2.0 * tmp3[i] < 1.0) - clr[i] = tmp2; - else if (3.0 * tmp3[i] < 2.0) - clr[i] = (tmp1 + (tmp2 - tmp1) * ((2.0 / 3.0) - tmp3[i]) * 6.0); - else - clr[i] = tmp1; - } - - cogl_color_init_from_4f (color, clr[0], clr[1], clr[2], 1.0f); -} diff --git a/mutter/cogl/cogl/cogl-color.h b/mutter/cogl/cogl/cogl-color.h deleted file mode 100644 index c5526d9..0000000 --- a/mutter/cogl/cogl/cogl-color.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -/** - * CoglColor: - * - * A generic color definition - * - * #CoglColor is a simple structure holding the definition of a color such - * that it can be efficiently used by GL - */ - -#include "cogl/cogl-types.h" -#include "cogl/cogl-macros.h" - -#include - -G_BEGIN_DECLS - -#define COGL_TYPE_COLOR (cogl_color_get_type ()) - -/** - * cogl_color_get_type: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_color_get_type (void); - -/** - * cogl_color_copy: - * @color: the color to copy - * - * Creates a copy of @color - * - * Return value: a newly-allocated #CoglColor. Use cogl_color_free() - * to free the allocate resources - */ -COGL_EXPORT CoglColor * -cogl_color_copy (const CoglColor *color); - -/** - * cogl_color_free: - * @color: the color to free - * - * Frees the resources allocated by cogl_color_new() and cogl_color_copy() - */ -COGL_EXPORT void -cogl_color_free (CoglColor *color); - -/** - * cogl_color_init_from_4f: - * @color: A pointer to a #CoglColor to initialize - * @red: value of the red channel, between 0 and 1.0 - * @green: value of the green channel, between 0 and 1.0 - * @blue: value of the blue channel, between 0 and 1.0 - * @alpha: value of the alpha channel, between 0 and 1.0 - * - * Sets the values of the passed channels into a #CoglColor - */ -COGL_EXPORT void -cogl_color_init_from_4f (CoglColor *color, - float red, - float green, - float blue, - float alpha); - -/** - * cogl_color_get_red: - * @color: a #CoglColor - * - * Retrieves the red channel of @color as a fixed point - * value between 0 and 1.0. - * - * Return value: the red channel of the passed color - */ -COGL_EXPORT float -cogl_color_get_red (const CoglColor *color); - -/** - * cogl_color_get_green: - * @color: a #CoglColor - * - * Retrieves the green channel of @color as a fixed point - * value between 0 and 1.0. - * - * Return value: the green channel of the passed color - */ -COGL_EXPORT float -cogl_color_get_green (const CoglColor *color); - -/** - * cogl_color_get_blue: - * @color: a #CoglColor - * - * Retrieves the blue channel of @color as a fixed point - * value between 0 and 1.0. - * - * Return value: the blue channel of the passed color - */ -COGL_EXPORT float -cogl_color_get_blue (const CoglColor *color); - -/** - * cogl_color_get_alpha: - * @color: a #CoglColor - * - * Retrieves the alpha channel of @color as a fixed point - * value between 0 and 1.0. - * - * Return value: the alpha channel of the passed color - */ -COGL_EXPORT float -cogl_color_get_alpha (const CoglColor *color); - -/** - * cogl_color_premultiply: - * @color: the color to premultiply - * - * Converts a non-premultiplied color to a pre-multiplied color. For - * example, semi-transparent red is (1.0, 0, 0, 0.5) when non-premultiplied - * and (0.5, 0, 0, 0.5) when premultiplied. - */ -COGL_EXPORT void -cogl_color_premultiply (CoglColor *color); - -/** - * cogl_color_equal: - * @v1: a #CoglColor - * @v2: a #CoglColor - * - * Compares two `CoglColor`s and checks if they are the same. - * - * This function can be passed to g_hash_table_new() as the @key_equal_func - * parameter, when using `CoglColor`s as keys in a #GHashTable. - * - * Return value: %TRUE if the two colors are the same. - */ -COGL_EXPORT gboolean -cogl_color_equal (const void *v1, const void *v2); - -/** - * cogl_color_to_hsl: - * @color: a #CoglColor - * @hue: (out): return location for the hue value or %NULL - * @saturation: (out): return location for the saturation value or %NULL - * @luminance: (out): return location for the luminance value or %NULL - * - * Converts @color to the HLS format. - * - * The @hue value is in the 0 .. 360 range. The @luminance and - * @saturation values are in the 0 .. 1 range. - */ -COGL_EXPORT void -cogl_color_to_hsl (const CoglColor *color, - float *hue, - float *saturation, - float *luminance); - -/** - * cogl_color_init_from_hsl: - * @color: (out): return location for a #CoglColor - * @hue: hue value, in the 0 .. 360 range - * @saturation: saturation value, in the 0 .. 1 range - * @luminance: luminance value, in the 0 .. 1 range - * - * Converts a color expressed in HLS (hue, luminance and saturation) - * values into a #CoglColor. - */ -COGL_EXPORT void -cogl_color_init_from_hsl (CoglColor *color, - float hue, - float saturation, - float luminance); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-context-private.h b/mutter/cogl/cogl/cogl-context-private.h deleted file mode 100644 index cd5db0e..0000000 --- a/mutter/cogl/cogl/cogl-context-private.h +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-context.h" -#include "cogl/cogl-flags.h" - -#include "cogl/cogl-display-private.h" -#include "cogl/cogl-clip-stack.h" -#include "cogl/cogl-matrix-stack.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-buffer-private.h" -#include "cogl/cogl-bitmask.h" -#include "cogl/cogl-atlas.h" -#include "cogl/cogl-driver.h" -#include "cogl/cogl-texture-driver.h" -#include "cogl/cogl-pipeline-cache.h" -#include "cogl/cogl-texture-2d.h" -#include "cogl/cogl-sampler-cache-private.h" -#include "cogl/cogl-gl-header.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-offscreen-private.h" -#include "cogl/cogl-onscreen-private.h" -#include "cogl/cogl-fence-private.h" -#include "cogl/cogl-poll-private.h" -#include "cogl/cogl-private.h" -#include "cogl/winsys/cogl-winsys-private.h" - -typedef struct -{ - GLfloat v[3]; - GLfloat t[2]; - GLubyte c[4]; -} CoglTextureGLVertex; - -struct _CoglTimestampQuery -{ - unsigned int id; -}; - -struct _CoglContext -{ - GObject parent_instance; - - CoglDisplay *display; - - CoglDriver driver; - - /* vtables for the driver functions */ - const CoglDriverVtable *driver_vtable; - const CoglTextureDriver *texture_driver; - - void *driver_context; - - int glsl_major; - int glsl_minor; - - /* This is the GLSL version that we will claim that snippets are - * written against using the #version pragma. This will be the - * largest version that is less than or equal to the version - * provided by the driver without massively altering the syntax. Eg, - * we wouldn't use version 1.3 even if it is available because that - * removes the ‘attribute’ and ‘varying’ keywords. */ - int glsl_version_to_use; - - /* Features cache */ - unsigned long features[COGL_FLAGS_N_LONGS_FOR_SIZE (_COGL_N_FEATURE_IDS)]; - unsigned long private_features - [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)]; - - CoglPipeline *default_pipeline; - CoglPipelineLayer *default_layer_0; - CoglPipelineLayer *default_layer_n; - CoglPipelineLayer *dummy_layer_dependant; - - GHashTable *attribute_name_states_hash; - GArray *attribute_name_index_map; - int n_attribute_names; - - CoglBitmask enabled_custom_attributes; - - /* These are temporary bitmasks that are used when disabling - * builtin and custom attribute arrays. They are here just - * to avoid allocating new ones each time */ - CoglBitmask enable_custom_attributes_tmp; - CoglBitmask changed_bits_tmp; - - /* A few handy matrix constants */ - graphene_matrix_t identity_matrix; - graphene_matrix_t y_flip_matrix; - - /* The matrix stack entries that should be flushed during the next - * pipeline state flush */ - CoglMatrixEntry *current_projection_entry; - CoglMatrixEntry *current_modelview_entry; - - CoglMatrixEntry identity_entry; - - /* Only used for comparing other pipelines when reading pixels. */ - CoglPipeline *opaque_color_pipeline; - - GString *codegen_header_buffer; - GString *codegen_source_buffer; - GString *codegen_boilerplate_buffer; - - CoglPipelineCache *pipeline_cache; - - /* Textures */ - CoglTexture *default_gl_texture_2d_tex; - - /* Central list of all framebuffers so all journals can be flushed - * at any time. */ - GList *framebuffers; - - /* Global journal buffers */ - GArray *journal_flush_attributes_array; - GArray *journal_clip_bounds; - - /* Some simple caching, to minimize state changes... */ - CoglPipeline *current_pipeline; - unsigned long current_pipeline_changes_since_flush; - gboolean current_pipeline_with_color_attrib; - gboolean current_pipeline_unknown_color_alpha; - unsigned long current_pipeline_age; - - gboolean gl_blend_enable_cache; - - gboolean depth_test_enabled_cache; - CoglDepthTestFunction depth_test_function_cache; - gboolean depth_writing_enabled_cache; - float depth_range_near_cache; - float depth_range_far_cache; - - CoglBuffer *current_buffer[COGL_BUFFER_BIND_TARGET_COUNT]; - - /* Framebuffers */ - unsigned long current_draw_buffer_state_flushed; - unsigned long current_draw_buffer_changes; - CoglFramebuffer *current_draw_buffer; - CoglFramebuffer *current_read_buffer; - - gboolean have_last_offscreen_allocate_flags; - CoglOffscreenAllocateFlags last_offscreen_allocate_flags; - - GHashTable *swap_callback_closures; - int next_swap_callback_id; - - CoglList onscreen_events_queue; - CoglList onscreen_dirty_queue; - CoglClosure *onscreen_dispatch_idle; - - /* This becomes TRUE the first time the context is bound to an - * onscreen buffer. This is used by cogl-framebuffer-gl to determine - * when to initialise the glDrawBuffer state */ - gboolean was_bound_to_onscreen; - - /* Primitives */ - CoglPipeline *stencil_pipeline; - - CoglIndices *rectangle_byte_indices; - CoglIndices *rectangle_short_indices; - int rectangle_short_indices_len; - - CoglPipeline *blit_texture_pipeline; - - GSList *atlases; - GHookList atlas_reorganize_callbacks; - - /* This debugging variable is used to pick a colour for visually - displaying the quad batches. It needs to be global so that it can - be reset by cogl_clear. It needs to be reset to increase the - chances of getting the same colour during an animation */ - uint8_t journal_rectangles_color; - - /* Cached values for GL_MAX_TEXTURE_[IMAGE_]UNITS to avoid calling - glGetInteger too often */ - GLint max_texture_units; - GLint max_texture_image_units; - GLint max_activateable_texture_units; - - /* Fragment processing programs */ - GLuint current_gl_program; - - gboolean current_gl_dither_enabled; - GLenum current_gl_draw_buffer; - - /* Clipping */ - /* TRUE if we have a valid clipping stack flushed. In that case - current_clip_stack will describe what the current state is. If - this is FALSE then the current clip stack is completely unknown - so it will need to be reflushed. In that case current_clip_stack - doesn't need to be a valid pointer. We can't just use NULL in - current_clip_stack to mark a dirty state because NULL is a valid - stack (meaning no clipping) */ - gboolean current_clip_stack_valid; - /* The clip state that was flushed. This isn't intended to be used - as a stack to push and pop new entries. Instead the current stack - that the user wants is part of the framebuffer state. This is - just used to record the flush state so we can avoid flushing the - same state multiple times. When the clip state is flushed this - will hold a reference */ - CoglClipStack *current_clip_stack; - - /* This is used as a temporary buffer to fill a CoglBuffer when - cogl_buffer_map fails and we only want to map to fill it with new - data */ - GByteArray *buffer_map_fallback_array; - gboolean buffer_map_fallback_in_use; - size_t buffer_map_fallback_offset; - - CoglSamplerCache *sampler_cache; - - unsigned long winsys_features - [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_WINSYS_FEATURE_N_FEATURES)]; - void *winsys; - - /* Array of names of uniforms. These are used like quarks to give a - unique number to each uniform name except that we ensure that - they increase sequentially so that we can use the id as an index - into a bitfield representing the uniforms that a pipeline - overrides from its parent. */ - GPtrArray *uniform_names; - /* A hash table to quickly get an index given an existing name. The - name strings are owned by the uniform_names array. The values are - the uniform location cast to a pointer. */ - GHashTable *uniform_name_hash; - int n_uniform_names; - - CoglPollSource *fences_poll_source; - CoglList fences; - - GHashTable *named_pipelines; - - /* This defines a list of function pointers that Cogl uses from - either GL or GLES. All functions are accessed indirectly through - these pointers rather than linking to them directly */ -#ifndef APIENTRY -#define APIENTRY -#endif - -#define COGL_EXT_BEGIN(name, \ - min_gl_major, min_gl_minor, \ - gles_availability, \ - extension_suffixes, extension_names) -#define COGL_EXT_FUNCTION(ret, name, args) \ - ret (APIENTRY * name) args; -#define COGL_EXT_END() - -#include "gl-prototypes/cogl-all-functions.h" - -#undef COGL_EXT_BEGIN -#undef COGL_EXT_FUNCTION -#undef COGL_EXT_END -}; - -COGL_EXPORT CoglContext * -_cogl_context_get_default (void); - -const CoglWinsysVtable * -_cogl_context_get_winsys (CoglContext *context); - -/* Query the GL extensions and lookup the corresponding function - * pointers. Theoretically the list of extensions can change for - * different GL contexts so it is the winsys backend's responsibility - * to know when to re-query the GL extensions. The backend should also - * check whether the GL context is supported by Cogl. If not it should - * return FALSE and set @error */ -gboolean -_cogl_context_update_features (CoglContext *context, - GError **error); - -/* Obtains the context and returns retval if NULL */ -#define _COGL_GET_CONTEXT(ctxvar, retval) \ -CoglContext *ctxvar = _cogl_context_get_default (); \ -if (ctxvar == NULL) return retval; - -#define NO_RETVAL - -void -_cogl_context_set_current_projection_entry (CoglContext *context, - CoglMatrixEntry *entry); - -void -_cogl_context_set_current_modelview_entry (CoglContext *context, - CoglMatrixEntry *entry); - -void -_cogl_context_update_sync (CoglContext *context); diff --git a/mutter/cogl/cogl/cogl-context.c b/mutter/cogl/cogl/cogl-context.c deleted file mode 100644 index 492d495..0000000 --- a/mutter/cogl/cogl/cogl-context.c +++ /dev/null @@ -1,560 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include "cogl/cogl-mutter.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl-profile.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-display-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-journal-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-texture-2d-private.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-onscreen-private.h" -#include "cogl/cogl-attribute-private.h" -#include "cogl/cogl1-context.h" -#include "cogl/winsys/cogl-winsys-private.h" - -#include -#include -#include - -G_DEFINE_TYPE (CoglContext, cogl_context, G_TYPE_OBJECT); - - -const CoglWinsysVtable * -_cogl_context_get_winsys (CoglContext *context) -{ - return context->display->renderer->winsys_vtable; -} - -static const CoglDriverVtable * -_cogl_context_get_driver (CoglContext *context) -{ - return context->driver_vtable; -} - -static void -cogl_context_dispose (GObject *object) -{ - CoglContext *context = COGL_CONTEXT (object); - const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); - const CoglDriverVtable *driver = _cogl_context_get_driver (context); - - winsys->context_deinit (context); - - if (context->default_gl_texture_2d_tex) - g_object_unref (context->default_gl_texture_2d_tex); - - if (context->opaque_color_pipeline) - g_object_unref (context->opaque_color_pipeline); - - if (context->blit_texture_pipeline) - g_object_unref (context->blit_texture_pipeline); - - if (context->swap_callback_closures) - g_hash_table_destroy (context->swap_callback_closures); - - if (context->journal_flush_attributes_array) - g_array_free (context->journal_flush_attributes_array, TRUE); - if (context->journal_clip_bounds) - g_array_free (context->journal_clip_bounds, TRUE); - - if (context->rectangle_byte_indices) - g_object_unref (context->rectangle_byte_indices); - if (context->rectangle_short_indices) - g_object_unref (context->rectangle_short_indices); - - if (context->default_pipeline) - g_object_unref (context->default_pipeline); - - if (context->dummy_layer_dependant) - g_object_unref (context->dummy_layer_dependant); - if (context->default_layer_n) - g_object_unref (context->default_layer_n); - if (context->default_layer_0) - g_object_unref (context->default_layer_0); - - if (context->current_clip_stack_valid) - _cogl_clip_stack_unref (context->current_clip_stack); - - g_slist_free (context->atlases); - g_hook_list_clear (&context->atlas_reorganize_callbacks); - - _cogl_bitmask_destroy (&context->enabled_custom_attributes); - _cogl_bitmask_destroy (&context->enable_custom_attributes_tmp); - _cogl_bitmask_destroy (&context->changed_bits_tmp); - - if (context->current_modelview_entry) - cogl_matrix_entry_unref (context->current_modelview_entry); - if (context->current_projection_entry) - cogl_matrix_entry_unref (context->current_projection_entry); - - _cogl_pipeline_cache_free (context->pipeline_cache); - - _cogl_sampler_cache_free (context->sampler_cache); - - g_ptr_array_free (context->uniform_names, TRUE); - g_hash_table_destroy (context->uniform_name_hash); - - g_hash_table_destroy (context->attribute_name_states_hash); - g_array_free (context->attribute_name_index_map, TRUE); - - g_byte_array_free (context->buffer_map_fallback_array, TRUE); - - driver->context_deinit (context); - - g_object_unref (context->display); - - g_hash_table_remove_all (context->named_pipelines); - g_hash_table_destroy (context->named_pipelines); - - G_OBJECT_CLASS (cogl_context_parent_class)->dispose (object); -} - -static void -cogl_context_init (CoglContext *info) -{ -} - -static void -cogl_context_class_init (CoglContextClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = cogl_context_dispose; -} - -extern void -_cogl_create_context_driver (CoglContext *context); - -static CoglContext *_cogl_context = NULL; - -static void -_cogl_init_feature_overrides (CoglContext *ctx) -{ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_PBOS))) - COGL_FLAGS_SET (ctx->private_features, COGL_PRIVATE_FEATURE_PBOS, FALSE); -} - -/* For reference: There was some deliberation over whether to have a - * constructor that could throw an exception but looking at standard - * practices with several high level OO languages including python, C++, - * C# Java and Ruby they all support exceptions in constructors and the - * general consensus appears to be that throwing an exception is neater - * than successfully constructing with an internal error status that - * would then have to be explicitly checked via some form of ::is_ok() - * method. - */ -CoglContext * -cogl_context_new (CoglDisplay *display, - GError **error) -{ - CoglContext *context; - uint8_t white_pixel[] = { 0xff, 0xff, 0xff, 0xff }; - const CoglWinsysVtable *winsys; - int i; - GError *local_error = NULL; - - _cogl_init (); - -#ifdef COGL_ENABLE_PROFILE - /* We need to be absolutely sure that uprof has been initialized - * before calling _cogl_uprof_init. uprof_init (NULL, NULL) - * will be a NOP if it has been initialized but it will also - * mean subsequent parsing of the UProf GOptionGroup will have no - * affect. - * - * Sadly GOptionGroup based library initialization is extremely - * fragile by design because GOptionGroups have no notion of - * dependencies and so the order things are initialized isn't - * currently under tight control. - */ - uprof_init (NULL, NULL); - _cogl_uprof_init (); -#endif - - /* Allocate context memory */ - context = g_object_new (COGL_TYPE_CONTEXT, NULL); - - /* XXX: Gross hack! - * Currently everything in Cogl just assumes there is a default - * context which it can access via _COGL_GET_CONTEXT() including - * code used to construct a CoglContext. Until all of that code - * has been updated to take an explicit context argument we have - * to immediately make our pointer the default context. - */ - _cogl_context = context; - - /* Init default values */ - memset (context->features, 0, sizeof (context->features)); - memset (context->private_features, 0, sizeof (context->private_features)); - memset (context->winsys_features, 0, sizeof (context->winsys_features)); - - if (!display) - { - CoglRenderer *renderer = cogl_renderer_new (); - if (!cogl_renderer_connect (renderer, error)) - { - g_object_unref (renderer); - g_object_unref (context); - return NULL; - } - - display = cogl_display_new (renderer, NULL); - g_object_unref (renderer); - } - else - g_object_ref (display); - - if (!cogl_display_setup (display, error)) - { - g_object_unref (display); - g_object_unref (context); - return NULL; - } - - context->display = display; - - /* This is duplicated data, but it's much more convenient to have - the driver attached to the context and the value is accessed a - lot throughout Cogl */ - context->driver = display->renderer->driver; - - /* Again this is duplicated data, but it convenient to be able - * access these from the context. */ - context->driver_vtable = display->renderer->driver_vtable; - context->texture_driver = display->renderer->texture_driver; - - for (i = 0; i < G_N_ELEMENTS (context->private_features); i++) - context->private_features[i] |= display->renderer->private_features[i]; - - winsys = _cogl_context_get_winsys (context); - if (!winsys->context_init (context, error)) - { - g_object_unref (display); - g_free (context); - return NULL; - } - - if (!context->driver_vtable->context_init (context)) - { - g_object_unref (display); - g_object_unref (context); - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Failed to initialize context"); - return NULL; - } - - context->attribute_name_states_hash = - g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - context->attribute_name_index_map = NULL; - context->n_attribute_names = 0; - - /* The "cogl_color_in" attribute needs a deterministic name_index - * so we make sure it's the first attribute name we register */ - _cogl_attribute_register_attribute_name (context, "cogl_color_in"); - - - context->uniform_names = - g_ptr_array_new_with_free_func ((GDestroyNotify) g_free); - context->uniform_name_hash = g_hash_table_new (g_str_hash, g_str_equal); - context->n_uniform_names = 0; - - /* Initialise the driver specific state */ - _cogl_init_feature_overrides (context); - - context->sampler_cache = _cogl_sampler_cache_new (context); - - _cogl_pipeline_init_default_pipeline (context); - _cogl_pipeline_init_default_layers (context); - _cogl_pipeline_init_state_hash_functions (); - _cogl_pipeline_init_layer_state_hash_functions (); - - context->current_clip_stack_valid = FALSE; - context->current_clip_stack = NULL; - - graphene_matrix_init_identity (&context->identity_matrix); - graphene_matrix_init_identity (&context->y_flip_matrix); - graphene_matrix_scale (&context->y_flip_matrix, 1, -1, 1); - - context->opaque_color_pipeline = cogl_pipeline_new (context); - - context->codegen_header_buffer = g_string_new (""); - context->codegen_source_buffer = g_string_new (""); - context->codegen_boilerplate_buffer = g_string_new (""); - - context->default_gl_texture_2d_tex = NULL; - - context->framebuffers = NULL; - context->current_draw_buffer = NULL; - context->current_read_buffer = NULL; - context->current_draw_buffer_state_flushed = 0; - context->current_draw_buffer_changes = COGL_FRAMEBUFFER_STATE_ALL; - - context->swap_callback_closures = - g_hash_table_new (g_direct_hash, g_direct_equal); - - _cogl_list_init (&context->onscreen_events_queue); - _cogl_list_init (&context->onscreen_dirty_queue); - - context->journal_flush_attributes_array = - g_array_new (TRUE, FALSE, sizeof (CoglAttribute *)); - context->journal_clip_bounds = NULL; - - context->current_pipeline = NULL; - context->current_pipeline_changes_since_flush = 0; - context->current_pipeline_with_color_attrib = FALSE; - - _cogl_bitmask_init (&context->enabled_custom_attributes); - _cogl_bitmask_init (&context->enable_custom_attributes_tmp); - _cogl_bitmask_init (&context->changed_bits_tmp); - - context->max_texture_units = -1; - context->max_activateable_texture_units = -1; - - context->current_gl_program = 0; - - context->current_gl_dither_enabled = TRUE; - - context->gl_blend_enable_cache = FALSE; - - context->depth_test_enabled_cache = FALSE; - context->depth_test_function_cache = COGL_DEPTH_TEST_FUNCTION_LESS; - context->depth_writing_enabled_cache = TRUE; - context->depth_range_near_cache = 0; - context->depth_range_far_cache = 1; - - context->pipeline_cache = _cogl_pipeline_cache_new (context); - - for (i = 0; i < COGL_BUFFER_BIND_TARGET_COUNT; i++) - context->current_buffer[i] = NULL; - - context->stencil_pipeline = cogl_pipeline_new (context); - - context->rectangle_byte_indices = NULL; - context->rectangle_short_indices = NULL; - context->rectangle_short_indices_len = 0; - - context->blit_texture_pipeline = NULL; - - context->current_modelview_entry = NULL; - context->current_projection_entry = NULL; - _cogl_matrix_entry_identity_init (&context->identity_entry); - - /* Create default textures used for fall backs */ - context->default_gl_texture_2d_tex = - cogl_texture_2d_new_from_data (context, - 1, 1, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - 0, /* rowstride */ - white_pixel, - &local_error); - if (!context->default_gl_texture_2d_tex) - { - g_object_unref (display); - g_free (context); - g_propagate_prefixed_error (error, local_error, - "Failed to create 1x1 fallback texture: "); - return NULL; - } - - context->atlases = NULL; - g_hook_list_init (&context->atlas_reorganize_callbacks, sizeof (GHook)); - - context->buffer_map_fallback_array = g_byte_array_new (); - context->buffer_map_fallback_in_use = FALSE; - - _cogl_list_init (&context->fences); - - context->named_pipelines = - g_hash_table_new_full (NULL, NULL, NULL, g_object_unref); - - return context; -} - -CoglContext * -_cogl_context_get_default (void) -{ - GError *error = NULL; - /* Create if doesn't exist yet */ - if (_cogl_context == NULL) - { - _cogl_context = cogl_context_new (NULL, &error); - if (!_cogl_context) - { - g_warning ("Failed to create default context: %s", - error->message); - g_error_free (error); - } - } - - return _cogl_context; -} - -CoglDisplay * -cogl_context_get_display (CoglContext *context) -{ - return context->display; -} - -CoglRenderer * -cogl_context_get_renderer (CoglContext *context) -{ - return context->display->renderer; -} - -gboolean -_cogl_context_update_features (CoglContext *context, - GError **error) -{ - return context->driver_vtable->update_features (context, error); -} - -void -_cogl_context_set_current_projection_entry (CoglContext *context, - CoglMatrixEntry *entry) -{ - cogl_matrix_entry_ref (entry); - if (context->current_projection_entry) - cogl_matrix_entry_unref (context->current_projection_entry); - context->current_projection_entry = entry; -} - -void -_cogl_context_set_current_modelview_entry (CoglContext *context, - CoglMatrixEntry *entry) -{ - cogl_matrix_entry_ref (entry); - if (context->current_modelview_entry) - cogl_matrix_entry_unref (context->current_modelview_entry); - context->current_modelview_entry = entry; -} - -void -_cogl_context_update_sync (CoglContext *context) -{ - const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); - - if (!winsys->update_sync) - return; - - winsys->update_sync (context); -} - -int -cogl_context_get_latest_sync_fd (CoglContext *context) -{ - const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); - - if (!winsys->get_sync_fd) - return -1; - - return winsys->get_sync_fd (context); -} - -CoglGraphicsResetStatus -cogl_get_graphics_reset_status (CoglContext *context) -{ - return context->driver_vtable->get_graphics_reset_status (context); -} - -gboolean -cogl_context_is_hardware_accelerated (CoglContext *context) -{ - return context->driver_vtable->is_hardware_accelerated (context); -} - -gboolean -cogl_context_format_supports_upload (CoglContext *ctx, - CoglPixelFormat format) -{ - return ctx->texture_driver->format_supports_upload (ctx, format); -} - -void -cogl_context_set_named_pipeline (CoglContext *context, - CoglPipelineKey *key, - CoglPipeline *pipeline) -{ - if (pipeline) - { - g_debug ("Adding named pipeline %s", *key); - g_hash_table_insert (context->named_pipelines, (gpointer) key, pipeline); - } - else - { - g_debug ("Removing named pipeline %s", *key); - g_hash_table_remove (context->named_pipelines, (gpointer) key); - } -} - -CoglPipeline * -cogl_context_get_named_pipeline (CoglContext *context, - CoglPipelineKey *key) -{ - return g_hash_table_lookup (context->named_pipelines, key); -} - -/** - * cogl_context_free_timestamp_query: - * @context: a #CoglContext object - * @query: (transfer full): the #CoglTimestampQuery to free - * - * Free the #CoglTimestampQuery - */ -void -cogl_context_free_timestamp_query (CoglContext *context, - CoglTimestampQuery *query) -{ - context->driver_vtable->free_timestamp_query (context, query); -} - -int64_t -cogl_context_timestamp_query_get_time_ns (CoglContext *context, - CoglTimestampQuery *query) -{ - return context->driver_vtable->timestamp_query_get_time_ns (context, query); -} - -int64_t -cogl_context_get_gpu_time_ns (CoglContext *context) -{ - g_return_val_if_fail (cogl_has_feature (context, - COGL_FEATURE_ID_TIMESTAMP_QUERY), - 0); - - return context->driver_vtable->get_gpu_time_ns (context); -} diff --git a/mutter/cogl/cogl/cogl-context.h b/mutter/cogl/cogl/cogl-context.h deleted file mode 100644 index fba7bed..0000000 --- a/mutter/cogl/cogl/cogl-context.h +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -/* We forward declare the CoglContext type here to avoid some circular - * dependency issues with the following headers. - */ -typedef struct _CoglContext CoglContext; -typedef struct _CoglTimestampQuery CoglTimestampQuery; - -#include "cogl/cogl-display.h" -#include "cogl/cogl-pipeline.h" -#include "cogl/cogl-primitive.h" - -#include - -G_BEGIN_DECLS - -/** - * CoglContext: - * - * The top level application context. - * - * A #CoglContext is the top most sandbox of Cogl state for an - * application or toolkit. Its main purpose is to act as a sandbox - * for the memory management of state objects. Normally an application - * will only create a single context since there is no way to share - * resources between contexts. - * - * For those familiar with OpenGL or perhaps Cairo it should be - * understood that unlike these APIs a Cogl context isn't a rendering - * context as such. In other words Cogl doesn't aim to provide a state - * machine style model for configuring rendering parameters. Most - * rendering state in Cogl is directly associated with user managed - * objects called pipelines and geometry is drawn with a specific - * pipeline object to a framebuffer object and those 3 things fully - * define the state for drawing. This is an important part of Cogl's - * design since it helps you write orthogonal rendering components - * that can all access the same GPU without having to worry about - * what state other components have left you with. - * - * Cogl does not maintain internal references to the context for - * resources that depend on the context so applications. This is to - * help applications control the lifetime a context without us needing to - * introduce special api to handle the breakup of internal circular - * references due to internal resources and caches associated with the - * context. - * - * One a context has been destroyed then all directly or indirectly - * dependent resources will be in an inconsistent state and should not - * be manipulated or queried in any way. - * - * For applications that rely on the operating system to clean up - * resources this policy shouldn't affect them, but for applications - * that need to carefully destroy and re-create Cogl contexts multiple - * times throughout their lifetime (such as Android applications) they - * should be careful to destroy all context dependent resources, such as - * framebuffers or textures etc before unrefing and destroying the - * context. - */ - -#define COGL_TYPE_CONTEXT (cogl_context_get_type ()) - -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglContext, - cogl_context, - COGL, - CONTEXT, - GObject) - -/** - * cogl_context_new: (constructor) - * @display: (allow-none): A #CoglDisplay pointer - * @error: A GError return location. - * - * Creates a new #CoglContext which acts as an application sandbox - * for any state objects that are allocated. - * - * Return value: (transfer full): A newly allocated #CoglContext - */ -COGL_EXPORT CoglContext * -cogl_context_new (CoglDisplay *display, - GError **error); - -/** - * cogl_context_get_display: - * @context: A #CoglContext pointer - * - * Retrieves the #CoglDisplay that is internally associated with the - * given @context. This will return the same #CoglDisplay that was - * passed to cogl_context_new() or if %NULL was passed to - * cogl_context_new() then this function returns a pointer to the - * display that was automatically setup internally. - * - * Return value: (transfer none): The #CoglDisplay associated with the - * given @context. - */ -COGL_EXPORT CoglDisplay * -cogl_context_get_display (CoglContext *context); - -/** - * cogl_context_get_renderer: - * @context: A #CoglContext pointer - * - * Retrieves the #CoglRenderer that is internally associated with the - * given @context. This will return the same #CoglRenderer that was - * passed to cogl_display_new() or if %NULL was passed to - * cogl_display_new() or cogl_context_new() then this function returns - * a pointer to the renderer that was automatically connected - * internally. - * - * Return value: (transfer none): The #CoglRenderer associated with the - * given @context. - */ -COGL_EXPORT CoglRenderer * -cogl_context_get_renderer (CoglContext *context); - - -/* XXX: not guarded by the EXPERIMENTAL_API defines to avoid - * upsetting glib-mkenums, but this can still be considered implicitly - * experimental since it's only useable with experimental API... */ -/** - * CoglFeatureID: - * @COGL_FEATURE_ID_TEXTURE_RG: Support for - * %COGL_TEXTURE_COMPONENTS_RG as the internal components of a - * texture. - * @COGL_FEATURE_ID_TEXTURE_RGBA1010102: Support for 10bpc RGBA formats - * @COGL_FEATURE_ID_TEXTURE_HALF_FLOAT: Support for half float formats - * @COGL_FEATURE_ID_TEXTURE_NORM16: Support for 16bpc formats - * @COGL_FEATURE_ID_UNSIGNED_INT_INDICES: Set if - * %COGL_INDICES_TYPE_UNSIGNED_INT is supported in - * cogl_indices_new(). - * @COGL_FEATURE_ID_MAP_BUFFER_FOR_READ: Whether cogl_buffer_map() is - * supported with CoglBufferAccess including read support. - * @COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE: Whether cogl_buffer_map() is - * supported with CoglBufferAccess including write support. - * @COGL_FEATURE_ID_BUFFER_AGE: Available if the age of #CoglOnscreen back - * buffers are tracked and so cogl_onscreen_get_buffer_age() can be - * expected to return age values other than 0. - * @COGL_FEATURE_ID_BLIT_FRAMEBUFFER: Whether blitting using - * cogl_blit_framebuffer() is supported. - * - * All the capabilities that can vary between different GPUs supported - * by Cogl. Applications that depend on any of these features should explicitly - * check for them using cogl_has_feature() or cogl_has_features(). - */ -typedef enum _CoglFeatureID -{ - COGL_FEATURE_ID_UNSIGNED_INT_INDICES, - COGL_FEATURE_ID_MAP_BUFFER_FOR_READ, - COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, - COGL_FEATURE_ID_FENCE, - COGL_FEATURE_ID_TEXTURE_RG, - COGL_FEATURE_ID_TEXTURE_RGBA1010102, - COGL_FEATURE_ID_TEXTURE_HALF_FLOAT, - COGL_FEATURE_ID_TEXTURE_NORM16, - COGL_FEATURE_ID_BUFFER_AGE, - COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL, - COGL_FEATURE_ID_BLIT_FRAMEBUFFER, - COGL_FEATURE_ID_TIMESTAMP_QUERY, - - /*< private >*/ - _COGL_N_FEATURE_IDS /*< skip >*/ -} CoglFeatureID; - - -/** - * cogl_has_feature: - * @context: A #CoglContext pointer - * @feature: A #CoglFeatureID - * - * Checks if a given @feature is currently available - * - * Cogl does not aim to be a lowest common denominator API, it aims to - * expose all the interesting features of GPUs to application which - * means applications have some responsibility to explicitly check - * that certain features are available before depending on them. - * - * Returns: %TRUE if the @feature is currently supported or %FALSE if - * not. - */ -COGL_EXPORT gboolean -cogl_has_feature (CoglContext *context, CoglFeatureID feature); - -/** - * cogl_has_features: - * @context: A #CoglContext pointer - * @...: A 0 terminated list of `CoglFeatureID`s - * - * Checks if a list of features are all currently available. - * - * This checks all of the listed features using cogl_has_feature() and - * returns %TRUE if all the features are available or %FALSE - * otherwise. - * - * Return value: %TRUE if all the features are available, %FALSE - * otherwise. - */ -COGL_EXPORT gboolean -cogl_has_features (CoglContext *context, ...); - -/** - * CoglFeatureCallback: - * @feature: A single feature currently supported by Cogl - * @user_data: A private pointer passed to cogl_foreach_feature(). - * - * A callback used with cogl_foreach_feature() for enumerating all - * context level features supported by Cogl. - */ -typedef void (*CoglFeatureCallback) (CoglFeatureID feature, void *user_data); - -/** - * cogl_foreach_feature: - * @context: A #CoglContext pointer - * @callback: (scope call): A #CoglFeatureCallback called for each - * supported feature - * @user_data: (closure): Private data to pass to the callback - * - * Iterates through all the context level features currently supported - * for a given @context and for each feature @callback is called. - */ -COGL_EXPORT void -cogl_foreach_feature (CoglContext *context, - CoglFeatureCallback callback, - void *user_data); - -/** - * CoglGraphicsResetStatus: - * @COGL_GRAPHICS_RESET_STATUS_NO_ERROR: - * @COGL_GRAPHICS_RESET_STATUS_GUILTY_CONTEXT_RESET: - * @COGL_GRAPHICS_RESET_STATUS_INNOCENT_CONTEXT_RESET: - * @COGL_GRAPHICS_RESET_STATUS_UNKNOWN_CONTEXT_RESET: - * @COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET: - * - * All the error values that might be returned by - * cogl_get_graphics_reset_status(). Each value's meaning corresponds - * to the similarly named value defined in the ARB_robustness and - * NV_robustness_video_memory_purge extensions. - */ -typedef enum _CoglGraphicsResetStatus -{ - COGL_GRAPHICS_RESET_STATUS_NO_ERROR, - COGL_GRAPHICS_RESET_STATUS_GUILTY_CONTEXT_RESET, - COGL_GRAPHICS_RESET_STATUS_INNOCENT_CONTEXT_RESET, - COGL_GRAPHICS_RESET_STATUS_UNKNOWN_CONTEXT_RESET, - COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET, -} CoglGraphicsResetStatus; - -/** - * cogl_get_graphics_reset_status: - * @context: a #CoglContext pointer - * - * Returns the graphics reset status as reported by - * GetGraphicsResetStatusARB defined in the ARB_robustness extension. - * - * Note that Cogl doesn't normally enable the ARB_robustness - * extension in which case this will only ever return - * #COGL_GRAPHICS_RESET_STATUS_NO_ERROR. - * - * Applications must explicitly use a backend specific method to - * request that errors get reported such as X11's - * cogl_xlib_renderer_request_reset_on_video_memory_purge(). - * - * Return value: a #CoglGraphicsResetStatus - */ -COGL_EXPORT CoglGraphicsResetStatus -cogl_get_graphics_reset_status (CoglContext *context); - -/** - * cogl_context_is_hardware_accelerated: - * @context: a #CoglContext pointer - * - * Returns: %TRUE if the @context is hardware accelerated, or %FALSE if - * not. - */ -COGL_EXPORT gboolean -cogl_context_is_hardware_accelerated (CoglContext *context); - -typedef const char * const CoglPipelineKey; - -/** - * cogl_context_set_named_pipeline: - * @context: a #CoglContext pointer - * @key: a #CoglPipelineKey pointer - * @pipeline: (nullable): a #CoglPipeline to associate with the @context and - * @key - * - * Associate a #CoglPipeline with a @context and @key. This will not take a new - * reference to the @pipeline, but will unref all associated pipelines when - * the @context gets destroyed. Similarly, if a pipeline gets overwritten, - * it will get unreffed as well. - */ -COGL_EXPORT void -cogl_context_set_named_pipeline (CoglContext *context, - CoglPipelineKey *key, - CoglPipeline *pipeline); - -/** - * cogl_context_get_named_pipeline: - * @context: a #CoglContext pointer - * @key: a #CoglPipelineKey pointer - * - * Return value: (transfer none): The #CoglPipeline associated with the - * given @context and @key, or %NULL if no such #CoglPipeline - * was found. - */ -COGL_EXPORT CoglPipeline * -cogl_context_get_named_pipeline (CoglContext *context, - CoglPipelineKey *key); - -/** - * cogl_context_free_timestamp_query: - * @context: a #CoglContext pointer - * @query: (transfer full): a #CoglTimestampQuery - */ -COGL_EXPORT void -cogl_context_free_timestamp_query (CoglContext *context, - CoglTimestampQuery *query); - -COGL_EXPORT int64_t -cogl_context_timestamp_query_get_time_ns (CoglContext *context, - CoglTimestampQuery *query); - -/** - * cogl_context_get_gpu_time_ns: - * @context: a #CoglContext pointer - * - * This function should only be called if the COGL_FEATURE_ID_TIMESTAMP_QUERY - * feature is advertised. - * - * Return value: Current GPU time in nanoseconds - */ -COGL_EXPORT int64_t -cogl_context_get_gpu_time_ns (CoglContext *context); - -/** - * cogl_context_get_latest_sync_fd - * @context: a #CoglContext pointer - * - * This function is used to get support for waiting on previous - * GPU work through sync fds. It will return a sync fd which will - * signal when the previous work has completed. - * - * Return value: sync fd for latest GPU submission if available, - * returns -1 if not. - */ -COGL_EXPORT int -cogl_context_get_latest_sync_fd (CoglContext *context); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-cpu-caps.c b/mutter/cogl/cogl/cogl-cpu-caps.c deleted file mode 100644 index 559caee..0000000 --- a/mutter/cogl/cogl/cogl-cpu-caps.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2022 Red Hat Inc - * Copyright 2008 Dennis Smit - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* CPU capability discovery code comes from lp_cpu_detect.c in mesa. */ - -#include "config.h" - -#include "cogl/cogl-cpu-caps.h" - -#include - -CoglCpuCaps cogl_cpu_caps; - -#ifdef __x86_64 -static inline uint64_t -xgetbv (void) -{ -#ifdef __GCC_ASM_FLAG_OUTPUTS__ - uint32_t eax, edx; - - __asm __volatile ( - ".byte 0x0f, 0x01, 0xd0" /* xgetbv isn't supported on gcc < 4.4 */ - : "=a"(eax), - "=d"(edx) - : "c"(0) - ); - - return ((uint64_t) edx << 32) | eax; -#else - return 0; -#endif -} - -static inline void -cpuid (uint32_t ax, - uint32_t *p) -{ -#ifdef __GCC_ASM_FLAG_OUTPUTS__ - __asm __volatile ( - "cpuid\n\t" - : "=a" (p[0]), - "=b" (p[1]), - "=c" (p[2]), - "=d" (p[3]) - : "0" (ax) - ); -#else - p[0] = 0; - p[1] = 0; - p[2] = 0; - p[3] = 0; -#endif -} -#endif - -void -cogl_init_cpu_caps (void) -{ -#ifdef __x86_64 - uint32_t regs[4]; - - cpuid (0x00000000, regs); - - if (regs[0] >= 0x00000001) - { - uint32_t regs2[4]; - gboolean has_avx; - - cpuid (0x00000001, regs2); - - has_avx = (((regs2[2] >> 28) & 1) && /* AVX */ - ((regs2[2] >> 27) & 1) && /* OSXSAVE */ - ((xgetbv () & 6) == 6)); /* XMM & YMM */ - if (((regs2[2] >> 29) & 1) && has_avx) - cogl_cpu_caps |= COGL_CPU_CAP_F16C; - } -#endif -} diff --git a/mutter/cogl/cogl/cogl-cpu-caps.h b/mutter/cogl/cogl/cogl-cpu-caps.h deleted file mode 100644 index 162e5b8..0000000 --- a/mutter/cogl/cogl/cogl-cpu-caps.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2022 Red Hat Inc - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef COGL_CPU_CAPS_H -#define COGL_CPU_CAPS_H - -#include "cogl/cogl-types.h" - -#include - -typedef enum _CoglCpuCaps -{ - COGL_CPU_CAP_F16C = 1 << 0, -} CoglCpuCaps; - -COGL_EXPORT -CoglCpuCaps cogl_cpu_caps; - -void cogl_init_cpu_caps (void); - -static inline gboolean -cogl_cpu_has_cap (CoglCpuCaps cap) -{ - return !!(cogl_cpu_caps & cap); -} - -#endif /* COGL_CPU_CAPS_H */ diff --git a/mutter/cogl/cogl/cogl-debug-options.h b/mutter/cogl/cogl/cogl-debug-options.h deleted file mode 100644 index e6b1ca4..0000000 --- a/mutter/cogl/cogl/cogl-debug-options.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -OPT (OBJECT, - N_("Cogl Tracing"), - "ref-counts", - N_("CoglObject references"), - N_("Debug ref counting issues for CoglObjects")) -OPT (SLICING, - N_("Cogl Tracing"), - "slicing", - N_("Trace Texture Slicing"), - N_("debug the creation of texture slices")) -OPT (ATLAS, - N_("Cogl Tracing"), - "atlas", - N_("Trace Atlas Textures"), - N_("Debug texture atlas management")) -OPT (BLEND_STRINGS, - N_("Cogl Tracing"), - "blend-strings", - N_("Trace Blend Strings"), - N_("Debug CoglBlendString parsing")) -OPT (JOURNAL, - N_("Cogl Tracing"), - "journal", - N_("Trace Journal"), - N_("View all the geometry passing through the journal")) -OPT (BATCHING, - N_("Cogl Tracing"), - "batching", - N_("Trace Batching"), - N_("Show how geometry is being batched in the journal")) -OPT (MATRICES, - N_("Cogl Tracing"), - "matrices", - N_("Trace matrices"), - N_("Trace all matrix manipulation")) -/* XXX we should replace the "draw" option its very hand wavy... */ -OPT (DRAW, - N_("Cogl Tracing"), - "draw", - N_("Trace Misc Drawing"), - N_("Trace some misc drawing operations")) -OPT (PANGO, - N_("Cogl Tracing"), - "pango", - N_("Trace Pango Renderer"), - N_("Trace the Cogl Pango renderer")) -OPT (TEXTURE_PIXMAP, - N_("Cogl Tracing"), - "texture-pixmap", - N_("Trace CoglTexturePixmap backend"), - N_("Trace the Cogl texture pixmap backend")) -OPT (RECTANGLES, - N_("Visualize"), - "rectangles", - N_("Outline rectangles"), - N_("Add wire outlines for all rectangular geometry")) -OPT (WIREFRAME, - N_("Visualize"), - "wireframe", - N_("Show wireframes"), - N_("Add wire outlines for all geometry")) -OPT (DISABLE_BATCHING, - N_("Root Cause"), - "disable-batching", - N_("Disable Journal batching"), - N_("Disable batching of geometry in the Cogl Journal.")) -OPT (DISABLE_PBOS, - N_("Root Cause"), - "disable-pbos", - N_("Disable GL Pixel Buffers"), - N_("Disable use of OpenGL pixel buffer objects")) -OPT (DISABLE_SOFTWARE_TRANSFORM, - N_("Root Cause"), - "disable-software-transform", - N_("Disable software rect transform"), - N_("Use the GPU to transform rectangular geometry")) -OPT (DUMP_ATLAS_IMAGE, - N_("Cogl Specialist"), - "dump-atlas-image", - N_("Dump atlas images"), - N_("Dump texture atlas changes to an image file")) -OPT (DISABLE_ATLAS, - N_("Root Cause"), - "disable-atlas", - N_("Disable texture atlasing"), - N_("Disable use of texture atlasing")) -OPT (DISABLE_SHARED_ATLAS, - N_("Root Cause"), - "disable-shared-atlas", - N_("Disable sharing the texture atlas between text and images"), - N_("When this is set the glyph cache will always use a separate texture " - "for its atlas. Otherwise it will try to share the atlas with images.")) -OPT (DISABLE_TEXTURING, - N_("Root Cause"), - "disable-texturing", - N_("Disable texturing"), - N_("Disable texturing any primitives")) -OPT (DISABLE_BLENDING, - N_("Root Cause"), - "disable-blending", - N_("Disable blending"), - N_("Disable use of blending")) -OPT (DISABLE_SOFTWARE_CLIP, - N_("Root Cause"), - "disable-software-clip", - N_("Disable software clipping"), - N_("Disables Cogl's attempts to clip some rectangles in software.")) -OPT (SHOW_SOURCE, - N_("Cogl Tracing"), - "show-source", - N_("Show source"), - N_("Show generated GLSL source code")) -OPT (OPENGL, - N_("Cogl Tracing"), - "opengl", - N_("Trace some OpenGL"), - N_("Traces some select OpenGL calls")) -OPT (OFFSCREEN, - N_("Cogl Tracing"), - "offscreen", - N_("Trace offscreen support"), - N_("Debug offscreen support")) -OPT (DISABLE_BLENDING, - N_("Root Cause"), - "disable-program-caches", - N_("Disable program caches"), - N_("Disable fallback caches for glsl programs")) -OPT (DISABLE_FAST_READ_PIXEL, - N_("Root Cause"), - "disable-fast-read-pixel", - N_("Disable read pixel optimization"), - N_("Disable optimization for reading 1px for simple " - "scenes of opaque rectangles")) -OPT (CLIPPING, - N_("Cogl Tracing"), - "clipping", - N_("Trace clipping"), - N_("Logs information about how Cogl is implementing clipping")) -OPT (PERFORMANCE, - N_("Cogl Tracing"), - "performance", - N_("Trace performance concerns"), - N_("Tries to highlight sub-optimal Cogl usage.")) -OPT (SYNC_PRIMITIVE, - N_("Root Cause"), - "sync-primitive", - N_("Render primitives synchronously"), - N_("Call glFinish after rendering each primitive, so profilers can see " - "the call stack of what's incurring most of the render time.")) -OPT (SYNC_FRAME, - N_("Root Cause"), - "sync-frame", - N_("Render frames synchronously"), - N_("Call glFinish after rendering each frame, so profilers can measure " - "the total render time (as a portion of the stage update time) more " - "accurately.")) -OPT (TEXTURES, - N_("Cogl Tracing"), - "textures", - N_("Debug texture management"), - N_("Logs information about texture management")) -OPT (STENCILLING, - N_("Root Cause"), - "stencilling", - N_("Stencil every clip entry"), - N_("Disables optimizations that usually avoid stencilling when it's not " - "needed. This exercises more of the stencilling logic than usual.")) diff --git a/mutter/cogl/cogl/cogl-debug.c b/mutter/cogl/cogl/cogl-debug.c deleted file mode 100644 index 2cf0eeb..0000000 --- a/mutter/cogl/cogl/cogl-debug.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include - -#include "cogl/cogl-i18n-private.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl-debug.h" -#include "cogl/cogl1-context.h" - -/* XXX: If you add a debug option, please also add an option - * definition to cogl-debug-options.h. This will enable us - for - * example - to emit a "help" description for the option. - */ - -/* NB: Only these options get enabled if COGL_DEBUG=all is - * used since they don't affect the behaviour of Cogl they - * simply print out verbose information */ -static const GDebugKey cogl_log_debug_keys[] = { - { "object", COGL_DEBUG_OBJECT }, - { "slicing", COGL_DEBUG_SLICING }, - { "atlas", COGL_DEBUG_ATLAS }, - { "blend-strings", COGL_DEBUG_BLEND_STRINGS }, - { "journal", COGL_DEBUG_JOURNAL }, - { "batching", COGL_DEBUG_BATCHING }, - { "matrices", COGL_DEBUG_MATRICES }, - { "draw", COGL_DEBUG_DRAW }, - { "opengl", COGL_DEBUG_OPENGL }, - { "pango", COGL_DEBUG_PANGO }, - { "show-source", COGL_DEBUG_SHOW_SOURCE}, - { "framebuffer", COGL_DEBUG_FRAMEBUFFER }, - { "offscreen", COGL_DEBUG_OFFSCREEN }, - { "texture-pixmap", COGL_DEBUG_TEXTURE_PIXMAP }, - { "bitmap", COGL_DEBUG_BITMAP }, - { "clipping", COGL_DEBUG_CLIPPING }, - { "winsys", COGL_DEBUG_WINSYS }, - { "performance", COGL_DEBUG_PERFORMANCE }, - { "textures", COGL_DEBUG_TEXTURES }, -}; -static const int n_cogl_log_debug_keys = - G_N_ELEMENTS (cogl_log_debug_keys); - -static const GDebugKey cogl_behavioural_debug_keys[] = { - { "rectangles", COGL_DEBUG_RECTANGLES }, - { "disable-batching", COGL_DEBUG_DISABLE_BATCHING }, - { "disable-pbos", COGL_DEBUG_DISABLE_PBOS }, - { "disable-software-transform", COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM }, - { "disable-atlas", COGL_DEBUG_DISABLE_ATLAS }, - { "disable-shared-atlas", COGL_DEBUG_DISABLE_SHARED_ATLAS }, - { "disable-texturing", COGL_DEBUG_DISABLE_TEXTURING}, - { "disable-blending", COGL_DEBUG_DISABLE_BLENDING}, - { "wireframe", COGL_DEBUG_WIREFRAME}, - { "disable-software-clip", COGL_DEBUG_DISABLE_SOFTWARE_CLIP}, - { "disable-program-caches", COGL_DEBUG_DISABLE_PROGRAM_CACHES}, - { "disable-fast-read-pixel", COGL_DEBUG_DISABLE_FAST_READ_PIXEL}, - { "sync-primitive", COGL_DEBUG_SYNC_PRIMITIVE }, - { "sync-frame", COGL_DEBUG_SYNC_FRAME}, - { "stencilling", COGL_DEBUG_STENCILLING }, -}; -static const int n_cogl_behavioural_debug_keys = - G_N_ELEMENTS (cogl_behavioural_debug_keys); - -unsigned long _cogl_debug_flags[COGL_DEBUG_N_LONGS]; -GHashTable *_cogl_debug_instances; - -static void -_cogl_parse_debug_string_for_keys (const char *value, - gboolean enable, - const GDebugKey *keys, - unsigned int nkeys) -{ - int long_num, key_num; - - /* g_parse_debug_string expects the value field in GDebugKey to be a - mask in an unsigned int but the flags are stored in an array of - multiple longs so we need to build a separate array for each - possible unsigned int */ - - for (long_num = 0; long_num < COGL_DEBUG_N_LONGS; long_num++) - { - int int_num; - - for (int_num = 0; - int_num < sizeof (unsigned long) / sizeof (unsigned int); - int_num++) - { - GDebugKey keys_for_int[sizeof (unsigned int) * 8]; - int nkeys_for_int = 0; - - for (key_num = 0; key_num < nkeys; key_num++) - { - int long_index = COGL_FLAGS_GET_INDEX (keys[key_num].value); - int int_index = (keys[key_num].value % - (sizeof (unsigned long) * 8) / - (sizeof (unsigned int) * 8)); - - if (long_index == long_num && int_index == int_num) - { - keys_for_int[nkeys_for_int] = keys[key_num]; - keys_for_int[nkeys_for_int].value = - COGL_FLAGS_GET_MASK (keys[key_num].value) >> - (int_num * sizeof (unsigned int) * 8); - nkeys_for_int++; - } - } - - if (nkeys_for_int > 0) - { - unsigned long mask = - ((unsigned long) g_parse_debug_string (value, - keys_for_int, - nkeys_for_int)) << - (int_num * sizeof (unsigned int) * 8); - - if (enable) - _cogl_debug_flags[long_num] |= mask; - else - _cogl_debug_flags[long_num] &= ~mask; - } - } - } -} - -void -_cogl_parse_debug_string (const char *value, - gboolean enable, - gboolean ignore_help) -{ - if (ignore_help && strcmp (value, "help") == 0) - return; - - /* We don't want to let g_parse_debug_string handle "all" because - * literally enabling all the debug options wouldn't be useful to - * anyone; instead the all option enables all non behavioural - * options. - */ - if (strcmp (value, "all") == 0 || - strcmp (value, "verbose") == 0) - { - int i; - for (i = 0; i < n_cogl_log_debug_keys; i++) - if (enable) - COGL_DEBUG_SET_FLAG (cogl_log_debug_keys[i].value); - else - COGL_DEBUG_CLEAR_FLAG (cogl_log_debug_keys[i].value); - } - else if (g_ascii_strcasecmp (value, "help") == 0) - { - g_printerr ("\n\n%28s\n", _("Supported debug values:")); -#define OPT(MASK_NAME, GROUP, NAME, NAME_FORMATTED, DESCRIPTION) \ - g_printerr ("%28s %s\n", NAME ":", DESCRIPTION); -#include "cogl/cogl-debug-options.h" - g_printerr ("\n%28s\n", _("Special debug values:")); - OPT (IGNORED, "ignored", "all", "ignored", \ - N_("Enables all non-behavioural debug options")); - OPT (IGNORED, "ignored", "verbose", "ignored", \ - N_("Enables all non-behavioural debug options")); -#undef OPT - - g_printerr ("\n" - "%28s\n" - " COGL_DISABLE_GL_EXTENSIONS: %s\n" - " COGL_OVERRIDE_GL_VERSION: %s\n", - _("Additional environment variables:"), - _("Comma-separated list of GL extensions to pretend are " - "disabled"), - _("Override the GL version that Cogl will assume the driver " - "supports")); - exit (1); - } - else - { - _cogl_parse_debug_string_for_keys (value, - enable, - cogl_log_debug_keys, - n_cogl_log_debug_keys); - _cogl_parse_debug_string_for_keys (value, - enable, - cogl_behavioural_debug_keys, - n_cogl_behavioural_debug_keys); - } -} - -void -_cogl_debug_check_environment (void) -{ - const char *env_string; - - env_string = g_getenv ("COGL_DEBUG"); - if (env_string != NULL) - { - _cogl_parse_debug_string (env_string, - TRUE /* enable the flags */, - FALSE /* don't ignore help */); - env_string = NULL; - } - - env_string = g_getenv ("COGL_NO_DEBUG"); - if (env_string != NULL) - { - _cogl_parse_debug_string (env_string, - FALSE /* disable the flags */, - FALSE /* don't ignore help */); - env_string = NULL; - } -} diff --git a/mutter/cogl/cogl/cogl-debug.h b/mutter/cogl/cogl/cogl-debug.h deleted file mode 100644 index 80980ad..0000000 --- a/mutter/cogl/cogl/cogl-debug.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-profile.h" -#include "cogl/cogl-flags.h" -#include "cogl/cogl-util.h" - -#include - -G_BEGIN_DECLS - -typedef enum -{ - COGL_DEBUG_SLICING, - COGL_DEBUG_FRAMEBUFFER, - COGL_DEBUG_OFFSCREEN, - COGL_DEBUG_DRAW, - COGL_DEBUG_PANGO, - COGL_DEBUG_RECTANGLES, - COGL_DEBUG_OBJECT, - COGL_DEBUG_BLEND_STRINGS, - COGL_DEBUG_DISABLE_BATCHING, - COGL_DEBUG_DISABLE_PBOS, - COGL_DEBUG_JOURNAL, - COGL_DEBUG_BATCHING, - COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM, - COGL_DEBUG_MATRICES, - COGL_DEBUG_ATLAS, - COGL_DEBUG_DISABLE_ATLAS, - COGL_DEBUG_DISABLE_SHARED_ATLAS, - COGL_DEBUG_OPENGL, - COGL_DEBUG_DISABLE_TEXTURING, - COGL_DEBUG_SHOW_SOURCE, - COGL_DEBUG_DISABLE_BLENDING, - COGL_DEBUG_TEXTURE_PIXMAP, - COGL_DEBUG_BITMAP, - COGL_DEBUG_WIREFRAME, - COGL_DEBUG_DISABLE_SOFTWARE_CLIP, - COGL_DEBUG_DISABLE_PROGRAM_CACHES, - COGL_DEBUG_DISABLE_FAST_READ_PIXEL, - COGL_DEBUG_CLIPPING, - COGL_DEBUG_WINSYS, - COGL_DEBUG_PERFORMANCE, - COGL_DEBUG_SYNC_PRIMITIVE, - COGL_DEBUG_SYNC_FRAME, - COGL_DEBUG_TEXTURES, - COGL_DEBUG_STENCILLING, - - COGL_DEBUG_N_FLAGS -} CoglDebugFlags; - -COGL_EXPORT -GHashTable *_cogl_debug_instances; -#define COGL_DEBUG_N_LONGS COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_DEBUG_N_FLAGS) - -COGL_EXPORT -unsigned long _cogl_debug_flags[COGL_DEBUG_N_LONGS]; - -#define COGL_DEBUG_ENABLED(flag) \ - COGL_FLAGS_GET (_cogl_debug_flags, flag) - -#define COGL_DEBUG_SET_FLAG(flag) \ - COGL_FLAGS_SET (_cogl_debug_flags, flag, TRUE) - -#define COGL_DEBUG_CLEAR_FLAG(flag) \ - COGL_FLAGS_SET (_cogl_debug_flags, flag, FALSE) - -#ifdef __GNUC__ -#define COGL_NOTE(type,x,a...) G_STMT_START { \ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_##type))) { \ - _cogl_profile_trace_message ("[" #type "] " G_STRLOC ": " x, ##a); \ - } } G_STMT_END - -#else -#define COGL_NOTE(type,...) G_STMT_START { \ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_##type))) { \ - char *_fmt = g_strdup_printf (__VA_ARGS__); \ - _cogl_profile_trace_message ("[" #type "] " G_STRLOC ": %s", _fmt);\ - g_free (_fmt); \ - } } G_STMT_END - -#endif /* __GNUC__ */ - -void -_cogl_debug_check_environment (void); - -void -_cogl_parse_debug_string (const char *value, - gboolean enable, - gboolean ignore_help); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-depth-state-private.h b/mutter/cogl/cogl/cogl-depth-state-private.h deleted file mode 100644 index 3e6a060..0000000 --- a/mutter/cogl/cogl/cogl-depth-state-private.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#define COGL_DEPTH_STATE_MAGIC 0xDEADBEEF diff --git a/mutter/cogl/cogl/cogl-depth-state.c b/mutter/cogl/cogl/cogl-depth-state.c deleted file mode 100644 index 3a81422..0000000 --- a/mutter/cogl/cogl/cogl-depth-state.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-util.h" -#include "cogl/cogl-depth-state-private.h" -#include "cogl/cogl-depth-state.h" - -void -cogl_depth_state_init (CoglDepthState *state) -{ - state->magic = COGL_DEPTH_STATE_MAGIC; - - /* The same as the GL defaults */ - state->test_enabled = FALSE; - state->write_enabled = TRUE; - state->test_function = COGL_DEPTH_TEST_FUNCTION_LESS; - state->range_near = 0; - state->range_far = 1; -} - -void -cogl_depth_state_set_test_enabled (CoglDepthState *state, - gboolean enabled) -{ - g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC); - state->test_enabled = enabled; -} - -gboolean -cogl_depth_state_get_test_enabled (CoglDepthState *state) -{ - g_return_val_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); - return state->test_enabled; -} - -void -cogl_depth_state_set_write_enabled (CoglDepthState *state, - gboolean enabled) -{ - g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC); - state->write_enabled = enabled; -} - -gboolean -cogl_depth_state_get_write_enabled (CoglDepthState *state) -{ - g_return_val_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); - return state->write_enabled; -} - -void -cogl_depth_state_set_test_function (CoglDepthState *state, - CoglDepthTestFunction function) -{ - g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC); - state->test_function = function; -} - -CoglDepthTestFunction -cogl_depth_state_get_test_function (CoglDepthState *state) -{ - g_return_val_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); - return state->test_function; -} - -void -cogl_depth_state_set_range (CoglDepthState *state, - float near, - float far) -{ - g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC); - state->range_near = near; - state->range_far = far; -} - -void -cogl_depth_state_get_range (CoglDepthState *state, - float *near_out, - float *far_out) -{ - g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC); - *near_out = state->range_near; - *far_out = state->range_far; -} diff --git a/mutter/cogl/cogl/cogl-depth-state.h b/mutter/cogl/cogl/cogl-depth-state.h deleted file mode 100644 index e32f97e..0000000 --- a/mutter/cogl/cogl/cogl-depth-state.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -G_BEGIN_DECLS - -/** - * CoglDepthState: - * - * Functions for describing the depth testing state of your GPU. - */ -typedef struct { - /*< private >*/ - uint32_t COGL_PRIVATE (magic); - - gboolean COGL_PRIVATE (test_enabled); - CoglDepthTestFunction COGL_PRIVATE (test_function); - gboolean COGL_PRIVATE (write_enabled); - float COGL_PRIVATE (range_near); - float COGL_PRIVATE (range_far); -} CoglDepthState; - -/** - * cogl_depth_state_init: - * @state: A #CoglDepthState struct - * - * Initializes the members of @state to their default values. - * - * You should never pass an un initialized #CoglDepthState structure - * to cogl_pipeline_set_depth_state(). - */ -COGL_EXPORT void -cogl_depth_state_init (CoglDepthState *state); - -/** - * cogl_depth_state_set_test_enabled: - * @state: A #CoglDepthState struct - * @enable: The enable state you want - * - * Enables or disables depth testing according to the value of - * @enable. - * - * If depth testing is enable then the #CoglDepthTestFunction set - * using cogl_depth_state_set_test_function() us used to evaluate - * the depth value of incoming fragments against the corresponding - * value stored in the current depth buffer, and if the test passes - * then the fragments depth value is used to update the depth buffer. - * (unless you have disabled depth writing via - * cogl_depth_state_set_write_enabled()) - * - * By default depth testing is disabled. - * - * NB: this won't directly affect the state of the GPU. You have - * to then set the state on a #CoglPipeline using - * cogl_pipeline_set_depth_state() - */ -COGL_EXPORT void -cogl_depth_state_set_test_enabled (CoglDepthState *state, - gboolean enable); - -/** - * cogl_depth_state_get_test_enabled: - * @state: A #CoglDepthState struct - * - * Gets the current depth test enabled state as previously set by - * cogl_depth_state_set_test_enabled(). - * - * Returns: The pipeline's current depth test enabled state. - */ -COGL_EXPORT gboolean -cogl_depth_state_get_test_enabled (CoglDepthState *state); - -/** - * cogl_depth_state_set_write_enabled: - * @state: A #CoglDepthState struct - * @enable: The enable state you want - * - * Enables or disables depth buffer writing according to the value of - * @enable. Normally when depth testing is enabled and the comparison - * between a fragment's depth value and the corresponding depth buffer - * value passes then the fragment's depth is written to the depth - * buffer unless writing is disabled here. - * - * By default depth writing is enabled - * - * NB: this won't directly affect the state of the GPU. You have - * to then set the state on a #CoglPipeline using - * cogl_pipeline_set_depth_state() - */ -COGL_EXPORT void -cogl_depth_state_set_write_enabled (CoglDepthState *state, - gboolean enable); - -/** - * cogl_depth_state_get_write_enabled: - * @state: A #CoglDepthState struct - * - * Gets the depth writing enable state as set by the corresponding - * cogl_depth_state_set_write_enabled(). - * - * Returns: The current depth writing enable state - */ -COGL_EXPORT gboolean -cogl_depth_state_get_write_enabled (CoglDepthState *state); - -/** - * cogl_depth_state_set_test_function: - * @state: A #CoglDepthState struct - * @function: The #CoglDepthTestFunction to set - * - * Sets the #CoglDepthTestFunction used to compare the depth value of - * an incoming fragment against the corresponding value in the current - * depth buffer. - * - * By default the depth test function is %COGL_DEPTH_TEST_FUNCTION_LESS - * - * NB: this won't directly affect the state of the GPU. You have - * to then set the state on a #CoglPipeline using - * cogl_pipeline_set_depth_state() - */ -COGL_EXPORT void -cogl_depth_state_set_test_function (CoglDepthState *state, - CoglDepthTestFunction function); - -/** - * cogl_depth_state_get_test_function: - * @state: A #CoglDepthState struct - * - * Gets the current depth test enable state as previously set via - * cogl_depth_state_set_test_enabled(). - * - * Returns: The current depth test enable state. - */ -COGL_EXPORT CoglDepthTestFunction -cogl_depth_state_get_test_function (CoglDepthState *state); - -/** - * cogl_depth_state_set_range: - * @state: A #CoglDepthState object - * @near_val: The near component of the desired depth range which will be - * clamped to the range [0, 1] - * @far_val: The far component of the desired depth range which will be - * clamped to the range [0, 1] - * - * Sets the range to map depth values in normalized device coordinates - * to before writing out to a depth buffer. - * - * After your geometry has be transformed, clipped and had perspective - * division applied placing it in normalized device - * coordinates all depth values between the near and far z clipping - * planes are in the range -1 to 1. Before writing any depth value to - * the depth buffer though the value is mapped into the range [0, 1]. - * - * With this function you can change the range which depth values are - * mapped too although the range must still lye within the range [0, - * 1]. - * - * By default normalized device coordinate depth values are mapped to - * the full range of depth buffer values, [0, 1]. - * - * NB: this won't directly affect the state of the GPU. You have - * to then set the state on a #CoglPipeline using - * cogl_pipeline_set_depth_state(). - */ -COGL_EXPORT void -cogl_depth_state_set_range (CoglDepthState *state, - float near_val, - float far_val); - -/** - * cogl_depth_state_get_range: - * @state: A #CoglDepthState object - * @near_val: A pointer to store the near component of the depth range - * @far_val: A pointer to store the far component of the depth range - * - * Gets the current range to which normalized depth values are mapped - * before writing to the depth buffer. This corresponds to the range - * set with cogl_depth_state_set_range(). - */ -COGL_EXPORT void -cogl_depth_state_get_range (CoglDepthState *state, - float *near_val, - float *far_val); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-display-private.h b/mutter/cogl/cogl/cogl-display-private.h deleted file mode 100644 index d88a084..0000000 --- a/mutter/cogl/cogl/cogl-display-private.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-display.h" -#include "cogl/cogl-renderer.h" -#include "cogl/cogl-onscreen-template-private.h" - -struct _CoglDisplay -{ - GObjectClass parnet_class; - - gboolean setup; - CoglRenderer *renderer; - CoglOnscreenTemplate *onscreen_template; - - void *winsys; -}; diff --git a/mutter/cogl/cogl/cogl-display.c b/mutter/cogl/cogl/cogl-display.c deleted file mode 100644 index 08158e5..0000000 --- a/mutter/cogl/cogl/cogl-display.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include - -#include "cogl/cogl-private.h" - -#include "cogl/cogl-display-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/winsys/cogl-winsys-private.h" - - -G_DEFINE_TYPE (CoglDisplay, cogl_display, G_TYPE_OBJECT); - -static const CoglWinsysVtable * -_cogl_display_get_winsys (CoglDisplay *display) -{ - return display->renderer->winsys_vtable; -} - -static void -cogl_display_dispose (GObject *object) -{ - CoglDisplay *display = COGL_DISPLAY (object); - - const CoglWinsysVtable *winsys; - - if (display->setup) - { - winsys = _cogl_display_get_winsys (display); - winsys->display_destroy (display); - display->setup = FALSE; - } - - g_clear_object (&display->renderer); - g_clear_object (&display->onscreen_template); - - G_OBJECT_CLASS (cogl_display_parent_class)->dispose (object); -} - -static void -cogl_display_init (CoglDisplay *display) -{ -} - -static void -cogl_display_class_init (CoglDisplayClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = cogl_display_dispose; -} - -CoglDisplay * -cogl_display_new (CoglRenderer *renderer, - CoglOnscreenTemplate *onscreen_template) -{ - CoglDisplay *display = g_object_new (COGL_TYPE_DISPLAY, NULL); - GError *error = NULL; - - _cogl_init (); - - display->renderer = renderer; - if (renderer) - g_object_ref (renderer); - else - display->renderer = cogl_renderer_new (); - - if (!cogl_renderer_connect (display->renderer, &error)) - g_error ("Failed to connect to renderer: %s\n", error->message); - - display->setup = FALSE; - - cogl_display_set_onscreen_template (display, onscreen_template); - - return display; -} - -CoglRenderer * -cogl_display_get_renderer (CoglDisplay *display) -{ - return display->renderer; -} - -void -cogl_display_set_onscreen_template (CoglDisplay *display, - CoglOnscreenTemplate *onscreen_template) -{ - g_return_if_fail (display->setup == FALSE); - - if (onscreen_template) - g_object_ref (onscreen_template); - - if (display->onscreen_template) - g_object_unref (display->onscreen_template); - - display->onscreen_template = onscreen_template; - - /* NB: we want to maintain the invariable that there is always an - * onscreen template associated with a CoglDisplay... */ - if (!onscreen_template) - display->onscreen_template = cogl_onscreen_template_new (NULL); -} - -gboolean -cogl_display_setup (CoglDisplay *display, - GError **error) -{ - const CoglWinsysVtable *winsys; - - if (display->setup) - return TRUE; - - winsys = _cogl_display_get_winsys (display); - if (!winsys->display_setup (display, error)) - return FALSE; - - display->setup = TRUE; - - return TRUE; -} diff --git a/mutter/cogl/cogl/cogl-display.h b/mutter/cogl/cogl/cogl-display.h deleted file mode 100644 index fa6f9ec..0000000 --- a/mutter/cogl/cogl/cogl-display.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-renderer.h" -#include "cogl/cogl-onscreen-template.h" - -#include - -G_BEGIN_DECLS - -/** - * CoglDisplay: - * - * Common aspects of a display pipeline - * - * The basic intention for this object is to let the application - * configure common display preferences before creating a context, and - * there are a few different aspects to this... - * - * Firstly there are options directly relating to the physical display - * pipeline that is currently being used including the digital to - * analogue conversion hardware and the screens the user sees. - * - * Another aspect is that display options may constrain or affect how - * onscreen framebuffers should later be configured. The original - * rationale for the display object in fact was to let us handle GLX - * and EGLs requirements that framebuffers must be "compatible" with - * the config associated with the current context meaning we have to - * force the user to describe how they would like to create their - * onscreen windows before we can choose a suitable fbconfig and - * create a GLContext. - */ - -typedef struct _CoglDisplay CoglDisplay; - -#define COGL_TYPE_DISPLAY (cogl_display_get_type ()) - -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglDisplay, - cogl_display, - COGL, - DISPLAY, - GObject) - -/** - * cogl_display_new: - * @renderer: A #CoglRenderer - * @onscreen_template: A #CoglOnscreenTemplate - * - * Explicitly allocates a new #CoglDisplay object to encapsulate the - * common state of the display pipeline that applies to the whole - * application. - * - * A @display can only be made for a specific choice of renderer which - * is why this takes the @renderer argument. - * - * A common use for explicitly allocating a display object is to - * define a template for allocating onscreen framebuffers which is - * what the @onscreen_template argument is for, or alternatively - * you can use cogl_display_set_onscreen_template(). - * - * When a display is first allocated via cogl_display_new() it is in a - * mutable configuration mode. It's designed this way so we can - * extend the apis available for configuring a display without - * requiring huge numbers of constructor arguments. - * - * When you have finished configuring a display object you can - * optionally call cogl_display_setup() to explicitly apply the - * configuration and check for errors. Alternaitvely you can pass the - * display to cogl_context_new() and Cogl will implicitly apply your - * configuration but if there are errors then the application will - * abort with a message. For simple applications with no fallback - * options then relying on the implicit setup can be fine. - * - * Return value: (transfer full): A newly allocated #CoglDisplay - * object in a mutable configuration mode. - */ -COGL_EXPORT CoglDisplay * -cogl_display_new (CoglRenderer *renderer, - CoglOnscreenTemplate *onscreen_template); - -/** - * cogl_display_get_renderer: - * @display: a #CoglDisplay - * - * Queries the #CoglRenderer associated with the given @display. - * - * Return value: (transfer none): The associated #CoglRenderer - * - */ -COGL_EXPORT CoglRenderer * -cogl_display_get_renderer (CoglDisplay *display); - -/** - * cogl_display_set_onscreen_template: - * @display: a #CoglDisplay - * @onscreen_template: A template for creating #CoglOnscreen framebuffers - * - * Specifies a template for creating #CoglOnscreen framebuffers. - * - * Depending on the system, the constraints for creating #CoglOnscreen - * framebuffers need to be known before setting up a #CoglDisplay because the - * final setup of the display may constrain how onscreen framebuffers may be - * allocated. If Cogl knows how an application wants to allocate onscreen - * framebuffers then it can try to make sure to setup the display accordingly. - */ -COGL_EXPORT void -cogl_display_set_onscreen_template (CoglDisplay *display, - CoglOnscreenTemplate *onscreen_template); - -/** - * cogl_display_setup: - * @display: a #CoglDisplay - * @error: return location for a #GError - * - * Explicitly sets up the given @display object. Use of this api is - * optional since Cogl will internally setup the display if not done - * explicitly. - * - * When a display is first allocated via cogl_display_new() it is in a - * mutable configuration mode. This allows us to extend the apis - * available for configuring a display without requiring huge numbers - * of constructor arguments. - * - * Its possible to request a configuration that might not be - * supportable on the current system and so this api provides a means - * to apply the configuration explicitly but if it fails then an - * exception will be returned so you can handle the error gracefully - * and perhaps fall back to an alternative configuration. - * - * If you instead rely on Cogl implicitly calling cogl_display_setup() - * for you then if there is an error with the configuration you won't - * get an opportunity to handle that and the application may abort - * with a message. For simple applications that don't have any - * fallback options this behaviour may be fine. - * - * Return value: Returns %TRUE if there was no error, else it returns - * %FALSE and returns an exception via @error. - */ -COGL_EXPORT gboolean -cogl_display_setup (CoglDisplay *display, - GError **error); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-dma-buf-handle.c b/mutter/cogl/cogl/cogl-dma-buf-handle.c deleted file mode 100644 index d0387fe..0000000 --- a/mutter/cogl/cogl/cogl-dma-buf-handle.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2020 Endless, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Georges Basile Stavracas Neto - */ - -#include "config.h" - -#include "cogl/cogl-dma-buf-handle.h" - -#include -#include -#include -#include -#include -#include -#include - -struct _CoglDmaBufHandle -{ - CoglFramebuffer *framebuffer; - int dmabuf_fd; - int width; - int height; - int stride; - int offset; - int bpp; - gpointer user_data; - GDestroyNotify destroy_func; -}; - -CoglDmaBufHandle * -cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer, - int dmabuf_fd, - int width, - int height, - int stride, - int offset, - int bpp, - gpointer user_data, - GDestroyNotify destroy_func) -{ - CoglDmaBufHandle *dmabuf_handle; - - g_assert (framebuffer); - g_assert (dmabuf_fd != -1); - - dmabuf_handle = g_new0 (CoglDmaBufHandle, 1); - dmabuf_handle->framebuffer = g_object_ref (framebuffer); - dmabuf_handle->dmabuf_fd = dmabuf_fd; - dmabuf_handle->user_data = user_data; - dmabuf_handle->destroy_func = destroy_func; - - dmabuf_handle->width = width; - dmabuf_handle->height = height; - dmabuf_handle->stride = stride; - dmabuf_handle->offset = offset; - dmabuf_handle->bpp = bpp; - - return dmabuf_handle; -} - -void -cogl_dma_buf_handle_free (CoglDmaBufHandle *dmabuf_handle) -{ - g_return_if_fail (dmabuf_handle != NULL); - - g_clear_object (&dmabuf_handle->framebuffer); - - if (dmabuf_handle->destroy_func) - g_clear_pointer (&dmabuf_handle->user_data, dmabuf_handle->destroy_func); - - g_clear_fd (&dmabuf_handle->dmabuf_fd, NULL); - - g_free (dmabuf_handle); -} - -static gboolean -sync_read (CoglDmaBufHandle *dmabuf_handle, - uint64_t start_or_end, - GError **error) -{ - struct dma_buf_sync sync = { 0 }; - - sync.flags = start_or_end | DMA_BUF_SYNC_READ; - - while (TRUE) - { - int ret; - - ret = ioctl (dmabuf_handle->dmabuf_fd, DMA_BUF_IOCTL_SYNC, &sync); - if (ret == -1 && errno == EINTR) - { - continue; - } - else if (ret == -1) - { - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), - "ioctl: %s", g_strerror (errno)); - return FALSE; - } - else - { - break; - } - } - - return TRUE; -} - -gboolean -cogl_dma_buf_handle_sync_read_start (CoglDmaBufHandle *dmabuf_handle, - GError **error) -{ - return sync_read (dmabuf_handle, DMA_BUF_SYNC_START, error); -} - -gboolean -cogl_dma_buf_handle_sync_read_end (CoglDmaBufHandle *dmabuf_handle, - GError **error) -{ - return sync_read (dmabuf_handle, DMA_BUF_SYNC_END, error); -} - -gpointer -cogl_dma_buf_handle_mmap (CoglDmaBufHandle *dmabuf_handle, - GError **error) -{ - size_t size; - gpointer data; - - size = dmabuf_handle->height * dmabuf_handle->stride; - - data = mmap (NULL, size, PROT_READ, MAP_PRIVATE, - dmabuf_handle->dmabuf_fd, - dmabuf_handle->offset); - if (data == MAP_FAILED) - { - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), - "mmap failed: %s", g_strerror (errno)); - return NULL; - } - - return data; -} - -gboolean -cogl_dma_buf_handle_munmap (CoglDmaBufHandle *dmabuf_handle, - gpointer data, - GError **error) -{ - size_t size; - - size = dmabuf_handle->height * dmabuf_handle->stride; - if (munmap (data, size) != 0) - { - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), - "munmap failed: %s", g_strerror (errno)); - return FALSE; - } - - return TRUE; -} - -CoglFramebuffer * -cogl_dma_buf_handle_get_framebuffer (CoglDmaBufHandle *dmabuf_handle) -{ - return dmabuf_handle->framebuffer; -} - -int -cogl_dma_buf_handle_get_fd (CoglDmaBufHandle *dmabuf_handle) -{ - return dmabuf_handle->dmabuf_fd; -} - -int -cogl_dma_buf_handle_get_width (CoglDmaBufHandle *dmabuf_handle) -{ - return dmabuf_handle->width; -} - -int -cogl_dma_buf_handle_get_height (CoglDmaBufHandle *dmabuf_handle) -{ - return dmabuf_handle->height; -} - -int -cogl_dma_buf_handle_get_stride (CoglDmaBufHandle *dmabuf_handle) -{ - return dmabuf_handle->stride; -} - -int -cogl_dma_buf_handle_get_offset (CoglDmaBufHandle *dmabuf_handle) -{ - return dmabuf_handle->offset; -} - -int -cogl_dma_buf_handle_get_bpp (CoglDmaBufHandle *dmabuf_handle) -{ - return dmabuf_handle->bpp; -} diff --git a/mutter/cogl/cogl/cogl-dma-buf-handle.h b/mutter/cogl/cogl/cogl-dma-buf-handle.h deleted file mode 100644 index ba469ce..0000000 --- a/mutter/cogl/cogl/cogl-dma-buf-handle.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2020 Endless, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Georges Basile Stavracas Neto - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-types.h" -#include "cogl/cogl-framebuffer.h" - -/** - * cogl_dma_buf_handle_new: (skip) - */ -COGL_EXPORT CoglDmaBufHandle * -cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer, - int dmabuf_fd, - int width, - int height, - int stride, - int offset, - int bpp, - gpointer user_data, - GDestroyNotify destroy_func); - -/** - * cogl_dma_buf_handle_free: - * @dmabuf_handle: (transfer full): a #CoglDmaBufHandle - * - * Releases @dmabuf_handle; it is a programming error to release - * an already released handle. - */ -COGL_EXPORT void -cogl_dma_buf_handle_free (CoglDmaBufHandle *dmabuf_handle); - -COGL_EXPORT gboolean -cogl_dma_buf_handle_sync_read_start (CoglDmaBufHandle *dmabuf_handle, - GError **error); - -COGL_EXPORT gboolean -cogl_dma_buf_handle_sync_read_end (CoglDmaBufHandle *dmabuf_handle, - GError **error); - -COGL_EXPORT gpointer -cogl_dma_buf_handle_mmap (CoglDmaBufHandle *dmabuf_handle, - GError **error); - -COGL_EXPORT gboolean -cogl_dma_buf_handle_munmap (CoglDmaBufHandle *dmabuf_handle, - gpointer data, - GError **error); - -/** - * cogl_dma_buf_handle_get_framebuffer: - * - * Retrieves the #CoglFramebuffer, backed by an exported DMABuf buffer, - * of @dmabuf_handle. - * - * Returns: (transfer none): a #CoglFramebuffer - */ -COGL_EXPORT CoglFramebuffer * -cogl_dma_buf_handle_get_framebuffer (CoglDmaBufHandle *dmabuf_handle); - -/** - * cogl_dma_buf_handle_get_fd: - * - * Retrieves the file descriptor of @dmabuf_handle. - * - * Returns: a valid file descriptor - */ -COGL_EXPORT int -cogl_dma_buf_handle_get_fd (CoglDmaBufHandle *dmabuf_handle); - -/** - * cogl_dmabuf_handle_get_width: - * - * Returns: the buffer width - */ -COGL_EXPORT int -cogl_dma_buf_handle_get_width (CoglDmaBufHandle *dmabuf_handle); - -/** - * cogl_dmabuf_handle_get_height: - * - * Returns: the buffer height - */ -COGL_EXPORT int -cogl_dma_buf_handle_get_height (CoglDmaBufHandle *dmabuf_handle); - -/** - * cogl_dmabuf_handle_get_stride: - * - * Returns: the buffer stride - */ -COGL_EXPORT int -cogl_dma_buf_handle_get_stride (CoglDmaBufHandle *dmabuf_handle); - -/** - * cogl_dmabuf_handle_get_offset: - * - * Returns: the buffer offset - */ -COGL_EXPORT int -cogl_dma_buf_handle_get_offset (CoglDmaBufHandle *dmabuf_handle); - -/** - * cogl_dmabuf_handle_get_bpp: - * - * Returns: the number of bytes per pixel - */ -COGL_EXPORT int -cogl_dma_buf_handle_get_bpp (CoglDmaBufHandle *dmabuf_handle); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (CoglDmaBufHandle, cogl_dma_buf_handle_free) diff --git a/mutter/cogl/cogl/cogl-driver.h b/mutter/cogl/cogl/cogl-driver.h deleted file mode 100644 index 3980443..0000000 --- a/mutter/cogl/cogl/cogl-driver.h +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-context.h" -#include "cogl/cogl-offscreen-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-attribute-private.h" -#include "cogl/cogl-sampler-cache-private.h" -#include "cogl/cogl-texture-private.h" - -typedef struct _CoglDriverVtable CoglDriverVtable; - -struct _CoglDriverVtable -{ - gboolean - (* context_init) (CoglContext *context); - - void - (* context_deinit) (CoglContext *context); - - gboolean - (* is_hardware_accelerated) (CoglContext *context); - - CoglGraphicsResetStatus - (* get_graphics_reset_status) (CoglContext *context); - - /* TODO: factor this out since this is OpenGL specific and - * so can be ignored by non-OpenGL drivers. */ - CoglPixelFormat - (* pixel_format_to_gl) (CoglContext *context, - CoglPixelFormat format, - GLenum *out_glintformat, - GLenum *out_glformat, - GLenum *out_gltype); - - CoglPixelFormat - (* get_read_pixels_format) (CoglContext *context, - CoglPixelFormat from, - CoglPixelFormat to, - GLenum *gl_format_out, - GLenum *gl_type_out); - - gboolean - (* update_features) (CoglContext *context, - GError **error); - - CoglFramebufferDriver * - (* create_framebuffer_driver) (CoglContext *context, - CoglFramebuffer *framebuffer, - const CoglFramebufferDriverConfig *driver_config, - GError **error); - - void - (* flush_framebuffer_state) (CoglContext *context, - CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer, - CoglFramebufferState state); - - /* Destroys any driver specific resources associated with the given - * 2D texture. */ - void - (* texture_2d_free) (CoglTexture2D *tex_2d); - - /* Returns TRUE if the driver can support creating a 2D texture with - * the given geometry and specified internal format. - */ - gboolean - (* texture_2d_can_create) (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format); - - /* Initializes driver private state before allocating any specific - * storage for a 2D texture, where base texture and texture 2D - * members will already be initialized before passing control to - * the driver. - */ - void - (* texture_2d_init) (CoglTexture2D *tex_2d); - - /* Allocates (uninitialized) storage for the given texture according - * to the configured size and format of the texture */ - gboolean - (* texture_2d_allocate) (CoglTexture *tex, - GError **error); - - /* Initialize the specified region of storage of the given texture - * with the contents of the specified framebuffer region - */ - void - (* texture_2d_copy_from_framebuffer) (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglFramebuffer *src_fb, - int dst_x, - int dst_y, - int level); - - /* If the given texture has a corresponding OpenGL texture handle - * then return that. - * - * This is optional - */ - unsigned int - (* texture_2d_get_gl_handle) (CoglTexture2D *tex_2d); - - /* Update all mipmap levels > 0 */ - void - (* texture_2d_generate_mipmap) (CoglTexture2D *tex_2d); - - /* Initialize the specified region of storage of the given texture - * with the contents of the specified bitmap region - * - * Since this may need to create the underlying storage first - * it may throw a NO_MEMORY error. - */ - gboolean - (* texture_2d_copy_from_bitmap) (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglBitmap *bitmap, - int dst_x, - int dst_y, - int level, - GError **error); - - gboolean - (* texture_2d_is_get_data_supported) (CoglTexture2D *tex_2d); - - /* Reads back the full contents of the given texture and write it to - * @data in the given @format and with the given @rowstride. - * - * This is optional - */ - void - (* texture_2d_get_data) (CoglTexture2D *tex_2d, - CoglPixelFormat format, - int rowstride, - uint8_t *data); - - /* Prepares for drawing by flushing the journal, framebuffer state, - * pipeline state and attribute state. - */ - void - (* flush_attributes_state) (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglFlushLayerState *layer_state, - CoglDrawFlags flags, - CoglAttribute **attributes, - int n_attributes); - - /* Flushes the clip stack to the GPU using a combination of the - * stencil buffer, scissor and clip plane state. - */ - void - (* clip_stack_flush) (CoglClipStack *stack, CoglFramebuffer *framebuffer); - - /* Enables the driver to create some meta data to represent a buffer - * but with no corresponding storage allocated yet. - */ - void - (* buffer_create) (CoglBuffer *buffer); - - void - (* buffer_destroy) (CoglBuffer *buffer); - - /* Maps a buffer into the CPU */ - void * - (* buffer_map_range) (CoglBuffer *buffer, - size_t offset, - size_t size, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error); - - /* Unmaps a buffer */ - void - (* buffer_unmap) (CoglBuffer *buffer); - - /* Uploads data to the buffer without needing to map it necessarily - */ - gboolean - (* buffer_set_data) (CoglBuffer *buffer, - unsigned int offset, - const void *data, - unsigned int size, - GError **error); - - void - (*sampler_init) (CoglContext *context, - CoglSamplerCacheEntry *entry); - - void - (*sampler_free) (CoglContext *context, - CoglSamplerCacheEntry *entry); - - void - (* set_uniform) (CoglContext *ctx, - GLint location, - const CoglBoxedValue *value); - - CoglTimestampQuery * - (* create_timestamp_query) (CoglContext *context); - - void - (* free_timestamp_query) (CoglContext *context, - CoglTimestampQuery *query); - - int64_t - (* timestamp_query_get_time_ns) (CoglContext *context, - CoglTimestampQuery *query); - - int64_t - (* get_gpu_time_ns) (CoglContext *context); -}; - -#define COGL_DRIVER_ERROR (_cogl_driver_error_quark ()) - -typedef enum /*< prefix=COGL_DRIVER_ERROR >*/ -{ - COGL_DRIVER_ERROR_UNKNOWN_VERSION, - COGL_DRIVER_ERROR_INVALID_VERSION, - COGL_DRIVER_ERROR_NO_SUITABLE_DRIVER_FOUND, - COGL_DRIVER_ERROR_FAILED_TO_LOAD_LIBRARY -} CoglDriverError; - -uint32_t -_cogl_driver_error_quark (void); diff --git a/mutter/cogl/cogl/cogl-egl-private.h b/mutter/cogl/cogl/cogl-egl-private.h deleted file mode 100644 index 5e9ae02..0000000 --- a/mutter/cogl/cogl/cogl-egl-private.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-egl.h" - -#if defined(GL_OES_EGL_image) && !defined(GLeglImageOES) -#define GLeglImageOES void * -#endif diff --git a/mutter/cogl/cogl/cogl-egl.h b/mutter/cogl/cogl/cogl-egl.h deleted file mode 100644 index deef1de..0000000 --- a/mutter/cogl/cogl/cogl-egl.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include -#include -#include - -#include "cogl/cogl-types.h" - -G_BEGIN_DECLS - -/** - * cogl_egl_context_get_egl_display: - * @context: A #CoglContext pointer - * - * If you have done a runtime check to determine that Cogl is using - * EGL internally then this API can be used to retrieve the EGLDisplay - * handle that was setup internally. The result is undefined if Cogl - * is not using EGL. - * - * Note: The current window system backend can be checked using - * cogl_renderer_get_winsys_id(). - * - * Return value: The internally setup EGLDisplay handle. - */ -COGL_EXPORT EGLDisplay -cogl_egl_context_get_egl_display (CoglContext *context); - -G_END_DECLS - -/* The gobject introspection scanner seems to parse public headers in - * isolation which means we need to be extra careful about how we - * define and undefine __COGL_H_INSIDE__ used to detect when internal - * headers are incorrectly included by developers. In the gobject - * introspection case we have to manually define __COGL_H_INSIDE__ as - * a commandline argument for the scanner which means we must be - * careful not to undefine it in a header... - */ -#ifdef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_EGL__ -#undef __COGL_H_INSIDE__ -#undef __COGL_EGL_H_INSIDE__ -#undef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_EGL__ -#endif diff --git a/mutter/cogl/cogl/cogl-enum-types.c.in b/mutter/cogl/cogl/cogl-enum-types.c.in deleted file mode 100644 index 91a5833..0000000 --- a/mutter/cogl/cogl/cogl-enum-types.c.in +++ /dev/null @@ -1,40 +0,0 @@ -/*** BEGIN file-header ***/ -#include "config.h" -#include "cogl/cogl-enum-types.h" -/*** END file-header ***/ - -/*** BEGIN file-production ***/ - -/* enumerations from "@filename@" */ -#include "@filename@" - -/*** END file-production ***/ - -/*** BEGIN value-header ***/ -GType -@enum_name@_get_type (void) -{ - static size_t g_enum_type_id = 0; - - if (g_once_init_enter (&g_enum_type_id)) - { - static const G@Type@Value values[] = { -/*** END value-header ***/ - -/*** BEGIN value-production ***/ - { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, -/*** END value-production ***/ - -/*** BEGIN value-tail ***/ - { 0, NULL, NULL } - }; - GType id; - - id = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); - - g_once_init_leave (&g_enum_type_id, id); - } - - return g_enum_type_id; -} -/*** END value-tail ***/ diff --git a/mutter/cogl/cogl/cogl-enum-types.h.in b/mutter/cogl/cogl/cogl-enum-types.h.in deleted file mode 100644 index 6fae5a2..0000000 --- a/mutter/cogl/cogl/cogl-enum-types.h.in +++ /dev/null @@ -1,27 +0,0 @@ -/*** BEGIN file-header ***/ -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-types.h" - -G_BEGIN_DECLS - -/*** END file-header ***/ - -/*** BEGIN file-production ***/ -/* enumerations from "@basename@" */ -/*** END file-production ***/ - -/*** BEGIN value-header ***/ -COGL_EXPORT GType @enum_name@_get_type (void) G_GNUC_CONST; -#define COGL_TYPE_@ENUMSHORT@ (@enum_name@_get_type()) - -/*** END value-header ***/ - -/*** BEGIN file-tail ***/ -G_END_DECLS - -/*** END file-tail ***/ diff --git a/mutter/cogl/cogl/cogl-feature-private.c b/mutter/cogl/cogl/cogl-feature-private.c deleted file mode 100644 index 1ef42b8..0000000 --- a/mutter/cogl/cogl/cogl-feature-private.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include - -#include "cogl/cogl-context-private.h" - -#include "cogl/cogl-feature-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-private.h" - -gboolean -_cogl_feature_check (CoglRenderer *renderer, - const char *driver_prefix, - const CoglFeatureData *data, - int gl_major, - int gl_minor, - CoglDriver driver, - char * const *extensions, - void *function_table) - -{ - const char *suffix = NULL; - int func_num; - CoglExtGlesAvailability gles_availability = 0; - - switch (driver) - { - case COGL_DRIVER_GLES2: - gles_availability = COGL_EXT_IN_GLES2; - - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 0)) - gles_availability |= COGL_EXT_IN_GLES3; - break; - case COGL_DRIVER_ANY: - g_assert_not_reached (); - case COGL_DRIVER_NOP: - case COGL_DRIVER_GL3: - break; - } - - /* First check whether the functions should be directly provided by - GL */ - if ((driver == COGL_DRIVER_GL3 && - COGL_CHECK_GL_VERSION (gl_major, gl_minor, - data->min_gl_major, data->min_gl_minor)) || - (data->gles_availability & gles_availability)) - { - suffix = ""; - } - else - { - /* Otherwise try all of the extensions */ - const char *namespace, *namespace_suffix; - unsigned int namespace_len; - - for (namespace = data->namespaces; - *namespace; - namespace += strlen (namespace) + 1) - { - const char *extension; - GString *full_extension_name = g_string_new (""); - - /* If the namespace part contains a ':' then the suffix for - the function names is different from the name space */ - if ((namespace_suffix = strchr (namespace, ':'))) - { - namespace_len = namespace_suffix - namespace; - namespace_suffix++; - } - else - { - namespace_len = strlen (namespace); - namespace_suffix = namespace; - } - - for (extension = data->extension_names; - *extension; - extension += strlen (extension) + 1) - { - g_string_assign (full_extension_name, driver_prefix); - g_string_append_c (full_extension_name, '_'); - g_string_append_len (full_extension_name, - namespace, namespace_len); - g_string_append_c (full_extension_name, '_'); - g_string_append (full_extension_name, extension); - if (_cogl_check_extension (full_extension_name->str, - extensions)) - break; - } - - g_string_free (full_extension_name, TRUE); - - /* If we found an extension with this namespace then use it - as the suffix */ - if (*extension) - { - suffix = namespace_suffix; - break; - } - } - } - - /* If we couldn't find anything that provides the functions then - give up */ - if (suffix == NULL) - goto error; - - /* Try to get all of the entry points */ - for (func_num = 0; data->functions[func_num].name; func_num++) - { - void *func; - char *full_function_name; - - full_function_name = g_strconcat (data->functions[func_num].name, - suffix, NULL); - func = _cogl_renderer_get_proc_address (renderer, - full_function_name); - g_free (full_function_name); - - if (func == NULL) - goto error; - - /* Set the function pointer in the context */ - *(void **) ((uint8_t *) function_table + - data->functions[func_num].pointer_offset) = func; - } - - return TRUE; - - /* If the extension isn't found or one of the functions wasn't found - * then set all of the functions pointers to NULL so Cogl can safely - * do feature testing by just looking at the function pointers */ -error: - for (func_num = 0; data->functions[func_num].name; func_num++) - *(void **) ((uint8_t *) function_table + - data->functions[func_num].pointer_offset) = NULL; - - return FALSE; -} - -/* Define a set of arrays containing the functions required from GL - for each feature */ -#define COGL_EXT_BEGIN(name, \ - min_gl_major, min_gl_minor, \ - gles_availability, \ - namespaces, extension_names) \ - static const CoglFeatureFunction cogl_ext_ ## name ## _funcs[] = { -#define COGL_EXT_FUNCTION(ret, name, args) \ - { G_STRINGIFY (name), G_STRUCT_OFFSET (CoglContext, name) }, -#define COGL_EXT_END() \ - { NULL, 0 }, \ - }; -#include "gl-prototypes/cogl-all-functions.h" - -/* Define an array of features */ -#undef COGL_EXT_BEGIN -#define COGL_EXT_BEGIN(name, \ - min_gl_major, min_gl_minor, \ - gles_availability, \ - namespaces, extension_names) \ - { min_gl_major, min_gl_minor, gles_availability, namespaces, \ - extension_names, 0, 0, \ - cogl_ext_ ## name ## _funcs }, -#undef COGL_EXT_FUNCTION -#define COGL_EXT_FUNCTION(ret, name, args) -#undef COGL_EXT_END -#define COGL_EXT_END() - -static const CoglFeatureData -cogl_feature_ext_functions_data[] = - { -#include "gl-prototypes/cogl-all-functions.h" - }; - -void -_cogl_feature_check_ext_functions (CoglContext *context, - int gl_major, - int gl_minor, - char * const *gl_extensions) -{ - int i; - - for (i = 0; i < G_N_ELEMENTS (cogl_feature_ext_functions_data); i++) - _cogl_feature_check (context->display->renderer, - "GL", cogl_feature_ext_functions_data + i, - gl_major, gl_minor, context->driver, - gl_extensions, - context); -} diff --git a/mutter/cogl/cogl/cogl-feature-private.h b/mutter/cogl/cogl/cogl-feature-private.h deleted file mode 100644 index 4480786..0000000 --- a/mutter/cogl/cogl/cogl-feature-private.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include - -#include "cogl/cogl-context.h" -#include "cogl/cogl-renderer.h" - -#define COGL_CHECK_GL_VERSION(driver_major, driver_minor, \ - target_major, target_minor) \ - ((driver_major) > (target_major) || \ - ((driver_major) == (target_major) && (driver_minor) >= (target_minor))) - -typedef enum -{ - COGL_EXT_IN_GL = (1 << 0), - COGL_EXT_IN_GLES2 = (1 << 1), - COGL_EXT_IN_GLES3 = (1 << 2) -} CoglExtGlesAvailability; - -typedef struct _CoglFeatureFunction CoglFeatureFunction; - -struct _CoglFeatureFunction -{ - /* The name of the function without the "EXT" or "ARB" suffix */ - const char *name; - /* The offset in the context of where to store the function pointer */ - unsigned int pointer_offset; -}; - -typedef struct _CoglFeatureData CoglFeatureData; - -struct _CoglFeatureData -{ - /* A minimum GL version which the functions should be defined in - without needing an extension. Set to 255,255 if it's only - provided in an extension */ - int min_gl_major, min_gl_minor; - /* Flags specifying which versions of GLES the feature is available - in core in */ - CoglExtGlesAvailability gles_availability; - /* \0 separated list of namespaces to try. Eg "EXT\0ARB\0" */ - const char *namespaces; - /* \0 separated list of required extension names without the GL_EXT - or GL_ARB prefix. Any of the extensions must be available for the - feature to be considered available. If the suffix for an - extension is different from the namespace, you can specify it - with a ':' after the namespace */ - const char *extension_names; - /* A set of private feature flags to enable if the extension is - * available */ - int feature_flags_private; - /* An optional corresponding winsys feature. */ - CoglWinsysFeature winsys_feature; - /* A list of functions required for this feature. Terminated with a - NULL name */ - const CoglFeatureFunction *functions; -}; - -gboolean -_cogl_feature_check (CoglRenderer *renderer, - const char *driver_prefix, - const CoglFeatureData *data, - int gl_major, - int gl_minor, - CoglDriver driver, - char * const *extensions, - void *function_table); - -void -_cogl_feature_check_ext_functions (CoglContext *context, - int gl_major, - int gl_minor, - char * const *gl_extensions); diff --git a/mutter/cogl/cogl/cogl-fence-private.h b/mutter/cogl/cogl/cogl-fence-private.h deleted file mode 100644 index 760e899..0000000 --- a/mutter/cogl/cogl/cogl-fence-private.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Collabora Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-fence.h" -#include "cogl/cogl-list.h" -#include "cogl/winsys/cogl-winsys-private.h" - -typedef enum -{ - FENCE_TYPE_PENDING, -#ifdef GL_ARB_sync - FENCE_TYPE_GL_ARB, -#endif - FENCE_TYPE_WINSYS, - FENCE_TYPE_ERROR -} CoglFenceType; - -struct _CoglFenceClosure -{ - CoglList link; - CoglFramebuffer *framebuffer; - - CoglFenceType type; - void *fence_obj; - - CoglFenceCallback callback; - void *user_data; -}; - -void -_cogl_fence_submit (CoglFenceClosure *fence); - -void -_cogl_fence_cancel_fences_for_framebuffer (CoglFramebuffer *framebuffer); diff --git a/mutter/cogl/cogl/cogl-fence.c b/mutter/cogl/cogl/cogl-fence.c deleted file mode 100644 index 8b44b0a..0000000 --- a/mutter/cogl/cogl/cogl-fence.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Collabora Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "config.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-fence.h" -#include "cogl/cogl-fence-private.h" -#include "cogl/winsys/cogl-winsys-private.h" - -#define FENCE_CHECK_TIMEOUT 5000 /* microseconds */ - -void * -cogl_fence_closure_get_user_data (CoglFenceClosure *closure) -{ - return closure->user_data; -} - -static void -_cogl_fence_check (CoglFenceClosure *fence) -{ - CoglContext *context = cogl_framebuffer_get_context (fence->framebuffer); - - if (fence->type == FENCE_TYPE_WINSYS) - { - const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); - gboolean ret; - - ret = winsys->fence_is_complete (context, fence->fence_obj); - if (!ret) - return; - } -#ifdef GL_ARB_sync - else if (fence->type == FENCE_TYPE_GL_ARB) - { - GLenum arb; - - arb = context->glClientWaitSync (fence->fence_obj, - GL_SYNC_FLUSH_COMMANDS_BIT, - 0); - if (arb != GL_ALREADY_SIGNALED && arb != GL_CONDITION_SATISFIED) - return; - } -#endif - - fence->callback (NULL, /* dummy CoglFence object */ - fence->user_data); - cogl_framebuffer_cancel_fence_callback (fence->framebuffer, fence); -} - -static void -_cogl_fence_poll_dispatch (void *source, int revents) -{ - CoglContext *context = source; - CoglFenceClosure *fence, *tmp; - - _cogl_list_for_each_safe (fence, tmp, &context->fences, link) - _cogl_fence_check (fence); -} - -static int64_t -_cogl_fence_poll_prepare (void *source) -{ - CoglContext *context = source; - GList *l; - - /* If there are any pending fences in any of the journals then we - * need to flush the journal otherwise the fence will never be - * hit and the main loop might block forever */ - for (l = context->framebuffers; l; l = l->next) - { - CoglFramebuffer *framebuffer = l->data; - CoglJournal *journal = cogl_framebuffer_get_journal (framebuffer); - - if (!_cogl_list_empty (&journal->pending_fences)) - _cogl_framebuffer_flush_journal (framebuffer); - } - - if (!_cogl_list_empty (&context->fences)) - return FENCE_CHECK_TIMEOUT; - else - return -1; -} - -void -_cogl_fence_submit (CoglFenceClosure *fence) -{ - CoglContext *context = cogl_framebuffer_get_context (fence->framebuffer); - const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); - - fence->type = FENCE_TYPE_ERROR; - - if (winsys->fence_add) - { - fence->fence_obj = winsys->fence_add (context); - if (fence->fence_obj) - { - fence->type = FENCE_TYPE_WINSYS; - goto done; - } - } - -#ifdef GL_ARB_sync - if (context->glFenceSync) - { - fence->fence_obj = context->glFenceSync (GL_SYNC_GPU_COMMANDS_COMPLETE, - 0); - if (fence->fence_obj) - { - fence->type = FENCE_TYPE_GL_ARB; - goto done; - } - } -#endif - - done: - _cogl_list_insert (context->fences.prev, &fence->link); - - if (!context->fences_poll_source) - { - context->fences_poll_source = - _cogl_poll_renderer_add_source (context->display->renderer, - _cogl_fence_poll_prepare, - _cogl_fence_poll_dispatch, - context); - } -} - -CoglFenceClosure * -cogl_framebuffer_add_fence_callback (CoglFramebuffer *framebuffer, - CoglFenceCallback callback, - void *user_data) -{ - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglJournal *journal = cogl_framebuffer_get_journal (framebuffer); - CoglFenceClosure *fence; - - if (!COGL_FLAGS_GET (context->features, COGL_FEATURE_ID_FENCE)) - return NULL; - - fence = g_new0 (CoglFenceClosure, 1); - fence->framebuffer = framebuffer; - fence->callback = callback; - fence->user_data = user_data; - fence->fence_obj = NULL; - - if (journal->entries->len) - { - _cogl_list_insert (journal->pending_fences.prev, &fence->link); - fence->type = FENCE_TYPE_PENDING; - } - else - _cogl_fence_submit (fence); - - return fence; -} - -void -cogl_framebuffer_cancel_fence_callback (CoglFramebuffer *framebuffer, - CoglFenceClosure *fence) -{ - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - - if (fence->type == FENCE_TYPE_PENDING) - { - _cogl_list_remove (&fence->link); - } - else - { - _cogl_list_remove (&fence->link); - - if (fence->type == FENCE_TYPE_WINSYS) - { - const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); - - winsys->fence_destroy (context, fence->fence_obj); - } -#ifdef GL_ARB_sync - else if (fence->type == FENCE_TYPE_GL_ARB) - { - context->glDeleteSync (fence->fence_obj); - } -#endif - } - - g_free (fence); -} - -void -_cogl_fence_cancel_fences_for_framebuffer (CoglFramebuffer *framebuffer) -{ - CoglJournal *journal = cogl_framebuffer_get_journal (framebuffer); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglFenceClosure *fence, *tmp; - - while (!_cogl_list_empty (&journal->pending_fences)) - { - fence = _cogl_container_of (journal->pending_fences.next, - CoglFenceClosure, - link); - cogl_framebuffer_cancel_fence_callback (framebuffer, fence); - } - - _cogl_list_for_each_safe (fence, tmp, &context->fences, link) - { - if (fence->framebuffer == framebuffer) - cogl_framebuffer_cancel_fence_callback (framebuffer, fence); - } -} diff --git a/mutter/cogl/cogl/cogl-fence.h b/mutter/cogl/cogl/cogl-fence.h deleted file mode 100644 index e97b73b..0000000 --- a/mutter/cogl/cogl/cogl-fence.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Collabora Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-types.h" -#include "cogl/cogl-framebuffer.h" - -/** - * CoglFence: - * - * Functions for notification of command completion - * - * Cogl allows notification of GPU command completion; users may mark - * points in the GPU command stream and receive notification when the GPU - * has executed to that point. - */ -typedef struct _CoglFence CoglFence; - -/** - * CoglFenceCallback: - * @fence: Unused. In the future this parameter may be used to pass - * extra information about the fence completion but for now it - * should be ignored. - * @user_data: The private data passed to cogl_framebuffer_add_fence_callback() - * - * The callback prototype used with - * cogl_framebuffer_add_fence_callback() for notification of GPU - * command completion. - */ -typedef void (* CoglFenceCallback) (CoglFence *fence, - void *user_data); - -/** - * CoglFenceClosure: - * - * An opaque type representing one future callback to be made when the - * GPU command stream has passed a certain point. - */ -typedef struct _CoglFenceClosure CoglFenceClosure; - -/** - * cogl_frame_closure_get_user_data: - * @closure: A #CoglFenceClosure returned from cogl_framebuffer_add_fence() - * - * Returns the user_data submitted to cogl_framebuffer_add_fence() which - * returned a given #CoglFenceClosure. - */ -COGL_EXPORT void * -cogl_fence_closure_get_user_data (CoglFenceClosure *closure); - -/** - * cogl_framebuffer_add_fence_callback: - * @framebuffer: The #CoglFramebuffer the commands have been submitted to - * @callback: (scope async): A #CoglFenceCallback to be called when - * all commands submitted to Cogl have been executed - * @user_data: (closure): Private data that will be passed to the callback - * - * Calls the provided callback when all previously-submitted commands have - * been executed by the GPU. - * - * Returns: (transfer none) (nullable): non-NULL if the fence succeeded, - * or %NULL if it was unable to be inserted and the callback will never be - * called. The user does not need to free the closure; it will be freed - * automatically when the callback is called, or cancelled. - */ -COGL_EXPORT CoglFenceClosure * -cogl_framebuffer_add_fence_callback (CoglFramebuffer *framebuffer, - CoglFenceCallback callback, - void *user_data); - -/** - * cogl_framebuffer_cancel_fence_callback: - * @framebuffer: The #CoglFramebuffer the commands were submitted to - * @closure: The #CoglFenceClosure returned from - * cogl_framebuffer_add_fence_callback() - * - * Removes a fence previously submitted with - * cogl_framebuffer_add_fence_callback(); the callback will not be - * called. - */ -COGL_EXPORT void -cogl_framebuffer_cancel_fence_callback (CoglFramebuffer *framebuffer, - CoglFenceClosure *closure); diff --git a/mutter/cogl/cogl/cogl-flags.h b/mutter/cogl/cogl/cogl-flags.h deleted file mode 100644 index 6e91e47..0000000 --- a/mutter/cogl/cogl/cogl-flags.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Neil Roberts - */ - -#pragma once - -#include - -#include "cogl/cogl-util.h" - -G_BEGIN_DECLS - -/* These are macros used to implement a fixed-size array of bits. This - should be used instead of CoglBitmask when the maximum bit number - that will be set is known at compile time, for example when setting - for recording a set of known available features */ - -/* The bits are stored in an array of unsigned longs. To use these - macros, you would typically have an enum defining the available - bits with an extra last enum to define the maximum value. Then to - store the flags you would declare an array of unsigned longs sized - using COGL_FLAGS_N_LONGS_FOR_SIZE, eg: - - typedef enum { FEATURE_A, FEATURE_B, FEATURE_C, N_FEATURES } Features; - - unsigned long feature_flags[COGL_FLAGS_N_LONGS_FOR_SIZE (N_FEATURES)]; -*/ - -#define COGL_FLAGS_N_LONGS_FOR_SIZE(size) \ - (((size) + \ - (sizeof (unsigned long) * 8 - 1)) \ - / (sizeof (unsigned long) * 8)) - -/* @flag is expected to be constant so these should result in a - constant expression. This means that setting a flag is equivalent - to just setting in a bit in a global variable at a known - location */ -#define COGL_FLAGS_GET_INDEX(flag) \ - ((flag) / (sizeof (unsigned long) * 8)) -#define COGL_FLAGS_GET_MASK(flag) \ - (1UL << ((unsigned long) (flag) & \ - (sizeof (unsigned long) * 8 - 1))) - -#define COGL_FLAGS_GET(array, flag) \ - (!!((array)[COGL_FLAGS_GET_INDEX (flag)] & \ - COGL_FLAGS_GET_MASK (flag))) - -/* The expectation here is that @value will be constant so the if - statement will be optimised out */ -#define COGL_FLAGS_SET(array, flag, value) \ - G_STMT_START { \ - if (value) \ - ((array)[COGL_FLAGS_GET_INDEX (flag)] |= \ - COGL_FLAGS_GET_MASK (flag)); \ - else \ - ((array)[COGL_FLAGS_GET_INDEX (flag)] &= \ - ~COGL_FLAGS_GET_MASK (flag)); \ - } G_STMT_END - -/* Macros to help iterate an array of flags. It should be used like - * this: - * - * int n_longs = COGL_FLAGS_N_LONGS_FOR_SIZE (...); - * unsigned long flags[n_longs]; - * int bit_num; - * - * COGL_FLAGS_FOREACH_START (flags, n_longs, bit_num) - * { - * do_something_with_the_bit (bit_num); - * } - * COGL_FLAGS_FOREACH_END; - */ -#define COGL_FLAGS_FOREACH_START(array, n_longs, bit) \ - G_STMT_START { \ - const unsigned long *_p = (array); \ - int _n_longs = (n_longs); \ - int _i; \ - \ - for (_i = 0; _i < _n_longs; _i++) \ - { \ - unsigned long _mask = *(_p++); \ - \ - (bit) = _i * sizeof (unsigned long) * 8 - 1; \ - \ - while (_mask) \ - { \ - int _next_bit = _cogl_util_ffsl (_mask); \ - (bit) += _next_bit; \ - /* This odd two-part shift is to avoid */ \ - /* shifting by sizeof (long)*8 which has */ \ - /* undefined results according to the */ \ - /* C spec (and seems to be a no-op in */ \ - /* practice) */ \ - _mask = (_mask >> (_next_bit - 1)) >> 1; \ - -#define COGL_FLAGS_FOREACH_END \ - } } } G_STMT_END - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-frame-info-private.h b/mutter/cogl/cogl/cogl-frame-info-private.h deleted file mode 100644 index 89a1eb3..0000000 --- a/mutter/cogl/cogl/cogl-frame-info-private.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-frame-info.h" -#include "cogl/cogl-context.h" - -typedef enum _CoglFrameInfoFlag -{ - COGL_FRAME_INFO_FLAG_NONE = 0, - COGL_FRAME_INFO_FLAG_SYMBOLIC = 1 << 0, - /* presentation_time timestamp was provided by the hardware */ - COGL_FRAME_INFO_FLAG_HW_CLOCK = 1 << 1, - /* - * The presentation of this frame was done zero-copy. This means the buffer - * from the client was given to display hardware as is, without copying it. - * Compositing with OpenGL counts as copying, even if textured directly from - * the client buffer. Possible zero-copy cases include direct scanout of a - * fullscreen surface and a surface on a hardware overlay. - */ - COGL_FRAME_INFO_FLAG_ZERO_COPY = 1 << 2, - /* - * The presentation was synchronized to the "vertical retrace" by the display - * hardware such that tearing does not happen. Relying on user space - * scheduling is not acceptable for this flag. If presentation is done by a - * copy to the active frontbuffer, then it must guarantee that tearing cannot - * happen. - */ - COGL_FRAME_INFO_FLAG_VSYNC = 1 << 3, -} CoglFrameInfoFlag; - -struct _CoglFrameInfo -{ - GObject parent_instance; - - CoglContext *context; - - int64_t frame_counter; - int64_t presentation_time_us; /* CLOCK_MONOTONIC */ - float refresh_rate; - - int64_t global_frame_counter; - - CoglFrameInfoFlag flags; - - unsigned int sequence; - - CoglTimestampQuery *timestamp_query; - gboolean has_valid_gpu_rendering_duration; - int64_t gpu_time_before_buffer_swap_ns; - int64_t cpu_time_before_buffer_swap_us; - - gboolean has_target_presentation_time; - int64_t target_presentation_time_us; -}; - -COGL_EXPORT -CoglFrameInfo *cogl_frame_info_new (CoglContext *context, - int64_t global_frame_counter); - -COGL_EXPORT -void cogl_frame_info_set_target_presentation_time (CoglFrameInfo *info, - int64_t presentation_time_us); diff --git a/mutter/cogl/cogl/cogl-frame-info.c b/mutter/cogl/cogl/cogl-frame-info.c deleted file mode 100644 index 40e5291..0000000 --- a/mutter/cogl/cogl/cogl-frame-info.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include "cogl/cogl-frame-info-private.h" -#include "cogl/cogl-context-private.h" - -G_DEFINE_TYPE (CoglFrameInfo, cogl_frame_info, G_TYPE_OBJECT); - -static void -cogl_frame_info_dispose (GObject *object) -{ - CoglFrameInfo *info = COGL_FRAME_INFO (object); - - if (info->timestamp_query) - cogl_context_free_timestamp_query (info->context, info->timestamp_query); - - G_OBJECT_CLASS (cogl_frame_info_parent_class)->dispose (object); -} - -static void -cogl_frame_info_init (CoglFrameInfo *info) -{ -} - -static void -cogl_frame_info_class_init (CoglFrameInfoClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = cogl_frame_info_dispose; -} - -CoglFrameInfo * -cogl_frame_info_new (CoglContext *context, - int64_t global_frame_counter) -{ - CoglFrameInfo *info; - - info = g_object_new (COGL_TYPE_FRAME_INFO, NULL); - info->context = context; - info->global_frame_counter = global_frame_counter; - - return info; -} - -int64_t -cogl_frame_info_get_frame_counter (CoglFrameInfo *info) -{ - return info->frame_counter; -} - -int64_t -cogl_frame_info_get_presentation_time_us (CoglFrameInfo *info) -{ - g_warn_if_fail (!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC)); - - return info->presentation_time_us; -} - -float -cogl_frame_info_get_refresh_rate (CoglFrameInfo *info) -{ - g_warn_if_fail (!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC)); - - return info->refresh_rate; -} - -int64_t -cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info) -{ - return info->global_frame_counter; -} - -gboolean -cogl_frame_info_get_is_symbolic (CoglFrameInfo *info) -{ - return !!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC); -} - -gboolean -cogl_frame_info_is_hw_clock (CoglFrameInfo *info) -{ - return !!(info->flags & COGL_FRAME_INFO_FLAG_HW_CLOCK); -} - -gboolean -cogl_frame_info_is_zero_copy (CoglFrameInfo *info) -{ - return !!(info->flags & COGL_FRAME_INFO_FLAG_ZERO_COPY); -} - -gboolean -cogl_frame_info_is_vsync (CoglFrameInfo *info) -{ - return !!(info->flags & COGL_FRAME_INFO_FLAG_VSYNC); -} - -unsigned int -cogl_frame_info_get_sequence (CoglFrameInfo *info) -{ - g_warn_if_fail (!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC)); - - return info->sequence; -} - -gboolean -cogl_frame_info_has_valid_gpu_rendering_duration (CoglFrameInfo *info) -{ - return info->has_valid_gpu_rendering_duration; -} - -int64_t -cogl_frame_info_get_rendering_duration_ns (CoglFrameInfo *info) -{ - int64_t gpu_time_rendering_done_ns; - - if (!info->timestamp_query || - info->gpu_time_before_buffer_swap_ns == 0) - return 0; - - gpu_time_rendering_done_ns = - cogl_context_timestamp_query_get_time_ns (info->context, - info->timestamp_query); - - return gpu_time_rendering_done_ns - info->gpu_time_before_buffer_swap_ns; -} - -int64_t -cogl_frame_info_get_time_before_buffer_swap_us (CoglFrameInfo *info) -{ - return info->cpu_time_before_buffer_swap_us; -} - -void -cogl_frame_info_set_target_presentation_time (CoglFrameInfo *info, - int64_t presentation_time_us) -{ - info->has_target_presentation_time = TRUE; - info->target_presentation_time_us = presentation_time_us; -} diff --git a/mutter/cogl/cogl/cogl-frame-info.h b/mutter/cogl/cogl/cogl-frame-info.h deleted file mode 100644 index 2a24cfa..0000000 --- a/mutter/cogl/cogl/cogl-frame-info.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Owen Taylor - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-types.h" -#include "cogl/cogl-output.h" - -#include -#include - -G_BEGIN_DECLS - -/** - * CoglFrameInfo: - * - * Frame information. - */ -typedef struct _CoglFrameInfo CoglFrameInfo; - -#define COGL_TYPE_FRAME_INFO (cogl_frame_info_get_type ()) - -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglFrameInfo, - cogl_frame_info, - COGL, - FRAME_INFO, - GObject) - -/** - * cogl_frame_info_get_frame_counter: - * @info: a #CoglFrameInfo object - * - * Gets the frame counter for the #CoglOnscreen that corresponds - * to this frame. - * - * Return value: The frame counter value - */ -COGL_EXPORT -int64_t cogl_frame_info_get_frame_counter (CoglFrameInfo *info); - -/** - * cogl_frame_info_get_presentation_time_us: - * @info: a #CoglFrameInfo object - * - * Gets the presentation time for the frame. This is the time at which - * the frame became visible to the user. - * - * The presentation time measured in microseconds, is based on - * CLOCK_MONOTONIC. - * - * Some buggy Mesa drivers up to 9.0.1 may - * incorrectly report non-monotonic timestamps. - * - * Return value: the presentation time for the frame - */ -COGL_EXPORT -int64_t cogl_frame_info_get_presentation_time_us (CoglFrameInfo *info); - -/** - * cogl_frame_info_get_refresh_rate: - * @info: a #CoglFrameInfo object - * - * Gets the refresh rate in Hertz for the output that the frame was on - * at the time the frame was presented. - * - * Some platforms can't associate a #CoglOutput with a - * #CoglFrameInfo object but are able to report a refresh rate via - * this api. Therefore if you need this information then this api is - * more reliable than using cogl_frame_info_get_output() followed by - * cogl_output_get_refresh_rate(). - * - * Return value: the refresh rate in Hertz - */ -COGL_EXPORT -float cogl_frame_info_get_refresh_rate (CoglFrameInfo *info); - -COGL_EXPORT -int64_t cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info); - -COGL_EXPORT -gboolean cogl_frame_info_get_is_symbolic (CoglFrameInfo *info); - -COGL_EXPORT -gboolean cogl_frame_info_is_hw_clock (CoglFrameInfo *info); - -COGL_EXPORT -gboolean cogl_frame_info_is_zero_copy (CoglFrameInfo *info); - -COGL_EXPORT -gboolean cogl_frame_info_is_vsync (CoglFrameInfo *info); - -COGL_EXPORT -unsigned int cogl_frame_info_get_sequence (CoglFrameInfo *info); - -COGL_EXPORT -gboolean cogl_frame_info_has_valid_gpu_rendering_duration (CoglFrameInfo *info); - -COGL_EXPORT -int64_t cogl_frame_info_get_rendering_duration_ns (CoglFrameInfo *info); - -COGL_EXPORT -int64_t cogl_frame_info_get_time_before_buffer_swap_us (CoglFrameInfo *info); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-framebuffer-driver.c b/mutter/cogl/cogl/cogl-framebuffer-driver.c deleted file mode 100644 index a1f595f..0000000 --- a/mutter/cogl/cogl/cogl-framebuffer-driver.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2012 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "config.h" - -#include "cogl/cogl-framebuffer-driver.h" - -enum -{ - PROP_0, - - PROP_FRAMEBUFFER, - - N_PROPS -}; - -static GParamSpec *obj_props[N_PROPS]; - -typedef struct _CoglFramebufferDriverPrivate -{ - CoglFramebuffer *framebuffer; -} CoglFramebufferDriverPrivate; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (CoglFramebufferDriver, - cogl_framebuffer_driver, - G_TYPE_OBJECT) - -CoglFramebuffer * -cogl_framebuffer_driver_get_framebuffer (CoglFramebufferDriver *driver) -{ - CoglFramebufferDriverPrivate *priv = - cogl_framebuffer_driver_get_instance_private (driver); - - return priv->framebuffer; -} - -void -cogl_framebuffer_driver_query_bits (CoglFramebufferDriver *driver, - CoglFramebufferBits *bits) -{ - COGL_FRAMEBUFFER_DRIVER_GET_CLASS (driver)->query_bits (driver, bits); -} - -void -cogl_framebuffer_driver_clear (CoglFramebufferDriver *driver, - unsigned long buffers, - float red, - float green, - float blue, - float alpha) -{ - COGL_FRAMEBUFFER_DRIVER_GET_CLASS (driver)->clear (driver, - buffers, - red, - green, - blue, - alpha); -} - -void -cogl_framebuffer_driver_finish (CoglFramebufferDriver *driver) -{ - COGL_FRAMEBUFFER_DRIVER_GET_CLASS (driver)->finish (driver); -} - -void -cogl_framebuffer_driver_flush (CoglFramebufferDriver *driver) -{ - COGL_FRAMEBUFFER_DRIVER_GET_CLASS (driver)->flush (driver); -} - -void -cogl_framebuffer_driver_discard_buffers (CoglFramebufferDriver *driver, - unsigned long buffers) -{ - COGL_FRAMEBUFFER_DRIVER_GET_CLASS (driver)->discard_buffers (driver, buffers); -} - -void -cogl_framebuffer_driver_draw_attributes (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags) -{ - COGL_FRAMEBUFFER_DRIVER_GET_CLASS (driver)->draw_attributes (driver, - pipeline, - mode, - first_vertex, - n_vertices, - attributes, - n_attributes, - flags); -} - -void -cogl_framebuffer_driver_draw_indexed_attributes (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags) -{ - CoglFramebufferDriverClass *klass = - COGL_FRAMEBUFFER_DRIVER_GET_CLASS (driver); - - klass->draw_indexed_attributes (driver, - pipeline, - mode, - first_vertex, - n_vertices, - indices, - attributes, - n_attributes, - flags); -} - -gboolean -cogl_framebuffer_driver_read_pixels_into_bitmap (CoglFramebufferDriver *driver, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap, - GError **error) -{ - CoglFramebufferDriverClass *klass = - COGL_FRAMEBUFFER_DRIVER_GET_CLASS (driver); - - return klass->read_pixels_into_bitmap (driver, x, y, source, bitmap, error); -} - -static void -cogl_framebuffer_driver_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (object); - CoglFramebufferDriverPrivate *priv = - cogl_framebuffer_driver_get_instance_private (driver); - - switch (prop_id) - { - case PROP_FRAMEBUFFER: - g_value_set_object (value, priv->framebuffer); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -cogl_framebuffer_driver_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (object); - CoglFramebufferDriverPrivate *priv = - cogl_framebuffer_driver_get_instance_private (driver); - - switch (prop_id) - { - case PROP_FRAMEBUFFER: - priv->framebuffer = g_value_get_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -cogl_framebuffer_driver_init (CoglFramebufferDriver *driver) -{ -} - -static void -cogl_framebuffer_driver_class_init (CoglFramebufferDriverClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->get_property = cogl_framebuffer_driver_get_property; - object_class->set_property = cogl_framebuffer_driver_set_property; - - obj_props[PROP_FRAMEBUFFER] = - g_param_spec_object ("framebuffer", NULL, NULL, - COGL_TYPE_FRAMEBUFFER, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - g_object_class_install_properties (object_class, N_PROPS, obj_props); -} diff --git a/mutter/cogl/cogl/cogl-framebuffer-driver.h b/mutter/cogl/cogl/cogl-framebuffer-driver.h deleted file mode 100644 index d6c58f6..0000000 --- a/mutter/cogl/cogl/cogl-framebuffer-driver.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2012 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#pragma once - -#include "cogl/cogl-attribute-private.h" -#include "cogl/cogl-framebuffer.h" - -typedef struct _CoglFramebufferBits CoglFramebufferBits; - -#define COGL_TYPE_FRAMEBUFFER_DRIVER (cogl_framebuffer_driver_get_type ()) -G_DECLARE_DERIVABLE_TYPE (CoglFramebufferDriver, - cogl_framebuffer_driver, - COGL, FRAMEBUFFER_DRIVER, - GObject) - -struct _CoglFramebufferDriverClass -{ - GObjectClass parent_cleass; - - void (* query_bits) (CoglFramebufferDriver *driver, - CoglFramebufferBits *bits); - - void (* clear) (CoglFramebufferDriver *driver, - unsigned long buffers, - float red, - float green, - float blue, - float alpha); - - void (* finish) (CoglFramebufferDriver *driver); - - void (* flush) (CoglFramebufferDriver *driver); - - void (* discard_buffers) (CoglFramebufferDriver *driver, - unsigned long buffers); - - void (* draw_attributes) (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags); - - void (* draw_indexed_attributes) (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags); - - gboolean (* read_pixels_into_bitmap) (CoglFramebufferDriver *driver, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap, - GError **error); -}; - -CoglFramebuffer * -cogl_framebuffer_driver_get_framebuffer (CoglFramebufferDriver *driver); - -void -cogl_framebuffer_driver_query_bits (CoglFramebufferDriver *driver, - CoglFramebufferBits *bits); - -void -cogl_framebuffer_driver_clear (CoglFramebufferDriver *driver, - unsigned long buffers, - float red, - float green, - float blue, - float alpha); - -void -cogl_framebuffer_driver_finish (CoglFramebufferDriver *driver); - -void -cogl_framebuffer_driver_flush (CoglFramebufferDriver *driver); - -void -cogl_framebuffer_driver_discard_buffers (CoglFramebufferDriver *driver, - unsigned long buffers); - -void -cogl_framebuffer_driver_draw_attributes (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags); - -void -cogl_framebuffer_driver_draw_indexed_attributes (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags); - -gboolean -cogl_framebuffer_driver_read_pixels_into_bitmap (CoglFramebufferDriver *driver, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap, - GError **error); diff --git a/mutter/cogl/cogl/cogl-framebuffer-private.h b/mutter/cogl/cogl/cogl-framebuffer-private.h deleted file mode 100644 index eb014e0..0000000 --- a/mutter/cogl/cogl/cogl-framebuffer-private.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-framebuffer-driver.h" -#include "cogl/cogl-matrix-stack-private.h" -#include "cogl/cogl-journal-private.h" -#include "cogl/winsys/cogl-winsys-private.h" -#include "cogl/cogl-attribute-private.h" -#include "cogl/cogl-clip-stack.h" - -typedef enum -{ - COGL_FRAMEBUFFER_DRIVER_TYPE_FBO, - COGL_FRAMEBUFFER_DRIVER_TYPE_BACK, -} CoglFramebufferDriverType; - -struct _CoglFramebufferDriverConfig -{ - CoglFramebufferDriverType type; - - gboolean disable_depth_and_stencil; -}; - -typedef struct -{ - CoglSwapChain *swap_chain; - gboolean need_stencil; - int samples_per_pixel; - gboolean stereo_enabled; -} CoglFramebufferConfig; - -/* XXX: The order of these indices determines the order they are - * flushed. - * - * Flushing clip state may trash the modelview and projection matrices - * so we must do it before flushing the matrices. - */ -typedef enum _CoglFramebufferStateIndex -{ - COGL_FRAMEBUFFER_STATE_INDEX_BIND = 0, - COGL_FRAMEBUFFER_STATE_INDEX_VIEWPORT = 1, - COGL_FRAMEBUFFER_STATE_INDEX_CLIP = 2, - COGL_FRAMEBUFFER_STATE_INDEX_DITHER = 3, - COGL_FRAMEBUFFER_STATE_INDEX_MODELVIEW = 4, - COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION = 5, - COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING = 6, - COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE = 7, - COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE = 8, - COGL_FRAMEBUFFER_STATE_INDEX_MAX = 9 -} CoglFramebufferStateIndex; - -typedef enum _CoglFramebufferState -{ - COGL_FRAMEBUFFER_STATE_BIND = 1<<0, - COGL_FRAMEBUFFER_STATE_VIEWPORT = 1<<1, - COGL_FRAMEBUFFER_STATE_CLIP = 1<<2, - COGL_FRAMEBUFFER_STATE_DITHER = 1<<3, - COGL_FRAMEBUFFER_STATE_MODELVIEW = 1<<4, - COGL_FRAMEBUFFER_STATE_PROJECTION = 1<<5, - COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<6, - COGL_FRAMEBUFFER_STATE_DEPTH_WRITE = 1<<7, - COGL_FRAMEBUFFER_STATE_STEREO_MODE = 1<<8 -} CoglFramebufferState; - -#define COGL_FRAMEBUFFER_STATE_ALL ((1<last_entry; -} - -static inline CoglMatrixEntry * -_cogl_framebuffer_get_projection_entry (CoglFramebuffer *framebuffer) -{ - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - return projection_stack->last_entry; -} - -gboolean -_cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap, - GError **error); - -CoglJournal * -cogl_framebuffer_get_journal (CoglFramebuffer *framebuffer); - -CoglFramebufferDriver * -cogl_framebuffer_get_driver (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_is_y_flipped: - * @framebuffer: a #CoglFramebuffer - * - * Returns %TRUE if the Y coordinate 0 means the bottom of the framebuffer, and - * %FALSE if the Y coordinate means the top. - */ -gboolean -cogl_framebuffer_is_y_flipped (CoglFramebuffer *framebuffer); diff --git a/mutter/cogl/cogl/cogl-framebuffer.c b/mutter/cogl/cogl/cogl-framebuffer.c deleted file mode 100644 index 269c49d..0000000 --- a/mutter/cogl/cogl/cogl-framebuffer.c +++ /dev/null @@ -1,2631 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2012 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include - -#include "cogl/cogl-debug.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-display-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-onscreen-template-private.h" -#include "cogl/cogl-clip-stack.h" -#include "cogl/cogl-journal-private.h" -#include "cogl/cogl-pipeline-state-private.h" -#include "cogl/cogl-primitive-private.h" -#include "cogl/cogl-offscreen.h" -#include "cogl/cogl1-context.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl-primitives-private.h" -#include "cogl/cogl-trace.h" -#include "cogl/winsys/cogl-winsys-private.h" - -enum -{ - PROP_0, - - PROP_CONTEXT, - PROP_DRIVER_CONFIG, - PROP_WIDTH, - PROP_HEIGHT, - - N_PROPS -}; - -static GParamSpec *obj_props[N_PROPS]; - -enum -{ - DESTROY, - - N_SIGNALS -}; - -static guint signals[N_SIGNALS]; - -#ifdef COGL_ENABLE_DEBUG -static GQuark wire_pipeline_key = 0; -#endif - -typedef struct _CoglFramebufferPrivate -{ - CoglContext *context; - - /* The user configuration before allocation... */ - CoglFramebufferConfig config; - - CoglFramebufferDriverConfig driver_config; - CoglFramebufferDriver *driver; - - int width; - int height; - /* Format of the pixels in the framebuffer (including the expected - premult state) */ - CoglPixelFormat internal_format; - gboolean allocated; - - CoglMatrixStack *modelview_stack; - CoglMatrixStack *projection_stack; - float viewport_x; - float viewport_y; - float viewport_width; - float viewport_height; - int viewport_age; - int viewport_age_for_scissor_workaround; - - CoglClipStack *clip_stack; - - gboolean dither_enabled; - gboolean depth_writing_enabled; - CoglStereoMode stereo_mode; - - /* We journal the textured rectangles we want to submit to OpenGL so - * we have an opportunity to batch them together into less draw - * calls. */ - CoglJournal *journal; - - /* The scene of a given framebuffer may depend on images in other - * framebuffers... */ - GList *deps; - - /* As part of an optimization for reading-back single pixels from a - * framebuffer in some simple cases where the geometry is still - * available in the journal we need to track the bounds of the last - * region cleared, its color and we need to track when something - * does in fact draw to that region so it is no longer clear. - */ - float clear_color_red; - float clear_color_green; - float clear_color_blue; - float clear_color_alpha; - int clear_clip_x0; - int clear_clip_y0; - int clear_clip_x1; - int clear_clip_y1; - gboolean clear_clip_dirty; - - int samples_per_pixel; - - /* Whether the depth buffer was enabled for this framebuffer, - * usually means it needs to be cleared before being reused next. - */ - gboolean depth_buffer_clear_needed; -} CoglFramebufferPrivate; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (CoglFramebuffer, cogl_framebuffer, - G_TYPE_OBJECT) - -uint32_t -cogl_framebuffer_error_quark (void) -{ - return g_quark_from_static_string ("cogl-framebuffer-error-quark"); -} - -gboolean -cogl_is_framebuffer (void *object) -{ - return COGL_IS_FRAMEBUFFER (object); -} - -static void -cogl_framebuffer_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - switch (prop_id) - { - case PROP_CONTEXT: - g_value_set_object (value, priv->context); - break; - case PROP_DRIVER_CONFIG: - g_value_set_pointer (value, &priv->driver_config); - break; - case PROP_WIDTH: - g_value_set_int (value, priv->width); - break; - case PROP_HEIGHT: - g_value_set_int (value, priv->height); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -cogl_framebuffer_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglFramebufferDriverConfig *driver_config; - - switch (prop_id) - { - case PROP_CONTEXT: - priv->context = g_value_get_object (value); - break; - case PROP_DRIVER_CONFIG: - driver_config = g_value_get_pointer (value); - if (driver_config) - priv->driver_config = *driver_config; - break; - case PROP_WIDTH: - priv->width = g_value_get_int (value); - break; - case PROP_HEIGHT: - priv->height = g_value_get_int (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -cogl_framebuffer_constructed (GObject *object) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - g_assert (priv->context); - - priv->internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE; - priv->viewport_x = 0; - priv->viewport_y = 0; - priv->viewport_width = priv->width; - priv->viewport_height = priv->height; - priv->viewport_age = 0; - priv->viewport_age_for_scissor_workaround = -1; - priv->dither_enabled = TRUE; - priv->depth_writing_enabled = TRUE; - priv->depth_buffer_clear_needed = TRUE; - - priv->modelview_stack = cogl_matrix_stack_new (priv->context); - priv->projection_stack = cogl_matrix_stack_new (priv->context); - - priv->samples_per_pixel = 0; - - priv->clip_stack = NULL; - - priv->journal = _cogl_journal_new (framebuffer); - - /* Ensure we know the framebuffer->clear_color* members can't be - * referenced for our fast-path read-pixel optimization (see - * _cogl_journal_try_read_pixel()) until some region of the - * framebuffer is initialized. - */ - priv->clear_clip_dirty = TRUE; - - /* XXX: We have to maintain a central list of all framebuffers - * because at times we need to be able to flush all known journals. - * - * Examples where we need to flush all journals are: - * - because journal entries can reference OpenGL texture - * coordinates that may not survive texture-atlas reorganization - * so we need the ability to flush those entries. - * - because although we generally advise against modifying - * pipelines after construction we have to handle that possibility - * and since pipelines may be referenced in journal entries we - * need to be able to flush them before allowing the pipelines to - * be changed. - * - * Note we don't maintain a list of journals and associate - * framebuffers with journals by e.g. having a journal->framebuffer - * reference since that would introduce a circular reference. - * - * Note: As a future change to try and remove the need to index all - * journals it might be possible to defer resolving of OpenGL - * texture coordinates for rectangle primitives until we come to - * flush a journal. This would mean for instance that a single - * rectangle entry in a journal could later be expanded into - * multiple quad primitives to handle sliced textures but would mean - * we don't have to worry about retaining references to OpenGL - * texture coordinates that may later become invalid. - */ - priv->context->framebuffers = g_list_prepend (priv->context->framebuffers, - framebuffer); -} - -void -_cogl_framebuffer_set_internal_format (CoglFramebuffer *framebuffer, - CoglPixelFormat internal_format) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->internal_format = internal_format; -} - -CoglPixelFormat -cogl_framebuffer_get_internal_format (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->internal_format; -} - -const CoglFramebufferConfig * -cogl_framebuffer_get_config (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return &priv->config; -} - -void -cogl_framebuffer_init_config (CoglFramebuffer *framebuffer, - const CoglFramebufferConfig *config) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->config = *config; - g_object_ref (priv->config.swap_chain); -} - -static void -cogl_framebuffer_dispose (GObject *object) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglContext *ctx = priv->context; - - if (priv->journal) - { - _cogl_journal_flush (priv->journal); - - g_signal_emit (framebuffer, signals[DESTROY], 0); - - _cogl_fence_cancel_fences_for_framebuffer (framebuffer); - } - - g_clear_pointer (&priv->clip_stack, _cogl_clip_stack_unref); - g_clear_object (&priv->modelview_stack); - g_clear_object (&priv->projection_stack); - g_clear_object (&priv->journal); - - ctx->framebuffers = g_list_remove (ctx->framebuffers, framebuffer); - - if (ctx->current_draw_buffer == framebuffer) - ctx->current_draw_buffer = NULL; - if (ctx->current_read_buffer == framebuffer) - ctx->current_read_buffer = NULL; - - g_clear_object (&priv->driver); - - G_OBJECT_CLASS (cogl_framebuffer_parent_class)->dispose (object); -} - -static void -cogl_framebuffer_init (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->width = -1; - priv->height = -1; -} - -static void -cogl_framebuffer_class_init (CoglFramebufferClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = cogl_framebuffer_dispose; - object_class->constructed = cogl_framebuffer_constructed; - object_class->get_property = cogl_framebuffer_get_property; - object_class->set_property = cogl_framebuffer_set_property; - - obj_props[PROP_CONTEXT] = - g_param_spec_object ("context", NULL, NULL, - COGL_TYPE_CONTEXT, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_DRIVER_CONFIG] = - g_param_spec_pointer ("driver-config", NULL, NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_WIDTH] = - g_param_spec_int ("width", NULL, NULL, - -1, INT_MAX, -1, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_HEIGHT] = - g_param_spec_int ("height", NULL, NULL, - -1, INT_MAX, -1, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, N_PROPS, obj_props); - - 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); -} - -/* This version of cogl_clear can be used internally as an alternative - * to avoid flushing the journal or the framebuffer state. This is - * needed when doing operations that may be called while flushing - * the journal */ -void -_cogl_framebuffer_clear_without_flush4f (CoglFramebuffer *framebuffer, - unsigned long buffers, - float red, - float green, - float blue, - float alpha) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - if (!buffers) - { - static gboolean shown = FALSE; - - if (!shown) - { - g_warning ("You should specify at least one auxiliary buffer " - "when calling cogl_framebuffer_clear"); - } - - return; - } - - cogl_framebuffer_driver_clear (priv->driver, - buffers, - red, - green, - blue, - alpha); -} - -void -_cogl_framebuffer_mark_clear_clip_dirty (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->clear_clip_dirty = TRUE; -} - -void -cogl_framebuffer_set_depth_buffer_clear_needed (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->depth_buffer_clear_needed = TRUE; -} - -void -cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, - unsigned long buffers, - float red, - float green, - float blue, - float alpha) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglClipStack *clip_stack = _cogl_framebuffer_get_clip_stack (framebuffer); - gboolean had_depth_and_color_buffer_bits; - int scissor_x0; - int scissor_y0; - int scissor_x1; - int scissor_y1; - - had_depth_and_color_buffer_bits = - (buffers & COGL_BUFFER_BIT_DEPTH) && - (buffers & COGL_BUFFER_BIT_COLOR); - - if (!priv->depth_buffer_clear_needed && - (buffers & COGL_BUFFER_BIT_DEPTH)) - buffers &= ~(COGL_BUFFER_BIT_DEPTH); - - if (buffers == 0) - return; - - _cogl_clip_stack_get_bounds (clip_stack, - &scissor_x0, &scissor_y0, - &scissor_x1, &scissor_y1); - - /* NB: the previous clear could have had an arbitrary clip. - * NB: everything for the last frame might still be in the journal - * but we can't assume anything about how each entry was - * clipped. - * NB: Clutter will scissor its pick renders which would mean all - * journal entries have a common ClipStack entry, but without - * a layering violation Cogl has to explicitly walk the journal - * entries to determine if this is the case. - * NB: We have a software only read-pixel optimization in the - * journal that determines the color at a given framebuffer - * coordinate for simple scenes without rendering with the GPU. - * When Clutter is hitting this fast-path we can expect to - * receive calls to clear the framebuffer with an un-flushed - * journal. - * NB: To fully support software based picking for Clutter we - * need to be able to reliably detect when the contents of a - * journal can be discarded and when we can skip the call to - * glClear because it matches the previous clear request. - */ - - /* Note: we don't check for the stencil buffer being cleared here - * since there isn't any public cogl api to manipulate the stencil - * buffer. - * - * Note: we check for an exact clip match here because - * 1) a smaller clip could mean existing journal entries may - * need to contribute to regions outside the new clear-clip - * 2) a larger clip would mean we need to issue a real - * glClear and we only care about cases avoiding a - * glClear. - * - * Note: Comparing without an epsilon is considered - * appropriate here. - */ - if (had_depth_and_color_buffer_bits && - !priv->clear_clip_dirty && - priv->clear_color_red == red && - priv->clear_color_green == green && - priv->clear_color_blue == blue && - priv->clear_color_alpha == alpha && - scissor_x0 == priv->clear_clip_x0 && - scissor_y0 == priv->clear_clip_y0 && - scissor_x1 == priv->clear_clip_x1 && - scissor_y1 == priv->clear_clip_y1) - { - /* NB: We only have to consider the clip state of journal - * entries if the current clear is clipped since otherwise we - * know every pixel of the framebuffer is affected by the clear - * and so all journal entries become redundant and can simply be - * discarded. - */ - if (clip_stack) - { - /* - * Note: the function for checking the journal entries is - * quite strict. It avoids detailed checking of all entry - * clip_stacks by only checking the details of the first - * entry and then it only verifies that the remaining - * entries share the same clip_stack ancestry. This means - * it's possible for some false negatives here but that will - * just result in us falling back to a real clear. - */ - if (_cogl_journal_all_entries_within_bounds (priv->journal, - scissor_x0, scissor_y0, - scissor_x1, scissor_y1)) - { - _cogl_journal_discard (priv->journal); - goto cleared; - } - } - else - { - _cogl_journal_discard (priv->journal); - goto cleared; - } - } - - COGL_NOTE (DRAW, "Clear begin"); - - _cogl_framebuffer_flush_journal (framebuffer); - - /* NB: cogl_context_flush_framebuffer_state may disrupt various state (such - * as the pipeline state) when flushing the clip stack, so should - * always be done first when preparing to draw. */ - cogl_context_flush_framebuffer_state (context, - framebuffer, framebuffer, - COGL_FRAMEBUFFER_STATE_ALL); - - _cogl_framebuffer_clear_without_flush4f (framebuffer, buffers, - red, green, blue, alpha); - - /* This is a debugging variable used to visually display the quad - * batches from the journal. It is reset here to increase the - * chances of getting the same colours for each frame during an - * animation */ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_RECTANGLES)) && - buffers & COGL_BUFFER_BIT_COLOR) - { - priv->context->journal_rectangles_color = 1; - } - - COGL_NOTE (DRAW, "Clear end"); - -cleared: - - _cogl_framebuffer_mark_clear_clip_dirty (framebuffer); - - if (buffers & COGL_BUFFER_BIT_DEPTH) - priv->depth_buffer_clear_needed = FALSE; - - if (had_depth_and_color_buffer_bits) - { - /* For our fast-path for reading back a single pixel of simple - * scenes where the whole frame is in the journal we need to - * track the cleared color of the framebuffer in case the point - * read doesn't intersect any of the journal rectangles. */ - priv->clear_clip_dirty = FALSE; - priv->clear_color_red = red; - priv->clear_color_green = green; - priv->clear_color_blue = blue; - priv->clear_color_alpha = alpha; - - /* NB: A clear may be scissored so we need to track the extents - * that the clear is applicable too... */ - _cogl_clip_stack_get_bounds (clip_stack, - &priv->clear_clip_x0, - &priv->clear_clip_y0, - &priv->clear_clip_x1, - &priv->clear_clip_y1); - } -} - -/* Note: the 'buffers' and 'color' arguments were switched around on - * purpose compared to the original cogl_clear API since it was odd - * that you would be expected to specify a color before even - * necessarily choosing to clear the color buffer. - */ -void -cogl_framebuffer_clear (CoglFramebuffer *framebuffer, - unsigned long buffers, - const CoglColor *color) -{ - cogl_framebuffer_clear4f (framebuffer, buffers, - cogl_color_get_red (color), - cogl_color_get_green (color), - cogl_color_get_blue (color), - cogl_color_get_alpha (color)); -} - -/* We will lazily allocate framebuffers if necessary when querying - * their size/viewport but note we need to be careful in the case of - * onscreen framebuffers that are instantiated with an initial request - * size that we don't trigger an allocation when this is queried since - * that would lead to a recursion when the winsys backend queries this - * requested size during allocation. */ -static void -ensure_size_initialized (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - /* In the case of offscreen framebuffers backed by a texture then - * until that texture has been allocated we might not know the size - * of the framebuffer */ - if (priv->width < 0) - { - /* Currently we assume the size is always initialized for - * onscreen framebuffers. */ - g_return_if_fail (COGL_IS_OFFSCREEN (framebuffer)); - - /* We also assume the size would have been initialized if the - * framebuffer were allocated. */ - g_return_if_fail (!priv->allocated); - - cogl_framebuffer_allocate (framebuffer, NULL); - } -} - -void -cogl_framebuffer_update_size (CoglFramebuffer *framebuffer, - int width, - int height) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->width = width; - priv->height = height; - - cogl_framebuffer_set_viewport (framebuffer, 0, 0, width, height); -} - -int -cogl_framebuffer_get_width (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - ensure_size_initialized (framebuffer); - return priv->width; -} - -int -cogl_framebuffer_get_height (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - ensure_size_initialized (framebuffer); - return priv->height; -} - -CoglClipStack * -_cogl_framebuffer_get_clip_stack (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->clip_stack; -} - -void -cogl_framebuffer_set_viewport4fv (CoglFramebuffer *framebuffer, - float *viewport) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - if (priv->viewport_x == viewport[0] && - priv->viewport_y == viewport[1] && - priv->viewport_width == viewport[2] && - priv->viewport_height == viewport[3]) - return; - - priv->viewport_x = viewport[0]; - priv->viewport_y = viewport[1]; - priv->viewport_width = viewport[2]; - priv->viewport_height = viewport[3]; - priv->viewport_age++; -} - -void -cogl_framebuffer_set_viewport (CoglFramebuffer *framebuffer, - float x, - float y, - float width, - float height) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - g_return_if_fail (width > 0 && height > 0); - - if (priv->viewport_x == x && - priv->viewport_y == y && - priv->viewport_width == width && - priv->viewport_height == height) - return; - - priv->viewport_x = x; - priv->viewport_y = y; - priv->viewport_width = width; - priv->viewport_height = height; -} - -float -cogl_framebuffer_get_viewport_x (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->viewport_x; -} - -float -cogl_framebuffer_get_viewport_y (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->viewport_y; -} - -float -cogl_framebuffer_get_viewport_width (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - ensure_size_initialized (framebuffer); - return priv->viewport_width; -} - -float -cogl_framebuffer_get_viewport_height (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - ensure_size_initialized (framebuffer); - return priv->viewport_height; -} - -void -cogl_framebuffer_get_viewport4f (CoglFramebuffer *framebuffer, - float *viewport_x, - float *viewport_y, - float *viewport_width, - float *viewport_height) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - ensure_size_initialized (framebuffer); - - *viewport_x = priv->viewport_x; - *viewport_y = priv->viewport_y; - *viewport_width = priv->viewport_width; - *viewport_height = priv->viewport_height; -} - -void -cogl_framebuffer_get_viewport4fv (CoglFramebuffer *framebuffer, - float *viewport) -{ - cogl_framebuffer_get_viewport4f (framebuffer, - &viewport[0], - &viewport[1], - &viewport[2], - &viewport[3]); -} - -CoglMatrixStack * -_cogl_framebuffer_get_modelview_stack (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->modelview_stack; -} - -CoglMatrixStack * -_cogl_framebuffer_get_projection_stack (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->projection_stack; -} - -void -_cogl_framebuffer_add_dependency (CoglFramebuffer *framebuffer, - CoglFramebuffer *dependency) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - GList *l; - - for (l = priv->deps; l; l = l->next) - { - CoglFramebuffer *existing_dep = l->data; - if (existing_dep == dependency) - return; - } - - /* TODO: generalize the primed-array type structure we e.g. use for - * g_object_set_qdata_full or for pipeline children as a way to - * avoid quite a lot of mid-scene micro allocations here... */ - priv->deps = - g_list_prepend (priv->deps, g_object_ref (dependency)); -} - -void -_cogl_framebuffer_flush_journal (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - _cogl_journal_flush (priv->journal); -} - -void -_cogl_framebuffer_flush_dependency_journals (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - g_list_foreach (priv->deps, (GFunc) _cogl_framebuffer_flush_journal, NULL); - g_list_free_full (priv->deps, g_object_unref); - priv->deps = NULL; -} - -gboolean -cogl_framebuffer_is_allocated (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->allocated; -} - -static gboolean -cogl_framebuffer_init_driver (CoglFramebuffer *framebuffer, - GError **error) - -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - const CoglDriverVtable *driver_vtable = priv->context->driver_vtable; - CoglFramebufferDriver *driver; - - driver = driver_vtable->create_framebuffer_driver (priv->context, - framebuffer, - &priv->driver_config, - error); - if (!driver) - return FALSE; - - priv->driver = driver; - return TRUE; -} - -gboolean -cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, - GError **error) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglFramebufferClass *klass = COGL_FRAMEBUFFER_GET_CLASS (framebuffer); - - if (priv->allocated) - return TRUE; - - if (!klass->allocate (framebuffer, error)) - return FALSE; - - if (!cogl_framebuffer_init_driver (framebuffer, error)) - return FALSE; - - priv->allocated = TRUE; - - return TRUE; -} - -static unsigned long -_cogl_framebuffer_compare_viewport_state (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - CoglFramebufferPrivate *priv_a = cogl_framebuffer_get_instance_private (a); - CoglFramebufferPrivate *priv_b = cogl_framebuffer_get_instance_private (b); - - if (priv_a->viewport_x != priv_b->viewport_x || - priv_a->viewport_y != priv_b->viewport_y || - priv_a->viewport_width != priv_b->viewport_width || - priv_a->viewport_height != priv_b->viewport_height || - /* NB: we render upside down to offscreen framebuffers and that - * can affect how we setup the GL viewport... */ - G_OBJECT_TYPE (a) != G_OBJECT_TYPE (b)) - return COGL_FRAMEBUFFER_STATE_VIEWPORT; - else - return 0; -} - -static unsigned long -_cogl_framebuffer_compare_clip_state (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - CoglFramebufferPrivate *priv_a = cogl_framebuffer_get_instance_private (a); - CoglFramebufferPrivate *priv_b = cogl_framebuffer_get_instance_private (b); - - if (priv_a->clip_stack != priv_b->clip_stack) - return COGL_FRAMEBUFFER_STATE_CLIP; - else - return 0; -} - -static unsigned long -_cogl_framebuffer_compare_dither_state (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - CoglFramebufferPrivate *priv_a = cogl_framebuffer_get_instance_private (a); - CoglFramebufferPrivate *priv_b = cogl_framebuffer_get_instance_private (b); - - return priv_a->dither_enabled != priv_b->dither_enabled ? - COGL_FRAMEBUFFER_STATE_DITHER : 0; -} - -static unsigned long -_cogl_framebuffer_compare_modelview_state (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - /* We always want to flush the modelview state. All this does is set - the current modelview stack on the context to the framebuffer's - stack. */ - return COGL_FRAMEBUFFER_STATE_MODELVIEW; -} - -static unsigned long -_cogl_framebuffer_compare_projection_state (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - /* We always want to flush the projection state. All this does is - set the current projection stack on the context to the - framebuffer's stack. */ - return COGL_FRAMEBUFFER_STATE_PROJECTION; -} - -static unsigned long -_cogl_framebuffer_compare_front_face_winding_state (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - if (G_OBJECT_TYPE (a) != G_OBJECT_TYPE (b)) - return COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING; - else - return 0; -} - -static unsigned long -_cogl_framebuffer_compare_depth_write_state (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - CoglFramebufferPrivate *priv_a = cogl_framebuffer_get_instance_private (a); - CoglFramebufferPrivate *priv_b = cogl_framebuffer_get_instance_private (b); - - return priv_a->depth_writing_enabled != priv_b->depth_writing_enabled ? - COGL_FRAMEBUFFER_STATE_DEPTH_WRITE : 0; -} - -static unsigned long -_cogl_framebuffer_compare_stereo_mode (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - CoglFramebufferPrivate *priv_a = cogl_framebuffer_get_instance_private (a); - CoglFramebufferPrivate *priv_b = cogl_framebuffer_get_instance_private (b); - - return priv_a->stereo_mode != priv_b->stereo_mode ? - COGL_FRAMEBUFFER_STATE_STEREO_MODE : 0; -} - -unsigned long -_cogl_framebuffer_compare (CoglFramebuffer *a, - CoglFramebuffer *b, - unsigned long state) -{ - unsigned long differences = 0; - int bit; - - if (state & COGL_FRAMEBUFFER_STATE_BIND) - { - differences |= COGL_FRAMEBUFFER_STATE_BIND; - state &= ~COGL_FRAMEBUFFER_STATE_BIND; - } - - COGL_FLAGS_FOREACH_START (&state, 1, bit) - { - /* XXX: We considered having an array of callbacks for each state index - * that we'd call here but decided that this way the compiler is more - * likely going to be able to in-line the comparison functions and use - * the index to jump straight to the required code. */ - switch (bit) - { - case COGL_FRAMEBUFFER_STATE_INDEX_VIEWPORT: - differences |= - _cogl_framebuffer_compare_viewport_state (a, b); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_CLIP: - differences |= _cogl_framebuffer_compare_clip_state (a, b); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_DITHER: - differences |= _cogl_framebuffer_compare_dither_state (a, b); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_MODELVIEW: - differences |= - _cogl_framebuffer_compare_modelview_state (a, b); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION: - differences |= - _cogl_framebuffer_compare_projection_state (a, b); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING: - differences |= - _cogl_framebuffer_compare_front_face_winding_state (a, b); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE: - differences |= - _cogl_framebuffer_compare_depth_write_state (a, b); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE: - differences |= - _cogl_framebuffer_compare_stereo_mode (a, b); - break; - default: - g_warn_if_reached (); - } - } - COGL_FLAGS_FOREACH_END; - - return differences; -} - -void -cogl_context_flush_framebuffer_state (CoglContext *ctx, - CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer, - CoglFramebufferState state) -{ - ctx->driver_vtable->flush_framebuffer_state (ctx, - draw_buffer, - read_buffer, - state); -} - -static void -cogl_framebuffer_query_bits (CoglFramebuffer *framebuffer, - CoglFramebufferBits *bits) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - g_return_if_fail (priv->driver); - - cogl_framebuffer_driver_query_bits (priv->driver, bits); -} - -int -cogl_framebuffer_get_red_bits (CoglFramebuffer *framebuffer) -{ - CoglFramebufferBits bits; - - cogl_framebuffer_query_bits (framebuffer, &bits); - - return bits.red; -} - -int -cogl_framebuffer_get_green_bits (CoglFramebuffer *framebuffer) -{ - CoglFramebufferBits bits; - - cogl_framebuffer_query_bits (framebuffer, &bits); - - return bits.green; -} - -int -cogl_framebuffer_get_blue_bits (CoglFramebuffer *framebuffer) -{ - CoglFramebufferBits bits; - - cogl_framebuffer_query_bits (framebuffer, &bits); - - return bits.blue; -} - -int -cogl_framebuffer_get_alpha_bits (CoglFramebuffer *framebuffer) -{ - CoglFramebufferBits bits; - - cogl_framebuffer_query_bits (framebuffer, &bits); - - return bits.alpha; -} - -int -cogl_framebuffer_get_depth_bits (CoglFramebuffer *framebuffer) -{ - CoglFramebufferBits bits; - - cogl_framebuffer_query_bits (framebuffer, &bits); - - return bits.depth; -} - -gboolean -cogl_framebuffer_get_is_stereo (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->config.stereo_enabled; -} - -CoglStereoMode -cogl_framebuffer_get_stereo_mode (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->stereo_mode; -} - -void -cogl_framebuffer_set_stereo_mode (CoglFramebuffer *framebuffer, - CoglStereoMode stereo_mode) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - if (priv->stereo_mode == stereo_mode) - return; - - /* Stereo mode changes don't go through the journal */ - _cogl_framebuffer_flush_journal (framebuffer); - - priv->stereo_mode = stereo_mode; - - if (priv->context->current_draw_buffer == framebuffer) - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_STEREO_MODE; -} - -gboolean -cogl_framebuffer_get_depth_write_enabled (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->depth_writing_enabled; -} - -void -cogl_framebuffer_set_depth_write_enabled (CoglFramebuffer *framebuffer, - gboolean depth_write_enabled) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - if (priv->depth_writing_enabled == depth_write_enabled) - return; - - /* XXX: Currently depth write changes don't go through the journal */ - _cogl_framebuffer_flush_journal (framebuffer); - - priv->depth_writing_enabled = depth_write_enabled; - - if (priv->context->current_draw_buffer == framebuffer) - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_DEPTH_WRITE; -} - -gboolean -cogl_framebuffer_get_dither_enabled (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->dither_enabled; -} - -void -cogl_framebuffer_set_dither_enabled (CoglFramebuffer *framebuffer, - gboolean dither_enabled) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - if (priv->dither_enabled == dither_enabled) - return; - - priv->dither_enabled = dither_enabled; -} - -int -cogl_framebuffer_get_samples_per_pixel (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - if (priv->allocated) - return priv->samples_per_pixel; - else - return priv->config.samples_per_pixel; -} - -void -cogl_framebuffer_set_samples_per_pixel (CoglFramebuffer *framebuffer, - int samples_per_pixel) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - g_return_if_fail (!priv->allocated); - - priv->config.samples_per_pixel = samples_per_pixel; -} - -void -cogl_framebuffer_update_samples_per_pixel (CoglFramebuffer *framebuffer, - int samples_per_pixel) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->samples_per_pixel = samples_per_pixel; -} - -void -cogl_framebuffer_resolve_samples (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - cogl_framebuffer_resolve_samples_region (framebuffer, - 0, 0, - priv->width, - priv->height); - - /* TODO: Make this happen implicitly when the resolve texture next gets used - * as a source, either via cogl_texture_get_data(), via cogl_read_pixels() or - * if used as a source for rendering. We would also implicitly resolve if - * necessary before freeing a CoglFramebuffer. - * - * This API should still be kept but it is optional, only necessary - * if the user wants to explicitly control when the resolve happens e.g. - * to ensure it's done in advance of it being used as a source. - * - * Every texture should have a CoglFramebuffer *needs_resolve member - * internally. When the texture gets validated before being used as a source - * we should first check the needs_resolve pointer and if set we'll - * automatically call cogl_framebuffer_resolve_samples (). - * - * Calling cogl_framebuffer_resolve_samples() or - * cogl_framebuffer_resolve_samples_region() should reset the textures - * needs_resolve pointer to NULL. - * - * Rendering anything to a framebuffer will cause the corresponding - * texture's ->needs_resolve pointer to be set. - * - * XXX: Note: we only need to address this TODO item when adding support for - * EXT_framebuffer_multisample because currently we only support hardware - * that resolves implicitly anyway. - */ -} - -void -cogl_framebuffer_resolve_samples_region (CoglFramebuffer *framebuffer, - int x, - int y, - int width, - int height) -{ - /* NOP for now since we don't support EXT_framebuffer_multisample yet which - * requires an explicit resolve. */ -} - -CoglContext * -cogl_framebuffer_get_context (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - g_return_val_if_fail (framebuffer != NULL, NULL); - - return priv->context; -} - -CoglJournal * -cogl_framebuffer_get_journal (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->journal; -} - -static gboolean -_cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - gboolean found_intersection; - CoglPixelFormat format; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_FAST_READ_PIXEL))) - return FALSE; - - if (source != COGL_READ_PIXELS_COLOR_BUFFER) - return FALSE; - - format = cogl_bitmap_get_format (bitmap); - - if (format != COGL_PIXEL_FORMAT_RGBA_8888_PRE && - format != COGL_PIXEL_FORMAT_RGBA_8888) - return FALSE; - - if (!_cogl_journal_try_read_pixel (priv->journal, - x, y, bitmap, - &found_intersection)) - return FALSE; - - /* If we can't determine the color from the primitives in the - * journal then see if we can use the last recorded clear color - */ - - /* If _cogl_journal_try_read_pixel() failed even though there was an - * intersection of the given point with a primitive in the journal - * then we can't fallback to the framebuffer's last clear color... - * */ - if (found_intersection) - return TRUE; - - /* If the framebuffer has been rendered too since it was last - * cleared then we can't return the last known clear color. */ - if (priv->clear_clip_dirty) - return FALSE; - - if (x >= priv->clear_clip_x0 && - x < priv->clear_clip_x1 && - y >= priv->clear_clip_y0 && - y < priv->clear_clip_y1) - { - uint8_t *pixel; - GError *ignore_error = NULL; - - /* we currently only care about cases where the premultiplied or - * unpremultipled colors are equivalent... */ - if (priv->clear_color_alpha != 1.0) - return FALSE; - - pixel = _cogl_bitmap_map (bitmap, - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD, - &ignore_error); - if (pixel == NULL) - { - g_error_free (ignore_error); - return FALSE; - } - - pixel[0] = priv->clear_color_red * 255.0; - pixel[1] = priv->clear_color_green * 255.0; - pixel[2] = priv->clear_color_blue * 255.0; - pixel[3] = priv->clear_color_alpha * 255.0; - - _cogl_bitmap_unmap (bitmap); - - return TRUE; - } - - return FALSE; -} - -gboolean -_cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap, - GError **error) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - int width; - int height; - - g_return_val_if_fail (source & COGL_READ_PIXELS_COLOR_BUFFER, FALSE); - g_return_val_if_fail (cogl_is_framebuffer (framebuffer), FALSE); - - if (!cogl_framebuffer_allocate (framebuffer, error)) - return FALSE; - - width = cogl_bitmap_get_width (bitmap); - height = cogl_bitmap_get_height (bitmap); - - if (width == 1 && height == 1 && !priv->clear_clip_dirty) - { - /* If everything drawn so far for this frame is still in the - * Journal then if all of the rectangles only have a flat - * opaque color we have a fast-path for reading a single pixel - * that avoids the relatively high cost of flushing primitives - * to be drawn on the GPU (considering how simple the geometry - * is in this case) and then blocking on the long GPU pipelines - * for the result. - */ - if (_cogl_framebuffer_try_fast_read_pixel (framebuffer, - x, y, source, bitmap)) - return TRUE; - } - - /* make sure any batched primitives get emitted to the driver - * before issuing our read pixels... - */ - _cogl_framebuffer_flush_journal (framebuffer); - - return cogl_framebuffer_driver_read_pixels_into_bitmap (priv->driver, - x, y, - source, - bitmap, - error); -} - -gboolean -cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap) -{ - GError *ignore_error = NULL; - gboolean status = - _cogl_framebuffer_read_pixels_into_bitmap (framebuffer, - x, y, source, bitmap, - &ignore_error); - g_clear_error (&ignore_error); - return status; -} - -gboolean -cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer, - int x, - int y, - int width, - int height, - CoglPixelFormat format, - uint8_t *pixels) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - int bpp; - CoglBitmap *bitmap; - gboolean ret; - - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); - - bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); - bitmap = cogl_bitmap_new_for_data (priv->context, - width, height, - format, - bpp * width, /* rowstride */ - pixels); - - /* Note: we don't try and catch errors here since we created the - * bitmap storage up-front and can assume we won't hit an - * out-of-memory error which should be the only exception - * this api throws. - */ - ret = _cogl_framebuffer_read_pixels_into_bitmap (framebuffer, - x, y, - COGL_READ_PIXELS_COLOR_BUFFER, - bitmap, - NULL); - g_object_unref (bitmap); - - return ret; -} - -gboolean -cogl_framebuffer_is_y_flipped (CoglFramebuffer *framebuffer) -{ - return COGL_FRAMEBUFFER_GET_CLASS (framebuffer)->is_y_flipped (framebuffer); -} - -gboolean -cogl_blit_framebuffer (CoglFramebuffer *framebuffer, - CoglFramebuffer *dst, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - GError **error) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglFramebufferPrivate *dst_priv = - cogl_framebuffer_get_instance_private (dst); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - int src_x1, src_y1, src_x2, src_y2; - int dst_x1, dst_y1, dst_x2, dst_y2; - - if (!cogl_has_feature (ctx, COGL_FEATURE_ID_BLIT_FRAMEBUFFER)) - { - g_set_error_literal (error, COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Cogl BLIT_FRAMEBUFFER is not supported by the system."); - return FALSE; - } - - /* The buffers must use the same premult convention */ - if (((priv->internal_format & COGL_PREMULT_BIT) != - (dst_priv->internal_format & COGL_PREMULT_BIT)) && - dst_priv->internal_format & COGL_A_BIT) - { - g_set_error_literal (error, COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "cogl_blit_framebuffer premult mismatch."); - return FALSE; - } - - /* Make sure any batched primitives get submitted to the driver - * before blitting - */ - _cogl_framebuffer_flush_journal (framebuffer); - - /* Make sure the current framebuffers are bound. We explicitly avoid - flushing the clip state so we can bind our own empty state */ - cogl_context_flush_framebuffer_state (ctx, - dst, - framebuffer, - (COGL_FRAMEBUFFER_STATE_ALL & - ~COGL_FRAMEBUFFER_STATE_CLIP)); - - /* Flush any empty clip stack because glBlitFramebuffer is affected - by the scissor and we want to hide this feature for the Cogl API - because it's not obvious to an app how the clip state will affect - the scissor */ - _cogl_clip_stack_flush (NULL, dst); - - /* XXX: Because we are manually flushing clip state here we need to - * make sure that the clip state gets updated the next time we flush - * framebuffer state by marking the current framebuffer's clip state - * as changed */ - ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP; - - /* Offscreens we do the normal way, onscreens need an y-flip. Even if - * we consider offscreens to be rendered upside-down, the offscreen - * orientation is in this function's API. */ - if (cogl_framebuffer_is_y_flipped (framebuffer)) - { - src_x1 = src_x; - src_y1 = src_y; - src_x2 = src_x + width; - src_y2 = src_y + height; - } - else - { - src_x1 = src_x; - src_y1 = cogl_framebuffer_get_height (framebuffer) - src_y; - src_x2 = src_x + width; - src_y2 = src_y1 - height; - } - - if (cogl_framebuffer_is_y_flipped (dst)) - { - dst_x1 = dst_x; - dst_y1 = dst_y; - dst_x2 = dst_x + width; - dst_y2 = dst_y + height; - } - else - { - dst_x1 = dst_x; - dst_y1 = cogl_framebuffer_get_height (dst) - dst_y; - dst_x2 = dst_x + width; - dst_y2 = dst_y1 - height; - } - - ctx->glBlitFramebuffer (src_x1, src_y1, src_x2, src_y2, - dst_x1, dst_y1, dst_x2, dst_y2, - GL_COLOR_BUFFER_BIT, - GL_NEAREST); - - return TRUE; -} - -void -cogl_framebuffer_discard_buffers (CoglFramebuffer *framebuffer, - unsigned long buffers) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - cogl_framebuffer_driver_discard_buffers (priv->driver, buffers); -} - -void -cogl_framebuffer_finish (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - COGL_TRACE_BEGIN_SCOPED (Finish, "Cogl::Framebuffer::finish()"); - - _cogl_framebuffer_flush_journal (framebuffer); - - cogl_framebuffer_driver_finish (priv->driver); -} - -void -cogl_framebuffer_flush (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - COGL_TRACE_BEGIN_SCOPED (Flush, "Cogl::Framebuffer::flush()"); - - _cogl_framebuffer_flush_journal (framebuffer); - - cogl_framebuffer_driver_flush (priv->driver); -} - -void -cogl_framebuffer_push_matrix (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_push (modelview_stack); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_pop_matrix (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_pop (modelview_stack); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_identity_matrix (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_load_identity (modelview_stack); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_scale (CoglFramebuffer *framebuffer, - float x, - float y, - float z) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_scale (modelview_stack, x, y, z); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_translate (CoglFramebuffer *framebuffer, - float x, - float y, - float z) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_translate (modelview_stack, x, y, z); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_rotate (CoglFramebuffer *framebuffer, - float angle, - float x, - float y, - float z) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_rotate (modelview_stack, angle, x, y, z); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_rotate_euler (CoglFramebuffer *framebuffer, - const graphene_euler_t *euler) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_rotate_euler (modelview_stack, euler); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_transform (CoglFramebuffer *framebuffer, - const graphene_matrix_t *matrix) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_multiply (modelview_stack, matrix); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_perspective (CoglFramebuffer *framebuffer, - float fov_y, - float aspect, - float z_near, - float z_far) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - float ymax = z_near * tanf (fov_y * G_PI / 360.0); - - cogl_framebuffer_frustum (framebuffer, - -ymax * aspect, /* left */ - ymax * aspect, /* right */ - -ymax, /* bottom */ - ymax, /* top */ - z_near, - z_far); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_PROJECTION; - } -} - -void -cogl_framebuffer_frustum (CoglFramebuffer *framebuffer, - float left, - float right, - float bottom, - float top, - float z_near, - float z_far) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - - /* XXX: The projection matrix isn't currently tracked in the journal - * so we need to flush all journaled primitives first... */ - _cogl_framebuffer_flush_journal (framebuffer); - - cogl_matrix_stack_load_identity (projection_stack); - - cogl_matrix_stack_frustum (projection_stack, - left, - right, - bottom, - top, - z_near, - z_far); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_PROJECTION; - } -} - -void -cogl_framebuffer_orthographic (CoglFramebuffer *framebuffer, - float x_1, - float y_1, - float x_2, - float y_2, - float near, - float far) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - graphene_matrix_t ortho; - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - - /* XXX: The projection matrix isn't currently tracked in the journal - * so we need to flush all journaled primitives first... */ - _cogl_framebuffer_flush_journal (framebuffer); - - graphene_matrix_init_ortho (&ortho, x_1, x_2, y_2, y_1, near, far); - cogl_matrix_stack_set (projection_stack, &ortho); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_PROJECTION; - } -} - -void -cogl_framebuffer_get_modelview_matrix (CoglFramebuffer *framebuffer, - graphene_matrix_t *matrix) -{ - CoglMatrixEntry *modelview_entry = - _cogl_framebuffer_get_modelview_entry (framebuffer); - - cogl_matrix_entry_get (modelview_entry, matrix); -} - -void -cogl_framebuffer_set_modelview_matrix (CoglFramebuffer *framebuffer, - const graphene_matrix_t *matrix) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_set (modelview_stack, matrix); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_get_projection_matrix (CoglFramebuffer *framebuffer, - graphene_matrix_t *matrix) -{ - CoglMatrixEntry *projection_entry = - _cogl_framebuffer_get_projection_entry (framebuffer); - - cogl_matrix_entry_get (projection_entry, matrix); -} - -void -cogl_framebuffer_set_projection_matrix (CoglFramebuffer *framebuffer, - const graphene_matrix_t *matrix) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - - /* XXX: The projection matrix isn't currently tracked in the journal - * so we need to flush all journaled primitives first... */ - _cogl_framebuffer_flush_journal (framebuffer); - - cogl_matrix_stack_set (projection_stack, matrix); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_PROJECTION; - } -} - -void -cogl_framebuffer_push_rectangle_clip (CoglFramebuffer *framebuffer, - float x_1, - float y_1, - float x_2, - float y_2) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixEntry *modelview_entry = - _cogl_framebuffer_get_modelview_entry (framebuffer); - CoglMatrixEntry *projection_entry = - _cogl_framebuffer_get_projection_entry (framebuffer); - /* XXX: It would be nicer if we stored the private viewport as a - * vec4 so we could avoid this redundant copy. */ - float viewport[] = { - priv->viewport_x, - priv->viewport_y, - priv->viewport_width, - priv->viewport_height - }; - - priv->clip_stack = - _cogl_clip_stack_push_rectangle (priv->clip_stack, - x_1, y_1, x_2, y_2, - modelview_entry, - projection_entry, - viewport); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_CLIP; - } -} - -void -cogl_framebuffer_push_primitive_clip (CoglFramebuffer *framebuffer, - CoglPrimitive *primitive, - float bounds_x1, - float bounds_y1, - float bounds_x2, - float bounds_y2) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixEntry *modelview_entry = - _cogl_framebuffer_get_modelview_entry (framebuffer); - CoglMatrixEntry *projection_entry = - _cogl_framebuffer_get_projection_entry (framebuffer); - /* XXX: It would be nicer if we stored the private viewport as a - * vec4 so we could avoid this redundant copy. */ - float viewport[] = { - priv->viewport_x, - priv->viewport_y, - priv->viewport_width, - priv->viewport_height - }; - - priv->clip_stack = - _cogl_clip_stack_push_primitive (priv->clip_stack, - primitive, - bounds_x1, bounds_y1, - bounds_x2, bounds_y2, - modelview_entry, - projection_entry, - viewport); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_CLIP; - } -} - -void -cogl_framebuffer_push_region_clip (CoglFramebuffer *framebuffer, - MtkRegion *region) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->clip_stack = - cogl_clip_stack_push_region (priv->clip_stack, - region); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_CLIP; - } -} - -void -cogl_framebuffer_pop_clip (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->clip_stack = _cogl_clip_stack_pop (priv->clip_stack); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_CLIP; - } -} - -#ifdef COGL_ENABLE_DEBUG -static int -get_index (void *indices, - CoglIndicesType type, - int _index) -{ - if (!indices) - return _index; - - switch (type) - { - case COGL_INDICES_TYPE_UNSIGNED_BYTE: - return ((uint8_t *)indices)[_index]; - case COGL_INDICES_TYPE_UNSIGNED_SHORT: - return ((uint16_t *)indices)[_index]; - case COGL_INDICES_TYPE_UNSIGNED_INT: - return ((uint32_t *)indices)[_index]; - } - - g_return_val_if_reached (0); -} - -static void -add_line (uint32_t *line_indices, - int base, - void *user_indices, - CoglIndicesType user_indices_type, - int index0, - int index1, - int *pos) -{ - index0 = get_index (user_indices, user_indices_type, index0); - index1 = get_index (user_indices, user_indices_type, index1); - - line_indices[(*pos)++] = base + index0; - line_indices[(*pos)++] = base + index1; -} - -static int -get_line_count (CoglVerticesMode mode, int n_vertices) -{ - if (mode == COGL_VERTICES_MODE_TRIANGLES && - (n_vertices % 3) == 0) - { - return n_vertices; - } - else if (mode == COGL_VERTICES_MODE_TRIANGLE_FAN && - n_vertices >= 3) - { - return 2 * n_vertices - 3; - } - else if (mode == COGL_VERTICES_MODE_TRIANGLE_STRIP && - n_vertices >= 3) - { - return 2 * n_vertices - 3; - } - /* In the journal we are a bit sneaky and actually use GL_QUADS - * which isn't actually a valid CoglVerticesMode! */ -#ifdef HAVE_GL - else if (mode == GL_QUADS && (n_vertices % 4) == 0) - { - return n_vertices; - } -#endif - - g_return_val_if_reached (0); -} - -static CoglIndices * -get_wire_line_indices (CoglContext *ctx, - CoglVerticesMode mode, - int first_vertex, - int n_vertices_in, - CoglIndices *user_indices, - int *n_indices) -{ - int n_lines; - uint32_t *line_indices; - CoglIndexBuffer *index_buffer; - void *indices; - CoglIndicesType indices_type; - int base = first_vertex; - int pos; - int i; - CoglIndices *ret; - - if (user_indices) - { - index_buffer = cogl_indices_get_buffer (user_indices); - indices = _cogl_buffer_map (COGL_BUFFER (index_buffer), - COGL_BUFFER_ACCESS_READ, 0, - NULL); - indices_type = cogl_indices_get_indices_type (user_indices); - } - else - { - index_buffer = NULL; - indices = NULL; - indices_type = COGL_INDICES_TYPE_UNSIGNED_BYTE; - } - - n_lines = get_line_count (mode, n_vertices_in); - - /* Note: we are using COGL_INDICES_TYPE_UNSIGNED_INT so 4 bytes per index. */ - line_indices = g_malloc (4 * n_lines * 2); - - pos = 0; - - if (mode == COGL_VERTICES_MODE_TRIANGLES && - (n_vertices_in % 3) == 0) - { - for (i = 0; i < n_vertices_in; i += 3) - { - add_line (line_indices, base, indices, indices_type, i, i+1, &pos); - add_line (line_indices, base, indices, indices_type, i+1, i+2, &pos); - add_line (line_indices, base, indices, indices_type, i+2, i, &pos); - } - } - else if (mode == COGL_VERTICES_MODE_TRIANGLE_FAN && - n_vertices_in >= 3) - { - add_line (line_indices, base, indices, indices_type, 0, 1, &pos); - add_line (line_indices, base, indices, indices_type, 1, 2, &pos); - add_line (line_indices, base, indices, indices_type, 0, 2, &pos); - - for (i = 3; i < n_vertices_in; i++) - { - add_line (line_indices, base, indices, indices_type, i - 1, i, &pos); - add_line (line_indices, base, indices, indices_type, 0, i, &pos); - } - } - else if (mode == COGL_VERTICES_MODE_TRIANGLE_STRIP && - n_vertices_in >= 3) - { - add_line (line_indices, base, indices, indices_type, 0, 1, &pos); - add_line (line_indices, base, indices, indices_type, 1, 2, &pos); - add_line (line_indices, base, indices, indices_type, 0, 2, &pos); - - for (i = 3; i < n_vertices_in; i++) - { - add_line (line_indices, base, indices, indices_type, i - 1, i, &pos); - add_line (line_indices, base, indices, indices_type, i - 2, i, &pos); - } - } - /* In the journal we are a bit sneaky and actually use GL_QUADS - * which isn't actually a valid CoglVerticesMode! */ -#ifdef HAVE_GL - else if (mode == GL_QUADS && (n_vertices_in % 4) == 0) - { - for (i = 0; i < n_vertices_in; i += 4) - { - add_line (line_indices, - base, indices, indices_type, i, i + 1, &pos); - add_line (line_indices, - base, indices, indices_type, i + 1, i + 2, &pos); - add_line (line_indices, - base, indices, indices_type, i + 2, i + 3, &pos); - add_line (line_indices, - base, indices, indices_type, i + 3, i, &pos); - } - } -#endif - - if (user_indices) - cogl_buffer_unmap (COGL_BUFFER (index_buffer)); - - *n_indices = n_lines * 2; - - ret = cogl_indices_new (ctx, - COGL_INDICES_TYPE_UNSIGNED_INT, - line_indices, - *n_indices); - - g_free (line_indices); - - return ret; -} - -static void -pipeline_destroyed_cb (CoglPipeline *weak_pipeline, void *user_data) -{ - CoglPipeline *original_pipeline = user_data; - - /* XXX: I think we probably need to provide a custom unref function for - * CoglPipeline because it's possible that we will reach this callback - * because original_pipeline is being freed which means g_object_unref - * will have already freed any associated user data. - * - * Setting more user data here will *probably* succeed but that may allocate - * a new user-data array which could be leaked. - * - * Potentially we could have a _cogl_object_free_user_data function so - * that a custom unref function could be written that can destroy weak - * pipeline children before removing user data. - */ - g_object_set_qdata_full (G_OBJECT (original_pipeline), - wire_pipeline_key, NULL, NULL); - - g_object_unref (weak_pipeline); -} - -static void -draw_wireframe (CoglContext *ctx, - CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes, - CoglIndices *indices, - CoglDrawFlags flags) -{ - CoglIndices *wire_indices; - CoglPipeline *wire_pipeline; - int n_indices; - wire_pipeline_key = g_quark_from_static_string ("framebuffer-wire-pipeline-key"); - wire_indices = get_wire_line_indices (ctx, - mode, - first_vertex, - n_vertices, - indices, - &n_indices); - - wire_pipeline = g_object_get_qdata (G_OBJECT (pipeline), - wire_pipeline_key); - - if (!wire_pipeline) - { - static CoglSnippet *snippet = NULL; - - wire_pipeline = - _cogl_pipeline_weak_copy (pipeline, pipeline_destroyed_cb, NULL); - - g_object_set_qdata_full (G_OBJECT (pipeline), - wire_pipeline_key, wire_pipeline, - NULL); - - /* If we have glsl then the pipeline may have an associated - * vertex program and since we'd like to see the results of the - * vertex program in the wireframe we just add a final clobber - * of the wire color leaving the rest of the state untouched. */ - - /* The snippet is cached so that it will reuse the program - * from the pipeline cache if possible */ - if (snippet == NULL) - { - snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, - NULL, - NULL); - cogl_snippet_set_replace (snippet, - "cogl_color_out = " - "vec4 (0.0, 1.0, 0.0, 1.0);\n"); - } - - cogl_pipeline_add_snippet (wire_pipeline, snippet); - } - - /* temporarily disable the wireframe to avoid recursion! */ - flags |= COGL_DRAW_SKIP_DEBUG_WIREFRAME; - _cogl_framebuffer_draw_indexed_attributes ( - framebuffer, - wire_pipeline, - COGL_VERTICES_MODE_LINES, - 0, - n_indices, - wire_indices, - attributes, - n_attributes, - flags); - COGL_DEBUG_SET_FLAG (COGL_DEBUG_WIREFRAME); - - g_object_unref (wire_indices); -} -#endif - -/* This can be called directly by the CoglJournal to draw attributes - * skipping the implicit journal flush, the framebuffer flush and - * pipeline validation. */ -void -_cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - -#ifdef COGL_ENABLE_DEBUG - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME) && - (flags & COGL_DRAW_SKIP_DEBUG_WIREFRAME) == 0) && - mode != COGL_VERTICES_MODE_LINES && - mode != COGL_VERTICES_MODE_LINE_LOOP && - mode != COGL_VERTICES_MODE_LINE_STRIP) - draw_wireframe (priv->context, - framebuffer, pipeline, - mode, first_vertex, n_vertices, - attributes, n_attributes, NULL, - flags); - else -#endif - { - cogl_framebuffer_driver_draw_attributes (priv->driver, - pipeline, - mode, - first_vertex, - n_vertices, - attributes, - n_attributes, - flags); - } -} - -void -_cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - -#ifdef COGL_ENABLE_DEBUG - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME) && - (flags & COGL_DRAW_SKIP_DEBUG_WIREFRAME) == 0) && - mode != COGL_VERTICES_MODE_LINES && - mode != COGL_VERTICES_MODE_LINE_LOOP && - mode != COGL_VERTICES_MODE_LINE_STRIP) - draw_wireframe (priv->context, - framebuffer, pipeline, - mode, first_vertex, n_vertices, - attributes, n_attributes, indices, - flags); - else -#endif - { - cogl_framebuffer_driver_draw_indexed_attributes (priv->driver, - pipeline, - mode, - first_vertex, - n_vertices, - indices, - attributes, - n_attributes, - flags); - } -} - -void -cogl_framebuffer_draw_rectangle (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2) -{ - const float position[4] = {x_1, y_1, x_2, y_2}; - CoglMultiTexturedRect rect; - - /* XXX: All the _*_rectangle* APIs normalize their input into an array of - * _CoglMultiTexturedRect rectangles and pass these on to our work horse; - * _cogl_framebuffer_draw_multitextured_rectangles. - */ - - rect.position = position; - rect.tex_coords = NULL; - rect.tex_coords_len = 0; - - _cogl_framebuffer_draw_multitextured_rectangles (framebuffer, - pipeline, - &rect, - 1); -} - -void -cogl_framebuffer_draw_textured_rectangle (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2, - float s_1, - float t_1, - float s_2, - float t_2) -{ - const float position[4] = {x_1, y_1, x_2, y_2}; - const float tex_coords[4] = {s_1, t_1, s_2, t_2}; - CoglMultiTexturedRect rect; - - /* XXX: All the _*_rectangle* APIs normalize their input into an array of - * CoglMultiTexturedRect rectangles and pass these on to our work horse; - * _cogl_framebuffer_draw_multitextured_rectangles. - */ - - rect.position = position; - rect.tex_coords = tex_coords; - rect.tex_coords_len = 4; - - _cogl_framebuffer_draw_multitextured_rectangles (framebuffer, - pipeline, - &rect, - 1); -} - -void -cogl_framebuffer_draw_multitextured_rectangle (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2, - const float *tex_coords, - int tex_coords_len) -{ - const float position[4] = {x_1, y_1, x_2, y_2}; - CoglMultiTexturedRect rect; - - /* XXX: All the _*_rectangle* APIs normalize their input into an array of - * CoglMultiTexturedRect rectangles and pass these on to our work horse; - * _cogl_framebuffer_draw_multitextured_rectangles. - */ - - rect.position = position; - rect.tex_coords = tex_coords; - rect.tex_coords_len = tex_coords_len; - - _cogl_framebuffer_draw_multitextured_rectangles (framebuffer, - pipeline, - &rect, - 1); -} - -void -cogl_framebuffer_draw_rectangles (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - const float *coordinates, - unsigned int n_rectangles) -{ - CoglMultiTexturedRect *rects; - int i; - - /* XXX: All the _*_rectangle* APIs normalize their input into an array of - * CoglMultiTexturedRect rectangles and pass these on to our work horse; - * _cogl_framebuffer_draw_multitextured_rectangles. - */ - - rects = g_alloca (n_rectangles * sizeof (CoglMultiTexturedRect)); - - for (i = 0; i < n_rectangles; i++) - { - rects[i].position = &coordinates[i * 4]; - rects[i].tex_coords = NULL; - rects[i].tex_coords_len = 0; - } - - _cogl_framebuffer_draw_multitextured_rectangles (framebuffer, - pipeline, - rects, - n_rectangles); -} - -void -cogl_framebuffer_draw_textured_rectangles (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - const float *coordinates, - unsigned int n_rectangles) -{ - CoglMultiTexturedRect *rects; - int i; - - /* XXX: All the _*_rectangle* APIs normalize their input into an array of - * _CoglMultiTexturedRect rectangles and pass these on to our work horse; - * _cogl_framebuffer_draw_multitextured_rectangles. - */ - - rects = g_alloca (n_rectangles * sizeof (CoglMultiTexturedRect)); - - for (i = 0; i < n_rectangles; i++) - { - rects[i].position = &coordinates[i * 8]; - rects[i].tex_coords = &coordinates[i * 8 + 4]; - rects[i].tex_coords_len = 4; - } - - _cogl_framebuffer_draw_multitextured_rectangles (framebuffer, - pipeline, - rects, - n_rectangles); -} - -CoglFramebufferDriver * -cogl_framebuffer_get_driver (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->driver; -} - -CoglTimestampQuery * -cogl_framebuffer_create_timestamp_query (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - const CoglDriverVtable *driver_vtable = priv->context->driver_vtable; - - g_return_val_if_fail (cogl_has_feature (priv->context, - COGL_FEATURE_ID_TIMESTAMP_QUERY), - NULL); - - /* The timestamp query completes upon completion of all previously submitted - * GL commands. So make sure those commands are indeed submitted by flushing - * the journal. - */ - _cogl_framebuffer_flush_journal (framebuffer); - - cogl_context_flush_framebuffer_state (priv->context, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - - return driver_vtable->create_timestamp_query (priv->context); -} diff --git a/mutter/cogl/cogl/cogl-framebuffer.h b/mutter/cogl/cogl/cogl-framebuffer.h deleted file mode 100644 index 9f25e4b..0000000 --- a/mutter/cogl/cogl/cogl-framebuffer.h +++ /dev/null @@ -1,1384 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2011 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-pipeline.h" -#include "cogl/cogl-indices.h" -#include "cogl/cogl-bitmap.h" -#include "cogl/cogl-texture.h" -#include "mtk/mtk.h" - -#include - -#include - -G_BEGIN_DECLS - -/** - * CoglFrameBuffer: - * - * A common interface for manipulating framebuffers - * - * Framebuffers are a collection of buffers that can be rendered too. - * A framebuffer may be comprised of one or more color buffers, an - * optional depth buffer and an optional stencil buffer. Other - * configuration parameters are associated with framebuffers too such - * as whether the framebuffer supports multi-sampling (an anti-aliasing - * technique) or dithering. - * - * There are two kinds of framebuffer in Cogl, #CoglOnscreen - * framebuffers and #CoglOffscreen framebuffers. As the names imply - * offscreen framebuffers are for rendering something offscreen - * (perhaps to a texture which is bound as one of the color buffers). - * The exact semantics of onscreen framebuffers depends on the window - * system backend that you are using, but typically you can expect - * rendering to a #CoglOnscreen framebuffer will be immediately - * visible to the user. - * - * If you want to create a new framebuffer then you should start by - * looking at the #CoglOnscreen and #CoglOffscreen constructor - * functions, such as cogl_offscreen_new_with_texture() or - * cogl_onscreen_new(). The #CoglFramebuffer interface deals with - * all aspects that are common between those two types of framebuffer. - * - * Setup of a new CoglFramebuffer happens in two stages. There is a - * configuration stage where you specify all the options and ancillary - * buffers you want associated with your framebuffer and then when you - * are happy with the configuration you can "allocate" the framebuffer - * using cogl_framebuffer_allocate(). Technically explicitly calling - * cogl_framebuffer_allocate() is optional for convenience and the - * framebuffer will automatically be allocated when you first try to - * draw to it, but if you do the allocation manually then you can - * also catch any possible errors that may arise from your - * configuration. - */ - -typedef struct _CoglFramebufferDriverConfig CoglFramebufferDriverConfig; - -#define COGL_TYPE_FRAMEBUFFER (cogl_framebuffer_get_type ()) -COGL_EXPORT -G_DECLARE_DERIVABLE_TYPE (CoglFramebuffer, cogl_framebuffer, - COGL, FRAMEBUFFER, GObject) - -struct _CoglFramebufferClass -{ - /*< private >*/ - GObjectClass parent_class; - - gboolean (* allocate) (CoglFramebuffer *framebuffer, - GError **error); - gboolean (* is_y_flipped) (CoglFramebuffer *framebuffer); -}; - -/** - * cogl_framebuffer_allocate: - * @framebuffer: A #CoglFramebuffer - * @error: A pointer to a #GError for returning exceptions. - * - * Explicitly allocates a configured #CoglFramebuffer allowing developers to - * check and handle any errors that might arise from an unsupported - * configuration so that fallback configurations may be tried. - * - * Many applications don't support any fallback options at least when - * they are initially developed and in that case the don't need to use this API - * since Cogl will automatically allocate a framebuffer when it first gets - * used. The disadvantage of relying on automatic allocation is that the - * program will abort with an error message if there is an error during - * automatic allocation. - * - * Return value: %TRUE if there were no error allocating the framebuffer, else %FALSE. - */ -COGL_EXPORT gboolean -cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, - GError **error); - -/** - * cogl_framebuffer_get_width: - * @framebuffer: A #CoglFramebuffer - * - * Queries the current width of the given @framebuffer. - * - * Return value: The width of @framebuffer. - */ -COGL_EXPORT int -cogl_framebuffer_get_width (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_height: - * @framebuffer: A #CoglFramebuffer - * - * Queries the current height of the given @framebuffer. - * - * Return value: The height of @framebuffer. - */ -COGL_EXPORT int -cogl_framebuffer_get_height (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_set_viewport: - * @framebuffer: A #CoglFramebuffer - * @x: The top-left x coordinate of the viewport origin (only integers - * supported currently) - * @y: The top-left y coordinate of the viewport origin (only integers - * supported currently) - * @width: The width of the viewport (only integers supported currently) - * @height: The height of the viewport (only integers supported currently) - * - * Defines a scale and offset for everything rendered relative to the - * top-left of the destination framebuffer. - * - * By default the viewport has an origin of (0,0) and width and height - * that match the framebuffer's size. Assuming a default projection and - * modelview matrix then you could translate the contents of a window - * down and right by leaving the viewport size unchanged by moving the - * offset to (10,10). The viewport coordinates are measured in pixels. - * If you left the x and y origin as (0,0) you could scale the windows - * contents down by specify and width and height that's half the real - * size of the framebuffer. - * - * Although the function takes floating point arguments, existing - * drivers only allow the use of integer values. In the future floating - * point values will be exposed via a checkable feature. - * - */ -COGL_EXPORT void -cogl_framebuffer_set_viewport (CoglFramebuffer *framebuffer, - float x, - float y, - float width, - float height); - -/** - * cogl_framebuffer_get_viewport_x: - * @framebuffer: A #CoglFramebuffer - * - * Queries the x coordinate of the viewport origin as set using cogl_framebuffer_set_viewport() - * or the default value which is 0. - * - * Return value: The x coordinate of the viewport origin. - */ -COGL_EXPORT float -cogl_framebuffer_get_viewport_x (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_viewport_y: - * @framebuffer: A #CoglFramebuffer - * - * Queries the y coordinate of the viewport origin as set using cogl_framebuffer_set_viewport() - * or the default value which is 0. - * - * Return value: The y coordinate of the viewport origin. - */ -COGL_EXPORT float -cogl_framebuffer_get_viewport_y (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_viewport_width: - * @framebuffer: A #CoglFramebuffer - * - * Queries the width of the viewport as set using cogl_framebuffer_set_viewport() - * or the default value which is the width of the framebuffer. - * - * Return value: The width of the viewport. - */ -COGL_EXPORT float -cogl_framebuffer_get_viewport_width (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_viewport_height: - * @framebuffer: A #CoglFramebuffer - * - * Queries the height of the viewport as set using cogl_framebuffer_set_viewport() - * or the default value which is the height of the framebuffer. - * - * Return value: The height of the viewport. - */ -COGL_EXPORT float -cogl_framebuffer_get_viewport_height (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_viewport4fv: - * @framebuffer: A #CoglFramebuffer - * @viewport: (out caller-allocates) (array fixed-size=4): A pointer to an - * array of 4 floats to receive the (x, y, width, height) - * components of the current viewport. - * - * Queries the x, y, width and height components of the current viewport as set - * using cogl_framebuffer_set_viewport() or the default values which are 0, 0, - * framebuffer_width and framebuffer_height. The values are written into the - * given @viewport array. - * - */ -COGL_EXPORT void -cogl_framebuffer_get_viewport4fv (CoglFramebuffer *framebuffer, - float *viewport); - -/** - * cogl_framebuffer_push_matrix: - * @framebuffer: A #CoglFramebuffer pointer - * - * Copies the current model-view matrix onto the matrix stack. The matrix - * can later be restored with cogl_framebuffer_pop_matrix(). - */ -COGL_EXPORT void -cogl_framebuffer_push_matrix (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_pop_matrix: - * @framebuffer: A #CoglFramebuffer pointer - * - * Restores the model-view matrix on the top of the matrix stack. - */ -COGL_EXPORT void -cogl_framebuffer_pop_matrix (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_identity_matrix: - * @framebuffer: A #CoglFramebuffer pointer - * - * Resets the current model-view matrix to the identity matrix. - */ -COGL_EXPORT void -cogl_framebuffer_identity_matrix (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_scale: - * @framebuffer: A #CoglFramebuffer pointer - * @x: Amount to scale along the x-axis - * @y: Amount to scale along the y-axis - * @z: Amount to scale along the z-axis - * - * Multiplies the current model-view matrix by one that scales the x, - * y and z axes by the given values. - */ -COGL_EXPORT void -cogl_framebuffer_scale (CoglFramebuffer *framebuffer, - float x, - float y, - float z); - -/** - * cogl_framebuffer_translate: - * @framebuffer: A #CoglFramebuffer pointer - * @x: Distance to translate along the x-axis - * @y: Distance to translate along the y-axis - * @z: Distance to translate along the z-axis - * - * Multiplies the current model-view matrix by one that translates the - * model along all three axes according to the given values. - */ -COGL_EXPORT void -cogl_framebuffer_translate (CoglFramebuffer *framebuffer, - float x, - float y, - float z); - -/** - * cogl_framebuffer_rotate: - * @framebuffer: A #CoglFramebuffer pointer - * @angle: Angle in degrees to rotate. - * @x: X-component of vertex to rotate around. - * @y: Y-component of vertex to rotate around. - * @z: Z-component of vertex to rotate around. - * - * Multiplies the current model-view matrix by one that rotates the - * model around the axis-vector specified by @x, @y and @z. The - * rotation follows the right-hand thumb rule so for example rotating - * by 10 degrees about the axis-vector (0, 0, 1) causes a small - * counter-clockwise rotation. - */ -COGL_EXPORT void -cogl_framebuffer_rotate (CoglFramebuffer *framebuffer, - float angle, - float x, - float y, - float z); - -/** - * cogl_framebuffer_rotate_euler: - * @framebuffer: A #CoglFramebuffer pointer - * @euler: A #graphene_euler_t - * - * Multiplies the current model-view matrix by one that rotates - * according to the rotation described by @euler. - */ -COGL_EXPORT void -cogl_framebuffer_rotate_euler (CoglFramebuffer *framebuffer, - const graphene_euler_t *euler); - -/** - * cogl_framebuffer_transform: - * @framebuffer: A #CoglFramebuffer pointer - * @matrix: the matrix to multiply with the current model-view - * - * Multiplies the current model-view matrix by the given matrix. - */ -COGL_EXPORT void -cogl_framebuffer_transform (CoglFramebuffer *framebuffer, - const graphene_matrix_t *matrix); - -/** - * cogl_framebuffer_get_modelview_matrix: - * @framebuffer: A #CoglFramebuffer pointer - * @matrix: (out): return location for the model-view matrix - * - * Stores the current model-view matrix in @matrix. - */ -COGL_EXPORT void -cogl_framebuffer_get_modelview_matrix (CoglFramebuffer *framebuffer, - graphene_matrix_t *matrix); - -/** - * cogl_framebuffer_set_modelview_matrix: - * @framebuffer: A #CoglFramebuffer pointer - * @matrix: the new model-view matrix - * - * Sets @matrix as the new model-view matrix. - */ -COGL_EXPORT void -cogl_framebuffer_set_modelview_matrix (CoglFramebuffer *framebuffer, - const graphene_matrix_t *matrix); - -/** - * cogl_framebuffer_perspective: - * @framebuffer: A #CoglFramebuffer pointer - * @fov_y: Vertical field of view angle in degrees. - * @aspect: The (width over height) aspect ratio for display - * @z_near: The distance to the near clipping plane (Must be positive, - * and must not be 0) - * @z_far: The distance to the far clipping plane (Must be positive) - * - * Replaces the current projection matrix with a perspective matrix - * based on the provided values. - * - * You should be careful not to have to great a @z_far / @z_near - * ratio since that will reduce the effectiveness of depth testing - * since there won't be enough precision to identify the depth of - * objects near to each other. - */ -COGL_EXPORT void -cogl_framebuffer_perspective (CoglFramebuffer *framebuffer, - float fov_y, - float aspect, - float z_near, - float z_far); - -/** - * cogl_framebuffer_frustum: - * @framebuffer: A #CoglFramebuffer pointer - * @left: X position of the left clipping plane where it - * intersects the near clipping plane - * @right: X position of the right clipping plane where it - * intersects the near clipping plane - * @bottom: Y position of the bottom clipping plane where it - * intersects the near clipping plane - * @top: Y position of the top clipping plane where it intersects - * the near clipping plane - * @z_near: The distance to the near clipping plane (Must be positive) - * @z_far: The distance to the far clipping plane (Must be positive) - * - * Replaces the current projection matrix with a perspective matrix - * for a given viewing frustum defined by 4 side clip planes that - * all cross through the origin and 2 near and far clip planes. - */ -COGL_EXPORT void -cogl_framebuffer_frustum (CoglFramebuffer *framebuffer, - float left, - float right, - float bottom, - float top, - float z_near, - float z_far); - -/** - * cogl_framebuffer_orthographic: - * @framebuffer: A #CoglFramebuffer pointer - * @x_1: The x coordinate for the first vertical clipping plane - * @y_1: The y coordinate for the first horizontal clipping plane - * @x_2: The x coordinate for the second vertical clipping plane - * @y_2: The y coordinate for the second horizontal clipping plane - * @near: The *distance* to the near clipping - * plane (will be *negative* if the plane is - * behind the viewer) - * @far: The *distance* to the far clipping - * plane (will be *negative* if the plane is - * behind the viewer) - * - * Replaces the current projection matrix with an orthographic projection - * matrix. - */ -COGL_EXPORT void -cogl_framebuffer_orthographic (CoglFramebuffer *framebuffer, - float x_1, - float y_1, - float x_2, - float y_2, - float near, - float far); - -/** - * cogl_framebuffer_get_projection_matrix: - * @framebuffer: A #CoglFramebuffer pointer - * @matrix: (out): return location for the projection matrix - * - * Stores the current projection matrix in @matrix. - */ -COGL_EXPORT void -cogl_framebuffer_get_projection_matrix (CoglFramebuffer *framebuffer, - graphene_matrix_t *matrix); - -/** - * cogl_framebuffer_set_projection_matrix: - * @framebuffer: A #CoglFramebuffer pointer - * @matrix: the new projection matrix - * - * Sets @matrix as the new projection matrix. - */ -COGL_EXPORT void -cogl_framebuffer_set_projection_matrix (CoglFramebuffer *framebuffer, - const graphene_matrix_t *matrix); - -/** - * cogl_framebuffer_push_rectangle_clip: - * @framebuffer: A #CoglFramebuffer pointer - * @x_1: x coordinate for top left corner of the clip rectangle - * @y_1: y coordinate for top left corner of the clip rectangle - * @x_2: x coordinate for bottom right corner of the clip rectangle - * @y_2: y coordinate for bottom right corner of the clip rectangle - * - * Specifies a modelview transformed rectangular clipping area for all - * subsequent drawing operations. Any drawing commands that extend - * outside the rectangle will be clipped so that only the portion - * inside the rectangle will be displayed. The rectangle dimensions - * are transformed by the current model-view matrix. - * - * The rectangle is intersected with the current clip region. To undo - * the effect of this function, call cogl_framebuffer_pop_clip(). - */ -COGL_EXPORT void -cogl_framebuffer_push_rectangle_clip (CoglFramebuffer *framebuffer, - float x_1, - float y_1, - float x_2, - float y_2); - -/** - * cogl_framebuffer_push_primitive_clip: - * @framebuffer: A #CoglFramebuffer pointer - * @primitive: A #CoglPrimitive describing a flat 2D shape - * @bounds_x1: x coordinate for the top-left corner of the primitives - * bounds - * @bounds_y1: y coordinate for the top-left corner of the primitives - * bounds - * @bounds_x2: x coordinate for the bottom-right corner of the - * primitives bounds. - * @bounds_y2: y coordinate for the bottom-right corner of the - * primitives bounds. - * - * Sets a new clipping area using a 2D shaped described with a - * #CoglPrimitive. The shape must not contain self overlapping - * geometry and must lie on a single 2D plane. A bounding box of the - * 2D shape in local coordinates (the same coordinates used to - * describe the shape) must be given. It is acceptable for the bounds - * to be larger than the true bounds but behaviour is undefined if the - * bounds are smaller than the true bounds. - * - * The primitive is transformed by the current model-view matrix and - * the silhouette is intersected with the previous clipping area. To - * restore the previous clipping area, call - * cogl_framebuffer_pop_clip(). - */ -COGL_EXPORT void -cogl_framebuffer_push_primitive_clip (CoglFramebuffer *framebuffer, - CoglPrimitive *primitive, - float bounds_x1, - float bounds_y1, - float bounds_x2, - float bounds_y2); - -COGL_EXPORT void -cogl_framebuffer_push_region_clip (CoglFramebuffer *framebuffer, - MtkRegion *region); - -/** - * cogl_framebuffer_pop_clip: - * @framebuffer: A #CoglFramebuffer pointer - * - * Reverts the clipping region to the state before the last call to - * cogl_framebuffer_push_rectangle_clip(), or - * cogl_framebuffer_push_primitive_clip(). - */ -COGL_EXPORT void -cogl_framebuffer_pop_clip (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_red_bits: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Retrieves the number of red bits of @framebuffer - * - * Return value: the number of bits - * - */ -COGL_EXPORT int -cogl_framebuffer_get_red_bits (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_green_bits: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Retrieves the number of green bits of @framebuffer - * - * Return value: the number of bits - * - */ -COGL_EXPORT int -cogl_framebuffer_get_green_bits (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_blue_bits: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Retrieves the number of blue bits of @framebuffer - * - * Return value: the number of bits - * - */ -COGL_EXPORT int -cogl_framebuffer_get_blue_bits (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_alpha_bits: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Retrieves the number of alpha bits of @framebuffer - * - * Return value: the number of bits - * - */ -COGL_EXPORT int -cogl_framebuffer_get_alpha_bits (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_depth_bits: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Retrieves the number of depth bits of @framebuffer - * - * Return value: the number of bits - */ -COGL_EXPORT int -cogl_framebuffer_get_depth_bits (CoglFramebuffer *framebuffer); - -/* - * cogl_framebuffer_get_is_stereo: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Retrieves whether @framebuffer has separate left and right - * buffers for use with stereo drawing. See - * cogl_framebuffer_set_stereo_mode(). - * - * Return value: %TRUE if @framebuffer has separate left and - * right buffers. - */ -COGL_EXPORT gboolean -cogl_framebuffer_get_is_stereo (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_dither_enabled: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Returns whether dithering has been requested for the given @framebuffer. - * See cogl_framebuffer_set_dither_enabled() for more details about dithering. - * - * This may return %TRUE even when the underlying @framebuffer - * display pipeline does not support dithering. This value only represents - * the user's request for dithering. - * - * Return value: %TRUE if dithering has been requested or %FALSE if not. - */ -COGL_EXPORT gboolean -cogl_framebuffer_get_dither_enabled (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_set_dither_enabled: - * @framebuffer: a pointer to a #CoglFramebuffer - * @dither_enabled: %TRUE to enable dithering or %FALSE to disable - * - * Enables or disabled dithering if supported by the hardware. - * - * Dithering is a hardware dependent technique to increase the visible - * color resolution beyond what the underlying hardware supports by playing - * tricks with the colors placed into the framebuffer to give the illusion - * of other colors. (For example this can be compared to half-toning used - * by some news papers to show varying levels of grey even though their may - * only be black and white are available). - * - * If the current display pipeline for @framebuffer does not support dithering - * then this has no affect. - * - * Dithering is enabled by default. - * - */ -COGL_EXPORT void -cogl_framebuffer_set_dither_enabled (CoglFramebuffer *framebuffer, - gboolean dither_enabled); - -/** - * cogl_framebuffer_get_depth_write_enabled: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Queries whether depth buffer writing is enabled for @framebuffer. This - * can be controlled via cogl_framebuffer_set_depth_write_enabled(). - * - * Return value: %TRUE if depth writing is enabled or %FALSE if not. - */ -COGL_EXPORT gboolean -cogl_framebuffer_get_depth_write_enabled (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_set_depth_write_enabled: - * @framebuffer: a pointer to a #CoglFramebuffer - * @depth_write_enabled: %TRUE to enable depth writing or %FALSE to disable - * - * Enables or disables depth buffer writing when rendering to @framebuffer. - * If depth writing is enabled for both the framebuffer and the rendering - * pipeline, and the framebuffer has an associated depth buffer, depth - * information will be written to this buffer during rendering. - * - * Depth buffer writing is enabled by default. - */ -COGL_EXPORT void -cogl_framebuffer_set_depth_write_enabled (CoglFramebuffer *framebuffer, - gboolean depth_write_enabled); - -/** - * cogl_framebuffer_get_stereo_mode: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Gets the current #CoglStereoMode, which defines which stereo buffers - * should be drawn to. See cogl_framebuffer_set_stereo_mode(). - * - * Returns: A #CoglStereoMode - */ -COGL_EXPORT CoglStereoMode -cogl_framebuffer_get_stereo_mode (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_set_stereo_mode: - * @framebuffer: a pointer to a #CoglFramebuffer - * @stereo_mode: A #CoglStereoMode specifying which stereo buffers - * should be drawn tow. - * - * Sets which stereo buffers should be drawn to. The default - * is %COGL_STEREO_BOTH, which means that both the left and - * right buffers will be affected by drawing. For this to have - * an effect, the display system must support stereo drawables, - * and the framebuffer must have been created with stereo - * enabled. (See cogl_onscreen_template_set_stereo_enabled(), - * cogl_framebuffer_get_is_stereo().) - */ -COGL_EXPORT void -cogl_framebuffer_set_stereo_mode (CoglFramebuffer *framebuffer, - CoglStereoMode stereo_mode); - -/** - * cogl_framebuffer_set_samples_per_pixel: - * @framebuffer: A #CoglFramebuffer framebuffer - * @samples_per_pixel: The minimum number of samples per pixel - * - * Requires that when rendering to @framebuffer then @n point samples - * should be made per pixel which will all contribute to the final - * resolved color for that pixel. The idea is that the hardware aims - * to get quality similar to what you would get if you rendered - * everything twice as big (for 4 samples per pixel) and then scaled - * that image back down with filtering. It can effectively remove the - * jagged edges of polygons and should be more efficient than if you - * were to manually render at a higher resolution and downscale - * because the hardware is often able to take some shortcuts. For - * example the GPU may only calculate a single texture sample for all - * points of a single pixel, and for tile based architectures all the - * extra sample data (such as depth and stencil samples) may be - * handled on-chip and so avoid increased demand on system memory - * bandwidth. - * - * By default this value is usually set to 0 and that is referred to - * as "single-sample" rendering. A value of 1 or greater is referred - * to as "multisample" rendering. - * - * There are some semantic differences between single-sample - * rendering and multisampling with just 1 point sample such as it - * being redundant to use the cogl_framebuffer_resolve_samples() and - * cogl_framebuffer_resolve_samples_region() apis with single-sample - * rendering. - * - * It's recommended that - * cogl_framebuffer_resolve_samples_region() be explicitly used at the - * end of rendering to a point sample buffer to minimize the number of - * samples that get resolved. By default Cogl will implicitly resolve - * all framebuffer samples but if only a small region of a - * framebuffer has changed this can lead to redundant work being - * done. - * - */ -COGL_EXPORT void -cogl_framebuffer_set_samples_per_pixel (CoglFramebuffer *framebuffer, - int samples_per_pixel); - -/** - * cogl_framebuffer_get_samples_per_pixel: - * @framebuffer: A #CoglFramebuffer framebuffer - * - * Gets the number of points that are sampled per-pixel when - * rasterizing geometry. Usually by default this will return 0 which - * means that single-sample not multisample rendering has been chosen. - * When using a GPU supporting multisample rendering it's possible to - * increase the number of samples per pixel using - * cogl_framebuffer_set_samples_per_pixel(). - * - * Calling cogl_framebuffer_get_samples_per_pixel() before the - * framebuffer has been allocated will simply return the value set - * using cogl_framebuffer_set_samples_per_pixel(). After the - * framebuffer has been allocated the value will reflect the actual - * number of samples that will be made by the GPU. - * - * Returns: The number of point samples made per pixel when - * rasterizing geometry or 0 if single-sample rendering - * has been chosen. - */ -COGL_EXPORT int -cogl_framebuffer_get_samples_per_pixel (CoglFramebuffer *framebuffer); - - -/** - * cogl_framebuffer_resolve_samples: - * @framebuffer: A #CoglFramebuffer framebuffer - * - * When point sample rendering (also known as multisample rendering) - * has been enabled via cogl_framebuffer_set_samples_per_pixel() - * then you can optionally call this function (or - * cogl_framebuffer_resolve_samples_region()) to explicitly resolve - * the point samples into values for the final color buffer. - * - * Some GPUs will implicitly resolve the point samples during - * rendering and so this function is effectively a nop, but with other - * architectures it is desirable to defer the resolve step until the - * end of the frame. - * - * Since Cogl will automatically ensure samples are resolved if the - * target color buffer is used as a source this API only needs to be - * used if explicit control is desired - perhaps because you want to - * ensure that the resolve is completed in advance to avoid later - * having to wait for the resolve to complete. - * - * If you are performing incremental updates to a framebuffer you - * should consider using cogl_framebuffer_resolve_samples_region() - * instead to avoid resolving redundant pixels. - * - */ -COGL_EXPORT void -cogl_framebuffer_resolve_samples (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_resolve_samples_region: - * @framebuffer: A #CoglFramebuffer framebuffer - * @x: top-left x coordinate of region to resolve - * @y: top-left y coordinate of region to resolve - * @width: width of region to resolve - * @height: height of region to resolve - * - * When point sample rendering (also known as multisample rendering) - * has been enabled via cogl_framebuffer_set_samples_per_pixel() - * then you can optionally call this function (or - * cogl_framebuffer_resolve_samples()) to explicitly resolve the point - * samples into values for the final color buffer. - * - * Some GPUs will implicitly resolve the point samples during - * rendering and so this function is effectively a nop, but with other - * architectures it is desirable to defer the resolve step until the - * end of the frame. - * - * Use of this API is recommended if incremental, small updates to - * a framebuffer are being made because by default Cogl will - * implicitly resolve all the point samples of the framebuffer which - * can result in redundant work if only a small number of samples have - * changed. - * - * Because some GPUs implicitly resolve point samples this function - * only guarantees that at-least the region specified will be resolved - * and if you have rendered to a larger region then it's possible that - * other samples may be implicitly resolved. - * - */ -COGL_EXPORT void -cogl_framebuffer_resolve_samples_region (CoglFramebuffer *framebuffer, - int x, - int y, - int width, - int height); - -/** - * cogl_framebuffer_get_context: - * @framebuffer: A #CoglFramebuffer - * - * Can be used to query the #CoglContext a given @framebuffer was - * instantiated within. This is the #CoglContext that was passed to - * cogl_onscreen_new() for example. - * - * Return value: (transfer none): The #CoglContext that the given - * @framebuffer was instantiated within. - */ -COGL_EXPORT CoglContext * -cogl_framebuffer_get_context (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_clear: - * @framebuffer: A #CoglFramebuffer - * @buffers: A mask of `CoglBufferBit`s identifying which auxiliary - * buffers to clear - * @color: The color to clear the color buffer too if specified in - * @buffers. - * - * Clears all the auxiliary buffers identified in the @buffers mask, and if - * that includes the color buffer then the specified @color is used. - * - */ -COGL_EXPORT void -cogl_framebuffer_clear (CoglFramebuffer *framebuffer, - unsigned long buffers, - const CoglColor *color); - -/** - * cogl_framebuffer_clear4f: - * @framebuffer: A #CoglFramebuffer - * @buffers: A mask of `CoglBufferBit`s identifying which auxiliary - * buffers to clear - * @red: The red component of color to clear the color buffer too if - * specified in @buffers. - * @green: The green component of color to clear the color buffer too if - * specified in @buffers. - * @blue: The blue component of color to clear the color buffer too if - * specified in @buffers. - * @alpha: The alpha component of color to clear the color buffer too if - * specified in @buffers. - * - * Clears all the auxiliary buffers identified in the @buffers mask, and if - * that includes the color buffer then the specified @color is used. - * - */ -COGL_EXPORT void -cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, - unsigned long buffers, - float red, - float green, - float blue, - float alpha); - -/** - * cogl_framebuffer_draw_rectangle: - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * @x_1: X coordinate of the top-left corner - * @y_1: Y coordinate of the top-left corner - * @x_2: X coordinate of the bottom-right corner - * @y_2: Y coordinate of the bottom-right corner - * - * Draws a rectangle to @framebuffer with the given @pipeline state - * and with the top left corner positioned at (@x_1, @y_1) and the - * bottom right corner positioned at (@x_2, @y_2). - * - * The position is the position before the rectangle has been - * transformed by the model-view matrix and the projection - * matrix. - * - * If you want to describe a rectangle with a texture mapped on - * it then you can use - * cogl_framebuffer_draw_textured_rectangle(). - */ -COGL_EXPORT void -cogl_framebuffer_draw_rectangle (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2); - -/** - * cogl_framebuffer_draw_textured_rectangle: - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * @x_1: x coordinate upper left on screen. - * @y_1: y coordinate upper left on screen. - * @x_2: x coordinate lower right on screen. - * @y_2: y coordinate lower right on screen. - * @s_1: S texture coordinate of the top-left coorner - * @t_1: T texture coordinate of the top-left coorner - * @s_2: S texture coordinate of the bottom-right coorner - * @t_2: T texture coordinate of the bottom-right coorner - * - * Draws a textured rectangle to @framebuffer using the given - * @pipeline state with the top left corner positioned at (@x_1, @y_1) - * and the bottom right corner positioned at (@x_2, @y_2). The top - * left corner will have texture coordinates of (@s_1, @t_1) and the - * bottom right corner will have texture coordinates of (@s_2, @t_2). - * - * The position is the position before the rectangle has been - * transformed by the model-view matrix and the projection - * matrix. - * - * This is a high level drawing api that can handle any kind of - * #CoglMetaTexture texture such as #CoglTexture2DSliced textures - * which may internally be comprised of multiple low-level textures. - * This is unlike low-level drawing apis such as cogl_primitive_draw() - * which only support low level texture types that are directly - * supported by GPUs such as #CoglTexture2D. - * - * The given texture coordinates will only be used for the first - * texture layer of the pipeline and if your pipeline has more than - * one layer then all other layers will have default texture - * coordinates of @s_1=0.0 @t_1=0.0 @s_2=1.0 @t_2=1.0 - * - * The given texture coordinates should always be normalized such that - * (0, 0) corresponds to the top left and (1, 1) corresponds to the - * bottom right. To map an entire texture across the rectangle pass - * in @s_1=0, @t_1=0, @s_2=1, @t_2=1. - */ -COGL_EXPORT void -cogl_framebuffer_draw_textured_rectangle (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2, - float s_1, - float t_1, - float s_2, - float t_2); - -/** - * cogl_framebuffer_draw_multitextured_rectangle: - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * @x_1: x coordinate upper left on screen. - * @y_1: y coordinate upper left on screen. - * @x_2: x coordinate lower right on screen. - * @y_2: y coordinate lower right on screen. - * @tex_coords: (in) (array) (transfer none): An array containing groups of - * 4 float values: [s_1, t_1, s_2, t_2] that are interpreted as two texture - * coordinates; one for the top left texel, and one for the bottom right - * texel. Each value should be between 0.0 and 1.0, where the coordinate - * (0.0, 0.0) represents the top left of the texture, and (1.0, 1.0) the - * bottom right. - * @tex_coords_len: The length of the @tex_coords array. (For one layer - * and one group of texture coordinates, this would be 4) - * - * Draws a textured rectangle to @framebuffer with the given @pipeline - * state with the top left corner positioned at (@x_1, @y_1) and the - * bottom right corner positioned at (@x_2, @y_2). As a pipeline may - * contain multiple texture layers this interface lets you supply - * texture coordinates for each layer of the pipeline. - * - * The position is the position before the rectangle has been - * transformed by the model-view matrix and the projection - * matrix. - * - * This is a high level drawing api that can handle any kind of - * #CoglMetaTexture texture for the first layer such as - * #CoglTexture2DSliced textures which may internally be comprised of - * multiple low-level textures. This is unlike low-level drawing apis - * such as cogl_primitive_draw() which only support low level texture - * types that are directly supported by GPUs such as #CoglTexture2D. - * - * This api can not currently handle multiple high-level meta - * texture layers. The first layer may be a high level meta texture - * such as #CoglTexture2DSliced but all other layers much be low - * level textures such as #CoglTexture2D. - * - * The top left texture coordinate for layer 0 of any pipeline will be - * (tex_coords[0], tex_coords[1]) and the bottom right coordinate will - * be (tex_coords[2], tex_coords[3]). The coordinates for layer 1 - * would be (tex_coords[4], tex_coords[5]) (tex_coords[6], - * tex_coords[7]) and so on... - * - * The given texture coordinates should always be normalized such that - * (0, 0) corresponds to the top left and (1, 1) corresponds to the - * bottom right. To map an entire texture across the rectangle pass - * in tex_coords[0]=0, tex_coords[1]=0, tex_coords[2]=1, - * tex_coords[3]=1. - * - * The first pair of coordinates are for the first layer (with the - * smallest layer index) and if you supply less texture coordinates - * than there are layers in the current source material then default - * texture coordinates (0.0, 0.0, 1.0, 1.0) are generated. - */ -COGL_EXPORT void -cogl_framebuffer_draw_multitextured_rectangle (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2, - const float *tex_coords, - int tex_coords_len); - -/** - * cogl_framebuffer_draw_rectangles: - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * @coordinates: (in) (array) (transfer none): an array of coordinates - * containing groups of 4 float values: [x_1, y_1, x_2, y_2] that are - * interpreted as two position coordinates; one for the top left of - * the rectangle (x1, y1), and one for the bottom right of the - * rectangle (x2, y2). - * @n_rectangles: number of rectangles defined in @coordinates. - * - * Draws a series of rectangles to @framebuffer with the given - * @pipeline state in the same way that - * cogl_framebuffer_draw_rectangle() does. - * - * The top left corner of the first rectangle is positioned at - * (coordinates[0], coordinates[1]) and the bottom right corner is - * positioned at (coordinates[2], coordinates[3]). The positions for - * the second rectangle are (coordinates[4], coordinates[5]) and - * (coordinates[6], coordinates[7]) and so on... - * - * The position is the position before the rectangle has been - * transformed by the model-view matrix and the projection - * matrix. - * - * As a general rule for better performance its recommended to use - * this this API instead of calling - * cogl_framebuffer_draw_textured_rectangle() separately for multiple - * rectangles if all of the rectangles will be drawn together with the - * same @pipeline state. - */ -COGL_EXPORT void -cogl_framebuffer_draw_rectangles (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - const float *coordinates, - unsigned int n_rectangles); - -/** - * cogl_framebuffer_draw_textured_rectangles: - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * @coordinates: (in) (array) (transfer none): an array containing - * groups of 8 float values: [x_1, y_1, x_2, y_2, s_1, t_1, s_2, t_2] - * that have the same meaning as the arguments for - * cogl_framebuffer_draw_textured_rectangle(). - * @n_rectangles: number of rectangles to @coordinates to draw - * - * Draws a series of rectangles to @framebuffer with the given - * @pipeline state in the same way that - * cogl_framebuffer_draw_textured_rectangle() does. - * - * The position is the position before the rectangle has been - * transformed by the model-view matrix and the projection - * matrix. - * - * This is a high level drawing api that can handle any kind of - * #CoglMetaTexture texture such as #CoglTexture2DSliced textures - * which may internally be comprised of multiple low-level textures. - * This is unlike low-level drawing apis such as cogl_primitive_draw() - * which only support low level texture types that are directly - * supported by GPUs such as #CoglTexture2D. - * - * The top left corner of the first rectangle is positioned at - * (coordinates[0], coordinates[1]) and the bottom right corner is - * positioned at (coordinates[2], coordinates[3]). The top left - * texture coordinate is (coordinates[4], coordinates[5]) and the - * bottom right texture coordinate is (coordinates[6], - * coordinates[7]). The coordinates for subsequent rectangles - * are defined similarly by the subsequent coordinates. - * - * As a general rule for better performance its recommended to use - * this this API instead of calling - * cogl_framebuffer_draw_textured_rectangle() separately for multiple - * rectangles if all of the rectangles will be drawn together with the - * same @pipeline state. - * - * The given texture coordinates should always be normalized such that - * (0, 0) corresponds to the top left and (1, 1) corresponds to the - * bottom right. To map an entire texture across the rectangle pass - * in tex_coords[0]=0, tex_coords[1]=0, tex_coords[2]=1, - * tex_coords[3]=1. - */ -COGL_EXPORT void -cogl_framebuffer_draw_textured_rectangles (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - const float *coordinates, - unsigned int n_rectangles); - -/* XXX: Should we take an n_buffers + buffer id array instead of using - * the CoglBufferBits type which doesn't seem future proof? */ -/** - * cogl_framebuffer_discard_buffers: - * @framebuffer: A #CoglFramebuffer - * @buffers: A #CoglBufferBit mask of which ancillary buffers you want - * to discard. - * - * Declares that the specified @buffers no longer need to be referenced - * by any further rendering commands. This can be an important - * optimization to avoid subsequent frames of rendering depending on - * the results of a previous frame. - * - * For example; some tile-based rendering GPUs are able to avoid allocating and - * accessing system memory for the depth and stencil buffer so long as these - * buffers are not required as input for subsequent frames and that can save a - * significant amount of memory bandwidth used to save and restore their - * contents to system memory between frames. - * - * It is currently considered an error to try and explicitly discard the color - * buffer by passing %COGL_BUFFER_BIT_COLOR. This is because the color buffer is - * already implicitly discard when you finish rendering to a #CoglOnscreen - * framebuffer, and it's not meaningful to try and discard the color buffer of - * a #CoglOffscreen framebuffer since they are single-buffered. - * - * - */ -COGL_EXPORT void -cogl_framebuffer_discard_buffers (CoglFramebuffer *framebuffer, - unsigned long buffers); - -/** - * cogl_framebuffer_finish: - * @framebuffer: A #CoglFramebuffer pointer - * - * This blocks the CPU until all pending rendering associated with the - * specified framebuffer has completed. It's very rare that developers should - * ever need this level of synchronization with the GPU and should never be - * used unless you clearly understand why you need to explicitly force - * synchronization. - * - * One example might be for benchmarking purposes to be sure timing - * measurements reflect the time that the GPU is busy for not just the time it - * takes to queue rendering commands. - */ -COGL_EXPORT void -cogl_framebuffer_finish (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_read_pixels_into_bitmap: - * @framebuffer: A #CoglFramebuffer - * @x: The x position to read from - * @y: The y position to read from - * @source: Identifies which auxiliary buffer you want to read - * (only COGL_READ_PIXELS_COLOR_BUFFER supported currently) - * @bitmap: The bitmap to store the results in. - * - * This reads a rectangle of pixels from the given framebuffer where - * position (0, 0) is the top left. The pixel at (x, y) is the first - * read, and a rectangle of pixels with the same size as the bitmap is - * read right and downwards from that point. - * - * Currently Cogl assumes that the framebuffer is in a premultiplied - * format so if the format of @bitmap is non-premultiplied it will - * convert it. To read the pixel values without any conversion you - * should either specify a format that doesn't use an alpha channel or - * use one of the formats ending in PRE. - * - * Return value: %TRUE if the read succeeded or %FALSE otherwise. The - * function is only likely to fail if the bitmap points to a pixel - * buffer and it could not be mapped. - */ -COGL_EXPORT gboolean -cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap); - -/** - * cogl_framebuffer_read_pixels: - * @framebuffer: A #CoglFramebuffer - * @x: The x position to read from - * @y: The y position to read from - * @width: The width of the region of rectangles to read - * @height: The height of the region of rectangles to read - * @format: The pixel format to store the data in - * @pixels: The address of the buffer to store the data in - * - * This is a convenience wrapper around - * cogl_framebuffer_read_pixels_into_bitmap() which allocates a - * temporary #CoglBitmap to read pixel data directly into the given - * buffer. The rowstride of the buffer is assumed to be the width of - * the region times the bytes per pixel of the format. The source for - * the data is always taken from the color buffer. If you want to use - * any other rowstride or source, please use the - * cogl_framebuffer_read_pixels_into_bitmap() function directly. - * - * The implementation of the function looks like this: - * - * ```c - * bitmap = cogl_bitmap_new_for_data (context, - * width, height, - * format, - * /* rowstride */ - * bpp * width, - * pixels); - * cogl_framebuffer_read_pixels_into_bitmap (framebuffer, - * x, y, - * COGL_READ_PIXELS_COLOR_BUFFER, - * bitmap); - * g_object_unref (bitmap); - * ``` - * - * Return value: %TRUE if the read succeeded or %FALSE otherwise. - */ -COGL_EXPORT gboolean -cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer, - int x, - int y, - int width, - int height, - CoglPixelFormat format, - uint8_t *pixels); - -COGL_EXPORT uint32_t -cogl_framebuffer_error_quark (void); - -/** - * COGL_FRAMEBUFFER_ERROR: - * - * An error domain for reporting #CoglFramebuffer exceptions - */ -#define COGL_FRAMEBUFFER_ERROR (cogl_framebuffer_error_quark ()) - -typedef enum /*< prefix=COGL_FRAMEBUFFER_ERROR >*/ -{ - COGL_FRAMEBUFFER_ERROR_ALLOCATE -} CoglFramebufferError; - -/** - * cogl_is_framebuffer: - * @object: A #CoglObject pointer - * - * Gets whether the given object references a #CoglFramebuffer. - * - * Return value: %TRUE if the object references a #CoglFramebuffer - * and %FALSE otherwise. - */ -COGL_EXPORT gboolean -cogl_is_framebuffer (void *object); - -/** - * cogl_blit_framebuffer: - * @framebuffer: The source #CoglFramebuffer - * @dst: The destination #CoglFramebuffer - * @src_x: Source x position - * @src_y: Source y position - * @dst_x: Destination x position - * @dst_y: Destination y position - * @width: Width of region to copy - * @height: Height of region to copy - * @error: optional error object - * - * @return FALSE for an immediately detected error, TRUE otherwise. - * - * This blits a region of the color buffer of the source buffer - * to the destination buffer. This function should only be - * called if the COGL_FEATURE_ID_BLIT_FRAMEBUFFER feature is - * advertised. - * - * The source and destination rectangles are defined in offscreen - * framebuffer orientation. When copying between an offscreen and - * onscreen framebuffers, the image is y-flipped accordingly. - * - * The two buffers must have the same value types (e.g. floating-point, - * unsigned int, signed int, or fixed-point), but color formats do not - * need to match. This limitation comes from OpenGL ES 3.0 definition - * of glBlitFramebuffer. - * - * Note that this function differs a lot from the glBlitFramebuffer - * function provided by the GL_EXT_framebuffer_blit extension. Notably - * it doesn't support having different sizes for the source and - * destination rectangle. This doesn't seem - * like a particularly useful feature. If the application wanted to - * scale the results it may make more sense to draw a primitive - * instead. - * - * The GL function is documented to be affected by the scissor. This - * function therefore ensure that an empty clip stack is flushed - * before performing the blit which means the scissor is effectively - * ignored. - * - * The function also doesn't support specifying the buffers to copy - * and instead only the color buffer is copied. When copying the depth - * or stencil buffers the extension on GLES2.0 only supports copying - * the full buffer which would be awkward to document with this - * API. If we wanted to support that feature it may be better to have - * a separate function to copy the entire buffer for a given mask. - * - * The @c error argument is optional, it can be NULL. If it is not NULL - * and this function returns FALSE, an error object with a code from - * COGL_SYSTEM_ERROR will be created. - */ -COGL_EXPORT gboolean -cogl_blit_framebuffer (CoglFramebuffer *framebuffer, - CoglFramebuffer *dst, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - GError **error); - -/** - * cogl_framebuffer_flush: - * @framebuffer: A #CoglFramebuffer pointer - * - * Flushes @framebuffer to ensure the current batch of commands is - * submitted to the GPU. - * - * Unlike cogl_framebuffer_finish(), this does not block the CPU. - */ -COGL_EXPORT void -cogl_framebuffer_flush (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_create_timestamp_query: (skip) - * - * Creates a query for the GPU timestamp that will complete upon completion of - * all previously submitted GL commands related to this framebuffer. E.g. when - * the rendering is finished on this framebuffer. - * - * This function should only be called if the COGL_FEATURE_ID_TIMESTAMP_QUERY - * feature is advertised. - */ -COGL_EXPORT CoglTimestampQuery * -cogl_framebuffer_create_timestamp_query (CoglFramebuffer *framebuffer); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-gl-header.h b/mutter/cogl/cogl/cogl-gl-header.h deleted file mode 100644 index 519d4f7..0000000 --- a/mutter/cogl/cogl/cogl-gl-header.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#if !defined(COGL_COMPILATION) && !defined(COGL_ENABLE_MUTTER_API) -#error "cogl-gl-header.h should only be included when compiling Cogl" -#endif - -#include "config.h" - -#if defined(HAVE_GL) -#include -#elif defined(HAVE_GLES2) -#include -#include -#endif - -#ifndef GL_OES_EGL_image -#define GLeglImageOES void * -#endif diff --git a/mutter/cogl/cogl/cogl-glib-source.c b/mutter/cogl/cogl/cogl-glib-source.c deleted file mode 100644 index d04fb7a..0000000 --- a/mutter/cogl/cogl/cogl-glib-source.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include "cogl/cogl-glib-source.h" -#include "cogl/cogl-poll.h" - -typedef struct _CoglGLibSource -{ - GSource source; - - CoglRenderer *renderer; - - GArray *poll_fds; - int poll_fds_age; - - int64_t expiration_time; -} CoglGLibSource; - -static gboolean -cogl_glib_source_prepare (GSource *source, int *timeout) -{ - CoglGLibSource *cogl_source = (CoglGLibSource *) source; - CoglPollFD *poll_fds; - int n_poll_fds; - int64_t cogl_timeout; - int age; - int i; - - age = cogl_poll_renderer_get_info (cogl_source->renderer, - &poll_fds, - &n_poll_fds, - &cogl_timeout); - - /* We have to be careful not to call g_source_add/remove_poll unless - * the FDs have changed because it will cause the main loop to - * immediately wake up. If we call it every time the source is - * prepared it will effectively never go idle. */ - if (age != cogl_source->poll_fds_age) - { - /* Remove any existing polls before adding the new ones */ - for (i = 0; i < cogl_source->poll_fds->len; i++) - { - GPollFD *poll_fd = &g_array_index (cogl_source->poll_fds, GPollFD, i); - g_source_remove_poll (source, poll_fd); - } - - g_array_set_size (cogl_source->poll_fds, n_poll_fds); - - for (i = 0; i < n_poll_fds; i++) - { - GPollFD *poll_fd = &g_array_index (cogl_source->poll_fds, GPollFD, i); - poll_fd->fd = poll_fds[i].fd; - g_source_add_poll (source, poll_fd); - } - } - - cogl_source->poll_fds_age = age; - - /* Update the events */ - for (i = 0; i < n_poll_fds; i++) - { - GPollFD *poll_fd = &g_array_index (cogl_source->poll_fds, GPollFD, i); - poll_fd->events = poll_fds[i].events; - poll_fd->revents = 0; - } - - if (cogl_timeout == -1) - { - *timeout = -1; - cogl_source->expiration_time = -1; - } - else - { - /* Round up to ensure that we don't try again too early */ - *timeout = (cogl_timeout + 999) / 1000; - cogl_source->expiration_time = (g_source_get_time (source) + - cogl_timeout); - } - - return *timeout == 0; -} - -static gboolean -cogl_glib_source_check (GSource *source) -{ - CoglGLibSource *cogl_source = (CoglGLibSource *) source; - int i; - - if (cogl_source->expiration_time >= 0 && - g_source_get_time (source) >= cogl_source->expiration_time) - return TRUE; - - for (i = 0; i < cogl_source->poll_fds->len; i++) - { - GPollFD *poll_fd = &g_array_index (cogl_source->poll_fds, GPollFD, i); - if (poll_fd->revents != 0) - return TRUE; - } - - return FALSE; -} - -static gboolean -cogl_glib_source_dispatch (GSource *source, - GSourceFunc callback, - void *user_data) -{ - CoglGLibSource *cogl_source = (CoglGLibSource *) source; - CoglPollFD *poll_fds = - (CoglPollFD *) &g_array_index (cogl_source->poll_fds, GPollFD, 0); - - cogl_poll_renderer_dispatch (cogl_source->renderer, - poll_fds, - cogl_source->poll_fds->len); - - return TRUE; -} - -static void -cogl_glib_source_finalize (GSource *source) -{ - CoglGLibSource *cogl_source = (CoglGLibSource *) source; - - g_array_free (cogl_source->poll_fds, TRUE); -} - -static GSourceFuncs -cogl_glib_source_funcs = - { - cogl_glib_source_prepare, - cogl_glib_source_check, - cogl_glib_source_dispatch, - cogl_glib_source_finalize - }; - -GSource * -cogl_glib_renderer_source_new (CoglRenderer *renderer, - int priority) -{ - GSource *source; - CoglGLibSource *cogl_source; - - source = g_source_new (&cogl_glib_source_funcs, - sizeof (CoglGLibSource)); - g_source_set_name (source, "[mutter] Cogl"); - cogl_source = (CoglGLibSource *) source; - - cogl_source->renderer = renderer; - cogl_source->poll_fds = g_array_new (FALSE, FALSE, sizeof (GPollFD)); - - if (priority != G_PRIORITY_DEFAULT) - g_source_set_priority (source, priority); - - return source; -} - -GSource * -cogl_glib_source_new (CoglContext *context, - int priority) -{ - return cogl_glib_renderer_source_new (cogl_context_get_renderer (context), - priority); -} - - diff --git a/mutter/cogl/cogl/cogl-glib-source.h b/mutter/cogl/cogl/cogl-glib-source.h deleted file mode 100644 index 01a0c2e..0000000 --- a/mutter/cogl/cogl/cogl-glib-source.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -#include "cogl/cogl-context.h" - -G_BEGIN_DECLS - -/** - * cogl_glib_source_new: - * @context: A #CoglContext - * @priority: The priority of the #GSource - * - * Creates a #GSource which handles Cogl's internal system event - * processing. This can be used as a convenience instead of - * cogl_poll_renderer_get_info() and cogl_poll_renderer_dispatch() in - * applications that are already using the GLib main loop. After this - * is called the #GSource should be attached to the main loop using - * g_source_attach(). - * - * Applications that manually connect to a #CoglRenderer before they - * create a #CoglContext should instead use - * cogl_glib_renderer_source_new() so that events may be dispatched - * before a context has been created. In that case you don't need to - * use this api in addition later, it is simply enough to use - * cogl_glib_renderer_source_new() instead. - * - * This api is actually just a thin convenience wrapper around - * cogl_glib_renderer_source_new() - * - * Return value: a new #GSource - */ -COGL_EXPORT GSource * -cogl_glib_source_new (CoglContext *context, - int priority); - -/** - * cogl_glib_renderer_source_new: - * @renderer: A #CoglRenderer - * @priority: The priority of the #GSource - * - * Creates a #GSource which handles Cogl's internal system event - * processing. This can be used as a convenience instead of - * cogl_poll_renderer_get_info() and cogl_poll_renderer_dispatch() in - * applications that are already using the GLib main loop. After this - * is called the #GSource should be attached to the main loop using - * g_source_attach(). - * - * Return value: a new #GSource - */ -COGL_EXPORT GSource * -cogl_glib_renderer_source_new (CoglRenderer *renderer, - int priority); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-glsl-shader-boilerplate.h b/mutter/cogl/cogl/cogl-glsl-shader-boilerplate.h deleted file mode 100644 index f5be36b..0000000 --- a/mutter/cogl/cogl/cogl-glsl-shader-boilerplate.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#define _COGL_COMMON_SHADER_BOILERPLATE \ - "#define COGL_VERSION 100\n" \ - "\n" \ - "uniform mat4 cogl_modelview_matrix;\n" \ - "uniform mat4 cogl_modelview_projection_matrix;\n" \ - "uniform mat4 cogl_projection_matrix;\n" - -/* This declares all of the variables that we might need. This is - * working on the assumption that the compiler will optimise them out - * if they are not actually used. The GLSL spec at least implies that - * this will happen for varyings but it doesn't explicitly so for - * attributes */ -#define _COGL_VERTEX_SHADER_BOILERPLATE \ - _COGL_COMMON_SHADER_BOILERPLATE \ - "#define cogl_color_out _cogl_color\n" \ - "varying vec4 _cogl_color;\n" \ - "#define cogl_tex_coord_out _cogl_tex_coord\n" \ - "#define cogl_position_out gl_Position\n" \ - "#define cogl_point_size_out gl_PointSize\n" \ - "\n" \ - "attribute vec4 cogl_color_in;\n" \ - "attribute vec4 cogl_position_in;\n" \ - "#define cogl_tex_coord_in cogl_tex_coord0_in;\n" \ - "attribute vec3 cogl_normal_in;\n" - -#define _COGL_FRAGMENT_SHADER_BOILERPLATE \ - "#ifdef GL_ES\n" \ - "precision highp float;\n" \ - "#endif\n" \ - _COGL_COMMON_SHADER_BOILERPLATE \ - "\n" \ - "varying vec4 _cogl_color;\n" \ - "\n" \ - "#define cogl_color_in _cogl_color\n" \ - "#define cogl_tex_coord_in _cogl_tex_coord\n" \ - "\n" \ - "#define cogl_color_out gl_FragColor\n" \ - "#define cogl_depth_out gl_FragDepth\n" \ - "\n" \ - "#define cogl_front_facing gl_FrontFacing\n" \ - "\n" \ - "#define cogl_point_coord gl_PointCoord\n" -#if 0 - /* GLSL 1.2 has a bottom left origin, though later versions - * allow use of an origin_upper_left keyword which would be - * more appropriate for Cogl. */ - "#define coglFragCoord gl_FragCoord\n" -#endif diff --git a/mutter/cogl/cogl/cogl-graphene.c b/mutter/cogl/cogl/cogl-graphene.c deleted file mode 100644 index 38631db..0000000 --- a/mutter/cogl/cogl/cogl-graphene.c +++ /dev/null @@ -1,284 +0,0 @@ -/* cogl-graphene.c - * - * Copyright 2020 Georges Basile Stavracas Neto - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - * - */ - -#include "cogl/cogl-graphene.h" - -typedef struct _Point2f -{ - float x; - float y; -} Point2f; - -typedef struct _Point3f -{ - float x; - float y; - float z; -} Point3f; - -typedef struct _Point4f -{ - float x; - float y; - float z; - float w; -} Point4f; - -static void -init_matrix_rows (const graphene_matrix_t *matrix, - unsigned int n_rows, - graphene_vec4_t *rows) -{ - graphene_matrix_t m; - unsigned int i; - - graphene_matrix_transpose (matrix, &m); - - for (i = 0; i < n_rows; i++) - graphene_matrix_get_row (&m, i, &rows[i]); -} - -static void -transform_points_f2 (const graphene_matrix_t *matrix, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - graphene_vec4_t rows[3]; - int i; - - init_matrix_rows (matrix, G_N_ELEMENTS (rows), rows); - - for (i = 0; i < n_points; i++) - { - Point2f p = *(Point2f *)((uint8_t *)points_in + i * stride_in); - Point3f *o = (Point3f *)((uint8_t *)points_out + i * stride_out); - graphene_vec4_t point; - - graphene_vec4_init (&point, p.x, p.y, 0.f, 1.f); - - o->x = graphene_vec4_dot (&rows[0], &point); - o->y = graphene_vec4_dot (&rows[1], &point); - o->z = graphene_vec4_dot (&rows[2], &point); - } -} - -static void -project_points_f2 (const graphene_matrix_t *matrix, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - graphene_vec4_t rows[4]; - int i; - - init_matrix_rows (matrix, G_N_ELEMENTS (rows), rows); - - for (i = 0; i < n_points; i++) - { - Point2f p = *(Point2f *)((uint8_t *)points_in + i * stride_in); - Point4f *o = (Point4f *)((uint8_t *)points_out + i * stride_out); - graphene_vec4_t point; - - graphene_vec4_init (&point, p.x, p.y, 0.f, 1.f); - - o->x = graphene_vec4_dot (&rows[0], &point); - o->y = graphene_vec4_dot (&rows[1], &point); - o->z = graphene_vec4_dot (&rows[2], &point); - o->w = graphene_vec4_dot (&rows[3], &point); - } -} - -static void -transform_points_f3 (const graphene_matrix_t *matrix, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - graphene_vec4_t rows[3]; - int i; - - init_matrix_rows (matrix, G_N_ELEMENTS (rows), rows); - - for (i = 0; i < n_points; i++) - { - Point3f p = *(Point3f *)((uint8_t *)points_in + i * stride_in); - Point3f *o = (Point3f *)((uint8_t *)points_out + i * stride_out); - graphene_vec4_t point; - - graphene_vec4_init (&point, p.x, p.y, p.z, 1.f); - - o->x = graphene_vec4_dot (&rows[0], &point); - o->y = graphene_vec4_dot (&rows[1], &point); - o->z = graphene_vec4_dot (&rows[2], &point); - } -} - -static void -project_points_f3 (const graphene_matrix_t *matrix, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - graphene_vec4_t rows[4]; - int i; - - init_matrix_rows (matrix, G_N_ELEMENTS (rows), rows); - - for (i = 0; i < n_points; i++) - { - Point3f p = *(Point3f *)((uint8_t *)points_in + i * stride_in); - Point4f *o = (Point4f *)((uint8_t *)points_out + i * stride_out); - graphene_vec4_t point; - - graphene_vec4_init (&point, p.x, p.y, p.z, 1.f); - - o->x = graphene_vec4_dot (&rows[0], &point); - o->y = graphene_vec4_dot (&rows[1], &point); - o->z = graphene_vec4_dot (&rows[2], &point); - o->w = graphene_vec4_dot (&rows[3], &point); - } -} - -static void -project_points_f4 (const graphene_matrix_t *matrix, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - graphene_vec4_t rows[4]; - int i; - - init_matrix_rows (matrix, G_N_ELEMENTS (rows), rows); - - for (i = 0; i < n_points; i++) - { - Point4f p = *(Point4f *)((uint8_t *)points_in + i * stride_in); - Point4f *o = (Point4f *)((uint8_t *)points_out + i * stride_out); - graphene_vec4_t point; - - graphene_vec4_init (&point, p.x, p.y, p.z, p.w); - - o->x = graphene_vec4_dot (&rows[0], &point); - o->y = graphene_vec4_dot (&rows[1], &point); - o->z = graphene_vec4_dot (&rows[2], &point); - o->w = graphene_vec4_dot (&rows[3], &point); - } -} - -void -cogl_graphene_matrix_project_point (const graphene_matrix_t *matrix, - float *x, - float *y, - float *z, - float *w) -{ - graphene_vec4_t p; - - graphene_vec4_init (&p, *x, *y, *z, *w); - graphene_matrix_transform_vec4 (matrix, &p, &p); - - *x = graphene_vec4_get_x (&p); - *y = graphene_vec4_get_y (&p); - *z = graphene_vec4_get_z (&p); - *w = graphene_vec4_get_w (&p); -} - -void -cogl_graphene_matrix_transform_points (const graphene_matrix_t *matrix, - int n_components, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - /* The results of transforming always have three components... */ - g_return_if_fail (stride_out >= sizeof (Point3f)); - - if (n_components == 2) - { - transform_points_f2 (matrix, - stride_in, points_in, - stride_out, points_out, - n_points); - } - else - { - g_return_if_fail (n_components == 3); - - transform_points_f3 (matrix, - stride_in, points_in, - stride_out, points_out, - n_points); - } -} - -void -cogl_graphene_matrix_project_points (const graphene_matrix_t *matrix, - int n_components, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - if (n_components == 2) - { - project_points_f2 (matrix, - stride_in, points_in, - stride_out, points_out, - n_points); - } - else if (n_components == 3) - { - project_points_f3 (matrix, - stride_in, points_in, - stride_out, points_out, - n_points); - } - else - { - g_return_if_fail (n_components == 4); - - project_points_f4 (matrix, - stride_in, points_in, - stride_out, points_out, - n_points); - } -} diff --git a/mutter/cogl/cogl/cogl-graphene.h b/mutter/cogl/cogl/cogl-graphene.h deleted file mode 100644 index c24f8b1..0000000 --- a/mutter/cogl/cogl/cogl-graphene.h +++ /dev/null @@ -1,168 +0,0 @@ -/* cogl-graphene.h - * - * Copyright 2020 Georges Basile Stavracas Neto - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - * - */ - -#pragma once - -#include "cogl/cogl-macros.h" -#include "cogl/cogl-types.h" - -#include - -#include - -G_BEGIN_DECLS - - -/** - * cogl_graphene_matrix_project_point: - * @matrix: A 4x4 transformation matrix - * @x: (inout): The X component of your points position - * @y: (inout): The Y component of your points position - * @z: (inout): The Z component of your points position - * @w: (inout): The W component of your points position - * - * Transforms a point whose position is given and returned as four float - * components. - */ -COGL_EXPORT void -cogl_graphene_matrix_project_point (const graphene_matrix_t *matrix, - float *x, - float *y, - float *z, - float *w); - -/** - * cogl_graphene_matrix_transform_points: - * @matrix: A transformation matrix - * @n_components: The number of position components for each input point. - * (either 2 or 3) - * @stride_in: The stride in bytes between input points. - * @points_in: A pointer to the first component of the first input point. - * @stride_out: The stride in bytes between output points. - * @points_out: A pointer to the first component of the first output point. - * @n_points: The number of points to transform. - * - * Transforms an array of input points and writes the result to - * another array of output points. The input points can either have 2 - * or 3 components each. The output points always have 3 components. - * The output array can simply point to the input array to do the - * transform in-place. - * - * If you need to transform 4 component points see - * cogl_graphene_matrix_project_points(). - * - * Here's an example with differing input/output strides: - * ```c - * typedef struct { - * float x,y; - * uint8_t r,g,b,a; - * float s,t,p; - * } MyInVertex; - * typedef struct { - * uint8_t r,g,b,a; - * float x,y,z; - * } MyOutVertex; - * MyInVertex vertices[N_VERTICES]; - * MyOutVertex results[N_VERTICES]; - * graphene_matrix_t matrix; - * - * my_load_vertices (vertices); - * my_get_matrix (&matrix); - * - * cogl_graphene_matrix_transform_points (&matrix, - * 2, - * sizeof (MyInVertex), - * &vertices[0].x, - * sizeof (MyOutVertex), - * &results[0].x, - * N_VERTICES); - * ``` - */ -COGL_EXPORT void -cogl_graphene_matrix_transform_points (const graphene_matrix_t *matrix, - int n_components, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points); - -/** - * cogl_graphene_matrix_project_points: - * @matrix: A projection matrix - * @n_components: The number of position components for each input point. - * (either 2, 3 or 4) - * @stride_in: The stride in bytes between input points. - * @points_in: A pointer to the first component of the first input point. - * @stride_out: The stride in bytes between output points. - * @points_out: A pointer to the first component of the first output point. - * @n_points: The number of points to transform. - * - * Projects an array of input points and writes the result to another - * array of output points. The input points can either have 2, 3 or 4 - * components each. The output points always have 4 components (known - * as homogeneous coordinates). The output array can simply point to - * the input array to do the transform in-place. - * - * Here's an example with differing input/output strides: - * ```c - * typedef struct { - * float x,y; - * uint8_t r,g,b,a; - * float s,t,p; - * } MyInVertex; - * typedef struct { - * uint8_t r,g,b,a; - * float x,y,z; - * } MyOutVertex; - * MyInVertex vertices[N_VERTICES]; - * MyOutVertex results[N_VERTICES]; - * graphene_matrix_t matrix; - * - * my_load_vertices (vertices); - * my_get_matrix (&matrix); - * - * cogl_graphene_matrix_project_points (&matrix, - * 2, - * sizeof (MyInVertex), - * &vertices[0].x, - * sizeof (MyOutVertex), - * &results[0].x, - * N_VERTICES); - * ``` - */ -COGL_EXPORT void -cogl_graphene_matrix_project_points (const graphene_matrix_t *matrix, - int n_components, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-half-float.c b/mutter/cogl/cogl/cogl-half-float.c deleted file mode 100644 index 26c3660..0000000 --- a/mutter/cogl/cogl/cogl-half-float.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * Copyright 2015 Philip Taylor - * Copyright 2018 Advanced Micro Devices, Inc. - * Copyright (C) 2018-2019 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -/* This file comes from half_float.c in mesa. */ - -#include "config.h" - -#include - -#if defined(__SSE__) || \ - (defined(_M_IX86_FP) && (_M_IX86_FP >= 1)) || \ - (defined(_M_X64) && !defined(_M_ARM64EC)) -#include -#include -#endif - -#include "cogl/cogl-half-float.h" -#include "cogl/cogl-soft-float.h" - -typedef union -{ - float f; - int32_t i; - uint32_t u; -} FloatInt; - -/** - * \brief Rounds \c x to the nearest integer, with ties to the even integer, - * and returns the value as a long int. - */ -static inline long -cogl_lroundevenf (float x) -{ -#if defined(__SSE__) || \ - (defined(_M_IX86_FP) && (_M_IX86_FP >= 1)) || \ - (defined(_M_X64) && !defined(_M_ARM64EC)) -#if LONG_MAX == INT64_MAX - return _mm_cvtss_si64 (_mm_load_ss (&x)); -#elif LONG_MAX == INT32_MAX - return _mm_cvtss_si32 (_mm_load_ss (&x)); -#else -#error "Unsupported long size" -#endif -#else - return lrintf (x); -#endif -} - -/** - * Convert a 4-byte float to a 2-byte half float. - * - * Not all float32 values can be represented exactly as a float16 value. We - * round such intermediate float32 values to the nearest float16. When the - * float32 lies exactly between to float16 values, we round to the one with - * an even mantissa. - * - * This rounding behavior has several benefits: - * - It has no sign bias. - * - * - It reproduces the behavior of real hardware: opcode F32TO16 in Intel's - * GPU ISA. - * - * - By reproducing the behavior of the GPU (at least on Intel hardware), - * compile-time evaluation of constant packHalf2x16 GLSL expressions will - * result in the same value as if the expression were executed on the GPU. - */ -uint16_t -cogl_float_to_half_slow (float val) -{ - const FloatInt fi = {val}; - const int flt_m = fi.i & 0x7fffff; - const int flt_e = (fi.i >> 23) & 0xff; - const int flt_s = (fi.i >> 31) & 0x1; - int s, e, m = 0; - uint16_t result; - - /* sign bit */ - s = flt_s; - - /* handle special cases */ - if ((flt_e == 0) && (flt_m == 0)) - { - /* zero */ - /* m = 0; - already set */ - e = 0; - } - else if ((flt_e == 0) && (flt_m != 0)) - { - /* denorm -- denorm float maps to 0 half */ - /* m = 0; - already set */ - e = 0; - } - else if ((flt_e == 0xff) && (flt_m == 0)) - { - /* infinity */ - /* m = 0; - already set */ - e = 31; - } - else if ((flt_e == 0xff) && (flt_m != 0)) - { - /* Retain the top bits of a NaN to make sure that the quiet/signaling - * status stays the same. - */ - m = flt_m >> 13; - if (!m) - m = 1; - e = 31; - } - else { - /* regular number */ - const int new_exp = flt_e - 127; - if (new_exp < -14) - { - /* The float32 lies in the range (0.0, min_normal16) and is rounded - * to a nearby float16 value. The result will be either zero, subnormal, - * or normal. - */ - e = 0; - m = cogl_lroundevenf ((1 << 24) * fabsf (fi.f)); - } - else if (new_exp > 15) - { - /* map this value to infinity */ - /* m = 0; - already set */ - e = 31; - } - else { - /* The float32 lies in the range - * [min_normal16, max_normal16 + max_step16) - * and is rounded to a nearby float16 value. The result will be - * either normal or infinite. - */ - e = new_exp + 15; - m = cogl_lroundevenf (flt_m / (float) (1 << 13)); - } - } - - g_assert (0 <= m && m <= 1024); - if (m == 1024) - { - /* The float32 was rounded upwards into the range of the next exponent, - * so bump the exponent. This correctly handles the case where f32 - * should be rounded up to float16 infinity. - */ - ++e; - m = 0; - } - - result = (s << 15) | (e << 10) | m; - return result; -} - -uint16_t -cogl_float_to_float16_rtz_slow (float val) -{ - return cogl_float_to_half_rtz_slow (val); -} - -/** - * Convert a 2-byte half float to a 4-byte float. - * Based on code from: - * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html - */ -float -cogl_half_to_float_slow (uint16_t val) -{ - FloatInt infnan; - FloatInt magic; - FloatInt f32; - - infnan.u = 0x8f << 23; - infnan.f = 65536.0f; - magic.u = 0xef << 23; - - /* Exponent / Mantissa */ - f32.u = (val & 0x7fff) << 13; - - /* Adjust */ - f32.f *= magic.f; - /* XXX: The magic mul relies on denorms being available */ - - /* Inf / NaN */ - if (f32.f >= infnan.f) - f32.u |= 0xff << 23; - - /* Sign */ - f32.u |= (uint32_t)(val & 0x8000) << 16; - - return f32.f; -} - -/** - * Convert 0.0 to 0x00, 1.0 to 0xff. - * Values outside the range [0.0, 1.0] will give undefined results. - */ -uint8_t cogl_half_to_unorm8 (uint16_t val) -{ - const int m = val & 0x3ff; - const int e = (val >> 10) & 0x1f; - const int s = (val >> 15) & 0x1; - - /* v = round_to_nearest (1.mmmmmmmmmm * 2^(e-15) * 255) - * = round_to_nearest ((1.mmmmmmmmmm * 255) * 2^(e-15)) - * = round_to_nearest ((1mmmmmmmmmm * 255) * 2^(e-25)) - * = round_to_zero ((1mmmmmmmmmm * 255) * 2^(e-25) + 0.5) - * = round_to_zero (((1mmmmmmmmmm * 255) * 2^(e-24) + 1) / 2) - * - * This happens to give the correct answer for zero/subnormals too - */ - g_assert (s == 0 && val <= FP16_ONE); /* check 0 <= this <= 1 */ - /* (implies e <= 15, which means the bit-shifts below are safe) */ - - uint32_t v = ((1 << 10) | m) * 255; - v = ((v >> (24 - e)) + 1) >> 1; - return v; -} - -/** - * Takes a uint16_t, divides by 65536, converts the infinite-precision - * result to fp16 with round-to-zero. Used by the ASTC decoder. - */ -uint16_t cogl_uint16_div_64k_to_half (uint16_t v) -{ - /* Zero or subnormal. Set the mantissa to (v << 8) and return. */ - if (v < 4) - return v << 8; - - /* Count the leading 0s in the uint16_t */ - int n = __builtin_clz (v) - 16; - - /* Shift the mantissa up so bit 16 is the hidden 1 bit, - * mask it off, then shift back down to 10 bits - */ - int m = (((uint32_t)v << (n + 1)) & 0xffff ) >> 6; - - /* (0{n} 1 X{15-n}) * 2^-16 - * = 1.X * 2^(15-n-16) - * = 1.X * 2^(14-n - 15) - * which is the FP16 form with e = 14 - n - */ - int e = 14 - n; - - g_assert (e >= 1 && e <= 30); - g_assert (m >= 0 && m < 0x400); - - return (e << 10) | m; -} diff --git a/mutter/cogl/cogl/cogl-half-float.h b/mutter/cogl/cogl/cogl-half-float.h deleted file mode 100644 index cee4374..0000000 --- a/mutter/cogl/cogl/cogl-half-float.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * Copyright (C) 2018-2019 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -/* This source file is originally from Mesa (src/util/half_float.h). */ - -#ifndef COGL_HALF_FLOAT_H -#define COGL_HALF_FLOAT_H - -#include "cogl/cogl-types.h" - -#include -#include - -#include "cogl/cogl-cpu-caps.h" -#include "cogl/cogl-soft-float.h" - -#ifdef __x86_64 -#include -#endif - -#define FP16_ONE ((uint16_t) 0x3c00) -#define FP16_ZERO ((uint16_t) 0) - -COGL_EXPORT -uint16_t cogl_float_to_half_slow (float val); - -COGL_EXPORT -float cogl_half_to_float_slow (uint16_t val); - -COGL_EXPORT -uint8_t cogl_half_to_unorm8 (uint16_t v); - -COGL_EXPORT -uint16_t cogl_uint16_div_64k_to_half (uint16_t v); - -COGL_EXPORT -uint16_t cogl_float_to_float16_rtz_slow (float val); - -static inline uint16_t -cogl_float_to_half (float val) -{ -#ifdef __x86_64 - if (cogl_cpu_has_cap (COGL_CPU_CAP_F16C)) - { - __m128 in = {val}; - __m128i out; - - /* $0 = round to nearest */ - __asm volatile ("vcvtps2ph $0, %1, %0" : "=v" (out) : "v" (in)); - return out[0]; - } -#endif - return cogl_float_to_half_slow (val); -} - -static inline float -cogl_half_to_float (uint16_t val) -{ -#ifdef __x86_64 - if (cogl_cpu_has_cap (COGL_CPU_CAP_F16C)) - { - __m128i in = {val}; - __m128 out; - - __asm volatile ("vcvtph2ps %1, %0" : "=v" (out) : "v" (in)); - return out[0]; - } -#endif - return cogl_half_to_float_slow (val); -} - -static inline uint16_t -cogl_float_to_float16_rtz (float val) -{ -#ifdef __x86_64 - if (cogl_cpu_has_cap (COGL_CPU_CAP_F16C)) - { - __m128 in = {val}; - __m128i out; - - /* $3 = round towards zero (truncate) */ - __asm volatile ("vcvtps2ph $3, %1, %0" : "=v" (out) : "v" (in)); - return out[0]; - } -#endif - return cogl_float_to_float16_rtz_slow (val); -} - -static inline uint16_t -cogl_float_to_float16_rtne (float val) -{ - return cogl_float_to_half (val); -} - -static inline gboolean -cogl_half_is_negative (uint16_t h) -{ - return !!(h & 0x8000); -} - -#endif /* COGL_HALF_FLOAT_H */ diff --git a/mutter/cogl/cogl/cogl-i18n-private.h b/mutter/cogl/cogl/cogl-i18n-private.h deleted file mode 100644 index 8d3edd4..0000000 --- a/mutter/cogl/cogl/cogl-i18n-private.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include - -#define _(X) X -#define N_(X) X diff --git a/mutter/cogl/cogl/cogl-index-buffer-private.h b/mutter/cogl/cogl/cogl-index-buffer-private.h deleted file mode 100644 index 4dfd737..0000000 --- a/mutter/cogl/cogl/cogl-index-buffer-private.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-buffer-private.h" - -struct _CoglIndexBuffer -{ - CoglBuffer parent_instance; -}; - -struct _CoglIndexBufferClass -{ - CoglBufferClass parent_class; -}; diff --git a/mutter/cogl/cogl/cogl-index-buffer.c b/mutter/cogl/cogl/cogl-index-buffer.c deleted file mode 100644 index 1e43094..0000000 --- a/mutter/cogl/cogl/cogl-index-buffer.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-indices.h" -#include "cogl/cogl-indices-private.h" -#include "cogl/cogl-context-private.h" - -G_DEFINE_FINAL_TYPE (CoglIndexBuffer, cogl_index_buffer, COGL_TYPE_BUFFER) - -static void -cogl_index_buffer_class_init (CoglIndexBufferClass *klass) -{ -} - -static void -cogl_index_buffer_init (CoglIndexBuffer *buffer) -{ -} - -/* XXX: Unlike the wiki design this just takes a size. A single - * indices buffer should be able to contain multiple ranges of indices - * which the wiki design doesn't currently consider. */ -CoglIndexBuffer * -cogl_index_buffer_new (CoglContext *context, - size_t bytes) -{ - CoglIndexBuffer *indices; - - indices = g_object_new (COGL_TYPE_INDEX_BUFFER, - "context", context, - "size", (uint64_t) bytes, - "default-target", COGL_BUFFER_BIND_TARGET_INDEX_BUFFER, - "update-hint", COGL_BUFFER_UPDATE_HINT_STATIC, - NULL); - return indices; -} diff --git a/mutter/cogl/cogl/cogl-index-buffer.h b/mutter/cogl/cogl/cogl-index-buffer.h deleted file mode 100644 index ec74183..0000000 --- a/mutter/cogl/cogl/cogl-index-buffer.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-context.h" - -#include - -G_BEGIN_DECLS - -/** - * CoglIndexBuffer: - * - *Functions for creating and manipulating vertex indices. - */ -#define COGL_TYPE_INDEX_BUFFER (cogl_index_buffer_get_type ()) -#define COGL_INDEX_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_INDEX_BUFFER, CoglIndexBuffer)) -#define COGL_INDEX_BUFFER_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_INDEX_BUFFER, CoglIndexBuffer const)) -#define COGL_INDEX_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_TYPE_INDEX_BUFFER, CoglIndexBufferClass)) -#define COGL_IS_INDEX_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_TYPE_INDEX_BUFFER)) -#define COGL_IS_INDEX_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_TYPE_INDEX_BUFFER)) -#define COGL_INDEX_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COGL_TYPE_INDEX_BUFFER, CoglIndexBufferClass)) - -typedef struct _CoglIndexBufferClass CoglIndexBufferClass; -typedef struct _CoglIndexBuffer CoglIndexBuffer; - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (CoglIndexBuffer, g_object_unref) - -COGL_EXPORT -GType cogl_index_buffer_get_type (void) G_GNUC_CONST; - -/** - * cogl_index_buffer_new: - * @context: A #CoglContext - * @bytes: The number of bytes to allocate for vertex attribute data. - * - * Declares a new #CoglIndexBuffer of @size bytes to contain vertex - * indices. Once declared, data can be set using - * cogl_buffer_set_data() or by mapping it into the application's - * address space using cogl_buffer_map(). - * - * Return value: (transfer full): A newly allocated #CoglIndexBuffer - */ -COGL_EXPORT CoglIndexBuffer * -cogl_index_buffer_new (CoglContext *context, - size_t bytes); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-indices-private.h b/mutter/cogl/cogl/cogl-indices-private.h deleted file mode 100644 index d50c57c..0000000 --- a/mutter/cogl/cogl/cogl-indices-private.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-index-buffer-private.h" -#include "cogl/cogl-types.h" - -struct _CoglIndices -{ - GObject parent_instance; - - CoglIndexBuffer *buffer; - size_t offset; - - CoglIndicesType type; - - int immutable_ref; -}; - -CoglIndices * -_cogl_indices_immutable_ref (CoglIndices *indices); - -void -_cogl_indices_immutable_unref (CoglIndices *indices); diff --git a/mutter/cogl/cogl/cogl-indices.c b/mutter/cogl/cogl/cogl-indices.c deleted file mode 100644 index 55a27b4..0000000 --- a/mutter/cogl/cogl/cogl-indices.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - * Neil Roberts - */ - -#include "config.h" - -#include "cogl/cogl-util.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-indices.h" -#include "cogl/cogl-indices-private.h" -#include "cogl/cogl-index-buffer.h" - -#include - -G_DEFINE_TYPE (CoglIndices, cogl_indices, G_TYPE_OBJECT); - -static void -cogl_indices_dispose (GObject *object) -{ - CoglIndices *indices = COGL_INDICES (object); - - g_object_unref (indices->buffer); - - G_OBJECT_CLASS (cogl_indices_parent_class)->dispose (object); -} - -static void -cogl_indices_init (CoglIndices *indices) -{ -} - -static void -cogl_indices_class_init (CoglIndicesClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = cogl_indices_dispose; -} - -static size_t -sizeof_indices_type (CoglIndicesType type) -{ - switch (type) - { - case COGL_INDICES_TYPE_UNSIGNED_BYTE: - return 1; - case COGL_INDICES_TYPE_UNSIGNED_SHORT: - return 2; - case COGL_INDICES_TYPE_UNSIGNED_INT: - return 4; - } - g_return_val_if_reached (0); -} - -CoglIndices * -cogl_indices_new_for_buffer (CoglIndicesType type, - CoglIndexBuffer *buffer, - size_t offset) -{ - CoglIndices *indices = g_object_new (COGL_TYPE_INDICES, NULL); - - indices->buffer = g_object_ref (buffer); - indices->offset = offset; - - indices->type = type; - - indices->immutable_ref = 0; - - return indices; -} - -CoglIndices * -cogl_indices_new (CoglContext *context, - CoglIndicesType type, - const void *indices_data, - int n_indices) -{ - size_t buffer_bytes = sizeof_indices_type (type) * n_indices; - CoglIndexBuffer *index_buffer = cogl_index_buffer_new (context, buffer_bytes); - CoglBuffer *buffer = COGL_BUFFER (index_buffer); - CoglIndices *indices; - GError *ignore_error = NULL; - - _cogl_buffer_set_data (buffer, - 0, - indices_data, - buffer_bytes, - &ignore_error); - if (ignore_error) - { - g_error_free (ignore_error); - g_object_unref (index_buffer); - return NULL; - } - - indices = cogl_indices_new_for_buffer (type, index_buffer, 0); - g_object_unref (index_buffer); - - return indices; -} - -CoglIndexBuffer * -cogl_indices_get_buffer (CoglIndices *indices) -{ - return indices->buffer; -} - -CoglIndicesType -cogl_indices_get_indices_type (CoglIndices *indices) -{ - g_return_val_if_fail (COGL_IS_INDICES (indices), - COGL_INDICES_TYPE_UNSIGNED_BYTE); - return indices->type; -} - -size_t -cogl_indices_get_offset (CoglIndices *indices) -{ - g_return_val_if_fail (COGL_IS_INDICES (indices), 0); - - return indices->offset; -} - -static void -warn_about_midscene_changes (void) -{ - static gboolean seen = FALSE; - if (!seen) - { - g_warning ("Mid-scene modification of indices has " - "undefined results\n"); - seen = TRUE; - } -} - -void -cogl_indices_set_offset (CoglIndices *indices, - size_t offset) -{ - g_return_if_fail (COGL_IS_INDICES (indices)); - - if (G_UNLIKELY (indices->immutable_ref)) - warn_about_midscene_changes (); - - indices->offset = offset; -} - -CoglIndices * -_cogl_indices_immutable_ref (CoglIndices *indices) -{ - g_return_val_if_fail (COGL_IS_INDICES (indices), NULL); - - indices->immutable_ref++; - _cogl_buffer_immutable_ref (COGL_BUFFER (indices->buffer)); - return indices; -} - -void -_cogl_indices_immutable_unref (CoglIndices *indices) -{ - g_return_if_fail (COGL_IS_INDICES (indices)); - g_return_if_fail (indices->immutable_ref > 0); - - indices->immutable_ref--; - _cogl_buffer_immutable_unref (COGL_BUFFER (indices->buffer)); -} - -CoglIndices * -cogl_get_rectangle_indices (CoglContext *ctx, int n_rectangles) -{ - int n_indices = n_rectangles * 6; - - /* Check if the largest index required will fit in a byte array... */ - if (n_indices <= 256 / 4 * 6) - { - /* Generate the byte array if we haven't already */ - if (ctx->rectangle_byte_indices == NULL) - { - uint8_t *byte_array = g_malloc (256 / 4 * 6 * sizeof (uint8_t)); - uint8_t *p = byte_array; - int i, vert_num = 0; - - for (i = 0; i < 256 / 4; i++) - { - *(p++) = vert_num + 0; - *(p++) = vert_num + 1; - *(p++) = vert_num + 2; - *(p++) = vert_num + 0; - *(p++) = vert_num + 2; - *(p++) = vert_num + 3; - vert_num += 4; - } - - ctx->rectangle_byte_indices - = cogl_indices_new (ctx, - COGL_INDICES_TYPE_UNSIGNED_BYTE, - byte_array, - 256 / 4 * 6); - - g_free (byte_array); - } - - return ctx->rectangle_byte_indices; - } - else - { - if (ctx->rectangle_short_indices_len < n_indices) - { - uint16_t *short_array; - uint16_t *p; - int i, vert_num = 0; - - if (ctx->rectangle_short_indices != NULL) - g_object_unref (ctx->rectangle_short_indices); - /* Pick a power of two >= MAX (512, n_indices) */ - if (ctx->rectangle_short_indices_len == 0) - ctx->rectangle_short_indices_len = 512; - while (ctx->rectangle_short_indices_len < n_indices) - ctx->rectangle_short_indices_len *= 2; - - /* Over-allocate to generate a whole number of quads */ - p = short_array = g_malloc ((ctx->rectangle_short_indices_len - + 5) / 6 * 6 - * sizeof (uint16_t)); - - /* Fill in the complete quads */ - for (i = 0; i < ctx->rectangle_short_indices_len; i += 6) - { - *(p++) = vert_num + 0; - *(p++) = vert_num + 1; - *(p++) = vert_num + 2; - *(p++) = vert_num + 0; - *(p++) = vert_num + 2; - *(p++) = vert_num + 3; - vert_num += 4; - } - - ctx->rectangle_short_indices - = cogl_indices_new (ctx, - COGL_INDICES_TYPE_UNSIGNED_SHORT, - short_array, - ctx->rectangle_short_indices_len); - - g_free (short_array); - } - - return ctx->rectangle_short_indices; - } -} - diff --git a/mutter/cogl/cogl/cogl-indices.h b/mutter/cogl/cogl/cogl-indices.h deleted file mode 100644 index 5712416..0000000 --- a/mutter/cogl/cogl/cogl-indices.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -/* We forward declare the CoglIndices type here to avoid some circular - * dependency issues with the following headers. - */ -typedef struct _CoglIndices CoglIndices; - -#include "cogl/cogl-index-buffer.h" - -#include - -G_BEGIN_DECLS - -/** - * CoglIndices: - * - * Describe vertex indices stored in a #CoglIndexBuffer. - * - * Indices allow you to avoid duplicating vertices in your vertex data - * by virtualizing your data and instead providing a sequence of index - * values that tell the GPU which data should be used for each vertex. - * - * If the GPU is given a sequence of indices it doesn't simply walk - * through each vertex of your data in order it will instead walk - * through the indices which can provide random access to the - * underlying data. - * - * Since it's very common to have duplicate vertices when describing a - * shape as a list of triangles it can often be a significant space - * saving to describe geometry using indices. Reducing the size of - * your models can make it cheaper to map them into the GPU by - * reducing the demand on memory bandwidth and may help to make better - * use of your GPUs internal vertex caching. - * - * For example, to describe a quadrilateral as 2 triangles for the GPU - * you could either provide data with 6 vertices or instead with - * indices you can provide vertex data for just 4 vertices and an - * index buffer that specifies the 6 vertices by indexing the shared - * vertices multiple times. - * - * ```c - * CoglVertexP2 quad_vertices[] = { - * {x0, y0}, //0 = top left - * {x1, y1}, //1 = bottom left - * {x2, y2}, //2 = bottom right - * {x3, y3}, //3 = top right - * }; - * //tell the gpu how to interpret the quad as 2 triangles... - * unsigned char indices[] = {0, 1, 2, 0, 2, 3}; - * ``` - * - * Even in the above illustration we see a saving of 10bytes for one - * quad compared to having data for 6 vertices and no indices but if - * you need to draw 100s or 1000s of quads then its really quite - * significant. - * - * Something else to consider is that often indices can be defined - * once and remain static while the vertex data may change for - * animations perhaps. That means you may be able to ignore the - * negligible cost of mapping your indices into the GPU if they don't - * ever change. - * - * The above illustration is actually a good example of static indices - * because it's really common that developers have quad mesh data that - * they need to display and we know exactly what that indices array - * needs to look like depending on the number of quads that need to be - * drawn. It doesn't matter how the quads might be animated and - * changed the indices will remain the same. Cogl even has a utility - * (cogl_get_rectangle_indices()) to get access to re-useable indices - * for drawing quads as above. - */ - -#define COGL_TYPE_INDICES (cogl_indices_get_type ()) - -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglIndices, cogl_indices, - COGL, INDICES, GObject) - -COGL_EXPORT CoglIndices * -cogl_indices_new (CoglContext *context, - CoglIndicesType type, - const void *indices_data, - int n_indices); - -COGL_EXPORT CoglIndices * -cogl_indices_new_for_buffer (CoglIndicesType type, - CoglIndexBuffer *buffer, - size_t offset); - -/** - * cogl_indices_get_buffer: - * - * Returns: (transfer none): a #CoglIndexBuffer - */ -COGL_EXPORT CoglIndexBuffer * -cogl_indices_get_buffer (CoglIndices *indices); - -COGL_EXPORT CoglIndicesType -cogl_indices_get_indices_type (CoglIndices *indices); - -COGL_EXPORT size_t -cogl_indices_get_offset (CoglIndices *indices); - -COGL_EXPORT void -cogl_indices_set_offset (CoglIndices *indices, - size_t offset); - -/** - * cogl_get_rectangle_indices: - * - * Returns: (transfer none): a #CoglIndices - */ -COGL_EXPORT CoglIndices * -cogl_get_rectangle_indices (CoglContext *context, int n_rectangles); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-journal-private.h b/mutter/cogl/cogl/cogl-journal-private.h deleted file mode 100644 index 4240d19..0000000 --- a/mutter/cogl/cogl/cogl-journal-private.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-texture.h" -#include "cogl/cogl-clip-stack.h" -#include "cogl/cogl-fence-private.h" - -#define COGL_JOURNAL_VBO_POOL_SIZE 8 - -typedef struct _CoglJournal -{ - GObject parent_instance; - - /* A pointer the framebuffer that is using this journal. This is - only valid when the journal is not empty. It *does* take a - reference on the framebuffer. Although this creates a circular - reference, the framebuffer has special code to handle the case - where the journal is the only thing holding a reference and it - will cause the journal to flush */ - CoglFramebuffer *framebuffer; - - GArray *entries; - GArray *vertices; - size_t needed_vbo_len; - - /* A pool of attribute buffers is used so that we can avoid repeatedly - reallocating buffers. Only one of these buffers at a time will be - used by Cogl but we keep more than one alive anyway in case the - GL driver is internally using the buffer and it would have to - allocate a new one when we start writing to it */ - CoglAttributeBuffer *vbo_pool[COGL_JOURNAL_VBO_POOL_SIZE]; - /* The next vbo to use from the pool. We just cycle through them in - order */ - unsigned int next_vbo_in_pool; - - int fast_read_pixel_count; - - CoglList pending_fences; - -} CoglJournal; - -#define COGL_TYPE_JOURNAL (cogl_journal_get_type ()) - -G_DECLARE_FINAL_TYPE (CoglJournal, - cogl_journal, - COGL, - JOURNAL, - GObject) - -/* To improve batching of geometry when submitting vertices to OpenGL we - * log the texture rectangles we want to draw to a journal, so when we - * later flush the journal we aim to batch data, and gl draw calls. */ -typedef struct _CoglJournalEntry -{ - CoglPipeline *pipeline; - CoglMatrixEntry *modelview_entry; - CoglClipStack *clip_stack; - float viewport[4]; - gboolean dither_enabled; - /* Offset into ctx->logged_vertices */ - size_t array_offset; - int n_layers; -} CoglJournalEntry; - -CoglJournal * -_cogl_journal_new (CoglFramebuffer *framebuffer); - -void -_cogl_journal_log_quad (CoglJournal *journal, - const float *position, - CoglPipeline *pipeline, - int n_layers, - CoglTexture *layer0_override_texture, - const float *tex_coords, - unsigned int tex_coords_len); - -void -_cogl_journal_flush (CoglJournal *journal); - -void -_cogl_journal_discard (CoglJournal *journal); - -gboolean -_cogl_journal_all_entries_within_bounds (CoglJournal *journal, - float clip_x0, - float clip_y0, - float clip_x1, - float clip_y1); - -gboolean -_cogl_journal_try_read_pixel (CoglJournal *journal, - int x, - int y, - CoglBitmap *bitmap, - gboolean *found_intersection); diff --git a/mutter/cogl/cogl/cogl-journal.c b/mutter/cogl/cogl/cogl-journal.c deleted file mode 100644 index fa67358..0000000 --- a/mutter/cogl/cogl/cogl-journal.c +++ /dev/null @@ -1,1919 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include "cogl/cogl-debug.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-graphene.h" -#include "cogl/cogl-journal-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-texture-2d-private.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-profile.h" -#include "cogl/cogl-attribute-private.h" -#include "cogl/cogl-point-in-poly-private.h" -#include "cogl/cogl-trace.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl1-context.h" - -#include -#include -#include - -/* XXX NB: - * The data logged in logged_vertices is formatted as follows: - * - * Per entry: - * 4 RGBA GLubytes for the color - * 2 floats for the top left position - * 2 * n_layers floats for the top left texture coordinates - * 2 floats for the bottom right position - * 2 * n_layers floats for the bottom right texture coordinates - */ -#define GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS(N_LAYERS) \ - (N_LAYERS * 2 + 2) - -/* XXX NB: - * Once in the vertex array, the journal's vertex data is arranged as follows: - * 4 vertices per quad: - * 2 or 3 GLfloats per position (3 when doing software transforms) - * 4 RGBA GLubytes, - * 2 GLfloats per tex coord * n_layers - * - * Where n_layers corresponds to the number of pipeline layers enabled - * - * To avoid frequent changes in the stride of our vertex data we always pad - * n_layers to be >= 2 - * - * There will be four vertices per quad in the vertex array - * - * When we are transforming quads in software we need to also track the z - * coordinate of transformed vertices. - * - * So for a given number of layers this gets the stride in 32bit words: - */ -#define SW_TRANSFORM (!(COGL_DEBUG_ENABLED \ - (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))) -#define POS_STRIDE (SW_TRANSFORM ? 3 : 2) /* number of 32bit words */ -#define N_POS_COMPONENTS POS_STRIDE -#define COLOR_STRIDE 1 /* number of 32bit words */ -#define TEX_STRIDE 2 /* number of 32bit words */ -#define MIN_LAYER_PADDING 2 -#define GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS(N_LAYERS) \ - (POS_STRIDE + COLOR_STRIDE + \ - TEX_STRIDE * (N_LAYERS < MIN_LAYER_PADDING ? MIN_LAYER_PADDING : N_LAYERS)) - -/* If a batch is longer than this threshold then we'll assume it's not - worth doing software clipping and it's cheaper to program the GPU - to do the clip */ -#define COGL_JOURNAL_HARDWARE_CLIP_THRESHOLD 8 - -typedef struct _CoglJournalFlushState -{ - CoglContext *ctx; - - CoglJournal *journal; - - CoglAttributeBuffer *attribute_buffer; - GArray *attributes; - int current_attribute; - - size_t stride; - size_t array_offset; - GLuint current_vertex; - - CoglIndices *indices; - size_t indices_type_size; - - CoglPipeline *pipeline; -} CoglJournalFlushState; - -typedef void (*CoglJournalBatchCallback) (CoglJournalEntry *start, - int n_entries, - void *data); -typedef gboolean (*CoglJournalBatchTest) (CoglJournalEntry *entry0, - CoglJournalEntry *entry1); - -G_DEFINE_TYPE (CoglJournal, cogl_journal, G_TYPE_OBJECT); - -static void -cogl_journal_dispose (GObject *object) -{ - CoglJournal *journal = COGL_JOURNAL (object); - int i; - - if (journal->entries) - g_array_free (journal->entries, TRUE); - if (journal->vertices) - g_array_free (journal->vertices, TRUE); - - for (i = 0; i < COGL_JOURNAL_VBO_POOL_SIZE; i++) - if (journal->vbo_pool[i]) - g_object_unref (journal->vbo_pool[i]); - - G_OBJECT_CLASS (cogl_journal_parent_class)->dispose (object); -} - -static void -cogl_journal_init (CoglJournal *journal) -{ -} - -static void -cogl_journal_class_init (CoglJournalClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = cogl_journal_dispose; -} - -CoglJournal * -_cogl_journal_new (CoglFramebuffer *framebuffer) -{ - CoglJournal *journal = g_object_new (COGL_TYPE_JOURNAL, NULL); - - journal->framebuffer = framebuffer; - journal->entries = g_array_new (FALSE, FALSE, sizeof (CoglJournalEntry)); - journal->vertices = g_array_new (FALSE, FALSE, sizeof (float)); - - _cogl_list_init (&journal->pending_fences); - - return journal; -} - -static void -_cogl_journal_dump_logged_quad (uint8_t *data, int n_layers) -{ - size_t stride = GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS (n_layers); - int i; - - g_print ("n_layers = %d; rgba=0x%02X%02X%02X%02X\n", - n_layers, data[0], data[1], data[2], data[3]); - - data += 4; - - for (i = 0; i < 2; i++) - { - float *v = (float *)data + (i * stride); - int j; - - g_print ("v%d: x = %f, y = %f", i, v[0], v[1]); - - for (j = 0; j < n_layers; j++) - { - float *t = v + 2 + TEX_STRIDE * j; - g_print (", tx%d = %f, ty%d = %f", j, t[0], j, t[1]); - } - g_print ("\n"); - } -} - -static void -_cogl_journal_dump_quad_vertices (uint8_t *data, int n_layers) -{ - size_t stride = GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (n_layers); - int i; - - g_print ("n_layers = %d; stride = %d; pos stride = %d; color stride = %d; " - "tex stride = %d; stride in bytes = %d\n", - n_layers, (int)stride, POS_STRIDE, COLOR_STRIDE, - TEX_STRIDE, (int)stride * 4); - - for (i = 0; i < 4; i++) - { - float *v = (float *)data + (i * stride); - uint8_t *c = data + (POS_STRIDE * 4) + (i * stride * 4); - int j; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED - (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))) - g_print ("v%d: x = %f, y = %f, rgba=0x%02X%02X%02X%02X", - i, v[0], v[1], c[0], c[1], c[2], c[3]); - else - g_print ("v%d: x = %f, y = %f, z = %f, rgba=0x%02X%02X%02X%02X", - i, v[0], v[1], v[2], c[0], c[1], c[2], c[3]); - for (j = 0; j < n_layers; j++) - { - float *t = v + POS_STRIDE + COLOR_STRIDE + TEX_STRIDE * j; - g_print (", tx%d = %f, ty%d = %f", j, t[0], j, t[1]); - } - g_print ("\n"); - } -} - -static void -_cogl_journal_dump_quad_batch (uint8_t *data, int n_layers, int n_quads) -{ - size_t byte_stride = GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (n_layers) * 4; - int i; - - g_print ("_cogl_journal_dump_quad_batch: n_layers = %d, n_quads = %d\n", - n_layers, n_quads); - for (i = 0; i < n_quads; i++) - _cogl_journal_dump_quad_vertices (data + byte_stride * 2 * i, n_layers); -} - -static void -batch_and_call (CoglJournalEntry *entries, - int n_entries, - CoglJournalBatchTest can_batch_callback, - CoglJournalBatchCallback batch_callback, - void *data) -{ - int i; - int batch_len = 1; - CoglJournalEntry *batch_start = entries; - - if (n_entries < 1) - return; - - for (i = 1; i < n_entries; i++) - { - CoglJournalEntry *entry0 = &entries[i - 1]; - CoglJournalEntry *entry1 = entry0 + 1; - - if (can_batch_callback (entry0, entry1)) - { - batch_len++; - continue; - } - - batch_callback (batch_start, batch_len, data); - - batch_start = entry1; - batch_len = 1; - } - - /* The last batch... */ - batch_callback (batch_start, batch_len, data); -} - -static void -_cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - CoglContext *ctx = state->ctx; - CoglFramebuffer *framebuffer = state->journal->framebuffer; - CoglAttribute **attributes; - CoglDrawFlags draw_flags = (COGL_DRAW_SKIP_JOURNAL_FLUSH | - COGL_DRAW_SKIP_PIPELINE_VALIDATION | - COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH); - - COGL_STATIC_TIMER (time_flush_modelview_and_entries, - "flush: pipeline+entries", /* parent */ - "flush: modelview+entries", - "The time spent flushing modelview + entries", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, time_flush_modelview_and_entries); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: modelview batch len = %d\n", batch_len); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))) - _cogl_context_set_current_modelview_entry (ctx, - batch_start->modelview_entry); - - attributes = (CoglAttribute **)state->attributes->data; - - if (!_cogl_pipeline_get_real_blend_enabled (state->pipeline)) - draw_flags |= COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE; - - if (batch_len > 1) - { - CoglVerticesMode mode = COGL_VERTICES_MODE_TRIANGLES; - int first_vertex = state->current_vertex * 6 / 4; - _cogl_framebuffer_draw_indexed_attributes (framebuffer, - state->pipeline, - mode, - first_vertex, - batch_len * 6, - state->indices, - attributes, - state->attributes->len, - draw_flags); - } - else - { - _cogl_framebuffer_draw_attributes (framebuffer, - state->pipeline, - COGL_VERTICES_MODE_TRIANGLE_FAN, - state->current_vertex, 4, - attributes, - state->attributes->len, - draw_flags); - } - - /* DEBUGGING CODE XXX: This path will cause all rectangles to be - * drawn with a coloured outline. Each batch will be rendered with - * the same color. This may e.g. help with debugging texture slicing - * issues, visually seeing what is batched and debugging blending - * issues, plus it looks quite cool. - */ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_RECTANGLES))) - { - static CoglPipeline *outline = NULL; - float color_intensity; - int i; - CoglAttribute *loop_attributes[1]; - CoglColor color; - - if (outline == NULL) - outline = cogl_pipeline_new (ctx); - - /* The least significant three bits represent the three - components so that the order of colours goes red, green, - yellow, blue, magenta, cyan. Black and white are skipped. The - next two bits give four scales of intensity for those colours - in the order 0xff, 0xcc, 0x99, and 0x66. This gives a total - of 24 colours. If there are more than 24 batches on the stage - then it will wrap around */ - color_intensity = (0xff - 0x33 * (ctx->journal_rectangles_color >> 3) ) / 255.0; - cogl_color_init_from_4f (&color, - (ctx->journal_rectangles_color & 1) ? - color_intensity : 0.0, - (ctx->journal_rectangles_color & 2) ? - color_intensity : 0.0, - (ctx->journal_rectangles_color & 4) ? - color_intensity : 0.0, - 1.0); - cogl_pipeline_set_color (outline, &color); - - loop_attributes[0] = attributes[0]; /* we just want the position */ - for (i = 0; i < batch_len; i++) - _cogl_framebuffer_draw_attributes (framebuffer, - outline, - COGL_VERTICES_MODE_LINE_LOOP, - 4 * i + state->current_vertex, 4, - loop_attributes, - 1, - draw_flags); - - /* Go to the next color */ - do - ctx->journal_rectangles_color = ((ctx->journal_rectangles_color + 1) & - ((1 << 5) - 1)); - /* We don't want to use black or white */ - while ((ctx->journal_rectangles_color & 0x07) == 0 - || (ctx->journal_rectangles_color & 0x07) == 0x07); - } - - state->current_vertex += (4 * batch_len); - - COGL_TIMER_STOP (_cogl_uprof_context, time_flush_modelview_and_entries); -} - -static gboolean -compare_entry_modelviews (CoglJournalEntry *entry0, - CoglJournalEntry *entry1) -{ - /* Batch together quads with the same model view matrix */ - return entry0->modelview_entry == entry1->modelview_entry; -} - -/* At this point we have a run of quads that we know have compatible - * pipelines, but they may not all have the same modelview matrix */ -static void -_cogl_journal_flush_pipeline_and_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - COGL_STATIC_TIMER (time_flush_pipeline_entries, - "flush: texcoords+pipeline+entries", /* parent */ - "flush: pipeline+entries", - "The time spent flushing pipeline + entries", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, time_flush_pipeline_entries); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: pipeline batch len = %d\n", batch_len); - - state->pipeline = batch_start->pipeline; - - /* If we haven't transformed the quads in software then we need to also break - * up batches according to changes in the modelview matrix... */ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))) - { - batch_and_call (batch_start, - batch_len, - compare_entry_modelviews, - _cogl_journal_flush_modelview_and_entries, - data); - } - else - _cogl_journal_flush_modelview_and_entries (batch_start, batch_len, data); - - COGL_TIMER_STOP (_cogl_uprof_context, time_flush_pipeline_entries); -} - -static gboolean -compare_entry_pipelines (CoglJournalEntry *entry0, CoglJournalEntry *entry1) -{ - /* batch rectangles using compatible pipelines */ - - if (_cogl_pipeline_equal (entry0->pipeline, - entry1->pipeline, - (COGL_PIPELINE_STATE_ALL & - ~COGL_PIPELINE_STATE_COLOR), - COGL_PIPELINE_LAYER_STATE_ALL)) - return TRUE; - else - return FALSE; -} - -typedef struct _CreateAttributeState -{ - int current; - CoglJournalFlushState *flush_state; -} CreateAttributeState; - -static gboolean -create_attribute_cb (CoglPipeline *pipeline, - int layer_number, - void *user_data) -{ - CreateAttributeState *state = user_data; - CoglJournalFlushState *flush_state = state->flush_state; - CoglAttribute **attribute_entry = - &g_array_index (flush_state->attributes, - CoglAttribute *, - state->current + 2); - const char *names[] = { - "cogl_tex_coord0_in", - "cogl_tex_coord1_in", - "cogl_tex_coord2_in", - "cogl_tex_coord3_in", - "cogl_tex_coord4_in", - "cogl_tex_coord5_in", - "cogl_tex_coord6_in", - "cogl_tex_coord7_in" - }; - char *name; - - /* XXX NB: - * Our journal's vertex data is arranged as follows: - * 4 vertices per quad: - * 2 or 3 floats per position (3 when doing software transforms) - * 4 RGBA bytes, - * 2 floats per tex coord * n_layers - * (though n_layers may be padded; see definition of - * GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS for details) - */ - name = layer_number < 8 ? (char *)names[layer_number] : - g_strdup_printf ("cogl_tex_coord%d_in", layer_number); - - /* XXX: it may be worth having some form of static initializer for - * attributes... */ - *attribute_entry = - cogl_attribute_new (flush_state->attribute_buffer, - name, - flush_state->stride, - flush_state->array_offset + - (POS_STRIDE + COLOR_STRIDE) * 4 + - TEX_STRIDE * 4 * state->current, - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - - if (layer_number >= 8) - g_free (name); - - state->current++; - - return TRUE; -} - -/* Since the stride may not reflect the number of texture layers in use - * (due to padding) we deal with texture coordinate offsets separately - * from vertex and color offsets... */ -static void -_cogl_journal_flush_texcoord_vbo_offsets_and_entries ( - CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - CreateAttributeState create_attrib_state; - int i; - COGL_STATIC_TIMER (time_flush_texcoord_pipeline_entries, - "flush: vbo+texcoords+pipeline+entries", /* parent */ - "flush: texcoords+pipeline+entries", - "The time spent flushing texcoord offsets + pipeline " - "+ entries", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, time_flush_texcoord_pipeline_entries); - - /* NB: attributes 0 and 1 are position and color */ - - for (i = 2; i < state->attributes->len; i++) - g_object_unref (g_array_index (state->attributes, CoglAttribute *, i)); - - g_array_set_size (state->attributes, batch_start->n_layers + 2); - - create_attrib_state.current = 0; - create_attrib_state.flush_state = state; - - cogl_pipeline_foreach_layer (batch_start->pipeline, - create_attribute_cb, - &create_attrib_state); - - batch_and_call (batch_start, - batch_len, - compare_entry_pipelines, - _cogl_journal_flush_pipeline_and_entries, - data); - COGL_TIMER_STOP (_cogl_uprof_context, time_flush_texcoord_pipeline_entries); -} - -static gboolean -compare_entry_layer_numbers (CoglJournalEntry *entry0, CoglJournalEntry *entry1) -{ - if (_cogl_pipeline_layer_numbers_equal (entry0->pipeline, entry1->pipeline)) - return TRUE; - else - return FALSE; -} - -/* At this point we know the stride has changed from the previous batch - * of journal entries */ -static void -_cogl_journal_flush_vbo_offsets_and_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - CoglFramebuffer *framebuffer = state->journal->framebuffer; - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - size_t stride; - int i; - CoglAttribute **attribute_entry; - COGL_STATIC_TIMER (time_flush_vbo_texcoord_pipeline_entries, - "flush: clip+vbo+texcoords+pipeline+entries", /* parent */ - "flush: vbo+texcoords+pipeline+entries", - "The time spent flushing vbo + texcoord offsets + " - "pipeline + entries", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, - time_flush_vbo_texcoord_pipeline_entries); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: vbo offset batch len = %d\n", batch_len); - - /* XXX NB: - * Our journal's vertex data is arranged as follows: - * 4 vertices per quad: - * 2 or 3 GLfloats per position (3 when doing software transforms) - * 4 RGBA GLubytes, - * 2 GLfloats per tex coord * n_layers - * (though n_layers may be padded; see definition of - * GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS for details) - */ - stride = GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (batch_start->n_layers); - stride *= sizeof (float); - state->stride = stride; - - for (i = 0; i < state->attributes->len; i++) - g_object_unref (g_array_index (state->attributes, CoglAttribute *, i)); - - g_array_set_size (state->attributes, 2); - - attribute_entry = &g_array_index (state->attributes, CoglAttribute *, 0); - *attribute_entry = cogl_attribute_new (state->attribute_buffer, - "cogl_position_in", - stride, - state->array_offset, - N_POS_COMPONENTS, - COGL_ATTRIBUTE_TYPE_FLOAT); - - attribute_entry = &g_array_index (state->attributes, CoglAttribute *, 1); - *attribute_entry = - cogl_attribute_new (state->attribute_buffer, - "cogl_color_in", - stride, - state->array_offset + (POS_STRIDE * 4), - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - - state->indices = cogl_get_rectangle_indices (ctx, batch_len); - - /* We only create new Attributes when the stride within the - * AttributeBuffer changes. (due to a change in the number of pipeline - * layers) While the stride remains constant we walk forward through - * the above AttributeBuffer using a vertex offset passed to - * cogl_draw_attributes - */ - state->current_vertex = 0; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_JOURNAL)) && - cogl_has_feature (ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_READ)) - { - uint8_t *verts; - - /* Mapping a buffer for read is probably a really bad thing to - do but this will only happen during debugging so it probably - doesn't matter */ - verts = ((uint8_t *)_cogl_buffer_map (COGL_BUFFER (state->attribute_buffer), - COGL_BUFFER_ACCESS_READ, 0, - NULL) + - state->array_offset); - - _cogl_journal_dump_quad_batch (verts, - batch_start->n_layers, - batch_len); - - cogl_buffer_unmap (COGL_BUFFER (state->attribute_buffer)); - } - - batch_and_call (batch_start, - batch_len, - compare_entry_layer_numbers, - _cogl_journal_flush_texcoord_vbo_offsets_and_entries, - data); - - /* progress forward through the VBO containing all our vertices */ - state->array_offset += (stride * 4 * batch_len); - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_JOURNAL))) - g_print ("new vbo offset = %lu\n", (unsigned long)state->array_offset); - - COGL_TIMER_STOP (_cogl_uprof_context, - time_flush_vbo_texcoord_pipeline_entries); -} - -static gboolean -compare_entry_strides (CoglJournalEntry *entry0, CoglJournalEntry *entry1) -{ - /* Currently the only thing that affects the stride for our vertex arrays - * is the number of pipeline layers. We need to update our VBO offsets - * whenever the stride changes. */ - /* TODO: We should be padding the n_layers == 1 case as if it were - * n_layers == 2 so we can reduce the need to split batches. */ - if (entry0->n_layers == entry1->n_layers || - (entry0->n_layers <= MIN_LAYER_PADDING && - entry1->n_layers <= MIN_LAYER_PADDING)) - return TRUE; - else - return FALSE; -} - -/* At this point we know the batch has a unique clip stack */ -static void -_cogl_journal_flush_clip_stacks_and_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - CoglFramebuffer *framebuffer = state->journal->framebuffer; - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglMatrixStack *projection_stack; - - COGL_STATIC_TIMER (time_flush_clip_stack_pipeline_entries, - "Journal Flush", /* parent */ - "flush: clip+vbo+texcoords+pipeline+entries", - "The time spent flushing clip + vbo + texcoord offsets + " - "pipeline + entries", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, - time_flush_clip_stack_pipeline_entries); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: clip stack batch len = %d\n", batch_len); - - _cogl_clip_stack_flush (batch_start->clip_stack, framebuffer); - - /* XXX: Because we are manually flushing clip state here we need to - * make sure that the clip state gets updated the next time we flush - * framebuffer state by marking the current framebuffer's clip state - * as changed. */ - ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP; - - /* If we have transformed all our quads at log time then we ensure - * no further model transform is applied by loading the identity - * matrix here. We need to do this after flushing the clip stack - * because the clip stack flushing code can modify the current - * modelview matrix entry */ - if (G_LIKELY (!(COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM)))) - _cogl_context_set_current_modelview_entry (ctx, &ctx->identity_entry); - - /* Setting up the clip state can sometimes also update the current - * projection matrix entry so we should update it again. This will have - * no affect if the clip code didn't modify the projection */ - projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - _cogl_context_set_current_projection_entry (ctx, - projection_stack->last_entry); - - batch_and_call (batch_start, - batch_len, - compare_entry_strides, - _cogl_journal_flush_vbo_offsets_and_entries, /* callback */ - data); - - COGL_TIMER_STOP (_cogl_uprof_context, - time_flush_clip_stack_pipeline_entries); -} - -typedef struct -{ - float x_1, y_1; - float x_2, y_2; -} ClipBounds; - -static gboolean -can_software_clip_entry (CoglJournalEntry *journal_entry, - CoglJournalEntry *prev_journal_entry, - CoglClipStack *clip_stack, - ClipBounds *clip_bounds_out) -{ - CoglPipeline *pipeline = journal_entry->pipeline; - CoglClipStack *clip_entry; - int layer_num; - - clip_bounds_out->x_1 = -G_MAXFLOAT; - clip_bounds_out->y_1 = -G_MAXFLOAT; - clip_bounds_out->x_2 = G_MAXFLOAT; - clip_bounds_out->y_2 = G_MAXFLOAT; - - /* Check the pipeline is usable. We can short-cut here for - entries using the same pipeline as the previous entry */ - if (prev_journal_entry == NULL || pipeline != prev_journal_entry->pipeline) - { - /* If the pipeline has a user program then we can't reliably modify - the texture coordinates */ - if (cogl_pipeline_get_user_program (pipeline)) - return FALSE; - - /* If any of the pipeline layers have a texture matrix then we can't - reliably modify the texture coordinates */ - for (layer_num = cogl_pipeline_get_n_layers (pipeline) - 1; - layer_num >= 0; - layer_num--) - if (_cogl_pipeline_layer_has_user_matrix (pipeline, layer_num)) - return FALSE; - } - - /* Now we need to verify that each clip entry's matrix is just a - translation of the journal entry's modelview matrix. We can - also work out the bounds of the clip in modelview space using - this translation */ - for (clip_entry = clip_stack; clip_entry; clip_entry = clip_entry->parent) - { - float rect_x1, rect_y1, rect_x2, rect_y2; - CoglClipStackRect *clip_rect; - float tx, ty, tz; - CoglMatrixEntry *modelview_entry; - - clip_rect = (CoglClipStackRect *) clip_entry; - - modelview_entry = journal_entry->modelview_entry; - if (!cogl_matrix_entry_calculate_translation (clip_rect->matrix_entry, - modelview_entry, - &tx, &ty, &tz)) - return FALSE; - - if (clip_rect->x0 < clip_rect->x1) - { - rect_x1 = clip_rect->x0; - rect_x2 = clip_rect->x1; - } - else - { - rect_x1 = clip_rect->x1; - rect_x2 = clip_rect->x0; - } - if (clip_rect->y0 < clip_rect->y1) - { - rect_y1 = clip_rect->y0; - rect_y2 = clip_rect->y1; - } - else - { - rect_y1 = clip_rect->y1; - rect_y2 = clip_rect->y0; - } - - clip_bounds_out->x_1 = MAX (clip_bounds_out->x_1, rect_x1 - tx); - clip_bounds_out->y_1 = MAX (clip_bounds_out->y_1, rect_y1 - ty); - clip_bounds_out->x_2 = MIN (clip_bounds_out->x_2, rect_x2 - tx); - clip_bounds_out->y_2 = MIN (clip_bounds_out->y_2, rect_y2 - ty); - } - - if (clip_bounds_out->x_2 <= clip_bounds_out->x_1 || - clip_bounds_out->y_2 <= clip_bounds_out->y_1) - memset (clip_bounds_out, 0, sizeof (ClipBounds)); - - return TRUE; -} - -static void -software_clip_entry (CoglJournalEntry *journal_entry, - float *verts, - ClipBounds *clip_bounds) -{ - size_t stride = - GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS (journal_entry->n_layers); - float rx1, ry1, rx2, ry2; - float vx1, vy1, vx2, vy2; - int layer_num; - - /* Remove the clip on the entry */ - _cogl_clip_stack_unref (journal_entry->clip_stack); - journal_entry->clip_stack = NULL; - - vx1 = verts[0]; - vy1 = verts[1]; - vx2 = verts[stride]; - vy2 = verts[stride + 1]; - - if (vx1 < vx2) - { - rx1 = vx1; - rx2 = vx2; - } - else - { - rx1 = vx2; - rx2 = vx1; - } - if (vy1 < vy2) - { - ry1 = vy1; - ry2 = vy2; - } - else - { - ry1 = vy2; - ry2 = vy1; - } - - rx1 = CLAMP (rx1, clip_bounds->x_1, clip_bounds->x_2); - ry1 = CLAMP (ry1, clip_bounds->y_1, clip_bounds->y_2); - rx2 = CLAMP (rx2, clip_bounds->x_1, clip_bounds->x_2); - ry2 = CLAMP (ry2, clip_bounds->y_1, clip_bounds->y_2); - - /* Check if the rectangle intersects the clip at all */ - if (rx1 == rx2 || ry1 == ry2) - /* Will set all of the vertex data to 0 in the hope that this - will create a degenerate rectangle and the GL driver will - be able to clip it quickly */ - memset (verts, 0, sizeof (float) * stride * 2); - else - { - if (vx1 > vx2) - { - float t = rx1; - rx1 = rx2; - rx2 = t; - } - if (vy1 > vy2) - { - float t = ry1; - ry1 = ry2; - ry2 = t; - } - - verts[0] = rx1; - verts[1] = ry1; - verts[stride] = rx2; - verts[stride + 1] = ry2; - - /* Convert the rectangle coordinates to a fraction of the original - rectangle */ - rx1 = (rx1 - vx1) / (vx2 - vx1); - ry1 = (ry1 - vy1) / (vy2 - vy1); - rx2 = (rx2 - vx1) / (vx2 - vx1); - ry2 = (ry2 - vy1) / (vy2 - vy1); - - for (layer_num = 0; layer_num < journal_entry->n_layers; layer_num++) - { - float *t = verts + 2 + 2 * layer_num; - float tx1 = t[0], ty1 = t[1]; - float tx2 = t[stride], ty2 = t[stride + 1]; - t[0] = rx1 * (tx2 - tx1) + tx1; - t[1] = ry1 * (ty2 - ty1) + ty1; - t[stride] = rx2 * (tx2 - tx1) + tx1; - t[stride + 1] = ry2 * (ty2 - ty1) + ty1; - } - } -} - -static void -maybe_software_clip_entries (CoglJournalEntry *batch_start, - int batch_len, - CoglJournalFlushState *state) -{ - CoglContext *ctx; - CoglJournal *journal; - CoglClipStack *clip_stack, *clip_entry; - int entry_num; - - /* This tries to find cases where the entry is logged with a clip - but it would be faster to modify the vertex and texture - coordinates rather than flush the clip so that it can batch - better */ - - /* If the batch is reasonably long then it's worthwhile programming - the GPU to do the clip */ - if (batch_len >= COGL_JOURNAL_HARDWARE_CLIP_THRESHOLD) - return; - - clip_stack = batch_start->clip_stack; - - if (clip_stack == NULL) - return; - - /* Verify that all of the clip stack entries are a simple rectangle - clip */ - for (clip_entry = clip_stack; clip_entry; clip_entry = clip_entry->parent) - if (clip_entry->type != COGL_CLIP_STACK_RECT) - return; - - ctx = state->ctx; - journal = state->journal; - - /* This scratch buffer is used to store the translation for each - entry in the journal. We store it in a separate buffer because - it's expensive to calculate but at this point we still don't know - whether we can clip all of the entries so we don't want to do the - rest of the dependent calculations until we're sure we can. */ - if (ctx->journal_clip_bounds == NULL) - ctx->journal_clip_bounds = g_array_new (FALSE, FALSE, sizeof (ClipBounds)); - g_array_set_size (ctx->journal_clip_bounds, batch_len); - - for (entry_num = 0; entry_num < batch_len; entry_num++) - { - CoglJournalEntry *journal_entry = batch_start + entry_num; - CoglJournalEntry *prev_journal_entry = - entry_num ? batch_start + (entry_num - 1) : NULL; - ClipBounds *clip_bounds = &g_array_index (ctx->journal_clip_bounds, - ClipBounds, entry_num); - - if (!can_software_clip_entry (journal_entry, prev_journal_entry, - clip_stack, - clip_bounds)) - return; - } - - /* If we make it here then we know we can software clip the entire batch */ - - COGL_NOTE (CLIPPING, "Software clipping a batch of length %i", batch_len); - - for (entry_num = 0; entry_num < batch_len; entry_num++) - { - CoglJournalEntry *journal_entry = batch_start + entry_num; - float *verts = &g_array_index (journal->vertices, float, - journal_entry->array_offset + 1); - ClipBounds *clip_bounds = &g_array_index (ctx->journal_clip_bounds, - ClipBounds, entry_num); - - software_clip_entry (journal_entry, verts, clip_bounds); - } - - return; -} - -static void -_cogl_journal_maybe_software_clip_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - - COGL_STATIC_TIMER (time_check_software_clip, - "Journal Flush", /* parent */ - "flush: software clipping", - "Time spent software clipping", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, - time_check_software_clip); - - maybe_software_clip_entries (batch_start, batch_len, state); - - COGL_TIMER_STOP (_cogl_uprof_context, - time_check_software_clip); -} - -static gboolean -compare_entry_clip_stacks (CoglJournalEntry *entry0, CoglJournalEntry *entry1) -{ - return entry0->clip_stack == entry1->clip_stack; -} - -static void -_cogl_journal_flush_dither_and_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - CoglFramebuffer *framebuffer = state->journal->framebuffer; - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - COGL_STATIC_TIMER (time_flush_dither_and_entries, - "Journal Flush", /* parent */ - "flush: viewport+dither+clip+vbo+texcoords+pipeline+entries", - "The time spent flushing viewport + dither + clip + vbo + " - "texcoord offsets + pipeline + entries", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, time_flush_dither_and_entries); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: dither batch len = %d\n", batch_len); - - cogl_framebuffer_set_dither_enabled (framebuffer, batch_start->dither_enabled); - ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_DITHER; - - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_DITHER); - - batch_and_call (batch_start, - batch_len, - compare_entry_clip_stacks, - _cogl_journal_flush_clip_stacks_and_entries, - state); - - COGL_TIMER_STOP (_cogl_uprof_context, time_flush_dither_and_entries); -} - -static gboolean -compare_entry_dither_states (CoglJournalEntry *entry0, CoglJournalEntry *entry1) -{ - return entry0->dither_enabled == entry1->dither_enabled; -} - -static void -_cogl_journal_flush_viewport_and_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - CoglFramebuffer *framebuffer = state->journal->framebuffer; - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - float current_viewport[4]; - - COGL_STATIC_TIMER (time_flush_viewport_and_entries, - "Journal Flush", /* parent */ - "flush: viewport+clip+vbo+texcoords+pipeline+entries", - "The time spent flushing viewport + clip + vbo + texcoord offsets + " - "pipeline + entries", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, time_flush_viewport_and_entries); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: viewport batch len = %d\n", batch_len); - - ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_VIEWPORT; - - cogl_framebuffer_get_viewport4fv (framebuffer, current_viewport); - cogl_framebuffer_set_viewport4fv (framebuffer, batch_start->viewport); - - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_VIEWPORT); - - batch_and_call (batch_start, - batch_len, - compare_entry_dither_states, - _cogl_journal_flush_dither_and_entries, - state); - - if (memcmp (batch_start->viewport, current_viewport, sizeof (float) * 4) != 0) - cogl_framebuffer_set_viewport4fv (framebuffer, current_viewport); - - COGL_TIMER_STOP (_cogl_uprof_context, time_flush_viewport_and_entries); -} - -static gboolean -compare_entry_viewports (CoglJournalEntry *entry0, CoglJournalEntry *entry1) -{ - return memcmp (entry0->viewport, entry1->viewport, sizeof (float) * 4) == 0; -} - -/* Gets a new vertex array from the pool. A reference is taken on the - array so it can be treated as if it was just newly allocated */ -static CoglAttributeBuffer * -create_attribute_buffer (CoglJournal *journal, - size_t n_bytes) -{ - CoglContext *ctx = cogl_framebuffer_get_context (journal->framebuffer); - CoglAttributeBuffer *vbo; - - vbo = journal->vbo_pool[journal->next_vbo_in_pool]; - - if (vbo == NULL) - { - vbo = cogl_attribute_buffer_new_with_size (ctx, n_bytes); - journal->vbo_pool[journal->next_vbo_in_pool] = vbo; - } - else if (cogl_buffer_get_size (COGL_BUFFER (vbo)) < n_bytes) - { - /* If the buffer is too small then we'll just recreate it */ - g_object_unref (vbo); - vbo = cogl_attribute_buffer_new_with_size (ctx, n_bytes); - journal->vbo_pool[journal->next_vbo_in_pool] = vbo; - } - - journal->next_vbo_in_pool = ((journal->next_vbo_in_pool + 1) % - COGL_JOURNAL_VBO_POOL_SIZE); - - return g_object_ref (vbo); -} - -static CoglAttributeBuffer * -upload_vertices (CoglJournal *journal, - const CoglJournalEntry *entries, - int n_entries, - size_t needed_vbo_len, - GArray *vertices) -{ - CoglAttributeBuffer *attribute_buffer; - CoglBuffer *buffer; - const float *vin; - float *vout; - int entry_num; - int i; - CoglMatrixEntry *last_modelview_entry = NULL; - graphene_matrix_t modelview; - - g_assert (needed_vbo_len); - - attribute_buffer = create_attribute_buffer (journal, needed_vbo_len * 4); - buffer = COGL_BUFFER (attribute_buffer); - cogl_buffer_set_update_hint (buffer, COGL_BUFFER_UPDATE_HINT_DYNAMIC); - - vout = _cogl_buffer_map_range_for_fill_or_fallback (buffer, - 0, /* offset */ - needed_vbo_len * 4); - vin = &g_array_index (vertices, float, 0); - - /* Expand the number of vertices from 2 to 4 while uploading */ - for (entry_num = 0; entry_num < n_entries; entry_num++) - { - const CoglJournalEntry *entry = entries + entry_num; - size_t vb_stride = GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (entry->n_layers); - size_t array_stride = - GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS (entry->n_layers); - - /* Copy the color to all four of the vertices */ - for (i = 0; i < 4; i++) - memcpy (vout + vb_stride * i + POS_STRIDE, vin, 4); - vin++; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))) - { - vout[vb_stride * 0] = vin[0]; - vout[vb_stride * 0 + 1] = vin[1]; - vout[vb_stride * 1] = vin[0]; - vout[vb_stride * 1 + 1] = vin[array_stride + 1]; - vout[vb_stride * 2] = vin[array_stride]; - vout[vb_stride * 2 + 1] = vin[array_stride + 1]; - vout[vb_stride * 3] = vin[array_stride]; - vout[vb_stride * 3 + 1] = vin[1]; - } - else - { - float v[8]; - - v[0] = vin[0]; - v[1] = vin[1]; - v[2] = vin[0]; - v[3] = vin[array_stride + 1]; - v[4] = vin[array_stride]; - v[5] = vin[array_stride + 1]; - v[6] = vin[array_stride]; - v[7] = vin[1]; - - if (entry->modelview_entry != last_modelview_entry) - cogl_matrix_entry_get (entry->modelview_entry, &modelview); - cogl_graphene_matrix_transform_points (&modelview, - 2, /* n_components */ - sizeof (float) * 2, /* stride_in */ - v, /* points_in */ - /* strideout */ - vb_stride * sizeof (float), - vout, /* points_out */ - 4 /* n_points */); - } - - for (i = 0; i < entry->n_layers; i++) - { - const float *tin = vin + 2; - float *tout = vout + POS_STRIDE + COLOR_STRIDE; - - tout[vb_stride * 0 + i * 2] = tin[i * 2]; - tout[vb_stride * 0 + 1 + i * 2] = tin[i * 2 + 1]; - tout[vb_stride * 1 + i * 2] = tin[i * 2]; - tout[vb_stride * 1 + 1 + i * 2] = tin[array_stride + i * 2 + 1]; - tout[vb_stride * 2 + i * 2] = tin[array_stride + i * 2]; - tout[vb_stride * 2 + 1 + i * 2] = tin[array_stride + i * 2 + 1]; - tout[vb_stride * 3 + i * 2] = tin[array_stride + i * 2]; - tout[vb_stride * 3 + 1 + i * 2] = tin[i * 2 + 1]; - } - - vin += array_stride * 2; - vout += vb_stride * 4; - } - - _cogl_buffer_unmap_for_fill_or_fallback (buffer); - - return attribute_buffer; -} - -void -_cogl_journal_discard (CoglJournal *journal) -{ - int i; - - if (journal->entries->len <= 0) - return; - - for (i = 0; i < journal->entries->len; i++) - { - CoglJournalEntry *entry = - &g_array_index (journal->entries, CoglJournalEntry, i); - _cogl_pipeline_journal_unref (entry->pipeline); - cogl_matrix_entry_unref (entry->modelview_entry); - _cogl_clip_stack_unref (entry->clip_stack); - } - - g_array_set_size (journal->entries, 0); - g_array_set_size (journal->vertices, 0); - journal->needed_vbo_len = 0; - journal->fast_read_pixel_count = 0; -} - -/* Note: A return value of FALSE doesn't mean 'no' it means - * 'unknown' */ -gboolean -_cogl_journal_all_entries_within_bounds (CoglJournal *journal, - float clip_x0, - float clip_y0, - float clip_x1, - float clip_y1) -{ - CoglJournalEntry *entry = (CoglJournalEntry *)journal->entries->data; - CoglClipStack *clip_entry; - CoglClipStack *reference = NULL; - int bounds_x0; - int bounds_y0; - int bounds_x1; - int bounds_y1; - int i; - - if (journal->entries->len == 0) - return TRUE; - - /* Find the shortest clip_stack ancestry that leaves us in the - * required bounds */ - for (clip_entry = entry->clip_stack; - clip_entry; - clip_entry = clip_entry->parent) - { - _cogl_clip_stack_get_bounds (clip_entry, - &bounds_x0, &bounds_y0, - &bounds_x1, &bounds_y1); - - if (bounds_x0 >= clip_x0 && bounds_y0 >= clip_y0 && - bounds_x1 <= clip_x1 && bounds_y1 <= clip_y1) - reference = clip_entry; - else - break; - } - - if (!reference) - return FALSE; - - /* For the remaining journal entries we will only verify they share - * 'reference' as an ancestor in their clip stack since that's - * enough to know that they would be within the required bounds. - */ - for (i = 1; i < journal->entries->len; i++) - { - gboolean found_reference = FALSE; - entry = &g_array_index (journal->entries, CoglJournalEntry, i); - - for (clip_entry = entry->clip_stack; - clip_entry; - clip_entry = clip_entry->parent) - { - if (clip_entry == reference) - { - found_reference = TRUE; - break; - } - } - - if (!found_reference) - return FALSE; - } - - return TRUE; -} - -static void -post_fences (CoglJournal *journal) -{ - CoglFenceClosure *fence, *tmp; - - _cogl_list_for_each_safe (fence, tmp, &journal->pending_fences, link) - { - _cogl_list_remove (&fence->link); - _cogl_fence_submit (fence); - } -} - -/* XXX NB: When _cogl_journal_flush() returns all state relating - * to pipelines, all glEnable flags and current matrix state - * is undefined. - */ -void -_cogl_journal_flush (CoglJournal *journal) -{ - CoglFramebuffer *framebuffer; - CoglContext *ctx; - CoglJournalFlushState state; - int i; - COGL_STATIC_TIMER (flush_timer, - "Mainloop", /* parent */ - "Journal Flush", - "The time spent flushing the Cogl journal", - 0 /* no application private data */); - COGL_STATIC_TIMER (discard_timer, - "Journal Flush", /* parent */ - "flush: discard", - "The time spent discarding the Cogl journal after a flush", - 0 /* no application private data */); - - COGL_TRACE_BEGIN_SCOPED (Flush, "Cogl::Journal::flush()"); - - if (journal->entries->len == 0) - { - post_fences (journal); - return; - } - - framebuffer = journal->framebuffer; - ctx = cogl_framebuffer_get_context (framebuffer); - - /* The entries in this journal may depend on images in other - * framebuffers which may require that we flush the journals - * associated with those framebuffers before we can flush - * this journal... */ - _cogl_framebuffer_flush_dependency_journals (framebuffer); - - /* Note: we start the timer after flushing dependency journals so - * that the timer isn't started recursively. */ - COGL_TIMER_START (_cogl_uprof_context, flush_timer); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: journal len = %d\n", journal->entries->len); - - /* NB: the journal deals with flushing the viewport, the modelview - * stack and clip state manually */ - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_ALL & - ~(COGL_FRAMEBUFFER_STATE_DITHER | - COGL_FRAMEBUFFER_STATE_VIEWPORT | - COGL_FRAMEBUFFER_STATE_MODELVIEW | - COGL_FRAMEBUFFER_STATE_CLIP)); - - /* We need to mark the current modelview state of the framebuffer as - * dirty because we are going to manually replace it */ - ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_MODELVIEW; - - state.ctx = ctx; - state.journal = journal; - - state.attributes = ctx->journal_flush_attributes_array; - - if (G_UNLIKELY ((COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SOFTWARE_CLIP)) == 0)) - { - /* We do an initial walk of the journal to analyse the clip stack - batches to see if we can do software clipping. We do this as a - separate walk of the journal because we can modify entries and - this may end up joining together clip stack batches in the next - iteration. */ - batch_and_call ((CoglJournalEntry *)journal->entries->data, /* first entry */ - journal->entries->len, /* max number of entries to consider */ - compare_entry_clip_stacks, - _cogl_journal_maybe_software_clip_entries, /* callback */ - &state); /* data */ - } - - /* We upload the vertices after the clip stack pass in case it - modifies the entries */ - state.attribute_buffer = - upload_vertices (journal, - &g_array_index (journal->entries, CoglJournalEntry, 0), - journal->entries->len, - journal->needed_vbo_len, - journal->vertices); - state.array_offset = 0; - - /* batch_and_call() batches a list of journal entries according to some - * given criteria and calls a callback once for each determined batch. - * - * The process of flushing the journal is staggered to reduce the amount - * of driver/GPU state changes necessary: - * 1) We split the entries according to the clip state. - * 2) We split the entries according to the stride of the vertices: - * Each time the stride of our vertex data changes we need to call - * gl{Vertex,Color}Pointer to inform GL of new VBO offsets. - * Currently the only thing that affects the stride of our vertex data - * is the number of pipeline layers. - * 3) We split the entries explicitly by the number of pipeline layers: - * We pad our vertex data when the number of layers is < 2 so that we - * can minimize changes in stride. - * 4) We then split according to compatible Cogl pipelines: - * This is where we flush pipeline state - * 5) Finally we split according to modelview matrix changes: - * This is when we finally tell GL to draw something. - * Note: Splitting by modelview changes is skipped when are doing the - * vertex transformation in software at log time. - */ - batch_and_call ((CoglJournalEntry *)journal->entries->data, - journal->entries->len, - compare_entry_viewports, - _cogl_journal_flush_viewport_and_entries, - &state); - - for (i = 0; i < state.attributes->len; i++) - g_object_unref (g_array_index (state.attributes, CoglAttribute *, i)); - g_array_set_size (state.attributes, 0); - - g_object_unref (state.attribute_buffer); - - COGL_TIMER_START (_cogl_uprof_context, discard_timer); - _cogl_journal_discard (journal); - COGL_TIMER_STOP (_cogl_uprof_context, discard_timer); - - post_fences (journal); - - COGL_TIMER_STOP (_cogl_uprof_context, flush_timer); -} - -static gboolean -add_framebuffer_deps_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglFramebuffer *framebuffer = user_data; - CoglTexture *texture = _cogl_pipeline_layer_get_texture_real (layer); - const GList *l; - - if (!texture) - return TRUE; - - for (l = _cogl_texture_get_associated_framebuffers (texture); l; l = l->next) - _cogl_framebuffer_add_dependency (framebuffer, l->data); - - return TRUE; -} - -void -_cogl_journal_log_quad (CoglJournal *journal, - const float *position, - CoglPipeline *pipeline, - int n_layers, - CoglTexture *layer0_override_texture, - const float *tex_coords, - unsigned int tex_coords_len) -{ - CoglFramebuffer *framebuffer = journal->framebuffer; - size_t stride; - int next_vert; - float *v; - int i; - int next_entry; - uint32_t disable_layers; - CoglJournalEntry *entry; - CoglPipeline *final_pipeline; - CoglClipStack *clip_stack; - CoglPipelineFlushOptions flush_options; - CoglMatrixStack *modelview_stack; - COGL_STATIC_TIMER (log_timer, - "Mainloop", /* parent */ - "Journal Log", - "The time spent logging in the Cogl journal", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, log_timer); - - /* The vertex data is logged into a separate array. The data needs - to be copied into a vertex array before it's given to GL so we - only store two vertices per quad and expand it to four while - uploading. */ - - /* XXX: See definition of GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS for details - * about how we pack our vertex data */ - stride = GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS (n_layers); - - next_vert = journal->vertices->len; - g_array_set_size (journal->vertices, next_vert + 2 * stride + 1); - v = &g_array_index (journal->vertices, float, next_vert); - - /* We calculate the needed size of the vbo as we go because it - depends on the number of layers in each entry and it's not easy - calculate based on the length of the logged vertices array */ - journal->needed_vbo_len += GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (n_layers) * 4; - - /* XXX: All the jumping around to fill in this strided buffer doesn't - * seem ideal. */ - - /* FIXME: This is a hacky optimization, since it will break if we - * change the definition of CoglColor: */ - _cogl_pipeline_get_colorubv (pipeline, (uint8_t *) v); - v++; - - memcpy (v, position, sizeof (float) * 2); - memcpy (v + stride, position + 2, sizeof (float) * 2); - - for (i = 0; i < n_layers; i++) - { - /* XXX: See definition of GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS - * for details about how we pack our vertex data */ - GLfloat *t = v + 2 + i * 2; - - memcpy (t, tex_coords + i * 4, sizeof (float) * 2); - memcpy (t + stride, tex_coords + i * 4 + 2, sizeof (float) * 2); - } - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_JOURNAL))) - { - g_print ("Logged new quad:\n"); - v = &g_array_index (journal->vertices, float, next_vert); - _cogl_journal_dump_logged_quad ((uint8_t *)v, n_layers); - } - - next_entry = journal->entries->len; - g_array_set_size (journal->entries, next_entry + 1); - entry = &g_array_index (journal->entries, CoglJournalEntry, next_entry); - - entry->n_layers = n_layers; - entry->array_offset = next_vert; - - final_pipeline = pipeline; - - flush_options.flags = 0; - if (G_UNLIKELY (cogl_pipeline_get_n_layers (pipeline) != n_layers)) - { - disable_layers = (1 << n_layers) - 1; - disable_layers = ~disable_layers; - flush_options.disable_layers = disable_layers; - flush_options.flags |= COGL_PIPELINE_FLUSH_DISABLE_MASK; - } - if (G_UNLIKELY (layer0_override_texture)) - { - flush_options.flags |= COGL_PIPELINE_FLUSH_LAYER0_OVERRIDE; - flush_options.layer0_override_texture = layer0_override_texture; - } - - if (G_UNLIKELY (flush_options.flags)) - { - final_pipeline = cogl_pipeline_copy (pipeline); - _cogl_pipeline_apply_overrides (final_pipeline, &flush_options); - } - - entry->pipeline = _cogl_pipeline_journal_ref (final_pipeline); - - clip_stack = _cogl_framebuffer_get_clip_stack (framebuffer); - entry->clip_stack = _cogl_clip_stack_ref (clip_stack); - entry->dither_enabled = cogl_framebuffer_get_dither_enabled (framebuffer); - - cogl_framebuffer_get_viewport4fv (framebuffer, entry->viewport); - - if (G_UNLIKELY (final_pipeline != pipeline)) - g_object_unref (final_pipeline); - - modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - entry->modelview_entry = cogl_matrix_entry_ref (modelview_stack->last_entry); - - _cogl_pipeline_foreach_layer_internal (pipeline, - add_framebuffer_deps_cb, - framebuffer); - - if (COGL_IS_OFFSCREEN (framebuffer)) - { - CoglOffscreen *offscreen = COGL_OFFSCREEN (framebuffer); - CoglTexture *texture = cogl_offscreen_get_texture (offscreen); - - _cogl_texture_2d_externally_modified (texture); - } - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SYNC_PRIMITIVE))) - { - _cogl_journal_flush (journal); - cogl_framebuffer_finish (framebuffer); - } - else if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_BATCHING))) - { - _cogl_journal_flush (journal); - } - - COGL_TIMER_STOP (_cogl_uprof_context, log_timer); -} - -static void -entry_to_screen_polygon (CoglFramebuffer *framebuffer, - const CoglJournalEntry *entry, - float *vertices, - float *poly) -{ - size_t array_stride = - GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS (entry->n_layers); - CoglMatrixStack *projection_stack; - graphene_matrix_t projection; - graphene_matrix_t modelview; - int i; - const float *viewport = entry->viewport; - - poly[0] = vertices[0]; - poly[1] = vertices[1]; - poly[2] = 0; - poly[3] = 1; - - poly[4] = vertices[0]; - poly[5] = vertices[array_stride + 1]; - poly[6] = 0; - poly[7] = 1; - - poly[8] = vertices[array_stride]; - poly[9] = vertices[array_stride + 1]; - poly[10] = 0; - poly[11] = 1; - - poly[12] = vertices[array_stride]; - poly[13] = vertices[1]; - poly[14] = 0; - poly[15] = 1; - - /* TODO: perhaps split the following out into a more generalized - * _cogl_transform_points utility... - */ - - cogl_matrix_entry_get (entry->modelview_entry, &modelview); - cogl_graphene_matrix_transform_points (&modelview, - 2, /* n_components */ - sizeof (float) * 4, /* stride_in */ - poly, /* points_in */ - /* strideout */ - sizeof (float) * 4, - poly, /* points_out */ - 4 /* n_points */); - - projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - cogl_matrix_stack_get (projection_stack, &projection); - - cogl_graphene_matrix_transform_points (&projection, - 3, /* n_components */ - sizeof (float) * 4, /* stride_in */ - poly, /* points_in */ - /* strideout */ - sizeof (float) * 4, - poly, /* points_out */ - 4 /* n_points */); - -/* Scale from OpenGL normalized device coordinates (ranging from -1 to 1) - * to Cogl window/framebuffer coordinates (ranging from 0 to buffer-size) with - * (0,0) being top left. */ -#define VIEWPORT_TRANSFORM_X(x, vp_origin_x, vp_width) \ - ( ( ((x) + 1.0) * ((vp_width) / 2.0) ) + (vp_origin_x) ) -/* Note: for Y we first flip all coordinates around the X axis while in - * normalized device coordinates */ -#define VIEWPORT_TRANSFORM_Y(y, vp_origin_y, vp_height) \ - ( ( ((-(y)) + 1.0) * ((vp_height) / 2.0) ) + (vp_origin_y) ) - - /* Scale from normalized device coordinates (in range [-1,1]) to - * window coordinates ranging [0,window-size] ... */ - for (i = 0; i < 4; i++) - { - float w = poly[4 * i + 3]; - - /* Perform perspective division */ - poly[4 * i] /= w; - poly[4 * i + 1] /= w; - - /* Apply viewport transform */ - poly[4 * i] = VIEWPORT_TRANSFORM_X (poly[4 * i], - viewport[0], viewport[2]); - poly[4 * i + 1] = VIEWPORT_TRANSFORM_Y (poly[4 * i + 1], - viewport[1], viewport[3]); - } - -#undef VIEWPORT_TRANSFORM_X -#undef VIEWPORT_TRANSFORM_Y -} - -static gboolean -try_checking_point_hits_entry_after_clipping (CoglFramebuffer *framebuffer, - CoglJournalEntry *entry, - float *vertices, - float x, - float y, - gboolean *hit) -{ - gboolean needs_software_clip = FALSE; - CoglClipStack *clip_entry; - - *hit = TRUE; - - /* Verify that all of the clip stack entries are simple rectangle - * clips */ - for (clip_entry = entry->clip_stack; - clip_entry; - clip_entry = clip_entry->parent) - { - if (x < clip_entry->bounds_x0 || - x >= clip_entry->bounds_x1 || - y < clip_entry->bounds_y0 || - y >= clip_entry->bounds_y1) - { - *hit = FALSE; - return TRUE; - } - - if (clip_entry->type == COGL_CLIP_STACK_RECT) - { - CoglClipStackRect *rect_entry = (CoglClipStackRect *)entry; - - if (rect_entry->can_be_scissor == FALSE) - needs_software_clip = TRUE; - /* If can_be_scissor is TRUE then we know it's screen - * aligned and the hit test we did above has determined - * that we are inside this clip. */ - } - else - return FALSE; - } - - if (needs_software_clip) - { - ClipBounds clip_bounds; - float poly[16]; - - if (!can_software_clip_entry (entry, NULL, - entry->clip_stack, &clip_bounds)) - return FALSE; - - software_clip_entry (entry, vertices, &clip_bounds); - entry_to_screen_polygon (framebuffer, entry, vertices, poly); - - *hit = _cogl_util_point_in_screen_poly (x, y, poly, sizeof (float) * 4, 4); - return TRUE; - } - - return TRUE; -} - -gboolean -_cogl_journal_try_read_pixel (CoglJournal *journal, - int x, - int y, - CoglBitmap *bitmap, - gboolean *found_intersection) -{ - CoglContext *ctx; - CoglPixelFormat format; - int i; - - /* XXX: this number has been plucked out of thin air, but the idea - * is that if so many pixels are being read from the same un-changed - * journal than we expect that it will be more efficient to fail - * here so we end up flushing and rendering the journal so that - * further reads can directly read from the framebuffer. There will - * be a bit more lag to flush the render but if there are going to - * continue being lots of arbitrary single pixel reads they will end - * up faster in the end. */ - if (journal->fast_read_pixel_count > 50) - return FALSE; - - format = cogl_bitmap_get_format (bitmap); - - if (format != COGL_PIXEL_FORMAT_RGBA_8888_PRE && - format != COGL_PIXEL_FORMAT_RGBA_8888) - return FALSE; - - ctx = _cogl_bitmap_get_context (bitmap); - - *found_intersection = FALSE; - - /* NB: The most recently added journal entry is the last entry, and - * assuming this is a simple scene only comprised of opaque coloured - * rectangles with no special pipelines involved (e.g. enabling - * depth testing) then we can assume painter's algorithm for the - * entries and so our fast read-pixel just needs to walk backwards - * through the journal entries trying to intersect each entry with - * the given point of interest. */ - for (i = journal->entries->len - 1; i >= 0; i--) - { - CoglJournalEntry *entry = - &g_array_index (journal->entries, CoglJournalEntry, i); - uint8_t *color = (uint8_t *)&g_array_index (journal->vertices, float, - entry->array_offset); - float *vertices = (float *)color + 1; - float poly[16]; - CoglFramebuffer *framebuffer = journal->framebuffer; - uint8_t *pixel; - GError *ignore_error; - - entry_to_screen_polygon (framebuffer, entry, vertices, poly); - - if (!_cogl_util_point_in_screen_poly (x, y, poly, sizeof (float) * 4, 4)) - continue; - - if (entry->clip_stack) - { - gboolean hit; - - if (!try_checking_point_hits_entry_after_clipping (framebuffer, - entry, - vertices, - x, y, &hit)) - return FALSE; /* hit couldn't be determined */ - - if (!hit) - continue; - } - - *found_intersection = TRUE; - - /* If we find that the rectangle the point of interest - * intersects has any state more complex than a constant opaque - * color then we bail out. */ - if (!_cogl_pipeline_equal (ctx->opaque_color_pipeline, entry->pipeline, - (COGL_PIPELINE_STATE_ALL & - ~COGL_PIPELINE_STATE_COLOR), - COGL_PIPELINE_LAYER_STATE_ALL)) - return FALSE; - - - /* we currently only care about cases where the premultiplied or - * unpremultipled colors are equivalent... */ - if (color[3] != 0xff) - return FALSE; - - pixel = _cogl_bitmap_map (bitmap, - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD, - &ignore_error); - if (pixel == NULL) - { - g_error_free (ignore_error); - return FALSE; - } - - pixel[0] = color[0]; - pixel[1] = color[1]; - pixel[2] = color[2]; - pixel[3] = color[3]; - - _cogl_bitmap_unmap (bitmap); - - goto success; - } - -success: - journal->fast_read_pixel_count++; - return TRUE; -} diff --git a/mutter/cogl/cogl/cogl-list.c b/mutter/cogl/cogl/cogl-list.c deleted file mode 100644 index 91f86b5..0000000 --- a/mutter/cogl/cogl/cogl-list.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright © 2008-2011 Kristian Høgsberg - * Copyright © 2011, 2012 Intel Corporation - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* This list implementation is based on the Wayland source code */ - -#include "config.h" - -#include -#include - -#include "cogl/cogl-list.h" - -void -_cogl_list_init (CoglList *list) -{ - list->prev = list; - list->next = list; -} - -void -_cogl_list_insert (CoglList *list, CoglList *elm) -{ - elm->prev = list; - elm->next = list->next; - list->next = elm; - elm->next->prev = elm; -} - -void -_cogl_list_remove (CoglList *elm) -{ - elm->prev->next = elm->next; - elm->next->prev = elm->prev; - elm->next = NULL; - elm->prev = NULL; -} - -int -_cogl_list_length (CoglList *list) -{ - CoglList *e; - int count; - - count = 0; - e = list->next; - while (e != list) - { - e = e->next; - count++; - } - - return count; -} - -int -_cogl_list_empty (CoglList *list) -{ - return list->next == list; -} - -void -_cogl_list_insert_list (CoglList *list, - CoglList *other) -{ - if (_cogl_list_empty (other)) - return; - - other->next->prev = list; - other->prev->next = list->next; - list->next->prev = other->prev; - list->next = other->next; -} diff --git a/mutter/cogl/cogl/cogl-list.h b/mutter/cogl/cogl/cogl-list.h deleted file mode 100644 index 9d52ce5..0000000 --- a/mutter/cogl/cogl/cogl-list.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright © 2008 Kristian Høgsberg - * Copyright © 2012, 2013 Intel Corporation - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#pragma once - -/* This list implementation is based on the Wayland source code */ - -#include - -/** - * CoglList - linked list - * - * The list head is of "CoglList" type, and must be initialized - * using cogl_list_init(). All entries in the list must be of the same - * type. The item type must have a "CoglList" member. This - * member will be initialized by cogl_list_insert(). There is no need to - * call cogl_list_init() on the individual item. To query if the list is - * empty in O(1), use cogl_list_empty(). - * - * Let's call the list reference "CoglList foo_list", the item type as - * "item_t", and the item member as "CoglList link". The following code - * - * The following code will initialize a list: - * - * cogl_list_init (foo_list); - * cogl_list_insert (foo_list, item1); Pushes item1 at the head - * cogl_list_insert (foo_list, item2); Pushes item2 at the head - * cogl_list_insert (item2, item3); Pushes item3 after item2 - * - * The list now looks like [item2, item3, item1] - * - * Will iterate the list in ascending order: - * - * item_t *item; - * cogl_list_for_each(item, foo_list, link) { - * Do_something_with_item(item); - * } - */ - -typedef struct _CoglList CoglList; - -struct _CoglList -{ - CoglList *prev; - CoglList *next; -}; - -void -_cogl_list_init (CoglList *list); - -void -_cogl_list_insert (CoglList *list, - CoglList *elm); - -void -_cogl_list_remove (CoglList *elm); - -int -_cogl_list_length (CoglList *list); - -int -_cogl_list_empty (CoglList *list); - -void -_cogl_list_insert_list (CoglList *list, - CoglList *other); - -/* This assigns to iterator first so that taking a reference to it - * later in the second step won't be an undefined operation. It - * assigns the value of list_node rather than 0 so that it is possible - * have list_node be based on the previous value of iterator. In that - * respect iterator is just used as a convenient temporary variable. - * The compiler optimises all of this down to a single subtraction by - * a constant */ -#define _cogl_list_set_iterator(list_node, iterator, member) \ - ((iterator) = (void *) (list_node), \ - (iterator) = (void *) ((char *) (iterator) - \ - (((char *) &(iterator)->member) - \ - (char *) (iterator)))) - -#define _cogl_container_of(ptr, type, member) \ - (type *) ((char *) (ptr) - offsetof (type, member)) - -#define _cogl_list_for_each(pos, head, member) \ - for (_cogl_list_set_iterator ((head)->next, pos, member); \ - &pos->member != (head); \ - _cogl_list_set_iterator (pos->member.next, pos, member)) - -#define _cogl_list_for_each_safe(pos, tmp, head, member) \ - for (_cogl_list_set_iterator ((head)->next, pos, member), \ - _cogl_list_set_iterator ((pos)->member.next, tmp, member); \ - &pos->member != (head); \ - pos = tmp, \ - _cogl_list_set_iterator (pos->member.next, tmp, member)) - -#define _cogl_list_for_each_reverse(pos, head, member) \ - for (_cogl_list_set_iterator ((head)->prev, pos, member); \ - &pos->member != (head); \ - _cogl_list_set_iterator (pos->member.prev, pos, member)) - -#define _cogl_list_for_each_reverse_safe(pos, tmp, head, member) \ - for (_cogl_list_set_iterator ((head)->prev, pos, member), \ - _cogl_list_set_iterator ((pos)->member.prev, tmp, member); \ - &pos->member != (head); \ - pos = tmp, \ - _cogl_list_set_iterator (pos->member.prev, tmp, member)) diff --git a/mutter/cogl/cogl/cogl-macros.h b/mutter/cogl/cogl/cogl-macros.h deleted file mode 100644 index 895a597..0000000 --- a/mutter/cogl/cogl/cogl-macros.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -/* These macros are used to mark deprecated functions, and thus have - * to be exposed in a public header. - * - * They are only intended for internal use and should not be used by - * other projects. - */ -#if defined(COGL_DISABLE_DEPRECATION_WARNINGS) || defined(COGL_COMPILATION) - -#define COGL_DEPRECATED -#define COGL_DEPRECATED_FOR(f) -#define COGL_UNAVAILABLE(maj,min) - -#else /* COGL_DISABLE_DEPRECATION_WARNINGS */ - -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) -#define COGL_DEPRECATED __attribute__((__deprecated__)) -#elif defined(_MSC_VER) && (_MSC_VER >= 1300) -#define COGL_DEPRECATED __declspec(deprecated) -#else -#define COGL_DEPRECATED -#endif - -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) -#define COGL_DEPRECATED_FOR(f) __attribute__((__deprecated__("Use '" #f "' instead"))) -#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320) -#define COGL_DEPRECATED_FOR(f) __declspec(deprecated("is deprecated. Use '" #f "' instead")) -#else -#define COGL_DEPRECATED_FOR(f) G_DEPRECATED -#endif - -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) -#define COGL_UNAVAILABLE(maj,min) __attribute__((deprecated("Not available before " #maj "." #min))) -#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320) -#define COGL_UNAVAILABLE(maj,min) __declspec(deprecated("is not available before " #maj "." #min)) -#else -#define COGL_UNAVAILABLE(maj,min) -#endif - -#endif /* COGL_DISABLE_DEPRECATION_WARNINGS */ - -#define COGL_EXPORT __attribute__((visibility("default"))) extern -#define COGL_EXPORT_TEST __attribute__((visibility("default"))) extern diff --git a/mutter/cogl/cogl/cogl-magazine-private.h b/mutter/cogl/cogl/cogl-magazine-private.h deleted file mode 100644 index b5cc95c..0000000 --- a/mutter/cogl/cogl/cogl-magazine-private.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include - -#include "cogl/cogl-memory-stack-private.h" - -typedef struct _CoglMagazineChunk CoglMagazineChunk; - -struct _CoglMagazineChunk -{ - CoglMagazineChunk *next; -}; - -typedef struct _CoglMagazine -{ - size_t chunk_size; - - CoglMemoryStack *stack; - CoglMagazineChunk *head; -} CoglMagazine; - -CoglMagazine * -_cogl_magazine_new (size_t chunk_size, int initial_chunk_count); - -static inline void * -_cogl_magazine_chunk_alloc (CoglMagazine *magazine) -{ - if (G_LIKELY (magazine->head)) - { - CoglMagazineChunk *chunk = magazine->head; - magazine->head = chunk->next; - return chunk; - } - else - return _cogl_memory_stack_alloc (magazine->stack, magazine->chunk_size); -} - -static inline void -_cogl_magazine_chunk_free (CoglMagazine *magazine, void *data) -{ - CoglMagazineChunk *chunk = data; - - chunk->next = magazine->head; - magazine->head = chunk; -} - -void -_cogl_magazine_free (CoglMagazine *magazine); diff --git a/mutter/cogl/cogl/cogl-magazine.c b/mutter/cogl/cogl/cogl-magazine.c deleted file mode 100644 index c155833..0000000 --- a/mutter/cogl/cogl/cogl-magazine.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * CoglMagazine provides a really light weight allocator for chunks - * of memory with a pre-determined size. - * - * This allocator builds on CoglMemoryStack for making all initial - * allocations but never frees memory back to the stack. - * - * Memory chunks that haven't been allocated yet are stored in a - * singly linked, fifo, list. - * - * Allocating from a magazine is simply a question of popping an entry - * from the head of the fifo list. If no entries are available then - * instead allocate from the memory stack instead. - * - * When an entry is freed, it is put back into the fifo list for - * re-use. - * - * No attempt is ever made to shrink the amount of memory associated - * with a CoglMagazine. - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-memory-stack-private.h" -#include "cogl/cogl-magazine-private.h" -#include - -#define ROUND_UP_8(X) ((X + (8 - 1)) & ~(8 - 1)) - -CoglMagazine * -_cogl_magazine_new (size_t chunk_size, int initial_chunk_count) -{ - CoglMagazine *magazine = g_new0 (CoglMagazine, 1); - - chunk_size = MAX (chunk_size, sizeof (CoglMagazineChunk)); - chunk_size = ROUND_UP_8 (chunk_size); - - magazine->chunk_size = chunk_size; - magazine->stack = _cogl_memory_stack_new (chunk_size * initial_chunk_count); - magazine->head = NULL; - - return magazine; -} - -void -_cogl_magazine_free (CoglMagazine *magazine) -{ - _cogl_memory_stack_free (magazine->stack); - g_free (magazine); -} diff --git a/mutter/cogl/cogl/cogl-matrix-stack-private.h b/mutter/cogl/cogl/cogl-matrix-stack-private.h deleted file mode 100644 index 9a4bcc3..0000000 --- a/mutter/cogl/cogl/cogl-matrix-stack-private.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009,2010,2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Havoc Pennington for litl - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-matrix-stack.h" -#include "cogl/cogl-context.h" -#include "cogl/cogl-framebuffer.h" - -typedef enum _CoglMatrixOp -{ - COGL_MATRIX_OP_LOAD_IDENTITY, - COGL_MATRIX_OP_TRANSLATE, - COGL_MATRIX_OP_ROTATE, - COGL_MATRIX_OP_ROTATE_EULER, - COGL_MATRIX_OP_SCALE, - COGL_MATRIX_OP_MULTIPLY, - COGL_MATRIX_OP_LOAD, - COGL_MATRIX_OP_SAVE, -} CoglMatrixOp; - -struct _CoglMatrixEntry -{ - CoglMatrixEntry *parent; - CoglMatrixOp op; - unsigned int ref_count; - - /* Debugging, only used when defined(COGL_ENABLE_DEBUG) - * Used for performance tracing */ - int composite_gets; -}; - -typedef struct _CoglMatrixEntryTranslate -{ - CoglMatrixEntry _parent_data; - - graphene_point3d_t translate; - -} CoglMatrixEntryTranslate; - -typedef struct _CoglMatrixEntryRotate -{ - CoglMatrixEntry _parent_data; - - float angle; - graphene_vec3_t axis; - -} CoglMatrixEntryRotate; - -typedef struct _CoglMatrixEntryRotateEuler -{ - CoglMatrixEntry _parent_data; - - graphene_euler_t euler; -} CoglMatrixEntryRotateEuler; - -typedef struct _CoglMatrixEntryScale -{ - CoglMatrixEntry _parent_data; - - float x; - float y; - float z; - -} CoglMatrixEntryScale; - -typedef struct _CoglMatrixEntryMultiply -{ - CoglMatrixEntry _parent_data; - - graphene_matrix_t matrix; - -} CoglMatrixEntryMultiply; - -typedef struct _CoglMatrixEntryLoad -{ - CoglMatrixEntry _parent_data; - - graphene_matrix_t matrix; - -} CoglMatrixEntryLoad; - -typedef struct _CoglMatrixEntrySave -{ - CoglMatrixEntry _parent_data; - - graphene_matrix_t cache; - gboolean cache_valid; - -} CoglMatrixEntrySave; - -typedef union _CoglMatrixEntryFull -{ - CoglMatrixEntry any; - CoglMatrixEntryTranslate translate; - CoglMatrixEntryRotate rotate; - CoglMatrixEntryRotateEuler rotate_euler; - CoglMatrixEntryScale scale; - CoglMatrixEntryMultiply multiply; - CoglMatrixEntryLoad load; - CoglMatrixEntrySave save; -} CoglMatrixEntryFull; - -struct _CoglMatrixStack -{ - GObject parent_instance; - - CoglContext *context; - - CoglMatrixEntry *last_entry; -}; - -typedef struct _CoglMatrixEntryCache -{ - CoglMatrixEntry *entry; - gboolean flushed_identity; - gboolean flipped; -} CoglMatrixEntryCache; - -void -_cogl_matrix_entry_identity_init (CoglMatrixEntry *entry); - -void -_cogl_matrix_entry_cache_init (CoglMatrixEntryCache *cache); - -gboolean -_cogl_matrix_entry_cache_maybe_update (CoglMatrixEntryCache *cache, - CoglMatrixEntry *entry, - gboolean flip); - -void -_cogl_matrix_entry_cache_destroy (CoglMatrixEntryCache *cache); diff --git a/mutter/cogl/cogl/cogl-matrix-stack.c b/mutter/cogl/cogl/cogl-matrix-stack.c deleted file mode 100644 index 96ac1e3..0000000 --- a/mutter/cogl/cogl/cogl-matrix-stack.c +++ /dev/null @@ -1,935 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009,2010,2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Havoc Pennington for litl - * Robert Bragg - * Neil Roberts - */ - -#include "config.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-graphene.h" -#include "cogl/cogl-matrix-stack.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-offscreen.h" -#include "cogl/cogl-magazine-private.h" - -G_DEFINE_BOXED_TYPE (CoglMatrixEntry, cogl_matrix_entry, - cogl_matrix_entry_ref, - cogl_matrix_entry_unref); - -static CoglMagazine *cogl_matrix_stack_magazine; - -/* XXX: Note: this leaves entry->parent uninitialized! */ -static CoglMatrixEntry * -_cogl_matrix_entry_new (CoglMatrixOp operation) -{ - CoglMatrixEntry *entry = - _cogl_magazine_chunk_alloc (cogl_matrix_stack_magazine); - - entry->ref_count = 1; - entry->op = operation; - -#ifdef COGL_ENABLE_DEBUG - entry->composite_gets = 0; -#endif - - return entry; -} - -G_DEFINE_TYPE (CoglMatrixStack, cogl_matrix_stack, G_TYPE_OBJECT); - -static void -cogl_matrix_stack_dispose (GObject *object) -{ - CoglMatrixStack *stack = COGL_MATRIX_STACK (object); - - cogl_matrix_entry_unref (stack->last_entry); - - G_OBJECT_CLASS (cogl_matrix_stack_parent_class)->dispose (object); -} - -static void -cogl_matrix_stack_init (CoglMatrixStack *stack) -{ -} - -static void -cogl_matrix_stack_class_init (CoglMatrixStackClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = cogl_matrix_stack_dispose; -} - - -static void * -_cogl_matrix_stack_push_entry (CoglMatrixStack *stack, - CoglMatrixEntry *entry) -{ - /* NB: The initial reference of the entry is transferred to the - * stack here. - * - * The stack only maintains a reference to the top of the stack (the - * last entry pushed) and each entry in-turn maintains a reference - * to its parent. - * - * We don't need to take a reference to the parent from the entry - * here because the we are stealing the reference that was held by - * the stack while that parent was previously the top of the stack. - */ - entry->parent = stack->last_entry; - stack->last_entry = entry; - - return entry; -} - -static void * -_cogl_matrix_stack_push_operation (CoglMatrixStack *stack, - CoglMatrixOp operation) -{ - CoglMatrixEntry *entry = _cogl_matrix_entry_new (operation); - - _cogl_matrix_stack_push_entry (stack, entry); - - return entry; -} - -static void * -_cogl_matrix_stack_push_replacement_entry (CoglMatrixStack *stack, - CoglMatrixOp operation) -{ - CoglMatrixEntry *old_top = stack->last_entry; - CoglMatrixEntry *new_top; - - /* This would only be called for operations that completely replace - * the matrix. In that case we don't need to keep a reference to - * anything up to the last save entry. This optimisation could be - * important for applications that aren't using the stack but - * instead just perform their own matrix manipulations and load a - * new stack every frame. If this optimisation isn't done then the - * stack would just grow endlessly. See the comments - * cogl_matrix_stack_pop for a description of how popping works. */ - for (new_top = old_top; - new_top->op != COGL_MATRIX_OP_SAVE && new_top->parent; - new_top = new_top->parent) - ; - - cogl_matrix_entry_ref (new_top); - cogl_matrix_entry_unref (old_top); - stack->last_entry = new_top; - - return _cogl_matrix_stack_push_operation (stack, operation); -} - -void -_cogl_matrix_entry_identity_init (CoglMatrixEntry *entry) -{ - entry->ref_count = 1; - entry->op = COGL_MATRIX_OP_LOAD_IDENTITY; - entry->parent = NULL; -#ifdef COGL_ENABLE_DEBUG - entry->composite_gets = 0; -#endif -} - -void -cogl_matrix_stack_load_identity (CoglMatrixStack *stack) -{ - _cogl_matrix_stack_push_replacement_entry (stack, - COGL_MATRIX_OP_LOAD_IDENTITY); -} - -void -cogl_matrix_stack_translate (CoglMatrixStack *stack, - float x, - float y, - float z) -{ - CoglMatrixEntryTranslate *entry; - - entry = _cogl_matrix_stack_push_operation (stack, COGL_MATRIX_OP_TRANSLATE); - - graphene_point3d_init (&entry->translate, x, y, z); -} - -void -cogl_matrix_stack_rotate (CoglMatrixStack *stack, - float angle, - float x, - float y, - float z) -{ - CoglMatrixEntryRotate *entry; - - entry = _cogl_matrix_stack_push_operation (stack, COGL_MATRIX_OP_ROTATE); - - entry->angle = angle; - graphene_vec3_init (&entry->axis, x, y, z); -} - -void -cogl_matrix_stack_rotate_euler (CoglMatrixStack *stack, - const graphene_euler_t *euler) -{ - CoglMatrixEntryRotateEuler *entry; - - entry = _cogl_matrix_stack_push_operation (stack, - COGL_MATRIX_OP_ROTATE_EULER); - graphene_euler_init_from_euler (&entry->euler, euler); -} - -void -cogl_matrix_stack_scale (CoglMatrixStack *stack, - float x, - float y, - float z) -{ - CoglMatrixEntryScale *entry; - - entry = _cogl_matrix_stack_push_operation (stack, COGL_MATRIX_OP_SCALE); - - entry->x = x; - entry->y = y; - entry->z = z; -} - -void -cogl_matrix_stack_multiply (CoglMatrixStack *stack, - const graphene_matrix_t *matrix) -{ - CoglMatrixEntryMultiply *entry; - - entry = _cogl_matrix_stack_push_operation (stack, COGL_MATRIX_OP_MULTIPLY); - graphene_matrix_init_from_matrix (&entry->matrix, matrix); -} - -void -cogl_matrix_stack_set (CoglMatrixStack *stack, - const graphene_matrix_t *matrix) -{ - CoglMatrixEntryLoad *entry; - - entry = - _cogl_matrix_stack_push_replacement_entry (stack, - COGL_MATRIX_OP_LOAD); - graphene_matrix_init_from_matrix (&entry->matrix, matrix); -} - -void -cogl_matrix_stack_frustum (CoglMatrixStack *stack, - float left, - float right, - float bottom, - float top, - float z_near, - float z_far) -{ - CoglMatrixEntryLoad *entry; - - entry = - _cogl_matrix_stack_push_replacement_entry (stack, - COGL_MATRIX_OP_LOAD); - - graphene_matrix_init_frustum (&entry->matrix, - left, right, - bottom, top, - z_near, z_far); -} - -void -cogl_matrix_stack_perspective (CoglMatrixStack *stack, - float fov_y, - float aspect, - float z_near, - float z_far) -{ - CoglMatrixEntryLoad *entry; - - entry = - _cogl_matrix_stack_push_replacement_entry (stack, - COGL_MATRIX_OP_LOAD); - graphene_matrix_init_perspective (&entry->matrix, - fov_y, aspect, - z_near, z_far); -} - -void -cogl_matrix_stack_orthographic (CoglMatrixStack *stack, - float x_1, - float y_1, - float x_2, - float y_2, - float near, - float far) -{ - CoglMatrixEntryLoad *entry; - - entry = - _cogl_matrix_stack_push_replacement_entry (stack, - COGL_MATRIX_OP_LOAD); - graphene_matrix_init_ortho (&entry->matrix, - x_1, x_2, - y_2, y_1, - near, far); -} - -void -cogl_matrix_stack_push (CoglMatrixStack *stack) -{ - CoglMatrixEntrySave *entry; - - entry = _cogl_matrix_stack_push_operation (stack, COGL_MATRIX_OP_SAVE); - - entry->cache_valid = FALSE; -} - -CoglMatrixEntry * -cogl_matrix_entry_ref (CoglMatrixEntry *entry) -{ - /* A NULL pointer is considered a valid stack so we should accept - that as an argument */ - if (entry) - entry->ref_count++; - - return entry; -} - -void -cogl_matrix_entry_unref (CoglMatrixEntry *entry) -{ - CoglMatrixEntry *parent; - - for (; entry && --entry->ref_count <= 0; entry = parent) - { - parent = entry->parent; - _cogl_magazine_chunk_free (cogl_matrix_stack_magazine, entry); - } -} - -void -cogl_matrix_stack_pop (CoglMatrixStack *stack) -{ - CoglMatrixEntry *old_top; - CoglMatrixEntry *new_top; - - g_return_if_fail (stack != NULL); - - old_top = stack->last_entry; - g_return_if_fail (old_top != NULL); - - /* To pop we are moving the top of the stack to the old top's parent - * node. The stack always needs to have a reference to the top entry - * so we must take a reference to the new top. The stack would have - * previously had a reference to the old top so we need to decrease - * the ref count on that. We need to ref the new head first in case - * this stack was the only thing referencing the old top. In that - * case the call to cogl_matrix_entry_unref will unref the parent. - */ - - /* Find the last save operation and remove it */ - - /* XXX: it would be an error to pop to the very beginning of the - * stack so we don't need to check for NULL pointer dereferencing. */ - for (new_top = old_top; - new_top->op != COGL_MATRIX_OP_SAVE; - new_top = new_top->parent) - ; - - new_top = new_top->parent; - cogl_matrix_entry_ref (new_top); - - cogl_matrix_entry_unref (old_top); - - stack->last_entry = new_top; -} - -gboolean -cogl_matrix_stack_get_inverse (CoglMatrixStack *stack, - graphene_matrix_t *inverse) -{ - graphene_matrix_t matrix; - graphene_matrix_t *internal = cogl_matrix_stack_get (stack, &matrix); - - if (internal) - return graphene_matrix_inverse (internal, inverse); - else - return graphene_matrix_inverse (&matrix, inverse); -} - -/* In addition to writing the stack matrix into the give @matrix - * argument this function *may* sometimes also return a pointer - * to a matrix too so if we are querying the inverse matrix we - * should query from the return matrix so that the result can - * be cached within the stack. */ -graphene_matrix_t * -cogl_matrix_entry_get (CoglMatrixEntry *entry, - graphene_matrix_t *matrix) -{ - CoglMatrixEntry *current; - int depth; - - graphene_matrix_init_identity (matrix); - - for (current = entry, depth = 0; - current; - current = current->parent, depth++) - { - switch (current->op) - { - case COGL_MATRIX_OP_TRANSLATE: - { - CoglMatrixEntryTranslate *translate = - (CoglMatrixEntryTranslate *) current; - graphene_matrix_translate (matrix, &translate->translate); - break; - } - case COGL_MATRIX_OP_ROTATE: - { - CoglMatrixEntryRotate *rotate = - (CoglMatrixEntryRotate *) current; - graphene_matrix_rotate (matrix, rotate->angle, &rotate->axis); - break; - } - case COGL_MATRIX_OP_ROTATE_EULER: - { - CoglMatrixEntryRotateEuler *rotate = - (CoglMatrixEntryRotateEuler *) current; - graphene_matrix_rotate_euler (matrix, &rotate->euler); - break; - } - case COGL_MATRIX_OP_SCALE: - { - CoglMatrixEntryScale *scale = - (CoglMatrixEntryScale *) current; - graphene_matrix_scale (matrix, scale->x, scale->y, scale->z); - break; - } - case COGL_MATRIX_OP_MULTIPLY: - { - CoglMatrixEntryMultiply *multiply = - (CoglMatrixEntryMultiply *) current; - graphene_matrix_multiply (matrix, &multiply->matrix, matrix); - break; - } - - case COGL_MATRIX_OP_LOAD_IDENTITY: - goto applied; - - case COGL_MATRIX_OP_LOAD: - { - CoglMatrixEntryLoad *load = (CoglMatrixEntryLoad *) current; - graphene_matrix_multiply (matrix, &load->matrix, matrix); - goto applied; - } - case COGL_MATRIX_OP_SAVE: - { - CoglMatrixEntrySave *save = (CoglMatrixEntrySave *) current; - if (!save->cache_valid) - { - cogl_matrix_entry_get (current->parent, &save->cache); - save->cache_valid = TRUE; - } - graphene_matrix_multiply (matrix, &save->cache, matrix); - goto applied; - } - } - } - -applied: - -#ifdef COGL_ENABLE_DEBUG - if (!current) - { - g_warning ("Inconsistent matrix stack"); - return NULL; - } - - entry->composite_gets++; - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_PERFORMANCE) && - entry->composite_gets >= 2) - { - COGL_NOTE (PERFORMANCE, - "Re-composing a matrix stack entry multiple times"); - } -#endif - - if (depth == 0) - { - switch (entry->op) - { - case COGL_MATRIX_OP_LOAD_IDENTITY: - case COGL_MATRIX_OP_TRANSLATE: - case COGL_MATRIX_OP_ROTATE: - case COGL_MATRIX_OP_ROTATE_EULER: - case COGL_MATRIX_OP_SCALE: - case COGL_MATRIX_OP_MULTIPLY: - return NULL; - - case COGL_MATRIX_OP_LOAD: - { - CoglMatrixEntryLoad *load = (CoglMatrixEntryLoad *)entry; - return &load->matrix; - } - case COGL_MATRIX_OP_SAVE: - { - CoglMatrixEntrySave *save = (CoglMatrixEntrySave *)entry; - return &save->cache; - } - } - g_warn_if_reached (); - return NULL; - } - - return NULL; -} - -CoglMatrixEntry * -cogl_matrix_stack_get_entry (CoglMatrixStack *stack) -{ - return stack->last_entry; -} - -/* In addition to writing the stack matrix into the give @matrix - * argument this function *may* sometimes also return a pointer - * to a matrix too so if we are querying the inverse matrix we - * should query from the return matrix so that the result can - * be cached within the stack. */ -graphene_matrix_t * -cogl_matrix_stack_get (CoglMatrixStack *stack, - graphene_matrix_t *matrix) -{ - return cogl_matrix_entry_get (stack->last_entry, matrix); -} - -CoglMatrixStack * -cogl_matrix_stack_new (CoglContext *ctx) -{ - CoglMatrixStack *stack = g_object_new (COGL_TYPE_MATRIX_STACK, NULL); - - if (G_UNLIKELY (cogl_matrix_stack_magazine == NULL)) - { - cogl_matrix_stack_magazine = - _cogl_magazine_new (sizeof (CoglMatrixEntryFull), 20); - } - - stack->context = ctx; - stack->last_entry = NULL; - - cogl_matrix_entry_ref (&ctx->identity_entry); - _cogl_matrix_stack_push_entry (stack, &ctx->identity_entry); - - return stack; -} - -static CoglMatrixEntry * -_cogl_matrix_entry_skip_saves (CoglMatrixEntry *entry) -{ - /* We currently assume that every stack starts with an - * _OP_LOAD_IDENTITY so we don't need to worry about - * NULL pointer dereferencing here. */ - while (entry->op == COGL_MATRIX_OP_SAVE) - entry = entry->parent; - - return entry; -} - -gboolean -cogl_matrix_entry_calculate_translation (CoglMatrixEntry *entry0, - CoglMatrixEntry *entry1, - float *x, - float *y, - float *z) -{ - GSList *head0 = NULL; - GSList *head1 = NULL; - CoglMatrixEntry *node0; - CoglMatrixEntry *node1; - int len0 = 0; - int len1 = 0; - int count; - GSList *common_ancestor0; - GSList *common_ancestor1; - - /* Algorithm: - * - * 1) Ignoring _OP_SAVE entries walk the ancestors of each entry to - * the root node or any non-translation node, adding a pointer to - * each ancestor node to two linked lists. - * - * 2) Compare the lists to find the nodes where they start to - * differ marking the common_ancestor node for each list. - * - * 3) For the list corresponding to entry0, start iterating after - * the common ancestor applying the negative of all translations - * to x, y and z. - * - * 4) For the list corresponding to entry1, start iterating after - * the common ancestor applying the positive of all translations - * to x, y and z. - * - * If we come across any non-translation operations during 3) or 4) - * then bail out returning FALSE. - */ - - for (node0 = entry0; node0; node0 = node0->parent) - { - GSList *link; - - if (node0->op == COGL_MATRIX_OP_SAVE) - continue; - - link = alloca (sizeof (GSList)); - link->next = head0; - link->data = node0; - head0 = link; - len0++; - - if (node0->op != COGL_MATRIX_OP_TRANSLATE) - break; - } - for (node1 = entry1; node1; node1 = node1->parent) - { - GSList *link; - - if (node1->op == COGL_MATRIX_OP_SAVE) - continue; - - link = alloca (sizeof (GSList)); - link->next = head1; - link->data = node1; - head1 = link; - len1++; - - if (node1->op != COGL_MATRIX_OP_TRANSLATE) - break; - } - - if (head0->data != head1->data) - return FALSE; - - common_ancestor0 = head0; - common_ancestor1 = head1; - head0 = head0->next; - head1 = head1->next; - count = MIN (len0, len1) - 1; - while (count--) - { - if (head0->data != head1->data) - break; - common_ancestor0 = head0; - common_ancestor1 = head1; - head0 = head0->next; - head1 = head1->next; - } - - *x = 0; - *y = 0; - *z = 0; - - for (head0 = common_ancestor0->next; head0; head0 = head0->next) - { - CoglMatrixEntryTranslate *translate; - - node0 = head0->data; - - if (node0->op != COGL_MATRIX_OP_TRANSLATE) - return FALSE; - - translate = (CoglMatrixEntryTranslate *)node0; - - *x = *x - translate->translate.x; - *y = *y - translate->translate.y; - *z = *z - translate->translate.z; - } - for (head1 = common_ancestor1->next; head1; head1 = head1->next) - { - CoglMatrixEntryTranslate *translate; - - node1 = head1->data; - - if (node1->op != COGL_MATRIX_OP_TRANSLATE) - return FALSE; - - translate = (CoglMatrixEntryTranslate *)node1; - - *x = *x + translate->translate.x; - *y = *y + translate->translate.y; - *z = *z + translate->translate.z; - } - - return TRUE; -} - -gboolean -cogl_matrix_entry_is_identity (CoglMatrixEntry *entry) -{ - return entry ? entry->op == COGL_MATRIX_OP_LOAD_IDENTITY : FALSE; -} - -gboolean -cogl_matrix_entry_equal (CoglMatrixEntry *entry0, - CoglMatrixEntry *entry1) -{ - for (; - entry0 && entry1; - entry0 = entry0->parent, entry1 = entry1->parent) - { - entry0 = _cogl_matrix_entry_skip_saves (entry0); - entry1 = _cogl_matrix_entry_skip_saves (entry1); - - if (entry0 == entry1) - return TRUE; - - if (entry0->op != entry1->op) - return FALSE; - - switch (entry0->op) - { - case COGL_MATRIX_OP_LOAD_IDENTITY: - return TRUE; - case COGL_MATRIX_OP_TRANSLATE: - { - CoglMatrixEntryTranslate *translate0 = - (CoglMatrixEntryTranslate *)entry0; - CoglMatrixEntryTranslate *translate1 = - (CoglMatrixEntryTranslate *)entry1; - /* We could perhaps use an epsilon to compare here? - * I expect the false negatives are probably never going to - * be a problem and this is a bit cheaper. */ - if (!graphene_point3d_equal (&translate0->translate, - &translate1->translate)) - return FALSE; - } - break; - case COGL_MATRIX_OP_ROTATE: - { - CoglMatrixEntryRotate *rotate0 = - (CoglMatrixEntryRotate *)entry0; - CoglMatrixEntryRotate *rotate1 = - (CoglMatrixEntryRotate *)entry1; - if (rotate0->angle != rotate1->angle || - !graphene_vec3_equal (&rotate0->axis, &rotate1->axis)) - return FALSE; - } - break; - case COGL_MATRIX_OP_ROTATE_EULER: - { - CoglMatrixEntryRotateEuler *rotate0 = - (CoglMatrixEntryRotateEuler *)entry0; - CoglMatrixEntryRotateEuler *rotate1 = - (CoglMatrixEntryRotateEuler *)entry1; - - if (!graphene_euler_equal (&rotate0->euler, &rotate1->euler)) - return FALSE; - } - break; - case COGL_MATRIX_OP_SCALE: - { - CoglMatrixEntryScale *scale0 = (CoglMatrixEntryScale *)entry0; - CoglMatrixEntryScale *scale1 = (CoglMatrixEntryScale *)entry1; - if (scale0->x != scale1->x || - scale0->y != scale1->y || - scale0->z != scale1->z) - return FALSE; - } - break; - case COGL_MATRIX_OP_MULTIPLY: - { - CoglMatrixEntryMultiply *mult0 = (CoglMatrixEntryMultiply *)entry0; - CoglMatrixEntryMultiply *mult1 = (CoglMatrixEntryMultiply *)entry1; - if (!graphene_matrix_equal (&mult0->matrix, &mult1->matrix)) - return FALSE; - } - break; - case COGL_MATRIX_OP_LOAD: - { - CoglMatrixEntryLoad *load0 = (CoglMatrixEntryLoad *)entry0; - CoglMatrixEntryLoad *load1 = (CoglMatrixEntryLoad *)entry1; - /* There's no need to check any further since an - * _OP_LOAD makes all the ancestors redundant as far as - * the final matrix value is concerned. */ - return graphene_matrix_equal (&load0->matrix, &load1->matrix); - } - case COGL_MATRIX_OP_SAVE: - /* We skip over saves above so we shouldn't see save entries */ - g_warn_if_reached (); - } - } - - return FALSE; -} - -void -cogl_debug_matrix_entry_print (CoglMatrixEntry *entry) -{ - int depth; - CoglMatrixEntry *e; - CoglMatrixEntry **children; - int i; - - for (depth = 0, e = entry; e; e = e->parent) - depth++; - - children = g_alloca (sizeof (CoglMatrixEntry) * depth); - - for (i = depth - 1, e = entry; - i >= 0 && e; - i--, e = e->parent) - { - children[i] = e; - } - - g_print ("MatrixEntry %p =\n", entry); - - for (i = 0; i < depth; i++) - { - entry = children[i]; - - switch (entry->op) - { - case COGL_MATRIX_OP_LOAD_IDENTITY: - g_print (" LOAD IDENTITY\n"); - continue; - case COGL_MATRIX_OP_TRANSLATE: - { - CoglMatrixEntryTranslate *translate = - (CoglMatrixEntryTranslate *)entry; - g_print (" TRANSLATE X=%f Y=%f Z=%f\n", - translate->translate.x, - translate->translate.y, - translate->translate.z); - continue; - } - case COGL_MATRIX_OP_ROTATE: - { - CoglMatrixEntryRotate *rotate = - (CoglMatrixEntryRotate *)entry; - g_print (" ROTATE ANGLE=%f X=%f Y=%f Z=%f\n", - rotate->angle, - graphene_vec3_get_x (&rotate->axis), - graphene_vec3_get_y (&rotate->axis), - graphene_vec3_get_z (&rotate->axis)); - continue; - } - case COGL_MATRIX_OP_ROTATE_EULER: - { - CoglMatrixEntryRotateEuler *rotate = - (CoglMatrixEntryRotateEuler *)entry; - g_print (" ROTATE EULER heading=%f pitch=%f roll=%f\n", - graphene_euler_get_y (&rotate->euler), - graphene_euler_get_x (&rotate->euler), - graphene_euler_get_z (&rotate->euler)); - continue; - } - case COGL_MATRIX_OP_SCALE: - { - CoglMatrixEntryScale *scale = (CoglMatrixEntryScale *)entry; - g_print (" SCALE X=%f Y=%f Z=%f\n", - scale->x, - scale->y, - scale->z); - continue; - } - case COGL_MATRIX_OP_MULTIPLY: - { - CoglMatrixEntryMultiply *mult = (CoglMatrixEntryMultiply *)entry; - g_print (" MULT:\n"); - graphene_matrix_print (&mult->matrix); - continue; - } - case COGL_MATRIX_OP_LOAD: - { - CoglMatrixEntryLoad *load = (CoglMatrixEntryLoad *)entry; - g_print (" LOAD:\n"); - graphene_matrix_print (&load->matrix); - continue; - } - case COGL_MATRIX_OP_SAVE: - g_print (" SAVE\n"); - } - } -} - -void -_cogl_matrix_entry_cache_init (CoglMatrixEntryCache *cache) -{ - cache->entry = NULL; - cache->flushed_identity = FALSE; - cache->flipped = FALSE; -} - -/* NB: This function can report false negatives since it never does a - * deep comparison of the stack matrices. */ -gboolean -_cogl_matrix_entry_cache_maybe_update (CoglMatrixEntryCache *cache, - CoglMatrixEntry *entry, - gboolean flip) -{ - gboolean is_identity; - gboolean updated = FALSE; - - if (cache->flipped != flip) - { - cache->flipped = flip; - updated = TRUE; - } - - is_identity = (entry->op == COGL_MATRIX_OP_LOAD_IDENTITY); - if (cache->flushed_identity != is_identity) - { - cache->flushed_identity = is_identity; - updated = TRUE; - } - - if (cache->entry != entry) - { - cogl_matrix_entry_ref (entry); - if (cache->entry) - cogl_matrix_entry_unref (cache->entry); - cache->entry = entry; - - /* We want to make sure here that if the cache->entry and the - * given @entry are both identity matrices then even though they - * are different entries we don't want to consider this an - * update... - */ - updated |= !is_identity; - } - - return updated; -} - -void -_cogl_matrix_entry_cache_destroy (CoglMatrixEntryCache *cache) -{ - if (cache->entry) - cogl_matrix_entry_unref (cache->entry); -} diff --git a/mutter/cogl/cogl/cogl-matrix-stack.h b/mutter/cogl/cogl/cogl-matrix-stack.h deleted file mode 100644 index 343c533..0000000 --- a/mutter/cogl/cogl/cogl-matrix-stack.h +++ /dev/null @@ -1,562 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009,2010,2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Havoc Pennington for litl - * Robert Bragg - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-context.h" - -#include - -/** - * CoglMatrixStack: - * - * Efficiently tracking many related transformations. - * - * Tracks your current position within a hierarchy and lets you build - * up a graph of transformations as you traverse through a hierarchy - * such as a scenegraph. - * - * A #CoglMatrixStack always maintains a reference to a single - * transformation at any point in time, representing the - * transformation at the current position in the hierarchy. You can - * get a reference to the current transformation by calling - * cogl_matrix_stack_get_entry(). - * - * When a #CoglMatrixStack is first created with - * cogl_matrix_stack_new() then it is conceptually positioned at the - * root of your hierarchy and the current transformation simply - * represents an identity transformation. - * - * As you traverse your object hierarchy (your scenegraph) then you - * should call cogl_matrix_stack_push() whenever you move down one - * level and call cogl_matrix_stack_pop() whenever you move back up - * one level towards the root. - * - * At any time you can apply a set of operations, such as "rotate", - * "scale", "translate" on top of the current transformation of a - * #CoglMatrixStack using functions such as - * cogl_matrix_stack_rotate(), cogl_matrix_stack_scale() and - * cogl_matrix_stack_translate(). These operations will derive a new - * current transformation and will never affect a transformation - * that you have referenced using cogl_matrix_stack_get_entry(). - * - * Internally applying operations to a #CoglMatrixStack builds up a - * graph of #CoglMatrixEntry structures which each represent a single - * immutable transform. - */ -typedef struct _CoglMatrixStack CoglMatrixStack; - -#define COGL_TYPE_MATRIX_STACK (cogl_matrix_stack_get_type ()) - -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglMatrixStack, - cogl_matrix_stack, - COGL, - MATRIX_STACK, - GObject) - -/** - * CoglMatrixEntry: - * - * Represents a single immutable transformation that was retrieved - * from a #CoglMatrixStack using cogl_matrix_stack_get_entry(). - * - * Internally a #CoglMatrixEntry represents a single matrix - * operation (such as "rotate", "scale", "translate") which is applied - * to the transform of a single parent entry. - * - * Using the #CoglMatrixStack api effectively builds up a graph of - * these immutable #CoglMatrixEntry structures whereby operations - * that can be shared between multiple transformations will result - * in shared #CoglMatrixEntry nodes in the graph. - * - * When a #CoglMatrixStack is first created it references one - * #CoglMatrixEntry that represents a single "load identity" - * operation. This serves as the root entry and all operations - * that are then applied to the stack will extend the graph - * starting from this root "load identity" entry. - * - * Given the typical usage model for a #CoglMatrixStack and the way - * the entries are built up while traversing a scenegraph then in most - * cases where an application is interested in comparing two - * transformations for equality then it is enough to simply compare - * two #CoglMatrixEntry pointers directly. Technically this can lead - * to false negatives that could be identified with a deeper - * comparison but often these false negatives are unlikely and - * don't matter anyway so this enables extremely cheap comparisons. - * - * `CoglMatrixEntry`s are reference counted using - * cogl_matrix_entry_ref() and cogl_matrix_entry_unref() not with - * g_object_ref() and g_object_unref(). - */ -typedef struct _CoglMatrixEntry CoglMatrixEntry; - -/** - * cogl_matrix_entry_get_type: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_matrix_entry_get_type (void); - - -/** - * cogl_matrix_stack_new: - * @ctx: A #CoglContext - * - * Allocates a new #CoglMatrixStack that can be used to build up - * transformations relating to objects in a scenegraph like hierarchy. - * (See the description of #CoglMatrixStack and #CoglMatrixEntry for - * more details of what a matrix stack is best suited for) - * - * When a #CoglMatrixStack is first allocated it is conceptually - * positioned at the root of your scenegraph hierarchy. As you - * traverse your scenegraph then you should call - * cogl_matrix_stack_push() whenever you move down a level and - * cogl_matrix_stack_pop() whenever you move back up a level towards - * the root. - * - * Once you have allocated a #CoglMatrixStack you can get a reference - * to the current transformation for the current position in the - * hierarchy by calling cogl_matrix_stack_get_entry(). - * - * Once you have allocated a #CoglMatrixStack you can apply operations - * such as rotate, scale and translate to modify the current transform - * for the current position in the hierarchy by calling - * cogl_matrix_stack_rotate(), cogl_matrix_stack_scale() and - * cogl_matrix_stack_translate(). - * - * Return value: (transfer full): A newly allocated #CoglMatrixStack - */ -COGL_EXPORT CoglMatrixStack * -cogl_matrix_stack_new (CoglContext *ctx); - -/** - * cogl_matrix_stack_push: - * @stack: A #CoglMatrixStack - * - * Saves the current transform and starts a new transform that derives - * from the current transform. - * - * This is usually called while traversing a scenegraph whenever you - * traverse one level deeper. cogl_matrix_stack_pop() can then be - * called when going back up one layer to restore the previous - * transform of an ancestor. - */ -COGL_EXPORT void -cogl_matrix_stack_push (CoglMatrixStack *stack); - -/** - * cogl_matrix_stack_pop: - * @stack: A #CoglMatrixStack - * - * Restores the previous transform that was last saved by calling - * cogl_matrix_stack_push(). - * - * This is usually called while traversing a scenegraph whenever you - * return up one level in the graph towards the root node. - */ -COGL_EXPORT void -cogl_matrix_stack_pop (CoglMatrixStack *stack); - -/** - * cogl_matrix_stack_load_identity: - * @stack: A #CoglMatrixStack - * - * Resets the current matrix to the identity matrix. - */ -COGL_EXPORT void -cogl_matrix_stack_load_identity (CoglMatrixStack *stack); - -/** - * cogl_matrix_stack_scale: - * @stack: A #CoglMatrixStack - * @x: Amount to scale along the x-axis - * @y: Amount to scale along the y-axis - * @z: Amount to scale along the z-axis - * - * Multiplies the current matrix by one that scales the x, y and z - * axes by the given values. - */ -COGL_EXPORT void -cogl_matrix_stack_scale (CoglMatrixStack *stack, - float x, - float y, - float z); - -/** - * cogl_matrix_stack_translate: - * @stack: A #CoglMatrixStack - * @x: Distance to translate along the x-axis - * @y: Distance to translate along the y-axis - * @z: Distance to translate along the z-axis - * - * Multiplies the current matrix by one that translates along all - * three axes according to the given values. - */ -COGL_EXPORT void -cogl_matrix_stack_translate (CoglMatrixStack *stack, - float x, - float y, - float z); - -/** - * cogl_matrix_stack_rotate: - * @stack: A #CoglMatrixStack - * @angle: Angle in degrees to rotate. - * @x: X-component of vertex to rotate around. - * @y: Y-component of vertex to rotate around. - * @z: Z-component of vertex to rotate around. - * - * Multiplies the current matrix by one that rotates the around the - * axis-vector specified by @x, @y and @z. The rotation follows the - * right-hand thumb rule so for example rotating by 10 degrees about - * the axis-vector (0, 0, 1) causes a small counter-clockwise - * rotation. - */ -COGL_EXPORT void -cogl_matrix_stack_rotate (CoglMatrixStack *stack, - float angle, - float x, - float y, - float z); - -/** - * cogl_matrix_stack_rotate_euler: - * @stack: A #CoglMatrixStack - * @euler: A #graphene_euler_t - * - * Multiplies the current matrix by one that rotates according to the - * rotation described by @euler. - */ -COGL_EXPORT void -cogl_matrix_stack_rotate_euler (CoglMatrixStack *stack, - const graphene_euler_t *euler); - -/** - * cogl_matrix_stack_multiply: - * @stack: A #CoglMatrixStack - * @matrix: the matrix to multiply with the current model-view - * - * Multiplies the current matrix by the given matrix. - */ -COGL_EXPORT void -cogl_matrix_stack_multiply (CoglMatrixStack *stack, - const graphene_matrix_t *matrix); - -/** - * cogl_matrix_stack_frustum: - * @stack: A #CoglMatrixStack - * @left: X position of the left clipping plane where it - * intersects the near clipping plane - * @right: X position of the right clipping plane where it - * intersects the near clipping plane - * @bottom: Y position of the bottom clipping plane where it - * intersects the near clipping plane - * @top: Y position of the top clipping plane where it intersects - * the near clipping plane - * @z_near: The distance to the near clipping plane (Must be positive) - * @z_far: The distance to the far clipping plane (Must be positive) - * - * Replaces the current matrix with a perspective matrix for a given - * viewing frustum defined by 4 side clip planes that all cross - * through the origin and 2 near and far clip planes. - */ -COGL_EXPORT void -cogl_matrix_stack_frustum (CoglMatrixStack *stack, - float left, - float right, - float bottom, - float top, - float z_near, - float z_far); - -/** - * cogl_matrix_stack_perspective: - * @stack: A #CoglMatrixStack - * @fov_y: Vertical field of view angle in degrees. - * @aspect: The (width over height) aspect ratio for display - * @z_near: The distance to the near clipping plane (Must be positive, - * and must not be 0) - * @z_far: The distance to the far clipping plane (Must be positive) - * - * Replaces the current matrix with a perspective matrix based on the - * provided values. - * - * You should be careful not to have too great a @z_far / @z_near - * ratio since that will reduce the effectiveness of depth testing - * since there won't be enough precision to identify the depth of - * objects near to each other. - */ -COGL_EXPORT void -cogl_matrix_stack_perspective (CoglMatrixStack *stack, - float fov_y, - float aspect, - float z_near, - float z_far); - -/** - * cogl_matrix_stack_orthographic: - * @stack: A #CoglMatrixStack - * @x_1: The x coordinate for the first vertical clipping plane - * @y_1: The y coordinate for the first horizontal clipping plane - * @x_2: The x coordinate for the second vertical clipping plane - * @y_2: The y coordinate for the second horizontal clipping plane - * @near: The *distance* to the near clipping - * plane (will be *negative* if the plane is - * behind the viewer) - * @far: The *distance* to the far clipping - * plane (will be *negative* if the plane is - * behind the viewer) - * - * Replaces the current matrix with an orthographic projection matrix. - */ -COGL_EXPORT void -cogl_matrix_stack_orthographic (CoglMatrixStack *stack, - float x_1, - float y_1, - float x_2, - float y_2, - float near, - float far); - -/** - * cogl_matrix_stack_get_inverse: - * @stack: A #CoglMatrixStack - * @inverse: (out): The destination for a 4x4 inverse transformation matrix - * - * Gets the inverse transform of the current matrix and uses it to - * initialize a new #graphene_matrix_t. - * - * Return value: %TRUE if the inverse was successfully calculated or %FALSE - * for degenerate transformations that can't be inverted (in this case the - * @inverse matrix will simply be initialized with the identity matrix) - */ -COGL_EXPORT gboolean -cogl_matrix_stack_get_inverse (CoglMatrixStack *stack, - graphene_matrix_t *inverse); - -/** - * cogl_matrix_stack_get_entry: - * @stack: A #CoglMatrixStack - * - * Gets a reference to the current transform represented by a - * #CoglMatrixEntry pointer. - * - * The transform represented by a #CoglMatrixEntry is - * immutable. - * - * `CoglMatrixEntry`s are reference counted using - * cogl_matrix_entry_ref() and cogl_matrix_entry_unref() and you - * should call cogl_matrix_entry_unref() when you are finished with - * and entry you get via cogl_matrix_stack_get_entry(). - * - * Return value: (transfer none): A pointer to the #CoglMatrixEntry - * representing the current matrix stack transform. - */ -COGL_EXPORT CoglMatrixEntry * -cogl_matrix_stack_get_entry (CoglMatrixStack *stack); - -/** - * cogl_matrix_stack_get: - * @stack: A #CoglMatrixStack - * @matrix: (out): The potential destination for the current matrix - * - * Resolves the current @stack transform into a #graphene_matrix_t by - * combining the operations that have been applied to build up the - * current transform. - * - * There are two possible ways that this function may return its - * result depending on whether the stack is able to directly point - * to an internal #graphene_matrix_t or whether the result needs to be - * composed of multiple operations. - * - * If an internal matrix contains the required result then this - * function will directly return a pointer to that matrix, otherwise - * if the function returns %NULL then @matrix will be initialized - * to match the current transform of @stack. - * - * @matrix will be left untouched if a direct pointer is - * returned. - * - * Return value: A direct pointer to the current transform or %NULL - * and in that case @matrix will be initialized with - * the value of the current transform. - */ -COGL_EXPORT graphene_matrix_t * -cogl_matrix_stack_get (CoglMatrixStack *stack, - graphene_matrix_t *matrix); - -/** - * cogl_matrix_entry_get: - * @entry: A #CoglMatrixEntry - * @matrix: (out): The potential destination for the transform as - * a matrix - * - * Resolves the current @entry transform into a #graphene_matrix_t by - * combining the sequence of operations that have been applied to - * build up the current transform. - * - * There are two possible ways that this function may return its - * result depending on whether it's possible to directly point - * to an internal #graphene_matrix_t or whether the result needs to be - * composed of multiple operations. - * - * If an internal matrix contains the required result then this - * function will directly return a pointer to that matrix, otherwise - * if the function returns %NULL then @matrix will be initialized - * to match the transform of @entry. - * - * @matrix will be left untouched if a direct pointer is - * returned. - * - * Return value: A direct pointer to a #graphene_matrix_t transform or %NULL - * and in that case @matrix will be initialized with - * the effective transform represented by @entry. - */ -COGL_EXPORT graphene_matrix_t * -cogl_matrix_entry_get (CoglMatrixEntry *entry, - graphene_matrix_t *matrix); - -/** - * cogl_matrix_stack_set: - * @stack: A #CoglMatrixStack - * @matrix: A #graphene_matrix_t replace the current matrix value with - * - * Replaces the current @stack matrix value with the value of @matrix. - * This effectively discards any other operations that were applied - * since the last time cogl_matrix_stack_push() was called or since - * the stack was initialized. - */ -COGL_EXPORT void -cogl_matrix_stack_set (CoglMatrixStack *stack, - const graphene_matrix_t *matrix); - -/** - * cogl_matrix_entry_calculate_translation: - * @entry0: The first reference transform - * @entry1: A second reference transform - * @x: (out): The destination for the x-component of the translation - * @y: (out): The destination for the y-component of the translation - * @z: (out): The destination for the z-component of the translation - * - * Determines if the only difference between two transforms is a - * translation and if so returns what the @x, @y, and @z components of - * the translation are. - * - * If the difference between the two translations involves anything - * other than a translation then the function returns %FALSE. - * - * Return value: %TRUE if the only difference between the transform of - * @entry0 and the transform of @entry1 is a translation, - * otherwise %FALSE. - */ -COGL_EXPORT gboolean -cogl_matrix_entry_calculate_translation (CoglMatrixEntry *entry0, - CoglMatrixEntry *entry1, - float *x, - float *y, - float *z); - -/** - * cogl_matrix_entry_is_identity: - * @entry: A #CoglMatrixEntry - * - * Determines whether @entry is known to represent an identity - * transform. - * - * If this returns %TRUE then the entry is definitely the identity - * matrix. If it returns %FALSE it may or may not be the identity - * matrix but no expensive comparison is performed to verify it. - * - * Return value: %TRUE if @entry is definitely an identity transform, - * otherwise %FALSE. - */ -COGL_EXPORT gboolean -cogl_matrix_entry_is_identity (CoglMatrixEntry *entry); - -/** - * cogl_matrix_entry_equal: - * @entry0: The first #CoglMatrixEntry to compare - * @entry1: A second #CoglMatrixEntry to compare - * - * Compares two arbitrary #CoglMatrixEntry transforms for equality - * returning %TRUE if they are equal or %FALSE otherwise. - * - * In many cases it is unnecessary to use this api and instead - * direct pointer comparisons of entries are good enough and much - * cheaper too. - * - * Return value: %TRUE if @entry0 represents the same transform as - * @entry1, otherwise %FALSE. - */ -COGL_EXPORT gboolean -cogl_matrix_entry_equal (CoglMatrixEntry *entry0, - CoglMatrixEntry *entry1); - -/** - * cogl_debug_matrix_entry_print: - * @entry: A #CoglMatrixEntry - * - * Allows visualizing the operations that build up the given @entry - * for debugging purposes by printing to stdout. - */ -COGL_EXPORT void -cogl_debug_matrix_entry_print (CoglMatrixEntry *entry); - -/** - * cogl_matrix_entry_ref: - * @entry: A #CoglMatrixEntry - * - * Takes a reference on the given @entry to ensure the @entry stays - * alive and remains valid. When you are finished with the @entry then - * you should call cogl_matrix_entry_unref(). - */ -COGL_EXPORT CoglMatrixEntry * -cogl_matrix_entry_ref (CoglMatrixEntry *entry); - -/** - * cogl_matrix_entry_unref: - * @entry: A #CoglMatrixEntry - * - * Releases a reference on @entry either taken by calling - * cogl_matrix_entry_unref() or to release the reference given when - * calling cogl_matrix_stack_get_entry(). - */ -COGL_EXPORT void -cogl_matrix_entry_unref (CoglMatrixEntry *entry); diff --git a/mutter/cogl/cogl/cogl-memory-stack-private.h b/mutter/cogl/cogl/cogl-memory-stack-private.h deleted file mode 100644 index fd6375b..0000000 --- a/mutter/cogl/cogl/cogl-memory-stack-private.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include - -typedef struct _CoglMemoryStack CoglMemoryStack; - -CoglMemoryStack * -_cogl_memory_stack_new (size_t initial_size_bytes); - -void * -_cogl_memory_stack_alloc (CoglMemoryStack *stack, size_t bytes); - -void -_cogl_memory_stack_free (CoglMemoryStack *stack); diff --git a/mutter/cogl/cogl/cogl-memory-stack.c b/mutter/cogl/cogl/cogl-memory-stack.c deleted file mode 100644 index a7e2971..0000000 --- a/mutter/cogl/cogl/cogl-memory-stack.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * CoglMemoryStack provides a really simple, but lightning fast - * memory stack allocation strategy: - * - * - The underlying pool of memory is grow-only. - * - The pool is considered to be a stack which may be comprised - * of multiple smaller stacks. Allocation is done as follows: - * - If there's enough memory in the current sub-stack then the - * stack-pointer will be returned as the allocation and the - * stack-pointer will be incremented by the allocation size. - * - If there isn't enough memory in the current sub-stack - * then a new sub-stack is allocated twice as big as the current - * sub-stack or twice as big as the requested allocation size if - * that's bigger and the stack-pointer is set to the start of the - * new sub-stack. - * - Allocations can't be freed in a random-order, you can only - * rewind the entire stack back to the start. There is no - * the concept of stack frames to allow partial rewinds. - * - * For example; we plan to use this in our tessellator which has to - * allocate lots of small vertex, edge and face structures because - * when tessellation has been finished we just want to free the whole - * lot in one go. - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-memory-stack-private.h" -#include "cogl/cogl-list.h" - -#include - -#include - -typedef struct _CoglMemorySubStack -{ - CoglList link; - size_t bytes; - uint8_t *data; -} CoglMemorySubStack; - -struct _CoglMemoryStack -{ - CoglList sub_stacks; - - CoglMemorySubStack *sub_stack; - size_t sub_stack_offset; -}; - -static CoglMemorySubStack * -_cogl_memory_sub_stack_alloc (size_t bytes) -{ - CoglMemorySubStack *sub_stack = g_new0 (CoglMemorySubStack, 1); - sub_stack->bytes = bytes; - sub_stack->data = g_malloc (bytes); - return sub_stack; -} - -static void -_cogl_memory_stack_add_sub_stack (CoglMemoryStack *stack, - size_t sub_stack_bytes) -{ - CoglMemorySubStack *sub_stack = - _cogl_memory_sub_stack_alloc (sub_stack_bytes); - _cogl_list_insert (stack->sub_stacks.prev, &sub_stack->link); - stack->sub_stack = sub_stack; - stack->sub_stack_offset = 0; -} - -CoglMemoryStack * -_cogl_memory_stack_new (size_t initial_size_bytes) -{ - CoglMemoryStack *stack = g_new0 (CoglMemoryStack, 1); - - _cogl_list_init (&stack->sub_stacks); - - _cogl_memory_stack_add_sub_stack (stack, initial_size_bytes); - - return stack; -} - -void * -_cogl_memory_stack_alloc (CoglMemoryStack *stack, size_t bytes) -{ - CoglMemorySubStack *sub_stack; - void *ret; - - sub_stack = stack->sub_stack; - if (G_LIKELY (sub_stack->bytes - stack->sub_stack_offset >= bytes)) - { - ret = sub_stack->data + stack->sub_stack_offset; - stack->sub_stack_offset += bytes; - return ret; - } - - /* If the stack has been rewound and then a large initial allocation - * is made then we may need to skip over one or more of the - * sub-stacks that are too small for the requested allocation - * size... */ - for (_cogl_list_set_iterator (sub_stack->link.next, sub_stack, link); - &sub_stack->link != &stack->sub_stacks; - _cogl_list_set_iterator (sub_stack->link.next, sub_stack, link)) - { - if (sub_stack->bytes >= bytes) - { - ret = sub_stack->data; - stack->sub_stack = sub_stack; - stack->sub_stack_offset = bytes; - return ret; - } - } - - /* Finally if we couldn't find a free sub-stack with enough space - * for the requested allocation we allocate another sub-stack that's - * twice as big as the last sub-stack or twice as big as the - * requested allocation if that's bigger. - */ - - sub_stack = _cogl_container_of (stack->sub_stacks.prev, - CoglMemorySubStack, - link); - - _cogl_memory_stack_add_sub_stack (stack, MAX (sub_stack->bytes, bytes) * 2); - - sub_stack = _cogl_container_of (stack->sub_stacks.prev, - CoglMemorySubStack, - link); - - stack->sub_stack_offset += bytes; - - return sub_stack->data; -} - -static void -_cogl_memory_sub_stack_free (CoglMemorySubStack *sub_stack) -{ - g_free (sub_stack->data); - g_free (sub_stack); -} - -void -_cogl_memory_stack_free (CoglMemoryStack *stack) -{ - - while (!_cogl_list_empty (&stack->sub_stacks)) - { - CoglMemorySubStack *sub_stack = - _cogl_container_of (stack->sub_stacks.next, CoglMemorySubStack, link); - _cogl_list_remove (&sub_stack->link); - _cogl_memory_sub_stack_free (sub_stack); - } - - g_free (stack); -} diff --git a/mutter/cogl/cogl/cogl-meta-texture.c b/mutter/cogl/cogl/cogl-meta-texture.c deleted file mode 100644 index 8da0cdb..0000000 --- a/mutter/cogl/cogl/cogl-meta-texture.c +++ /dev/null @@ -1,580 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-texture.h" -#include "cogl/cogl-spans.h" -#include "cogl/cogl-meta-texture.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-pipeline-layer-state.h" - -#include -#include - -typedef struct _ForeachData -{ - float meta_region_coords[4]; - CoglPipelineWrapMode wrap_s; - CoglPipelineWrapMode wrap_t; - CoglMetaTextureCallback callback; - void *user_data; - - int width; - int height; - - CoglTexture *padded_textures[9]; - const float *grid_slice_texture_coords; - float slice_offset_s; - float slice_offset_t; - float slice_range_s; - float slice_range_t; -} ForeachData; - -static void -padded_grid_repeat_cb (CoglTexture *slice_texture, - const float *slice_texture_coords, - const float *meta_coords, - void *user_data) -{ - ForeachData *data; - float mapped_coords[4]; - - /* Ignore padding slices for the current grid */ - if (!slice_texture) - return; - - data = user_data; - - /* NB: the slice_texture_coords[] we get here will always be - * normalized. - * - * We now need to map the normalized slice_texture_coords[] we have - * here back to the real slice coordinates we saved in the previous - * stage... - */ - mapped_coords[0] = - slice_texture_coords[0] * data->slice_range_s + data->slice_offset_s; - mapped_coords[1] = - slice_texture_coords[1] * data->slice_range_t + data->slice_offset_t; - mapped_coords[2] = - slice_texture_coords[2] * data->slice_range_s + data->slice_offset_s; - mapped_coords[3] = - slice_texture_coords[3] * data->slice_range_t + data->slice_offset_t; - - data->callback (slice_texture, - mapped_coords, meta_coords, data->user_data); -} - -static int -setup_padded_spans (CoglSpan *spans, - float start, - float end, - float range, - int *real_index) -{ - int span_index = 0; - - if (start > 0) - { - spans[0].start = 0; - spans[0].size = start; - spans[0].waste = 0; - span_index++; - spans[1].start = spans[0].size; - } - else - spans[span_index].start = 0; - - spans[span_index].size = end - start; - spans[span_index].waste = 0; - *real_index = span_index; - span_index++; - - if (end < range) - { - spans[span_index].start = - spans[span_index - 1].start + spans[span_index - 1].size; - spans[span_index].size = range - end; - spans[span_index].waste = 0; - span_index++; - } - - return span_index; -} - -/* This handles each sub-texture within the range [0,1] of our - * original meta texture and repeats each one separately across the - * users requested virtual texture coordinates. - * - * A notable advantage of this approach is that we will batch - * together callbacks corresponding to the same underlying slice - * together. - */ -static void -create_grid_and_repeat_cb (CoglTexture *slice_texture, - const float *slice_texture_coords, - const float *meta_coords, - void *user_data) -{ - ForeachData *data = user_data; - CoglSpan x_spans[3]; - int n_x_spans; - int x_real_index; - CoglSpan y_spans[3]; - int n_y_spans; - int y_real_index; - - /* NB: This callback is called for each slice of the meta-texture - * in the range [0,1]. - * - * We define a "padded grid" for each slice of the meta-texture in - * the range [0,1]. The x axis and y axis grid lines are defined - * using CoglSpans. - * - * The padded grid maps over the meta-texture coordinates in the - * range [0,1] but only contains one valid cell that corresponds to - * current slice being iterated and all the surrounding cells just - * provide padding. - * - * Once we've defined our padded grid we then repeat that across - * the user's original region, calling their callback whenever - * we see our current slice - ignoring padding. - * - * NB: we can assume meta_coords[] are normalized at this point - * since TextureRectangles aren't iterated with this code-path. - * - * NB: spans are always defined using non-normalized coordinates - */ - n_x_spans = setup_padded_spans (x_spans, - meta_coords[0] * data->width, - meta_coords[2] * data->width, - data->width, - &x_real_index); - n_y_spans = setup_padded_spans (y_spans, - meta_coords[1] * data->height, - meta_coords[3] * data->height, - data->height, - &y_real_index); - - data->padded_textures[n_x_spans * y_real_index + x_real_index] = - slice_texture; - - /* Our callback is going to be passed normalized slice texture - * coordinates, and we will need to map the range [0,1] to the real - * slice_texture_coords we have here... */ - data->grid_slice_texture_coords = slice_texture_coords; - data->slice_range_s = fabs (data->grid_slice_texture_coords[2] - - data->grid_slice_texture_coords[0]); - data->slice_range_t = fabs (data->grid_slice_texture_coords[3] - - data->grid_slice_texture_coords[1]); - data->slice_offset_s = MIN (data->grid_slice_texture_coords[0], - data->grid_slice_texture_coords[2]); - data->slice_offset_t = MIN (data->grid_slice_texture_coords[1], - data->grid_slice_texture_coords[3]); - - /* Now actually iterate the region the user originally requested - * using the current padded grid */ - _cogl_texture_spans_foreach_in_region (x_spans, - n_x_spans, - y_spans, - n_y_spans, - data->padded_textures, - data->meta_region_coords, - data->width, - data->height, - data->wrap_s, - data->wrap_t, - padded_grid_repeat_cb, - data); - - /* Clear the padded_textures ready for the next iteration */ - data->padded_textures[n_x_spans * y_real_index + x_real_index] = NULL; -} - -#define SWAP(A,B) do { float tmp = B; B = A; A = tmp; } while (0) - -typedef struct _ClampData -{ - float start; - float end; - gboolean s_flipped; - gboolean t_flipped; - CoglMetaTextureCallback callback; - void *user_data; -} ClampData; - -static void -clamp_s_cb (CoglTexture *sub_texture, - const float *sub_texture_coords, - const float *meta_coords, - void *user_data) -{ - ClampData *clamp_data = user_data; - float mapped_meta_coords[4] = { - clamp_data->start, - meta_coords[1], - clamp_data->end, - meta_coords[3] - }; - if (clamp_data->s_flipped) - SWAP (mapped_meta_coords[0], mapped_meta_coords[2]); - /* NB: we never need to flip the t coords when dealing with - * s-axis clamping so no need to check if ->t_flipped */ - clamp_data->callback (sub_texture, - sub_texture_coords, mapped_meta_coords, - clamp_data->user_data); -} - -static void -clamp_t_cb (CoglTexture *sub_texture, - const float *sub_texture_coords, - const float *meta_coords, - void *user_data) -{ - ClampData *clamp_data = user_data; - float mapped_meta_coords[4] = { - meta_coords[0], - clamp_data->start, - meta_coords[2], - clamp_data->end, - }; - if (clamp_data->s_flipped) - SWAP (mapped_meta_coords[0], mapped_meta_coords[2]); - if (clamp_data->t_flipped) - SWAP (mapped_meta_coords[1], mapped_meta_coords[3]); - clamp_data->callback (sub_texture, - sub_texture_coords, mapped_meta_coords, - clamp_data->user_data); -} - -static gboolean -foreach_clamped_region (CoglTexture *texture, - float *tx_1, - float *ty_1, - float *tx_2, - float *ty_2, - CoglPipelineWrapMode wrap_s, - CoglPipelineWrapMode wrap_t, - CoglMetaTextureCallback callback, - void *user_data) -{ - float width = cogl_texture_get_width (texture); - ClampData clamp_data; - - /* Consider that *tx_1 may be > *tx_2 and to simplify things - * we just flip them around if that's the case and keep a note - * of the fact that they are flipped. */ - if (*tx_1 > *tx_2) - { - SWAP (*tx_1, *tx_2); - clamp_data.s_flipped = TRUE; - } - else - clamp_data.s_flipped = FALSE; - - /* The same goes for ty_1 and ty_2... */ - if (*ty_1 > *ty_2) - { - SWAP (*ty_1, *ty_2); - clamp_data.t_flipped = TRUE; - } - else - clamp_data.t_flipped = FALSE; - - clamp_data.callback = callback; - clamp_data.user_data = user_data; - - if (wrap_s == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE) - { - float max_s_coord = 1.0; - float half_texel_width; - - half_texel_width = max_s_coord / (width * 2); - - /* Handle any left clamped region */ - if (*tx_1 < 0) - { - clamp_data.start = *tx_1; - clamp_data.end = MIN (0, *tx_2); - cogl_meta_texture_foreach_in_region (texture, - half_texel_width, *ty_1, - half_texel_width, *ty_2, - COGL_PIPELINE_WRAP_MODE_REPEAT, - wrap_t, - clamp_s_cb, - &clamp_data); - /* Have we handled everything? */ - if (*tx_2 <= 0) - return TRUE; - - /* clamp tx_1 since we've handled everything with x < 0 */ - *tx_1 = 0; - } - - /* Handle any right clamped region - including the corners */ - if (*tx_2 > max_s_coord) - { - clamp_data.start = MAX (max_s_coord, *tx_1); - clamp_data.end = *tx_2; - cogl_meta_texture_foreach_in_region (texture, - max_s_coord - half_texel_width, - *ty_1, - max_s_coord - half_texel_width, - *ty_2, - COGL_PIPELINE_WRAP_MODE_REPEAT, - wrap_t, - clamp_s_cb, - &clamp_data); - /* Have we handled everything? */ - if (*tx_1 >= max_s_coord) - return TRUE; - - /* clamp tx_2 since we've handled everything with x > - * max_s_coord */ - *tx_2 = max_s_coord; - } - } - - if (wrap_t == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE) - { - float height = cogl_texture_get_height (texture); - float max_t_coord = 1.0; - float half_texel_height; - - half_texel_height = max_t_coord / (height * 2); - - /* Handle any top clamped region */ - if (*ty_1 < 0) - { - clamp_data.start = *ty_1; - clamp_data.end = MIN (0, *ty_2); - cogl_meta_texture_foreach_in_region (texture, - *tx_1, half_texel_height, - *tx_2, half_texel_height, - wrap_s, - COGL_PIPELINE_WRAP_MODE_REPEAT, - clamp_t_cb, - &clamp_data); - /* Have we handled everything? */ - if (*tx_2 <= 0) - return TRUE; - - /* clamp ty_1 since we've handled everything with y < 0 */ - *ty_1 = 0; - } - - /* Handle any bottom clamped region */ - if (*ty_2 > max_t_coord) - { - clamp_data.start = MAX (max_t_coord, *ty_1); - clamp_data.end = *ty_2; - cogl_meta_texture_foreach_in_region (texture, - *tx_1, - max_t_coord - half_texel_height, - *tx_2, - max_t_coord - half_texel_height, - wrap_s, - COGL_PIPELINE_WRAP_MODE_REPEAT, - clamp_t_cb, - &clamp_data); - /* Have we handled everything? */ - if (*ty_1 >= max_t_coord) - return TRUE; - - /* clamp ty_2 since we've handled everything with y > - * max_t_coord */ - *ty_2 = max_t_coord; - } - } - - if (clamp_data.s_flipped) - SWAP (*tx_1, *tx_2); - if (clamp_data.t_flipped) - SWAP (*ty_1, *ty_2); - - return FALSE; -} - -typedef struct _NormalizeData -{ - CoglMetaTextureCallback callback; - void *user_data; - float s_normalize_factor; - float t_normalize_factor; -} NormalizeData; - -static void -normalize_meta_coords_cb (CoglTexture *slice_texture, - const float *slice_coords, - const float *meta_coords, - void *user_data) -{ - NormalizeData *data = user_data; - float normalized_meta_coords[4] = { - meta_coords[0] * data->s_normalize_factor, - meta_coords[1] * data->t_normalize_factor, - meta_coords[2] * data->s_normalize_factor, - meta_coords[3] * data->t_normalize_factor - }; - - data->callback (slice_texture, - slice_coords, normalized_meta_coords, - data->user_data); -} - -void -cogl_meta_texture_foreach_in_region (CoglTexture *texture, - float tx_1, - float ty_1, - float tx_2, - float ty_2, - CoglPipelineWrapMode wrap_s, - CoglPipelineWrapMode wrap_t, - CoglMetaTextureCallback callback, - void *user_data) -{ - float width = cogl_texture_get_width (texture); - float height = cogl_texture_get_height (texture); - NormalizeData normalize_data; - - if (wrap_s == COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - wrap_s = COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; - if (wrap_t == COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - wrap_t = COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; - - if (wrap_s == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE || - wrap_t == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE) - { - gboolean finished = foreach_clamped_region (texture, - &tx_1, &ty_1, &tx_2, &ty_2, - wrap_s, wrap_t, - callback, - user_data); - if (finished) - return; - - /* Since clamping has been handled we now want to normalize our - * wrap modes we se can assume from this point on we don't - * need to consider CLAMP_TO_EDGE. (NB: The spans code will - * assert that CLAMP_TO_EDGE isn't requested) */ - if (wrap_s == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE) - wrap_s = COGL_PIPELINE_WRAP_MODE_REPEAT; - if (wrap_t == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE) - wrap_t = COGL_PIPELINE_WRAP_MODE_REPEAT; - } - - /* It makes things simpler to deal with non-normalized region - * coordinates beyond this point and only re-normalize just before - * calling the user's callback... */ - - normalize_data.callback = callback; - normalize_data.user_data = user_data; - normalize_data.s_normalize_factor = 1.0f / width; - normalize_data.t_normalize_factor = 1.0f / height; - callback = normalize_meta_coords_cb; - user_data = &normalize_data; - tx_1 *= width; - ty_1 *= height; - tx_2 *= width; - ty_2 *= height; - - /* XXX: at some point this won't be routed through the CoglTexture - * vtable, instead there will be a separate CoglMetaTexture - * interface vtable. */ - - if (COGL_TEXTURE_GET_CLASS (texture)->foreach_sub_texture_in_region) - { - ForeachData data; - - data.meta_region_coords[0] = tx_1; - data.meta_region_coords[1] = ty_1; - data.meta_region_coords[2] = tx_2; - data.meta_region_coords[3] = ty_2; - data.wrap_s = wrap_s; - data.wrap_t = wrap_t; - data.callback = callback; - data.user_data = user_data; - - data.width = width; - data.height = height; - - memset (data.padded_textures, 0, sizeof (data.padded_textures)); - - /* - * 1) We iterate all the slices of the meta-texture only within - * the range [0,1]. - * - * 2) We define a "padded grid" for each slice of the - * meta-texture in the range [0,1]. - * - * The padded grid maps over the meta-texture coordinates in - * the range [0,1] but only contains one valid cell that - * corresponds to current slice being iterated and all the - * surrounding cells just provide padding. - * - * 3) Once we've defined our padded grid we then repeat that - * across the user's original region, calling their callback - * whenever we see our current slice - ignoring padding. - * - * A notable benefit of this design is that repeating a texture - * made of multiple slices will result in us repeating each - * slice in-turn so the user gets repeat callbacks for the same - * texture batched together. For manual emulation of texture - * repeats done by drawing geometry this makes it more likely - * that we can batch geometry. - */ - - COGL_TEXTURE_GET_CLASS (texture)->foreach_sub_texture_in_region (texture, - 0, 0, 1, 1, - create_grid_and_repeat_cb, - &data); - } - else - { - CoglSpan x_span = { 0, width, 0 }; - CoglSpan y_span = { 0, height, 0 }; - float meta_region_coords[4] = { tx_1, ty_1, tx_2, ty_2 }; - - _cogl_texture_spans_foreach_in_region (&x_span, 1, - &y_span, 1, - &texture, - meta_region_coords, - width, - height, - wrap_s, - wrap_t, - callback, - user_data); - } -} -#undef SWAP diff --git a/mutter/cogl/cogl/cogl-meta-texture.h b/mutter/cogl/cogl/cogl-meta-texture.h deleted file mode 100644 index 59a335b..0000000 --- a/mutter/cogl/cogl/cogl-meta-texture.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-pipeline-layer-state.h" - -G_BEGIN_DECLS - -/** - * SECTION:meta-texture - * Interface for high-level textures built from - * low-level textures like #CoglTexture2D. - * - * Cogl helps to make it easy to deal with high level textures such - * as `CoglAtlasTexture`s, `CoglSubTexture`s, - * #CoglTexturePixmapX11 textures and #CoglTexture2DSliced textures - * consistently. - * - * A #CoglMetaTexture is a texture that might internally be - * represented by one or more low-level `CoglTexture`s - * such as #CoglTexture2D. These low-level textures are the only ones - * that a GPU really understands but because applications often want - * more high-level texture abstractions (such as storing multiple - * textures inside one larger "atlas" texture) it's desirable to be - * able to deal with these using a common interface. - * - * For example the GPU is not able to automatically handle repeating a - * texture that is part of a larger atlas texture but if you use - * %COGL_PIPELINE_WRAP_MODE_REPEAT with an atlas texture when drawing - * with cogl_rectangle() you should see that it "Just Works™" - at - * least if you don't use multi-texturing. The reason this works is - * because cogl_rectangle() internally understands the #CoglMetaTexture - * interface and is able to manually resolve the low-level textures - * using this interface and by making multiple draw calls it can - * emulate the texture repeat modes. - * - * Cogl doesn't aim to pretend that meta-textures are just like real - * textures because it would get extremely complex to try and emulate - * low-level GPU semantics transparently for these textures. The low - * level drawing APIs of Cogl, such as cogl_primitive_draw() don't - * actually know anything about the #CoglMetaTexture interface and its - * the developer's responsibility to resolve all textures referenced - * by a #CoglPipeline to low-level textures before drawing. - * - * If you want to develop custom primitive APIs like - * cogl_framebuffer_draw_rectangle() and you want to support drawing - * with `CoglAtlasTexture`s or `CoglSubTexture`s for - * example, then you will need to use this #CoglMetaTexture interface - * to be able to resolve high-level textures into low-level textures - * before drawing with Cogl's low-level drawing APIs such as - * cogl_primitive_draw(). - * - * Most developers won't need to use this interface directly - * but still it is worth understanding the distinction between - * low-level and meta textures because you may find other references - * in the documentation that detail limitations of using - * meta-textures. - */ - -/** - * CoglMetaTextureCallback: - * @sub_texture: A low-level #CoglTexture making up part of a - * #CoglMetaTexture. - * @sub_texture_coords: A float 4-tuple ordered like - * (tx1,ty1,tx2,ty2) defining what region of the - * current @sub_texture maps to a sub-region of a - * #CoglMetaTexture. (tx1,ty1) is the top-left - * sub-region coordinate and (tx2,ty2) is the - * bottom-right. These are low-level texture - * coordinates. - * @meta_coords: A float 4-tuple ordered like (tx1,ty1,tx2,ty2) - * defining what sub-region of a #CoglMetaTexture this - * low-level @sub_texture maps too. (tx1,ty1) is - * the top-left sub-region coordinate and (tx2,ty2) is - * the bottom-right. These are high-level meta-texture - * coordinates. - * @user_data: A private pointer passed to - * cogl_meta_texture_foreach_in_region(). - * - * A callback used with cogl_meta_texture_foreach_in_region() to - * retrieve details of all the low-level `CoglTexture`s that - * make up a given #CoglMetaTexture. - */ -typedef void (*CoglMetaTextureCallback) (CoglTexture *sub_texture, - const float *sub_texture_coords, - const float *meta_coords, - void *user_data); - -/** - * cogl_meta_texture_foreach_in_region: - * @texture: An object implementing the #CoglMetaTexture interface. - * @tx_1: The top-left x coordinate of the region to iterate - * @ty_1: The top-left y coordinate of the region to iterate - * @tx_2: The bottom-right x coordinate of the region to iterate - * @ty_2: The bottom-right y coordinate of the region to iterate - * @wrap_s: The wrap mode for the x-axis - * @wrap_t: The wrap mode for the y-axis - * @callback: (scope call): A #CoglMetaTextureCallback pointer to be called - * for each low-level texture within the specified region. - * @user_data: A private pointer that is passed to @callback. - * - * Allows you to manually iterate the low-level textures that define a - * given region of a high-level #CoglMetaTexture. - * - * For example cogl_texture_2d_sliced_new_with_size() can be used to - * create a meta texture that may slice a large image into multiple, - * smaller power-of-two sized textures. These high level textures are - * not directly understood by a GPU and so this API must be used to - * manually resolve the underlying textures for drawing. - * - * All high level textures (#CoglAtlasTexture, #CoglSubTexture, - * #CoglTexturePixmapX11, and #CoglTexture2DSliced) can be handled - * consistently using this interface which greately simplifies - * implementing primitives that support all texture types. - * - * For example if you use the cogl_rectangle() API then Cogl will - * internally use this API to resolve the low level textures of any - * meta textures you have associated with CoglPipeline layers. - * - * The low level drawing APIs such as cogl_primitive_draw() - * don't understand the #CoglMetaTexture interface and so it is your - * responsibility to use this API to resolve all CoglPipeline textures - * into low-level textures before drawing. - * - * For each low-level texture that makes up part of the given region - * of the @meta_texture, @callback is called specifying how the - * low-level texture maps to the original region. - */ -COGL_EXPORT void -cogl_meta_texture_foreach_in_region (CoglTexture *texture, - float tx_1, - float ty_1, - float tx_2, - float ty_2, - CoglPipelineWrapMode wrap_s, - CoglPipelineWrapMode wrap_t, - CoglMetaTextureCallback callback, - void *user_data); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-mutter.h b/mutter/cogl/cogl/cogl-mutter.h deleted file mode 100644 index aadbb63..0000000 --- a/mutter/cogl/cogl/cogl-mutter.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2016 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-texture.h" -#include "cogl/cogl-meta-texture.h" -#include "cogl/cogl-frame-info-private.h" -#include "cogl/cogl-renderer-private.h" -#ifdef HAVE_EGL -#include "cogl/winsys/cogl-onscreen-egl.h" -#include "cogl/winsys/cogl-winsys-egl-private.h" -#endif -#ifdef HAVE_GLX -#include "cogl/winsys/cogl-onscreen-glx.h" -#endif -#ifdef HAVE_X11 -#include "cogl/winsys/cogl-onscreen-xlib.h" -#include "cogl/cogl-x11-onscreen.h" -#endif -#include "cogl/winsys/cogl-winsys-private.h" - -COGL_EXPORT -void cogl_renderer_set_custom_winsys (CoglRenderer *renderer, - CoglCustomWinsysVtableGetter winsys_vtable_getter, - void *user_data); - -COGL_EXPORT -gboolean cogl_context_format_supports_upload (CoglContext *ctx, - CoglPixelFormat format); diff --git a/mutter/cogl/cogl/cogl-node-private.h b/mutter/cogl/cogl/cogl-node-private.h deleted file mode 100644 index 14e2d9b..0000000 --- a/mutter/cogl/cogl/cogl-node-private.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-list.h" - -typedef struct _CoglNodeClass CoglNodeClass; -typedef struct _CoglNode CoglNode; - -/* Pipelines and layers represent their state in a tree structure where - * some of the state relating to a given pipeline or layer may actually - * be owned by one if is ancestors in the tree. We have a common data - * type to track the tree hierarchy so we can share code... */ -struct _CoglNode -{ - GObject parent_instance; - - /* The parent pipeline/layer */ - CoglNode *parent; - - /* The list entry here contains pointers to the node's siblings */ - CoglList link; - - /* List of children */ - CoglList children; - - /* TRUE if the node took a strong reference on its parent. Weak - * pipelines for instance don't take a reference on their parent. */ - gboolean has_parent_reference; -}; - -struct _CoglNodeClass -{ - GObjectClass parent_class; -}; - -#define COGL_TYPE_NODE (cogl_node_get_type ()) -#define COGL_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_NODE, CoglNode)) -#define COGL_NODE_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_NODE, CoglNode const)) -#define COGL_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_TYPE_NODE, CoglNodeClass)) -#define COGL_IS_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_TYPE_NODE)) -#define COGL_IS_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_TYPE_NODE)) -#define COGL_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COGL_TYPE_NODE, CoglNodeClass)) - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (CoglNode, g_object_unref) - -GType cogl_node_get_type (void) G_GNUC_CONST; - -void -_cogl_pipeline_node_set_parent_real (CoglNode *node, - CoglNode *parent, - gboolean take_strong_reference); - -void -_cogl_pipeline_node_unparent_real (CoglNode *node); - -typedef gboolean (*CoglNodeChildCallback) (CoglNode *child, void *user_data); - -void -_cogl_pipeline_node_foreach_child (CoglNode *node, - CoglNodeChildCallback callback, - void *user_data); diff --git a/mutter/cogl/cogl/cogl-node.c b/mutter/cogl/cogl/cogl-node.c deleted file mode 100644 index e203978..0000000 --- a/mutter/cogl/cogl/cogl-node.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-util.h" -#include "cogl/cogl-node-private.h" - -G_DEFINE_ABSTRACT_TYPE (CoglNode, cogl_node, G_TYPE_OBJECT) - -static void -cogl_node_class_init (CoglNodeClass *klass) -{ -} - -static void -cogl_node_init (CoglNode *node) -{ - node->parent = NULL; - _cogl_list_init (&node->children); -} - -void -_cogl_pipeline_node_set_parent_real (CoglNode *node, - CoglNode *parent, - gboolean take_strong_reference) -{ - /* NB: the old parent may indirectly be keeping the new parent alive - * so we have to ref the new parent before unrefing the old. - * - * Note: we take a reference here regardless of - * take_strong_reference because weak children may need special - * handling when the parent disposes itself which relies on a - * consistent link to all weak nodes. Once the node is linked to its - * parent then we remove the reference at the end if - * take_strong_reference == FALSE. */ - g_object_ref (parent); - - if (node->parent) - _cogl_pipeline_node_unparent_real (node); - - _cogl_list_insert (&parent->children, &node->link); - - node->parent = parent; - node->has_parent_reference = take_strong_reference; - - /* Now that there is a consistent parent->child link we can remove - * the parent reference if no reference was requested. If it turns - * out that the new parent was only being kept alive by the old - * parent then it will be disposed of here. */ - if (!take_strong_reference) - g_object_unref (parent); -} - -void -_cogl_pipeline_node_unparent_real (CoglNode *node) -{ - CoglNode *parent = node->parent; - - if (parent == NULL) - return; - - g_return_if_fail (!_cogl_list_empty (&parent->children)); - - _cogl_list_remove (&node->link); - - if (node->has_parent_reference) - g_object_unref (parent); - - node->parent = NULL; -} - -void -_cogl_pipeline_node_foreach_child (CoglNode *node, - CoglNodeChildCallback callback, - void *user_data) -{ - CoglNode *child, *next; - - _cogl_list_for_each_safe (child, next, &node->children, link) - callback (child, user_data); -} - - diff --git a/mutter/cogl/cogl/cogl-offscreen-private.h b/mutter/cogl/cogl/cogl-offscreen-private.h deleted file mode 100644 index 9e1090d..0000000 --- a/mutter/cogl/cogl/cogl-offscreen-private.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#pragma once - -#include "cogl/cogl-gl-header.h" -#include "cogl/cogl-offscreen.h" - -/* Flags to pass to _cogl_offscreen_new_with_texture_full */ -typedef enum -{ - COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL = 1 -} CoglOffscreenFlags; - -typedef enum -{ - COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL = 1 << 0, - COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH = 1 << 1, - COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL = 1 << 2, -} CoglOffscreenAllocateFlags; - -/* - * _cogl_offscreen_new_with_texture_full: - * @texture: A #CoglTexture pointer - * @create_flags: Flags specifying how to create the FBO - * @level: The mipmap level within the texture to target - * - * Creates a new offscreen buffer which will target the given - * texture. By default the buffer will have a depth and stencil - * buffer. This can be disabled by passing - * %COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL in @create_flags. - * - * Return value: the new CoglOffscreen object. - */ -CoglOffscreen * -_cogl_offscreen_new_with_texture_full (CoglTexture *texture, - CoglOffscreenFlags create_flags, - int level); - -int -cogl_offscreen_get_texture_level (CoglOffscreen *offscreen); diff --git a/mutter/cogl/cogl/cogl-offscreen.c b/mutter/cogl/cogl/cogl-offscreen.c deleted file mode 100644 index 3b08985..0000000 --- a/mutter/cogl/cogl/cogl-offscreen.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2012 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "config.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-offscreen-private.h" -#include "cogl/cogl-texture-private.h" - -struct _CoglOffscreen -{ - CoglFramebuffer parent; - - CoglTexture *texture; - int texture_level; -}; - -G_DEFINE_TYPE (CoglOffscreen, cogl_offscreen, - COGL_TYPE_FRAMEBUFFER) - -CoglOffscreen * -_cogl_offscreen_new_with_texture_full (CoglTexture *texture, - CoglOffscreenFlags flags, - int level) -{ - CoglContext *ctx = cogl_texture_get_context (texture); - CoglFramebufferDriverConfig driver_config; - CoglOffscreen *offscreen; - CoglFramebuffer *fb; - - g_return_val_if_fail (COGL_IS_TEXTURE (texture), NULL); - - driver_config = (CoglFramebufferDriverConfig) { - .type = COGL_FRAMEBUFFER_DRIVER_TYPE_FBO, - .disable_depth_and_stencil = - !!(flags & COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL), - }; - offscreen = g_object_new (COGL_TYPE_OFFSCREEN, - "context", ctx, - "driver-config", &driver_config, - NULL); - offscreen->texture = g_object_ref (texture); - offscreen->texture_level = level; - - fb = COGL_FRAMEBUFFER (offscreen); - - /* NB: we can't assume we can query the texture's width yet, since - * it might not have been allocated yet and for example if the - * texture is being loaded from a file then the file might not - * have been read yet. */ - - _cogl_texture_associate_framebuffer (texture, fb); - - return offscreen; -} - -CoglOffscreen * -cogl_offscreen_new_with_texture (CoglTexture *texture) -{ - return _cogl_offscreen_new_with_texture_full (texture, 0, 0); -} - -CoglTexture * -cogl_offscreen_get_texture (CoglOffscreen *offscreen) -{ - return offscreen->texture; -} - -int -cogl_offscreen_get_texture_level (CoglOffscreen *offscreen) -{ - return offscreen->texture_level; -} - -static gboolean -cogl_offscreen_allocate (CoglFramebuffer *framebuffer, - GError **error) -{ - CoglOffscreen *offscreen = COGL_OFFSCREEN (framebuffer); - CoglPixelFormat texture_format; - int width, height; - - if (!cogl_texture_allocate (offscreen->texture, error)) - return FALSE; - - /* NB: it's only after allocating the texture that we will - * determine whether a texture needs slicing... */ - if (cogl_texture_is_sliced (offscreen->texture)) - { - g_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_UNSUPPORTED, - "Can't create offscreen framebuffer from " - "sliced texture"); - return FALSE; - } - - width = cogl_texture_get_width (offscreen->texture); - height = cogl_texture_get_height (offscreen->texture); - cogl_framebuffer_update_size (framebuffer, width, height); - - texture_format = _cogl_texture_get_format (offscreen->texture); - _cogl_framebuffer_set_internal_format (framebuffer, texture_format); - - return TRUE; -} - -static gboolean -cogl_offscreen_is_y_flipped (CoglFramebuffer *framebuffer) -{ - return TRUE; -} - -static void -cogl_offscreen_dispose (GObject *object) -{ - CoglOffscreen *offscreen = COGL_OFFSCREEN (object); - - G_OBJECT_CLASS (cogl_offscreen_parent_class)->dispose (object); - - g_clear_object (&offscreen->texture); -} - -static void -cogl_offscreen_init (CoglOffscreen *offscreen) -{ -} - -static void -cogl_offscreen_class_init (CoglOffscreenClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - CoglFramebufferClass *framebuffer_class = COGL_FRAMEBUFFER_CLASS (klass); - - object_class->dispose = cogl_offscreen_dispose; - - framebuffer_class->allocate = cogl_offscreen_allocate; - framebuffer_class->is_y_flipped = cogl_offscreen_is_y_flipped; -} diff --git a/mutter/cogl/cogl/cogl-offscreen.h b/mutter/cogl/cogl/cogl-offscreen.h deleted file mode 100644 index 79f8877..0000000 --- a/mutter/cogl/cogl/cogl-offscreen.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-types.h" -#include "cogl/cogl-texture.h" - -#include - -G_BEGIN_DECLS - -/** - * CoglOffscreen: - * - * Functions for creating and manipulating offscreen framebuffers. - */ - -/* Offscreen api */ - -#define COGL_TYPE_OFFSCREEN (cogl_offscreen_get_type ()) -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglOffscreen, cogl_offscreen, - COGL, OFFSCREEN, - CoglFramebuffer) - -/** - * cogl_offscreen_new_with_texture: - * @texture: A #CoglTexture pointer - * - * This creates an offscreen framebuffer object using the given - * @texture as the primary color buffer. It doesn't just initialize - * the contents of the offscreen buffer with the @texture; they are - * tightly bound so that drawing to the offscreen buffer effectively - * updates the contents of the given texture. You don't need to - * destroy the offscreen buffer before you can use the @texture again. - * - * This api only works with low-level #CoglTexture types such as - * #CoglTexture2D and not with meta-texture types such as - * #CoglTexture2DSliced. - * - * The storage for the framebuffer is actually allocated lazily - * so this function will never return %NULL to indicate a runtime - * error. This means it is still possible to configure the framebuffer - * before it is really allocated. - * - * Simple applications without full error handling can simply rely on - * Cogl to lazily allocate the storage of framebuffers but you should - * be aware that if Cogl encounters an error (such as running out of - * GPU memory) then your application will simply abort with an error - * message. If you need to be able to catch such exceptions at runtime - * then you can explicitly allocate your framebuffer when you have - * finished configuring it by calling cogl_framebuffer_allocate() and - * passing in a #GError argument to catch any exceptions. - * - * Return value: (transfer full): a newly instantiated #CoglOffscreen - * framebuffer. - */ -COGL_EXPORT CoglOffscreen * -cogl_offscreen_new_with_texture (CoglTexture *texture); - -/** - * cogl_offscreen_get_texture: - * - * Returns: (transfer none): a #CoglTexture - */ -COGL_EXPORT CoglTexture * -cogl_offscreen_get_texture (CoglOffscreen *offscreen); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-onscreen-private.h b/mutter/cogl/cogl/cogl-onscreen-private.h deleted file mode 100644 index 959a605..0000000 --- a/mutter/cogl/cogl/cogl-onscreen-private.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-onscreen.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-closure-list-private.h" -#include "cogl/cogl-list.h" - -#include - -typedef struct _CoglOnscreenEvent -{ - CoglList link; - - CoglOnscreen *onscreen; - CoglFrameInfo *info; - CoglFrameEvent type; -} CoglOnscreenEvent; - -typedef struct _CoglOnscreenQueuedDirty -{ - CoglList link; - - CoglOnscreen *onscreen; - CoglOnscreenDirtyInfo info; -} CoglOnscreenQueuedDirty; - -void -_cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer, - int width, int height); - -COGL_EXPORT void -_cogl_onscreen_notify_frame_sync (CoglOnscreen *onscreen, CoglFrameInfo *info); - -COGL_EXPORT void -_cogl_onscreen_notify_complete (CoglOnscreen *onscreen, CoglFrameInfo *info); - -void -_cogl_onscreen_queue_dirty (CoglOnscreen *onscreen, - const CoglOnscreenDirtyInfo *info); - -void -cogl_onscreen_bind (CoglOnscreen *onscreen); - -COGL_EXPORT CoglFrameInfo * -cogl_onscreen_peek_head_frame_info (CoglOnscreen *onscreen); - -COGL_EXPORT CoglFrameInfo * -cogl_onscreen_peek_tail_frame_info (CoglOnscreen *onscreen); - -COGL_EXPORT CoglFrameInfo * -cogl_onscreen_pop_head_frame_info (CoglOnscreen *onscreen); diff --git a/mutter/cogl/cogl/cogl-onscreen-template-private.h b/mutter/cogl/cogl/cogl-onscreen-template-private.h deleted file mode 100644 index 466eb9f..0000000 --- a/mutter/cogl/cogl/cogl-onscreen-template-private.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-swap-chain.h" -#include "cogl/cogl-framebuffer-private.h" - -struct _CoglOnscreenTemplate -{ - GObject parent_instance; - - CoglFramebufferConfig config; -}; diff --git a/mutter/cogl/cogl/cogl-onscreen-template.c b/mutter/cogl/cogl/cogl-onscreen-template.c deleted file mode 100644 index e5d5faa..0000000 --- a/mutter/cogl/cogl/cogl-onscreen-template.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-onscreen-template-private.h" - -#include - -G_DEFINE_TYPE (CoglOnscreenTemplate, cogl_onscreen_template, G_TYPE_OBJECT); - -static void -cogl_onscreen_template_init (CoglOnscreenTemplate *onscreen_template) -{ -} - -static void -cogl_onscreen_template_class_init (CoglOnscreenTemplateClass *class) -{ -} - -CoglOnscreenTemplate * -cogl_onscreen_template_new (CoglSwapChain *swap_chain) -{ - CoglOnscreenTemplate *onscreen_template = g_object_new (COGL_TYPE_ONSCREEN_TEMPLATE, NULL); - char *user_config; - - onscreen_template->config.swap_chain = swap_chain; - if (swap_chain) - g_object_ref (swap_chain); - else - onscreen_template->config.swap_chain = cogl_swap_chain_new (); - - onscreen_template->config.need_stencil = TRUE; - onscreen_template->config.samples_per_pixel = 0; - - user_config = getenv ("COGL_POINT_SAMPLES_PER_PIXEL"); - if (user_config) - { - unsigned long samples_per_pixel = strtoul (user_config, NULL, 10); - if (samples_per_pixel != ULONG_MAX) - onscreen_template->config.samples_per_pixel = - samples_per_pixel; - } - - return onscreen_template; -} - -void -cogl_onscreen_template_set_samples_per_pixel ( - CoglOnscreenTemplate *onscreen_template, - int samples_per_pixel) -{ - onscreen_template->config.samples_per_pixel = samples_per_pixel; -} - -void -cogl_onscreen_template_set_stereo_enabled ( - CoglOnscreenTemplate *onscreen_template, - gboolean enabled) -{ - onscreen_template->config.stereo_enabled = enabled; -} diff --git a/mutter/cogl/cogl/cogl-onscreen-template.h b/mutter/cogl/cogl/cogl-onscreen-template.h deleted file mode 100644 index 40d83e5..0000000 --- a/mutter/cogl/cogl/cogl-onscreen-template.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-swap-chain.h" - -#include - -G_BEGIN_DECLS - -typedef struct _CoglOnscreenTemplate CoglOnscreenTemplate; - -#define COGL_TYPE_ONSCREEN_TEMPLATE (cogl_onscreen_template_get_type ()) - -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglOnscreenTemplate, cogl_onscreen_template, - COGL, ONSCREEN_TEMPLATE, GObject) - -COGL_EXPORT CoglOnscreenTemplate * -cogl_onscreen_template_new (CoglSwapChain *swap_chain); - -/** - * cogl_onscreen_template_set_samples_per_pixel: - * @onscreen_template: A #CoglOnscreenTemplate template framebuffer - * @n: The minimum number of samples per pixel - * - * Requires that any future CoglOnscreen framebuffers derived from - * this template must support making at least @n samples per pixel - * which will all contribute to the final resolved color for that - * pixel. - * - * By default this value is usually set to 0 and that is referred to - * as "single-sample" rendering. A value of 1 or greater is referred - * to as "multisample" rendering. - * - * There are some semantic differences between single-sample - * rendering and multisampling with just 1 point sample such as it - * being redundant to use the cogl_framebuffer_resolve_samples() and - * cogl_framebuffer_resolve_samples_region() apis with single-sample - * rendering. - */ -COGL_EXPORT void -cogl_onscreen_template_set_samples_per_pixel ( - CoglOnscreenTemplate *onscreen_template, - int n); - -/** - * cogl_onscreen_template_set_stereo_enabled: - * @onscreen_template: A #CoglOnscreenTemplate template framebuffer - * @enabled: Whether framebuffers are created with stereo buffers - * - * Sets whether future #CoglOnscreen framebuffers derived from this - * template are attempted to be created with both left and right - * buffers, for use with stereo display. If the display system - * does not support stereo, then creation of the framebuffer will - * fail. - */ -COGL_EXPORT void -cogl_onscreen_template_set_stereo_enabled ( - CoglOnscreenTemplate *onscreen_template, - gboolean enabled); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-onscreen.c b/mutter/cogl/cogl/cogl-onscreen.c deleted file mode 100644 index afb648b..0000000 --- a/mutter/cogl/cogl/cogl-onscreen.c +++ /dev/null @@ -1,597 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011, 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include - -#include "cogl/cogl-util.h" -#include "cogl/cogl-onscreen-private.h" -#include "cogl/cogl-frame-info-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-onscreen-template-private.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl1-context.h" -#include "cogl/cogl-closure-list-private.h" -#include "cogl/cogl-poll-private.h" - -typedef struct _CoglOnscreenPrivate -{ - CoglList frame_closures; - - CoglList dirty_closures; - - int64_t frame_counter; - int64_t swap_frame_counter; /* frame counter at last all to - * cogl_onscreen_swap_region() or - * cogl_onscreen_swap_buffers() */ - GQueue pending_frame_infos; -} CoglOnscreenPrivate; - -static void -_cogl_onscreen_queue_full_dirty (CoglOnscreen *onscreen); - -G_DEFINE_TYPE_WITH_PRIVATE (CoglOnscreen, cogl_onscreen, COGL_TYPE_FRAMEBUFFER) - -static gpointer -cogl_dummy_copy (gpointer data) -{ - return data; -} - -static void -cogl_dummy_free (gpointer data) -{ -} - -G_DEFINE_BOXED_TYPE (CoglFrameClosure, - cogl_frame_closure, - cogl_dummy_copy, - cogl_dummy_free) - -G_DEFINE_BOXED_TYPE (CoglOnscreenDirtyClosure, - cogl_onscreen_dirty_closure, - cogl_dummy_copy, - cogl_dummy_free) - -G_DEFINE_QUARK (cogl-scanout-error-quark, cogl_scanout_error) - -static gboolean -cogl_onscreen_allocate (CoglFramebuffer *framebuffer, - GError **error) -{ - CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - /* If the winsys doesn't support dirty events then we'll report - * one on allocation so that if the application only paints in - * response to dirty events then it will at least paint once to - * start */ - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_DIRTY_EVENTS)) - _cogl_onscreen_queue_full_dirty (onscreen); - - return TRUE; -} - -static gboolean -cogl_onscreen_is_y_flipped (CoglFramebuffer *framebuffer) -{ - return FALSE; -} - -static void -cogl_onscreen_init_from_template (CoglOnscreen *onscreen, - CoglOnscreenTemplate *onscreen_template) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - - _cogl_list_init (&priv->frame_closures); - _cogl_list_init (&priv->dirty_closures); - - cogl_framebuffer_init_config (framebuffer, &onscreen_template->config); -} - -static void -cogl_onscreen_constructed (GObject *object) -{ - CoglOnscreen *onscreen = COGL_ONSCREEN (object); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglOnscreenTemplate *onscreen_template; - - onscreen_template = ctx->display->onscreen_template; - cogl_onscreen_init_from_template (onscreen, onscreen_template); - - G_OBJECT_CLASS (cogl_onscreen_parent_class)->constructed (object); -} - -static void -cogl_onscreen_dispose (GObject *object) -{ - CoglOnscreen *onscreen = COGL_ONSCREEN (object); - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - CoglFrameInfo *frame_info; - - _cogl_closure_list_disconnect_all (&priv->frame_closures); - _cogl_closure_list_disconnect_all (&priv->dirty_closures); - - while ((frame_info = g_queue_pop_tail (&priv->pending_frame_infos))) - g_object_unref (frame_info); - g_queue_clear (&priv->pending_frame_infos); - - G_OBJECT_CLASS (cogl_onscreen_parent_class)->dispose (object); -} - -static void -cogl_onscreen_init (CoglOnscreen *onscreen) -{ -} - -static void -cogl_onscreen_class_init (CoglOnscreenClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - CoglFramebufferClass *framebuffer_class = COGL_FRAMEBUFFER_CLASS (klass); - - object_class->constructed = cogl_onscreen_constructed; - object_class->dispose = cogl_onscreen_dispose; - - framebuffer_class->allocate = cogl_onscreen_allocate; - framebuffer_class->is_y_flipped = cogl_onscreen_is_y_flipped; -} - -static void -notify_event (CoglOnscreen *onscreen, - CoglFrameEvent event, - CoglFrameInfo *info) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - _cogl_closure_list_invoke (&priv->frame_closures, - CoglFrameCallback, - onscreen, event, info); -} - -static void -_cogl_dispatch_onscreen_cb (CoglContext *context) -{ - CoglOnscreenEvent *event, *tmp; - CoglList queue; - - /* Dispatching the event callback may cause another frame to be - * drawn which in may cause another event to be queued immediately. - * To make sure this loop will only dispatch one set of events we'll - * steal the queue and iterate that separately */ - _cogl_list_init (&queue); - _cogl_list_insert_list (&queue, &context->onscreen_events_queue); - _cogl_list_init (&context->onscreen_events_queue); - - g_clear_pointer (&context->onscreen_dispatch_idle, - _cogl_closure_disconnect); - - _cogl_list_for_each_safe (event, tmp, &queue, link) - { - CoglOnscreen *onscreen = event->onscreen; - CoglFrameInfo *info = event->info; - - notify_event (onscreen, event->type, info); - - g_object_unref (onscreen); - g_object_unref (info); - - g_free (event); - } - - while (!_cogl_list_empty (&context->onscreen_dirty_queue)) - { - CoglOnscreenQueuedDirty *qe = - _cogl_container_of (context->onscreen_dirty_queue.next, - CoglOnscreenQueuedDirty, - link); - CoglOnscreen *onscreen = qe->onscreen; - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - _cogl_list_remove (&qe->link); - - _cogl_closure_list_invoke (&priv->dirty_closures, - CoglOnscreenDirtyCallback, - qe->onscreen, - &qe->info); - - g_object_unref (qe->onscreen); - - g_free (qe); - } -} - -static void -_cogl_onscreen_queue_dispatch_idle (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - if (!ctx->onscreen_dispatch_idle) - { - ctx->onscreen_dispatch_idle = - _cogl_poll_renderer_add_idle (ctx->display->renderer, - (CoglIdleCallback) - _cogl_dispatch_onscreen_cb, - ctx, - NULL); - } -} - -void -_cogl_onscreen_queue_dirty (CoglOnscreen *onscreen, - const CoglOnscreenDirtyInfo *info) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglOnscreenQueuedDirty *qe = g_new0 (CoglOnscreenQueuedDirty, 1); - - qe->onscreen = g_object_ref (onscreen); - qe->info = *info; - _cogl_list_insert (ctx->onscreen_dirty_queue.prev, &qe->link); - - _cogl_onscreen_queue_dispatch_idle (onscreen); -} - -void -_cogl_onscreen_queue_full_dirty (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglOnscreenDirtyInfo info; - - info.x = 0; - info.y = 0; - info.width = cogl_framebuffer_get_width (framebuffer); - info.height = cogl_framebuffer_get_height (framebuffer); - - _cogl_onscreen_queue_dirty (onscreen, &info); -} - -static void -_cogl_onscreen_queue_event (CoglOnscreen *onscreen, - CoglFrameEvent type, - CoglFrameInfo *info) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - CoglOnscreenEvent *event = g_new0 (CoglOnscreenEvent, 1); - - event->onscreen = g_object_ref (onscreen); - event->info = g_object_ref (info); - event->type = type; - - _cogl_list_insert (ctx->onscreen_events_queue.prev, &event->link); - - _cogl_onscreen_queue_dispatch_idle (onscreen); -} - -void -cogl_onscreen_bind (CoglOnscreen *onscreen) -{ - COGL_ONSCREEN_GET_CLASS (onscreen)->bind (onscreen); -} - -void -cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles) -{ - CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen); - - if (!klass->queue_damage_region) - return; - - klass->queue_damage_region (onscreen, rectangles, n_rectangles); -} - -void -cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen); - - g_return_if_fail (COGL_IS_ONSCREEN (framebuffer)); - - info->frame_counter = priv->frame_counter; - g_queue_push_tail (&priv->pending_frame_infos, info); - - _cogl_framebuffer_flush_journal (framebuffer); - - /* Update our "latest" sync fd to contain all previous work */ - _cogl_context_update_sync (context); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SYNC_FRAME))) - cogl_framebuffer_finish (framebuffer); - - cogl_framebuffer_discard_buffers (framebuffer, - COGL_BUFFER_BIT_DEPTH | - COGL_BUFFER_BIT_STENCIL); - - klass->swap_buffers_with_damage (onscreen, - rectangles, - n_rectangles, - info, - user_data); - - if (!_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) - { - CoglFrameInfo *info; - - g_warn_if_fail (priv->pending_frame_infos.length == 1); - - info = g_queue_pop_tail (&priv->pending_frame_infos); - - _cogl_onscreen_queue_event (onscreen, COGL_FRAME_EVENT_SYNC, info); - _cogl_onscreen_queue_event (onscreen, COGL_FRAME_EVENT_COMPLETE, info); - - g_object_unref (info); - } - - priv->frame_counter++; -} - -void -cogl_onscreen_swap_buffers (CoglOnscreen *onscreen, - CoglFrameInfo *info, - gpointer user_data) -{ - cogl_onscreen_swap_buffers_with_damage (onscreen, NULL, 0, info, user_data); -} - -void -cogl_onscreen_swap_region (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen); - - g_return_if_fail (COGL_IS_ONSCREEN (framebuffer)); - - info->frame_counter = priv->frame_counter; - g_queue_push_tail (&priv->pending_frame_infos, info); - - _cogl_framebuffer_flush_journal (framebuffer); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SYNC_FRAME))) - cogl_framebuffer_finish (framebuffer); - - /* This should only be called if the winsys advertises - COGL_WINSYS_FEATURE_SWAP_REGION */ - g_return_if_fail (klass->swap_region); - - cogl_framebuffer_discard_buffers (framebuffer, - COGL_BUFFER_BIT_DEPTH | - COGL_BUFFER_BIT_STENCIL); - - klass->swap_region (onscreen, - rectangles, - n_rectangles, - info, - user_data); - - if (!_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) - { - CoglFrameInfo *info; - - g_warn_if_fail (priv->pending_frame_infos.length == 1); - - info = g_queue_pop_tail (&priv->pending_frame_infos); - - _cogl_onscreen_queue_event (onscreen, COGL_FRAME_EVENT_SYNC, info); - _cogl_onscreen_queue_event (onscreen, COGL_FRAME_EVENT_COMPLETE, info); - - g_object_unref (info); - } - - priv->frame_counter++; -} - -int -cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen); - - g_return_val_if_fail (COGL_IS_ONSCREEN (framebuffer), 0); - - if (!klass->get_buffer_age) - return 0; - - return klass->get_buffer_age (onscreen); -} - -gboolean -cogl_onscreen_direct_scanout (CoglOnscreen *onscreen, - CoglScanout *scanout, - CoglFrameInfo *info, - gpointer user_data, - GError **error) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen); - - g_warn_if_fail (COGL_IS_ONSCREEN (framebuffer)); - g_warn_if_fail (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)); - - if (!klass->direct_scanout) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Direct scanout not supported"); - return FALSE; - } - - info->frame_counter = priv->frame_counter; - g_queue_push_tail (&priv->pending_frame_infos, info); - - if (!klass->direct_scanout (onscreen, - scanout, - info, - user_data, - error)) - { - g_queue_pop_tail (&priv->pending_frame_infos); - return FALSE; - } - - info->flags |= COGL_FRAME_INFO_FLAG_ZERO_COPY; - priv->frame_counter++; - return TRUE; -} - -void -cogl_onscreen_add_frame_info (CoglOnscreen *onscreen, - CoglFrameInfo *info) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - info->frame_counter = priv->frame_counter; - g_queue_push_tail (&priv->pending_frame_infos, info); -} - -CoglFrameInfo * -cogl_onscreen_peek_head_frame_info (CoglOnscreen *onscreen) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - return g_queue_peek_head (&priv->pending_frame_infos); -} - -CoglFrameInfo * -cogl_onscreen_peek_tail_frame_info (CoglOnscreen *onscreen) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - return g_queue_peek_tail (&priv->pending_frame_infos); -} - -CoglFrameInfo * -cogl_onscreen_pop_head_frame_info (CoglOnscreen *onscreen) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - return g_queue_pop_head (&priv->pending_frame_infos); -} - -CoglFrameClosure * -cogl_onscreen_add_frame_callback (CoglOnscreen *onscreen, - CoglFrameCallback callback, - void *user_data, - GDestroyNotify destroy) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - return _cogl_closure_list_add (&priv->frame_closures, - callback, - user_data, - destroy); -} - -void -cogl_onscreen_remove_frame_callback (CoglOnscreen *onscreen, - CoglFrameClosure *closure) -{ - g_return_if_fail (closure); - - _cogl_closure_disconnect (closure); -} - -void -_cogl_onscreen_notify_frame_sync (CoglOnscreen *onscreen, CoglFrameInfo *info) -{ - notify_event (onscreen, COGL_FRAME_EVENT_SYNC, info); -} - -void -_cogl_onscreen_notify_complete (CoglOnscreen *onscreen, CoglFrameInfo *info) -{ - notify_event (onscreen, COGL_FRAME_EVENT_COMPLETE, info); -} - -void -_cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer, - int width, int height) -{ - if (cogl_framebuffer_get_width (framebuffer) == width && - cogl_framebuffer_get_height (framebuffer) == height) - return; - - cogl_framebuffer_update_size (framebuffer, width, height); - - if (!_cogl_has_private_feature (cogl_framebuffer_get_context (framebuffer), - COGL_PRIVATE_FEATURE_DIRTY_EVENTS)) - _cogl_onscreen_queue_full_dirty (COGL_ONSCREEN (framebuffer)); -} - -CoglOnscreenDirtyClosure * -cogl_onscreen_add_dirty_callback (CoglOnscreen *onscreen, - CoglOnscreenDirtyCallback callback, - void *user_data, - GDestroyNotify destroy) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - return _cogl_closure_list_add (&priv->dirty_closures, - callback, - user_data, - destroy); -} - -void -cogl_onscreen_remove_dirty_callback (CoglOnscreen *onscreen, - CoglOnscreenDirtyClosure *closure) -{ - g_return_if_fail (closure); - - _cogl_closure_disconnect (closure); -} - -int64_t -cogl_onscreen_get_frame_counter (CoglOnscreen *onscreen) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - return priv->frame_counter; -} diff --git a/mutter/cogl/cogl/cogl-onscreen.h b/mutter/cogl/cogl/cogl-onscreen.h deleted file mode 100644 index 8419376..0000000 --- a/mutter/cogl/cogl/cogl-onscreen.h +++ /dev/null @@ -1,574 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011,2012,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-context.h" -#include "cogl/cogl-framebuffer.h" -#include "cogl/cogl-frame-info.h" - -#include - -G_BEGIN_DECLS - -#define COGL_TYPE_ONSCREEN (cogl_onscreen_get_type ()) -COGL_EXPORT -G_DECLARE_DERIVABLE_TYPE (CoglOnscreen, cogl_onscreen, - COGL, ONSCREEN, - CoglFramebuffer) - -struct _CoglOnscreenClass -{ - /*< private >*/ - CoglFramebufferClass parent_class; - - void (* bind) (CoglOnscreen *onscreen); - - void (* swap_buffers_with_damage) (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data); - - void (* swap_region) (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data); - - void (* queue_damage_region) (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles); - - gboolean (* direct_scanout) (CoglOnscreen *onscreen, - CoglScanout *scanout, - CoglFrameInfo *info, - gpointer user_data, - GError **error); - - int (* get_buffer_age) (CoglOnscreen *onscreen); -}; - -/** - * cogl_onscreen_show: - * @onscreen: The onscreen framebuffer to make visible - * - * This requests to make @onscreen visible to the user. - * - * Actually the precise semantics of this function depend on the - * window system currently in use, and if you don't have a - * multi-windowining system this function may in-fact do nothing. - * - * This function will implicitly allocate the given @onscreen - * framebuffer before showing it if it hasn't already been allocated. - * - * When using the Wayland winsys calling this will set the surface to - * a toplevel type which will make it appear. If the application wants - * to set a different type for the surface, it can avoid calling - * cogl_onscreen_show() and set its own type directly with the Wayland - * client API via cogl_wayland_onscreen_get_surface(). - * - * Since Cogl doesn't explicitly track the visibility status of - * onscreen framebuffers it won't try to avoid redundant window system - * requests e.g. to show an already visible window. This also means - * that it's acceptable to alternatively use native APIs to show and - * hide windows without confusing Cogl. - */ -COGL_EXPORT void -cogl_onscreen_show (CoglOnscreen *onscreen); - -/** - * cogl_onscreen_hide: - * @onscreen: The onscreen framebuffer to make invisible - * - * This requests to make @onscreen invisible to the user. - * - * Actually the precise semantics of this function depend on the - * window system currently in use, and if you don't have a - * multi-windowining system this function may in-fact do nothing. - * - * This function does not implicitly allocate the given @onscreen - * framebuffer before hiding it. - * - * Since Cogl doesn't explicitly track the visibility status of - * onscreen framebuffers it won't try to avoid redundant window system - * requests e.g. to show an already visible window. This also means - * that it's acceptable to alternatively use native APIs to show and - * hide windows without confusing Cogl. - */ -COGL_EXPORT void -cogl_onscreen_hide (CoglOnscreen *onscreen); - -/** - * cogl_onscreen_swap_buffers: - * @onscreen: A #CoglOnscreen framebuffer - * - * Swaps the current back buffer being rendered too, to the front for display. - * - * This function also implicitly discards the contents of the color, depth and - * stencil buffers as if cogl_framebuffer_discard_buffers() were used. The - * significance of the discard is that you should not expect to be able to - * start a new frame that incrementally builds on the contents of the previous - * frame. - * - * It is highly recommended that applications use - * cogl_onscreen_swap_buffers_with_damage() instead whenever possible - * and also use the cogl_onscreen_get_buffer_age() api so they can - * perform incremental updates to older buffers instead of having to - * render a full buffer for every frame. - */ -COGL_EXPORT void -cogl_onscreen_swap_buffers (CoglOnscreen *onscreen, - CoglFrameInfo *frame_info, - gpointer user_data); - - -/** - * cogl_onscreen_get_buffer_age: - * @onscreen: A #CoglOnscreen framebuffer - * - * Gets the current age of the buffer contents. - * - * This function allows applications to query the age of the current - * back buffer contents for a #CoglOnscreen as the number of frames - * elapsed since the contents were most recently defined. - * - * These age values exposes enough information to applications about - * how Cogl internally manages back buffers to allow applications to - * re-use the contents of old frames and minimize how much must be - * redrawn for the next frame. - * - * The back buffer contents can either be reported as invalid (has an - * age of 0) or it may be reported to be the same contents as from n - * frames prior to the current frame. - * - * The queried value remains valid until the next buffer swap. - * - * One caveat is that under X11 the buffer age does not reflect - * changes to buffer contents caused by the window systems. X11 - * applications must track Expose events to determine what buffer - * regions need to additionally be repaired each frame. - * - * The recommended way to take advantage of this buffer age api is to - * build up a circular buffer of length 3 for tracking damage regions - * over the last 3 frames and when starting a new frame look at the - * age of the buffer and combine the damage regions for the current - * frame with the damage regions of previous @age frames so you know - * everything that must be redrawn to update the old contents for the - * new frame. - * - * If the system doesn't not support being able to track the age - * of back buffers then this function will always return 0 which - * implies that the contents are undefined. - * - * The %COGL_FEATURE_ID_BUFFER_AGE feature can optionally be - * explicitly checked to determine if Cogl is currently tracking the - * age of #CoglOnscreen back buffer contents. If this feature is - * missing then this function will always return 0. - * - * Return value: The age of the buffer contents or 0 when the buffer - * contents are undefined. - */ -COGL_EXPORT int -cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen); - -/** - * cogl_onscreen_queue_damage_region: - * @onscreen: A #CoglOnscreen framebuffer - * @rectangles: (array length=n_rectangles): An array of integer 4-tuples - * representing damaged rectangles as (x, y, width, height) tuples. - * @n_rectangles: The number of 4-tuples to be read from @rectangles - * - * Implementation for https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_partial_update.txt - * This immediately queues state to OpenGL that will be used for the - * next swap. - * This needs to be called every frame. - * - * The expected values are independent of any viewport transforms applied to - * the framebuffer. - */ -COGL_EXPORT void -cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles); - -/** - * cogl_onscreen_swap_buffers_with_damage: - * @onscreen: A #CoglOnscreen framebuffer - * @rectangles: (array length=n_rectangles): An array of integer 4-tuples - * representing damaged rectangles as (x, y, width, height) tuples. - * @n_rectangles: The number of 4-tuples to be read from @rectangles - * - * Swaps the current back buffer being rendered too, to the front for - * display and provides information to any system compositor about - * what regions of the buffer have changed (damage) with respect to - * the last swapped buffer. - * - * This function has the same semantics as - * cogl_framebuffer_swap_buffers() except that it additionally allows - * applications to pass a list of damaged rectangles which may be - * passed on to a compositor so that it can minimize how much of the - * screen is redrawn in response to this applications newly swapped - * front buffer. - * - * For example if your application is only animating a small object in - * the corner of the screen and everything else is remaining static - * then it can help the compositor to know that only the bottom right - * corner of your newly swapped buffer has really changed with respect - * to your previously swapped front buffer. - * - * If @n_rectangles is 0 then the whole buffer will implicitly be - * reported as damaged as if cogl_onscreen_swap_buffers() had been - * called. - * - * This function also implicitly discards the contents of the color, - * depth and stencil buffers as if cogl_framebuffer_discard_buffers() - * were used. The significance of the discard is that you should not - * expect to be able to start a new frame that incrementally builds on - * the contents of the previous frame. If you want to perform - * incremental updates to older back buffers then please refer to the - * cogl_onscreen_get_buffer_age() api. - * - * Whenever possible it is recommended that applications use this - * function instead of cogl_onscreen_swap_buffers() to improve - * performance when running under a compositor. - * - * It is highly recommended to use this API in conjunction with - * the cogl_onscreen_get_buffer_age() api so that your application can - * perform incremental rendering based on old back buffers. - */ -COGL_EXPORT void -cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data); - -/** - * cogl_onscreen_direct_scanout: - */ -COGL_EXPORT gboolean -cogl_onscreen_direct_scanout (CoglOnscreen *onscreen, - CoglScanout *scanout, - CoglFrameInfo *info, - gpointer user_data, - GError **error); - -/** - * cogl_onscreen_add_frame_info: - * @onscreen: A #CoglOnscreen framebuffer - * @info: (transfer full): A #CoglFrameInfo - */ -COGL_EXPORT void -cogl_onscreen_add_frame_info (CoglOnscreen *onscreen, - CoglFrameInfo *info); - -/** - * cogl_onscreen_swap_region: - * @onscreen: A #CoglOnscreen framebuffer - * @rectangles: (array length=n_rectangles): An array of integer 4-tuples - * representing rectangles as (x, y, width, height) tuples. - * @n_rectangles: The number of 4-tuples to be read from @rectangles - * - * Swaps a region of the back buffer being rendered too, to the front for - * display. @rectangles represents the region as array of @n_rectangles each - * defined by 4 sequential (x, y, width, height) integers. - * - * This function also implicitly discards the contents of the color, depth and - * stencil buffers as if cogl_framebuffer_discard_buffers() were used. The - * significance of the discard is that you should not expect to be able to - * start a new frame that incrementally builds on the contents of the previous - * frame. - */ -COGL_EXPORT void -cogl_onscreen_swap_region (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data); - -/** - * CoglFrameEvent: - * @COGL_FRAME_EVENT_SYNC: Notifies that the system compositor has - * acknowledged a frame and is ready for a - * new frame to be created. - * @COGL_FRAME_EVENT_COMPLETE: Notifies that a frame has ended. This - * is a good time for applications to - * collect statistics about the frame - * since the #CoglFrameInfo should hold - * the most data at this point. No other - * events should be expected after a - * @COGL_FRAME_EVENT_COMPLETE event. - * - * Identifiers that are passed to #CoglFrameCallback functions - * (registered using cogl_onscreen_add_frame_callback()) that - * mark the progression of a frame in some way which usually - * means that new information will have been accumulated in the - * frame's corresponding #CoglFrameInfo object. - * - * The last event that will be sent for a frame will be a - * @COGL_FRAME_EVENT_COMPLETE event and so these are a good - * opportunity to collect statistics about a frame since the - * #CoglFrameInfo should hold the most data at this point. - * - * A frame may not be completed before the next frame can start - * so applications should avoid needing to collect all statistics for - * a particular frame before they can start a new frame. - */ -typedef enum _CoglFrameEvent -{ - COGL_FRAME_EVENT_SYNC = 1, - COGL_FRAME_EVENT_COMPLETE -} CoglFrameEvent; - -/** - * CoglFrameCallback: - * @onscreen: The onscreen that the frame is associated with - * @event: A #CoglFrameEvent notifying how the frame has progressed - * @info: The meta information, such as timing information, about - * the frame that has progressed. - * @user_data: The user pointer passed to - * cogl_onscreen_add_frame_callback() - * - * Is a callback that can be registered via - * cogl_onscreen_add_frame_callback() to be called when a frame - * progresses in some notable way. - * - * Please see the documentation for #CoglFrameEvent and - * cogl_onscreen_add_frame_callback() for more details about what - * events can be notified. - */ -typedef void (*CoglFrameCallback) (CoglOnscreen *onscreen, - CoglFrameEvent event, - CoglFrameInfo *info, - void *user_data); - -/** - * CoglFrameClosure: - * - * An opaque type that tracks a #CoglFrameCallback and associated user - * data. A #CoglFrameClosure pointer will be returned from - * cogl_onscreen_add_frame_callback() and it allows you to remove a - * callback later using cogl_onscreen_remove_frame_callback(). - */ -typedef struct _CoglClosure CoglFrameClosure; - -/** - * cogl_frame_closure_get_type: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_frame_closure_get_type (void); - -/** - * cogl_onscreen_add_frame_callback: - * @onscreen: A #CoglOnscreen framebuffer - * @callback: (scope notified): A callback function to call for frame events - * @user_data: (closure): A private pointer to be passed to @callback - * @destroy: (allow-none): An optional callback to destroy @user_data - * when the @callback is removed or @onscreen is freed. - * - * Installs a @callback function that will be called for significant - * events relating to the given @onscreen framebuffer. - * - * The @callback will be used to notify when the system compositor is - * ready for this application to render a new frame. In this case - * %COGL_FRAME_EVENT_SYNC will be passed as the event argument to the - * given @callback in addition to the #CoglFrameInfo corresponding to - * the frame being acknowledged by the compositor. - * - * The @callback will also be called to notify when the frame has - * ended. In this case %COGL_FRAME_EVENT_COMPLETE will be passed as - * the event argument to the given @callback in addition to the - * #CoglFrameInfo corresponding to the newly presented frame. The - * meaning of "ended" here simply means that no more timing - * information will be collected within the corresponding - * #CoglFrameInfo and so this is a good opportunity to analyse the - * given info. It does not necessarily mean that the GPU has finished - * rendering the corresponding frame. - * - * We highly recommend throttling your application according to - * %COGL_FRAME_EVENT_SYNC events so that your application can avoid - * wasting resources, drawing more frames than your system compositor - * can display. - * - * Returns: (transfer none): a #CoglFrameClosure pointer that can be used to - * remove the callback and associated @user_data later. - */ -COGL_EXPORT CoglFrameClosure * -cogl_onscreen_add_frame_callback (CoglOnscreen *onscreen, - CoglFrameCallback callback, - void *user_data, - GDestroyNotify destroy); - -/** - * cogl_onscreen_remove_frame_callback: - * @onscreen: A #CoglOnscreen - * @closure: A #CoglFrameClosure returned from - * cogl_onscreen_add_frame_callback() - * - * Removes a callback and associated user data that were previously - * registered using cogl_onscreen_add_frame_callback(). - * - * If a destroy callback was passed to - * cogl_onscreen_add_frame_callback() to destroy the user data then - * this will get called. - */ -COGL_EXPORT void -cogl_onscreen_remove_frame_callback (CoglOnscreen *onscreen, - CoglFrameClosure *closure); - -/** - * CoglOnscreenDirtyInfo: - * @x: Left edge of the dirty rectangle - * @y: Top edge of the dirty rectangle, measured from the top of the window - * @width: Width of the dirty rectangle - * @height: Height of the dirty rectangle - * - * A structure passed to callbacks registered using - * cogl_onscreen_add_dirty_callback(). The members describe a - * rectangle within the onscreen buffer that should be redrawn. - */ -typedef struct _CoglOnscreenDirtyInfo CoglOnscreenDirtyInfo; - -struct _CoglOnscreenDirtyInfo -{ - int x, y; - int width, height; -}; - -/** - * CoglOnscreenDirtyCallback: - * @onscreen: The onscreen that the frame is associated with - * @info: A #CoglOnscreenDirtyInfo struct containing the details of the - * dirty area - * @user_data: The user pointer passed to - * cogl_onscreen_add_frame_callback() - * - * Is a callback that can be registered via - * cogl_onscreen_add_dirty_callback() to be called when the windowing - * system determines that a region of the onscreen window has been - * lost and the application should redraw it. - */ -typedef void (*CoglOnscreenDirtyCallback) (CoglOnscreen *onscreen, - const CoglOnscreenDirtyInfo *info, - void *user_data); - -/** - * CoglOnscreenDirtyClosure: - * - * An opaque type that tracks a #CoglOnscreenDirtyCallback and associated - * user data. A #CoglOnscreenDirtyClosure pointer will be returned from - * cogl_onscreen_add_dirty_callback() and it allows you to remove a - * callback later using cogl_onscreen_remove_dirty_callback(). - */ -typedef struct _CoglClosure CoglOnscreenDirtyClosure; - -/** - * cogl_onscreen_dirty_closure_get_type: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_onscreen_dirty_closure_get_type (void); - -/** - * cogl_onscreen_add_dirty_callback: - * @onscreen: A #CoglOnscreen framebuffer - * @callback: (scope notified): A callback function to call for dirty events - * @user_data: (closure): A private pointer to be passed to @callback - * @destroy: (allow-none): An optional callback to destroy @user_data when the - * @callback is removed or @onscreen is freed. - * - * Installs a @callback function that will be called whenever the - * window system has lost the contents of a region of the onscreen - * buffer and the application should redraw it to repair the buffer. - * For example this may happen in a window system without a compositor - * if a window that was previously covering up the onscreen window has - * been moved causing a region of the onscreen to be exposed. - * - * The @callback will be passed a #CoglOnscreenDirtyInfo struct which - * describes a rectangle containing the newly dirtied region. Note that - * this may be called multiple times to describe a non-rectangular - * region composed of multiple smaller rectangles. - * - * The dirty events are separate from %COGL_FRAME_EVENT_SYNC events so - * the application should also listen for this event before rendering - * the dirty region to ensure that the framebuffer is actually ready - * for rendering. - * - * Returns: (transfer none): a #CoglOnscreenDirtyClosure pointer that can be - * used to remove the callback and associated @user_data later. - */ -COGL_EXPORT CoglOnscreenDirtyClosure * -cogl_onscreen_add_dirty_callback (CoglOnscreen *onscreen, - CoglOnscreenDirtyCallback callback, - void *user_data, - GDestroyNotify destroy); - -/** - * cogl_onscreen_remove_dirty_callback: - * @onscreen: A #CoglOnscreen - * @closure: A #CoglOnscreenDirtyClosure returned from - * cogl_onscreen_add_dirty_callback() - * - * Removes a callback and associated user data that were previously - * registered using cogl_onscreen_add_dirty_callback(). - * - * If a destroy callback was passed to - * cogl_onscreen_add_dirty_callback() to destroy the user data then - * this will also get called. - */ -COGL_EXPORT void -cogl_onscreen_remove_dirty_callback (CoglOnscreen *onscreen, - CoglOnscreenDirtyClosure *closure); - -/** - * cogl_onscreen_get_frame_counter: - * - * Gets the value of the framebuffers frame counter. This is - * a counter that increases by one each time - * cogl_onscreen_swap_buffers() or cogl_onscreen_swap_region() - * is called. - * - * Return value: the current frame counter value - */ -COGL_EXPORT int64_t -cogl_onscreen_get_frame_counter (CoglOnscreen *onscreen); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-output-private.h b/mutter/cogl/cogl/cogl-output-private.h deleted file mode 100644 index 8185010..0000000 --- a/mutter/cogl/cogl/cogl-output-private.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-output.h" - -struct _CoglOutput -{ - GObject parent_instance; - - char *name; - - int x; /* Must be first field for _cogl_output_values_equal() */ - int y; - int width; - int height; - int mm_width; - int mm_height; - float refresh_rate; - CoglSubpixelOrder subpixel_order; -}; - -CoglOutput *_cogl_output_new (const char *name); -gboolean _cogl_output_values_equal (CoglOutput *output, - CoglOutput *other); diff --git a/mutter/cogl/cogl/cogl-output.c b/mutter/cogl/cogl/cogl-output.c deleted file mode 100644 index a161c99..0000000 --- a/mutter/cogl/cogl/cogl-output.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include "cogl/cogl-output-private.h" - -#include - -G_DEFINE_TYPE (CoglOutput, cogl_output, G_TYPE_OBJECT); - -static void -cogl_output_dispose (GObject *object) -{ - CoglOutput *output = COGL_OUTPUT (object); - - g_free (output->name); - - G_OBJECT_CLASS (cogl_output_parent_class)->dispose (object); -} - -static void -cogl_output_init (CoglOutput *output) -{ -} - -static void -cogl_output_class_init (CoglOutputClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = cogl_output_dispose; -} - -CoglOutput * -_cogl_output_new (const char *name) -{ - CoglOutput *output; - - output = g_object_new (COGL_TYPE_OUTPUT, NULL); - output->name = g_strdup (name); - - return output; -} - -gboolean -_cogl_output_values_equal (CoglOutput *output, - CoglOutput *other) -{ - return memcmp ((const char *)output + G_STRUCT_OFFSET (CoglOutput, x), - (const char *)other + G_STRUCT_OFFSET (CoglOutput, x), - sizeof (CoglOutput) - G_STRUCT_OFFSET (CoglOutput, x)) == 0; -} - -int -cogl_output_get_x (CoglOutput *output) -{ - return output->x; -} - -int -cogl_output_get_y (CoglOutput *output) -{ - return output->y; -} - -int -cogl_output_get_width (CoglOutput *output) -{ - return output->width; -} - -int -cogl_output_get_height (CoglOutput *output) -{ - return output->height; -} - -int -cogl_output_get_mm_width (CoglOutput *output) -{ - return output->mm_width; -} - -int -cogl_output_get_mm_height (CoglOutput *output) -{ - return output->mm_height; -} - -CoglSubpixelOrder -cogl_output_get_subpixel_order (CoglOutput *output) -{ - return output->subpixel_order; -} - -float -cogl_output_get_refresh_rate (CoglOutput *output) -{ - return output->refresh_rate; -} diff --git a/mutter/cogl/cogl/cogl-output.h b/mutter/cogl/cogl/cogl-output.h deleted file mode 100644 index 3542755..0000000 --- a/mutter/cogl/cogl/cogl-output.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Owen Taylor - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-types.h" - -#include - -G_BEGIN_DECLS - -/** - * CoglOutput: - * - * Information about an output device - * - * The #CoglOutput object holds information about an output device - * such as a monitor or laptop display. It can be queried to find - * out the position of the output with respect to the screen - * coordinate system and other information such as the resolution - * and refresh rate of the device. - * - * There can be any number of outputs which may overlap: the - * same area of the screen may be displayed by multiple output - * devices. - * - * XXX: though it's possible to query the position of the output - * with respect to screen coordinates, there is currently no way - * of finding out the position of a #CoglOnscreen in screen - * coordinates, at least without using windowing-system specific - * API's, so it's not easy to get the output positions relative - * to the #CoglOnscreen. - */ - -typedef struct _CoglOutput CoglOutput; - -#define COGL_TYPE_OUTPUT (cogl_output_get_type ()) - -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglOutput, - cogl_output, - COGL, - OUTPUT, - GObject) - -/** - * CoglSubpixelOrder: - * @COGL_SUBPIXEL_ORDER_UNKNOWN: the layout of subpixel - * components for the device is unknown. - * @COGL_SUBPIXEL_ORDER_NONE: the device displays colors - * without geometrically-separated subpixel components, - * or the positioning or colors of the components do not - * match any of the values in the enumeration. - * @COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB: the device has - * horizontally arranged components in the order - * red-green-blue from left to right. - * @COGL_SUBPIXEL_ORDER_HORIZONTAL_BGR: the device has - * horizontally arranged components in the order - * blue-green-red from left to right. - * @COGL_SUBPIXEL_ORDER_VERTICAL_RGB: the device has - * vertically arranged components in the order - * red-green-blue from top to bottom. - * @COGL_SUBPIXEL_ORDER_VERTICAL_BGR: the device has - * vertically arranged components in the order - * blue-green-red from top to bottom. - * - * Some output devices (such as LCD panels) display colors - * by making each pixel consist of smaller "subpixels" - * that each have a particular color. By using knowledge - * of the layout of this subpixel components, it is possible - * to create image content with higher resolution than the - * pixel grid. - */ -typedef enum -{ - COGL_SUBPIXEL_ORDER_UNKNOWN, - COGL_SUBPIXEL_ORDER_NONE, - COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB, - COGL_SUBPIXEL_ORDER_HORIZONTAL_BGR, - COGL_SUBPIXEL_ORDER_VERTICAL_RGB, - COGL_SUBPIXEL_ORDER_VERTICAL_BGR -} CoglSubpixelOrder; - -/** - * cogl_output_get_x: - * @output: a #CoglOutput - * - * Gets the X position of the output with respect to the coordinate - * system of the screen. - * - * Return value: the X position of the output as a pixel offset - * from the left side of the screen coordinate space - */ -COGL_EXPORT int -cogl_output_get_x (CoglOutput *output); - -/** - * cogl_output_get_y: - * @output: a #CoglOutput - * - * Gets the Y position of the output with respect to the coordinate - * system of the screen. - * - * Return value: the Y position of the output as a pixel offset - * from the top side of the screen coordinate space - */ -COGL_EXPORT int -cogl_output_get_y (CoglOutput *output); - -/** - * cogl_output_get_width: - * @output: a #CoglOutput - * - * Gets the width of the output in pixels. - * - * Return value: the width of the output in pixels - */ -COGL_EXPORT int -cogl_output_get_width (CoglOutput *output); - -/** - * cogl_output_get_height: - * @output: a #CoglOutput - * - * Gets the height of the output in pixels. - * - * Return value: the height of the output in pixels - */ -COGL_EXPORT int -cogl_output_get_height (CoglOutput *output); - -/** - * cogl_output_get_mm_width: - * @output: a #CoglOutput - * - * Gets the physical width of the output. In some cases (such as - * as a projector), the value returned here might correspond to - * nominal resolution rather than the actual physical size of the - * output device. - * - * Return value: the height of the output in millimeters. A value - * of 0 indicates the width is unknown - */ -COGL_EXPORT int -cogl_output_get_mm_width (CoglOutput *output); - -/** - * cogl_output_get_mm_height: - * @output: a #CoglOutput - * - * Gets the physical height of the output. In some cases (such as - * as a projector), the value returned here might correspond to - * nominal resolution rather than the actual physical size of the - * output device. - * - * Return value: the height of the output in millimeters. A value - * of 0 indicates that the height is unknown - */ -COGL_EXPORT int -cogl_output_get_mm_height (CoglOutput *output); - -/** - * cogl_output_get_subpixel_order: - * @output: a #CoglOutput - * - * For an output device where each pixel is made up of smaller components - * with different colors, returns the layout of the subpixel - * components. - * - * Return value: the order of subpixel components for the output device - */ -COGL_EXPORT CoglSubpixelOrder -cogl_output_get_subpixel_order (CoglOutput *output); - -/** - * cogl_output_get_refresh_rate: - * @output: a #CoglOutput - * - * Gets the number of times per second that the output device refreshes - * the display contents. - * - * Return value: the refresh rate of the output device. A value of zero - * indicates that the refresh rate is unknown. - */ -COGL_EXPORT float -cogl_output_get_refresh_rate (CoglOutput *output); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-pipeline-cache-private.h b/mutter/cogl/cogl/cogl-pipeline-cache-private.h deleted file mode 100644 index f105c7e..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-cache-private.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2022 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#include "cogl/cogl-macros.h" -#include "cogl/cogl-pipeline-hash-table.h" - -COGL_EXPORT_TEST -CoglPipelineHashTable * cogl_pipeline_cache_get_fragment_hash (CoglPipelineCache *cache); - - -COGL_EXPORT_TEST -CoglPipelineHashTable * cogl_pipeline_cache_get_combined_hash (CoglPipelineCache *cache); diff --git a/mutter/cogl/cogl/cogl-pipeline-cache.c b/mutter/cogl/cogl/cogl-pipeline-cache.c deleted file mode 100644 index c591f6d..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-cache.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011, 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Neil Roberts - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-pipeline-cache.h" -#include "cogl/cogl-pipeline-cache-private.h" -#include "cogl/cogl-pipeline-hash-table.h" - -struct _CoglPipelineCache -{ - CoglPipelineHashTable fragment_hash; - CoglPipelineHashTable vertex_hash; - CoglPipelineHashTable combined_hash; -}; - -CoglPipelineCache * -_cogl_pipeline_cache_new (CoglContext *ctx) -{ - g_autofree CoglPipelineCache *cache = g_new (CoglPipelineCache, 1); - unsigned long vertex_state; - unsigned long layer_vertex_state; - unsigned int fragment_state; - unsigned int layer_fragment_state; - - vertex_state = - _cogl_pipeline_get_state_for_vertex_codegen (ctx); - layer_vertex_state = - COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN; - fragment_state = - _cogl_pipeline_get_state_for_fragment_codegen (ctx); - layer_fragment_state = - _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx); - - _cogl_pipeline_hash_table_init (&cache->vertex_hash, - vertex_state, - layer_vertex_state, - "vertex shaders"); - _cogl_pipeline_hash_table_init (&cache->fragment_hash, - fragment_state, - layer_fragment_state, - "fragment shaders"); - _cogl_pipeline_hash_table_init (&cache->combined_hash, - vertex_state | fragment_state, - layer_vertex_state | layer_fragment_state, - "programs"); - - return g_steal_pointer (&cache); -} - -void -_cogl_pipeline_cache_free (CoglPipelineCache *cache) -{ - _cogl_pipeline_hash_table_destroy (&cache->fragment_hash); - _cogl_pipeline_hash_table_destroy (&cache->vertex_hash); - _cogl_pipeline_hash_table_destroy (&cache->combined_hash); - g_free (cache); -} - -CoglPipelineCacheEntry * -_cogl_pipeline_cache_get_fragment_template (CoglPipelineCache *cache, - CoglPipeline *key_pipeline) -{ - return _cogl_pipeline_hash_table_get (&cache->fragment_hash, - key_pipeline); -} - -CoglPipelineCacheEntry * -_cogl_pipeline_cache_get_vertex_template (CoglPipelineCache *cache, - CoglPipeline *key_pipeline) -{ - return _cogl_pipeline_hash_table_get (&cache->vertex_hash, - key_pipeline); -} - -CoglPipelineCacheEntry * -_cogl_pipeline_cache_get_combined_template (CoglPipelineCache *cache, - CoglPipeline *key_pipeline) -{ - return _cogl_pipeline_hash_table_get (&cache->combined_hash, - key_pipeline); -} - -CoglPipelineHashTable * -cogl_pipeline_cache_get_fragment_hash (CoglPipelineCache *cache) -{ - return &cache->fragment_hash; -} - -CoglPipelineHashTable * -cogl_pipeline_cache_get_combined_hash (CoglPipelineCache *cache) -{ - return &cache->combined_hash; -} diff --git a/mutter/cogl/cogl/cogl-pipeline-cache.h b/mutter/cogl/cogl/cogl-pipeline-cache.h deleted file mode 100644 index 99b9c3e..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-cache.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-pipeline.h" - -typedef struct _CoglPipelineCache CoglPipelineCache; - -typedef struct -{ - CoglPipeline *pipeline; - - /* Number of usages of this template. If this drops to zero then it - * will be a candidate for removal from the cache */ - int usage_count; -} CoglPipelineCacheEntry; - -CoglPipelineCache * -_cogl_pipeline_cache_new (CoglContext *ctx); - -void -_cogl_pipeline_cache_free (CoglPipelineCache *cache); - -/* - * Gets a pipeline from the cache that has the same state as - * @key_pipeline for the state in - * COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN. If there is no - * matching pipeline already then a copy of key_pipeline is stored in - * the cache so that it will be used next time the function is called - * with a similar pipeline. In that case the copy itself will be - * returned - */ -CoglPipelineCacheEntry * -_cogl_pipeline_cache_get_fragment_template (CoglPipelineCache *cache, - CoglPipeline *key_pipeline); - -/* - * Gets a pipeline from the cache that has the same state as - * @key_pipeline for the state in - * COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN. If there is no - * matching pipeline already then a copy of key_pipeline is stored in - * the cache so that it will be used next time the function is called - * with a similar pipeline. In that case the copy itself will be - * returned - */ -CoglPipelineCacheEntry * -_cogl_pipeline_cache_get_vertex_template (CoglPipelineCache *cache, - CoglPipeline *key_pipeline); - -/* - * Gets a pipeline from the cache that has the same state as - * @key_pipeline for the combination of the state state in - * COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN and - * COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN. If there is no - * matching pipeline already then a copy of key_pipeline is stored in - * the cache so that it will be used next time the function is called - * with a similar pipeline. In that case the copy itself will be - * returned - */ -CoglPipelineCacheEntry * -_cogl_pipeline_cache_get_combined_template (CoglPipelineCache *cache, - CoglPipeline *key_pipeline); diff --git a/mutter/cogl/cogl/cogl-pipeline-debug.c b/mutter/cogl/cogl/cogl-pipeline-debug.c deleted file mode 100644 index ba86df7..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-debug.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-debug.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-pipeline-layer-private.h" -#include "cogl/cogl-node-private.h" - -#include - -typedef struct -{ - int parent_id; - int *node_id_ptr; - GString *graph; - int indent; -} PrintDebugState; - -static gboolean -dump_layer_cb (CoglNode *node, void *user_data) -{ - CoglPipelineLayer *layer = COGL_PIPELINE_LAYER (node); - PrintDebugState *state = user_data; - int layer_id = *state->node_id_ptr; - PrintDebugState state_out; - GString *changes_label; - gboolean changes = FALSE; - - if (state->parent_id >= 0) - g_string_append_printf (state->graph, "%*slayer%p -> layer%p;\n", - state->indent, "", - layer->parent_instance.parent, - layer); - - g_string_append_printf (state->graph, - "%*slayer%p [label=\"layer=0x%p\\n" - "ref count=%d\" " - "color=\"blue\"];\n", - state->indent, "", - layer, - layer, - G_OBJECT (layer)->ref_count); - - changes_label = g_string_new (""); - g_string_append_printf (changes_label, - "%*slayer%p -> layer_state%d [weight=100];\n" - "%*slayer_state%d [shape=box label=\"", - state->indent, "", - layer, - layer_id, - state->indent, "", - layer_id); - - if (layer->differences & COGL_PIPELINE_LAYER_STATE_UNIT) - { - changes = TRUE; - g_string_append_printf (changes_label, - "\\lunit=%u\\n", - layer->unit_index); - } - - if (layer->differences & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA) - { - changes = TRUE; - g_string_append_printf (changes_label, - "\\ltexture=%p\\n", - layer->texture); - } - - if (changes) - { - g_string_append_printf (changes_label, "\"];\n"); - g_string_append (state->graph, changes_label->str); - } - - g_string_free (changes_label, TRUE); - - state_out.parent_id = layer_id; - - state_out.node_id_ptr = state->node_id_ptr; - (*state_out.node_id_ptr)++; - - state_out.graph = state->graph; - state_out.indent = state->indent + 2; - - _cogl_pipeline_node_foreach_child (COGL_NODE (layer), - dump_layer_cb, - &state_out); - - return TRUE; -} - -static gboolean -dump_layer_ref_cb (CoglPipelineLayer *layer, void *data) -{ - PrintDebugState *state = data; - int pipeline_id = *state->node_id_ptr; - - g_string_append_printf (state->graph, - "%*spipeline_state%d -> layer%p;\n", - state->indent, "", - pipeline_id, - layer); - - return TRUE; -} - -static gboolean -dump_pipeline_cb (CoglNode *node, void *user_data) -{ - CoglPipeline *pipeline = COGL_PIPELINE (node); - PrintDebugState *state = user_data; - int pipeline_id = *state->node_id_ptr; - PrintDebugState state_out; - GString *changes_label; - gboolean changes = FALSE; - gboolean layers = FALSE; - - if (state->parent_id >= 0) - g_string_append_printf (state->graph, "%*spipeline%d -> pipeline%d;\n", - state->indent, "", - state->parent_id, - pipeline_id); - - g_string_append_printf (state->graph, - "%*spipeline%d [label=\"pipeline=0x%p\\n" - "ref count=%d\\n" - "breadcrumb=\\\"%s\\\"\" color=\"red\"];\n", - state->indent, "", - pipeline_id, - pipeline, - G_OBJECT (pipeline)->ref_count, -#ifdef COGL_ENABLE_DEBUG - pipeline->has_static_breadcrumb ? - pipeline->static_breadcrumb : "NULL" -#else - "NULL" -#endif - ); - - changes_label = g_string_new (""); - g_string_append_printf (changes_label, - "%*spipeline%d -> pipeline_state%d [weight=100];\n" - "%*spipeline_state%d [shape=box label=\"", - state->indent, "", - pipeline_id, - pipeline_id, - state->indent, "", - pipeline_id); - - - if (pipeline->differences & COGL_PIPELINE_STATE_COLOR) - { - changes = TRUE; - g_string_append_printf (changes_label, - "\\lcolor=0x%02X%02X%02X%02X\\n", - (int) (cogl_color_get_red (&pipeline->color) * 255.0), - (int) (cogl_color_get_green (&pipeline->color) * 255.0), - (int) (cogl_color_get_blue (&pipeline->color) * 255.0), - (int) (cogl_color_get_alpha (&pipeline->color) * 255.0)); - } - - if (pipeline->differences & COGL_PIPELINE_STATE_BLEND) - { - changes = TRUE; - g_string_append_printf (changes_label, - "\\lblend\\n"); - } - - if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS) - { - changes = TRUE; - layers = TRUE; - g_string_append_printf (changes_label, "\\ln_layers=%d\\n", - pipeline->n_layers); - } - - if (changes) - { - g_string_append_printf (changes_label, "\"];\n"); - g_string_append (state->graph, changes_label->str); - } - - g_string_free (changes_label, TRUE); - - if (layers) - { - g_list_foreach (pipeline->layer_differences, - (GFunc)dump_layer_ref_cb, - state); - } - - state_out.parent_id = pipeline_id; - - state_out.node_id_ptr = state->node_id_ptr; - (*state_out.node_id_ptr)++; - - state_out.graph = state->graph; - state_out.indent = state->indent + 2; - - _cogl_pipeline_node_foreach_child (COGL_NODE (pipeline), - dump_pipeline_cb, - &state_out); - - return TRUE; -} - -/* This function is just here to be called from GDB so we don't really - want to put a declaration in a header and we just add it here to - avoid a warning */ -void -_cogl_debug_dump_pipelines_dot_file (const char *filename); - -void -_cogl_debug_dump_pipelines_dot_file (const char *filename) -{ - GString *graph; - PrintDebugState layer_state; - PrintDebugState pipeline_state; - int layer_id = 0; - int pipeline_id = 0; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!ctx->default_pipeline) - return; - - graph = g_string_new (""); - g_string_append_printf (graph, "digraph {\n"); - - layer_state.graph = graph; - layer_state.parent_id = -1; - layer_state.node_id_ptr = &layer_id; - layer_state.indent = 0; - dump_layer_cb ((CoglNode *)ctx->default_layer_0, &layer_state); - - pipeline_state.graph = graph; - pipeline_state.parent_id = -1; - pipeline_state.node_id_ptr = &pipeline_id; - pipeline_state.indent = 0; - dump_pipeline_cb ((CoglNode *)ctx->default_pipeline, &pipeline_state); - - g_string_append_printf (graph, "}\n"); - - if (filename) - g_file_set_contents (filename, graph->str, -1, NULL); - else - g_print ("%s", graph->str); - - g_string_free (graph, TRUE); -} diff --git a/mutter/cogl/cogl/cogl-pipeline-hash-table.c b/mutter/cogl/cogl/cogl-pipeline-hash-table.c deleted file mode 100644 index e57dfbf..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-hash-table.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Neil Roberts - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-pipeline-hash-table.h" -#include "cogl/cogl-pipeline-cache.h" - -typedef struct -{ - CoglPipelineCacheEntry parent; - - /* Calculating the hash is a little bit expensive for pipelines so - * we don't want to do it repeatedly for entries that are already in - * the hash table. Instead we cache the value here and calculate it - * outside of the GHashTable. */ - unsigned int hash_value; - - /* GHashTable annoyingly doesn't let us pass a user data pointer to - * the hash and equal functions so to work around it we have to - * store the pointer in every hash table entry. We will use this - * entry as both the key and the value */ - CoglPipelineHashTable *hash; - - /* The number of unique pipelines that had been created when this - * pipeline was last accessed */ - int age; -} CoglPipelineHashTableEntry; - -static void -value_destroy_cb (void *value) -{ - CoglPipelineHashTableEntry *entry = value; - - g_object_unref (entry->parent.pipeline); - - g_free (entry); -} - -static unsigned int -entry_hash (const void *data) -{ - const CoglPipelineHashTableEntry *entry = data; - - return entry->hash_value; -} - -static gboolean -entry_equal (const void *a, - const void *b) -{ - const CoglPipelineHashTableEntry *entry_a = a; - const CoglPipelineHashTableEntry *entry_b = b; - const CoglPipelineHashTable *hash = entry_a->hash; - - return _cogl_pipeline_equal (entry_a->parent.pipeline, - entry_b->parent.pipeline, - hash->main_state, - hash->layer_state); -} - -void -_cogl_pipeline_hash_table_init (CoglPipelineHashTable *hash, - unsigned int main_state, - unsigned int layer_state, - const char *debug_string) -{ - hash->n_unique_pipelines = 0; - hash->debug_string = debug_string; - hash->main_state = main_state; - hash->layer_state = layer_state; - /* We'll only start pruning once we get to 16 unique pipelines */ - hash->expected_min_size = 8; - hash->table = g_hash_table_new_full (entry_hash, - entry_equal, - NULL, /* key destroy */ - value_destroy_cb); -} - -void -_cogl_pipeline_hash_table_destroy (CoglPipelineHashTable *hash) -{ - g_hash_table_destroy (hash->table); -} - -static void -collect_prunable_entries_cb (void *key, - void *value, - void *user_data) -{ - GQueue *entries = user_data; - CoglPipelineCacheEntry *entry = value; - - if (entry->usage_count == 0) - g_queue_push_tail (entries, entry); -} - -static int -compare_pipeline_age_cb (const void *a, - const void *b) -{ - const CoglPipelineHashTableEntry *ae = a; - const CoglPipelineHashTableEntry *be = b; - - return be->age - ae->age; -} - -static void -prune_old_pipelines (CoglPipelineHashTable *hash) -{ - GQueue entries; - GList *l; - int i; - - /* Collect all of the prunable entries into a GQueue */ - g_queue_init (&entries); - g_hash_table_foreach (hash->table, - collect_prunable_entries_cb, - &entries); - - /* Sort the entries by increasing order of age */ - entries.head = g_list_sort (entries.head, compare_pipeline_age_cb); - - /* The +1 is to include the pipeline that we're about to add */ - hash->expected_min_size = (g_hash_table_size (hash->table) - - entries.length + - 1); - - /* Remove oldest half of the prunable pipelines. We still want to - * keep some of the prunable entries that are recently used because - * it's not unlikely that the application will recreate the same - * pipeline */ - for (l = entries.head, i = 0; i < entries.length / 2; l = l->next, i++) - { - CoglPipelineCacheEntry *entry = l->data; - - g_hash_table_remove (hash->table, entry); - } - - g_list_free (entries.head); -} - -CoglPipelineCacheEntry * -_cogl_pipeline_hash_table_get (CoglPipelineHashTable *hash, - CoglPipeline *key_pipeline) -{ - CoglPipelineHashTableEntry dummy_entry; - CoglPipelineHashTableEntry *entry; - unsigned int copy_state; - - dummy_entry.parent.pipeline = key_pipeline; - dummy_entry.hash = hash; - dummy_entry.hash_value = _cogl_pipeline_hash (key_pipeline, - hash->main_state, - hash->layer_state); - entry = g_hash_table_lookup (hash->table, &dummy_entry); - - if (entry) - { - entry->age = hash->n_unique_pipelines; - return &entry->parent; - } - - if (hash->n_unique_pipelines == 50) - g_warning ("Over 50 separate %s have been generated which is very " - "unusual, so something is probably wrong!\n", - hash->debug_string); - - /* If we are going to have more than twice the expected minimum - * number of pipelines in the hash then we'll try pruning and update - * the minimum */ - if (g_hash_table_size (hash->table) >= hash->expected_min_size * 2) - prune_old_pipelines (hash); - - entry = g_new0 (CoglPipelineHashTableEntry, 1); - entry->parent.usage_count = 0; - entry->hash = hash; - entry->hash_value = dummy_entry.hash_value; - entry->age = hash->n_unique_pipelines; - - copy_state = hash->main_state; - if (hash->layer_state) - copy_state |= COGL_PIPELINE_STATE_LAYERS; - - /* Create a new pipeline that is a child of the root pipeline - * instead of a normal copy so that the template pipeline won't hold - * a reference to the original pipeline */ - entry->parent.pipeline = _cogl_pipeline_deep_copy (key_pipeline, - copy_state, - hash->layer_state); - - g_hash_table_insert (hash->table, entry, entry); - - hash->n_unique_pipelines++; - - return &entry->parent; -} diff --git a/mutter/cogl/cogl/cogl-pipeline-hash-table.h b/mutter/cogl/cogl/cogl-pipeline-hash-table.h deleted file mode 100644 index 3fc1c7e..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-hash-table.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-pipeline-cache.h" - -typedef struct -{ - /* Total number of pipelines that were ever added to the hash. This - * is not decremented when a pipeline is removed. It is only used to - * generate a warning if an unusually high number of pipelines are - * generated */ - int n_unique_pipelines; - - /* This is the expected minimum size we could prune the hash table - * to if we were to remove all pipelines that are not in use. This - * is only updated after we prune the table */ - int expected_min_size; - - /* String that will be used to describe the usage of this hash table - * in the debug warning when too many pipelines are generated. This - * must be a static string because it won't be copied or freed */ - const char *debug_string; - - unsigned int main_state; - unsigned int layer_state; - - GHashTable *table; -} CoglPipelineHashTable; - -void -_cogl_pipeline_hash_table_init (CoglPipelineHashTable *hash, - unsigned int main_state, - unsigned int layer_state, - const char *debug_string); - -void -_cogl_pipeline_hash_table_destroy (CoglPipelineHashTable *hash); - -/* - * Gets a pipeline from the hash that has the same state as - * @key_pipeline according to the limited state bits passed to - * _cogl_pipeline_hash_table_init(). If there is no matching pipelines - * already then a copy of key_pipeline is stored in the hash so that - * it will be used next time the function is called with a similar - * pipeline. In that case the copy itself will be returned - */ -CoglPipelineCacheEntry * -_cogl_pipeline_hash_table_get (CoglPipelineHashTable *hash, - CoglPipeline *key_pipeline); diff --git a/mutter/cogl/cogl/cogl-pipeline-layer-private.h b/mutter/cogl/cogl/cogl-pipeline-layer-private.h deleted file mode 100644 index b939044..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-layer-private.h +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-private.h" -#include "cogl/cogl-pipeline.h" -#include "cogl/cogl-node-private.h" -#include "cogl/cogl-texture.h" -#include "cogl/cogl-pipeline-layer-state.h" -#include "cogl/cogl-pipeline-snippet-private.h" -#include "cogl/cogl-sampler-cache-private.h" - -#include - -#define COGL_TYPE_PIPELINE_LAYER (cogl_pipeline_layer_get_type ()) -#define COGL_PIPELINE_LAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_PIPELINE_LAYER, CoglPipelineLayer)) -#define COGL_PIPELINE_LAYER_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_PIPELINE_LAYER, CoglPipelineLayer const)) -#define COGL_PIPELINE_LAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_TYPE_PIPELINE_LAYER, CoglPipelineLayerClass)) -#define COGL_IS_PIPELINE_LAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_TYPE_PIPELINE_LAYER)) -#define COGL_IS_PIPELINE_LAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_TYPE_PIPELINE_LAYER)) -#define COGL_PIPELINE_LAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COGL_TYPE_PIPELINE_LAYER, CoglPipelineLayerClass)) - -typedef struct _CoglPipelineLayerClass CoglPipelineLayerClass; -typedef struct _CoglPipelineLayer CoglPipelineLayer; - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (CoglPipelineLayer, g_object_unref) - -GType cogl_pipeline_layer_get_type (void) G_GNUC_CONST; - -/* XXX: should I rename these as - * COGL_PIPELINE_LAYER_STATE_INDEX_XYZ... ? - */ -typedef enum -{ - /* sparse state */ - COGL_PIPELINE_LAYER_STATE_UNIT_INDEX, - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX, - COGL_PIPELINE_LAYER_STATE_SAMPLER_INDEX, - COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX, - COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX, - COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX, - COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX, - COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS_INDEX, - COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS_INDEX, - - /* note: layers don't currently have any non-sparse state */ - - COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT, - COGL_PIPELINE_LAYER_STATE_COUNT = COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT -} CoglPipelineLayerStateIndex; - -/* XXX: If you add or remove state groups here you may need to update - * some of the state masks following this enum too! - * - * FIXME: perhaps it would be better to rename this enum to - * CoglPipelineLayerStateGroup to better convey the fact that a single - * enum here can map to multiple properties. - */ -typedef enum -{ - COGL_PIPELINE_LAYER_STATE_UNIT = - 1L< TEXTURE0 to store - very large layer numbers */ - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE, - COGL_PIPELINE_COMBINE_SOURCE_CONSTANT, - COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR, - COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS, - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 -} CoglPipelineCombineSource; - -typedef enum -{ - /* These are the same values as GL */ - COGL_PIPELINE_COMBINE_OP_SRC_COLOR = 0x0300, - COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_COLOR = 0x0301, - COGL_PIPELINE_COMBINE_OP_SRC_ALPHA = 0x0302, - COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA = 0x0303 -} CoglPipelineCombineOp; - -typedef struct -{ - /* The texture combine state determines how the color of individual - * texture fragments are calculated. */ - CoglPipelineCombineFunc texture_combine_rgb_func; - CoglPipelineCombineSource texture_combine_rgb_src[3]; - CoglPipelineCombineOp texture_combine_rgb_op[3]; - - CoglPipelineCombineFunc texture_combine_alpha_func; - CoglPipelineCombineSource texture_combine_alpha_src[3]; - CoglPipelineCombineOp texture_combine_alpha_op[3]; - - float texture_combine_constant[4]; - - /* The texture matrix dscribes how to transform texture coordinates */ - graphene_matrix_t matrix; - - CoglPipelineSnippetList vertex_snippets; - CoglPipelineSnippetList fragment_snippets; - - gboolean point_sprite_coords; -} CoglPipelineLayerBigState; - -struct _CoglPipelineLayer -{ - /* XXX: Please think twice about adding members that *have* be - * initialized during a _cogl_pipeline_layer_copy. We are aiming - * to have copies be as cheap as possible and copies may be - * done by the primitives APIs which means they may happen - * in performance critical code paths. - * - * XXX: If you are extending the state we track please consider if - * the state is expected to vary frequently across many pipelines or - * if the state can be shared among many derived pipelines instead. - * This will determine if the state should be added directly to this - * structure which will increase the memory overhead for *all* - * layers or if instead it can go under ->big_state. - */ - - /* Layers represent their state in a tree structure where some of - * the state relating to a given pipeline or layer may actually be - * owned by one if is ancestors in the tree. We have a common data - * type to track the tree hierarchy so we can share code... */ - CoglNode parent_instance; - - /* Some layers have a pipeline owner, which is to say that the layer - * is referenced in that pipelines->layer_differences list. A layer - * doesn't always have an owner and may simply be an ancestor for - * other layers that keeps track of some shared state. */ - CoglPipeline *owner; - - /* The lowest index is blended first then others on top */ - int index; - - /* A mask of which state groups are different in this layer - * in comparison to its parent. */ - unsigned int differences; - - /* Common differences - * - * As a basic way to reduce memory usage we divide the layer - * state into two groups; the minimal state modified in 90% of - * all layers and the rest, so that the second group can - * be allocated dynamically when required. - */ - - /* Each layer is directly associated with a single texture unit */ - int unit_index; - - /* The texture for this layer, or NULL for an empty - * layer */ - CoglTexture *texture; - - const CoglSamplerCacheEntry *sampler_cache_entry; - - /* Infrequent differences aren't currently tracked in - * a separate, dynamically allocated structure as they are - * for pipelines... */ - CoglPipelineLayerBigState *big_state; - - /* bitfields */ - - /* Determines if layer->big_state is valid */ - unsigned int has_big_state:1; - -}; - -struct _CoglPipelineLayerClass -{ - CoglNodeClass parent_class; -}; - - -typedef gboolean -(*CoglPipelineLayerStateComparator) (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - - - -void -_cogl_pipeline_init_default_layers (CoglContext *ctx); - -static inline CoglPipelineLayer * -_cogl_pipeline_layer_get_parent (CoglPipelineLayer *layer) -{ - CoglNode *parent_node = COGL_NODE (layer)->parent; - return COGL_PIPELINE_LAYER (parent_node); -} - -CoglPipelineLayer * -_cogl_pipeline_layer_copy (CoglPipelineLayer *layer); - -void -_cogl_pipeline_layer_resolve_authorities (CoglPipelineLayer *layer, - unsigned long differences, - CoglPipelineLayer **authorities); - -gboolean -_cogl_pipeline_layer_equal (CoglPipelineLayer *layer0, - CoglPipelineLayer *layer1, - unsigned long differences_mask); - -CoglPipelineLayer * -_cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change); - -void -_cogl_pipeline_layer_prune_redundant_ancestry (CoglPipelineLayer *layer); - -gboolean -_cogl_pipeline_layer_has_alpha (CoglPipelineLayer *layer); - -gboolean -_cogl_pipeline_layer_has_user_matrix (CoglPipeline *pipeline, - int layer_index); - -/* - * Calls the pre_paint method on the layer texture if there is - * one. This will determine whether mipmaps are needed based on the - * filter settings. - */ -void -_cogl_pipeline_layer_pre_paint (CoglPipelineLayer *layerr); - -void -_cogl_pipeline_layer_get_wrap_modes (CoglPipelineLayer *layer, - CoglSamplerCacheWrapMode *wrap_mode_s, - CoglSamplerCacheWrapMode *wrap_mode_t); - -void -_cogl_pipeline_layer_get_filters (CoglPipelineLayer *layer, - CoglPipelineFilter *min_filter, - CoglPipelineFilter *mag_filter); - -const CoglSamplerCacheEntry * -_cogl_pipeline_layer_get_sampler_state (CoglPipelineLayer *layer); - -typedef enum -{ - COGL_PIPELINE_LAYER_TYPE_TEXTURE -} CoglPipelineLayerType; - -CoglPipelineLayerType -_cogl_pipeline_layer_get_type (CoglPipelineLayer *layer); - -CoglTexture * -_cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer); - -CoglTexture * -_cogl_pipeline_layer_get_texture_real (CoglPipelineLayer *layer); - -void -_cogl_pipeline_layer_copy_differences (CoglPipelineLayer *dest, - CoglPipelineLayer *src, - unsigned long differences); - -unsigned long -_cogl_pipeline_layer_compare_differences (CoglPipelineLayer *layer0, - CoglPipelineLayer *layer1); - -CoglPipelineLayer * -_cogl_pipeline_layer_get_authority (CoglPipelineLayer *layer, - unsigned long difference); - -int -_cogl_pipeline_layer_get_unit_index (CoglPipelineLayer *layer); - -gboolean -_cogl_pipeline_layer_needs_combine_separate - (CoglPipelineLayer *combine_authority); diff --git a/mutter/cogl/cogl/cogl-pipeline-layer-state-private.h b/mutter/cogl/cogl/cogl-pipeline-layer-state-private.h deleted file mode 100644 index 17652de..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-layer-state-private.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-pipeline-layer-state.h" -#include "cogl/cogl-pipeline-private.h" - -CoglPipelineLayer * -_cogl_pipeline_set_layer_unit (CoglPipeline *required_owner, - CoglPipelineLayer *layer, - int unit_index); - -gboolean -_cogl_pipeline_layer_texture_data_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - -gboolean -_cogl_pipeline_layer_combine_state_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - -gboolean -_cogl_pipeline_layer_combine_constant_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - -gboolean -_cogl_pipeline_layer_sampler_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - -gboolean -_cogl_pipeline_layer_user_matrix_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - -gboolean -_cogl_pipeline_layer_point_sprite_coords_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - -gboolean -_cogl_pipeline_layer_vertex_snippets_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - -gboolean -_cogl_pipeline_layer_fragment_snippets_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - -void -_cogl_pipeline_layer_hash_unit_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -void -_cogl_pipeline_layer_hash_texture_data_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -void -_cogl_pipeline_layer_hash_sampler_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -void -_cogl_pipeline_layer_hash_combine_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -void -_cogl_pipeline_layer_hash_combine_constant_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -void -_cogl_pipeline_layer_hash_user_matrix_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -void -_cogl_pipeline_layer_hash_point_sprite_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -void -_cogl_pipeline_layer_hash_vertex_snippets_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -void -_cogl_pipeline_layer_hash_fragment_snippets_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); diff --git a/mutter/cogl/cogl/cogl-pipeline-layer-state.c b/mutter/cogl/cogl/cogl-pipeline-layer-state.c deleted file mode 100644 index 88a6dc8..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-layer-state.c +++ /dev/null @@ -1,1481 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-blend-string.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-snippet-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-pipeline-layer-state-private.h" - -#include "string.h" - -/* - * XXX: consider special casing layer->unit_index so it's not a sparse - * property so instead we can assume it's valid for all layer - * instances. - * - We would need to initialize ->unit_index in - * _cogl_pipeline_layer_copy (). - * - * XXX: If you use this API you should consider that the given layer - * might not be writeable and so a new derived layer will be allocated - * and modified instead. The layer modified will be returned so you - * can identify when this happens. - */ -CoglPipelineLayer * -_cogl_pipeline_set_layer_unit (CoglPipeline *required_owner, - CoglPipelineLayer *layer, - int unit_index) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_UNIT; - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, change); - CoglPipelineLayer *new; - - if (authority->unit_index == unit_index) - return layer; - - new = - _cogl_pipeline_layer_pre_change_notify (required_owner, - layer, - change); - if (new != layer) - layer = new; - else - { - /* If the layer we found is currently the authority on the state - * we are changing see if we can revert to one of our ancestors - * being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, change); - - if (old_authority->unit_index == unit_index) - { - layer->differences &= ~change; - return layer; - } - } - } - - layer->unit_index = unit_index; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - - return layer; -} - -CoglTexture * -_cogl_pipeline_layer_get_texture_real (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA); - - return authority->texture; -} - -CoglTexture * -cogl_pipeline_get_layer_texture (CoglPipeline *pipeline, - int layer_index) -{ - CoglPipelineLayer *layer = - _cogl_pipeline_get_layer (pipeline, layer_index); - return _cogl_pipeline_layer_get_texture (layer); -} - -static void -_cogl_pipeline_set_layer_texture_data (CoglPipeline *pipeline, - int layer_index, - CoglTexture *texture) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglPipelineLayer *new; - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - if (authority->texture == texture) - return; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, change); - - if (old_authority->texture == texture) - { - layer->differences &= ~change; - - if (layer->texture != NULL) - g_object_unref (layer->texture); - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - goto changed; - } - } - } - - if (texture != NULL) - g_object_ref (texture); - if (layer == authority && - layer->texture != NULL) - g_object_unref (layer->texture); - layer->texture = texture; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - -changed: - - pipeline->dirty_real_blend_enable = TRUE; -} - -void -cogl_pipeline_set_layer_texture (CoglPipeline *pipeline, - int layer_index, - CoglTexture *texture) -{ - _cogl_pipeline_set_layer_texture_data (pipeline, layer_index, texture); -} - -void -cogl_pipeline_set_layer_null_texture (CoglPipeline *pipeline, - int layer_index) -{ - _cogl_pipeline_set_layer_texture_data (pipeline, layer_index, NULL); -} - -static void -_cogl_pipeline_set_layer_sampler_state (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - CoglPipelineLayer *authority, - const CoglSamplerCacheEntry *state) -{ - CoglPipelineLayer *new; - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_SAMPLER; - - if (authority->sampler_cache_entry == state) - return; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, change); - - if (old_authority->sampler_cache_entry == state) - { - layer->differences &= ~change; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - return; - } - } - } - - layer->sampler_cache_entry = state; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } -} - -static CoglSamplerCacheWrapMode -public_to_internal_wrap_mode (CoglPipelineWrapMode mode) -{ - return (CoglSamplerCacheWrapMode)mode; -} - -static CoglPipelineWrapMode -internal_to_public_wrap_mode (CoglSamplerCacheWrapMode internal_mode) -{ - g_return_val_if_fail (internal_mode != - COGL_SAMPLER_CACHE_WRAP_MODE_CLAMP_TO_BORDER, - COGL_PIPELINE_WRAP_MODE_AUTOMATIC); - return (CoglPipelineWrapMode)internal_mode; -} - -void -cogl_pipeline_set_layer_wrap_mode_s (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_SAMPLER; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglSamplerCacheWrapMode internal_mode = - public_to_internal_wrap_mode (mode); - const CoglSamplerCacheEntry *sampler_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - sampler_state = - _cogl_sampler_cache_update_wrap_modes (ctx->sampler_cache, - authority->sampler_cache_entry, - internal_mode, - authority->sampler_cache_entry-> - wrap_mode_t); - _cogl_pipeline_set_layer_sampler_state (pipeline, - layer, - authority, - sampler_state); -} - -void -cogl_pipeline_set_layer_wrap_mode_t (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_SAMPLER; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglSamplerCacheWrapMode internal_mode = - public_to_internal_wrap_mode (mode); - const CoglSamplerCacheEntry *sampler_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - sampler_state = - _cogl_sampler_cache_update_wrap_modes (ctx->sampler_cache, - authority->sampler_cache_entry, - authority->sampler_cache_entry-> - wrap_mode_s, - internal_mode); - _cogl_pipeline_set_layer_sampler_state (pipeline, - layer, - authority, - sampler_state); -} - -void -cogl_pipeline_set_layer_wrap_mode (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_SAMPLER; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglSamplerCacheWrapMode internal_mode = - public_to_internal_wrap_mode (mode); - const CoglSamplerCacheEntry *sampler_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - sampler_state = - _cogl_sampler_cache_update_wrap_modes (ctx->sampler_cache, - authority->sampler_cache_entry, - internal_mode, - internal_mode); - _cogl_pipeline_set_layer_sampler_state (pipeline, - layer, - authority, - sampler_state); -} - -/* FIXME: deprecate this API */ -static CoglPipelineWrapMode -_cogl_pipeline_layer_get_wrap_mode_s (CoglPipelineLayer *layer) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_SAMPLER; - CoglPipelineLayer *authority; - const CoglSamplerCacheEntry *sampler_state; - - g_return_val_if_fail (COGL_IS_PIPELINE_LAYER (layer), FALSE); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - sampler_state = authority->sampler_cache_entry; - return internal_to_public_wrap_mode (sampler_state->wrap_mode_s); -} - -CoglPipelineWrapMode -cogl_pipeline_get_layer_wrap_mode_s (CoglPipeline *pipeline, int layer_index) -{ - CoglPipelineLayer *layer; - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), FALSE); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - /* FIXME: we shouldn't ever construct a layer in a getter function */ - - return _cogl_pipeline_layer_get_wrap_mode_s (layer); -} - -/* FIXME: deprecate this API */ -static CoglPipelineWrapMode -_cogl_pipeline_layer_get_wrap_mode_t (CoglPipelineLayer *layer) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_SAMPLER; - CoglPipelineLayer *authority; - const CoglSamplerCacheEntry *sampler_state; - - g_return_val_if_fail (COGL_IS_PIPELINE_LAYER (layer), FALSE); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - sampler_state = authority->sampler_cache_entry; - return internal_to_public_wrap_mode (sampler_state->wrap_mode_t); -} - -CoglPipelineWrapMode -cogl_pipeline_get_layer_wrap_mode_t (CoglPipeline *pipeline, int layer_index) -{ - CoglPipelineLayer *layer; - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), FALSE); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - /* FIXME: we shouldn't ever construct a layer in a getter function */ - - return _cogl_pipeline_layer_get_wrap_mode_t (layer); -} - -void -_cogl_pipeline_layer_get_wrap_modes (CoglPipelineLayer *layer, - CoglSamplerCacheWrapMode *wrap_mode_s, - CoglSamplerCacheWrapMode *wrap_mode_t) -{ - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_SAMPLER); - - *wrap_mode_s = authority->sampler_cache_entry->wrap_mode_s; - *wrap_mode_t = authority->sampler_cache_entry->wrap_mode_t; -} - -gboolean -cogl_pipeline_set_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, - int layer_index, - gboolean enable, - GError **error) -{ - CoglPipelineLayerState change = - COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS; - CoglPipelineLayer *layer; - CoglPipelineLayer *new; - CoglPipelineLayer *authority; - - _COGL_GET_CONTEXT (ctx, FALSE); - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), FALSE); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - if (authority->big_state->point_sprite_coords == enable) - return TRUE; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, change); - - if (old_authority->big_state->point_sprite_coords == enable) - { - layer->differences &= ~change; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - return TRUE; - } - } - } - - layer->big_state->point_sprite_coords = enable; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - - return TRUE; -} - -gboolean -cogl_pipeline_get_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, - int layer_index) -{ - CoglPipelineLayerState change = - COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), FALSE); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - /* FIXME: we shouldn't ever construct a layer in a getter function */ - - authority = _cogl_pipeline_layer_get_authority (layer, change); - - return authority->big_state->point_sprite_coords; -} - -static void -_cogl_pipeline_layer_add_vertex_snippet (CoglPipeline *pipeline, - int layer_index, - CoglSnippet *snippet) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS; - CoglPipelineLayer *layer, *authority; - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - layer = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change); - - _cogl_pipeline_snippet_list_add (&layer->big_state->vertex_snippets, - snippet); - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } -} - -static void -_cogl_pipeline_layer_add_fragment_snippet (CoglPipeline *pipeline, - int layer_index, - CoglSnippet *snippet) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS; - CoglPipelineLayer *layer, *authority; - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - layer = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change); - - _cogl_pipeline_snippet_list_add (&layer->big_state->fragment_snippets, - snippet); - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } -} - -void -cogl_pipeline_add_layer_snippet (CoglPipeline *pipeline, - int layer_index, - CoglSnippet *snippet) -{ - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - g_return_if_fail (COGL_IS_SNIPPET (snippet)); - g_return_if_fail (snippet->hook >= COGL_SNIPPET_FIRST_LAYER_HOOK); - - if (snippet->hook < COGL_SNIPPET_FIRST_LAYER_FRAGMENT_HOOK) - _cogl_pipeline_layer_add_vertex_snippet (pipeline, - layer_index, - snippet); - else - _cogl_pipeline_layer_add_fragment_snippet (pipeline, - layer_index, - snippet); -} - -gboolean -_cogl_pipeline_layer_texture_data_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - if (authority0->texture == NULL) - { - if (authority1->texture == NULL) - return TRUE; - else - return FALSE; - } - else if (authority1->texture == NULL) - return FALSE; - else - { - GLuint gl_handle0, gl_handle1; - - cogl_texture_get_gl_texture (authority0->texture, &gl_handle0, NULL); - cogl_texture_get_gl_texture (authority1->texture, &gl_handle1, NULL); - - return gl_handle0 == gl_handle1; - } -} - -gboolean -_cogl_pipeline_layer_combine_state_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - CoglPipelineLayerBigState *big_state0 = authority0->big_state; - CoglPipelineLayerBigState *big_state1 = authority1->big_state; - int n_args; - int i; - - if (big_state0->texture_combine_rgb_func != - big_state1->texture_combine_rgb_func) - return FALSE; - - if (big_state0->texture_combine_alpha_func != - big_state1->texture_combine_alpha_func) - return FALSE; - - n_args = - _cogl_get_n_args_for_combine_func (big_state0->texture_combine_rgb_func); - for (i = 0; i < n_args; i++) - { - if ((big_state0->texture_combine_rgb_src[i] != - big_state1->texture_combine_rgb_src[i]) || - (big_state0->texture_combine_rgb_op[i] != - big_state1->texture_combine_rgb_op[i])) - return FALSE; - } - - n_args = - _cogl_get_n_args_for_combine_func (big_state0->texture_combine_alpha_func); - for (i = 0; i < n_args; i++) - { - if ((big_state0->texture_combine_alpha_src[i] != - big_state1->texture_combine_alpha_src[i]) || - (big_state0->texture_combine_alpha_op[i] != - big_state1->texture_combine_alpha_op[i])) - return FALSE; - } - - return TRUE; -} - -gboolean -_cogl_pipeline_layer_combine_constant_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - return memcmp (authority0->big_state->texture_combine_constant, - authority1->big_state->texture_combine_constant, - sizeof (float) * 4) == 0 ? TRUE : FALSE; -} - -gboolean -_cogl_pipeline_layer_sampler_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - /* We compare the actual sampler objects rather than just the entry - pointers because two states with different values can lead to the - same state in GL terms when AUTOMATIC is used as a wrap mode */ - return (authority0->sampler_cache_entry->sampler_object == - authority1->sampler_cache_entry->sampler_object); -} - -gboolean -_cogl_pipeline_layer_user_matrix_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - CoglPipelineLayerBigState *big_state0 = authority0->big_state; - CoglPipelineLayerBigState *big_state1 = authority1->big_state; - - if (!graphene_matrix_equal (&big_state0->matrix, &big_state1->matrix)) - return FALSE; - - return TRUE; -} - -gboolean -_cogl_pipeline_layer_point_sprite_coords_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - CoglPipelineLayerBigState *big_state0 = authority0->big_state; - CoglPipelineLayerBigState *big_state1 = authority1->big_state; - - return big_state0->point_sprite_coords == big_state1->point_sprite_coords; -} - -gboolean -_cogl_pipeline_layer_vertex_snippets_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - return _cogl_pipeline_snippet_list_equal (&authority0->big_state-> - vertex_snippets, - &authority1->big_state-> - vertex_snippets); -} - -gboolean -_cogl_pipeline_layer_fragment_snippets_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - return _cogl_pipeline_snippet_list_equal (&authority0->big_state-> - fragment_snippets, - &authority1->big_state-> - fragment_snippets); -} - -static void -setup_texture_combine_state (CoglBlendStringStatement *statement, - CoglPipelineCombineFunc *texture_combine_func, - CoglPipelineCombineSource *texture_combine_src, - CoglPipelineCombineOp *texture_combine_op) -{ - int i; - - switch (statement->function->type) - { - case COGL_BLEND_STRING_FUNCTION_REPLACE: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_REPLACE; - break; - case COGL_BLEND_STRING_FUNCTION_MODULATE: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_MODULATE; - break; - case COGL_BLEND_STRING_FUNCTION_ADD: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_ADD; - break; - case COGL_BLEND_STRING_FUNCTION_ADD_SIGNED: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_ADD_SIGNED; - break; - case COGL_BLEND_STRING_FUNCTION_INTERPOLATE: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_INTERPOLATE; - break; - case COGL_BLEND_STRING_FUNCTION_SUBTRACT: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_SUBTRACT; - break; - case COGL_BLEND_STRING_FUNCTION_DOT3_RGB: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_DOT3_RGB; - break; - case COGL_BLEND_STRING_FUNCTION_DOT3_RGBA: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA; - break; - } - - for (i = 0; i < statement->function->argc; i++) - { - CoglBlendStringArgument *arg = &statement->args[i]; - - switch (arg->source.info->type) - { - case COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT: - texture_combine_src[i] = COGL_PIPELINE_COMBINE_SOURCE_CONSTANT; - break; - case COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE: - texture_combine_src[i] = COGL_PIPELINE_COMBINE_SOURCE_TEXTURE; - break; - case COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N: - texture_combine_src[i] = - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 + arg->source.texture; - break; - case COGL_BLEND_STRING_COLOR_SOURCE_PRIMARY: - texture_combine_src[i] = COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR; - break; - case COGL_BLEND_STRING_COLOR_SOURCE_PREVIOUS: - texture_combine_src[i] = COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS; - break; - default: - g_warning ("Unexpected texture combine source"); - texture_combine_src[i] = COGL_PIPELINE_COMBINE_SOURCE_TEXTURE; - } - - if (arg->source.mask == COGL_BLEND_STRING_CHANNEL_MASK_RGB) - { - if (statement->args[i].source.one_minus) - texture_combine_op[i] = - COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_COLOR; - else - texture_combine_op[i] = COGL_PIPELINE_COMBINE_OP_SRC_COLOR; - } - else - { - if (statement->args[i].source.one_minus) - texture_combine_op[i] = - COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA; - else - texture_combine_op[i] = COGL_PIPELINE_COMBINE_OP_SRC_ALPHA; - } - } -} - -gboolean -cogl_pipeline_set_layer_combine (CoglPipeline *pipeline, - int layer_index, - const char *combine_description, - GError **error) -{ - CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_COMBINE; - CoglPipelineLayer *authority; - CoglPipelineLayer *layer; - CoglBlendStringStatement statements[2]; - CoglBlendStringStatement split[2]; - CoglBlendStringStatement *rgb; - CoglBlendStringStatement *a; - int count; - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), FALSE); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, state); - - count = - _cogl_blend_string_compile (combine_description, - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE, - statements, - error); - if (!count) - return FALSE; - - if (statements[0].mask == COGL_BLEND_STRING_CHANNEL_MASK_RGBA) - { - _cogl_blend_string_split_rgba_statement (statements, - &split[0], &split[1]); - rgb = &split[0]; - a = &split[1]; - } - else - { - rgb = &statements[0]; - a = &statements[1]; - } - - /* FIXME: compare the new state with the current state! */ - - /* possibly flush primitives referencing the current state... */ - layer = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, state); - - setup_texture_combine_state (rgb, - &layer->big_state->texture_combine_rgb_func, - layer->big_state->texture_combine_rgb_src, - layer->big_state->texture_combine_rgb_op); - - setup_texture_combine_state (a, - &layer->big_state->texture_combine_alpha_func, - layer->big_state->texture_combine_alpha_src, - layer->big_state->texture_combine_alpha_op); - - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, state); - - if (_cogl_pipeline_layer_combine_state_equal (authority, - old_authority)) - { - layer->differences &= ~state; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - goto changed; - } - } - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= state; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - -changed: - - pipeline->dirty_real_blend_enable = TRUE; - return TRUE; -} - -void -cogl_pipeline_set_layer_combine_constant (CoglPipeline *pipeline, - int layer_index, - const CoglColor *constant_color) -{ - CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglPipelineLayer *new; - float color_as_floats[4]; - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, state); - - color_as_floats[0] = cogl_color_get_red (constant_color); - color_as_floats[1] = cogl_color_get_green (constant_color); - color_as_floats[2] = cogl_color_get_blue (constant_color); - color_as_floats[3] = cogl_color_get_alpha (constant_color); - - if (memcmp (authority->big_state->texture_combine_constant, - color_as_floats, sizeof (float) * 4) == 0) - return; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, state); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, state); - CoglPipelineLayerBigState *old_big_state = old_authority->big_state; - - if (memcmp (old_big_state->texture_combine_constant, - color_as_floats, sizeof (float) * 4) == 0) - { - layer->differences &= ~state; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - goto changed; - } - } - } - - memcpy (layer->big_state->texture_combine_constant, - color_as_floats, - sizeof (color_as_floats)); - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= state; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - -changed: - - pipeline->dirty_real_blend_enable = TRUE; -} - -void -_cogl_pipeline_get_layer_combine_constant (CoglPipeline *pipeline, - int layer_index, - float *constant) -{ - CoglPipelineLayerState change = - COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - /* FIXME: we shouldn't ever construct a layer in a getter function */ - - authority = _cogl_pipeline_layer_get_authority (layer, change); - memcpy (constant, authority->big_state->texture_combine_constant, - sizeof (float) * 4); -} - -/* We should probably make a public API version of this that has a - matrix out-param. For an internal API it's good to be able to avoid - copying the matrix */ -const graphene_matrix_t * -_cogl_pipeline_get_layer_matrix (CoglPipeline *pipeline, int layer_index) -{ - CoglPipelineLayerState change = - COGL_PIPELINE_LAYER_STATE_USER_MATRIX; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), NULL); - - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - authority = _cogl_pipeline_layer_get_authority (layer, change); - return &authority->big_state->matrix; -} - -void -cogl_pipeline_set_layer_matrix (CoglPipeline *pipeline, - int layer_index, - const graphene_matrix_t *matrix) -{ - CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_USER_MATRIX; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglPipelineLayer *new; - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, state); - - if (graphene_matrix_equal (matrix, &authority->big_state->matrix)) - return; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, state); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, state); - - if (graphene_matrix_equal (matrix, &old_authority->big_state->matrix)) - { - layer->differences &= ~state; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - return; - } - } - } - - layer->big_state->matrix = *matrix; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= state; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } -} - -CoglTexture * -_cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer) -{ - g_return_val_if_fail (COGL_IS_PIPELINE_LAYER (layer), NULL); - - return _cogl_pipeline_layer_get_texture_real (layer); -} - -gboolean -_cogl_pipeline_layer_has_user_matrix (CoglPipeline *pipeline, - int layer_index) -{ - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_USER_MATRIX); - - /* If the authority is the default pipeline then no, otherwise yes */ - return _cogl_pipeline_layer_get_parent (authority) ? TRUE : FALSE; -} - -void -_cogl_pipeline_layer_get_filters (CoglPipelineLayer *layer, - CoglPipelineFilter *min_filter, - CoglPipelineFilter *mag_filter) -{ - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_SAMPLER); - - *min_filter = authority->sampler_cache_entry->min_filter; - *mag_filter = authority->sampler_cache_entry->mag_filter; -} - -void -cogl_pipeline_get_layer_filters (CoglPipeline *pipeline, - int layer_index, - CoglPipelineFilter *min_filter, - CoglPipelineFilter *mag_filter) -{ - CoglPipelineLayer *layer; - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - return _cogl_pipeline_layer_get_filters (layer, min_filter, mag_filter); -} - -void -cogl_pipeline_set_layer_filters (CoglPipeline *pipeline, - int layer_index, - CoglPipelineFilter min_filter, - CoglPipelineFilter mag_filter) -{ - CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_SAMPLER; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - const CoglSamplerCacheEntry *sampler_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - g_return_if_fail (mag_filter == COGL_PIPELINE_FILTER_NEAREST || - mag_filter == COGL_PIPELINE_FILTER_LINEAR); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, state); - - sampler_state = - _cogl_sampler_cache_update_filters (ctx->sampler_cache, - authority->sampler_cache_entry, - min_filter, - mag_filter); - _cogl_pipeline_set_layer_sampler_state (pipeline, - layer, - authority, - sampler_state); -} - -void -cogl_pipeline_set_layer_max_mipmap_level (CoglPipeline *pipeline, - int layer, - int max_level) -{ - CoglTexture *texture = cogl_pipeline_get_layer_texture (pipeline, layer); - - if (texture != NULL) - cogl_texture_set_max_level (texture, max_level); -} - -const CoglSamplerCacheEntry * -_cogl_pipeline_layer_get_sampler_state (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *authority; - - authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_SAMPLER); - - return authority->sampler_cache_entry; -} - -void -_cogl_pipeline_layer_hash_unit_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - int unit = authority->unit_index; - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &unit, sizeof (unit)); -} - -void -_cogl_pipeline_layer_hash_texture_data_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - GLuint gl_handle; - - cogl_texture_get_gl_texture (authority->texture, &gl_handle, NULL); - - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &gl_handle, sizeof (gl_handle)); -} - -void -_cogl_pipeline_layer_hash_sampler_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, - &authority->sampler_cache_entry, - sizeof (authority->sampler_cache_entry)); -} - -void -_cogl_pipeline_layer_hash_combine_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - unsigned int hash = state->hash; - CoglPipelineLayerBigState *b = authority->big_state; - int n_args; - int i; - - hash = _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_rgb_func, - sizeof (b->texture_combine_rgb_func)); - n_args = _cogl_get_n_args_for_combine_func (b->texture_combine_rgb_func); - for (i = 0; i < n_args; i++) - { - hash = - _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_rgb_src[i], - sizeof (b->texture_combine_rgb_src[i])); - hash = - _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_rgb_op[i], - sizeof (b->texture_combine_rgb_op[i])); - } - - hash = _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_alpha_func, - sizeof (b->texture_combine_alpha_func)); - n_args = _cogl_get_n_args_for_combine_func (b->texture_combine_alpha_func); - for (i = 0; i < n_args; i++) - { - hash = - _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_alpha_src[i], - sizeof (b->texture_combine_alpha_src[i])); - hash = - _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_alpha_op[i], - sizeof (b->texture_combine_alpha_op[i])); - } - - state->hash = hash; -} - -void -_cogl_pipeline_layer_hash_combine_constant_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - CoglPipelineLayerBigState *b = authority->big_state; - gboolean need_hash = FALSE; - int n_args; - int i; - - /* XXX: If the user also asked to hash the ALPHA_FUNC_STATE then it - * would be nice if we could combine the n_args loops in this - * function and _cogl_pipeline_layer_hash_combine_state. - */ - - n_args = _cogl_get_n_args_for_combine_func (b->texture_combine_rgb_func); - for (i = 0; i < n_args; i++) - { - if (b->texture_combine_rgb_src[i] == - COGL_PIPELINE_COMBINE_SOURCE_CONSTANT) - { - /* XXX: should we be careful to only hash the alpha - * component in the COGL_PIPELINE_COMBINE_OP_SRC_ALPHA case? */ - need_hash = TRUE; - goto done; - } - } - - n_args = _cogl_get_n_args_for_combine_func (b->texture_combine_alpha_func); - for (i = 0; i < n_args; i++) - { - if (b->texture_combine_alpha_src[i] == - COGL_PIPELINE_COMBINE_SOURCE_CONSTANT) - { - /* XXX: should we be careful to only hash the alpha - * component in the COGL_PIPELINE_COMBINE_OP_SRC_ALPHA case? */ - need_hash = TRUE; - goto done; - } - } - -done: - if (need_hash) - { - float *constant = b->texture_combine_constant; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, constant, - sizeof (float) * 4); - } -} - -void -_cogl_pipeline_layer_hash_user_matrix_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - CoglPipelineLayerBigState *big_state = authority->big_state; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, &big_state->matrix, - sizeof (float) * 16); -} - -void -_cogl_pipeline_layer_hash_point_sprite_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - CoglPipelineLayerBigState *big_state = authority->big_state; - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &big_state->point_sprite_coords, - sizeof (big_state->point_sprite_coords)); -} - -void -_cogl_pipeline_layer_hash_vertex_snippets_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - _cogl_pipeline_snippet_list_hash (&authority->big_state->vertex_snippets, - &state->hash); -} - -void -_cogl_pipeline_layer_hash_fragment_snippets_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - _cogl_pipeline_snippet_list_hash (&authority->big_state->fragment_snippets, - &state->hash); -} diff --git a/mutter/cogl/cogl/cogl-pipeline-layer-state.h b/mutter/cogl/cogl/cogl-pipeline-layer-state.h deleted file mode 100644 index c3ea36d..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-layer-state.h +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-pipeline.h" -#include "cogl/cogl-color.h" -#include "cogl/cogl-texture.h" - -G_BEGIN_DECLS - -/** - * CoglPipelineFilter: - * @COGL_PIPELINE_FILTER_NEAREST: Measuring in manhatten distance from the, - * current pixel center, use the nearest texture texel - * @COGL_PIPELINE_FILTER_LINEAR: Use the weighted average of the 4 texels - * nearest the current pixel center - * @COGL_PIPELINE_FILTER_NEAREST_MIPMAP_NEAREST: Select the mimap level whose - * texel size most closely matches the current pixel, and use the - * %COGL_PIPELINE_FILTER_NEAREST criterion - * @COGL_PIPELINE_FILTER_LINEAR_MIPMAP_NEAREST: Select the mimap level whose - * texel size most closely matches the current pixel, and use the - * %COGL_PIPELINE_FILTER_LINEAR criterion - * @COGL_PIPELINE_FILTER_NEAREST_MIPMAP_LINEAR: Select the two mimap levels - * whose texel size most closely matches the current pixel, use - * the %COGL_PIPELINE_FILTER_NEAREST criterion on each one and take - * their weighted average - * @COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR: Select the two mimap levels - * whose texel size most closely matches the current pixel, use - * the %COGL_PIPELINE_FILTER_LINEAR criterion on each one and take - * their weighted average - * - * Texture filtering is used whenever the current pixel maps either to more - * than one texture element (texel) or less than one. These filter enums - * correspond to different strategies used to come up with a pixel color, by - * possibly referring to multiple neighbouring texels and taking a weighted - * average or simply using the nearest texel. - */ -typedef enum -{ - COGL_PIPELINE_FILTER_NEAREST = 0x2600, - COGL_PIPELINE_FILTER_LINEAR = 0x2601, - COGL_PIPELINE_FILTER_NEAREST_MIPMAP_NEAREST = 0x2700, - COGL_PIPELINE_FILTER_LINEAR_MIPMAP_NEAREST = 0x2701, - COGL_PIPELINE_FILTER_NEAREST_MIPMAP_LINEAR = 0x2702, - COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR = 0x2703 -} CoglPipelineFilter; -/* NB: these values come from the equivalents in gl.h */ - -/** - * CoglPipelineWrapMode: - * @COGL_PIPELINE_WRAP_MODE_REPEAT: The texture will be repeated. This - * is useful for example to draw a tiled background. - * @COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE: The coordinates outside the - * range 0→1 will sample copies of the edge pixels of the - * texture. This is useful to avoid artifacts if only one copy of - * the texture is being rendered. - * @COGL_PIPELINE_WRAP_MODE_AUTOMATIC: Cogl will try to automatically - * decide which of the above two to use. For cogl_rectangle(), it - * will use repeat mode if any of the texture coordinates are - * outside the range 0→1, otherwise it will use clamp to edge. For - * cogl_polygon() it will always use repeat mode. For - * cogl_vertex_buffer_draw() it will use repeat mode except for - * layers that have point sprite coordinate generation enabled. This - * is the default value. - * - * The wrap mode specifies what happens when texture coordinates - * outside the range 0→1 are used. Note that if the filter mode is - * anything but %COGL_PIPELINE_FILTER_NEAREST then texels outside the - * range 0→1 might be used even when the coordinate is exactly 0 or 1 - * because OpenGL will try to sample neighbouring pixels. For example - * if you are trying to render the full texture then you may get - * artifacts around the edges when the pixels from the other side are - * merged in if the wrap mode is set to repeat. - */ -/* GL_ALWAYS is just used here as a value that is known not to clash - * with any valid GL wrap modes - * - * XXX: keep the values in sync with the CoglPipelineWrapModeInternal - * enum so no conversion is actually needed. - */ -typedef enum -{ - COGL_PIPELINE_WRAP_MODE_REPEAT = 0x2901, - COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT = 0x8370, - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE = 0x812F, - COGL_PIPELINE_WRAP_MODE_AUTOMATIC = 0x0207 /* GL_ALWAYS */ -} CoglPipelineWrapMode; -/* NB: these values come from the equivalents in gl.h */ - -/** - * cogl_pipeline_set_layer: - * @pipeline: A #CoglPipeline object - * @layer_index: the index of the layer - * @texture: a #CoglTexture for the layer object - * - * In addition to the standard OpenGL lighting model a Cogl pipeline may have - * one or more layers comprised of textures that can be blended together in - * order, with a number of different texture combine modes. This function - * defines a new texture layer. - * - * The index values of multiple layers do not have to be consecutive; it is - * only their relative order that is important. - * - * The @texture parameter can also be %NULL in which case the pipeline - * will use a default white texture. The type of the default texture - * will be the same as whatever texture was last used for the pipeline - * or %COGL_TEXTURE_TYPE_2D if none has been specified yet. To - * explicitly specify the type of default texture required, use - * cogl_pipeline_set_layer_null_texture() instead. - * - * In the future, we may define other types of pipeline layers, such - * as purely GLSL based layers. - */ -COGL_EXPORT void -cogl_pipeline_set_layer_texture (CoglPipeline *pipeline, - int layer_index, - CoglTexture *texture); - -/** - * cogl_pipeline_set_layer_null_texture: - * @pipeline: A #CoglPipeline - * @layer_index: The layer number to modify - * - * Sets the texture for this layer to be the default texture for the - * given type. The default texture is a 1x1 pixel white texture. - * - * This function is mostly useful if you want to create a base - * pipeline that you want to create multiple copies from using - * cogl_pipeline_copy(). In that case this function can be used to - * specify the texture type so that any pipeline copies can share the - * internal texture type state for efficiency. - */ -COGL_EXPORT void -cogl_pipeline_set_layer_null_texture (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_get_layer_texture: - * @pipeline: A #CoglPipeline object - * @layer_index: the index of the layer - * - * Return value: (transfer none): the texture that was set for the - * given layer of the pipeline or %NULL if no texture was set. - */ -COGL_EXPORT CoglTexture * -cogl_pipeline_get_layer_texture (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_remove_layer: - * @pipeline: A #CoglPipeline object - * @layer_index: Specifies the layer you want to remove - * - * This function removes a layer from your pipeline - */ -COGL_EXPORT void -cogl_pipeline_remove_layer (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_set_layer_combine: - * @pipeline: A #CoglPipeline object - * @layer_index: Specifies the layer you want define a combine function for - * @blend_string: A Cogl blend string describing the desired - * texture combine function. - * @error: A #GError that may report parse errors or lack of GPU/driver - * support. May be %NULL, in which case a warning will be printed out if an - * error is encountered. - * - * - * These are all the functions available for texture combining: - * - * - `REPLACE(arg0) = arg0` - * - `MODULATE(arg0, arg1) = arg0 x arg1` - * - `ADD(arg0, arg1) = arg0 + arg1` - * - `ADD_SIGNED(arg0, arg1) = arg0 + arg1 - 0.5` - * - `INTERPOLATE(arg0, arg1, arg2) = arg0 x arg2 + arg1 x (1 - arg2)` - * - `SUBTRACT(arg0, arg1) = arg0 - arg1` - * - - * ``` - * DOT3_RGB(arg0, arg1) = 4 x ((arg0[R] - 0.5)) * (arg1[R] - 0.5) + - * (arg0[G] - 0.5)) * (arg1[G] - 0.5) + - * (arg0[B] - 0.5)) * (arg1[B] - 0.5)) - * ``` - * - - * ``` - * DOT3_RGBA(arg0, arg1) = 4 x ((arg0[R] - 0.5)) * (arg1[R] - 0.5) + - * (arg0[G] - 0.5)) * (arg1[G] - 0.5) + - * (arg0[B] - 0.5)) * (arg1[B] - 0.5)) - * ``` - * - * The valid source names for texture combining are: - * - * - `TEXTURE`: Use the color from the current texture layer - * - `TEXTURE_0, TEXTURE_1, etc`: Use the color from the specified texture layer - * - `CONSTANT`: Use the color from the constant given with - * [method@Cogl.Pipeline.set_layer_combine_constant] - * - `PRIMARY`: Use the color of the pipeline as set with - * [method@Cogl.Pipeline.set_color] - * - `PREVIOUS`: Either use the texture color from the previous layer, or - * if this is layer 0, use the color of the pipeline as set with - * [method@Cogl.Pipeline.set_color] - * - * Layer Combine Examples: - * - * This is effectively what the default blending is: - * - * ``` - * RGBA = MODULATE (PREVIOUS, TEXTURE) - * ``` - * - * This could be used to cross-fade between two images, using - * the alpha component of a constant as the interpolator. The constant - * color is given by calling [method@Cogl.Pipeline.set_layer_combine_constant]. - * - * ``` - * RGBA = INTERPOLATE (PREVIOUS, TEXTURE, CONSTANT[A]) - * ``` - * - * You can't give a multiplication factor for arguments as you can - * with blending. - * - * Return value: %TRUE if the blend string was successfully parsed, and the - * described texture combining is supported by the underlying driver and - * or hardware. On failure, %FALSE is returned and @error is set - */ -COGL_EXPORT gboolean -cogl_pipeline_set_layer_combine (CoglPipeline *pipeline, - int layer_index, - const char *blend_string, - GError **error); - -/** - * cogl_pipeline_set_layer_combine_constant: - * @pipeline: A #CoglPipeline object - * @layer_index: Specifies the layer you want to specify a constant used - * for texture combining - * @constant: The constant color you want - * - * When you are using the 'CONSTANT' color source in a layer combine - * description then you can use this function to define its value. - */ -COGL_EXPORT void -cogl_pipeline_set_layer_combine_constant (CoglPipeline *pipeline, - int layer_index, - const CoglColor *constant); - -/** - * cogl_pipeline_set_layer_matrix: - * @pipeline: A #CoglPipeline object - * @layer_index: the index for the layer inside @pipeline - * @matrix: the transformation matrix for the layer - * - * This function lets you set a matrix that can be used to e.g. translate - * and rotate a single layer of a pipeline used to fill your geometry. - */ -COGL_EXPORT void -cogl_pipeline_set_layer_matrix (CoglPipeline *pipeline, - int layer_index, - const graphene_matrix_t *matrix); - -/** - * cogl_pipeline_get_n_layers: - * @pipeline: A #CoglPipeline object - * - * Retrieves the number of layers defined for the given @pipeline - * - * Return value: the number of layers - */ -COGL_EXPORT int -cogl_pipeline_get_n_layers (CoglPipeline *pipeline); - -/** - * cogl_pipeline_get_layer_filters: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @min_filter: (out): Return location for the filter used when scaling - * a texture down. - * @mag_filter: (out): Return location for the filter used when magnifying - * a texture. - * - * Returns the decimation and interpolation filters used when a texture is - * drawn at other scales than 100%. - */ -COGL_EXPORT void -cogl_pipeline_get_layer_filters (CoglPipeline *pipeline, - int layer_index, - CoglPipelineFilter *min_filter, - CoglPipelineFilter *mag_filter); - -/** - * cogl_pipeline_set_layer_filters: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @min_filter: the filter used when scaling a texture down. - * @mag_filter: the filter used when magnifying a texture. - * - * Changes the decimation and interpolation filters used when a texture is - * drawn at other scales than 100%. - * - * It is an error to pass anything other than - * %COGL_PIPELINE_FILTER_NEAREST or %COGL_PIPELINE_FILTER_LINEAR as - * magnification filters since magnification doesn't ever need to - * reference values stored in the mipmap chain. - */ -COGL_EXPORT void -cogl_pipeline_set_layer_filters (CoglPipeline *pipeline, - int layer_index, - CoglPipelineFilter min_filter, - CoglPipelineFilter mag_filter); - -/** - * cogl_pipeline_set_layer_point_sprite_coords_enabled: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @enable: whether to enable point sprite coord generation. - * @error: A return location for a #GError, or NULL to ignore errors. - * - * When rendering points, if @enable is %TRUE then the texture - * coordinates for this layer will be replaced with coordinates that - * vary from 0.0 to 1.0 across the primitive. The top left of the - * point will have the coordinates 0.0,0.0 and the bottom right will - * have 1.0,1.0. If @enable is %FALSE then the coordinates will be - * fixed for the entire point. - * - * Return value: %TRUE if the function succeeds, %FALSE otherwise. - */ -COGL_EXPORT gboolean -cogl_pipeline_set_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, - int layer_index, - gboolean enable, - GError **error); - -/** - * cogl_pipeline_get_layer_point_sprite_coords_enabled: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to check. - * - * Gets whether point sprite coordinate generation is enabled for this - * texture layer. - * - * Return value: whether the texture coordinates will be replaced with - * point sprite coordinates. - */ -COGL_EXPORT gboolean -cogl_pipeline_get_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_get_layer_wrap_mode_s: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * - * Returns the wrap mode for the 's' coordinate of texture lookups on this - * layer. - * - * Return value: the wrap mode for the 's' coordinate of texture lookups on - * this layer. - */ -COGL_EXPORT CoglPipelineWrapMode -cogl_pipeline_get_layer_wrap_mode_s (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_set_layer_wrap_mode_s: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for the 's' coordinate of texture lookups on this layer. - */ -COGL_EXPORT void -cogl_pipeline_set_layer_wrap_mode_s (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode); - -/** - * cogl_pipeline_get_layer_wrap_mode_t: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * - * Returns the wrap mode for the 't' coordinate of texture lookups on this - * layer. - * - * Return value: the wrap mode for the 't' coordinate of texture lookups on - * this layer. - */ -COGL_EXPORT CoglPipelineWrapMode -cogl_pipeline_get_layer_wrap_mode_t (CoglPipeline *pipeline, - int layer_index); - - -/** - * cogl_pipeline_set_layer_wrap_mode_t: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for the 't' coordinate of texture lookups on this layer. - */ -COGL_EXPORT void -cogl_pipeline_set_layer_wrap_mode_t (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode); - -/** - * cogl_pipeline_set_layer_wrap_mode: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for all three coordinates of texture lookups on - * this layer. This is equivalent to calling - * cogl_pipeline_set_layer_wrap_mode_s() and - * cogl_pipeline_set_layer_wrap_mode_t() separately. - */ -COGL_EXPORT void -cogl_pipeline_set_layer_wrap_mode (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode); - -/** - * cogl_pipeline_add_layer_snippet: - * @pipeline: A #CoglPipeline - * @layer: The layer to hook the snippet to - * @snippet: A #CoglSnippet - * - * Adds a shader snippet that will hook on to the given layer of the - * pipeline. The exact part of the pipeline that the snippet wraps - * around depends on the hook that is given to - * cogl_snippet_new(). Note that some hooks can't be used with a layer - * and need to be added with cogl_pipeline_add_snippet() instead. - */ -COGL_EXPORT void -cogl_pipeline_add_layer_snippet (CoglPipeline *pipeline, - int layer, - CoglSnippet *snippet); - -COGL_EXPORT void -cogl_pipeline_set_layer_max_mipmap_level (CoglPipeline *pipeline, - int layer, - int max_level); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-pipeline-layer.c b/mutter/cogl/cogl/cogl-pipeline-layer.c deleted file mode 100644 index 6586ee1..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-layer.c +++ /dev/null @@ -1,899 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-util.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-texture-private.h" - -#include "cogl/cogl-pipeline.h" -#include "cogl/cogl-pipeline-layer-private.h" -#include "cogl/cogl-pipeline-layer-state-private.h" -#include "cogl/cogl-pipeline-layer-state.h" -#include "cogl/cogl-node-private.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-texture-private.h" - -#include - -G_DEFINE_FINAL_TYPE (CoglPipelineLayer, cogl_pipeline_layer, COGL_TYPE_NODE) - -static void -cogl_pipeline_layer_dispose (GObject *object) -{ - CoglPipelineLayer *layer = COGL_PIPELINE_LAYER (object); - - _cogl_pipeline_node_unparent_real (COGL_NODE (layer)); - - if (layer->differences & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA && - layer->texture != NULL) - g_object_unref (layer->texture); - - if (layer->differences & COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS) - _cogl_pipeline_snippet_list_free (&layer->big_state->vertex_snippets); - - if (layer->differences & COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS) - _cogl_pipeline_snippet_list_free (&layer->big_state->fragment_snippets); - - if (layer->differences & COGL_PIPELINE_LAYER_STATE_NEEDS_BIG_STATE) - g_free (layer->big_state); - - G_OBJECT_CLASS (cogl_pipeline_layer_parent_class)->dispose (object); -} - -static void -cogl_pipeline_layer_class_init (CoglPipelineLayerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = cogl_pipeline_layer_dispose; -} - -static void -cogl_pipeline_layer_init (CoglPipelineLayer *layer) -{ -} - -CoglPipelineLayer * -_cogl_pipeline_layer_get_authority (CoglPipelineLayer *layer, - unsigned long difference) -{ - CoglPipelineLayer *authority = layer; - while (!(authority->differences & difference)) - authority = _cogl_pipeline_layer_get_parent (authority); - return authority; -} - -int -_cogl_pipeline_layer_get_unit_index (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, COGL_PIPELINE_LAYER_STATE_UNIT); - return authority->unit_index; -} - -gboolean -_cogl_pipeline_layer_has_alpha (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *combine_authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_COMBINE); - CoglPipelineLayerBigState *big_state = combine_authority->big_state; - CoglPipelineLayer *tex_authority; - CoglPipelineLayer *snippets_authority; - - /* has_alpha maintains the alpha status for the GL_PREVIOUS layer */ - - /* For anything but the default texture combine we currently just - * assume it may result in an alpha value < 1 - * - * FIXME: we could do better than this. */ - if (big_state->texture_combine_alpha_func != - COGL_PIPELINE_COMBINE_FUNC_MODULATE || - big_state->texture_combine_alpha_src[0] != - COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS || - big_state->texture_combine_alpha_op[0] != - COGL_PIPELINE_COMBINE_OP_SRC_ALPHA || - big_state->texture_combine_alpha_src[1] != - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE || - big_state->texture_combine_alpha_op[1] != - COGL_PIPELINE_COMBINE_OP_SRC_ALPHA) - { - return TRUE; - } - - /* NB: A layer may have a combine mode set on it but not yet - * have an associated texture which would mean we'd fallback - * to the default texture which doesn't have an alpha component - */ - tex_authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA); - if (tex_authority->texture && - _cogl_texture_get_format (tex_authority->texture) & COGL_A_BIT) - { - return TRUE; - } - - /* All bets are off if the layer contains any snippets */ - snippets_authority = _cogl_pipeline_layer_get_authority - (layer, COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS); - if (snippets_authority->big_state->vertex_snippets.entries != NULL) - return TRUE; - snippets_authority = _cogl_pipeline_layer_get_authority - (layer, COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS); - if (snippets_authority->big_state->fragment_snippets.entries != NULL) - return TRUE; - - return FALSE; -} - -unsigned int -_cogl_get_n_args_for_combine_func (CoglPipelineCombineFunc func) -{ - switch (func) - { - case COGL_PIPELINE_COMBINE_FUNC_REPLACE: - return 1; - case COGL_PIPELINE_COMBINE_FUNC_MODULATE: - case COGL_PIPELINE_COMBINE_FUNC_ADD: - case COGL_PIPELINE_COMBINE_FUNC_ADD_SIGNED: - case COGL_PIPELINE_COMBINE_FUNC_SUBTRACT: - case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGB: - case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA: - return 2; - case COGL_PIPELINE_COMBINE_FUNC_INTERPOLATE: - return 3; - } - return 0; -} - -void -_cogl_pipeline_layer_copy_differences (CoglPipelineLayer *dest, - CoglPipelineLayer *src, - unsigned long differences) -{ - CoglPipelineLayerBigState *big_dest, *big_src; - - if ((differences & COGL_PIPELINE_LAYER_STATE_NEEDS_BIG_STATE) && - !dest->has_big_state) - { - dest->big_state = g_new0 (CoglPipelineLayerBigState, 1); - dest->has_big_state = TRUE; - } - - big_dest = dest->big_state; - big_src = src->big_state; - - dest->differences |= differences; - - while (differences) - { - int index = ffs (differences) - 1; - - differences &= ~(1 << index); - - /* This convoluted switch statement is just here so that we'll - * get a warning if a new state is added without handling it - * here */ - switch (index) - { - case COGL_PIPELINE_LAYER_STATE_COUNT: - case COGL_PIPELINE_LAYER_STATE_UNIT_INDEX: - g_warn_if_reached (); - break; - - case COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX: - dest->texture = src->texture; - if (dest->texture) - g_object_ref (dest->texture); - break; - - case COGL_PIPELINE_LAYER_STATE_SAMPLER_INDEX: - dest->sampler_cache_entry = src->sampler_cache_entry; - break; - - case COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX: - { - CoglPipelineCombineFunc func; - int n_args, i; - - func = big_src->texture_combine_rgb_func; - big_dest->texture_combine_rgb_func = func; - n_args = _cogl_get_n_args_for_combine_func (func); - for (i = 0; i < n_args; i++) - { - big_dest->texture_combine_rgb_src[i] = - big_src->texture_combine_rgb_src[i]; - big_dest->texture_combine_rgb_op[i] = - big_src->texture_combine_rgb_op[i]; - } - - func = big_src->texture_combine_alpha_func; - big_dest->texture_combine_alpha_func = func; - n_args = _cogl_get_n_args_for_combine_func (func); - for (i = 0; i < n_args; i++) - { - big_dest->texture_combine_alpha_src[i] = - big_src->texture_combine_alpha_src[i]; - big_dest->texture_combine_alpha_op[i] = - big_src->texture_combine_alpha_op[i]; - } - } - break; - - case COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX: - memcpy (big_dest->texture_combine_constant, - big_src->texture_combine_constant, - sizeof (big_dest->texture_combine_constant)); - break; - - case COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX: - big_dest->point_sprite_coords = big_src->point_sprite_coords; - break; - - case COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS_INDEX: - _cogl_pipeline_snippet_list_copy (&big_dest->vertex_snippets, - &big_src->vertex_snippets); - break; - - case COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS_INDEX: - _cogl_pipeline_snippet_list_copy (&big_dest->fragment_snippets, - &big_src->fragment_snippets); - break; - } - } -} - -static void -_cogl_pipeline_layer_init_multi_property_sparse_state ( - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - CoglPipelineLayer *authority; - - /* Nothing to initialize in these cases since they are all comprised - * of one member which we expect to immediately be overwritten. */ - if (!(change & COGL_PIPELINE_LAYER_STATE_MULTI_PROPERTY)) - return; - - authority = _cogl_pipeline_layer_get_authority (layer, change); - - switch (change) - { - /* XXX: avoid using a default: label so we get a warning if we - * don't explicitly handle a newly defined state-group here. */ - case COGL_PIPELINE_LAYER_STATE_UNIT: - case COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA: - case COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS: - case COGL_PIPELINE_LAYER_STATE_USER_MATRIX: - case COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT: - case COGL_PIPELINE_LAYER_STATE_SAMPLER: - g_return_if_reached (); - - /* XXX: technically we could probably even consider these as - * single property state-groups from the pov that currently the - * corresponding property setters always update all of the values - * at the same time. */ - case COGL_PIPELINE_LAYER_STATE_COMBINE: - { - int n_args; - int i; - CoglPipelineLayerBigState *src_big_state = authority->big_state; - CoglPipelineLayerBigState *dest_big_state = layer->big_state; - GLint func = src_big_state->texture_combine_rgb_func; - - dest_big_state->texture_combine_rgb_func = func; - n_args = _cogl_get_n_args_for_combine_func (func); - for (i = 0; i < n_args; i++) - { - dest_big_state->texture_combine_rgb_src[i] = - src_big_state->texture_combine_rgb_src[i]; - dest_big_state->texture_combine_rgb_op[i] = - src_big_state->texture_combine_rgb_op[i]; - } - - func = src_big_state->texture_combine_alpha_func; - dest_big_state->texture_combine_alpha_func = func; - n_args = _cogl_get_n_args_for_combine_func (func); - for (i = 0; i < n_args; i++) - { - dest_big_state->texture_combine_alpha_src[i] = - src_big_state->texture_combine_alpha_src[i]; - dest_big_state->texture_combine_alpha_op[i] = - src_big_state->texture_combine_alpha_op[i]; - } - break; - } - case COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS: - _cogl_pipeline_snippet_list_copy (&layer->big_state->vertex_snippets, - &authority->big_state-> - vertex_snippets); - break; - case COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS: - _cogl_pipeline_snippet_list_copy (&layer->big_state->fragment_snippets, - &authority->big_state-> - fragment_snippets); - break; - } -} - -/* NB: If a layer has descendants we can't modify the layer - * NB: If the layer is owned and the owner has descendants we can't - * modify the layer. - * - * This function will allocate a new derived layer if you are trying - * to change the state of a layer with dependants (as described above) - * so you must always check the return value. - * - * If a new layer is returned it will be owned by required_owner. - * (NB: a layer is always modified with respect to a pipeline - the - * "required_owner") - * - * required_owner can only by NULL for new, currently unowned layers - * with no dependants. - */ -CoglPipelineLayer * -_cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - /* Identify the case where the layer is new with no owner or - * dependants and so we don't need to do anything. */ - if (_cogl_list_empty (&COGL_NODE (layer)->children) && - layer->owner == NULL) - goto init_layer_state; - - /* We only allow a NULL required_owner for new layers */ - g_return_val_if_fail (required_owner != NULL, layer); - - /* Chain up: - * A modification of a layer is indirectly also a modification of - * its owner so first make sure to flush the journal of any - * references to the current owner state and if necessary perform - * a copy-on-write for the required_owner if it has dependants. - */ - _cogl_pipeline_pre_change_notify (required_owner, - COGL_PIPELINE_STATE_LAYERS, - NULL, - TRUE); - - /* Unlike pipelines; layers are simply considered immutable once - * they have dependants - either direct children, or another - * pipeline as an owner. - */ - if (!_cogl_list_empty (&COGL_NODE (layer)->children) || - layer->owner != required_owner) - { - CoglPipelineLayer *new = _cogl_pipeline_layer_copy (layer); - if (layer->owner == required_owner) - _cogl_pipeline_remove_layer_difference (required_owner, layer, FALSE); - _cogl_pipeline_add_layer_difference (required_owner, new, FALSE); - g_object_unref (new); - layer = new; - goto init_layer_state; - } - - /* Note: At this point we know there is only one pipeline dependent on - * this layer (required_owner), and there are no other layers - * dependent on this layer so it's ok to modify it. */ - - /* NB: Although layers can have private state associated with them - * by multiple backends we know that a layer can't be *changed* if - * it has multiple dependants so if we reach here we know we only - * have a single owner and can only be associated with a single - * backend that needs to be notified of the layer change... - */ - { - const CoglPipelineProgend *progend = _cogl_pipeline_progend; - const CoglPipelineFragend *fragend = _cogl_pipeline_fragend; - const CoglPipelineVertend *vertend = _cogl_pipeline_vertend; - - if (fragend->layer_pre_change_notify) - fragend->layer_pre_change_notify (required_owner, layer, change); - if (vertend->layer_pre_change_notify) - vertend->layer_pre_change_notify (required_owner, layer, change); - if (progend->layer_pre_change_notify) - progend->layer_pre_change_notify (required_owner, layer, change); - } - -init_layer_state: - - if (required_owner) - required_owner->age++; - - if (change & COGL_PIPELINE_LAYER_STATE_NEEDS_BIG_STATE && - !layer->has_big_state) - { - layer->big_state = g_new0 (CoglPipelineLayerBigState, 1); - layer->has_big_state = TRUE; - } - - /* Note: conceptually we have just been notified that a single - * property value is about to change, but since some state-groups - * contain multiple properties and 'layer' is about to take over - * being the authority for the property's corresponding state-group - * we need to maintain the integrity of the other property values - * too. - * - * To ensure this we handle multi-property state-groups by copying - * all the values from the old-authority to the new... - * - * We don't have to worry about non-sparse property groups since - * we never take over being an authority for such properties so - * they automatically maintain integrity. - */ - if (change & COGL_PIPELINE_LAYER_STATE_ALL_SPARSE && - !(layer->differences & change)) - { - _cogl_pipeline_layer_init_multi_property_sparse_state (layer, change); - layer->differences |= change; - } - - return layer; -} - -static void -_cogl_pipeline_layer_set_parent (CoglPipelineLayer *layer, - CoglPipelineLayer *parent) -{ - /* Chain up */ - _cogl_pipeline_node_set_parent_real (COGL_NODE (layer), - COGL_NODE (parent), - TRUE); -} - -CoglPipelineLayer * -_cogl_pipeline_layer_copy (CoglPipelineLayer *src) -{ - CoglPipelineLayer *layer = g_object_new (COGL_TYPE_PIPELINE_LAYER, NULL); - - layer->owner = NULL; - layer->index = src->index; - layer->differences = 0; - layer->has_big_state = FALSE; - - _cogl_pipeline_layer_set_parent (layer, src); - - return layer; -} - -/* XXX: This is duplicated logic; the same as for - * _cogl_pipeline_prune_redundant_ancestry it would be nice to find a - * way to consolidate these functions! */ -void -_cogl_pipeline_layer_prune_redundant_ancestry (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *new_parent = _cogl_pipeline_layer_get_parent (layer); - - /* walk up past ancestors that are now redundant and potentially - * reparent the layer. */ - while (_cogl_pipeline_layer_get_parent (new_parent) && - (new_parent->differences | layer->differences) == - layer->differences) - new_parent = _cogl_pipeline_layer_get_parent (new_parent); - - _cogl_pipeline_layer_set_parent (layer, new_parent); -} - -/* Determine the mask of differences between two layers. - * - * XXX: If layers and pipelines could both be cast to a common Tree - * type of some kind then we could have a unified - * compare_differences() function. - */ -unsigned long -_cogl_pipeline_layer_compare_differences (CoglPipelineLayer *layer0, - CoglPipelineLayer *layer1) -{ - GSList *head0 = NULL; - GSList *head1 = NULL; - CoglPipelineLayer *node0; - CoglPipelineLayer *node1; - int len0 = 0; - int len1 = 0; - int count; - GSList *common_ancestor0; - GSList *common_ancestor1; - unsigned long layers_difference = 0; - - /* Algorithm: - * - * 1) Walk the ancestors of each layer to the root node, adding a - * pointer to each ancestor node to two linked lists - * - * 2) Compare the lists to find the nodes where they start to - * differ marking the common_ancestor node for each list. - * - * 3) For each list now iterate starting after the common_ancestor - * nodes ORing each nodes ->difference mask into the final - * differences mask. - */ - - for (node0 = layer0; node0; node0 = _cogl_pipeline_layer_get_parent (node0)) - { - GSList *link = alloca (sizeof (GSList)); - link->next = head0; - link->data = node0; - head0 = link; - len0++; - } - for (node1 = layer1; node1; node1 = _cogl_pipeline_layer_get_parent (node1)) - { - GSList *link = alloca (sizeof (GSList)); - link->next = head1; - link->data = node1; - head1 = link; - len1++; - } - - /* NB: There's no point looking at the head entries since we know both layers - * must have the same default layer as their root node. */ - common_ancestor0 = head0; - common_ancestor1 = head1; - head0 = head0->next; - head1 = head1->next; - count = MIN (len0, len1) - 1; - while (count--) - { - if (head0->data != head1->data) - break; - common_ancestor0 = head0; - common_ancestor1 = head1; - head0 = head0->next; - head1 = head1->next; - } - - for (head0 = common_ancestor0->next; head0; head0 = head0->next) - { - node0 = head0->data; - layers_difference |= node0->differences; - } - for (head1 = common_ancestor1->next; head1; head1 = head1->next) - { - node1 = head1->data; - layers_difference |= node1->differences; - } - - return layers_difference; -} - -static gboolean -layer_state_equal (CoglPipelineLayerStateIndex state_index, - CoglPipelineLayer **authorities0, - CoglPipelineLayer **authorities1, - CoglPipelineLayerStateComparator comparator) -{ - return comparator (authorities0[state_index], authorities1[state_index]); -} - -void -_cogl_pipeline_layer_resolve_authorities (CoglPipelineLayer *layer, - unsigned long differences, - CoglPipelineLayer **authorities) -{ - unsigned long remaining = differences; - CoglPipelineLayer *authority = layer; - - do - { - unsigned long found = authority->differences & remaining; - int i; - - if (found == 0) - continue; - - for (i = 0; TRUE; i++) - { - unsigned long state = (1L< found) - break; - } - - remaining &= ~found; - if (remaining == 0) - return; - } - while ((authority = _cogl_pipeline_layer_get_parent (authority))); - - g_assert (remaining == 0); -} - -gboolean -_cogl_pipeline_layer_equal (CoglPipelineLayer *layer0, - CoglPipelineLayer *layer1, - unsigned long differences_mask) -{ - unsigned long layers_difference; - CoglPipelineLayer *authorities0[COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT]; - CoglPipelineLayer *authorities1[COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT]; - - if (layer0 == layer1) - return TRUE; - - layers_difference = - _cogl_pipeline_layer_compare_differences (layer0, layer1); - - /* Only compare the sparse state groups requested by the caller... */ - layers_difference &= differences_mask; - - _cogl_pipeline_layer_resolve_authorities (layer0, - layers_difference, - authorities0); - _cogl_pipeline_layer_resolve_authorities (layer1, - layers_difference, - authorities1); - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA) - { - CoglPipelineLayerStateIndex state_index = - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX; - if (!_cogl_pipeline_layer_texture_data_equal (authorities0[state_index], - authorities1[state_index])) - return FALSE; - } - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_COMBINE && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_combine_state_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_combine_constant_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_SAMPLER && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_SAMPLER_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_sampler_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_USER_MATRIX && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_user_matrix_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_point_sprite_coords_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_vertex_snippets_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_fragment_snippets_equal)) - return FALSE; - - return TRUE; -} - -void -_cogl_pipeline_init_default_layers (CoglContext *ctx) -{ - CoglPipelineLayer *layer = g_object_new (COGL_TYPE_PIPELINE_LAYER, NULL); - CoglPipelineLayerBigState *big_state = - g_new0 (CoglPipelineLayerBigState, 1); - CoglPipelineLayer *new; - - layer->index = 0; - - layer->differences = COGL_PIPELINE_LAYER_STATE_ALL_SPARSE; - - layer->unit_index = 0; - - layer->texture = NULL; - - layer->sampler_cache_entry = - _cogl_sampler_cache_get_default_entry (ctx->sampler_cache); - - layer->big_state = big_state; - layer->has_big_state = TRUE; - - /* Choose the same default combine mode as OpenGL: - * RGBA = MODULATE(PREVIOUS[RGBA],TEXTURE[RGBA]) */ - big_state->texture_combine_rgb_func = - COGL_PIPELINE_COMBINE_FUNC_MODULATE; - big_state->texture_combine_rgb_src[0] = - COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS; - big_state->texture_combine_rgb_src[1] = - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE; - big_state->texture_combine_rgb_op[0] = - COGL_PIPELINE_COMBINE_OP_SRC_COLOR; - big_state->texture_combine_rgb_op[1] = - COGL_PIPELINE_COMBINE_OP_SRC_COLOR; - big_state->texture_combine_alpha_func = - COGL_PIPELINE_COMBINE_FUNC_MODULATE; - big_state->texture_combine_alpha_src[0] = - COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS; - big_state->texture_combine_alpha_src[1] = - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE; - big_state->texture_combine_alpha_op[0] = - COGL_PIPELINE_COMBINE_OP_SRC_ALPHA; - big_state->texture_combine_alpha_op[1] = - COGL_PIPELINE_COMBINE_OP_SRC_ALPHA; - - big_state->point_sprite_coords = FALSE; - - graphene_matrix_init_identity (&big_state->matrix); - - ctx->default_layer_0 = layer; - - /* TODO: we should make default_layer_n comprise of two - * descendants of default_layer_0: - * - the first descendant should change the texture combine - * to what we expect is most commonly used for multitexturing - * - the second should revert the above change. - * - * why? the documentation for how a new layer is initialized - * doesn't say that layers > 0 have different defaults so unless - * we change the documentation we can't use different defaults, - * but if the user does what we expect and changes the - * texture combine then we can revert the authority to the - * first descendant which means we can maximize the number - * of layers with a common ancestor. - * - * The main problem will be that we'll need to disable the - * optimizations for flattening the ancestry when we make - * the second descendant which reverts the state. - */ - ctx->default_layer_n = _cogl_pipeline_layer_copy (layer); - new = _cogl_pipeline_set_layer_unit (NULL, ctx->default_layer_n, 1); - g_assert (new == ctx->default_layer_n); - /* Since we passed a newly allocated layer we don't expect that - * _set_layer_unit() will have to allocate *another* layer. */ - - /* Finally we create a dummy dependent for ->default_layer_n which - * effectively ensures that ->default_layer_n and ->default_layer_0 - * remain immutable. - */ - ctx->dummy_layer_dependant = - _cogl_pipeline_layer_copy (ctx->default_layer_n); -} - -void -_cogl_pipeline_layer_pre_paint (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *texture_authority; - - texture_authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA); - - if (texture_authority->texture != NULL) - { - CoglTexturePrePaintFlags flags = 0; - CoglPipelineFilter min_filter; - CoglPipelineFilter mag_filter; - - _cogl_pipeline_layer_get_filters (layer, &min_filter, &mag_filter); - - if (min_filter == COGL_PIPELINE_FILTER_NEAREST_MIPMAP_NEAREST - || min_filter == COGL_PIPELINE_FILTER_LINEAR_MIPMAP_NEAREST - || min_filter == COGL_PIPELINE_FILTER_NEAREST_MIPMAP_LINEAR - || min_filter == COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR) - flags |= COGL_TEXTURE_NEEDS_MIPMAP; - - _cogl_texture_pre_paint (texture_authority->texture, flags); - } -} - -/* Determines if we need to handle the RGB and A texture combining - * separately or is the same function used for both channel masks and - * with the same arguments... - */ -gboolean -_cogl_pipeline_layer_needs_combine_separate - (CoglPipelineLayer *combine_authority) -{ - CoglPipelineLayerBigState *big_state = combine_authority->big_state; - int n_args; - int i; - - if (big_state->texture_combine_rgb_func != - big_state->texture_combine_alpha_func) - return TRUE; - - n_args = _cogl_get_n_args_for_combine_func (big_state->texture_combine_rgb_func); - - for (i = 0; i < n_args; i++) - { - if (big_state->texture_combine_rgb_src[i] != - big_state->texture_combine_alpha_src[i]) - return TRUE; - - /* - * We can allow some variation of the source operands without - * needing a separation... - * - * "A = REPLACE (CONSTANT[A])" + either of the following... - * "RGB = REPLACE (CONSTANT[RGB])" - * "RGB = REPLACE (CONSTANT[A])" - * - * can be combined as: - * "RGBA = REPLACE (CONSTANT)" or - * "RGBA = REPLACE (CONSTANT[A])" or - * - * And "A = REPLACE (1-CONSTANT[A])" + either of the following... - * "RGB = REPLACE (1-CONSTANT)" or - * "RGB = REPLACE (1-CONSTANT[A])" - * - * can be combined as: - * "RGBA = REPLACE (1-CONSTANT)" or - * "RGBA = REPLACE (1-CONSTANT[A])" - */ - switch (big_state->texture_combine_alpha_op[i]) - { - case GL_SRC_ALPHA: - switch (big_state->texture_combine_rgb_op[i]) - { - case GL_SRC_COLOR: - case GL_SRC_ALPHA: - break; - default: - return FALSE; - } - break; - case GL_ONE_MINUS_SRC_ALPHA: - switch (big_state->texture_combine_rgb_op[i]) - { - case GL_ONE_MINUS_SRC_COLOR: - case GL_ONE_MINUS_SRC_ALPHA: - break; - default: - return FALSE; - } - break; - default: - return FALSE; /* impossible */ - } - } - - return FALSE; -} - - diff --git a/mutter/cogl/cogl/cogl-pipeline-private.h b/mutter/cogl/cogl/cogl-pipeline-private.h deleted file mode 100644 index 3c729d3..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-private.h +++ /dev/null @@ -1,799 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-debug.h" -#include "cogl/cogl-node-private.h" -#include "cogl/cogl-pipeline-layer-private.h" -#include "cogl/cogl-pipeline.h" -#include "cogl/cogl-profile.h" -#include "cogl/cogl-list.h" -#include "cogl/cogl-boxed-value.h" -#include "cogl/cogl-pipeline-snippet-private.h" -#include "cogl/cogl-pipeline-state.h" -#include "cogl/cogl-framebuffer.h" -#include "cogl/cogl-bitmask.h" - -#include - -/* XXX: should I rename these as - * COGL_PIPELINE_STATE_INDEX_XYZ... ? - */ -typedef enum -{ - /* sparse state */ - COGL_PIPELINE_STATE_COLOR_INDEX, - COGL_PIPELINE_STATE_LAYERS_INDEX, - COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX, - COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX, - COGL_PIPELINE_STATE_BLEND_INDEX, - COGL_PIPELINE_STATE_USER_SHADER_INDEX, - COGL_PIPELINE_STATE_DEPTH_INDEX, - COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE_INDEX, - COGL_PIPELINE_STATE_POINT_SIZE_INDEX, - COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX, - COGL_PIPELINE_STATE_CULL_FACE_INDEX, - COGL_PIPELINE_STATE_UNIFORMS_INDEX, - COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX, - COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS_INDEX, - - /* non-sparse */ - COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX, - - COGL_PIPELINE_STATE_COUNT -} CoglPipelineStateIndex; - -#define COGL_PIPELINE_STATE_SPARSE_COUNT (COGL_PIPELINE_STATE_COUNT - 1) - -/* Used in pipeline->differences masks and for notifying pipeline - * state changes. - * - * XXX: If you add or remove state groups here you may need to update - * some of the state masks following this enum too! - * - * FIXME: perhaps it would be better to rename this enum to - * CoglPipelineStateGroup to better convey the fact that a single enum - * here can map to multiple properties. - */ -typedef enum _CoglPipelineState -{ - COGL_PIPELINE_STATE_COLOR = - 1L<big_state. - */ - - /* Layers represent their state in a tree structure where some of - * the state relating to a given pipeline or layer may actually be - * owned by one if is ancestors in the tree. We have a common data - * type to track the tree hierarchy so we can share code... */ - CoglNode parent_instance; - - CoglContext *context; - - /* When weak pipelines are destroyed the user is notified via this - * callback */ - CoglPipelineDestroyCallback destroy_callback; - - /* When notifying that a weak pipeline has been destroyed this - * private data is passed to the above callback */ - void *destroy_data; - - /* We need to track if a pipeline is referenced in the journal - * because we can't allow modification to these pipelines without - * flushing the journal first */ - unsigned int journal_ref_count; - - /* A mask of which sparse state groups are different in this - * pipeline in comparison to its parent. */ - unsigned int differences; - - /* Whenever a pipeline is modified we increment the age. There's no - * guarantee that it won't wrap but it can nevertheless be a - * convenient mechanism to determine when a pipeline has been - * changed to you can invalidate some some associated cache that - * depends on the old state. */ - unsigned int age; - - /* This is the primary color of the pipeline. - * - * This is a sparse property, ref COGL_PIPELINE_STATE_COLOR */ - CoglColor color; - - /* A pipeline may be made up with multiple layers used to combine - * textures together. - * - * This is sparse state, ref COGL_PIPELINE_STATE_LAYERS */ - unsigned int n_layers; - GList *layer_differences; - - /* As a basic way to reduce memory usage we divide the pipeline - * state into two groups; the minimal state modified in 90% of - * all pipelines and the rest, so that the second group can - * be allocated dynamically when required... */ - CoglPipelineBigState *big_state; - - /* Cached state... */ - - /* A cached, complete list of the layers this pipeline depends - * on sorted by layer->unit_index. */ - CoglPipelineLayer **layers_cache; - /* To avoid a separate ->layers_cache allocation for common - * pipelines with only a few layers... */ - CoglPipelineLayer *short_layers_cache[3]; - - /* XXX: consider adding an authorities cache to speed up sparse - * property value lookups: - * CoglPipeline *authorities_cache[COGL_PIPELINE_N_SPARSE_PROPERTIES]; - * and corresponding authorities_cache_dirty:1 bitfield - */ - - /* bitfields */ - - /* Weak pipelines don't count as dependants on their parents which - * means that the parent pipeline can be modified without - * considering how the modifications may affect the weak pipeline. - */ - unsigned int is_weak:1; - - /* Determines if pipeline->big_state is valid */ - unsigned int has_big_state:1; - - /* There are many factors that can determine if we need to enable - * blending, this holds our final decision */ - unsigned int real_blend_enable:1; - - /* Since the code for deciding if blending really needs to be - * enabled for a particular pipeline is quite expensive we update - * the real_blend_enable flag lazily when flushing a pipeline if - * this dirty flag has been set. */ - unsigned int dirty_real_blend_enable:1; - - /* Whenever a pipeline is flushed we keep track of whether the - * pipeline was used with a color attribute where we don't know - * whether the colors are opaque. The real_blend_enable state - * depends on this, and must be updated whenever this changes (even - * if dirty_real_blend_enable isn't set) */ - unsigned int unknown_color_alpha:1; - - unsigned int layers_cache_dirty:1; - - /* Debugging, only used when defined(COGL_ENABLE_DEBUG) */ - - /* For debugging purposes it's possible to associate a static const - * string with a pipeline which can be an aid when trying to trace - * where the pipeline originates from */ - unsigned int has_static_breadcrumb:1; - - /* For debugging purposes it's possible to associate a static const - * string with a pipeline which can be an aid when trying to trace - * where the pipeline originates from */ - const char *static_breadcrumb; -}; - -struct _CoglPipelineClass -{ - CoglNodeClass parent_class; -}; - -typedef struct _CoglPipelineFragend -{ - void (*start) (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference); - gboolean (*add_layer) (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference); - gboolean (*end) (CoglPipeline *pipeline, - unsigned long pipelines_difference); - - void (*pipeline_pre_change_notify) (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color); - void (*layer_pre_change_notify) (CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change); -} CoglPipelineFragend; - -typedef struct _CoglPipelineVertend -{ - void (*start) (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference); - gboolean (*add_layer) (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference, - CoglFramebuffer *framebuffer); - gboolean (*end) (CoglPipeline *pipeline, - unsigned long pipelines_difference); - - void (*pipeline_pre_change_notify) (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color); - void (*layer_pre_change_notify) (CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change); -} CoglPipelineVertend; - -typedef struct -{ - gboolean (*start) (CoglPipeline *pipeline); - void (*end) (CoglPipeline *pipeline, - unsigned long pipelines_difference); - void (*pipeline_pre_change_notify) (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color); - void (*layer_pre_change_notify) (CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change); - /* This is called after all of the other functions whenever the - pipeline is flushed, even if the pipeline hasn't changed since - the last flush */ - void (* pre_paint) (CoglPipeline *pipeline, CoglFramebuffer *framebuffer); -} CoglPipelineProgend; - -extern const CoglPipelineFragend *_cogl_pipeline_fragend; -extern const CoglPipelineVertend *_cogl_pipeline_vertend; -extern const CoglPipelineProgend *_cogl_pipeline_progend; - -void -_cogl_pipeline_init_default_pipeline (CoglContext *ctx); - -static inline CoglPipeline * -_cogl_pipeline_get_parent (CoglPipeline *pipeline) -{ - CoglNode *parent_node = COGL_NODE (pipeline)->parent; - return COGL_PIPELINE (parent_node); -} - -static inline CoglPipeline * -_cogl_pipeline_get_authority (CoglPipeline *pipeline, - unsigned long difference) -{ - CoglPipeline *authority = pipeline; - while (!(authority->differences & difference)) - authority = _cogl_pipeline_get_parent (authority); - return authority; -} - -typedef gboolean (*CoglPipelineStateComparator) (CoglPipeline *authority0, - CoglPipeline *authority1); - -void -_cogl_pipeline_update_authority (CoglPipeline *pipeline, - CoglPipeline *authority, - CoglPipelineState state, - CoglPipelineStateComparator comparator); - -void -_cogl_pipeline_pre_change_notify (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color, - gboolean from_layer_change); - -void -_cogl_pipeline_prune_redundant_ancestry (CoglPipeline *pipeline); - -void -_cogl_pipeline_update_real_blend_enable (CoglPipeline *pipeline, - gboolean unknown_color_alpha); - -typedef enum -{ - COGL_PIPELINE_GET_LAYER_NO_CREATE = 1<<0 -} CoglPipelineGetLayerFlags; - -CoglPipelineLayer * -_cogl_pipeline_get_layer_with_flags (CoglPipeline *pipeline, - int layer_index, - CoglPipelineGetLayerFlags flags); - -#define _cogl_pipeline_get_layer(p, l) \ - _cogl_pipeline_get_layer_with_flags (p, l, 0) - -void -_cogl_pipeline_prune_empty_layer_difference (CoglPipeline *layers_authority, - CoglPipelineLayer *layer); - -gboolean -_cogl_pipeline_get_real_blend_enabled (CoglPipeline *pipeline); - -/* - * Calls the pre_paint method on the layer texture if there is - * one. This will determine whether mipmaps are needed based on the - * filter settings. - */ -void -_cogl_pipeline_pre_paint_for_layer (CoglPipeline *pipeline, - int layer_id); - -/* - * CoglPipelineFlushFlag: - * @COGL_PIPELINE_FLUSH_FALLBACK_MASK: The fallback_layers member is set to - * a uint32_t mask of the layers that can't be supported with the user - * supplied texture and need to be replaced with fallback textures. (1 = - * fallback, and the least significant bit = layer 0) - * @COGL_PIPELINE_FLUSH_DISABLE_MASK: The disable_layers member is set to - * a uint32_t mask of the layers that you want to completely disable - * texturing for (1 = fallback, and the least significant bit = layer 0) - * @COGL_PIPELINE_FLUSH_LAYER0_OVERRIDE: The layer0_override_texture member is - * set to a GLuint OpenGL texture name to override the texture used for - * layer 0 of the pipeline. This is intended for dealing with sliced - * textures where you will need to point to each of the texture slices in - * turn when drawing your geometry. Passing a value of 0 is the same as - * not passing the option at all. - * @COGL_PIPELINE_FLUSH_SKIP_GL_COLOR: When flushing the GL state for the - * pipeline don't call glColor. - */ -typedef enum _CoglPipelineFlushFlag -{ - COGL_PIPELINE_FLUSH_FALLBACK_MASK = 1L<<0, - COGL_PIPELINE_FLUSH_DISABLE_MASK = 1L<<1, - COGL_PIPELINE_FLUSH_LAYER0_OVERRIDE = 1L<<2, - COGL_PIPELINE_FLUSH_SKIP_GL_COLOR = 1L<<3 -} CoglPipelineFlushFlag; - -/* - * CoglPipelineFlushOptions: - * - */ -typedef struct _CoglPipelineFlushOptions -{ - CoglPipelineFlushFlag flags; - - uint32_t fallback_layers; - uint32_t disable_layers; - CoglTexture *layer0_override_texture; -} CoglPipelineFlushOptions; - -unsigned int -_cogl_get_n_args_for_combine_func (CoglPipelineCombineFunc func); - -/* - * _cogl_pipeline_weak_copy: - * @pipeline: A #CoglPipeline object - * @callback: A callback to notify when your weak pipeline is destroyed - * @user_data: Private data to pass to your given callback. - * - * Returns a weak copy of the given source @pipeline. Unlike a normal - * copy no internal reference is taken on the source @pipeline and you - * can expect that later modifications of the source pipeline (or in - * fact any other pipeline) can result in the weak pipeline being - * destroyed. - * - * To understand this better its good to know a bit about the internal - * design of #CoglPipeline... - * - * Internally `CoglPipeline`s are represented as a graph of - * property diff's, where each node is a diff of properties that gets - * applied on top of its parent. Copying a pipeline creates an empty - * diff and a child->parent relationship between the empty diff and - * the source @pipeline, parent. - * - * Because of this internal graph design a single #CoglPipeline may - * indirectly depend on a chain of ancestors to fully define all of - * its properties. Because a node depends on its ancestors it normally - * owns a reference to its parent to stop it from being freed. Also if - * you try to modify a pipeline with children we internally use a - * copy-on-write mechanism to ensure that you don't indirectly change - * the properties those children. - * - * Weak pipelines avoid the use of copy-on-write to preserve the - * integrity of weak dependants and instead weak dependants are - * simply destroyed allowing the parent to be modified directly. Also - * because weak pipelines don't own a reference to their parent they - * won't stop the source @pipeline from being freed when the user - * releases their reference on it. - * - * Because weak pipelines don't own a reference on their parent they - * are the recommended mechanism for creating derived pipelines that you - * want to cache as a private property of the original pipeline - * because they won't result in a circular dependency. - * - * An example use case: - * - * Consider for example you are implementing a custom primitive that is - * not compatible with certain source pipelines. To handle this you - * implement a validation stage that given an arbitrary pipeline as - * input will create a derived pipeline that is suitable for drawing - * your primitive. - * - * Because you don't want to have to repeat this validation every time - * the same incompatible pipeline is given as input you want to cache - * the result as a private property of the original pipeline. If the - * derived pipeline were created using cogl_pipeline_copy that would - * create a circular dependency so the original pipeline can never be - * freed. - * - * If you instead create a weak copy you won't stop the original pipeline - * from being freed if it's no longer needed, and you will instead simply - * be notified that your weak pipeline has been destroyed. - * - * This is the recommended coding pattern for validating an input - * pipeline and caching a derived result: - * ```c - * static GQuark _cogl_my_cache_key = 0; - * - * typedef struct { - * CoglPipeline *validated_source; - * } MyValidatedMaterialCache; - * - * static void - * destroy_cache_cb (CoglObject *object, void *user_data) - * { - * g_free (user_data); - * } - * - * static void - * invalidate_cache_cb (CoglPipeline *destroyed, void *user_data) - * { - * MyValidatedMaterialCache *cache = user_data; - * g_object_unref (cache->validated_source); - * cache->validated_source = NULL; - * } - * - * static CoglPipeline * - * get_validated_pipeline (CoglPipeline *source) - * { - * _cogl_my_cache_key = g_quark_from_static_string ("my-cache-key"); - * MyValidatedMaterialCache *cache = - * g_object_get_qdata (G_OBJECT (source), - * _cogl_my_cache_key); - * if (G_UNLIKELY (cache == NULL)) - * { - * cache = g_new0 (MyValidatedMaterialCache, 1); - * - * g_object_set_qdata_full (G_OBJECT (source), - * _cogl_my_cache_key, - * cache, destroy_cache_cb); - * cache->validated_source = source; - * } - * - * if (G_UNLIKELY (cache->validated_source == NULL)) - * { - * cache->validated_source = source; - * - * / * Start validating source... * / - * - * / * If you find you need to change something... * / - * if (cache->validated_source == source) - * cache->validated_source = - * cogl_pipeline_weak_copy (source, - * invalidate_cache_cb, - * cache); - * - * / * Modify cache->validated_source * / - * } - * - * return cache->validated_source; - * } - * ``` - */ -CoglPipeline * -_cogl_pipeline_weak_copy (CoglPipeline *pipeline, - CoglPipelineDestroyCallback callback, - void *user_data); - -void -_cogl_pipeline_set_progend (CoglPipeline *pipeline, int progend); - -void -_cogl_pipeline_get_colorubv (CoglPipeline *pipeline, - uint8_t *color); - -/* XXX: At some point it could be good for this to accept a mask of - * the state groups we are interested in comparing since we can - * probably use that information in a number situations to reduce - * the work we do. */ -unsigned long -_cogl_pipeline_compare_differences (CoglPipeline *pipeline0, - CoglPipeline *pipeline1); - -gboolean -_cogl_pipeline_equal (CoglPipeline *pipeline0, - CoglPipeline *pipeline1, - unsigned int differences, - unsigned long layer_differences); - -unsigned int -_cogl_pipeline_hash (CoglPipeline *pipeline, - unsigned int differences, - unsigned long layer_differences); - -/* Makes a copy of the given pipeline that is a child of the root - * pipeline rather than a child of the source pipeline. That way the - * new pipeline won't hold a reference to the source pipeline. The - * differences specified in @differences and @layer_differences are - * copied across and all other state is left with the default - * values. */ -CoglPipeline * -_cogl_pipeline_deep_copy (CoglPipeline *pipeline, - unsigned long differences, - unsigned long layer_differences); - -CoglPipeline * -_cogl_pipeline_journal_ref (CoglPipeline *pipeline); - -void -_cogl_pipeline_journal_unref (CoglPipeline *pipeline); - -const graphene_matrix_t * -_cogl_pipeline_get_layer_matrix (CoglPipeline *pipeline, - int layer_index); - -void -_cogl_pipeline_texture_storage_change_notify (CoglTexture *texture); - -void -_cogl_pipeline_apply_legacy_state (CoglPipeline *pipeline); - -void -_cogl_pipeline_apply_overrides (CoglPipeline *pipeline, - CoglPipelineFlushOptions *options); - -#ifdef COGL_ENABLE_DEBUG -void -_cogl_pipeline_set_static_breadcrumb (CoglPipeline *pipeline, - const char *breadcrumb); -#endif - -unsigned long -_cogl_pipeline_get_age (CoglPipeline *pipeline); - -void -_cogl_pipeline_add_layer_difference (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - gboolean inc_n_layers); - -void -_cogl_pipeline_remove_layer_difference (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - gboolean dec_n_layers); - -CoglPipeline * -_cogl_pipeline_find_equivalent_parent (CoglPipeline *pipeline, - CoglPipelineState pipeline_state, - CoglPipelineLayerState layer_state); - -void -_cogl_pipeline_get_layer_combine_constant (CoglPipeline *pipeline, - int layer_index, - float *constant); - -void -_cogl_pipeline_prune_to_n_layers (CoglPipeline *pipeline, int n); - - -/* - * API to support the deprecate cogl_pipeline_layer_xyz functions... - */ - -typedef gboolean (*CoglPipelineInternalLayerCallback) (CoglPipelineLayer *layer, - void *user_data); - -void -_cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline, - CoglPipelineInternalLayerCallback callback, - void *user_data); - -gboolean -_cogl_pipeline_layer_numbers_equal (CoglPipeline *pipeline0, - CoglPipeline *pipeline1); - -gboolean -_cogl_pipeline_layer_and_unit_numbers_equal (CoglPipeline *pipeline0, - CoglPipeline *pipeline1); - -gboolean -_cogl_pipeline_need_texture_combine_separate - (CoglPipelineLayer *combine_authority); - -void -_cogl_pipeline_init_state_hash_functions (void); - -void -_cogl_pipeline_init_layer_state_hash_functions (void); - -CoglPipelineState -_cogl_pipeline_get_state_for_vertex_codegen (CoglContext *context); - -CoglPipelineLayerState -_cogl_pipeline_get_layer_state_for_fragment_codegen (CoglContext *context); - -CoglPipelineState -_cogl_pipeline_get_state_for_fragment_codegen (CoglContext *context); diff --git a/mutter/cogl/cogl/cogl-pipeline-snippet-private.h b/mutter/cogl/cogl/cogl-pipeline-snippet-private.h deleted file mode 100644 index b7799b7..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-snippet-private.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011, 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#pragma once - -#include - -#include "cogl/cogl-snippet.h" - -typedef struct -{ - GList *entries; -} CoglPipelineSnippetList; - -/* Arguments to pass to _cogl_pipeline_snippet_generate_code() */ -typedef struct -{ - CoglPipelineSnippetList *snippets; - - /* Only snippets at this hook point will be used */ - CoglSnippetHook hook; - - /* The final function to chain on to after all of the snippets code - has been run */ - const char *chain_function; - - /* The name of the final generated function */ - const char *final_name; - - /* A prefix to insert before each generate function name */ - const char *function_prefix; - - /* The return type of all of the functions, or NULL to use void */ - const char *return_type; - - /* A variable to return from the functions. The snippets are - expected to modify this variable. Ignored if return_type is - NULL */ - const char *return_variable; - - /* If this is TRUE then it won't allocate a separate variable for - the return value. Instead it is expected that the snippet will - modify one of the argument variables directly and that will be - returned */ - gboolean return_variable_is_argument; - - /* The argument names or NULL if there are none */ - const char *arguments; - - /* The argument types or NULL */ - const char *argument_declarations; - - /* The string to generate the source into */ - GString *source_buf; -} CoglPipelineSnippetData; - -void -_cogl_pipeline_snippet_generate_code (const CoglPipelineSnippetData *data); - -void -_cogl_pipeline_snippet_generate_declarations (GString *declarations_buf, - CoglSnippetHook hook, - CoglPipelineSnippetList *list); - -void -_cogl_pipeline_snippet_list_free (CoglPipelineSnippetList *list); - -void -_cogl_pipeline_snippet_list_add (CoglPipelineSnippetList *list, - CoglSnippet *snippet); - -void -_cogl_pipeline_snippet_list_copy (CoglPipelineSnippetList *dst, - const CoglPipelineSnippetList *src); - -void -_cogl_pipeline_snippet_list_hash (CoglPipelineSnippetList *list, - unsigned int *hash); - -gboolean -_cogl_pipeline_snippet_list_equal (CoglPipelineSnippetList *list0, - CoglPipelineSnippetList *list1); diff --git a/mutter/cogl/cogl/cogl-pipeline-snippet.c b/mutter/cogl/cogl/cogl-pipeline-snippet.c deleted file mode 100644 index 141b8ee..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-snippet.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011, 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#include "config.h" - -#include - -#include "cogl/cogl-types.h" -#include "cogl/cogl-pipeline-snippet-private.h" -#include "cogl/cogl-snippet-private.h" -#include "cogl/cogl-util.h" - -/* Helper functions that are used by both GLSL pipeline backends */ - -void -_cogl_pipeline_snippet_generate_code (const CoglPipelineSnippetData *data) -{ - GList *first_snippet, *l; - CoglSnippet *snippet; - int snippet_num = 0; - int n_snippets = 0; - - first_snippet = data->snippets->entries; - - /* First count the number of snippets so we can easily tell when - we're at the last one */ - for (l = data->snippets->entries; l; l = l->next) - { - snippet = l->data; - - if (snippet->hook == data->hook) - { - /* Don't bother processing any previous snippets if we reach - one that has a replacement */ - if (snippet->replace) - { - n_snippets = 1; - first_snippet = l; - } - else - n_snippets++; - } - } - - /* If there weren't any snippets then generate a stub function with - the final name */ - if (n_snippets == 0) - { - if (data->return_type) - g_string_append_printf (data->source_buf, - "\n" - "%s\n" - "%s (%s)\n" - "{\n" - " return %s (%s);\n" - "}\n", - data->return_type, - data->final_name, - data->argument_declarations ? - data->argument_declarations : "", - data->chain_function, - data->arguments ? data->arguments : ""); - else - g_string_append_printf (data->source_buf, - "\n" - "void\n" - "%s (%s)\n" - "{\n" - " %s (%s);\n" - "}\n", - data->final_name, - data->argument_declarations ? - data->argument_declarations : "", - data->chain_function, - data->arguments ? data->arguments : ""); - - return; - } - - for (l = first_snippet; snippet_num < n_snippets; l = l->next) - { - snippet = l->data; - - if (snippet->hook == data->hook) - { - const char *source; - - if ((source = cogl_snippet_get_declarations (snippet))) - g_string_append (data->source_buf, source); - - g_string_append_printf (data->source_buf, - "\n" - "%s\n", - data->return_type ? - data->return_type : - "void"); - - if (snippet_num + 1 < n_snippets) - g_string_append_printf (data->source_buf, - "%s_%i", - data->function_prefix, - snippet_num); - else - g_string_append (data->source_buf, data->final_name); - - g_string_append (data->source_buf, " ("); - - if (data->argument_declarations) - g_string_append (data->source_buf, data->argument_declarations); - - g_string_append (data->source_buf, - ")\n" - "{\n"); - - if (data->return_type && !data->return_variable_is_argument) - g_string_append_printf (data->source_buf, - " %s %s;\n" - "\n", - data->return_type, - data->return_variable); - - if ((source = cogl_snippet_get_pre (snippet))) - g_string_append (data->source_buf, source); - - /* Chain on to the next function, or bypass it if there is - a replace string */ - if ((source = cogl_snippet_get_replace (snippet))) - g_string_append (data->source_buf, source); - else - { - g_string_append (data->source_buf, " "); - - if (data->return_type) - g_string_append_printf (data->source_buf, - "%s = ", - data->return_variable); - - if (snippet_num > 0) - g_string_append_printf (data->source_buf, - "%s_%i", - data->function_prefix, - snippet_num - 1); - else - g_string_append (data->source_buf, data->chain_function); - - g_string_append (data->source_buf, " ("); - - if (data->arguments) - g_string_append (data->source_buf, data->arguments); - - g_string_append (data->source_buf, ");\n"); - } - - if ((source = cogl_snippet_get_post (snippet))) - g_string_append (data->source_buf, source); - - if (data->return_type) - g_string_append_printf (data->source_buf, - " return %s;\n", - data->return_variable); - - g_string_append (data->source_buf, "}\n"); - snippet_num++; - } - } -} - -void -_cogl_pipeline_snippet_generate_declarations (GString *declarations_buf, - CoglSnippetHook hook, - CoglPipelineSnippetList *snippets) -{ - GList *l; - - for (l = snippets->entries; l; l = l->next) - { - CoglSnippet *snippet = l->data; - - if (snippet->hook == hook) - { - const char *source; - - if ((source = cogl_snippet_get_declarations (snippet))) - g_string_append (declarations_buf, source); - } - } -} - -void -_cogl_pipeline_snippet_list_free (CoglPipelineSnippetList *list) -{ - GList *l, *tmp; - - for (l = list->entries; l; l = tmp) - { - tmp = l->next; - - g_object_unref (l->data); - g_list_free_1 (l); - } -} - -void -_cogl_pipeline_snippet_list_add (CoglPipelineSnippetList *list, - CoglSnippet *snippet) -{ - list->entries = g_list_append (list->entries, g_object_ref (snippet)); - - _cogl_snippet_make_immutable (snippet); -} - -void -_cogl_pipeline_snippet_list_copy (CoglPipelineSnippetList *dst, - const CoglPipelineSnippetList *src) -{ - GQueue queue = G_QUEUE_INIT; - const GList *l; - - for (l = src->entries; l; l = l->next) - g_queue_push_tail (&queue, g_object_ref (l->data)); - - dst->entries = queue.head; -} - -void -_cogl_pipeline_snippet_list_hash (CoglPipelineSnippetList *list, - unsigned int *hash) -{ - GList *l; - - for (l = list->entries; l; l = l->next) - { - CoglSnippet *snippet = l->data; - - *hash = _cogl_util_one_at_a_time_hash (*hash, - &snippet, - sizeof (CoglSnippet *)); - } -} - -gboolean -_cogl_pipeline_snippet_list_equal (CoglPipelineSnippetList *list0, - CoglPipelineSnippetList *list1) -{ - GList *l0, *l1; - - for (l0 = list0->entries, l1 = list1->entries; - l0 && l1; - l0 = l0->next, l1 = l1->next) - if (l0->data != l1->data) - return FALSE; - - return l0 == NULL && l1 == NULL; -} diff --git a/mutter/cogl/cogl/cogl-pipeline-state-private.h b/mutter/cogl/cogl/cogl-pipeline-state-private.h deleted file mode 100644 index 9633e98..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-state-private.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -gboolean -_cogl_pipeline_has_vertex_snippets (CoglPipeline *pipeline); - -gboolean -_cogl_pipeline_has_non_layer_vertex_snippets (CoglPipeline *pipeline); - -gboolean -_cogl_pipeline_has_non_layer_fragment_snippets (CoglPipeline *pipeline); - -gboolean -_cogl_pipeline_alpha_func_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_alpha_func_reference_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_blend_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_depth_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_non_zero_point_size_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_point_size_equal (CoglPipeline *authority0, - CoglPipeline *authority1); -gboolean -_cogl_pipeline_per_vertex_point_size_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_user_shader_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_cull_face_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_uniforms_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_vertex_snippets_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_fragment_snippets_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -void -_cogl_pipeline_hash_color_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_alpha_func_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_alpha_func_reference_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_blend_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_user_shader_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_depth_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_non_zero_point_size_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_point_size_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_per_vertex_point_size_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_cull_face_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_uniforms_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_vertex_snippets_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_fragment_snippets_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_compare_uniform_differences (unsigned long *differences, - CoglPipeline *pipeline0, - CoglPipeline *pipeline1); diff --git a/mutter/cogl/cogl/cogl-pipeline-state.c b/mutter/cogl/cogl/cogl-pipeline-state.c deleted file mode 100644 index 2e879fb..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-state.c +++ /dev/null @@ -1,1512 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-color-private.h" -#include "cogl/cogl-blend-string.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-depth-state-private.h" -#include "cogl/cogl-pipeline-state-private.h" -#include "cogl/cogl-snippet-private.h" - -#include "string.h" - -#ifndef GL_FUNC_ADD -#define GL_FUNC_ADD 0x8006 -#endif - -static gboolean -_cogl_pipeline_color_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return cogl_color_equal (&authority0->color, &authority1->color); -} - -gboolean -_cogl_pipeline_alpha_func_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - CoglPipelineAlphaFuncState *alpha_state0 = - &authority0->big_state->alpha_state; - CoglPipelineAlphaFuncState *alpha_state1 = - &authority1->big_state->alpha_state; - - return alpha_state0->alpha_func == alpha_state1->alpha_func; -} - -gboolean -_cogl_pipeline_alpha_func_reference_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - CoglPipelineAlphaFuncState *alpha_state0 = - &authority0->big_state->alpha_state; - CoglPipelineAlphaFuncState *alpha_state1 = - &authority1->big_state->alpha_state; - - return (alpha_state0->alpha_func_reference == - alpha_state1->alpha_func_reference); -} - -gboolean -_cogl_pipeline_blend_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - CoglPipelineBlendState *blend_state0 = &authority0->big_state->blend_state; - CoglPipelineBlendState *blend_state1 = &authority1->big_state->blend_state; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (blend_state0->blend_equation_rgb != blend_state1->blend_equation_rgb) - return FALSE; - - if (blend_state0->blend_equation_alpha != - blend_state1->blend_equation_alpha) - return FALSE; - if (blend_state0->blend_src_factor_alpha != - blend_state1->blend_src_factor_alpha) - return FALSE; - if (blend_state0->blend_dst_factor_alpha != - blend_state1->blend_dst_factor_alpha) - return FALSE; - - if (blend_state0->blend_src_factor_rgb != - blend_state1->blend_src_factor_rgb) - return FALSE; - if (blend_state0->blend_dst_factor_rgb != - blend_state1->blend_dst_factor_rgb) - return FALSE; - - if (blend_state0->blend_src_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR || - blend_state0->blend_src_factor_rgb == GL_CONSTANT_COLOR || - blend_state0->blend_dst_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR || - blend_state0->blend_dst_factor_rgb == GL_CONSTANT_COLOR) - { - if (!cogl_color_equal (&blend_state0->blend_constant, - &blend_state1->blend_constant)) - return FALSE; - } - - return TRUE; -} - -gboolean -_cogl_pipeline_depth_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - if (authority0->big_state->depth_state.test_enabled == FALSE && - authority1->big_state->depth_state.test_enabled == FALSE) - return TRUE; - else - { - CoglDepthState *s0 = &authority0->big_state->depth_state; - CoglDepthState *s1 = &authority1->big_state->depth_state; - return s0->test_enabled == s1->test_enabled && - s0->test_function == s1->test_function && - s0->write_enabled == s1->write_enabled && - s0->range_near == s1->range_near && - s0->range_far == s1->range_far; - } -} - -gboolean -_cogl_pipeline_non_zero_point_size_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return (authority0->big_state->non_zero_point_size == - authority1->big_state->non_zero_point_size); -} - -gboolean -_cogl_pipeline_point_size_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return authority0->big_state->point_size == authority1->big_state->point_size; -} - -gboolean -_cogl_pipeline_per_vertex_point_size_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return (authority0->big_state->per_vertex_point_size == - authority1->big_state->per_vertex_point_size); -} - -gboolean -_cogl_pipeline_cull_face_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - CoglPipelineCullFaceState *cull_face_state0 - = &authority0->big_state->cull_face_state; - CoglPipelineCullFaceState *cull_face_state1 - = &authority1->big_state->cull_face_state; - - /* The cull face state is considered equal if two pipelines are both - set to no culling. If the front winding property is ever used for - anything else or the comparison is used not just for drawing then - this would have to change */ - - if (cull_face_state0->mode == COGL_PIPELINE_CULL_FACE_MODE_NONE) - return cull_face_state1->mode == COGL_PIPELINE_CULL_FACE_MODE_NONE; - - return (cull_face_state0->mode == cull_face_state1->mode && - cull_face_state0->front_winding == cull_face_state1->front_winding); -} - -gboolean -_cogl_pipeline_user_shader_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return (authority0->big_state->user_program == - authority1->big_state->user_program); -} - -typedef struct -{ - const CoglBoxedValue **dst_values; - const CoglBoxedValue *src_values; - int override_count; -} GetUniformsClosure; - -static gboolean -get_uniforms_cb (int uniform_num, void *user_data) -{ - GetUniformsClosure *data = user_data; - - if (data->dst_values[uniform_num] == NULL) - data->dst_values[uniform_num] = data->src_values + data->override_count; - - data->override_count++; - - return TRUE; -} - -static void -_cogl_pipeline_get_all_uniform_values (CoglPipeline *pipeline, - const CoglBoxedValue **values) -{ - GetUniformsClosure data; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - memset (values, 0, - sizeof (const CoglBoxedValue *) * ctx->n_uniform_names); - - data.dst_values = values; - - do - { - if ((pipeline->differences & COGL_PIPELINE_STATE_UNIFORMS)) - { - const CoglPipelineUniformsState *uniforms_state = - &pipeline->big_state->uniforms_state; - - data.override_count = 0; - data.src_values = uniforms_state->override_values; - - _cogl_bitmask_foreach (&uniforms_state->override_mask, - get_uniforms_cb, - &data); - } - pipeline = _cogl_pipeline_get_parent (pipeline); - } - while (pipeline); -} - -gboolean -_cogl_pipeline_uniforms_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - unsigned long *differences; - const CoglBoxedValue **values0, **values1; - int n_longs; - int i; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (authority0 == authority1) - return TRUE; - - values0 = g_alloca (sizeof (const CoglBoxedValue *) * ctx->n_uniform_names); - values1 = g_alloca (sizeof (const CoglBoxedValue *) * ctx->n_uniform_names); - - n_longs = COGL_FLAGS_N_LONGS_FOR_SIZE (ctx->n_uniform_names); - differences = g_alloca (n_longs * sizeof (unsigned long)); - memset (differences, 0, sizeof (unsigned long) * n_longs); - _cogl_pipeline_compare_uniform_differences (differences, - authority0, - authority1); - - _cogl_pipeline_get_all_uniform_values (authority0, values0); - _cogl_pipeline_get_all_uniform_values (authority1, values1); - - COGL_FLAGS_FOREACH_START (differences, n_longs, i) - { - const CoglBoxedValue *value0 = values0[i]; - const CoglBoxedValue *value1 = values1[i]; - - if (value0 == NULL) - { - if (value1 != NULL && value1->type != COGL_BOXED_NONE) - return FALSE; - } - else if (value1 == NULL) - { - if (value0 != NULL && value0->type != COGL_BOXED_NONE) - return FALSE; - } - else if (!_cogl_boxed_value_equal (value0, value1)) - return FALSE; - } - COGL_FLAGS_FOREACH_END; - - return TRUE; -} - -gboolean -_cogl_pipeline_vertex_snippets_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return _cogl_pipeline_snippet_list_equal (&authority0->big_state-> - vertex_snippets, - &authority1->big_state-> - vertex_snippets); -} - -gboolean -_cogl_pipeline_fragment_snippets_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return _cogl_pipeline_snippet_list_equal (&authority0->big_state-> - fragment_snippets, - &authority1->big_state-> - fragment_snippets); -} - -void -cogl_pipeline_get_color (CoglPipeline *pipeline, - CoglColor *color) -{ - CoglPipeline *authority; - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR); - - *color = authority->color; -} - -/* This is used heavily by the cogl journal when logging quads */ -void -_cogl_pipeline_get_colorubv (CoglPipeline *pipeline, - uint8_t *color) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR); - - _cogl_color_get_rgba_4ubv (&authority->color, color); -} - -void -cogl_pipeline_set_color (CoglPipeline *pipeline, - const CoglColor *color) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_COLOR; - CoglPipeline *authority; - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - if (cogl_color_equal (color, &authority->color)) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, color, FALSE); - - pipeline->color = *color; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_color_equal); - - pipeline->dirty_real_blend_enable = TRUE; -} - -static void -_cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline, - CoglPipelineAlphaFunc alpha_func) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_ALPHA_FUNC; - CoglPipeline *authority; - CoglPipelineAlphaFuncState *alpha_state; - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - alpha_state = &authority->big_state->alpha_state; - if (alpha_state->alpha_func == alpha_func) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - alpha_state = &pipeline->big_state->alpha_state; - alpha_state->alpha_func = alpha_func; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_alpha_func_state_equal); -} - -static void -_cogl_pipeline_set_alpha_test_function_reference (CoglPipeline *pipeline, - float alpha_reference) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE; - CoglPipeline *authority; - CoglPipelineAlphaFuncState *alpha_state; - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - alpha_state = &authority->big_state->alpha_state; - if (alpha_state->alpha_func_reference == alpha_reference) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - alpha_state = &pipeline->big_state->alpha_state; - alpha_state->alpha_func_reference = alpha_reference; - - _cogl_pipeline_update_authority - (pipeline, authority, state, - _cogl_pipeline_alpha_func_reference_state_equal); -} - -void -cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline, - CoglPipelineAlphaFunc alpha_func, - float alpha_reference) -{ - _cogl_pipeline_set_alpha_test_function (pipeline, alpha_func); - _cogl_pipeline_set_alpha_test_function_reference (pipeline, alpha_reference); -} - -CoglPipelineAlphaFunc -cogl_pipeline_get_alpha_test_function (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), 0); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_ALPHA_FUNC); - - return authority->big_state->alpha_state.alpha_func; -} - -float -cogl_pipeline_get_alpha_test_reference (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), 0.0f); - - authority = - _cogl_pipeline_get_authority (pipeline, - COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE); - - return authority->big_state->alpha_state.alpha_func_reference; -} - -static GLenum -arg_to_gl_blend_factor (CoglBlendStringArgument *arg) -{ - if (arg->source.is_zero) - return GL_ZERO; - if (arg->factor.is_one) - return GL_ONE; - else if (arg->factor.is_src_alpha_saturate) - return GL_SRC_ALPHA_SATURATE; - else if (arg->factor.source.info->type == - COGL_BLEND_STRING_COLOR_SOURCE_SRC_COLOR) - { - if (arg->factor.source.mask != COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_SRC_COLOR; - else - return GL_SRC_COLOR; - } - else - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_SRC_ALPHA; - else - return GL_SRC_ALPHA; - } - } - else if (arg->factor.source.info->type == - COGL_BLEND_STRING_COLOR_SOURCE_DST_COLOR) - { - if (arg->factor.source.mask != COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_DST_COLOR; - else - return GL_DST_COLOR; - } - else - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_DST_ALPHA; - else - return GL_DST_ALPHA; - } - } - else if (arg->factor.source.info->type == - COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT) - { - if (arg->factor.source.mask != COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_CONSTANT_COLOR; - else - return GL_CONSTANT_COLOR; - } - else - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_CONSTANT_ALPHA; - else - return GL_CONSTANT_ALPHA; - } - } - - g_warning ("Unable to determine valid blend factor from blend string\n"); - return GL_ONE; -} - -static void -setup_blend_state (CoglBlendStringStatement *statement, - GLenum *blend_equation, - GLint *blend_src_factor, - GLint *blend_dst_factor) -{ - switch (statement->function->type) - { - case COGL_BLEND_STRING_FUNCTION_ADD: - *blend_equation = GL_FUNC_ADD; - break; - /* TODO - add more */ - default: - g_warning ("Unsupported blend function given"); - *blend_equation = GL_FUNC_ADD; - } - - *blend_src_factor = arg_to_gl_blend_factor (&statement->args[0]); - *blend_dst_factor = arg_to_gl_blend_factor (&statement->args[1]); -} - -gboolean -cogl_pipeline_set_blend (CoglPipeline *pipeline, - const char *blend_description, - GError **error) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_BLEND; - CoglPipeline *authority; - CoglBlendStringStatement statements[2]; - CoglBlendStringStatement *rgb; - CoglBlendStringStatement *a; - int count; - CoglPipelineBlendState *blend_state; - - _COGL_GET_CONTEXT (ctx, FALSE); - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), FALSE); - - count = - _cogl_blend_string_compile (blend_description, - COGL_BLEND_STRING_CONTEXT_BLENDING, - statements, - error); - if (!count) - return FALSE; - - if (count == 1) - rgb = a = statements; - else - { - rgb = &statements[0]; - a = &statements[1]; - } - - authority = - _cogl_pipeline_get_authority (pipeline, state); - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - blend_state = &pipeline->big_state->blend_state; - - setup_blend_state (rgb, - &blend_state->blend_equation_rgb, - &blend_state->blend_src_factor_rgb, - &blend_state->blend_dst_factor_rgb); - setup_blend_state (a, - &blend_state->blend_equation_alpha, - &blend_state->blend_src_factor_alpha, - &blend_state->blend_dst_factor_alpha); - - /* If we are the current authority see if we can revert to one of our - * ancestors being the authority */ - if (pipeline == authority && - _cogl_pipeline_get_parent (authority) != NULL) - { - CoglPipeline *parent = _cogl_pipeline_get_parent (authority); - CoglPipeline *old_authority = - _cogl_pipeline_get_authority (parent, state); - - if (_cogl_pipeline_blend_state_equal (authority, old_authority)) - pipeline->differences &= ~state; - } - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (pipeline != authority) - { - pipeline->differences |= state; - _cogl_pipeline_prune_redundant_ancestry (pipeline); - } - - pipeline->dirty_real_blend_enable = TRUE; - - return TRUE; -} - -void -cogl_pipeline_set_blend_constant (CoglPipeline *pipeline, - const CoglColor *constant_color) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_BLEND; - CoglPipeline *authority; - CoglPipelineBlendState *blend_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - blend_state = &authority->big_state->blend_state; - if (cogl_color_equal (constant_color, &blend_state->blend_constant)) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - blend_state = &pipeline->big_state->blend_state; - blend_state->blend_constant = *constant_color; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_blend_state_equal); - - pipeline->dirty_real_blend_enable = TRUE; -} - -CoglProgram* -cogl_pipeline_get_user_program (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), NULL); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_USER_SHADER); - - return authority->big_state->user_program; -} - -/* XXX: for now we don't mind if the program has vertex shaders - * attached but if we ever make a similar API public we should only - * allow attaching of programs containing fragment shaders. Eventually - * we will have a CoglPipeline abstraction to also cover vertex - * processing. - */ -void -cogl_pipeline_set_user_program (CoglPipeline *pipeline, - CoglProgram *program) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_USER_SHADER; - CoglPipeline *authority; - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - if (authority->big_state->user_program == program) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - /* If we are the current authority see if we can revert to one of our - * ancestors being the authority */ - if (pipeline == authority && - _cogl_pipeline_get_parent (authority) != NULL) - { - CoglPipeline *parent = _cogl_pipeline_get_parent (authority); - CoglPipeline *old_authority = - _cogl_pipeline_get_authority (parent, state); - - if (old_authority->big_state->user_program == program) - pipeline->differences &= ~state; - } - else if (pipeline != authority) - { - /* If we weren't previously the authority on this state then we - * need to extended our differences mask and so it's possible - * that some of our ancestry will now become redundant, so we - * aim to reparent ourselves if that's true... */ - pipeline->differences |= state; - _cogl_pipeline_prune_redundant_ancestry (pipeline); - } - - if (program != NULL) - g_object_ref (program); - if (authority == pipeline && - pipeline->big_state->user_program != NULL) - g_object_unref (pipeline->big_state->user_program); - pipeline->big_state->user_program = program; - - pipeline->dirty_real_blend_enable = TRUE; -} - -gboolean -cogl_pipeline_set_depth_state (CoglPipeline *pipeline, - const CoglDepthState *depth_state, - GError **error) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_DEPTH; - CoglPipeline *authority; - CoglDepthState *orig_state; - - _COGL_GET_CONTEXT (ctx, FALSE); - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), FALSE); - g_return_val_if_fail (depth_state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - orig_state = &authority->big_state->depth_state; - if (orig_state->test_enabled == depth_state->test_enabled && - orig_state->write_enabled == depth_state->write_enabled && - orig_state->test_function == depth_state->test_function && - orig_state->range_near == depth_state->range_near && - orig_state->range_far == depth_state->range_far) - return TRUE; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - pipeline->big_state->depth_state = *depth_state; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_depth_state_equal); - - return TRUE; -} - -void -cogl_pipeline_get_depth_state (CoglPipeline *pipeline, - CoglDepthState *state) -{ - CoglPipeline *authority; - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH); - *state = authority->big_state->depth_state; -} - -void -cogl_pipeline_set_cull_face_mode (CoglPipeline *pipeline, - CoglPipelineCullFaceMode cull_face_mode) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE; - CoglPipeline *authority; - CoglPipelineCullFaceState *cull_face_state; - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - cull_face_state = &authority->big_state->cull_face_state; - - if (cull_face_state->mode == cull_face_mode) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - pipeline->big_state->cull_face_state.mode = cull_face_mode; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_cull_face_state_equal); -} - -void -cogl_pipeline_set_front_face_winding (CoglPipeline *pipeline, - CoglWinding front_winding) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE; - CoglPipeline *authority; - CoglPipelineCullFaceState *cull_face_state; - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - cull_face_state = &authority->big_state->cull_face_state; - - if (cull_face_state->front_winding == front_winding) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - pipeline->big_state->cull_face_state.front_winding = front_winding; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_cull_face_state_equal); -} - -CoglPipelineCullFaceMode -cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE; - CoglPipeline *authority; - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), - COGL_PIPELINE_CULL_FACE_MODE_NONE); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - return authority->big_state->cull_face_state.mode; -} - -CoglWinding -cogl_pipeline_get_front_face_winding (CoglPipeline *pipeline) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE; - CoglPipeline *authority; - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), - COGL_WINDING_CLOCKWISE); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - return authority->big_state->cull_face_state.front_winding; -} - -float -cogl_pipeline_get_point_size (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), FALSE); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_POINT_SIZE); - - return authority->big_state->point_size; -} - -static void -_cogl_pipeline_set_non_zero_point_size (CoglPipeline *pipeline, - gboolean value) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE; - CoglPipeline *authority; - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - pipeline->big_state->non_zero_point_size = !!value; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_non_zero_point_size_equal); -} - -void -cogl_pipeline_set_point_size (CoglPipeline *pipeline, - float point_size) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_POINT_SIZE; - CoglPipeline *authority; - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - if (authority->big_state->point_size == point_size) - return; - - /* Changing the point size may additionally modify - * COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE. */ - - if ((authority->big_state->point_size > 0.0f) != (point_size > 0.0f)) - _cogl_pipeline_set_non_zero_point_size (pipeline, point_size > 0.0f); - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - pipeline->big_state->point_size = point_size; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_point_size_equal); -} - -gboolean -cogl_pipeline_set_per_vertex_point_size (CoglPipeline *pipeline, - gboolean enable, - GError **error) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE; - CoglPipeline *authority; - - _COGL_GET_CONTEXT (ctx, FALSE); - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), FALSE); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - enable = !!enable; - - if (authority->big_state->per_vertex_point_size == enable) - return TRUE; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - pipeline->big_state->per_vertex_point_size = enable; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_point_size_equal); - - return TRUE; -} - -gboolean -cogl_pipeline_get_per_vertex_point_size (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), FALSE); - - authority = - _cogl_pipeline_get_authority (pipeline, - COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE); - - return authority->big_state->per_vertex_point_size; -} - -static CoglBoxedValue * -_cogl_pipeline_override_uniform (CoglPipeline *pipeline, - int location) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_UNIFORMS; - CoglPipelineUniformsState *uniforms_state; - int override_index; - - _COGL_GET_CONTEXT (ctx, NULL); - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), NULL); - g_return_val_if_fail (location >= 0, NULL); - g_return_val_if_fail (location < ctx->n_uniform_names, NULL); - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - uniforms_state = &pipeline->big_state->uniforms_state; - - /* Count the number of bits that are set below this location. That - should give us the position where our new value should lie */ - override_index = _cogl_bitmask_popcount_upto (&uniforms_state->override_mask, - location); - - _cogl_bitmask_set (&uniforms_state->changed_mask, location, TRUE); - - /* If this pipeline already has an override for this value then we - can just use it directly */ - if (_cogl_bitmask_get (&uniforms_state->override_mask, location)) - return uniforms_state->override_values + override_index; - - /* We need to create a new override value in the right position - within the array. This is pretty inefficient but the hope is that - it will be much more common to modify an existing uniform rather - than modify a new one so it is more important to optimise the - former case. */ - - if (uniforms_state->override_values == NULL) - { - g_assert (override_index == 0); - uniforms_state->override_values = g_new (CoglBoxedValue, 1); - } - else - { - /* We need to grow the array and copy in the old values */ - CoglBoxedValue *old_values = uniforms_state->override_values; - int old_size = _cogl_bitmask_popcount (&uniforms_state->override_mask); - - uniforms_state->override_values = g_new (CoglBoxedValue, old_size + 1); - - /* Copy in the old values leaving a gap for the new value */ - memcpy (uniforms_state->override_values, - old_values, - sizeof (CoglBoxedValue) * override_index); - memcpy (uniforms_state->override_values + override_index + 1, - old_values + override_index, - sizeof (CoglBoxedValue) * (old_size - override_index)); - - g_free (old_values); - } - - _cogl_boxed_value_init (uniforms_state->override_values + override_index); - - _cogl_bitmask_set (&uniforms_state->override_mask, location, TRUE); - - return uniforms_state->override_values + override_index; -} - -void -cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, - int uniform_location, - float value) -{ - CoglBoxedValue *boxed_value; - - boxed_value = _cogl_pipeline_override_uniform (pipeline, uniform_location); - - _cogl_boxed_value_set_1f (boxed_value, value); -} - -void -cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, - int uniform_location, - int value) -{ - CoglBoxedValue *boxed_value; - - boxed_value = _cogl_pipeline_override_uniform (pipeline, uniform_location); - - _cogl_boxed_value_set_1i (boxed_value, value); -} - -void -cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, - int uniform_location, - int n_components, - int count, - const float *value) -{ - CoglBoxedValue *boxed_value; - - boxed_value = _cogl_pipeline_override_uniform (pipeline, uniform_location); - - _cogl_boxed_value_set_float (boxed_value, n_components, count, value); -} - -void -cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, - int uniform_location, - int n_components, - int count, - const int *value) -{ - CoglBoxedValue *boxed_value; - - boxed_value = _cogl_pipeline_override_uniform (pipeline, uniform_location); - - _cogl_boxed_value_set_int (boxed_value, n_components, count, value); -} - -void -cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, - int uniform_location, - int dimensions, - int count, - gboolean transpose, - const float *value) -{ - CoglBoxedValue *boxed_value; - - boxed_value = _cogl_pipeline_override_uniform (pipeline, uniform_location); - - _cogl_boxed_value_set_matrix (boxed_value, - dimensions, - count, - transpose, - value); -} - -static void -_cogl_pipeline_add_vertex_snippet (CoglPipeline *pipeline, - CoglSnippet *snippet) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_VERTEX_SNIPPETS; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - _cogl_pipeline_snippet_list_add (&pipeline->big_state->vertex_snippets, - snippet); -} - -static void -_cogl_pipeline_add_fragment_snippet (CoglPipeline *pipeline, - CoglSnippet *snippet) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - _cogl_pipeline_snippet_list_add (&pipeline->big_state->fragment_snippets, - snippet); -} - -void -cogl_pipeline_add_snippet (CoglPipeline *pipeline, - CoglSnippet *snippet) -{ - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - g_return_if_fail (COGL_IS_SNIPPET (snippet)); - g_return_if_fail (snippet->hook < COGL_SNIPPET_FIRST_LAYER_HOOK); - - if (snippet->hook < COGL_SNIPPET_FIRST_PIPELINE_FRAGMENT_HOOK) - _cogl_pipeline_add_vertex_snippet (pipeline, snippet); - else - _cogl_pipeline_add_fragment_snippet (pipeline, snippet); -} - -gboolean -_cogl_pipeline_has_non_layer_vertex_snippets (CoglPipeline *pipeline) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, - COGL_PIPELINE_STATE_VERTEX_SNIPPETS); - - return authority->big_state->vertex_snippets.entries != NULL; -} - -static gboolean -check_layer_has_vertex_snippet (CoglPipelineLayer *layer, - void *user_data) -{ - unsigned long state = COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS; - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, state); - gboolean *found_vertex_snippet = user_data; - - if (authority->big_state->vertex_snippets.entries) - { - *found_vertex_snippet = TRUE; - return FALSE; - } - - return TRUE; -} - -gboolean -_cogl_pipeline_has_vertex_snippets (CoglPipeline *pipeline) -{ - gboolean found_vertex_snippet = FALSE; - - if (_cogl_pipeline_has_non_layer_vertex_snippets (pipeline)) - return TRUE; - - _cogl_pipeline_foreach_layer_internal (pipeline, - check_layer_has_vertex_snippet, - &found_vertex_snippet); - - return found_vertex_snippet; -} - -gboolean -_cogl_pipeline_has_non_layer_fragment_snippets (CoglPipeline *pipeline) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, - COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS); - - return authority->big_state->fragment_snippets.entries != NULL; -} - -void -_cogl_pipeline_hash_color_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - state->hash = _cogl_util_one_at_a_time_hash (state->hash, &authority->color, - _COGL_COLOR_DATA_SIZE); -} - -void -_cogl_pipeline_hash_alpha_func_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - CoglPipelineAlphaFuncState *alpha_state = &authority->big_state->alpha_state; - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &alpha_state->alpha_func, - sizeof (alpha_state->alpha_func)); -} - -void -_cogl_pipeline_hash_alpha_func_reference_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - CoglPipelineAlphaFuncState *alpha_state = &authority->big_state->alpha_state; - float ref = alpha_state->alpha_func_reference; - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &ref, sizeof (float)); -} - -void -_cogl_pipeline_hash_blend_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - CoglPipelineBlendState *blend_state = &authority->big_state->blend_state; - unsigned int hash; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!authority->real_blend_enable) - return; - - hash = state->hash; - - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_equation_rgb, - sizeof (blend_state->blend_equation_rgb)); - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_equation_alpha, - sizeof (blend_state->blend_equation_alpha)); - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_src_factor_alpha, - sizeof (blend_state->blend_src_factor_alpha)); - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_dst_factor_alpha, - sizeof (blend_state->blend_dst_factor_alpha)); - - if (blend_state->blend_src_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR || - blend_state->blend_src_factor_rgb == GL_CONSTANT_COLOR || - blend_state->blend_dst_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR || - blend_state->blend_dst_factor_rgb == GL_CONSTANT_COLOR) - { - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_constant, - sizeof (blend_state->blend_constant)); - } - - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_src_factor_rgb, - sizeof (blend_state->blend_src_factor_rgb)); - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_dst_factor_rgb, - sizeof (blend_state->blend_dst_factor_rgb)); - - state->hash = hash; -} - -void -_cogl_pipeline_hash_user_shader_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - CoglProgram *user_program = authority->big_state->user_program; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, &user_program, - sizeof (user_program)); -} - -void -_cogl_pipeline_hash_depth_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - CoglDepthState *depth_state = &authority->big_state->depth_state; - unsigned int hash = state->hash; - - if (depth_state->test_enabled) - { - uint8_t enabled = depth_state->test_enabled; - CoglDepthTestFunction function = depth_state->test_function; - hash = _cogl_util_one_at_a_time_hash (hash, &enabled, sizeof (enabled)); - hash = _cogl_util_one_at_a_time_hash (hash, &function, sizeof (function)); - } - - if (depth_state->write_enabled) - { - uint8_t enabled = depth_state->write_enabled; - float near_val = depth_state->range_near; - float far_val = depth_state->range_far; - hash = _cogl_util_one_at_a_time_hash (hash, &enabled, sizeof (enabled)); - hash = _cogl_util_one_at_a_time_hash (hash, &near_val, sizeof (near_val)); - hash = _cogl_util_one_at_a_time_hash (hash, &far_val, sizeof (far_val)); - } - - state->hash = hash; -} - -void -_cogl_pipeline_hash_non_zero_point_size_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - gboolean non_zero_point_size = authority->big_state->non_zero_point_size; - - state->hash = _cogl_util_one_at_a_time_hash (state->hash, - &non_zero_point_size, - sizeof (non_zero_point_size)); -} - -void -_cogl_pipeline_hash_point_size_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - float point_size = authority->big_state->point_size; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, &point_size, - sizeof (point_size)); -} - -void -_cogl_pipeline_hash_per_vertex_point_size_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - gboolean per_vertex_point_size = authority->big_state->per_vertex_point_size; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, - &per_vertex_point_size, - sizeof (per_vertex_point_size)); -} - -void -_cogl_pipeline_hash_cull_face_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - CoglPipelineCullFaceState *cull_face_state - = &authority->big_state->cull_face_state; - - /* The cull face state is considered equal if two pipelines are both - set to no culling. If the front winding property is ever used for - anything else or the hashing is used not just for drawing then - this would have to change */ - if (cull_face_state->mode == COGL_PIPELINE_CULL_FACE_MODE_NONE) - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, - &cull_face_state->mode, - sizeof (CoglPipelineCullFaceMode)); - else - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, - cull_face_state, - sizeof (CoglPipelineCullFaceState)); -} - -void -_cogl_pipeline_hash_uniforms_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - /* This isn't used anywhere yet because the uniform state doesn't - affect program generation. It's quite a hassle to implement so - let's just leave it until something actually needs it */ - g_warn_if_reached (); -} - -void -_cogl_pipeline_compare_uniform_differences (unsigned long *differences, - CoglPipeline *pipeline0, - CoglPipeline *pipeline1) -{ - GSList *head0 = NULL; - GSList *head1 = NULL; - CoglPipeline *node0; - CoglPipeline *node1; - int len0 = 0; - int len1 = 0; - int count; - GSList *common_ancestor0; - GSList *common_ancestor1; - - /* This algorithm is copied from - _cogl_pipeline_compare_differences(). It might be nice to share - the code more */ - - for (node0 = pipeline0; node0; node0 = _cogl_pipeline_get_parent (node0)) - { - GSList *link = alloca (sizeof (GSList)); - link->next = head0; - link->data = node0; - head0 = link; - len0++; - } - for (node1 = pipeline1; node1; node1 = _cogl_pipeline_get_parent (node1)) - { - GSList *link = alloca (sizeof (GSList)); - link->next = head1; - link->data = node1; - head1 = link; - len1++; - } - - /* NB: There's no point looking at the head entries since we know both - * pipelines must have the same default pipeline as their root node. */ - common_ancestor0 = head0; - common_ancestor1 = head1; - head0 = head0->next; - head1 = head1->next; - count = MIN (len0, len1) - 1; - while (count--) - { - if (head0->data != head1->data) - break; - common_ancestor0 = head0; - common_ancestor1 = head1; - head0 = head0->next; - head1 = head1->next; - } - - for (head0 = common_ancestor0->next; head0; head0 = head0->next) - { - node0 = head0->data; - if ((node0->differences & COGL_PIPELINE_STATE_UNIFORMS)) - { - const CoglPipelineUniformsState *uniforms_state = - &node0->big_state->uniforms_state; - _cogl_bitmask_set_flags (&uniforms_state->override_mask, - differences); - } - } - for (head1 = common_ancestor1->next; head1; head1 = head1->next) - { - node1 = head1->data; - if ((node1->differences & COGL_PIPELINE_STATE_UNIFORMS)) - { - const CoglPipelineUniformsState *uniforms_state = - &node1->big_state->uniforms_state; - _cogl_bitmask_set_flags (&uniforms_state->override_mask, - differences); - } - } -} - -void -_cogl_pipeline_hash_vertex_snippets_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - _cogl_pipeline_snippet_list_hash (&authority->big_state->vertex_snippets, - &state->hash); -} - -void -_cogl_pipeline_hash_fragment_snippets_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - _cogl_pipeline_snippet_list_hash (&authority->big_state->fragment_snippets, - &state->hash); -} diff --git a/mutter/cogl/cogl/cogl-pipeline-state.h b/mutter/cogl/cogl/cogl-pipeline-state.h deleted file mode 100644 index 0650687..0000000 --- a/mutter/cogl/cogl/cogl-pipeline-state.h +++ /dev/null @@ -1,617 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-pipeline.h" -#include "cogl/cogl-color.h" -#include "cogl/cogl-depth-state.h" -#include "cogl/deprecated/cogl-program.h" - -G_BEGIN_DECLS - -/** - * cogl_pipeline_set_color: - * @pipeline: A #CoglPipeline object - * @color: The components of the color - * - * Sets the basic color of the pipeline, used when no lighting is enabled. - * - * Note that if you don't add any layers to the pipeline then the color - * will be blended unmodified with the destination; the default blend - * expects premultiplied colors: for example, use (0.5, 0.0, 0.0, 0.5) for - * semi-transparent red. See cogl_color_premultiply(). - * - * The default value is (1.0, 1.0, 1.0, 1.0) - */ -COGL_EXPORT void -cogl_pipeline_set_color (CoglPipeline *pipeline, - const CoglColor *color); - -/** - * cogl_pipeline_get_color: - * @pipeline: A #CoglPipeline object - * @color: (out): The location to store the color - * - * Retrieves the current pipeline color. - */ -COGL_EXPORT void -cogl_pipeline_get_color (CoglPipeline *pipeline, - CoglColor *color); - -/** - * CoglPipelineAlphaFunc: - * @COGL_PIPELINE_ALPHA_FUNC_NEVER: Never let the fragment through. - * @COGL_PIPELINE_ALPHA_FUNC_LESS: Let the fragment through if the incoming - * alpha value is less than the reference alpha value - * @COGL_PIPELINE_ALPHA_FUNC_EQUAL: Let the fragment through if the incoming - * alpha value equals the reference alpha value - * @COGL_PIPELINE_ALPHA_FUNC_LEQUAL: Let the fragment through if the incoming - * alpha value is less than or equal to the reference alpha value - * @COGL_PIPELINE_ALPHA_FUNC_GREATER: Let the fragment through if the incoming - * alpha value is greater than the reference alpha value - * @COGL_PIPELINE_ALPHA_FUNC_NOTEQUAL: Let the fragment through if the incoming - * alpha value does not equal the reference alpha value - * @COGL_PIPELINE_ALPHA_FUNC_GEQUAL: Let the fragment through if the incoming - * alpha value is greater than or equal to the reference alpha value. - * @COGL_PIPELINE_ALPHA_FUNC_ALWAYS: Always let the fragment through. - * - * Alpha testing happens before blending primitives with the framebuffer and - * gives an opportunity to discard fragments based on a comparison with the - * incoming alpha value and a reference alpha value. The #CoglPipelineAlphaFunc - * determines how the comparison is done. - */ -typedef enum -{ - COGL_PIPELINE_ALPHA_FUNC_NEVER = 0x0200, - COGL_PIPELINE_ALPHA_FUNC_LESS = 0x0201, - COGL_PIPELINE_ALPHA_FUNC_EQUAL = 0x0202, - COGL_PIPELINE_ALPHA_FUNC_LEQUAL = 0x0203, - COGL_PIPELINE_ALPHA_FUNC_GREATER = 0x0204, - COGL_PIPELINE_ALPHA_FUNC_NOTEQUAL = 0x0205, - COGL_PIPELINE_ALPHA_FUNC_GEQUAL = 0x0206, - COGL_PIPELINE_ALPHA_FUNC_ALWAYS = 0x0207 -} CoglPipelineAlphaFunc; -/* NB: these values come from the equivalents in gl.h */ - -/** - * cogl_pipeline_set_alpha_test_function: - * @pipeline: A #CoglPipeline object - * @alpha_func: A @CoglPipelineAlphaFunc constant - * @alpha_reference: A reference point that the chosen alpha function uses - * to compare incoming fragments to. - * - * Before a primitive is blended with the framebuffer, it goes through an - * alpha test stage which lets you discard fragments based on the current - * alpha value. This function lets you change the function used to evaluate - * the alpha channel, and thus determine which fragments are discarded - * and which continue on to the blending stage. - * - * The default is %COGL_PIPELINE_ALPHA_FUNC_ALWAYS - */ -COGL_EXPORT void -cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline, - CoglPipelineAlphaFunc alpha_func, - float alpha_reference); - -/** - * cogl_pipeline_get_alpha_test_function: - * @pipeline: A #CoglPipeline object - * - * Return value: The alpha test function of @pipeline. - */ -COGL_EXPORT CoglPipelineAlphaFunc -cogl_pipeline_get_alpha_test_function (CoglPipeline *pipeline); - -/** - * cogl_pipeline_get_alpha_test_reference: - * @pipeline: A #CoglPipeline object - * - * Return value: The alpha test reference value of @pipeline. - */ -COGL_EXPORT float -cogl_pipeline_get_alpha_test_reference (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_blend: - * @pipeline: A #CoglPipeline object - * @blend_string: A Cogl blend string - * describing the desired blend function. - * @error: return location for a #GError that may report lack of driver - * support if you give separate blend string statements for the alpha - * channel and RGB channels since some drivers, or backends such as - * GLES 1.1, don't support this feature. May be %NULL, in which case a - * warning will be printed out using GLib's logging facilities if an - * error is encountered. - * - * Blending occurs after the alpha test function, and combines fragments with - * the framebuffer. - - * Currently the only blend function Cogl exposes is ADD(). So any valid - * blend statements will be of the form: - * - * ``` - * <channel-mask>=ADD(SRC_COLOR*(<factor>), DST_COLOR*(<factor>)) - * ``` - * - * This is the list of source-names usable as blend factors: - * - * - `SRC_COLOR`: The color of the incoming fragment - * - `DST_COLOR`: The color of the framebuffer - * - `CONSTANT`: The constant set via cogl_pipeline_set_blend_constant() - * - * These can also be used as factors: - * - * - `0`: (0, 0, 0, 0) - * - `1`: (1, 1, 1, 1) - * - `SRC_ALPHA_SATURATE_FACTOR`: (f,f,f,1) where `f = MIN(SRC_COLOR[A],1-DST_COLOR[A])` - * - * Remember; all color components are normalized to the range [0, 1] - * before computing the result of blending. - * - * - Blend Strings/1: - * Blend a non-premultiplied source over a destination with - * premultiplied alpha: - * ``` - * "RGB = ADD(SRC_COLOR*(SRC_COLOR[A]), DST_COLOR*(1-SRC_COLOR[A]))" - * "A = ADD(SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))" - * ``` - * - * Blend Strings/2: - * Blend a premultiplied source over a destination with - * premultiplied alpha - * ``` - * "RGBA = ADD(SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))" - * ``` - * - * The default blend string is: - * ``` - * RGBA = ADD (SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A])) - * ``` - * - * That gives normal alpha-blending when the calculated color for the pipeline - * is in premultiplied form. - * - * Return value: %TRUE if the blend string was successfully parsed, and the - * described blending is supported by the underlying driver/hardware. If - * there was an error, %FALSE is returned and @error is set accordingly (if - * present). - */ -COGL_EXPORT gboolean -cogl_pipeline_set_blend (CoglPipeline *pipeline, - const char *blend_string, - GError **error); - -/** - * cogl_pipeline_set_blend_constant: - * @pipeline: A #CoglPipeline object - * @constant_color: The constant color you want - * - * When blending is setup to reference a CONSTANT blend factor then - * blending will depend on the constant set with this function. - */ -COGL_EXPORT void -cogl_pipeline_set_blend_constant (CoglPipeline *pipeline, - const CoglColor *constant_color); - -/** - * cogl_pipeline_set_point_size: - * @pipeline: a #CoglPipeline pointer - * @point_size: the new point size. - * - * Changes the size of points drawn when %COGL_VERTICES_MODE_POINTS is - * used with the attribute buffer API. Note that typically the GPU - * will only support a limited minimum and maximum range of point - * sizes. If the chosen point size is outside that range then the - * nearest value within that range will be used instead. The size of a - * point is in screen space so it will be the same regardless of any - * transformations. - * - * If the point size is set to 0.0 then drawing points with the - * pipeline will have undefined results. This is the default value so - * if an application wants to draw points it must make sure to use a - * pipeline that has an explicit point size set on it. - */ -COGL_EXPORT void -cogl_pipeline_set_point_size (CoglPipeline *pipeline, - float point_size); - -/** - * cogl_pipeline_get_point_size: - * @pipeline: a #CoglPipeline pointer - * - * Get the size of points drawn when %COGL_VERTICES_MODE_POINTS is - * used with the vertex buffer API. - * - * Return value: the point size of the @pipeline. - */ -COGL_EXPORT float -cogl_pipeline_get_point_size (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_per_vertex_point_size: - * @pipeline: a #CoglPipeline pointer - * @enable: whether to enable per-vertex point size - * @error: a location to store a #GError if the change failed - * - * Sets whether to use a per-vertex point size or to use the value set - * by cogl_pipeline_set_point_size(). If per-vertex point size is - * enabled then the point size can be set for an individual point - * either by drawing with a #CoglAttribute with the name - * ‘cogl_point_size_in’ or by writing to the GLSL builtin - * ‘cogl_point_size_out’ from a vertex shader snippet. - * - * If per-vertex point size is enabled and this attribute is not used - * and cogl_point_size_out is not written to then the results are - * undefined. - * Return value: %TRUE if the change succeeded or %FALSE otherwise - */ -COGL_EXPORT gboolean -cogl_pipeline_set_per_vertex_point_size (CoglPipeline *pipeline, - gboolean enable, - GError **error); - -/** - * cogl_pipeline_get_per_vertex_point_size: - * @pipeline: a #CoglPipeline pointer - * Return value: %TRUE if the pipeline has per-vertex point size - * enabled or %FALSE otherwise. The per-vertex point size can be - * enabled with cogl_pipeline_set_per_vertex_point_size(). - */ -COGL_EXPORT gboolean -cogl_pipeline_get_per_vertex_point_size (CoglPipeline *pipeline); - -/** - * cogl_pipeline_get_user_program: - * @pipeline: a #CoglPipeline object. - * - * Queries what user program has been associated with the given - * @pipeline using cogl_pipeline_set_user_program(). - * - * Return value: (transfer none): The current user program or %NULL. - */ -COGL_EXPORT CoglProgram* -cogl_pipeline_get_user_program (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_user_program: - * @pipeline: a #CoglPipeline object. - * @program: A linked CoglProgram - * - * Associates a linked CoglProgram with the given pipeline so that the - * program can take full control of vertex and/or fragment processing. - * - * This is an example of how it can be used to associate an ARBfp - * program with a #CoglPipeline: - * ```c - * CoglShader *shader; - * CoglProgram *program; - * CoglPipeline *pipeline; - * - * shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); - * cogl_shader_source (shader, - * "!!ARBfp1.0\n" - * "MOV result.color,fragment.color;\n" - * "END\n"); - * - * program = cogl_create_program (); - * cogl_program_attach_shader (program, shader); - * cogl_program_link (program); - * - * pipeline = cogl_pipeline_new (); - * cogl_pipeline_set_user_program (pipeline, program); - * - * cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); - * cogl_rectangle (0, 0, 100, 100); - * ``` - * - * It is possibly worth keeping in mind that this API is not part of - * the long term design for how we want to expose shaders to Cogl - * developers (We are planning on deprecating the cogl_program and - * cogl_shader APIs in favour of a "snippet" framework) but in the - * meantime we hope this will handle most practical GLSL and ARBfp - * requirements. - */ -COGL_EXPORT void -cogl_pipeline_set_user_program (CoglPipeline *pipeline, - CoglProgram *program); - -/** - * cogl_pipeline_set_depth_state: - * @pipeline: A #CoglPipeline object - * @state: A #CoglDepthState struct - * @error: A #GError to report failures to setup the given @state. - * - * This commits all the depth state configured in @state struct to the - * given @pipeline. The configuration values are copied into the - * pipeline so there is no requirement to keep the #CoglDepthState - * struct around if you don't need it any more. - * - * Note: Since some platforms do not support the depth range feature - * it is possible for this function to fail and report an @error. - * - * Returns: %TRUE if the GPU supports all the given @state else %FALSE - * and returns an @error. - */ -COGL_EXPORT gboolean -cogl_pipeline_set_depth_state (CoglPipeline *pipeline, - const CoglDepthState *state, - GError **error); - -/** - * cogl_pipeline_get_depth_state: - * @pipeline: A #CoglPipeline object - * @state_out: (out): A destination #CoglDepthState struct - * - * Retrieves the current depth state configuration for the given - * @pipeline as previously set using cogl_pipeline_set_depth_state(). - */ -COGL_EXPORT void -cogl_pipeline_get_depth_state (CoglPipeline *pipeline, - CoglDepthState *state_out); - -/** - * CoglPipelineCullFaceMode: - * @COGL_PIPELINE_CULL_FACE_MODE_NONE: Neither face will be - * culled. This is the default. - * @COGL_PIPELINE_CULL_FACE_MODE_FRONT: Front faces will be culled. - * @COGL_PIPELINE_CULL_FACE_MODE_BACK: Back faces will be culled. - * @COGL_PIPELINE_CULL_FACE_MODE_BOTH: All faces will be culled. - * - * Specifies which faces should be culled. This can be set on a - * pipeline using cogl_pipeline_set_cull_face_mode(). - */ -typedef enum -{ - COGL_PIPELINE_CULL_FACE_MODE_NONE, - COGL_PIPELINE_CULL_FACE_MODE_FRONT, - COGL_PIPELINE_CULL_FACE_MODE_BACK, - COGL_PIPELINE_CULL_FACE_MODE_BOTH -} CoglPipelineCullFaceMode; - -/** - * cogl_pipeline_set_cull_face_mode: - * @pipeline: A #CoglPipeline - * @cull_face_mode: The new mode to set - * - * Sets which faces will be culled when drawing. Face culling can be - * used to increase efficiency by avoiding drawing faces that would - * get overridden. For example, if a model has gaps so that it is - * impossible to see the inside then faces which are facing away from - * the screen will never be seen so there is no point in drawing - * them. This can be achieved by setting the cull face mode to - * %COGL_PIPELINE_CULL_FACE_MODE_BACK. - * - * Face culling relies on the primitives being drawn with a specific - * order to represent which faces are facing inside and outside the - * model. This order can be specified by calling - * cogl_pipeline_set_front_face_winding(). - */ -COGL_EXPORT void -cogl_pipeline_set_cull_face_mode (CoglPipeline *pipeline, - CoglPipelineCullFaceMode cull_face_mode); - -/** - * cogl_pipeline_get_cull_face_mode: - * - * Return value: the cull face mode that was previously set with - * cogl_pipeline_set_cull_face_mode(). - */ -COGL_EXPORT CoglPipelineCullFaceMode -cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_front_face_winding: - * @pipeline: a #CoglPipeline - * @front_winding: the winding order - * - * The order of the vertices within a primitive specifies whether it - * is considered to be front or back facing. This function specifies - * which order is considered to be the front - * faces. %COGL_WINDING_COUNTER_CLOCKWISE sets the front faces to - * primitives with vertices in a counter-clockwise order and - * %COGL_WINDING_CLOCKWISE sets them to be clockwise. The default is - * %COGL_WINDING_COUNTER_CLOCKWISE. - */ -COGL_EXPORT void -cogl_pipeline_set_front_face_winding (CoglPipeline *pipeline, - CoglWinding front_winding); - -/** - * cogl_pipeline_get_front_face_winding: - * @pipeline: a #CoglPipeline - * - * The order of the vertices within a primitive specifies whether it - * is considered to be front or back facing. This function specifies - * which order is considered to be the front - * faces. %COGL_WINDING_COUNTER_CLOCKWISE sets the front faces to - * primitives with vertices in a counter-clockwise order and - * %COGL_WINDING_CLOCKWISE sets them to be clockwise. The default is - * %COGL_WINDING_COUNTER_CLOCKWISE. - * - * Returns: The @pipeline front face winding - */ -COGL_EXPORT CoglWinding -cogl_pipeline_get_front_face_winding (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_uniform_1f: - * @pipeline: A #CoglPipeline object - * @uniform_location: The uniform's location identifier - * @value: The new value for the uniform - * - * Sets a new value for the uniform at @uniform_location. If this - * pipeline has a user program attached and is later used as a source - * for drawing, the given value will be assigned to the uniform which - * can be accessed from the shader's source. The value for - * @uniform_location should be retrieved from the string name of the - * uniform by calling cogl_pipeline_get_uniform_location(). - * - * This function should be used to set uniforms that are of type - * float. It can also be used to set a single member of a float array - * uniform. - */ -COGL_EXPORT void -cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, - int uniform_location, - float value); - -/** - * cogl_pipeline_set_uniform_1i: - * @pipeline: A #CoglPipeline object - * @uniform_location: The uniform's location identifier - * @value: The new value for the uniform - * - * Sets a new value for the uniform at @uniform_location. If this - * pipeline has a user program attached and is later used as a source - * for drawing, the given value will be assigned to the uniform which - * can be accessed from the shader's source. The value for - * @uniform_location should be retrieved from the string name of the - * uniform by calling cogl_pipeline_get_uniform_location(). - * - * This function should be used to set uniforms that are of type - * int. It can also be used to set a single member of a int array - * uniform or a sampler uniform. - */ -COGL_EXPORT void -cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, - int uniform_location, - int value); - -/** - * cogl_pipeline_set_uniform_float: - * @pipeline: A #CoglPipeline object - * @uniform_location: The uniform's location identifier - * @n_components: The number of components in the corresponding uniform's type - * @count: The number of values to set - * @value: Pointer to the new values to set - * - * Sets new values for the uniform at @uniform_location. If this - * pipeline has a user program attached and is later used as a source - * for drawing, the given values will be assigned to the uniform which - * can be accessed from the shader's source. The value for - * @uniform_location should be retrieved from the string name of the - * uniform by calling cogl_pipeline_get_uniform_location(). - * - * This function can be used to set any floating point type uniform, - * including float arrays and float vectors. For example, to set a - * single vec4 uniform you would use 4 for @n_components and 1 for - * @count. To set an array of 8 float values, you could use 1 for - * @n_components and 8 for @count. - */ -COGL_EXPORT void -cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, - int uniform_location, - int n_components, - int count, - const float *value); - -/** - * cogl_pipeline_set_uniform_int: - * @pipeline: A #CoglPipeline object - * @uniform_location: The uniform's location identifier - * @n_components: The number of components in the corresponding uniform's type - * @count: The number of values to set - * @value: Pointer to the new values to set - * - * Sets new values for the uniform at @uniform_location. If this - * pipeline has a user program attached and is later used as a source - * for drawing, the given values will be assigned to the uniform which - * can be accessed from the shader's source. The value for - * @uniform_location should be retrieved from the string name of the - * uniform by calling cogl_pipeline_get_uniform_location(). - * - * This function can be used to set any integer type uniform, - * including int arrays and int vectors. For example, to set a single - * ivec4 uniform you would use 4 for @n_components and 1 for - * @count. To set an array of 8 int values, you could use 1 for - * @n_components and 8 for @count. - */ -COGL_EXPORT void -cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, - int uniform_location, - int n_components, - int count, - const int *value); - -/** - * cogl_pipeline_set_uniform_matrix: - * @pipeline: A #CoglPipeline object - * @uniform_location: The uniform's location identifier - * @dimensions: The size of the matrix - * @count: The number of values to set - * @transpose: Whether to transpose the matrix - * @value: Pointer to the new values to set - * - * Sets new values for the uniform at @uniform_location. If this - * pipeline has a user program attached and is later used as a source - * for drawing, the given values will be assigned to the uniform which - * can be accessed from the shader's source. The value for - * @uniform_location should be retrieved from the string name of the - * uniform by calling cogl_pipeline_get_uniform_location(). - * - * This function can be used to set any matrix type uniform, including - * matrix arrays. For example, to set a single mat4 uniform you would - * use 4 for @dimensions and 1 for @count. To set an array of 8 - * mat3 values, you could use 3 for @dimensions and 8 for @count. - * - * If @transpose is %FALSE then the matrix is expected to be in - * column-major order or if it is %TRUE then the matrix is in - * row-major order. You can pass a #graphene_matrix_t by calling by passing - * the result of graphene_matrix_to_float() in @value and setting - * @transpose to %FALSE. - */ -COGL_EXPORT void -cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, - int uniform_location, - int dimensions, - int count, - gboolean transpose, - const float *value); - -/** - * cogl_pipeline_add_snippet: - * @pipeline: A #CoglPipeline - * @snippet: The #CoglSnippet to add to the vertex processing hook - * - * Adds a shader snippet to @pipeline. The snippet will wrap around or - * replace some part of the pipeline as defined by the hook point in - * @snippet. Note that some hook points are specific to a layer and - * must be added with cogl_pipeline_add_layer_snippet() instead. - */ -COGL_EXPORT void -cogl_pipeline_add_snippet (CoglPipeline *pipeline, - CoglSnippet *snippet); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-pipeline.c b/mutter/cogl/cogl/cogl-pipeline.c deleted file mode 100644 index f5a48b9..0000000 --- a/mutter/cogl/cogl/cogl-pipeline.c +++ /dev/null @@ -1,2794 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-debug.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-pipeline-state-private.h" -#include "cogl/cogl-pipeline-layer-state-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-blend-string.h" -#include "cogl/cogl-journal-private.h" -#include "cogl/cogl-color-private.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-profile.h" -#include "cogl/cogl-depth-state-private.h" -#include "cogl/cogl1-context.h" - -#include -#include -#include - -static void recursively_free_layer_caches (CoglPipeline *pipeline); -static gboolean _cogl_pipeline_is_weak (CoglPipeline *pipeline); - -const CoglPipelineFragend *_cogl_pipeline_fragend; -const CoglPipelineVertend *_cogl_pipeline_vertend; -const CoglPipelineProgend *_cogl_pipeline_progend; - -#include "cogl/driver/gl/cogl-pipeline-fragend-glsl-private.h" -#include "cogl/driver/gl/cogl-pipeline-vertend-glsl-private.h" -#include "cogl/driver/gl/cogl-pipeline-progend-glsl-private.h" - -G_DEFINE_FINAL_TYPE (CoglPipeline, cogl_pipeline, COGL_TYPE_NODE) - -static void -_cogl_pipeline_revert_weak_ancestors (CoglPipeline *strong) -{ - CoglNode *n; - - g_return_if_fail (!strong->is_weak); - - /* This reverts the effect of calling - _cogl_pipeline_promote_weak_ancestors */ - - if (COGL_NODE (strong)->parent == NULL) - return; - - for (n = COGL_NODE (strong)->parent; - /* We can assume that all weak pipelines have a parent */ - COGL_PIPELINE (n)->is_weak; - n = n->parent) - /* 'n' is weak so we unref its parent */ - g_object_unref (n->parent); -} - -static gboolean -destroy_weak_children_cb (CoglNode *node, - void *user_data) -{ - CoglPipeline *pipeline = COGL_PIPELINE (node); - - if (_cogl_pipeline_is_weak (pipeline)) - { - _cogl_pipeline_node_foreach_child (COGL_NODE (pipeline), - destroy_weak_children_cb, - NULL); - - pipeline->destroy_callback (pipeline, pipeline->destroy_data); - _cogl_pipeline_node_unparent_real (COGL_NODE (pipeline)); - } - - return TRUE; -} - -static void -cogl_pipeline_dispose (GObject *object) -{ - CoglPipeline *pipeline = COGL_PIPELINE (object); - - if (!pipeline->is_weak) - _cogl_pipeline_revert_weak_ancestors (pipeline); - - /* Weak pipelines don't take a reference on their parent */ - _cogl_pipeline_node_foreach_child (COGL_NODE (pipeline), - destroy_weak_children_cb, - NULL); - - g_assert (_cogl_list_empty (&COGL_NODE (pipeline)->children)); - - _cogl_pipeline_node_unparent_real (COGL_NODE (pipeline)); - - if (pipeline->differences & COGL_PIPELINE_STATE_USER_SHADER && - pipeline->big_state->user_program) - g_object_unref (pipeline->big_state->user_program); - - if (pipeline->differences & COGL_PIPELINE_STATE_UNIFORMS) - { - CoglPipelineUniformsState *uniforms_state - = &pipeline->big_state->uniforms_state; - int n_overrides = _cogl_bitmask_popcount (&uniforms_state->override_mask); - int i; - - for (i = 0; i < n_overrides; i++) - _cogl_boxed_value_destroy (uniforms_state->override_values + i); - g_free (uniforms_state->override_values); - - _cogl_bitmask_destroy (&uniforms_state->override_mask); - _cogl_bitmask_destroy (&uniforms_state->changed_mask); - } - - if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS) - g_list_free_full (pipeline->layer_differences, g_object_unref); - - if (pipeline->differences & COGL_PIPELINE_STATE_VERTEX_SNIPPETS) - _cogl_pipeline_snippet_list_free (&pipeline->big_state->vertex_snippets); - - if (pipeline->differences & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS) - _cogl_pipeline_snippet_list_free (&pipeline->big_state->fragment_snippets); - - if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE) - g_free (pipeline->big_state); - - recursively_free_layer_caches (pipeline); - - G_OBJECT_CLASS (cogl_pipeline_parent_class)->dispose (object); -} - -static void -cogl_pipeline_class_init (CoglPipelineClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = cogl_pipeline_dispose; -} - -static void -cogl_pipeline_init (CoglPipeline *pipeline) -{ -} - -static CoglPipelineBigState * -create_default_big_state (void) -{ - /* XXX: NB: It's important that we zero this to avoid polluting - * pipeline hash values with un-initialized data */ - CoglPipelineBigState *big_state = g_new0 (CoglPipelineBigState, 1); - CoglPipelineAlphaFuncState *alpha_state = &big_state->alpha_state; - CoglPipelineBlendState *blend_state = &big_state->blend_state; - CoglPipelineCullFaceState *cull_face_state = &big_state->cull_face_state; - CoglPipelineUniformsState *uniforms_state = &big_state->uniforms_state; - - big_state->user_program = NULL; - big_state->point_size = 0.0f; - cogl_depth_state_init (&big_state->depth_state); - - /* Use the same defaults as the GL spec... */ - alpha_state->alpha_func = COGL_PIPELINE_ALPHA_FUNC_ALWAYS; - alpha_state->alpha_func_reference = 0.0; - - /* Not the same as the GL default, but seems saner... */ - blend_state->blend_equation_rgb = GL_FUNC_ADD; - blend_state->blend_equation_alpha = GL_FUNC_ADD; - blend_state->blend_src_factor_alpha = GL_ONE; - blend_state->blend_dst_factor_alpha = GL_ONE_MINUS_SRC_ALPHA; - cogl_color_init_from_4f (&blend_state->blend_constant, - 0.0, 0.0, 0.0, 0.0); - blend_state->blend_src_factor_rgb = GL_ONE; - blend_state->blend_dst_factor_rgb = GL_ONE_MINUS_SRC_ALPHA; - - cull_face_state->mode = COGL_PIPELINE_CULL_FACE_MODE_NONE; - cull_face_state->front_winding = COGL_WINDING_COUNTER_CLOCKWISE; - - _cogl_bitmask_init (&uniforms_state->override_mask); - _cogl_bitmask_init (&uniforms_state->changed_mask); - uniforms_state->override_values = NULL; - - return big_state; -} - -/* - * This initializes the first pipeline owned by the Cogl context. All - * subsequently instantiated pipelines created via the cogl_pipeline_new() - * API will initially be a copy of this pipeline. - * - * The default pipeline is the topmost ancestor for all pipelines. - */ -void -_cogl_pipeline_init_default_pipeline (CoglContext *context) -{ - /* Create new - blank - pipeline */ - CoglPipeline *pipeline = g_object_new (COGL_TYPE_PIPELINE, NULL); - pipeline->context = context; - - pipeline->differences = COGL_PIPELINE_STATE_ALL_SPARSE; - - pipeline->big_state = create_default_big_state (); - pipeline->has_big_state = TRUE; - - /* Use the same defaults as the GL spec... */ - cogl_color_init_from_4f (&pipeline->color, 1.0, 1.0, 1.0, 1.0); - -#ifdef COGL_ENABLE_DEBUG - pipeline->static_breadcrumb = "default pipeline"; - pipeline->has_static_breadcrumb = TRUE; -#endif - - context->default_pipeline = pipeline; - - /* Take this opportunity to setup the backends... */ - _cogl_pipeline_fragend = &_cogl_pipeline_glsl_fragend; - _cogl_pipeline_progend = &_cogl_pipeline_glsl_progend; - _cogl_pipeline_vertend = &_cogl_pipeline_glsl_vertend; -} - - -static gboolean -recursively_free_layer_caches_cb (CoglNode *node, - void *user_data) -{ - recursively_free_layer_caches (COGL_PIPELINE (node)); - return TRUE; -} - -/* This recursively frees the layers_cache of a pipeline and all of - * its descendants. - * - * For instance if we change a pipelines ->layer_differences list - * then that pipeline and all of its descendants may now have - * incorrect layer caches. */ -static void -recursively_free_layer_caches (CoglPipeline *pipeline) -{ - /* Note: we maintain the invariable that if a pipeline already has a - * dirty layers_cache then so do all of its descendants. */ - if (pipeline->layers_cache_dirty) - return; - - if (G_UNLIKELY (pipeline->layers_cache != pipeline->short_layers_cache)) - g_free (pipeline->layers_cache); - pipeline->layers_cache_dirty = TRUE; - - _cogl_pipeline_node_foreach_child (COGL_NODE (pipeline), - recursively_free_layer_caches_cb, - NULL); -} - -static void -_cogl_pipeline_set_parent (CoglPipeline *pipeline, - CoglPipeline *parent, - gboolean take_strong_reference) -{ - /* Chain up */ - _cogl_pipeline_node_set_parent_real (COGL_NODE (pipeline), - COGL_NODE (parent), - take_strong_reference); - - /* Since we just changed the ancestry of the pipeline its cache of - * layers could now be invalid so free it... */ - if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS) - recursively_free_layer_caches (pipeline); -} - -static void -_cogl_pipeline_promote_weak_ancestors (CoglPipeline *strong) -{ - CoglNode *n; - - g_return_if_fail (!strong->is_weak); - - /* If the parent of strong is weak, then we want to promote it by - taking a reference on strong's grandparent. We don't need to take - a reference on strong's direct parent */ - - if (COGL_NODE (strong)->parent == NULL) - return; - - for (n = COGL_NODE (strong)->parent; - /* We can assume that all weak pipelines have a parent */ - COGL_PIPELINE (n)->is_weak; - n = n->parent) - /* 'n' is weak so we take a reference on its parent */ - g_object_ref (n->parent); -} - -/* XXX: Always have an eye out for opportunities to lower the cost of - * cogl_pipeline_copy. */ -static CoglPipeline * -_cogl_pipeline_copy (CoglPipeline *src, gboolean is_weak) -{ - CoglPipeline *pipeline = g_object_new (COGL_TYPE_PIPELINE, NULL); - - pipeline->context = src->context; - - /* NB: real_blend_enable isn't a sparse property, it's valid for - * every pipeline node so we have fast access to it. */ - pipeline->real_blend_enable = src->real_blend_enable; - pipeline->dirty_real_blend_enable = src->dirty_real_blend_enable; - pipeline->unknown_color_alpha = src->unknown_color_alpha; - - /* XXX: - * consider generalizing the idea of "cached" properties. These - * would still have an authority like other sparse properties but - * you wouldn't have to walk up the ancestry to find the authority - * because the value would be cached directly in each pipeline. - */ - pipeline->layers_cache_dirty = TRUE; - - _cogl_pipeline_set_parent (pipeline, src, !is_weak); - - /* The semantics for copying a weak pipeline are that we promote all - * weak ancestors to temporarily become strong pipelines until the - * copy is freed. */ - if (!is_weak) - _cogl_pipeline_promote_weak_ancestors (pipeline); - - return pipeline; -} - -CoglPipeline * -cogl_pipeline_copy (CoglPipeline *src) -{ - return _cogl_pipeline_copy (src, FALSE); -} - -CoglPipeline * -_cogl_pipeline_weak_copy (CoglPipeline *pipeline, - CoglPipelineDestroyCallback callback, - void *user_data) -{ - CoglPipeline *copy; - - copy = _cogl_pipeline_copy (pipeline, TRUE); - copy->destroy_callback = callback; - copy->destroy_data = user_data; - - return copy; -} - -CoglPipeline * -cogl_pipeline_new (CoglContext *context) -{ - CoglPipeline *new = cogl_pipeline_copy (context->default_pipeline); - -#ifdef COGL_ENABLE_DEBUG - _cogl_pipeline_set_static_breadcrumb (new, "new"); -#endif - return new; -} - -gboolean -_cogl_pipeline_get_real_blend_enabled (CoglPipeline *pipeline) -{ - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), FALSE); - - return pipeline->real_blend_enable; -} - -static void -_cogl_pipeline_update_layers_cache (CoglPipeline *pipeline) -{ - /* Note: we assume this pipeline is a _LAYERS authority */ - int n_layers; - CoglPipeline *current; - int layers_found; - - if (G_LIKELY (!pipeline->layers_cache_dirty) || - pipeline->n_layers == 0) - return; - - pipeline->layers_cache_dirty = FALSE; - - n_layers = pipeline->n_layers; - if (G_LIKELY (n_layers < G_N_ELEMENTS (pipeline->short_layers_cache))) - { - pipeline->layers_cache = pipeline->short_layers_cache; - memset (pipeline->layers_cache, 0, - sizeof (CoglPipelineLayer *) * - G_N_ELEMENTS (pipeline->short_layers_cache)); - } - else - { - pipeline->layers_cache = - g_malloc0 (sizeof (CoglPipelineLayer *) * n_layers); - } - - /* Notes: - * - * Each pipeline doesn't have to contain a complete list of the layers - * it depends on, some of them are indirectly referenced through the - * pipeline's ancestors. - * - * pipeline->layer_differences only contains a list of layers that - * have changed in relation to its parent. - * - * pipeline->layer_differences is not maintained sorted, but it - * won't contain multiple layers corresponding to a particular - * ->unit_index. - * - * Some of the ancestor pipelines may reference layers with - * ->unit_index values >= n_layers so we ignore them. - * - * As we ascend through the ancestors we are searching for any - * CoglPipelineLayers corresponding to the texture ->unit_index - * values in the range [0,n_layers-1]. As soon as a pointer is found - * we ignore layers of further ancestors with the same ->unit_index - * values. - */ - - layers_found = 0; - for (current = pipeline; - _cogl_pipeline_get_parent (current); - current = _cogl_pipeline_get_parent (current)) - { - GList *l; - - if (!(current->differences & COGL_PIPELINE_STATE_LAYERS)) - continue; - - for (l = current->layer_differences; l; l = l->next) - { - CoglPipelineLayer *layer = l->data; - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - - if (unit_index < n_layers && !pipeline->layers_cache[unit_index]) - { - pipeline->layers_cache[unit_index] = layer; - layers_found++; - if (layers_found == n_layers) - return; - } - } - } - - g_warn_if_reached (); -} - -/* XXX: Be careful when using this API that the callback given doesn't result - * in the layer cache being invalidated during the iteration! */ -void -_cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline, - CoglPipelineInternalLayerCallback callback, - void *user_data) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - int n_layers; - int i; - gboolean cont; - - n_layers = authority->n_layers; - if (n_layers == 0) - return; - - _cogl_pipeline_update_layers_cache (authority); - - for (i = 0, cont = TRUE; i < n_layers && cont == TRUE; i++) - { - g_return_if_fail (authority->layers_cache_dirty == FALSE); - cont = callback (authority->layers_cache[i], user_data); - } -} - -gboolean -_cogl_pipeline_layer_numbers_equal (CoglPipeline *pipeline0, - CoglPipeline *pipeline1) -{ - CoglPipeline *authority0 = - _cogl_pipeline_get_authority (pipeline0, COGL_PIPELINE_STATE_LAYERS); - CoglPipeline *authority1 = - _cogl_pipeline_get_authority (pipeline1, COGL_PIPELINE_STATE_LAYERS); - int n_layers = authority0->n_layers; - int i; - - if (authority1->n_layers != n_layers) - return FALSE; - - _cogl_pipeline_update_layers_cache (authority0); - _cogl_pipeline_update_layers_cache (authority1); - - for (i = 0; i < n_layers; i++) - { - CoglPipelineLayer *layer0 = authority0->layers_cache[i]; - CoglPipelineLayer *layer1 = authority1->layers_cache[i]; - - if (layer0->index != layer1->index) - return FALSE; - } - - return TRUE; -} - -gboolean -_cogl_pipeline_layer_and_unit_numbers_equal (CoglPipeline *pipeline0, - CoglPipeline *pipeline1) -{ - CoglPipeline *authority0 = - _cogl_pipeline_get_authority (pipeline0, COGL_PIPELINE_STATE_LAYERS); - CoglPipeline *authority1 = - _cogl_pipeline_get_authority (pipeline1, COGL_PIPELINE_STATE_LAYERS); - int n_layers = authority0->n_layers; - int i; - - if (authority1->n_layers != n_layers) - return FALSE; - - _cogl_pipeline_update_layers_cache (authority0); - _cogl_pipeline_update_layers_cache (authority1); - - for (i = 0; i < n_layers; i++) - { - CoglPipelineLayer *layer0 = authority0->layers_cache[i]; - CoglPipelineLayer *layer1 = authority1->layers_cache[i]; - int unit0, unit1; - - if (layer0->index != layer1->index) - return FALSE; - - unit0 = _cogl_pipeline_layer_get_unit_index (layer0); - unit1 = _cogl_pipeline_layer_get_unit_index (layer1); - if (unit0 != unit1) - return FALSE; - } - - return TRUE; -} - -typedef struct -{ - int i; - int *indices; -} AppendLayerIndexState; - -static gboolean -append_layer_index_cb (CoglPipelineLayer *layer, - void *user_data) -{ - AppendLayerIndexState *state = user_data; - state->indices[state->i++] = layer->index; - return TRUE; -} - -void -cogl_pipeline_foreach_layer (CoglPipeline *pipeline, - CoglPipelineLayerCallback callback, - void *user_data) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - AppendLayerIndexState state; - gboolean cont; - int i; - - /* XXX: We don't know what the user is going to want to do to the layers - * but any modification of layers can result in the layer graph changing - * which could confuse _cogl_pipeline_foreach_layer_internal(). We first - * get a list of layer indices which will remain valid so long as the - * user doesn't remove layers. */ - - state.i = 0; - state.indices = g_alloca (authority->n_layers * sizeof (int)); - - _cogl_pipeline_foreach_layer_internal (pipeline, - append_layer_index_cb, - &state); - - for (i = 0, cont = TRUE; i < authority->n_layers && cont; i++) - cont = callback (pipeline, state.indices[i], user_data); -} - -static gboolean -layer_has_alpha_cb (CoglPipelineLayer *layer, void *data) -{ - gboolean *has_alpha = data; - *has_alpha = _cogl_pipeline_layer_has_alpha (layer); - - /* return FALSE to stop iterating layers if we find any layer - * has alpha ... - * - * FIXME: actually we should never be bailing out because it's - * always possible that a later layer could discard any previous - * alpha! - */ - - return !(*has_alpha); -} - -/* NB: If this pipeline returns FALSE that doesn't mean that the - * pipeline is definitely opaque, it just means that that the - * given changes dont imply transparency. - * - * If you want to find out of the pipeline is opaque then assuming - * this returns FALSE for a set of changes then you can follow - * up - */ -static gboolean -_cogl_pipeline_change_implies_transparency (CoglPipeline *pipeline, - unsigned int changes, - const CoglColor *override_color, - gboolean unknown_color_alpha) -{ - /* In the case of a layer state change we need to check everything - * else first since they contribute to the has_alpha status of the - * "PREVIOUS" layer. */ - if (changes & COGL_PIPELINE_STATE_LAYERS) - changes = COGL_PIPELINE_STATE_AFFECTS_BLENDING; - - if (unknown_color_alpha) - return TRUE; - - if (override_color && - !G_APPROX_VALUE (cogl_color_get_alpha (override_color), 1.0, FLT_EPSILON)) - return TRUE; - - if (changes & COGL_PIPELINE_STATE_COLOR) - { - CoglColor tmp; - cogl_pipeline_get_color (pipeline, &tmp); - if (!G_APPROX_VALUE (cogl_color_get_alpha (&tmp), 1.0, FLT_EPSILON)) - return TRUE; - } - - if (changes & COGL_PIPELINE_STATE_USER_SHADER) - { - /* We can't make any assumptions about the alpha channel if the user - * is using an unknown fragment shader. - * - * TODO: check that it isn't just a vertex shader! - */ - if (cogl_pipeline_get_user_program (pipeline) != NULL) - return TRUE; - } - - if (changes & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS) - { - if (_cogl_pipeline_has_non_layer_fragment_snippets (pipeline)) - return TRUE; - } - - if (changes & COGL_PIPELINE_STATE_VERTEX_SNIPPETS) - { - if (_cogl_pipeline_has_non_layer_vertex_snippets (pipeline)) - return TRUE; - } - - if (changes & COGL_PIPELINE_STATE_LAYERS) - { - /* has_alpha tracks the alpha status of the GL_PREVIOUS layer. - * To start with that's defined by the pipeline color which - * must be fully opaque if we got this far. */ - gboolean has_alpha = FALSE; - _cogl_pipeline_foreach_layer_internal (pipeline, - layer_has_alpha_cb, - &has_alpha); - if (has_alpha) - return TRUE; - } - - return FALSE; -} - -static gboolean -_cogl_pipeline_needs_blending_enabled (CoglPipeline *pipeline, - unsigned int changes, - const CoglColor *override_color, - gboolean unknown_color_alpha) -{ - CoglPipeline *blend_authority; - CoglPipelineBlendState *blend_state; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_BLENDING))) - return FALSE; - - blend_authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND); - - blend_state = &blend_authority->big_state->blend_state; - - /* We are trying to identify some cases that are equivalent to - * blending being disable, where the output is simply GL_SRC_COLOR. - * - * Note: we currently only consider a few cases that can be - * optimized but there could be opportunities to special case more - * blend functions later. - */ - - /* As the most common way that we currently use to effectively - * disable blending is to use an equation of - * "RGBA=ADD(SRC_COLOR, 0)" that's the first thing we check - * for... */ - if (blend_state->blend_equation_rgb == GL_FUNC_ADD && - blend_state->blend_equation_alpha == GL_FUNC_ADD && - blend_state->blend_src_factor_alpha == GL_ONE && - blend_state->blend_dst_factor_alpha == GL_ZERO) - { - return FALSE; - } - - /* NB: The default blending equation for Cogl is - * "RGBA=ADD(SRC_COLOR, DST_COLOR * (1-SRC_COLOR[A]))" - * - * Next we check if the default blending equation is being used. If - * so then we follow that by looking for cases where SRC_COLOR[A] == - * 1 since that simplifies "DST_COLOR * (1-SRC_COLOR[A])" to 0 which - * also effectively requires no blending. - */ - - if (blend_state->blend_equation_rgb != GL_FUNC_ADD || - blend_state->blend_equation_alpha != GL_FUNC_ADD) - return TRUE; - - if (blend_state->blend_src_factor_alpha != GL_ONE || - blend_state->blend_dst_factor_alpha != GL_ONE_MINUS_SRC_ALPHA) - return TRUE; - - if (blend_state->blend_src_factor_rgb != GL_ONE || - blend_state->blend_dst_factor_rgb != GL_ONE_MINUS_SRC_ALPHA) - return TRUE; - - /* Given the above constraints, it's now a case of finding any - * SRC_ALPHA that != 1 */ - - if (_cogl_pipeline_change_implies_transparency (pipeline, changes, - override_color, - unknown_color_alpha)) - return TRUE; - - /* At this point, considering just the state that has changed it - * looks like blending isn't needed. If blending was previously - * enabled though it could be that some other state still requires - * that we have blending enabled because it implies transparency. - * In this case we still need to go and check the other state... - * - * XXX: We could explicitly keep track of the mask of state groups - * that are currently causing blending to be enabled so that we - * never have to resort to checking *all* the state and can instead - * always limit the check to those in the mask. - */ - if (pipeline->real_blend_enable) - { - unsigned int other_state = - COGL_PIPELINE_STATE_AFFECTS_BLENDING & ~changes; - if (other_state && - _cogl_pipeline_change_implies_transparency (pipeline, other_state, NULL, FALSE)) - return TRUE; - } - - return FALSE; -} - -static void -_cogl_pipeline_copy_differences (CoglPipeline *dest, - CoglPipeline *src, - unsigned long differences) -{ - CoglPipelineBigState *big_state; - - if (differences & COGL_PIPELINE_STATE_COLOR) - dest->color = src->color; - - if (differences & COGL_PIPELINE_STATE_LAYERS) - { - GList *l; - - if (dest->differences & COGL_PIPELINE_STATE_LAYERS && - dest->layer_differences) - g_list_free_full (dest->layer_differences, g_object_unref); - - for (l = src->layer_differences; l; l = l->next) - { - /* NB: a layer can't have more than one ->owner so we can't - * simply take a references on each of the original - * layer_differences, we have to derive new layers from the - * originals instead. */ - CoglPipelineLayer *copy = _cogl_pipeline_layer_copy (l->data); - _cogl_pipeline_add_layer_difference (dest, copy, FALSE); - g_object_unref (copy); - } - - /* Note: we initialize n_layers after adding the layer differences - * since the act of adding the layers will initialize n_layers to 0 - * because dest isn't initially a STATE_LAYERS authority. */ - dest->n_layers = src->n_layers; - } - - if (differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE) - { - if (!dest->has_big_state) - { - dest->big_state = g_new0 (CoglPipelineBigState, 1); - dest->has_big_state = TRUE; - } - big_state = dest->big_state; - } - else - goto check_for_blending_change; - - if (differences & COGL_PIPELINE_STATE_ALPHA_FUNC) - big_state->alpha_state.alpha_func = - src->big_state->alpha_state.alpha_func; - - if (differences & COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE) - big_state->alpha_state.alpha_func_reference = - src->big_state->alpha_state.alpha_func_reference; - - if (differences & COGL_PIPELINE_STATE_BLEND) - { - memcpy (&big_state->blend_state, - &src->big_state->blend_state, - sizeof (CoglPipelineBlendState)); - } - - if (differences & COGL_PIPELINE_STATE_USER_SHADER) - { - if (src->big_state->user_program) - big_state->user_program = - g_object_ref (src->big_state->user_program); - else - big_state->user_program = NULL; - } - - if (differences & COGL_PIPELINE_STATE_DEPTH) - { - memcpy (&big_state->depth_state, - &src->big_state->depth_state, - sizeof (CoglDepthState)); - } - - if (differences & COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE) - big_state->non_zero_point_size = src->big_state->non_zero_point_size; - - if (differences & COGL_PIPELINE_STATE_POINT_SIZE) - big_state->point_size = src->big_state->point_size; - - if (differences & COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE) - big_state->per_vertex_point_size = src->big_state->per_vertex_point_size; - - if (differences & COGL_PIPELINE_STATE_CULL_FACE) - { - memcpy (&big_state->cull_face_state, - &src->big_state->cull_face_state, - sizeof (CoglPipelineCullFaceState)); - } - - if (differences & COGL_PIPELINE_STATE_UNIFORMS) - { - int n_overrides = - _cogl_bitmask_popcount (&src->big_state->uniforms_state.override_mask); - int i; - - big_state->uniforms_state.override_values = - g_malloc (n_overrides * sizeof (CoglBoxedValue)); - - for (i = 0; i < n_overrides; i++) - { - CoglBoxedValue *dst_bv = - big_state->uniforms_state.override_values + i; - const CoglBoxedValue *src_bv = - src->big_state->uniforms_state.override_values + i; - - _cogl_boxed_value_copy (dst_bv, src_bv); - } - - _cogl_bitmask_init (&big_state->uniforms_state.override_mask); - _cogl_bitmask_set_bits (&big_state->uniforms_state.override_mask, - &src->big_state->uniforms_state.override_mask); - - _cogl_bitmask_init (&big_state->uniforms_state.changed_mask); - } - - if (differences & COGL_PIPELINE_STATE_VERTEX_SNIPPETS) - _cogl_pipeline_snippet_list_copy (&big_state->vertex_snippets, - &src->big_state->vertex_snippets); - - if (differences & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS) - _cogl_pipeline_snippet_list_copy (&big_state->fragment_snippets, - &src->big_state->fragment_snippets); - - /* XXX: we shouldn't bother doing this in most cases since - * _copy_differences is typically used to initialize pipeline state - * by copying it from the current authority, so it's not actually - * *changing* anything. - */ -check_for_blending_change: - if (differences & COGL_PIPELINE_STATE_AFFECTS_BLENDING) - dest->dirty_real_blend_enable = TRUE; - - dest->differences |= differences; -} - -static void -_cogl_pipeline_init_multi_property_sparse_state (CoglPipeline *pipeline, - CoglPipelineState change) -{ - CoglPipeline *authority; - - g_return_if_fail (change & COGL_PIPELINE_STATE_ALL_SPARSE); - - if (!(change & COGL_PIPELINE_STATE_MULTI_PROPERTY)) - return; - - authority = _cogl_pipeline_get_authority (pipeline, change); - - switch (change) - { - /* XXX: avoid using a default: label so we get a warning if we - * don't explicitly handle a newly defined state-group here. */ - case COGL_PIPELINE_STATE_COLOR: - case COGL_PIPELINE_STATE_ALPHA_FUNC: - case COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE: - case COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE: - case COGL_PIPELINE_STATE_POINT_SIZE: - case COGL_PIPELINE_STATE_USER_SHADER: - case COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE: - case COGL_PIPELINE_STATE_REAL_BLEND_ENABLE: - g_return_if_reached (); - - case COGL_PIPELINE_STATE_LAYERS: - pipeline->n_layers = authority->n_layers; - pipeline->layer_differences = NULL; - break; - case COGL_PIPELINE_STATE_BLEND: - { - memcpy (&pipeline->big_state->blend_state, - &authority->big_state->blend_state, - sizeof (CoglPipelineBlendState)); - break; - } - case COGL_PIPELINE_STATE_DEPTH: - { - memcpy (&pipeline->big_state->depth_state, - &authority->big_state->depth_state, - sizeof (CoglDepthState)); - break; - } - case COGL_PIPELINE_STATE_CULL_FACE: - { - memcpy (&pipeline->big_state->cull_face_state, - &authority->big_state->cull_face_state, - sizeof (CoglPipelineCullFaceState)); - break; - } - case COGL_PIPELINE_STATE_UNIFORMS: - { - CoglPipelineUniformsState *uniforms_state = - &pipeline->big_state->uniforms_state; - _cogl_bitmask_init (&uniforms_state->override_mask); - _cogl_bitmask_init (&uniforms_state->changed_mask); - uniforms_state->override_values = NULL; - break; - } - case COGL_PIPELINE_STATE_VERTEX_SNIPPETS: - _cogl_pipeline_snippet_list_copy (&pipeline->big_state->vertex_snippets, - &authority->big_state->vertex_snippets); - break; - - case COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS: - _cogl_pipeline_snippet_list_copy (&pipeline->big_state->fragment_snippets, - &authority->big_state-> - fragment_snippets); - break; - } -} - -static gboolean -check_if_strong_cb (CoglNode *node, void *user_data) -{ - CoglPipeline *pipeline = COGL_PIPELINE (node); - gboolean *has_strong_child = user_data; - - if (!_cogl_pipeline_is_weak (pipeline)) - { - *has_strong_child = TRUE; - return FALSE; - } - - return TRUE; -} - -static gboolean -has_strong_children (CoglPipeline *pipeline) -{ - gboolean has_strong_child = FALSE; - _cogl_pipeline_node_foreach_child (COGL_NODE (pipeline), - check_if_strong_cb, - &has_strong_child); - return has_strong_child; -} - -static gboolean -_cogl_pipeline_is_weak (CoglPipeline *pipeline) -{ - if (pipeline->is_weak && !has_strong_children (pipeline)) - return TRUE; - else - return FALSE; -} - -static gboolean -reparent_children_cb (CoglNode *node, - void *user_data) -{ - CoglPipeline *pipeline = COGL_PIPELINE (node); - CoglPipeline *parent = user_data; - - _cogl_pipeline_set_parent (pipeline, parent, TRUE); - - return TRUE; -} - -void -_cogl_pipeline_pre_change_notify (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color, - gboolean from_layer_change) -{ - CoglContext *ctx = pipeline->context; - - /* If primitives have been logged in the journal referencing the - * current state of this pipeline we need to flush the journal - * before we can modify it... */ - if (pipeline->journal_ref_count) - { - gboolean skip_journal_flush = FALSE; - - /* XXX: We don't usually need to flush the journal just due to - * color changes since pipeline colors are logged in the - * journal's vertex buffer. The exception is when the change in - * color enables or disables the need for blending. */ - if (change == COGL_PIPELINE_STATE_COLOR) - { - gboolean will_need_blending = - _cogl_pipeline_needs_blending_enabled (pipeline, - change, - new_color, - FALSE); - gboolean blend_enable = pipeline->real_blend_enable ? TRUE : FALSE; - - if (will_need_blending == blend_enable) - skip_journal_flush = TRUE; - } - - if (!skip_journal_flush) - { - /* XXX: note we use cogl_flush() not _cogl_flush_journal() so - * we will flush *all* known journals that might reference the - * current pipeline. */ - cogl_flush (); - } - } - - /* XXX: - * To simplify things for the vertex, fragment and program backends - * we are careful about how we report STATE_LAYERS changes. - * - * All STATE_LAYERS change notifications with the exception of - * ->n_layers will also result in layer_pre_change_notifications. - * - * For backends that perform code generation for fragment processing - * they typically need to understand the details of how layers get - * changed to determine if they need to repeat codegen. It doesn't - * help them to report a pipeline STATE_LAYERS change for all layer - * changes since it's so broad, they really need to wait for the - * specific layer change to be notified. What does help though is - * to report a STATE_LAYERS change for a change in ->n_layers - * because they typically do need to repeat codegen in that case. - * - * Here we ensure that change notifications against a pipeline or - * against a layer are mutually exclusive as far as fragment, vertex - * and program backends are concerned. - * - * NB: A pipeline can potentially have private state from multiple - * backends associated with it because descendants may cache state - * with an ancestor to maximize the chance that it can later be - * re-used by other descendants and a descendent can require a - * different backend to an ancestor. - */ - if (!from_layer_change) - { - const CoglPipelineProgend *progend = _cogl_pipeline_progend; - const CoglPipelineVertend *vertend = _cogl_pipeline_vertend; - const CoglPipelineFragend *fragend = _cogl_pipeline_fragend; - - if (vertend->pipeline_pre_change_notify) - vertend->pipeline_pre_change_notify (pipeline, change, new_color); - - /* TODO: make the vertend and fragend implementation details - * of the progend */ - - if (fragend->pipeline_pre_change_notify) - fragend->pipeline_pre_change_notify (pipeline, change, new_color); - - if (progend->pipeline_pre_change_notify) - progend->pipeline_pre_change_notify (pipeline, change, new_color); - } - - /* There may be an arbitrary tree of descendants of this pipeline; - * any of which may indirectly depend on this pipeline as the - * authority for some set of properties. (Meaning for example that - * one of its descendants derives its color or blending state from - * this pipeline.) - * - * We can't modify any property that this pipeline is the authority - * for unless we create another pipeline to take its place first and - * make sure descendants reference this new pipeline instead. - */ - - /* The simplest descendants to handle are weak pipelines; we simply - * destroy them if we are modifying a pipeline they depend on. This - * means weak pipelines never cause us to do a copy-on-write. */ - _cogl_pipeline_node_foreach_child (COGL_NODE (pipeline), - destroy_weak_children_cb, - NULL); - - /* If there are still children remaining though we'll need to - * perform a copy-on-write and reparent the dependants as children - * of the copy. */ - if (!_cogl_list_empty (&COGL_NODE (pipeline)->children)) - { - CoglPipeline *new_authority; - - COGL_STATIC_COUNTER (pipeline_copy_on_write_counter, - "pipeline copy on write counter", - "Increments each time a pipeline " - "must be copied to allow modification", - 0 /* no application private data */); - - COGL_COUNTER_INC (_cogl_uprof_context, pipeline_copy_on_write_counter); - - new_authority = - cogl_pipeline_copy (_cogl_pipeline_get_parent (pipeline)); -#ifdef COGL_ENABLE_DEBUG - _cogl_pipeline_set_static_breadcrumb (new_authority, - "pre_change_notify:copy-on-write"); -#endif - - /* We could explicitly walk the descendants, OR together the set - * of differences that we determine this pipeline is the - * authority on and only copy those differences copied across. - * - * Or, if we don't explicitly walk the descendants we at least - * know that pipeline->differences represents the largest set of - * differences that this pipeline could possibly be an authority - * on. - * - * We do the later just because it's simplest, but we might need - * to come back to this later... - */ - _cogl_pipeline_copy_differences (new_authority, pipeline, - pipeline->differences); - - /* Reparent the dependants of pipeline to be children of - * new_authority instead... */ - _cogl_pipeline_node_foreach_child (COGL_NODE (pipeline), - reparent_children_cb, - new_authority); - - /* The children will keep the new authority alive so drop the - * reference we got when copying... */ - g_object_unref (new_authority); - } - - /* At this point we know we have a pipeline with no strong - * dependants (though we may have some weak children) so we are now - * free to modify the pipeline. */ - - pipeline->age++; - - if (change & COGL_PIPELINE_STATE_NEEDS_BIG_STATE && - !pipeline->has_big_state) - { - pipeline->big_state = g_new0 (CoglPipelineBigState, 1); - pipeline->has_big_state = TRUE; - } - - /* Note: conceptually we have just been notified that a single - * property value is about to change, but since some state-groups - * contain multiple properties and 'pipeline' is about to take over - * being the authority for the property's corresponding state-group - * we need to maintain the integrity of the other property values - * too. - * - * To ensure this we handle multi-property state-groups by copying - * all the values from the old-authority to the new... - * - * We don't have to worry about non-sparse property groups since - * we never take over being an authority for such properties so - * they automatically maintain integrity. - */ - if (change & COGL_PIPELINE_STATE_ALL_SPARSE && - !(pipeline->differences & change)) - { - _cogl_pipeline_init_multi_property_sparse_state (pipeline, change); - pipeline->differences |= change; - } - - /* Each pipeline has a sorted cache of the layers it depends on - * which will need updating via _cogl_pipeline_update_layers_cache - * if a pipeline's layers are changed. */ - if (change == COGL_PIPELINE_STATE_LAYERS) - recursively_free_layer_caches (pipeline); - - /* If the pipeline being changed is the same as the last pipeline we - * flushed then we keep a track of the changes so we can try to - * minimize redundant OpenGL calls if the same pipeline is flushed - * again. - */ - if (ctx->current_pipeline == pipeline) - ctx->current_pipeline_changes_since_flush |= change; -} - - -void -_cogl_pipeline_add_layer_difference (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - gboolean inc_n_layers) -{ - g_return_if_fail (layer->owner == NULL); - - layer->owner = pipeline; - g_object_ref (layer); - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - /* Note: the last argument to _cogl_pipeline_pre_change_notify is - * needed to differentiate STATE_LAYER changes which don't affect - * the number of layers from those that do. NB: Layer change - * notifications that don't change the number of layers don't get - * forwarded to the fragend. */ - _cogl_pipeline_pre_change_notify (pipeline, - COGL_PIPELINE_STATE_LAYERS, - NULL, - !inc_n_layers); - - pipeline->differences |= COGL_PIPELINE_STATE_LAYERS; - - pipeline->layer_differences = - g_list_prepend (pipeline->layer_differences, layer); - - if (inc_n_layers) - pipeline->n_layers++; - - /* Adding a layer difference may mean this pipeline now overrides - * all of the layers of its parent which might make the parent - * redundant so we should try to prune the hierarchy */ - _cogl_pipeline_prune_redundant_ancestry (pipeline); -} - -void -_cogl_pipeline_remove_layer_difference (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - gboolean dec_n_layers) -{ - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - /* Note: the last argument to _cogl_pipeline_pre_change_notify is - * needed to differentiate STATE_LAYER changes which don't affect - * the number of layers from those that do. NB: Layer change - * notifications that don't change the number of layers don't get - * forwarded to the fragend. */ - _cogl_pipeline_pre_change_notify (pipeline, - COGL_PIPELINE_STATE_LAYERS, - NULL, - !dec_n_layers); - - /* We only need to remove the layer difference if the pipeline is - * currently the owner. If it is not the owner then one of two - * things will happen to make sure this layer is replaced. If it is - * the last layer being removed then decrementing n_layers will - * ensure that the last layer is skipped. If it is any other layer - * then the subsequent layers will have been shifted down and cause - * it be replaced */ - if (layer->owner == pipeline) - { - layer->owner = NULL; - g_object_unref (layer); - - pipeline->layer_differences = - g_list_remove (pipeline->layer_differences, layer); - } - - pipeline->differences |= COGL_PIPELINE_STATE_LAYERS; - - if (dec_n_layers) - pipeline->n_layers--; -} - -static void -_cogl_pipeline_try_reverting_layers_authority (CoglPipeline *authority, - CoglPipeline *old_authority) -{ - if (authority->layer_differences == NULL && - _cogl_pipeline_get_parent (authority)) - { - /* If the previous _STATE_LAYERS authority has the same - * ->n_layers then we can revert to that being the authority - * again. */ - if (!old_authority) - { - old_authority = - _cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority), - COGL_PIPELINE_STATE_LAYERS); - } - - if (old_authority->n_layers == authority->n_layers) - authority->differences &= ~COGL_PIPELINE_STATE_LAYERS; - } -} - -void -_cogl_pipeline_update_real_blend_enable (CoglPipeline *pipeline, - gboolean unknown_color_alpha) -{ - CoglPipeline *parent; - unsigned int differences; - - if (pipeline->dirty_real_blend_enable == FALSE && - pipeline->unknown_color_alpha == unknown_color_alpha) - return; - - if (pipeline->dirty_real_blend_enable) - { - differences = pipeline->differences; - - parent = _cogl_pipeline_get_parent (pipeline); - while (parent->dirty_real_blend_enable) - { - differences |= parent->differences; - parent = _cogl_pipeline_get_parent (parent); - } - - /* We initialize the pipeline's real_blend_enable with a known - * reference value from its nearest ancestor with clean state so - * we can then potentially reduce the work involved in checking - * if the pipeline really needs blending itself because we can - * just look at the things that differ between the ancestor and - * this pipeline. - */ - pipeline->real_blend_enable = parent->real_blend_enable; - } - else /* pipeline->unknown_color_alpha != unknown_color_alpha */ - differences = 0; - - /* Note we don't call _cogl_pipeline_pre_change_notify() for this - * state change because ->real_blend_enable is lazily derived from - * other state while flushing the pipeline and we'd need to avoid - * recursion problems in cases where _pre_change_notify() flushes - * the journal if the pipeline is referenced by a journal. - */ - pipeline->real_blend_enable = - _cogl_pipeline_needs_blending_enabled (pipeline, differences, - NULL, unknown_color_alpha); - pipeline->dirty_real_blend_enable = FALSE; - pipeline->unknown_color_alpha = unknown_color_alpha; -} - -typedef struct -{ - int keep_n; - int current_pos; - int first_index_to_prune; -} CoglPipelinePruneLayersInfo; - -static gboolean -update_prune_layers_info_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglPipelinePruneLayersInfo *state = user_data; - - if (state->current_pos == state->keep_n) - { - state->first_index_to_prune = layer->index; - return FALSE; - } - state->current_pos++; - return TRUE; -} - -void -_cogl_pipeline_prune_to_n_layers (CoglPipeline *pipeline, int n) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - CoglPipelinePruneLayersInfo state; - GList *l; - GList *next; - - if (authority->n_layers <= n) - return; - - /* This call to foreach_layer_internal needs to be done before - * calling pre_change_notify because it recreates the layer cache. - * We are relying on pre_change_notify to clear the layer cache - * before we change the number of layers */ - state.keep_n = n; - state.current_pos = 0; - state.first_index_to_prune = 0; - _cogl_pipeline_foreach_layer_internal (pipeline, - update_prune_layers_info_cb, - &state); - - _cogl_pipeline_pre_change_notify (pipeline, - COGL_PIPELINE_STATE_LAYERS, - NULL, - FALSE); - - pipeline->differences |= COGL_PIPELINE_STATE_LAYERS; - pipeline->n_layers = n; - - /* It's possible that this pipeline owns some of the layers being - * discarded, so we'll need to unlink them... */ - for (l = pipeline->layer_differences; l; l = next) - { - CoglPipelineLayer *layer = l->data; - next = l->next; /* we're modifying the list we're iterating */ - - if (layer->index >= state.first_index_to_prune) - _cogl_pipeline_remove_layer_difference (pipeline, layer, FALSE); - } - - pipeline->differences |= COGL_PIPELINE_STATE_LAYERS; -} - -typedef struct -{ - /* The layer we are trying to find */ - int layer_index; - - /* The layer we find or untouched if not found */ - CoglPipelineLayer *layer; - - /* If the layer can't be found then a new layer should be - * inserted after this texture unit index... */ - int insert_after; - - /* When adding a layer we need the list of layers to shift up - * to a new texture unit. When removing we need the list of - * layers to shift down. - * - * Note: the list isn't sorted */ - CoglPipelineLayer **layers_to_shift; - int n_layers_to_shift; - - /* When adding a layer we don't need a complete list of - * layers_to_shift if we find a layer already corresponding to the - * layer_index. */ - gboolean ignore_shift_layers_if_found; - -} CoglPipelineLayerInfo; - -/* Returns TRUE once we know there is nothing more to update */ -static gboolean -update_layer_info (CoglPipelineLayer *layer, - CoglPipelineLayerInfo *layer_info) -{ - if (layer->index == layer_info->layer_index) - { - layer_info->layer = layer; - if (layer_info->ignore_shift_layers_if_found) - return TRUE; - } - else if (layer->index < layer_info->layer_index) - { - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - layer_info->insert_after = unit_index; - } - else - layer_info->layers_to_shift[layer_info->n_layers_to_shift++] = - layer; - - return FALSE; -} - -/* Returns FALSE to break out of a _foreach_layer () iteration */ -static gboolean -update_layer_info_cb (CoglPipelineLayer *layer, - void *user_data) -{ - CoglPipelineLayerInfo *layer_info = user_data; - - if (update_layer_info (layer, layer_info)) - return FALSE; /* break */ - else - return TRUE; /* continue */ -} - -static void -_cogl_pipeline_get_layer_info (CoglPipeline *pipeline, - CoglPipelineLayerInfo *layer_info) -{ - /* Note: we are assuming this pipeline is a _STATE_LAYERS authority */ - int n_layers = pipeline->n_layers; - int i; - - /* FIXME: _cogl_pipeline_foreach_layer_internal now calls - * _cogl_pipeline_update_layers_cache anyway so this codepath is - * pointless! */ - if (layer_info->ignore_shift_layers_if_found && - pipeline->layers_cache_dirty) - { - /* The expectation is that callers of - * _cogl_pipeline_get_layer_info are likely to be modifying the - * list of layers associated with a pipeline so in this case - * where we don't have a cache of the layers and we don't - * necessarily have to iterate all the layers of the pipeline we - * use a foreach_layer callback instead of updating the cache - * and iterating that as below. */ - _cogl_pipeline_foreach_layer_internal (pipeline, - update_layer_info_cb, - layer_info); - return; - } - - _cogl_pipeline_update_layers_cache (pipeline); - for (i = 0; i < n_layers; i++) - { - CoglPipelineLayer *layer = pipeline->layers_cache[i]; - - if (update_layer_info (layer, layer_info)) - return; - } -} - -CoglPipelineLayer * -_cogl_pipeline_get_layer_with_flags (CoglPipeline *pipeline, - int layer_index, - CoglPipelineGetLayerFlags flags) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - CoglPipelineLayerInfo layer_info; - CoglPipelineLayer *layer; - int unit_index; - int i; - CoglContext *ctx = pipeline->context; - - /* The layer index of the layer we want info about */ - layer_info.layer_index = layer_index; - - /* If a layer already exists with the given index this will be - * updated. */ - layer_info.layer = NULL; - - /* If a layer isn't found for the given index we'll need to know - * where to insert a new layer. */ - layer_info.insert_after = -1; - - /* If a layer can't be found then we'll need to insert a new layer - * and bump up the texture unit for all layers with an index - * > layer_index. */ - layer_info.layers_to_shift = - g_alloca (sizeof (CoglPipelineLayer *) * authority->n_layers); - layer_info.n_layers_to_shift = 0; - - /* If an exact match is found though we don't need a complete - * list of layers with indices > layer_index... */ - layer_info.ignore_shift_layers_if_found = TRUE; - - _cogl_pipeline_get_layer_info (authority, &layer_info); - - if (layer_info.layer || (flags & COGL_PIPELINE_GET_LAYER_NO_CREATE)) - return layer_info.layer; - - unit_index = layer_info.insert_after + 1; - if (unit_index == 0) - layer = _cogl_pipeline_layer_copy (ctx->default_layer_0); - else - { - CoglPipelineLayer *new; - layer = _cogl_pipeline_layer_copy (ctx->default_layer_n); - new = _cogl_pipeline_set_layer_unit (NULL, layer, unit_index); - /* Since we passed a newly allocated layer we wouldn't expect - * _set_layer_unit() to have to allocate *another* layer. */ - g_assert (new == layer); - } - layer->index = layer_index; - - for (i = 0; i < layer_info.n_layers_to_shift; i++) - { - CoglPipelineLayer *shift_layer = layer_info.layers_to_shift[i]; - - unit_index = _cogl_pipeline_layer_get_unit_index (shift_layer); - _cogl_pipeline_set_layer_unit (pipeline, shift_layer, unit_index + 1); - /* NB: shift_layer may not be writeable so _set_layer_unit() - * will allocate a derived layer internally which will become - * owned by pipeline. Check the return value if we need to do - * anything else with this layer. */ - } - - _cogl_pipeline_add_layer_difference (pipeline, layer, TRUE); - - g_object_unref (layer); - - return layer; -} - -void -_cogl_pipeline_prune_empty_layer_difference (CoglPipeline *layers_authority, - CoglPipelineLayer *layer) -{ - /* Find the GList link that references the empty layer */ - GList *link = g_list_find (layers_authority->layer_differences, layer); - /* No pipeline directly owns the root node layer so this is safe... */ - CoglPipelineLayer *layer_parent = _cogl_pipeline_layer_get_parent (layer); - CoglPipelineLayerInfo layer_info; - CoglPipeline *old_layers_authority; - - g_return_if_fail (link != NULL); - - /* If the layer's parent doesn't have an owner then we can simply - * take ownership ourselves and drop our reference on the empty - * layer. We don't want to take ownership of the root node layer so - * we also need to verify that the parent has a parent - */ - if (layer_parent->index == layer->index && layer_parent->owner == NULL && - _cogl_pipeline_layer_get_parent (layer_parent) != NULL) - { - g_object_ref (layer_parent); - layer_parent->owner = layers_authority; - link->data = layer_parent; - g_object_unref (layer); - recursively_free_layer_caches (layers_authority); - return; - } - - /* Now we want to find the layer that would become the authority for - * layer->index if we were to remove layer from - * layers_authority->layer_differences - */ - - /* The layer index of the layer we want info about */ - layer_info.layer_index = layer->index; - - /* If a layer already exists with the given index this will be - * updated. */ - layer_info.layer = NULL; - - /* If a layer can't be found then we'll need to insert a new layer - * and bump up the texture unit for all layers with an index - * > layer_index. */ - layer_info.layers_to_shift = - g_alloca (sizeof (CoglPipelineLayer *) * layers_authority->n_layers); - layer_info.n_layers_to_shift = 0; - - /* If an exact match is found though we don't need a complete - * list of layers with indices > layer_index... */ - layer_info.ignore_shift_layers_if_found = TRUE; - - /* We know the default/root pipeline isn't a LAYERS authority so it's - * safe to use the result of _cogl_pipeline_get_parent (layers_authority) - * without checking it. - */ - old_layers_authority = - _cogl_pipeline_get_authority (_cogl_pipeline_get_parent (layers_authority), - COGL_PIPELINE_STATE_LAYERS); - - _cogl_pipeline_get_layer_info (old_layers_authority, &layer_info); - - /* If layer is the defining layer for the corresponding ->index then - * we can't get rid of it. */ - if (!layer_info.layer) - return; - - /* If the layer that would become the authority for layer->index is - * _cogl_pipeline_layer_get_parent (layer) then we can simply remove the - * layer difference. */ - if (layer_info.layer == _cogl_pipeline_layer_get_parent (layer)) - { - _cogl_pipeline_remove_layer_difference (layers_authority, layer, FALSE); - _cogl_pipeline_try_reverting_layers_authority (layers_authority, - old_layers_authority); - } -} - -typedef struct -{ - int i; - CoglPipeline *pipeline; - unsigned long fallback_layers; -} CoglPipelineFallbackState; - -static gboolean -fallback_layer_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglPipelineFallbackState *state = user_data; - CoglPipeline *pipeline = state->pipeline; - CoglContext *ctx = pipeline->context; - CoglTexture *texture = NULL; - COGL_STATIC_COUNTER (layer_fallback_counter, - "layer fallback counter", - "Increments each time a layer's texture is " - "forced to a fallback texture", - 0 /* no application private data */); - - if (!(state->fallback_layers & 1<i)) - return TRUE; - - COGL_COUNTER_INC (_cogl_uprof_context, layer_fallback_counter); - - texture = ctx->default_gl_texture_2d_tex; - - if (texture == NULL) - { - g_warning ("We don't have a fallback texture we can use to fill " - "in for an invalid pipeline layer, since it was " - "using an unsupported texture target "); - /* might get away with this... */ - texture = ctx->default_gl_texture_2d_tex; - } - - cogl_pipeline_set_layer_texture (pipeline, layer->index, texture); - - state->i++; - - return TRUE; -} - -typedef struct -{ - CoglPipeline *pipeline; - CoglTexture *texture; -} CoglPipelineOverrideLayerState; - -static gboolean -override_layer_texture_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglPipelineOverrideLayerState *state = user_data; - - cogl_pipeline_set_layer_texture (state->pipeline, - layer->index, - state->texture); - - return TRUE; -} - -void -_cogl_pipeline_apply_overrides (CoglPipeline *pipeline, - CoglPipelineFlushOptions *options) -{ - COGL_STATIC_COUNTER (apply_overrides_counter, - "pipeline overrides counter", - "Increments each time we have to apply " - "override options to a pipeline", - 0 /* no application private data */); - - COGL_COUNTER_INC (_cogl_uprof_context, apply_overrides_counter); - - if (options->flags & COGL_PIPELINE_FLUSH_DISABLE_MASK) - { - int i; - - /* NB: we can assume that once we see one bit to disable - * a layer, all subsequent layers are also disabled. */ - for (i = 0; i < 32 && options->disable_layers & (1<flags & COGL_PIPELINE_FLUSH_FALLBACK_MASK) - { - CoglPipelineFallbackState state; - - state.i = 0; - state.pipeline = pipeline; - state.fallback_layers = options->fallback_layers; - - _cogl_pipeline_foreach_layer_internal (pipeline, - fallback_layer_cb, - &state); - } - - if (options->flags & COGL_PIPELINE_FLUSH_LAYER0_OVERRIDE) - { - CoglPipelineOverrideLayerState state; - - _cogl_pipeline_prune_to_n_layers (pipeline, 1); - - /* NB: we are overriding the first layer, but we don't know - * the user's given layer_index, which is why we use - * _cogl_pipeline_foreach_layer_internal() here even though we know - * there's only one layer. */ - state.pipeline = pipeline; - state.texture = options->layer0_override_texture; - _cogl_pipeline_foreach_layer_internal (pipeline, - override_layer_texture_cb, - &state); - } -} - -static gboolean -_cogl_pipeline_layers_equal (CoglPipeline *authority0, - CoglPipeline *authority1, - unsigned long differences) -{ - int i; - - if (authority0->n_layers != authority1->n_layers) - return FALSE; - - _cogl_pipeline_update_layers_cache (authority0); - _cogl_pipeline_update_layers_cache (authority1); - - for (i = 0; i < authority0->n_layers; i++) - { - if (!_cogl_pipeline_layer_equal (authority0->layers_cache[i], - authority1->layers_cache[i], - differences)) - return FALSE; - } - return TRUE; -} - -/* Determine the mask of differences between two pipelines */ -unsigned long -_cogl_pipeline_compare_differences (CoglPipeline *pipeline0, - CoglPipeline *pipeline1) -{ - GSList *head0 = NULL; - GSList *head1 = NULL; - CoglPipeline *node0; - CoglPipeline *node1; - int len0 = 0; - int len1 = 0; - int count; - GSList *common_ancestor0; - GSList *common_ancestor1; - unsigned long pipelines_difference = 0; - - /* Algorithm: - * - * 1) Walk the ancestors of each pipeline to the root node, adding a - * pointer to each ancestor node to two linked lists - * - * 2) Compare the lists to find the nodes where they start to - * differ marking the common_ancestor node for each list. - * - * 3) For each list now iterate starting after the common_ancestor - * nodes ORing each nodes ->difference mask into the final - * differences mask. - */ - - for (node0 = pipeline0; node0; node0 = _cogl_pipeline_get_parent (node0)) - { - GSList *link = alloca (sizeof (GSList)); - link->next = head0; - link->data = node0; - head0 = link; - len0++; - } - for (node1 = pipeline1; node1; node1 = _cogl_pipeline_get_parent (node1)) - { - GSList *link = alloca (sizeof (GSList)); - link->next = head1; - link->data = node1; - head1 = link; - len1++; - } - - /* NB: There's no point looking at the head entries since we know both - * pipelines must have the same default pipeline as their root node. */ - common_ancestor0 = head0; - common_ancestor1 = head1; - head0 = head0->next; - head1 = head1->next; - count = MIN (len0, len1) - 1; - while (count--) - { - if (head0->data != head1->data) - break; - common_ancestor0 = head0; - common_ancestor1 = head1; - head0 = head0->next; - head1 = head1->next; - } - - for (head0 = common_ancestor0->next; head0; head0 = head0->next) - { - node0 = head0->data; - pipelines_difference |= node0->differences; - } - for (head1 = common_ancestor1->next; head1; head1 = head1->next) - { - node1 = head1->data; - pipelines_difference |= node1->differences; - } - - return pipelines_difference; -} - -static void -_cogl_pipeline_resolve_authorities (CoglPipeline *pipeline, - unsigned long differences, - CoglPipeline **authorities) -{ - unsigned long remaining = differences; - CoglPipeline *authority = pipeline; - - do - { - unsigned long found = authority->differences & remaining; - int i; - - if (found == 0) - continue; - - for (i = 0; TRUE; i++) - { - unsigned long state = (1L< found) - break; - } - - remaining &= ~found; - if (remaining == 0) - return; - } - while ((authority = _cogl_pipeline_get_parent (authority))); - - g_assert (remaining == 0); -} - -/* Comparison of two arbitrary pipelines is done by: - * 1) walking up the parents of each pipeline until a common - * ancestor is found, and at each step ORing together the - * difference masks. - * - * 2) using the final difference mask to determine which state - * groups to compare. - * - * This is used, for example, by the Cogl journal to compare pipelines so that - * it can split up geometry that needs different OpenGL state. - * - * XXX: When comparing texture layers, _cogl_pipeline_equal will actually - * compare the underlying GL texture handle that the Cogl texture uses so that - * atlas textures and sub textures will be considered equal if they point to - * the same texture. This is useful for comparing pipelines in the journal but - * it means that _cogl_pipeline_equal doesn't strictly compare whether the - * pipelines are the same. If we needed those semantics we could perhaps add - * another function or some flags to control the behaviour. - * - * XXX: Similarly when comparing the wrap modes, - * COGL_PIPELINE_WRAP_MODE_AUTOMATIC is considered to be the same as - * COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE because once they get to the - * journal stage they act exactly the same. - */ -gboolean -_cogl_pipeline_equal (CoglPipeline *pipeline0, - CoglPipeline *pipeline1, - unsigned int differences, - unsigned long layer_differences) -{ - unsigned long pipelines_difference; - CoglPipeline *authorities0[COGL_PIPELINE_STATE_SPARSE_COUNT]; - CoglPipeline *authorities1[COGL_PIPELINE_STATE_SPARSE_COUNT]; - int bit; - gboolean ret; - - COGL_STATIC_TIMER (pipeline_equal_timer, - "Mainloop", /* parent */ - "_cogl_pipeline_equal", - "The time spent comparing cogl pipelines", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, pipeline_equal_timer); - - if (pipeline0 == pipeline1) - { - ret = TRUE; - goto done; - } - - ret = FALSE; - - _cogl_pipeline_update_real_blend_enable (pipeline0, FALSE); - _cogl_pipeline_update_real_blend_enable (pipeline1, FALSE); - - /* First check non-sparse properties */ - - if (differences & COGL_PIPELINE_STATE_REAL_BLEND_ENABLE && - pipeline0->real_blend_enable != pipeline1->real_blend_enable) - goto done; - - /* Then check sparse properties */ - - pipelines_difference = - _cogl_pipeline_compare_differences (pipeline0, pipeline1); - - /* Only compare the sparse state groups requested by the caller... */ - pipelines_difference &= differences; - - _cogl_pipeline_resolve_authorities (pipeline0, - pipelines_difference, - authorities0); - _cogl_pipeline_resolve_authorities (pipeline1, - pipelines_difference, - authorities1); - - COGL_FLAGS_FOREACH_START (&pipelines_difference, 1, bit) - { - /* XXX: We considered having an array of callbacks for each state index - * that we'd call here but decided that this way the compiler is more - * likely going to be able to in-line the comparison functions and use - * the index to jump straight to the required code. */ - switch ((CoglPipelineStateIndex)bit) - { - case COGL_PIPELINE_STATE_COLOR_INDEX: - if (!cogl_color_equal (&authorities0[bit]->color, - &authorities1[bit]->color)) - goto done; - break; - case COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX: - if (!_cogl_pipeline_alpha_func_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX: - if (!_cogl_pipeline_alpha_func_reference_state_equal ( - authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_BLEND_INDEX: - /* We don't need to compare the detailed blending state if we know - * blending is disabled for both pipelines. */ - if (pipeline0->real_blend_enable) - { - if (!_cogl_pipeline_blend_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - } - break; - case COGL_PIPELINE_STATE_DEPTH_INDEX: - if (!_cogl_pipeline_depth_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_CULL_FACE_INDEX: - if (!_cogl_pipeline_cull_face_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE_INDEX: - if (!_cogl_pipeline_non_zero_point_size_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_POINT_SIZE_INDEX: - if (!_cogl_pipeline_point_size_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX: - if (!_cogl_pipeline_per_vertex_point_size_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_USER_SHADER_INDEX: - if (!_cogl_pipeline_user_shader_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_UNIFORMS_INDEX: - if (!_cogl_pipeline_uniforms_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX: - if (!_cogl_pipeline_vertex_snippets_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS_INDEX: - if (!_cogl_pipeline_fragment_snippets_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_LAYERS_INDEX: - { - if (!_cogl_pipeline_layers_equal (authorities0[bit], - authorities1[bit], - layer_differences)) - goto done; - break; - } - - case COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX: - case COGL_PIPELINE_STATE_COUNT: - g_warn_if_reached (); - } - } - COGL_FLAGS_FOREACH_END; - - ret = TRUE; -done: - COGL_TIMER_STOP (_cogl_uprof_context, pipeline_equal_timer); - return ret; -} - -void -_cogl_pipeline_prune_redundant_ancestry (CoglPipeline *pipeline) -{ - CoglPipeline *new_parent = _cogl_pipeline_get_parent (pipeline); - - /* Before considering pruning redundant ancestry we check if this - * pipeline is an authority for layer state and if so only consider - * reparenting if it *owns* all the layers it depends on. NB: A - * pipeline can be be a STATE_LAYERS authority but it may still - * defer to its ancestors to define the state for some of its - * layers. - * - * For example a pipeline that derives from a parent with 5 layers - * can become a STATE_LAYERS authority by simply changing it's - * ->n_layers count to 4 and in that case it can still defer to its - * ancestors to define the state of those 4 layers. - * - * If a pipeline depends on any ancestors for layer state then we - * immediately bail out. - */ - if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS) - { - if (pipeline->n_layers != g_list_length (pipeline->layer_differences)) - return; - } - - /* walk up past ancestors that are now redundant and potentially - * reparent the pipeline. */ - while (_cogl_pipeline_get_parent (new_parent) && - (new_parent->differences | pipeline->differences) == - pipeline->differences) - new_parent = _cogl_pipeline_get_parent (new_parent); - - if (new_parent != _cogl_pipeline_get_parent (pipeline)) - { - gboolean is_weak = _cogl_pipeline_is_weak (pipeline); - _cogl_pipeline_set_parent (pipeline, new_parent, is_weak ? FALSE : TRUE); - } -} - -void -_cogl_pipeline_update_authority (CoglPipeline *pipeline, - CoglPipeline *authority, - CoglPipelineState state, - CoglPipelineStateComparator comparator) -{ - /* If we are the current authority see if we can revert to one of - * our ancestors being the authority */ - if (pipeline == authority && - _cogl_pipeline_get_parent (authority) != NULL) - { - CoglPipeline *parent = _cogl_pipeline_get_parent (authority); - CoglPipeline *old_authority = - _cogl_pipeline_get_authority (parent, state); - - if (comparator (authority, old_authority)) - pipeline->differences &= ~state; - } - else if (pipeline != authority) - { - /* If we weren't previously the authority on this state then we - * need to extended our differences mask and so it's possible - * that some of our ancestry will now become redundant, so we - * aim to reparent ourselves if that's true... */ - pipeline->differences |= state; - _cogl_pipeline_prune_redundant_ancestry (pipeline); - } -} - -unsigned long -_cogl_pipeline_get_age (CoglPipeline *pipeline) -{ - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), 0); - - return pipeline->age; -} - -void -cogl_pipeline_remove_layer (CoglPipeline *pipeline, int layer_index) -{ - CoglPipeline *authority; - CoglPipelineLayerInfo layer_info; - int i; - - g_return_if_fail (COGL_IS_PIPELINE (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - - /* The layer index of the layer we want info about */ - layer_info.layer_index = layer_index; - - /* This will be updated with a reference to the layer being removed - * if it can be found. */ - layer_info.layer = NULL; - - /* This will be filled in with a list of layers that need to be - * dropped down to a lower texture unit to fill the gap of the - * removed layer. */ - layer_info.layers_to_shift = - g_alloca (sizeof (CoglPipelineLayer *) * authority->n_layers); - layer_info.n_layers_to_shift = 0; - - /* Unlike when we query layer info when adding a layer we must - * always have a complete layers_to_shift list... */ - layer_info.ignore_shift_layers_if_found = FALSE; - - _cogl_pipeline_get_layer_info (authority, &layer_info); - - if (layer_info.layer == NULL) - return; - - for (i = 0; i < layer_info.n_layers_to_shift; i++) - { - CoglPipelineLayer *shift_layer = layer_info.layers_to_shift[i]; - int unit_index = _cogl_pipeline_layer_get_unit_index (shift_layer); - _cogl_pipeline_set_layer_unit (pipeline, shift_layer, unit_index - 1); - /* NB: shift_layer may not be writeable so _set_layer_unit() - * will allocate a derived layer internally which will become - * owned by pipeline. Check the return value if we need to do - * anything else with this layer. */ - } - - _cogl_pipeline_remove_layer_difference (pipeline, layer_info.layer, TRUE); - _cogl_pipeline_try_reverting_layers_authority (pipeline, NULL); - - pipeline->dirty_real_blend_enable = TRUE; -} - -int -cogl_pipeline_get_n_layers (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (COGL_IS_PIPELINE (pipeline), 0); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - - return authority->n_layers; -} - -void -_cogl_pipeline_pre_paint_for_layer (CoglPipeline *pipeline, - int layer_id) -{ - CoglPipelineLayer *layer = _cogl_pipeline_get_layer (pipeline, layer_id); - _cogl_pipeline_layer_pre_paint (layer); -} - -/* While a pipeline is referenced by the Cogl journal we can not allow - * modifications, so this gives us a mechanism to track journal - * references separately */ -CoglPipeline * -_cogl_pipeline_journal_ref (CoglPipeline *pipeline) -{ - pipeline->journal_ref_count++; - return g_object_ref (pipeline); -} - -void -_cogl_pipeline_journal_unref (CoglPipeline *pipeline) -{ - pipeline->journal_ref_count--; - g_object_unref (pipeline); -} - -#ifdef COGL_ENABLE_DEBUG -void -_cogl_pipeline_set_static_breadcrumb (CoglPipeline *pipeline, - const char *breadcrumb) -{ - pipeline->has_static_breadcrumb = TRUE; - pipeline->static_breadcrumb = breadcrumb; -} -#endif - -typedef void (*LayerStateHashFunction) (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -static LayerStateHashFunction -layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT]; - -/* XXX: We don't statically initialize the array of hash functions, so - * we won't get caught out by later re-indexing the groups for some - * reason. */ -void -_cogl_pipeline_init_layer_state_hash_functions (void) -{ - CoglPipelineLayerStateIndex _index; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_UNIT_INDEX] = - _cogl_pipeline_layer_hash_unit_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX] = - _cogl_pipeline_layer_hash_texture_data_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_SAMPLER_INDEX] = - _cogl_pipeline_layer_hash_sampler_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX] = - _cogl_pipeline_layer_hash_combine_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX] = - _cogl_pipeline_layer_hash_combine_constant_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX] = - _cogl_pipeline_layer_hash_user_matrix_state; - _index = COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX; - layer_state_hash_functions[_index] = - _cogl_pipeline_layer_hash_point_sprite_state; - _index = COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS_INDEX; - layer_state_hash_functions[_index] = - _cogl_pipeline_layer_hash_point_sprite_state; - _index = COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS_INDEX; - layer_state_hash_functions[_index] = - _cogl_pipeline_layer_hash_fragment_snippets_state; - - { - /* So we get a big error if we forget to update this code! */ - _COGL_STATIC_ASSERT (COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT == 9, - "Don't forget to install a hash function for new " - "pipeline state and update assert at end of " - "_cogl_pipeline_init_state_hash_functions"); - } -} - -static gboolean -_cogl_pipeline_hash_layer_cb (CoglPipelineLayer *layer, - void *user_data) -{ - CoglPipelineHashState *state = user_data; - unsigned long differences = state->layer_differences; - CoglPipelineLayer *authorities[COGL_PIPELINE_LAYER_STATE_COUNT]; - unsigned long mask; - int i; - - /* Theoretically we would hash non-sparse layer state here but - * currently layers don't have any. */ - - /* XXX: we resolve all the authorities here - not just those - * corresponding to hash_state->layer_differences - because - * the hashing of some state groups actually depends on the values - * in other groups. For example we don't hash layer combine - * constants if they are aren't referenced by the current layer - * combine function. - */ - mask = COGL_PIPELINE_LAYER_STATE_ALL_SPARSE; - _cogl_pipeline_layer_resolve_authorities (layer, - mask, - authorities); - - /* So we go right ahead and hash the sparse state... */ - for (i = 0; i < COGL_PIPELINE_LAYER_STATE_COUNT; i++) - { - unsigned long current_state = (1L< differences) - break; - } - - return TRUE; -} - -static void -_cogl_pipeline_hash_layers_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &authority->n_layers, - sizeof (authority->n_layers)); - _cogl_pipeline_foreach_layer_internal (authority, - _cogl_pipeline_hash_layer_cb, - state); -} - -typedef void (*StateHashFunction) (CoglPipeline *authority, CoglPipelineHashState *state); - -static StateHashFunction -state_hash_functions[COGL_PIPELINE_STATE_SPARSE_COUNT]; - -/* We don't statically initialize the array of hash functions - * so we won't get caught out by later re-indexing the groups for - * some reason. */ -void -_cogl_pipeline_init_state_hash_functions (void) -{ - state_hash_functions[COGL_PIPELINE_STATE_COLOR_INDEX] = - _cogl_pipeline_hash_color_state; - state_hash_functions[COGL_PIPELINE_STATE_LAYERS_INDEX] = - _cogl_pipeline_hash_layers_state; - state_hash_functions[COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX] = - _cogl_pipeline_hash_alpha_func_state; - state_hash_functions[COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX] = - _cogl_pipeline_hash_alpha_func_reference_state; - state_hash_functions[COGL_PIPELINE_STATE_BLEND_INDEX] = - _cogl_pipeline_hash_blend_state; - state_hash_functions[COGL_PIPELINE_STATE_USER_SHADER_INDEX] = - _cogl_pipeline_hash_user_shader_state; - state_hash_functions[COGL_PIPELINE_STATE_DEPTH_INDEX] = - _cogl_pipeline_hash_depth_state; - state_hash_functions[COGL_PIPELINE_STATE_CULL_FACE_INDEX] = - _cogl_pipeline_hash_cull_face_state; - state_hash_functions[COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE_INDEX] = - _cogl_pipeline_hash_non_zero_point_size_state; - state_hash_functions[COGL_PIPELINE_STATE_POINT_SIZE_INDEX] = - _cogl_pipeline_hash_point_size_state; - state_hash_functions[COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX] = - _cogl_pipeline_hash_per_vertex_point_size_state; - state_hash_functions[COGL_PIPELINE_STATE_UNIFORMS_INDEX] = - _cogl_pipeline_hash_uniforms_state; - state_hash_functions[COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX] = - _cogl_pipeline_hash_vertex_snippets_state; - state_hash_functions[COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS_INDEX] = - _cogl_pipeline_hash_fragment_snippets_state; - - { - /* So we get a big error if we forget to update this code! */ - _COGL_STATIC_ASSERT (COGL_PIPELINE_STATE_SPARSE_COUNT == 14, - "Make sure to install a hash function for " - "newly added pipeline state and update assert " - "in _cogl_pipeline_init_state_hash_functions"); - } -} - -unsigned int -_cogl_pipeline_hash (CoglPipeline *pipeline, - unsigned int differences, - unsigned long layer_differences) -{ - CoglPipeline *authorities[COGL_PIPELINE_STATE_SPARSE_COUNT]; - unsigned int mask; - int i; - CoglPipelineHashState state; - unsigned int final_hash = 0; - - state.hash = 0; - state.layer_differences = layer_differences; - - _cogl_pipeline_update_real_blend_enable (pipeline, FALSE); - - /* hash non-sparse state */ - - if (differences & COGL_PIPELINE_STATE_REAL_BLEND_ENABLE) - { - gboolean enable = pipeline->real_blend_enable; - state.hash = - _cogl_util_one_at_a_time_hash (state.hash, &enable, sizeof (enable)); - } - - /* hash sparse state */ - - mask = differences & COGL_PIPELINE_STATE_ALL_SPARSE; - _cogl_pipeline_resolve_authorities (pipeline, mask, authorities); - - for (i = 0; i < COGL_PIPELINE_STATE_SPARSE_COUNT; i++) - { - unsigned int current_state = (1< differences) - break; - } - - return _cogl_util_one_at_a_time_mix (final_hash); -} - -typedef struct -{ - CoglContext *context; - CoglPipeline *src_pipeline; - CoglPipeline *dst_pipeline; - unsigned int layer_differences; -} DeepCopyData; - -static gboolean -deep_copy_layer_cb (CoglPipelineLayer *src_layer, - void *user_data) -{ - DeepCopyData *data = user_data; - CoglPipelineLayer *dst_layer; - unsigned int differences = data->layer_differences; - - dst_layer = _cogl_pipeline_get_layer (data->dst_pipeline, src_layer->index); - - while (src_layer != data->context->default_layer_n && - src_layer != data->context->default_layer_0 && - differences) - { - unsigned long to_copy = differences & src_layer->differences; - - if (to_copy) - { - _cogl_pipeline_layer_copy_differences (dst_layer, src_layer, to_copy); - differences ^= to_copy; - } - - src_layer = COGL_PIPELINE_LAYER (COGL_NODE (src_layer)->parent); - } - - return TRUE; -} - -CoglPipeline * -_cogl_pipeline_deep_copy (CoglPipeline *pipeline, - unsigned long differences, - unsigned long layer_differences) -{ - CoglPipeline *new, *authority; - CoglContext *ctx = pipeline->context; - gboolean copy_layer_state; - - if ((differences & COGL_PIPELINE_STATE_LAYERS)) - { - copy_layer_state = TRUE; - differences &= ~COGL_PIPELINE_STATE_LAYERS; - } - else - copy_layer_state = FALSE; - - new = cogl_pipeline_new (ctx); - - for (authority = pipeline; - authority != ctx->default_pipeline && differences; - authority = COGL_PIPELINE (COGL_NODE (authority)->parent)) - { - unsigned long to_copy = differences & authority->differences; - - if (to_copy) - { - _cogl_pipeline_copy_differences (new, authority, to_copy); - differences ^= to_copy; - } - } - - if (copy_layer_state) - { - DeepCopyData data; - - /* The unit index doesn't need to be copied because it should - * end up with the same values anyway because the new pipeline - * will have the same indices as the source pipeline */ - layer_differences &= ~COGL_PIPELINE_LAYER_STATE_UNIT; - - data.context = ctx; - data.src_pipeline = pipeline; - data.dst_pipeline = new; - data.layer_differences = layer_differences; - - _cogl_pipeline_foreach_layer_internal (pipeline, - deep_copy_layer_cb, - &data); - } - - return new; -} - -typedef struct -{ - int i; - CoglPipelineLayer **layers; -} AddLayersToArrayState; - -static gboolean -add_layer_to_array_cb (CoglPipelineLayer *layer, - void *user_data) -{ - AddLayersToArrayState *state = user_data; - state->layers[state->i++] = layer; - return TRUE; -} - -/* This tries to find the oldest ancestor whose pipeline and layer - state matches the given flags. This is mostly used to detect code - gen authorities so that we can reduce the number of programs - generated */ -CoglPipeline * -_cogl_pipeline_find_equivalent_parent (CoglPipeline *pipeline, - CoglPipelineState pipeline_state, - CoglPipelineLayerState layer_state) -{ - CoglPipeline *authority0; - CoglPipeline *authority1; - int n_layers; - CoglPipelineLayer **authority0_layers; - CoglPipelineLayer **authority1_layers; - - /* Find the first pipeline that modifies state that affects the - * state or any layer state... */ - authority0 = _cogl_pipeline_get_authority (pipeline, - pipeline_state | - COGL_PIPELINE_STATE_LAYERS); - - /* Find the next ancestor after that, that also modifies the - * state... */ - if (_cogl_pipeline_get_parent (authority0)) - { - authority1 = - _cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority0), - pipeline_state | - COGL_PIPELINE_STATE_LAYERS); - } - else - return authority0; - - n_layers = cogl_pipeline_get_n_layers (authority0); - - for (;;) - { - AddLayersToArrayState state; - int i; - - if (n_layers != cogl_pipeline_get_n_layers (authority1)) - return authority0; - - /* If the programs differ by anything that isn't part of the - layer state then we can't continue */ - if (pipeline_state && - (_cogl_pipeline_compare_differences (authority0, authority1) & - pipeline_state)) - return authority0; - - authority0_layers = - g_alloca (sizeof (CoglPipelineLayer *) * n_layers); - state.i = 0; - state.layers = authority0_layers; - _cogl_pipeline_foreach_layer_internal (authority0, - add_layer_to_array_cb, - &state); - - authority1_layers = - g_alloca (sizeof (CoglPipelineLayer *) * n_layers); - state.i = 0; - state.layers = authority1_layers; - _cogl_pipeline_foreach_layer_internal (authority1, - add_layer_to_array_cb, - &state); - - for (i = 0; i < n_layers; i++) - { - unsigned long layer_differences; - - if (authority0_layers[i] == authority1_layers[i]) - continue; - - layer_differences = - _cogl_pipeline_layer_compare_differences (authority0_layers[i], - authority1_layers[i]); - - if (layer_differences & layer_state) - return authority0; - } - - /* Find the next ancestor after that, that also modifies state - * affecting codegen... */ - - if (!_cogl_pipeline_get_parent (authority1)) - break; - - authority0 = authority1; - authority1 = - _cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority1), - pipeline_state | - COGL_PIPELINE_STATE_LAYERS); - if (authority1 == authority0) - break; - } - - return authority1; -} - -CoglPipelineState -_cogl_pipeline_get_state_for_vertex_codegen (CoglContext *context) -{ - CoglPipelineState state = (COGL_PIPELINE_STATE_LAYERS | - COGL_PIPELINE_STATE_USER_SHADER | - COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE | - COGL_PIPELINE_STATE_VERTEX_SNIPPETS); - state |= COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE; - - return state; -} - -CoglPipelineLayerState -_cogl_pipeline_get_layer_state_for_fragment_codegen (CoglContext *context) -{ - CoglPipelineLayerState state = - (COGL_PIPELINE_LAYER_STATE_COMBINE | - COGL_PIPELINE_LAYER_STATE_UNIT | - COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS); - - /* Since the driver supports GLSL then we might be using gl_PointCoord - * to implement the sprite coords. In that case the generated code - * depends on the point sprite state */ - state |= COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS; - - return state; -} - -CoglPipelineState -_cogl_pipeline_get_state_for_fragment_codegen (CoglContext *context) -{ - CoglPipelineState state = (COGL_PIPELINE_STATE_LAYERS | - COGL_PIPELINE_STATE_USER_SHADER | - COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS | - COGL_PIPELINE_STATE_ALPHA_FUNC); - - return state; -} - -int -cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, - const char *uniform_name) -{ - CoglContext *ctx = pipeline->context; - void *location_ptr; - char *uniform_name_copy; - - /* This API is designed as if the uniform locations are specific to - a pipeline but they are actually unique across a whole - CoglContext. Potentially this could just be - cogl_context_get_uniform_location but it seems to make sense to - keep the API this way so that we can change the internals if need - be. */ - - /* Look for an existing uniform with this name */ - if (g_hash_table_lookup_extended (ctx->uniform_name_hash, - uniform_name, - NULL, - &location_ptr)) - return GPOINTER_TO_INT (location_ptr); - - uniform_name_copy = g_strdup (uniform_name); - g_ptr_array_add (ctx->uniform_names, uniform_name_copy); - g_hash_table_insert (ctx->uniform_name_hash, - uniform_name_copy, - GINT_TO_POINTER (ctx->n_uniform_names)); - - return ctx->n_uniform_names++; -} diff --git a/mutter/cogl/cogl/cogl-pipeline.h b/mutter/cogl/cogl/cogl-pipeline.h deleted file mode 100644 index 483f8e2..0000000 --- a/mutter/cogl/cogl/cogl-pipeline.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -/* We forward declare the CoglPipeline type here to avoid some circular - * dependency issues with the following headers. - */ -typedef struct _CoglPipeline CoglPipeline; - -#include "cogl/cogl-types.h" -#include "cogl/cogl-context.h" -#include "cogl/cogl-snippet.h" - -#include - -G_BEGIN_DECLS - -/** - * CoglPipeline: - * - * Functions for creating and manipulating the GPU pipeline - * - * Cogl allows creating and manipulating objects representing the full - * configuration of the GPU pipeline. In simplified terms the GPU - * pipeline takes primitive geometry as the input, it first performs - * vertex processing, allowing you to deform your geometry, then - * rasterizes that (turning it from pure geometry into fragments) then - * performs fragment processing including depth testing and texture - * mapping. Finally it blends the result with the framebuffer. - */ -#define COGL_TYPE_PIPELINE (cogl_pipeline_get_type ()) -#define COGL_PIPELINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_PIPELINE, CoglPipeline)) -#define COGL_PIPELINE_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_PIPELINE, CoglPipeline const)) -#define COGL_PIPELINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_TYPE_PIPELINE, CoglPipelineClass)) -#define COGL_IS_PIPELINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_TYPE_PIPELINE)) -#define COGL_IS_PIPELINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_TYPE_PIPELINE)) -#define COGL_PIPELINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COGL_TYPE_PIPELINE, CoglPipelineClass)) - -typedef struct _CoglPipelineClass CoglPipelineClass; -typedef struct _CoglPipeline CoglPipeline; - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (CoglPipeline, g_object_unref) - -COGL_EXPORT -GType cogl_pipeline_get_type (void) G_GNUC_CONST; - -/** - * cogl_pipeline_new: (constructor) - * @context: a #CoglContext - * - * Allocates and initializes a default simple pipeline that will color - * a primitive white. - * - * Return value: (transfer full): a pointer to a new #CoglPipeline - */ -COGL_EXPORT CoglPipeline * -cogl_pipeline_new (CoglContext *context); - -/** - * cogl_pipeline_copy: - * @source: a #CoglPipeline object to copy - * - * Creates a new pipeline with the configuration copied from the - * source pipeline. - * - * We would strongly advise developers to always aim to use - * cogl_pipeline_copy() instead of cogl_pipeline_new() whenever there will - * be any similarity between two pipelines. Copying a pipeline helps Cogl - * keep track of a pipelines ancestry which we may use to help minimize GPU - * state changes. - * - * Return value: (transfer full): a pointer to the newly allocated #CoglPipeline - */ -COGL_EXPORT CoglPipeline * -cogl_pipeline_copy (CoglPipeline *source); - -/** - * CoglPipelineLayerCallback: - * @pipeline: The #CoglPipeline whose layers are being iterated - * @layer_index: The current layer index - * @user_data: The private data passed to cogl_pipeline_foreach_layer() - * - * The callback prototype used with cogl_pipeline_foreach_layer() for - * iterating all the layers of a @pipeline. - */ -typedef gboolean (*CoglPipelineLayerCallback) (CoglPipeline *pipeline, - int layer_index, - void *user_data); - -/** - * cogl_pipeline_foreach_layer: - * @pipeline: A #CoglPipeline object - * @callback: (scope call): A #CoglPipelineLayerCallback to be - * called for each layer index - * @user_data: (closure): Private data that will be passed to the - * callback - * - * Iterates all the layer indices of the given @pipeline. - */ -COGL_EXPORT void -cogl_pipeline_foreach_layer (CoglPipeline *pipeline, - CoglPipelineLayerCallback callback, - void *user_data); - -/** - * cogl_pipeline_get_uniform_location: - * @pipeline: A #CoglPipeline object - * @uniform_name: The name of a uniform - * - * This is used to get an integer representing the uniform with the - * name @uniform_name. The integer can be passed to functions such as - * cogl_pipeline_set_uniform_1f() to set the value of a uniform. - * - * This function will always return a valid integer. Ie, unlike - * OpenGL, it does not return -1 if the uniform is not available in - * this pipeline so it can not be used to test whether uniforms are - * present. It is not necessary to set the program on the pipeline - * before calling this function. - * - * Return value: A integer representing the location of the given uniform. - */ -COGL_EXPORT int -cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, - const char *uniform_name); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-pixel-buffer-private.h b/mutter/cogl/cogl/cogl-pixel-buffer-private.h deleted file mode 100644 index 3085626..0000000 --- a/mutter/cogl/cogl/cogl-pixel-buffer-private.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Damien Lespiau - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-buffer-private.h" - -#include - -G_BEGIN_DECLS - -struct _CoglPixelBuffer -{ - CoglBuffer parent_instance; -}; - -struct _CoglPixelBufferClass -{ - CoglBufferClass parent_class; -}; - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-pixel-buffer.c b/mutter/cogl/cogl/cogl-pixel-buffer.c deleted file mode 100644 index 3924609..0000000 --- a/mutter/cogl/cogl/cogl-pixel-buffer.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Damien Lespiau - * Robert Bragg - */ - -/* For an overview of the functionality implemented here, please see - * cogl-buffer-array.h, which contains the gtk-doc section overview for the - * Pixel Buffers API. - */ - -#include "config.h" - -#include -#include -#include - -#include "cogl/cogl-private.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-pixel-buffer-private.h" -#include "cogl/cogl-pixel-buffer.h" - -G_DEFINE_FINAL_TYPE (CoglPixelBuffer, cogl_pixel_buffer, COGL_TYPE_BUFFER) - -static void -cogl_pixel_buffer_class_init (CoglPixelBufferClass *klass) -{ -} - -static void -cogl_pixel_buffer_init (CoglPixelBuffer *buffer) -{ -} - -static CoglPixelBuffer * -_cogl_pixel_buffer_new (CoglContext *context, - size_t size, - const void *data, - GError **error) -{ - CoglPixelBuffer *pixel_buffer; - - pixel_buffer = g_object_new (COGL_TYPE_PIXEL_BUFFER, - "context", context, - "size", (uint64_t) size, - "default-target", COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK, - "update-hint", COGL_BUFFER_UPDATE_HINT_STATIC, - NULL); - - if (data) - { - if (!_cogl_buffer_set_data (COGL_BUFFER (pixel_buffer), - 0, - data, - size, - error)) - { - g_object_unref (pixel_buffer); - return NULL; - } - } - - return pixel_buffer; -} - -CoglPixelBuffer * -cogl_pixel_buffer_new (CoglContext *context, - size_t size, - const void *data) -{ - GError *ignore_error = NULL; - CoglPixelBuffer *buffer = - _cogl_pixel_buffer_new (context, size, data, &ignore_error); - - g_clear_error (&ignore_error); - return buffer; -} diff --git a/mutter/cogl/cogl/cogl-pixel-buffer.h b/mutter/cogl/cogl/cogl-pixel-buffer.h deleted file mode 100644 index cf26a61..0000000 --- a/mutter/cogl/cogl/cogl-pixel-buffer.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Damien Lespiau - * Robert Bragg - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -/* XXX: We forward declare CoglPixelBuffer here to allow for circular - * dependencies between some headers */ -typedef struct _CoglPixelBuffer CoglPixelBuffer; - -#include "cogl/cogl-types.h" -#include "cogl/cogl-context.h" - -#include - -G_BEGIN_DECLS - -/** - * CoglPixelBuffer: - */ -#define COGL_TYPE_PIXEL_BUFFER (cogl_pixel_buffer_get_type ()) -#define COGL_PIXEL_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_PIXEL_BUFFER, CoglPixelBuffer)) -#define COGL_PIXEL_BUFFER_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_PIXEL_BUFFER, CoglPixelBuffer const)) -#define COGL_PIXEL_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_TYPE_PIXEL_BUFFER, CoglPixelBufferClass)) -#define COGL_IS_PIXEL_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_TYPE_PIXEL_BUFFER)) -#define COGL_IS_PIXEL_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_TYPE_PIXEL_BUFFER)) -#define COGL_PIXEL_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COGL_TYPE_PIXEL_BUFFER, CoglPixelBufferClass)) - -typedef struct _CoglPixelBufferClass CoglPixelBufferClass; -typedef struct _CoglPixelBuffer CoglPixelBuffer; - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (CoglPixelBuffer, g_object_unref) - -COGL_EXPORT -GType cogl_pixel_buffer_get_type (void) G_GNUC_CONST; - -/** - * cogl_pixel_buffer_new: - * @context: A #CoglContext - * @size: The number of bytes to allocate for the pixel data. - * @data: (array length=size) (element-type guint8): An optional pointer to - * vertex data to upload immediately - * - * Declares a new #CoglPixelBuffer of @size bytes to contain arrays of - * pixels. Once declared, data can be set using cogl_buffer_set_data() - * or by mapping it into the application's address space using - * cogl_buffer_map(). - * - * If @data isn't %NULL then @size bytes will be read from @data and - * immediately copied into the new buffer. - * - * Return value: (transfer full): a newly allocated #CoglPixelBuffer - */ -COGL_EXPORT CoglPixelBuffer * -cogl_pixel_buffer_new (CoglContext *context, - size_t size, - const void *data); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-pixel-format.c b/mutter/cogl/cogl/cogl-pixel-format.c deleted file mode 100644 index 3b28df6..0000000 --- a/mutter/cogl/cogl/cogl-pixel-format.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include -#include -#include - -#include "cogl/cogl-pixel-format.h" - -/* An entry to map CoglPixelFormats to their respective properties */ -typedef struct _CoglPixelFormatInfo -{ - CoglPixelFormat cogl_format; - const char *format_str; - int aligned; /* Aligned components? (-1 if n/a) */ - uint8_t n_planes; - - /* Per-plane information */ - uint8_t bpp[COGL_PIXEL_FORMAT_MAX_PLANES]; /* Bytes per pixel */ -} CoglPixelFormatInfo; - -static const CoglPixelFormatInfo format_info_table[] = { - { - .cogl_format = COGL_PIXEL_FORMAT_ANY, - .format_str = "ANY", - .n_planes = 0, - .aligned = -1, - .bpp = { 0 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_A_8, - .format_str = "A_8", - .n_planes = 1, - .aligned = 1, - .bpp = { 1 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGB_565, - .format_str = "RGB_565", - .n_planes = 1, - .aligned = 0, - .bpp = { 2 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_4444, - .format_str = "RGBA_4444", - .n_planes = 1, - .aligned = 0, - .bpp = { 2 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_5551, - .format_str = "RGBA_5551", - .n_planes = 1, - .aligned = 0, - .bpp = { 2 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_YUV, - .format_str = "YUV", - .n_planes = 1, - .aligned = -1, - .bpp = { 0 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_R_8, - .format_str = "R_8", - .n_planes = 1, - .aligned = 1, - .bpp = { 1 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_R_16, - .format_str = "R_16", - .n_planes = 1, - .aligned = 1, - .bpp = { 2 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RG_88, - .format_str = "RG_88", - .n_planes = 1, - .aligned = 1, - .bpp = { 2 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RG_1616, - .format_str = "RG_1616", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_16161616, - .format_str = "RGBA_16161616", - .n_planes = 1, - .aligned = 1, - .bpp = { 8 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_16161616_PRE, - .format_str = "RGBA_16161616_PRE", - .n_planes = 1, - .aligned = 1, - .bpp = { 8 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGB_888, - .format_str = "RGB_888", - .n_planes = 1, - .aligned = 1, - .bpp = { 3 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_BGR_888, - .format_str = "BGR_888", - .n_planes = 1, - .aligned = 1, - .bpp = { 3 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBX_8888, - .format_str = "RGBX_8888", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_8888, - .format_str = "RGBA_8888", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_BGRX_8888, - .format_str = "BGRX_8888", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_BGRA_8888, - .format_str = "BGRA_8888", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_XRGB_8888, - .format_str = "XRGB_8888", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ARGB_8888, - .format_str = "ARGB_8888", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_XBGR_8888, - .format_str = "XBGR_8888", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ABGR_8888, - .format_str = "ABGR_8888", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102, - .format_str = "RGBA_1010102", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102, - .format_str = "BGRA_1010102", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_XRGB_2101010, - .format_str = "XRGB_2101010", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010, - .format_str = "ARGB_2101010", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_XBGR_2101010, - .format_str = "XBGR_2101010", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010, - .format_str = "ABGR_2101010", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE, - .format_str = "RGBA_8888_PRE", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE, - .format_str = "BGRA_8888_PRE", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE, - .format_str = "ARGB_8888_PRE", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ABGR_8888_PRE, - .format_str = "ABGR_8888_PRE", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_4444_PRE, - .format_str = "RGBA_4444_PRE", - .n_planes = 1, - .aligned = 0, - .bpp = { 2 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_5551_PRE, - .format_str = "RGBA_5551_PRE", - .n_planes = 1, - .aligned = 0, - .bpp = { 2 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102_PRE, - .format_str = "RGBA_1010102_PRE", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102_PRE, - .format_str = "BGRA_1010102_PRE", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE, - .format_str = "ARGB_2101010_PRE", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE, - .format_str = "ABGR_2101010_PRE", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBX_FP_16161616, - .format_str = "RGBX_FP_16161616", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_FP_16161616, - .format_str = "RGBA_FP_16161616", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_BGRX_FP_16161616, - .format_str = "BGRX_FP_16161616", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_BGRA_FP_16161616, - .format_str = "BGRA_FP_16161616", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_XRGB_FP_16161616, - .format_str = "ARGB_FP_16161616", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ARGB_FP_16161616, - .format_str = "ARGB_FP_16161616", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_XBGR_FP_16161616, - .format_str = "ABGR_FP_16161616", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ABGR_FP_16161616, - .format_str = "ABGR_FP_16161616", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE, - .format_str = "RGBA_FP_16161616_PRE", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE, - .format_str = "BGRA_FP_16161616_PRE", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE, - .format_str = "ARGB_FP_16161616_PRE", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE, - .format_str = "ABGR_FP_16161616_PRE", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_FP_32323232, - .format_str = "RGBA_FP_32323232", - .n_planes = 1, - .bpp = { 16 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE, - .format_str = "RGBA_FP_32323232_PRE", - .n_planes = 1, - .bpp = { 16 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_DEPTH_16, - .format_str = "DEPTH_16", - .n_planes = 1, - .aligned = 1, - .bpp = { 2 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8, - .format_str = "DEPTH_24_STENCIL_8", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, -}; - -int -cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format, - int plane) -{ - size_t i; - - for (i = 0; i < G_N_ELEMENTS (format_info_table); i++) - { - if (format_info_table[i].cogl_format == format) - { - g_return_val_if_fail (plane < format_info_table[i].n_planes, 0); - - return format_info_table[i].bpp[plane]; - } - } - - g_assert_not_reached (); -} - -/* Note: this also refers to the mapping defined above for - * cogl_pixel_format_get_bytes_per_pixel() */ -gboolean -_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format) -{ - int aligned = -1; - size_t i; - - /* NB: currently checking whether the format components are aligned - * or not determines whether the format is endian dependent or not. - * In the future though we might consider adding formats with - * aligned components that are also endian independent. */ - - for (i = 0; i < G_N_ELEMENTS (format_info_table); i++) - { - if (format_info_table[i].cogl_format == format) - { - aligned = format_info_table[i].aligned; - break; - } - } - - g_return_val_if_fail (aligned != -1, FALSE); - - return aligned; -} - -int -cogl_pixel_format_get_n_planes (CoglPixelFormat format) -{ - size_t i; - - for (i = 0; i < G_N_ELEMENTS (format_info_table); i++) - { - if (format_info_table[i].cogl_format == format) - return format_info_table[i].n_planes; - } - - g_assert_not_reached (); -} - -const char * -cogl_pixel_format_to_string (CoglPixelFormat format) -{ - size_t i; - - for (i = 0; i < G_N_ELEMENTS (format_info_table); i++) - { - if (format_info_table[i].cogl_format == format) - return format_info_table[i].format_str; - } - - g_assert_not_reached (); -} diff --git a/mutter/cogl/cogl/cogl-pixel-format.h b/mutter/cogl/cogl/cogl-pixel-format.h deleted file mode 100644 index 0f00d66..0000000 --- a/mutter/cogl/cogl/cogl-pixel-format.h +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include -#include - -#include "cogl/cogl-macros.h" - -#include -#include - -G_BEGIN_DECLS - -#define COGL_A_BIT (1 << 4) -#define COGL_BGR_BIT (1 << 5) -#define COGL_AFIRST_BIT (1 << 6) -#define COGL_PREMULT_BIT (1 << 7) -#define COGL_DEPTH_BIT (1 << 8) -#define COGL_STENCIL_BIT (1 << 9) - -/* XXX: Notes to those adding new formats here... - * - * First this diagram outlines how we allocate the 32bits of a - * CoglPixelFormat currently... - * - * 6 bits for flags - * |-----| - * enum unused 4 bits for the bytes-per-pixel - * and component alignment info - * |------| |-------------| |--| - * 00000000 xxxxxxxx xxxxxxSD PFBA0000 - * ^ stencil - * ^ depth - * ^ premult - * ^ alpha first - * ^ bgr order - * ^ has alpha - * - * The most awkward part about the formats is how we use the last 4 - * bits to encode the bytes per pixel and component alignment - * information. Ideally we should have had 3 bits for the bpp and a - * flag for alignment but we didn't plan for that in advance so we - * instead use a small lookup table to query the bpp and whether the - * components are byte aligned or not. - * - * The mapping is the following (see discussion on bug #660188): - * - * 0 = undefined - * 1, 8 = 1 bpp (e.g. A_8, R_8) - * 2 = 3 bpp, aligned (e.g. 888) - * 3 = 4 bpp, aligned (e.g. 8888) - * 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551) - * 7 = YUV: undefined bpp, undefined alignment - * 9 = 2 bpp, aligned - * 10 = 8 bpp, RGBA_161616 - * 11 = 8 bpp fp16 - * 12 = 16 bpp fp32 - * 13 = 4 bpp, not aligned (e.g. 2101010) - * 14 = 2 bpp, aligned (e.g. G_16) - * 15 = 4 bpp, aligned (e.g. RG_1616) - * - * Note: the gap at 10-11 is just because we wanted to maintain that - * all non-aligned formats have the third bit set in case that's - * useful later. - * - * Since we don't want to waste bits adding more and more flags, we'd - * like to see most new pixel formats that can't be represented - * uniquely with the existing flags in the least significant byte - * simply be enumerated with sequential values in the most significant - * enum byte. - * - * Note: Cogl avoids exposing any padded XRGB or RGBX formats and - * instead we leave it up to applications to decided whether they - * consider the A component as padding or valid data. We shouldn't - * change this policy without good reasoning. - * - * So to add a new format: - * 1) Use the mapping table above to figure out what to but in - * the lowest nibble. - * 2) OR in the COGL_PREMULT_BIT, COGL_AFIRST_BIT, COGL_A_BIT and - * COGL_BGR_BIT flags as appropriate. - * 3) If the result is not yet unique then also combine with an - * increment of the last sequence number in the most significant - * byte. - * - * The last sequence number used was 0 (i.e. no formats currently need - * a sequence number) - * Update this note whenever a new sequence number is used. - */ -/** - * CoglPixelFormat: - * @COGL_PIXEL_FORMAT_ANY: Any format - * @COGL_PIXEL_FORMAT_A_8: 8 bits alpha mask - * @COGL_PIXEL_FORMAT_RG_88: RG, 16 bits. Note that red-green textures - * are only available if %COGL_FEATURE_ID_TEXTURE_RG is advertised. - * See cogl_texture_set_components() for details. - * @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits - * @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits - * @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits - * @COGL_PIXEL_FORMAT_YUV: Not currently supported - * @COGL_PIXEL_FORMAT_R_8: Single luminance component - * @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits - * @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits - * @COGL_PIXEL_FORMAT_RGBX_8888: RGBX, 32 bits - * @COGL_PIXEL_FORMAT_RGBA_8888: RGBA, 32 bits - * @COGL_PIXEL_FORMAT_BGRX_8888: BGRX, 32 bits - * @COGL_PIXEL_FORMAT_BGRA_8888: BGRA, 32 bits - * @COGL_PIXEL_FORMAT_XRGB_8888: XRGB, 32 bits - * @COGL_PIXEL_FORMAT_ARGB_8888: ARGB, 32 bits - * @COGL_PIXEL_FORMAT_XBGR_8888: XBGR, 32 bits - * @COGL_PIXEL_FORMAT_ABGR_8888: ABGR, 32 bits - * @COGL_PIXEL_FORMAT_RGBA_8888_PRE: Premultiplied RGBA, 32 bits - * @COGL_PIXEL_FORMAT_BGRA_8888_PRE: Premultiplied BGRA, 32 bits - * @COGL_PIXEL_FORMAT_ARGB_8888_PRE: Premultiplied ARGB, 32 bits - * @COGL_PIXEL_FORMAT_ABGR_8888_PRE: Premultiplied ABGR, 32 bits - * @COGL_PIXEL_FORMAT_RGBA_4444_PRE: Premultiplied RGBA, 16 bits - * @COGL_PIXEL_FORMAT_RGBA_5551_PRE: Premultiplied RGBA, 16 bits - * @COGL_PIXEL_FORMAT_RGBA_1010102 : RGBA, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_BGRA_1010102 : BGRA, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_XRGB_2101010 : XRGB, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_ARGB_2101010 : ARGB, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_XBGR_2101010 : XBGR, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_ABGR_2101010 : ABGR, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_RGBA_1010102_PRE: Premultiplied RGBA, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_BGRA_1010102_PRE: Premultiplied BGRA, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_ARGB_2101010_PRE: Premultiplied ARGB, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_ABGR_2101010_PRE: Premultiplied ABGR, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_RGBX_FP_16161616: RGBX half floating point, 64 bit - * @COGL_PIXEL_FORMAT_RGBA_FP_16161616: RGBA half floating point, 64 bit - * @COGL_PIXEL_FORMAT_BGRX_FP_16161616: BGRX half floating point, 64 bit - * @COGL_PIXEL_FORMAT_BGRA_FP_16161616: BGRA half floating point, 64 bit - * @COGL_PIXEL_FORMAT_ARGB_FP_16161616: ARGB half floating point, 64 bit - * @COGL_PIXEL_FORMAT_ABGR_FP_16161616: ABGR half floating point, 64 bit - * @COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: Premultiplied RGBA half floating point, 64 bit - * @COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: Premultiplied BGRA half floating point, 64 bit - * @COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: Premultiplied ARGB half floating point, 64 bit - * @COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: Premultiplied ABGR half floating point, 64 bit - * @COGL_PIXEL_FORMAT_RGBA_FP_32323232: RGBA floating point, 128 bit - * @COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE: Premultiplied RGBA floating point, 128 bit - * @COGL_PIXEL_FORMAT_R_16: Single luminance component, 16 bits - * @COGL_PIXEL_FORMAT_RG_1616: RG, 32 bits - * @COGL_PIXEL_FORMAT_RGBA_16161616: RGBA, 64 bits, 16bpc - * - * Pixel formats used by Cogl. For the formats with a byte per - * component, the order of the components specify the order in - * increasing memory addresses. So for example - * %COGL_PIXEL_FORMAT_RGB_888 would have the red component in the - * lowest address, green in the next address and blue after that - * regardless of the endianness of the system. - * - * For the formats with non byte aligned components the component - * order specifies the order within a 16-bit or 32-bit number from - * most significant bit to least significant. So for - * %COGL_PIXEL_FORMAT_RGB_565, the red component would be in bits - * 11-15, the green component would be in 6-11 and the blue component - * would be in 1-5. Therefore the order in memory depends on the - * endianness of the system. - * - * When uploading a texture %COGL_PIXEL_FORMAT_ANY can be used as the - * internal format. Cogl will try to pick the best format to use - * internally and convert the texture data if necessary. - */ -typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/ -{ - COGL_PIXEL_FORMAT_ANY = 0, - COGL_PIXEL_FORMAT_A_8 = 1 | COGL_A_BIT, - - COGL_PIXEL_FORMAT_RGB_565 = 4, - COGL_PIXEL_FORMAT_RGBA_4444 = 5 | COGL_A_BIT, - COGL_PIXEL_FORMAT_RGBA_5551 = 6 | COGL_A_BIT, - COGL_PIXEL_FORMAT_YUV = 7, - COGL_PIXEL_FORMAT_R_8 = 8, - COGL_PIXEL_FORMAT_RG_88 = 9, - - COGL_PIXEL_FORMAT_RGB_888 = 2, - COGL_PIXEL_FORMAT_BGR_888 = (2 | COGL_BGR_BIT), - - COGL_PIXEL_FORMAT_RGBX_8888 = 3, - COGL_PIXEL_FORMAT_RGBA_8888 = (3 | COGL_A_BIT), - COGL_PIXEL_FORMAT_BGRX_8888 = (3 | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_BGRA_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_XRGB_8888 = (3 | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ARGB_8888 = (3 | COGL_A_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_XBGR_8888 = (3 | COGL_BGR_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ABGR_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), - - COGL_PIXEL_FORMAT_RGBA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_BGRA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_ARGB_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ABGR_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_RGBA_4444_PRE = (COGL_PIXEL_FORMAT_RGBA_4444 | COGL_A_BIT | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_RGBA_5551_PRE = (COGL_PIXEL_FORMAT_RGBA_5551 | COGL_A_BIT | COGL_PREMULT_BIT), - - COGL_PIXEL_FORMAT_RGBA_1010102 = (13 | COGL_A_BIT), - COGL_PIXEL_FORMAT_BGRA_1010102 = (13 | COGL_A_BIT | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_XRGB_2101010 = (13 | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ARGB_2101010 = (13 | COGL_A_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_XBGR_2101010 = (13 | COGL_BGR_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ABGR_2101010 = (13 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), - - COGL_PIXEL_FORMAT_RGBA_1010102_PRE = (COGL_PIXEL_FORMAT_RGBA_1010102 | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_BGRA_1010102_PRE = (COGL_PIXEL_FORMAT_BGRA_1010102 | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_ARGB_2101010_PRE = (COGL_PIXEL_FORMAT_ARGB_2101010 | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_ABGR_2101010_PRE = (COGL_PIXEL_FORMAT_ABGR_2101010 | COGL_PREMULT_BIT), - - COGL_PIXEL_FORMAT_RGBX_FP_16161616 = 11, - COGL_PIXEL_FORMAT_RGBA_FP_16161616 = (11 | COGL_A_BIT), - COGL_PIXEL_FORMAT_BGRX_FP_16161616 = (11 | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_BGRA_FP_16161616 = (11 | COGL_A_BIT | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_XRGB_FP_16161616 = (11 | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ARGB_FP_16161616 = (11 | COGL_A_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_XBGR_FP_16161616 = (11 | COGL_BGR_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ABGR_FP_16161616 = (11 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), - - COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE = (11 | COGL_A_BIT | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE = (11 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE = (11 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE = (11 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), - - COGL_PIXEL_FORMAT_RGBA_FP_32323232 = (12 | COGL_A_BIT), - COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE = (12 | COGL_A_BIT | COGL_PREMULT_BIT), - - COGL_PIXEL_FORMAT_R_16 = 14, - COGL_PIXEL_FORMAT_RG_1616 = 15, - COGL_PIXEL_FORMAT_RGBA_16161616 = (10 | COGL_A_BIT), - COGL_PIXEL_FORMAT_RGBA_16161616_PRE = (10 | COGL_A_BIT | COGL_PREMULT_BIT), - - COGL_PIXEL_FORMAT_DEPTH_16 = (9 | COGL_DEPTH_BIT), - - COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT) -} CoglPixelFormat; - -/** - * COGL_PIXEL_FORMAT_CAIRO_ARGB32_COMPAT: - * - * Architecture dependant format, similar to CAIRO_ARGB32. -*/ -#if G_BYTE_ORDER == G_LITTLE_ENDIAN -#define COGL_PIXEL_FORMAT_CAIRO_ARGB32_COMPAT COGL_PIXEL_FORMAT_BGRA_8888_PRE -#else -#define COGL_PIXEL_FORMAT_CAIRO_ARGB32_COMPAT COGL_PIXEL_FORMAT_ARGB_8888_PRE -#endif - -/** - * COGL_PIXEL_FORMAT_MAX_PLANES: - * - * The maximum number of planes of a pixel format (see also - * cogl_pixel_format_get_planes()). - */ -#define COGL_PIXEL_FORMAT_MAX_PLANES (4) - -/** - * cogl_pixel_format_get_bytes_per_pixel: - * @format: The pixel format - * @plane: The index of the plane (should not be more than the number of planes - * in the given format). - * - * Queries the number of bytes per pixel for a given format in the given plane. - * - * Returns: The number of bytes per pixel in the given format's given plane. - */ -COGL_EXPORT int -cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format, - int plane); - -/* - * _cogl_pixel_format_has_aligned_components: - * @format: a #CoglPixelFormat - * - * Queries whether the ordering of the components for the given - * @format depend on the endianness of the host CPU or if the - * components can be accessed using bit shifting and bitmasking by - * loading a whole pixel into a word. - * - * XXX: If we ever consider making something like this public we - * should really try to think of a better name and come up with - * much clearer documentation since it really depends on what - * point of view you consider this from whether a format like - * COGL_PIXEL_FORMAT_RGBA_8888 is endian dependent. E.g. If you - * read an RGBA_8888 pixel into a uint32 - * it's endian dependent how you mask out the different channels. - * But If you already have separate color components and you want - * to write them to an RGBA_8888 pixel then the bytes can be - * written sequentially regardless of the endianness. - * - * Return value: %TRUE if you need to consider the host CPU - * endianness when dealing with the given @format - * else %FALSE. - */ -gboolean -_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format); - -/* - * COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format): - * @format: a #CoglPixelFormat - * - * Returns TRUE if the pixel format can take a premult bit. This is - * currently true for all formats that have an alpha channel except - * COGL_PIXEL_FORMAT_A_8 (because that doesn't have any other - * components to multiply by the alpha). - */ -#define COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format) \ - (((format) & COGL_A_BIT) && (format) != COGL_PIXEL_FORMAT_A_8) - -/** - * cogl_pixel_format_get_n_planes: - * @format: The format for which to get the number of planes - * - * Returns the number of planes the given CoglPixelFormat specifies. - * - * Returns: The no. of planes of @format (at most %COGL_PIXEL_FORMAT_MAX_PLANES) - */ -COGL_EXPORT int -cogl_pixel_format_get_n_planes (CoglPixelFormat format); - -/** - * cogl_pixel_format_to_string: - * @format: a #CoglPixelFormat - * - * Returns a string representation of @format, useful for debugging purposes. - * - * Returns: (transfer none): A string representation of @format. - */ -COGL_EXPORT const char * -cogl_pixel_format_to_string (CoglPixelFormat format); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-point-in-poly-private.h b/mutter/cogl/cogl/cogl-point-in-poly-private.h deleted file mode 100644 index 862a2fb..0000000 --- a/mutter/cogl/cogl/cogl-point-in-poly-private.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#include - -G_BEGIN_DECLS - -int -_cogl_util_point_in_screen_poly (float point_x, - float point_y, - void *vertices, - size_t stride, - int n_vertices); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-point-in-poly.c b/mutter/cogl/cogl/cogl-point-in-poly.c deleted file mode 100644 index 25ffc2e..0000000 --- a/mutter/cogl/cogl/cogl-point-in-poly.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Point Inclusion in Polygon Test - * - * Copyright (c) 1970-2003, Wm. Randolph Franklin - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimers. - * 2. Redistributions in binary form must reproduce the above - * copyright notice in the documentation and/or other materials - * provided with the distribution. - * 3. The name of W. Randolph Franklin may not be used to endorse or - * promote products derived from this Software without specific - * prior written permission. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Note: - * The algorithm for this point_in_poly() function was learnt from: - * http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html - */ - -#include "config.h" - -#include "cogl/cogl-util.h" -#include "cogl/cogl-point-in-poly-private.h" - -#include - -/* We've made a notable change to the original algorithm referenced - * above to make sure we have reliable results for screen aligned - * rectangles even though there may be some numerical in-precision in - * how the vertices of the polygon were calculated. - * - * We've avoided introducing an epsilon factor to the comparisons - * since we feel there's a risk of changing some semantics in ways that - * might not be desirable. One of those is that if you transform two - * polygons which share an edge and test a point close to that edge - * then this algorithm will currently give a positive result for only - * one polygon. - * - * Another concern is the way this algorithm resolves the corner case - * where the horizontal ray being cast to count edge crossings may - * cross directly through a vertex. The solution is based on the "idea - * of Simulation of Simplicity" and "pretends to shift the ray - * infinitesimally down so that it either clearly intersects, or - * clearly doesn't touch". I'm not familiar with the idea myself so I - * expect a misplaced epsilon is likely to break that aspect of the - * algorithm. - * - * The simple solution we've gone for is to pixel align the polygon - * vertices which should eradicate most noise due to in-precision. - */ -int -_cogl_util_point_in_screen_poly (float point_x, - float point_y, - void *vertices, - size_t stride, - int n_vertices) -{ - int i, j, c = 0; - - for (i = 0, j = n_vertices - 1; i < n_vertices; j = i++) - { - float vert_xi = *(float *)((uint8_t *)vertices + i * stride); - float vert_xj = *(float *)((uint8_t *)vertices + j * stride); - float vert_yi = *(float *)((uint8_t *)vertices + i * stride + - sizeof (float)); - float vert_yj = *(float *)((uint8_t *)vertices + j * stride + - sizeof (float)); - - vert_xi = COGL_UTIL_NEARBYINT (vert_xi); - vert_xj = COGL_UTIL_NEARBYINT (vert_xj); - vert_yi = COGL_UTIL_NEARBYINT (vert_yi); - vert_yj = COGL_UTIL_NEARBYINT (vert_yj); - - if (((vert_yi > point_y) != (vert_yj > point_y)) && - (point_x < (vert_xj - vert_xi) * (point_y - vert_yi) / - (vert_yj - vert_yi) + vert_xi) ) - c = !c; - } - - return c; -} - diff --git a/mutter/cogl/cogl/cogl-poll-private.h b/mutter/cogl/cogl/cogl-poll-private.h deleted file mode 100644 index 1512d2c..0000000 --- a/mutter/cogl/cogl/cogl-poll-private.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-poll.h" -#include "cogl/cogl-renderer.h" -#include "cogl/cogl-closure-list-private.h" - -typedef int64_t (*CoglPollPrepareCallback) (void *user_data); -typedef void (*CoglPollDispatchCallback) (void *user_data, int revents); - -void -_cogl_poll_renderer_add_fd (CoglRenderer *renderer, - int fd, - CoglPollFDEvent events, - CoglPollPrepareCallback prepare, - CoglPollDispatchCallback dispatch, - void *user_data); - -typedef struct _CoglPollSource CoglPollSource; - -CoglPollSource * -_cogl_poll_renderer_add_source (CoglRenderer *renderer, - CoglPollPrepareCallback prepare, - CoglPollDispatchCallback dispatch, - void *user_data); - -typedef void (*CoglIdleCallback) (void *user_data); - -CoglClosure * -_cogl_poll_renderer_add_idle (CoglRenderer *renderer, - CoglIdleCallback idle_cb, - void *user_data, - GDestroyNotify destroy_cb); diff --git a/mutter/cogl/cogl/cogl-poll.c b/mutter/cogl/cogl/cogl-poll.c deleted file mode 100644 index 1d93c00..0000000 --- a/mutter/cogl/cogl/cogl-poll.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Neil Roberts - */ - -#include "config.h" - -#include "cogl/cogl-poll.h" -#include "cogl/cogl-poll-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/winsys/cogl-winsys-private.h" - -struct _CoglPollSource -{ - int fd; - CoglPollPrepareCallback prepare; - CoglPollDispatchCallback dispatch; - void *user_data; -}; - -int -cogl_poll_renderer_get_info (CoglRenderer *renderer, - CoglPollFD **poll_fds, - int *n_poll_fds, - int64_t *timeout) -{ - GList *l, *next; - - g_return_val_if_fail (COGL_IS_RENDERER (renderer), 0); - g_return_val_if_fail (poll_fds != NULL, 0); - g_return_val_if_fail (n_poll_fds != NULL, 0); - g_return_val_if_fail (timeout != NULL, 0); - - *timeout = -1; - - if (!_cogl_list_empty (&renderer->idle_closures)) - *timeout = 0; - - /* This loop needs to cope with the prepare callback removing its - * own fd */ - for (l = renderer->poll_sources; l; l = next) - { - CoglPollSource *source = l->data; - - next = l->next; - - if (source->prepare) - { - int64_t source_timeout = source->prepare (source->user_data); - if (source_timeout >= 0 && - (*timeout == -1 || *timeout > source_timeout)) - *timeout = source_timeout; - } - } - - /* This is deliberately set after calling the prepare callbacks in - * case one of them removes its fd */ - *poll_fds = (void *)renderer->poll_fds->data; - *n_poll_fds = renderer->poll_fds->len; - - return renderer->poll_fds_age; -} - -void -cogl_poll_renderer_dispatch (CoglRenderer *renderer, - const CoglPollFD *poll_fds, - int n_poll_fds) -{ - GList *l, *next; - - g_return_if_fail (COGL_IS_RENDERER (renderer)); - - _cogl_closure_list_invoke_no_args (&renderer->idle_closures); - - /* This loop needs to cope with the dispatch callback removing its - * own fd */ - for (l = renderer->poll_sources; l; l = next) - { - CoglPollSource *source = l->data; - int i; - - next = l->next; - - if (source->fd == -1) - { - source->dispatch (source->user_data, 0); - continue; - } - - for (i = 0; i < n_poll_fds; i++) - { - const CoglPollFD *pollfd = &poll_fds[i]; - - if (pollfd->fd == source->fd) - { - source->dispatch (source->user_data, pollfd->revents); - break; - } - } - } -} - -static int -find_pollfd (CoglRenderer *renderer, int fd) -{ - int i; - - for (i = 0; i < renderer->poll_fds->len; i++) - { - CoglPollFD *pollfd = &g_array_index (renderer->poll_fds, CoglPollFD, i); - - if (pollfd->fd == fd) - return i; - } - - return -1; -} - -static void -_cogl_poll_renderer_remove_fd (CoglRenderer *renderer, int fd) -{ - int i = find_pollfd (renderer, fd); - GList *l; - - if (i < 0) - return; - - g_array_remove_index_fast (renderer->poll_fds, i); - renderer->poll_fds_age++; - - for (l = renderer->poll_sources; l; l = l->next) - { - CoglPollSource *source = l->data; - if (source->fd == fd) - { - renderer->poll_sources = - g_list_delete_link (renderer->poll_sources, l); - g_free (source); - break; - } - } -} - -void -_cogl_poll_renderer_add_fd (CoglRenderer *renderer, - int fd, - CoglPollFDEvent events, - CoglPollPrepareCallback prepare, - CoglPollDispatchCallback dispatch, - void *user_data) -{ - CoglPollFD pollfd = { - fd, - events - }; - CoglPollSource *source; - - _cogl_poll_renderer_remove_fd (renderer, fd); - - source = g_new0 (CoglPollSource, 1); - source->fd = fd; - source->prepare = prepare; - source->dispatch = dispatch; - source->user_data = user_data; - - renderer->poll_sources = g_list_prepend (renderer->poll_sources, source); - - g_array_append_val (renderer->poll_fds, pollfd); - renderer->poll_fds_age++; -} - -CoglPollSource * -_cogl_poll_renderer_add_source (CoglRenderer *renderer, - CoglPollPrepareCallback prepare, - CoglPollDispatchCallback dispatch, - void *user_data) -{ - CoglPollSource *source; - - source = g_new0 (CoglPollSource, 1); - source->fd = -1; - source->prepare = prepare; - source->dispatch = dispatch; - source->user_data = user_data; - - renderer->poll_sources = g_list_prepend (renderer->poll_sources, source); - - return source; -} - -CoglClosure * -_cogl_poll_renderer_add_idle (CoglRenderer *renderer, - CoglIdleCallback idle_cb, - void *user_data, - GDestroyNotify destroy_cb) -{ - return _cogl_closure_list_add (&renderer->idle_closures, - idle_cb, - user_data, - destroy_cb); -} diff --git a/mutter/cogl/cogl/cogl-poll.h b/mutter/cogl/cogl/cogl-poll.h deleted file mode 100644 index 1ccb729..0000000 --- a/mutter/cogl/cogl/cogl-poll.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Neil Roberts - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-context.h" - -#include - -#define COGL_SYSDEF_POLLIN POLLIN -#define COGL_SYSDEF_POLLPRI POLLPRI -#define COGL_SYSDEF_POLLOUT POLLOUT -#define COGL_SYSDEF_POLLERR POLLERR -#define COGL_SYSDEF_POLLHUP POLLHUP -#define COGL_SYSDEF_POLLNVAL POLLNVAL - -G_BEGIN_DECLS - -/** - * CoglPoll: - * - * Functions for integrating Cogl with an application's main loop - * - * Cogl needs to integrate with the application's main loop so that it - * can internally handle some events from the driver. All Cogl - * applications must use these functions. They provide enough - * information to describe the state that Cogl will need to wake up - * on. An application using the GLib main loop can instead use - * cogl_glib_source_new() which provides a #GSource ready to be added - * to the main loop. - */ - -/** - * CoglPollFDEvent: - * @COGL_POLL_FD_EVENT_IN: there is data to read - * @COGL_POLL_FD_EVENT_PRI: data can be written (without blocking) - * @COGL_POLL_FD_EVENT_OUT: there is urgent data to read. - * @COGL_POLL_FD_EVENT_ERR: error condition - * @COGL_POLL_FD_EVENT_HUP: hung up (the connection has been broken, usually - * for pipes and sockets). - * @COGL_POLL_FD_EVENT_NVAL: invalid request. The file descriptor is not open. - * - * A bitmask of events that Cogl may need to wake on for a file - * descriptor. Note that these all have the same values as the - * corresponding defines for the poll function call on Unix so they - * may be directly passed to poll. - */ -typedef enum -{ - COGL_POLL_FD_EVENT_IN = COGL_SYSDEF_POLLIN, - COGL_POLL_FD_EVENT_PRI = COGL_SYSDEF_POLLPRI, - COGL_POLL_FD_EVENT_OUT = COGL_SYSDEF_POLLOUT, - COGL_POLL_FD_EVENT_ERR = COGL_SYSDEF_POLLERR, - COGL_POLL_FD_EVENT_HUP = COGL_SYSDEF_POLLHUP, - COGL_POLL_FD_EVENT_NVAL = COGL_SYSDEF_POLLNVAL -} CoglPollFDEvent; - -/** - * CoglPollFD: - * @fd: The file descriptor to block on - * @events: A bitmask of events to block on - * @revents: A bitmask of returned events - * - * A struct for describing the state of a file descriptor that Cogl - * needs to block on. The @events field contains a bitmask of - * `CoglPollFDEvent`s that should cause the application to wake - * up. After the application is woken up from idle it should pass back - * an array of `CoglPollFD`s to Cogl and update the @revents - * mask to the actual events that occurred on the file descriptor. - * - * Note that CoglPollFD is deliberately exactly the same as struct - * pollfd on Unix so that it can simply be cast when calling poll. - */ -typedef struct { - int fd; - short int events; - short int revents; -} CoglPollFD; - -/** - * cogl_poll_renderer_get_info: - * @renderer: A #CoglRenderer - * @poll_fds: A return location for a pointer to an array - * of `CoglPollFD`s - * @n_poll_fds: A return location for the number of entries in *@poll_fds - * @timeout: A return location for the maximum length of time to wait - * in microseconds, or -1 to wait indefinitely. - * - * Is used to integrate Cogl with an application mainloop that is based - * on the unix poll(2) api (or select() or something equivalent). This - * api should be called whenever an application is about to go idle so - * that Cogl has a chance to describe what file descriptor events it - * needs to be woken up for. - * - * If your application is using the Glib mainloop then you - * should jump to the cogl_glib_source_new() api as a more convenient - * way of integrating Cogl with the mainloop. - * - * After the function is called *@poll_fds will contain a pointer to - * an array of #CoglPollFD structs describing the file descriptors - * that Cogl expects. The fd and events members will be updated - * accordingly. After the application has completed its idle it is - * expected to either update the revents members directly in this - * array or to create a copy of the array and update them - * there. - * - * When the application mainloop returns from calling poll(2) (or its - * equivalent) then it should call cogl_poll_renderer_dispatch() - * passing a pointer the array of `CoglPollFD`s with updated - * revent values. - * - * @timeout will contain a maximum amount of time to wait in - * microseconds before the application should wake up or -1 if the - * application should wait indefinitely. This can also be 0 if - * Cogl needs to be woken up immediately. - * - * Return value: A "poll fd state age" that changes whenever the set - * of poll_fds has changed. If this API is being used to - * integrate with another system mainloop api then - * knowing if the set of file descriptors and events has - * really changed can help avoid redundant work - * depending the api. The age isn't guaranteed to change - * when the timeout changes. - */ -COGL_EXPORT int -cogl_poll_renderer_get_info (CoglRenderer *renderer, - CoglPollFD **poll_fds, - int *n_poll_fds, - int64_t *timeout); - -/** - * cogl_poll_renderer_dispatch: - * @renderer: A #CoglRenderer - * @poll_fds: An array of `CoglPollFD`s describing the events - * that have occurred since the application went idle. - * @n_poll_fds: The length of the @poll_fds array. - * - * This should be called whenever an application is woken up from - * going idle in its main loop. The @poll_fds array should contain a - * list of file descriptors matched with the events that occurred in - * revents. The events field is ignored. It is safe to pass in extra - * file descriptors that Cogl didn't request when calling - * cogl_poll_renderer_get_info() or a shorter array missing some file - * descriptors that Cogl requested. - */ -COGL_EXPORT void -cogl_poll_renderer_dispatch (CoglRenderer *renderer, - const CoglPollFD *poll_fds, - int n_poll_fds); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-primitive-private.h b/mutter/cogl/cogl/cogl-primitive-private.h deleted file mode 100644 index 64ef890..0000000 --- a/mutter/cogl/cogl/cogl-primitive-private.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-attribute-buffer-private.h" -#include "cogl/cogl-attribute-private.h" -#include "cogl/cogl-framebuffer.h" - -struct _CoglPrimitive -{ - GObject parent_instance; - - CoglIndices *indices; - CoglVerticesMode mode; - int first_vertex; - int n_vertices; - - int immutable_ref; - - GPtrArray *attributes; - int n_attributes; -}; - -CoglPrimitive * -_cogl_primitive_immutable_ref (CoglPrimitive *primitive); - -void -_cogl_primitive_immutable_unref (CoglPrimitive *primitive); - -void -_cogl_primitive_draw (CoglPrimitive *primitive, - CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglDrawFlags flags); diff --git a/mutter/cogl/cogl/cogl-primitive-texture.c b/mutter/cogl/cogl/cogl-primitive-texture.c deleted file mode 100644 index e703a69..0000000 --- a/mutter/cogl/cogl/cogl-primitive-texture.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Neil Roberts - */ - -#include "config.h" - -#include "cogl/cogl-primitive-texture.h" -#include "cogl/cogl-texture-private.h" - - -void -cogl_primitive_texture_set_auto_mipmap (CoglTexture *texture, - gboolean value) -{ - g_return_if_fail (COGL_IS_TEXTURE (texture) && - texture->is_primitive); - - g_assert (COGL_TEXTURE_GET_CLASS (texture)->set_auto_mipmap != NULL); - - COGL_TEXTURE_GET_CLASS (texture)->set_auto_mipmap (texture, value); -} diff --git a/mutter/cogl/cogl/cogl-primitive-texture.h b/mutter/cogl/cogl/cogl-primitive-texture.h deleted file mode 100644 index 98de61c..0000000 --- a/mutter/cogl/cogl/cogl-primitive-texture.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-texture.h" - -G_BEGIN_DECLS - -/** - * cogl_primitive_texture_set_auto_mipmap: - * @primitive_texture: A #CoglPrimitiveTexture - * @value: The new value for whether to auto mipmap - * - * Sets whether the texture will automatically update the smaller - * mipmap levels after any part of level 0 is updated. The update will - * only occur whenever the texture is used for drawing with a texture - * filter that requires the lower mipmap levels. An application should - * disable this if it wants to upload its own data for the other - * levels. By default auto mipmapping is enabled. - */ -COGL_EXPORT void -cogl_primitive_texture_set_auto_mipmap (CoglTexture *primitive_texture, - gboolean value); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-primitive.c b/mutter/cogl/cogl/cogl-primitive.c deleted file mode 100644 index d31eeeb..0000000 --- a/mutter/cogl/cogl/cogl-primitive.c +++ /dev/null @@ -1,588 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-util.h" -#include "cogl/cogl-primitive.h" -#include "cogl/cogl-primitive-private.h" -#include "cogl/cogl-attribute-private.h" -#include "cogl/cogl-framebuffer-private.h" - -#include -#include - -G_DEFINE_TYPE (CoglPrimitive, cogl_primitive, G_TYPE_OBJECT); - -static void -cogl_primitive_dispose (GObject *object) -{ - CoglPrimitive *primitive = COGL_PRIMITIVE (object); - - g_ptr_array_free (primitive->attributes, TRUE); - - if (primitive->indices) - g_object_unref (primitive->indices); - - G_OBJECT_CLASS (cogl_primitive_parent_class)->dispose (object); -} - -static void -cogl_primitive_class_init (CoglPrimitiveClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = cogl_primitive_dispose; -} - -static void -cogl_primitive_init (CoglPrimitive *primitive) -{ - primitive->first_vertex = 0; - primitive->immutable_ref = 0; - primitive->indices = NULL; - primitive->attributes = g_ptr_array_new_with_free_func (g_object_unref); -} - -CoglPrimitive * -cogl_primitive_new_with_attributes (CoglVerticesMode mode, - int n_vertices, - CoglAttribute **attributes, - int n_attributes) -{ - CoglPrimitive *primitive; - int i; - - primitive = g_object_new (COGL_TYPE_PRIMITIVE, NULL); - primitive->mode = mode; - primitive->n_vertices = n_vertices; - - primitive->n_attributes = n_attributes; - for (i = 0; i < n_attributes; i++) - { - CoglAttribute *attribute = attributes[i]; - g_object_ref (attribute); - - g_return_val_if_fail (COGL_IS_ATTRIBUTE (attribute), NULL); - - g_ptr_array_add (primitive->attributes, attribute); - } - - return primitive; -} - -/* This is just an internal convenience wrapper around - new_with_attributes that also unrefs the attributes. It is just - used for the builtin struct constructors */ -static CoglPrimitive * -_cogl_primitive_new_with_attributes_unref (CoglVerticesMode mode, - int n_vertices, - CoglAttribute **attributes, - int n_attributes) -{ - CoglPrimitive *primitive; - int i; - - primitive = cogl_primitive_new_with_attributes (mode, - n_vertices, - attributes, - n_attributes); - - for (i = 0; i < n_attributes; i++) - g_object_unref (attributes[i]); - - return primitive; -} - -CoglPrimitive * -cogl_primitive_new (CoglVerticesMode mode, - int n_vertices, - ...) -{ - va_list ap; - int n_attributes; - CoglAttribute **attributes; - int i; - CoglAttribute *attribute; - - va_start (ap, n_vertices); - for (n_attributes = 0; va_arg (ap, CoglAttribute *); n_attributes++) - ; - va_end (ap); - - attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes); - - va_start (ap, n_vertices); - for (i = 0; (attribute = va_arg (ap, CoglAttribute *)); i++) - attributes[i] = attribute; - va_end (ap); - - return cogl_primitive_new_with_attributes (mode, n_vertices, - attributes, - i); -} - -CoglPrimitive * -cogl_primitive_new_p2 (CoglContext *ctx, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2 *data) -{ - CoglAttributeBuffer *attribute_buffer = - cogl_attribute_buffer_new (ctx, n_vertices * sizeof (CoglVertexP2), data); - CoglAttribute *attributes[1]; - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP2), - offsetof (CoglVertexP2, x), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - - g_object_unref (attribute_buffer); - - return _cogl_primitive_new_with_attributes_unref (mode, n_vertices, - attributes, - 1); -} - -CoglPrimitive * -cogl_primitive_new_p3 (CoglContext *ctx, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3 *data) -{ - CoglAttributeBuffer *attribute_buffer = - cogl_attribute_buffer_new (ctx, n_vertices * sizeof (CoglVertexP3), data); - CoglAttribute *attributes[1]; - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP3), - offsetof (CoglVertexP3, x), - 3, - COGL_ATTRIBUTE_TYPE_FLOAT); - - g_object_unref (attribute_buffer); - - return _cogl_primitive_new_with_attributes_unref (mode, n_vertices, - attributes, - 1); -} - -CoglPrimitive * -cogl_primitive_new_p2c4 (CoglContext *ctx, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2C4 *data) -{ - CoglAttributeBuffer *attribute_buffer = - cogl_attribute_buffer_new (ctx, n_vertices * sizeof (CoglVertexP2C4), data); - CoglAttribute *attributes[2]; - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP2C4), - offsetof (CoglVertexP2C4, x), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (attribute_buffer, - "cogl_color_in", - sizeof (CoglVertexP2C4), - offsetof (CoglVertexP2C4, r), - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - - g_object_unref (attribute_buffer); - - return _cogl_primitive_new_with_attributes_unref (mode, n_vertices, - attributes, - 2); -} - -CoglPrimitive * -cogl_primitive_new_p3c4 (CoglContext *ctx, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3C4 *data) -{ - CoglAttributeBuffer *attribute_buffer = - cogl_attribute_buffer_new (ctx, n_vertices * sizeof (CoglVertexP3C4), data); - CoglAttribute *attributes[2]; - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP3C4), - offsetof (CoglVertexP3C4, x), - 3, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (attribute_buffer, - "cogl_color_in", - sizeof (CoglVertexP3C4), - offsetof (CoglVertexP3C4, r), - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - - g_object_unref (attribute_buffer); - - return _cogl_primitive_new_with_attributes_unref (mode, n_vertices, - attributes, - 2); -} - -CoglPrimitive * -cogl_primitive_new_p2t2 (CoglContext *ctx, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2T2 *data) -{ - CoglAttributeBuffer *attribute_buffer = - cogl_attribute_buffer_new (ctx, n_vertices * sizeof (CoglVertexP2T2), data); - CoglAttribute *attributes[2]; - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP2T2), - offsetof (CoglVertexP2T2, x), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (attribute_buffer, - "cogl_tex_coord0_in", - sizeof (CoglVertexP2T2), - offsetof (CoglVertexP2T2, s), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - - g_object_unref (attribute_buffer); - - return _cogl_primitive_new_with_attributes_unref (mode, n_vertices, - attributes, - 2); -} - -CoglPrimitive * -cogl_primitive_new_p3t2 (CoglContext *ctx, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3T2 *data) -{ - CoglAttributeBuffer *attribute_buffer = - cogl_attribute_buffer_new (ctx, n_vertices * sizeof (CoglVertexP3T2), data); - CoglAttribute *attributes[2]; - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP3T2), - offsetof (CoglVertexP3T2, x), - 3, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (attribute_buffer, - "cogl_tex_coord0_in", - sizeof (CoglVertexP3T2), - offsetof (CoglVertexP3T2, s), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - - g_object_unref (attribute_buffer); - - return _cogl_primitive_new_with_attributes_unref (mode, n_vertices, - attributes, - 2); -} - -CoglPrimitive * -cogl_primitive_new_p2t2c4 (CoglContext *ctx, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2T2C4 *data) -{ - CoglAttributeBuffer *attribute_buffer = - cogl_attribute_buffer_new (ctx, - n_vertices * sizeof (CoglVertexP2T2C4), data); - CoglAttribute *attributes[3]; - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP2T2C4), - offsetof (CoglVertexP2T2C4, x), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (attribute_buffer, - "cogl_tex_coord0_in", - sizeof (CoglVertexP2T2C4), - offsetof (CoglVertexP2T2C4, s), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[2] = cogl_attribute_new (attribute_buffer, - "cogl_color_in", - sizeof (CoglVertexP2T2C4), - offsetof (CoglVertexP2T2C4, r), - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - - g_object_unref (attribute_buffer); - - return _cogl_primitive_new_with_attributes_unref (mode, n_vertices, - attributes, - 3); -} - -CoglPrimitive * -cogl_primitive_new_p3t2c4 (CoglContext *ctx, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3T2C4 *data) -{ - CoglAttributeBuffer *attribute_buffer = - cogl_attribute_buffer_new (ctx, - n_vertices * sizeof (CoglVertexP3T2C4), data); - CoglAttribute *attributes[3]; - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP3T2C4), - offsetof (CoglVertexP3T2C4, x), - 3, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (attribute_buffer, - "cogl_tex_coord0_in", - sizeof (CoglVertexP3T2C4), - offsetof (CoglVertexP3T2C4, s), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[2] = cogl_attribute_new (attribute_buffer, - "cogl_color_in", - sizeof (CoglVertexP3T2C4), - offsetof (CoglVertexP3T2C4, r), - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - - g_object_unref (attribute_buffer); - - return _cogl_primitive_new_with_attributes_unref (mode, n_vertices, - attributes, - 3); -} - -static void -warn_about_midscene_changes (void) -{ - static gboolean seen = FALSE; - if (!seen) - { - g_warning ("Mid-scene modification of primitives has " - "undefined results\n"); - seen = TRUE; - } -} - -int -cogl_primitive_get_first_vertex (CoglPrimitive *primitive) -{ - g_return_val_if_fail (COGL_IS_PRIMITIVE (primitive), 0); - - return primitive->first_vertex; -} - -void -cogl_primitive_set_first_vertex (CoglPrimitive *primitive, - int first_vertex) -{ - g_return_if_fail (COGL_IS_PRIMITIVE (primitive)); - - if (G_UNLIKELY (primitive->immutable_ref)) - { - warn_about_midscene_changes (); - return; - } - - primitive->first_vertex = first_vertex; -} - -int -cogl_primitive_get_n_vertices (CoglPrimitive *primitive) -{ - g_return_val_if_fail (COGL_IS_PRIMITIVE (primitive), 0); - - return primitive->n_vertices; -} - -void -cogl_primitive_set_n_vertices (CoglPrimitive *primitive, - int n_vertices) -{ - g_return_if_fail (COGL_IS_PRIMITIVE (primitive)); - - primitive->n_vertices = n_vertices; -} - -CoglVerticesMode -cogl_primitive_get_mode (CoglPrimitive *primitive) -{ - g_return_val_if_fail (COGL_IS_PRIMITIVE (primitive), 0); - - return primitive->mode; -} - -void -cogl_primitive_set_mode (CoglPrimitive *primitive, - CoglVerticesMode mode) -{ - g_return_if_fail (COGL_IS_PRIMITIVE (primitive)); - - if (G_UNLIKELY (primitive->immutable_ref)) - { - warn_about_midscene_changes (); - return; - } - - primitive->mode = mode; -} - -void -cogl_primitive_set_indices (CoglPrimitive *primitive, - CoglIndices *indices, - int n_indices) -{ - g_return_if_fail (COGL_IS_PRIMITIVE (primitive)); - - if (G_UNLIKELY (primitive->immutable_ref)) - { - warn_about_midscene_changes (); - return; - } - - if (indices) - g_object_ref (indices); - if (primitive->indices) - g_object_unref (primitive->indices); - primitive->indices = indices; - primitive->n_vertices = n_indices; -} - -CoglIndices * -cogl_primitive_get_indices (CoglPrimitive *primitive) -{ - return primitive->indices; -} - -CoglPrimitive * -cogl_primitive_copy (CoglPrimitive *primitive) -{ - CoglPrimitive *copy; - - copy = cogl_primitive_new_with_attributes (primitive->mode, - primitive->n_vertices, - (CoglAttribute **)primitive->attributes->pdata, - primitive->n_attributes); - - cogl_primitive_set_indices (copy, primitive->indices, primitive->n_vertices); - cogl_primitive_set_first_vertex (copy, primitive->first_vertex); - - return copy; -} - -CoglPrimitive * -_cogl_primitive_immutable_ref (CoglPrimitive *primitive) -{ - int i; - - g_return_val_if_fail (COGL_IS_PRIMITIVE (primitive), NULL); - - primitive->immutable_ref++; - - for (i = 0; i < primitive->n_attributes; i++) - _cogl_attribute_immutable_ref (primitive->attributes->pdata[i]); - - return primitive; -} - -void -_cogl_primitive_immutable_unref (CoglPrimitive *primitive) -{ - int i; - - g_return_if_fail (COGL_IS_PRIMITIVE (primitive)); - g_return_if_fail (primitive->immutable_ref > 0); - - primitive->immutable_ref--; - - for (i = 0; i < primitive->n_attributes; i++) - _cogl_attribute_immutable_unref (primitive->attributes->pdata[i]); -} - -void -cogl_primitive_foreach_attribute (CoglPrimitive *primitive, - CoglPrimitiveAttributeCallback callback, - void *user_data) -{ - int i; - for (i = 0; i < primitive->n_attributes; i++) - if (!callback (primitive, primitive->attributes->pdata[i], user_data)) - break; -} - -void -_cogl_primitive_draw (CoglPrimitive *primitive, - CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglDrawFlags flags) -{ - if (primitive->indices) - _cogl_framebuffer_draw_indexed_attributes (framebuffer, - pipeline, - primitive->mode, - primitive->first_vertex, - primitive->n_vertices, - primitive->indices, - (CoglAttribute **) primitive->attributes->pdata, - primitive->n_attributes, - flags); - else - _cogl_framebuffer_draw_attributes (framebuffer, - pipeline, - primitive->mode, - primitive->first_vertex, - primitive->n_vertices, - (CoglAttribute **) primitive->attributes->pdata, - primitive->n_attributes, - flags); -} - -void -cogl_primitive_draw (CoglPrimitive *primitive, - CoglFramebuffer *framebuffer, - CoglPipeline *pipeline) -{ - _cogl_primitive_draw (primitive, framebuffer, pipeline, 0 /* flags */); -} diff --git a/mutter/cogl/cogl/cogl-primitive.h b/mutter/cogl/cogl/cogl-primitive.h deleted file mode 100644 index 0de14b2..0000000 --- a/mutter/cogl/cogl/cogl-primitive.h +++ /dev/null @@ -1,817 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -/* We forward declare the CoglPrimitive type here to avoid some circular - * dependency issues with the following headers. - */ -typedef struct _CoglPrimitive CoglPrimitive; - -#include "cogl/cogl-types.h" /* for CoglVerticesMode */ -#include "cogl/cogl-attribute.h" -#include "cogl/cogl-framebuffer.h" - -#include - -G_BEGIN_DECLS - -/** - * CoglPrimitive: - * - *Functions for creating, manipulating and drawing primitives - */ - -#define COGL_TYPE_PRIMITIVE (cogl_primitive_get_type ()) - -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglPrimitive, - cogl_primitive, - COGL, - PRIMITIVE, - GObject) -/** - * CoglVertexP2: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_p2(). - */ -typedef struct { - float x, y; -} CoglVertexP2; - -/** - * CoglVertexP3: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @z: The z component of a position attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_p3(). - */ -typedef struct { - float x, y, z; -} CoglVertexP3; - -/** - * CoglVertexP2C4: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @r: The red component of a color attribute - * @b: The green component of a color attribute - * @g: The blue component of a color attribute - * @a: The alpha component of a color attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_p2c4(). - */ -typedef struct { - float x, y; - uint8_t r, g, b, a; -} CoglVertexP2C4; - -/** - * CoglVertexP3C4: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @z: The z component of a position attribute - * @r: The red component of a color attribute - * @b: The green component of a color attribute - * @g: The blue component of a color attribute - * @a: The alpha component of a color attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_p3c4(). - */ -typedef struct { - float x, y, z; - uint8_t r, g, b, a; -} CoglVertexP3C4; - -/** - * CoglVertexP2T2: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @s: The s component of a texture coordinate attribute - * @t: The t component of a texture coordinate attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_p2t2(). - */ -typedef struct { - float x, y; - float s, t; -} CoglVertexP2T2; - -/** - * CoglVertexP3T2: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @z: The z component of a position attribute - * @s: The s component of a texture coordinate attribute - * @t: The t component of a texture coordinate attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_p3t2(). - */ -typedef struct { - float x, y, z; - float s, t; -} CoglVertexP3T2; - - -/** - * CoglVertexP2T2C4: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @s: The s component of a texture coordinate attribute - * @t: The t component of a texture coordinate attribute - * @r: The red component of a color attribute - * @b: The green component of a color attribute - * @g: The blue component of a color attribute - * @a: The alpha component of a color attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_p3t2c4(). - */ -typedef struct { - float x, y; - float s, t; - uint8_t r, g, b, a; -} CoglVertexP2T2C4; - -/** - * CoglVertexP3T2C4: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @z: The z component of a position attribute - * @s: The s component of a texture coordinate attribute - * @t: The t component of a texture coordinate attribute - * @r: The red component of a color attribute - * @b: The green component of a color attribute - * @g: The blue component of a color attribute - * @a: The alpha component of a color attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_p3t2c4(). - */ -typedef struct { - float x, y, z; - float s, t; - uint8_t r, g, b, a; -} CoglVertexP3T2C4; - -/** - * cogl_primitive_new: - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to process when drawing - * @...: A %NULL terminated list of attributes - * - * Combines a set of `CoglAttribute`s with a specific draw @mode - * and defines a vertex count so a #CoglPrimitive object can be retained and - * drawn later with no addition information required. - * - * The value passed as @n_vertices will simply update the - * #CoglPrimitive `n_vertices` property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - * - * Return value: (transfer full): A newly allocated #CoglPrimitive object - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new (CoglVerticesMode mode, - int n_vertices, - ...); - -/** - * cogl_primitive_new_with_attributes: - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to process when drawing - * @attributes: (array length=n_attributes): An array of CoglAttribute - * @n_attributes: The number of attributes - * - * Combines a set of `CoglAttribute`s with a specific draw @mode - * and defines a vertex count so a #CoglPrimitive object can be retained and - * drawn later with no addition information required. - * - * The value passed as @n_vertices will simply update the - * #CoglPrimitive `n_vertices` property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - * - * Return value: (transfer full): A newly allocated #CoglPrimitive object - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_with_attributes (CoglVerticesMode mode, - int n_vertices, - CoglAttribute **attributes, - int n_attributes); - -/** - * cogl_primitive_new_p2: - * @context: A #CoglContext - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to read from @data and also - * the number of vertices to read when later drawing. - * @data: (array length=n_vertices) (element-type Cogl.VertexP2): An array - * of #CoglVertexP2 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglAttributeBuffer storage, describe the position - * attribute with a #CoglAttribute and upload your data. - * - * For example to draw a convex polygon you can do: - * ```c - * CoglVertexP2 triangle[] = - * { - * { 0, 300 }, - * { 150, 0, }, - * { 300, 300 } - * }; - * prim = cogl_primitive_new_p2 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ``` - * - * The value passed as @n_vertices is initially used to determine how - * much can be read from @data but it will also be used to update the - * #CoglPrimitive `n_vertices` property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - - * The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). If your - * hardware doesn't support non-power of two textures (For example you - * are using GLES 1.1) then you will need to make sure your assets are - * resized to a power-of-two size (though they don't have to be square) - * - * - * Return value: (transfer full): A newly allocated #CoglPrimitive - * with a reference of 1. This can be freed using g_object_unref(). - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_p2 (CoglContext *context, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2 *data); - -/** - * cogl_primitive_new_p3: - * @context: A #CoglContext - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to read from @data and also - * the number of vertices to read when later drawing. - * @data: (array length=n_vertices) (element-type Cogl.VertexP3): An array of - * #CoglVertexP3 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglAttributeBuffer storage, describe the position - * attribute with a #CoglAttribute and upload your data. - * - * For example to draw a convex polygon you can do: - * ```c - * CoglVertexP3 triangle[] = - * { - * { 0, 300, 0 }, - * { 150, 0, 0 }, - * { 300, 300, 0 } - * }; - * prim = cogl_primitive_new_p3 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ``` - * - * The value passed as @n_vertices is initially used to determine how - * much can be read from @data but it will also be used to update the - * #CoglPrimitive `n_vertices` property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - - * The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). If your - * hardware doesn't support non-power of two textures (For example you - * are using GLES 1.1) then you will need to make sure your assets are - * resized to a power-of-two size (though they don't have to be square) - * - * - * Return value: (transfer full): A newly allocated #CoglPrimitive - * with a reference of 1. This can be freed using g_object_unref(). - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_p3 (CoglContext *context, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3 *data); - -/** - * cogl_primitive_new_p2c4: - * @context: A #CoglContext - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to read from @data and also - * the number of vertices to read when later drawing. - * @data: (array length=n_vertices) (element-type Cogl.VertexP2C4): An array - * of #CoglVertexP2C4 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglAttributeBuffer storage, describe the position - * and color attributes with `CoglAttribute`s and upload - * your data. - * - * For example to draw a convex polygon with a linear gradient you - * can do: - * ```c - * CoglVertexP2C4 triangle[] = - * { - * { 0, 300, 0xff, 0x00, 0x00, 0xff }, - * { 150, 0, 0x00, 0xff, 0x00, 0xff }, - * { 300, 300, 0xff, 0x00, 0x00, 0xff } - * }; - * prim = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ``` - * - * The value passed as @n_vertices is initially used to determine how - * much can be read from @data but it will also be used to update the - * #CoglPrimitive `n_vertices` property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - - * The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). If your - * hardware doesn't support non-power of two textures (For example you - * are using GLES 1.1) then you will need to make sure your assets are - * resized to a power-of-two size (though they don't have to be square) - * - * - * Return value: (transfer full): A newly allocated #CoglPrimitive - * with a reference of 1. This can be freed using g_object_unref(). - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_p2c4 (CoglContext *context, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2C4 *data); - -/** - * cogl_primitive_new_p3c4: - * @context: A #CoglContext - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to read from @data and also - * the number of vertices to read when later drawing. - * @data: (array length=n_vertices) (element-type Cogl.VertexP3C4): An array - * of #CoglVertexP3C4 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglAttributeBuffer storage, describe the position - * and color attributes with `CoglAttribute`s and upload - * your data. - * - * For example to draw a convex polygon with a linear gradient you - * can do: - * ```c - * CoglVertexP3C4 triangle[] = - * { - * { 0, 300, 0, 0xff, 0x00, 0x00, 0xff }, - * { 150, 0, 0, 0x00, 0xff, 0x00, 0xff }, - * { 300, 300, 0, 0xff, 0x00, 0x00, 0xff } - * }; - * prim = cogl_primitive_new_p3c4 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ``` - * - * The value passed as @n_vertices is initially used to determine how - * much can be read from @data but it will also be used to update the - * #CoglPrimitive `n_vertices` property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - - * The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). If your - * hardware doesn't support non-power of two textures (For example you - * are using GLES 1.1) then you will need to make sure your assets are - * resized to a power-of-two size (though they don't have to be square) - * - * - * Return value: (transfer full): A newly allocated #CoglPrimitive - * with a reference of 1. This can be freed using g_object_unref(). - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_p3c4 (CoglContext *context, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3C4 *data); - -/** - * cogl_primitive_new_p2t2: - * @context: A #CoglContext - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to read from @data and also - * the number of vertices to read when later drawing. - * @data: (array length=n_vertices) (element-type Cogl.VertexP2T2): An array - * of #CoglVertexP2T2 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglAttributeBuffer storage, describe the position and - * texture coordinate attributes with `CoglAttribute`s and - * upload your data. - * - * For example to draw a convex polygon with texture mapping you can - * do: - * ```c - * CoglVertexP2T2 triangle[] = - * { - * { 0, 300, 0.0, 1.0}, - * { 150, 0, 0.5, 0.0}, - * { 300, 300, 1.0, 1.0} - * }; - * prim = cogl_primitive_new_p2t2 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ``` - * - * The value passed as @n_vertices is initially used to determine how - * much can be read from @data but it will also be used to update the - * #CoglPrimitive `n_vertices` property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - - * The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). If your - * hardware doesn't support non-power of two textures (For example you - * are using GLES 1.1) then you will need to make sure your assets are - * resized to a power-of-two size (though they don't have to be square) - * - * - * Return value: (transfer full): A newly allocated #CoglPrimitive - * with a reference of 1. This can be freed using g_object_unref(). - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_p2t2 (CoglContext *context, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2T2 *data); - -/** - * cogl_primitive_new_p3t2: - * @context: A #CoglContext - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to read from @data and also - * the number of vertices to read when later drawing. - * @data: (array length=n_vertices) (element-type Cogl.VertexP3T2): An array - * of #CoglVertexP3T2 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglAttributeBuffer storage, describe the position and - * texture coordinate attributes with `CoglAttribute`s and - * upload your data. - * - * For example to draw a convex polygon with texture mapping you can - * do: - * ```c - * CoglVertexP3T2 triangle[] = - * { - * { 0, 300, 0, 0.0, 1.0}, - * { 150, 0, 0, 0.5, 0.0}, - * { 300, 300, 0, 1.0, 1.0} - * }; - * prim = cogl_primitive_new_p3t2 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ``` - * - * The value passed as @n_vertices is initially used to determine how - * much can be read from @data but it will also be used to update the - * #CoglPrimitive `n_vertices` property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - - * The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). If your - * hardware doesn't support non-power of two textures (For example you - * are using GLES 1.1) then you will need to make sure your assets are - * resized to a power-of-two size (though they don't have to be square) - * - * - * Return value: (transfer full): A newly allocated #CoglPrimitive - * with a reference of 1. This can be freed using g_object_unref(). - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_p3t2 (CoglContext *context, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3T2 *data); - -/** - * cogl_primitive_new_p2t2c4: - * @context: A #CoglContext - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to read from @data and also - * the number of vertices to read when later drawing. - * @data: (array length=n_vertices) (element-type Cogl.VertexP2T2C4): An - * array of #CoglVertexP2T2C4 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglAttributeBuffer storage, describe the position, texture - * coordinate and color attributes with `CoglAttribute`s and - * upload your data. - * - * For example to draw a convex polygon with texture mapping and a - * linear gradient you can do: - * ```c - * CoglVertexP2T2C4 triangle[] = - * { - * { 0, 300, 0.0, 1.0, 0xff, 0x00, 0x00, 0xff}, - * { 150, 0, 0.5, 0.0, 0x00, 0xff, 0x00, 0xff}, - * { 300, 300, 1.0, 1.0, 0xff, 0x00, 0x00, 0xff} - * }; - * prim = cogl_primitive_new_p2t2c4 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ``` - * - * The value passed as @n_vertices is initially used to determine how - * much can be read from @data but it will also be used to update the - * #CoglPrimitive `n_vertices` property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - - * The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). If your - * hardware doesn't support non-power of two textures (For example you - * are using GLES 1.1) then you will need to make sure your assets are - * resized to a power-of-two size (though they don't have to be square) - * - * - * Return value: (transfer full): A newly allocated #CoglPrimitive - * with a reference of 1. This can be freed using g_object_unref(). - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_p2t2c4 (CoglContext *context, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2T2C4 *data); - -/** - * cogl_primitive_new_p3t2c4: - * @context: A #CoglContext - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to read from @data and also - * the number of vertices to read when later drawing. - * @data: (array length=n_vertices) (element-type Cogl.VertexP3T2C4): An - * array of #CoglVertexP3T2C4 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglAttributeBuffer storage, describe the position, texture - * coordinate and color attributes with `CoglAttribute`s and - * upload your data. - * - * For example to draw a convex polygon with texture mapping and a - * linear gradient you can do: - * ```c - * CoglVertexP3T2C4 triangle[] = - * { - * { 0, 300, 0, 0.0, 1.0, 0xff, 0x00, 0x00, 0xff}, - * { 150, 0, 0, 0.5, 0.0, 0x00, 0xff, 0x00, 0xff}, - * { 300, 300, 0, 1.0, 1.0, 0xff, 0x00, 0x00, 0xff} - * }; - * prim = cogl_primitive_new_p3t2c4 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ``` - * - * The value passed as @n_vertices is initially used to determine how - * much can be read from @data but it will also be used to update the - * #CoglPrimitive `n_vertices` property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - - * The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). If your - * hardware doesn't support non-power of two textures (For example you - * are using GLES 1.1) then you will need to make sure your assets are - * resized to a power-of-two size (though they don't have to be square) - * - * - * Return value: (transfer full): A newly allocated #CoglPrimitive - * with a reference of 1. This can be freed using g_object_unref(). - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_p3t2c4 (CoglContext *context, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3T2C4 *data); -COGL_EXPORT int -cogl_primitive_get_first_vertex (CoglPrimitive *primitive); - -COGL_EXPORT void -cogl_primitive_set_first_vertex (CoglPrimitive *primitive, - int first_vertex); - -/** - * cogl_primitive_get_n_vertices: - * @primitive: A #CoglPrimitive object - * - * Queries the number of vertices to read when drawing the given - * @primitive. Usually this value is implicitly set when associating - * vertex data or indices with a #CoglPrimitive. - * - * If cogl_primitive_set_indices() has been used to associate a - * sequence of #CoglIndices with the given @primitive then the - * number of vertices to read can also be phrased as the number - * of indices to read. - * - * To be clear; it doesn't refer to the number of vertices - in - * terms of data - associated with the primitive it's just the number - * of vertices to read and draw. - * - * Returns: The number of vertices to read when drawing. - */ -COGL_EXPORT int -cogl_primitive_get_n_vertices (CoglPrimitive *primitive); - -/** - * cogl_primitive_set_n_vertices: - * @primitive: A #CoglPrimitive object - * @n_vertices: The number of vertices to read when drawing. - * - * Specifies how many vertices should be read when drawing the given - * @primitive. - * - * Usually this value is set implicitly when associating vertex data - * or indices with a #CoglPrimitive. - * - * To be clear; it doesn't refer to the number of vertices - in - * terms of data - associated with the primitive it's just the number - * of vertices to read and draw. - */ -COGL_EXPORT void -cogl_primitive_set_n_vertices (CoglPrimitive *primitive, - int n_vertices); - -COGL_EXPORT CoglVerticesMode -cogl_primitive_get_mode (CoglPrimitive *primitive); - -COGL_EXPORT void -cogl_primitive_set_mode (CoglPrimitive *primitive, - CoglVerticesMode mode); - -/** - * cogl_primitive_set_indices: - * @primitive: A #CoglPrimitive - * @indices: (array length=n_indices): A #CoglIndices array - * @n_indices: The number of indices to reference when drawing - * - * Associates a sequence of #CoglIndices with the given @primitive. - * - * #CoglIndices provide a way to virtualize your real vertex data by - * providing a sequence of indices that index into your real vertex - * data. The GPU will walk though the index values to indirectly - * lookup the data for each vertex instead of sequentially walking - * through the data directly. This lets you save memory by indexing - * shared data multiple times instead of duplicating the data. - * - * The value passed as @n_indices will simply update the - * #CoglPrimitive `n_vertices` property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to draw or, put another way, how many - * indices should be read from @indices when drawing. - * - * The #CoglPrimitive `first_vertex` property - * also affects drawing with indices by defining the first entry of the - * indices to start drawing from. - */ -COGL_EXPORT void -cogl_primitive_set_indices (CoglPrimitive *primitive, - CoglIndices *indices, - int n_indices); - -/** - * cogl_primitive_get_indices: - * @primitive: A #CoglPrimitive - * - * Return value: (transfer none) (nullable) (array): the indices that were set - * with cogl_primitive_set_indices() or %NULL if no indices were set. - */ -COGL_EXPORT CoglIndices * -cogl_primitive_get_indices (CoglPrimitive *primitive); - -/** - * cogl_primitive_copy: - * @primitive: A primitive copy - * - * Makes a copy of an existing #CoglPrimitive. Note that the primitive - * is a shallow copy which means it will use the same attributes and - * attribute buffers as the original primitive. - * - * Return value: (transfer full): the new primitive - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_copy (CoglPrimitive *primitive); - -/** - * CoglPrimitiveAttributeCallback: - * @primitive: The #CoglPrimitive whose attributes are being iterated - * @attribute: The #CoglAttribute - * @user_data: The private data passed to cogl_primitive_foreach_attribute() - * - * The callback prototype used with cogl_primitive_foreach_attribute() - * for iterating all the attributes of a #CoglPrimitive. - * - * The function should return TRUE to continue iteration or FALSE to - * stop. - */ -typedef gboolean (* CoglPrimitiveAttributeCallback) (CoglPrimitive *primitive, - CoglAttribute *attribute, - void *user_data); - -/** - * cogl_primitive_foreach_attribute: - * @primitive: A #CoglPrimitive object - * @callback: (scope call): A #CoglPrimitiveAttributeCallback to be - * called for each attribute - * @user_data: (closure): Private data that will be passed to the - * callback - * - * Iterates all the attributes of the given #CoglPrimitive. - */ -COGL_EXPORT void -cogl_primitive_foreach_attribute (CoglPrimitive *primitive, - CoglPrimitiveAttributeCallback callback, - void *user_data); - -/** - * cogl_primitive_draw: - * @primitive: A #CoglPrimitive geometry object - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * - * Draws the given @primitive geometry to the specified destination - * @framebuffer using the graphics processing state described by @pipeline. - * - * This drawing api doesn't support high-level meta texture types such - * as #CoglTexture2DSliced so it is the user's responsibility to - * ensure that only low-level textures that can be directly sampled by - * a GPU such as #CoglTexture2D are associated with layers of the given - * @pipeline. - */ -COGL_EXPORT void -cogl_primitive_draw (CoglPrimitive *primitive, - CoglFramebuffer *framebuffer, - CoglPipeline *pipeline); - - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-primitives-private.h b/mutter/cogl/cogl/cogl-primitives-private.h deleted file mode 100644 index ef932df..0000000 --- a/mutter/cogl/cogl/cogl-primitives-private.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include - -G_BEGIN_DECLS - -/* Draws a rectangle without going through the journal so that it will - be flushed immediately. This should only be used in situations - where the code may be called while the journal is already being - flushed. In that case using the journal would go wrong */ -void -_cogl_rectangle_immediate (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2); - -void -cogl_2d_primitives_immediate (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - const CoglVertexP2 *vertices, - unsigned int n_vertices); - -typedef struct _CoglMultiTexturedRect -{ - const float *position; /* x0,y0,x1,y1 */ - const float *tex_coords; /* (tx0,ty0,tx1,ty1)(tx0,ty0,tx1,ty1)(... */ - int tex_coords_len; /* number of floats in tex_coords? */ -} CoglMultiTexturedRect; - -void -_cogl_framebuffer_draw_multitextured_rectangles ( - CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglMultiTexturedRect *rects, - int n_rects); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-primitives.c b/mutter/cogl/cogl/cogl-primitives.c deleted file mode 100644 index 7f0cf30..0000000 --- a/mutter/cogl/cogl/cogl-primitives.c +++ /dev/null @@ -1,759 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include "cogl/cogl-debug.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-journal-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-attribute-private.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl-meta-texture.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl1-context.h" -#include "cogl/cogl-primitives-private.h" - -#include -#include - -#define _COGL_MAX_BEZ_RECURSE_DEPTH 16 - -typedef struct _TextureSlicedQuadState -{ - CoglFramebuffer *framebuffer; - CoglPipeline *pipeline; - CoglTexture *main_texture; - float tex_virtual_origin_x; - float tex_virtual_origin_y; - float quad_origin_x; - float quad_origin_y; - float v_to_q_scale_x; - float v_to_q_scale_y; - float quad_len_x; - float quad_len_y; - gboolean flipped_x; - gboolean flipped_y; -} TextureSlicedQuadState; - -static void -log_quad_sub_textures_cb (CoglTexture *texture, - const float *subtexture_coords, - const float *virtual_coords, - void *user_data) -{ - TextureSlicedQuadState *state = user_data; - CoglFramebuffer *framebuffer = state->framebuffer; - CoglTexture *texture_override; - float quad_coords[4]; - -#define TEX_VIRTUAL_TO_QUAD(V, Q, AXIS) \ - do { \ - Q = V - state->tex_virtual_origin_##AXIS; \ - Q *= state->v_to_q_scale_##AXIS; \ - if (state->flipped_##AXIS) \ - Q = state->quad_len_##AXIS - Q; \ - Q += state->quad_origin_##AXIS; \ - } while (0); - - TEX_VIRTUAL_TO_QUAD (virtual_coords[0], quad_coords[0], x); - TEX_VIRTUAL_TO_QUAD (virtual_coords[1], quad_coords[1], y); - - TEX_VIRTUAL_TO_QUAD (virtual_coords[2], quad_coords[2], x); - TEX_VIRTUAL_TO_QUAD (virtual_coords[3], quad_coords[3], y); - -#undef TEX_VIRTUAL_TO_QUAD - - COGL_NOTE (DRAW, - "~~~~~ slice\n" - "qx1: %f\t" - "qy1: %f\n" - "qx2: %f\t" - "qy2: %f\n" - "tx1: %f\t" - "ty1: %f\n" - "tx2: %f\t" - "ty2: %f\n", - quad_coords[0], quad_coords[1], - quad_coords[2], quad_coords[3], - subtexture_coords[0], subtexture_coords[1], - subtexture_coords[2], subtexture_coords[3]); - - /* We only need to override the texture if it's different from the - main texture */ - if (texture == state->main_texture) - texture_override = NULL; - else - texture_override = texture; - - _cogl_journal_log_quad (cogl_framebuffer_get_journal (framebuffer), - quad_coords, - state->pipeline, - 1, /* one layer */ - texture_override, /* replace the layer0 texture */ - subtexture_coords, - 4); -} - -typedef struct _ValidateFirstLayerState -{ - CoglPipeline *override_pipeline; -} ValidateFirstLayerState; - -static gboolean -validate_first_layer_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - ValidateFirstLayerState *state = user_data; - CoglPipelineWrapMode clamp_to_edge = - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; - CoglPipelineWrapMode wrap_s; - CoglPipelineWrapMode wrap_t; - - /* We can't use hardware repeat so we need to set clamp to edge - * otherwise it might pull in edge pixels from the other side. By - * default WRAP_MODE_AUTOMATIC becomes CLAMP_TO_EDGE so we only need - * to override if the wrap mode isn't already automatic or - * clamp_to_edge. - */ - wrap_s = cogl_pipeline_get_layer_wrap_mode_s (pipeline, layer_index); - if (wrap_s != COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE && - wrap_s != COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - if (!state->override_pipeline) - state->override_pipeline = cogl_pipeline_copy (pipeline); - cogl_pipeline_set_layer_wrap_mode_s (state->override_pipeline, - layer_index, clamp_to_edge); - } - - wrap_t = cogl_pipeline_get_layer_wrap_mode_t (pipeline, layer_index); - if (wrap_t != COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE && - wrap_t != COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - if (!state->override_pipeline) - state->override_pipeline = cogl_pipeline_copy (pipeline); - cogl_pipeline_set_layer_wrap_mode_t (state->override_pipeline, - layer_index, clamp_to_edge); - } - - return FALSE; -} - -/* This path doesn't currently support multitexturing but is used for - * CoglTextures that don't support repeating using the GPU so we need to - * manually emit extra geometry to fake the repeating. This includes: - * - * - CoglTexture2DSliced: when made of > 1 slice or if the users given - * texture coordinates require repeating, - * - CoglTexture2DAtlas: if the users given texture coordinates require - * repeating, - * - CoglTexturePixmap: if the users given texture coordinates require - * repeating - */ -/* TODO: support multitexturing */ -static void -_cogl_texture_quad_multiple_primitives (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglTexture *texture, - int layer_index, - const float *position, - float tx_1, - float ty_1, - float tx_2, - float ty_2) -{ - TextureSlicedQuadState state; - gboolean tex_virtual_flipped_x; - gboolean tex_virtual_flipped_y; - gboolean quad_flipped_x; - gboolean quad_flipped_y; - ValidateFirstLayerState validate_first_layer_state; - CoglPipelineWrapMode wrap_s, wrap_t; - - wrap_s = cogl_pipeline_get_layer_wrap_mode_s (pipeline, layer_index); - wrap_t = cogl_pipeline_get_layer_wrap_mode_t (pipeline, layer_index); - - validate_first_layer_state.override_pipeline = NULL; - cogl_pipeline_foreach_layer (pipeline, - validate_first_layer_cb, - &validate_first_layer_state); - - state.framebuffer = framebuffer; - state.main_texture = texture; - - if (validate_first_layer_state.override_pipeline) - state.pipeline = validate_first_layer_state.override_pipeline; - else - state.pipeline = pipeline; - - /* Get together the data we need to transform the virtual texture - * coordinates of each slice into quad coordinates... - * - * NB: We need to consider that the quad coordinates and the texture - * coordinates may be inverted along the x or y axis, and must preserve the - * inversions when we emit the final geometry. - */ - -#define X0 0 -#define Y0 1 -#define X1 2 -#define Y1 3 - - tex_virtual_flipped_x = (tx_1 > tx_2) ? TRUE : FALSE; - tex_virtual_flipped_y = (ty_1 > ty_2) ? TRUE : FALSE; - state.tex_virtual_origin_x = tex_virtual_flipped_x ? tx_2 : tx_1; - state.tex_virtual_origin_y = tex_virtual_flipped_y ? ty_2 : ty_1; - - quad_flipped_x = (position[X0] > position[X1]) ? TRUE : FALSE; - quad_flipped_y = (position[Y0] > position[Y1]) ? TRUE : FALSE; - state.quad_origin_x = quad_flipped_x ? position[X1] : position[X0]; - state.quad_origin_y = quad_flipped_y ? position[Y1] : position[Y0]; - - /* flatten the two forms of coordinate inversion into one... */ - state.flipped_x = tex_virtual_flipped_x ^ quad_flipped_x; - state.flipped_y = tex_virtual_flipped_y ^ quad_flipped_y; - - /* We use the _len_AXIS naming here instead of _width and _height because - * log_quad_slice_cb uses a macro with symbol concatenation to handle both - * axis, so this is more convenient... */ - state.quad_len_x = fabs (position[X1] - position[X0]); - state.quad_len_y = fabs (position[Y1] - position[Y0]); - -#undef X0 -#undef Y0 -#undef X1 -#undef Y1 - - state.v_to_q_scale_x = fabs (state.quad_len_x / (tx_2 - tx_1)); - state.v_to_q_scale_y = fabs (state.quad_len_y / (ty_2 - ty_1)); - - /* For backwards compatibility the default wrap mode for cogl_rectangle() is - * _REPEAT... */ - if (wrap_s == COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - wrap_s = COGL_PIPELINE_WRAP_MODE_REPEAT; - if (wrap_t == COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - wrap_t = COGL_PIPELINE_WRAP_MODE_REPEAT; - - cogl_meta_texture_foreach_in_region (texture, - tx_1, ty_1, tx_2, ty_2, - wrap_s, - wrap_t, - log_quad_sub_textures_cb, - &state); - - if (validate_first_layer_state.override_pipeline) - g_object_unref (validate_first_layer_state.override_pipeline); -} - -typedef struct _ValidateTexCoordsState -{ - int i; - int n_layers; - const float *user_tex_coords; - int user_tex_coords_len; - float *final_tex_coords; - CoglPipeline *override_pipeline; - gboolean needs_multiple_primitives; -} ValidateTexCoordsState; - -/* - * Validate the texture coordinates for this rectangle. - */ -static gboolean -validate_tex_coords_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - ValidateTexCoordsState *state = user_data; - CoglTexture *texture; - const float *in_tex_coords; - float *out_tex_coords; - float default_tex_coords[4] = {0.0, 0.0, 1.0, 1.0}; - CoglTransformResult transform_result; - - state->i++; - - /* FIXME: we should be able to avoid this copying when no - * transform is required by the texture backend and the user - * has supplied enough coordinates for all the layers. - */ - - /* If the user didn't supply texture coordinates for this layer - then use the default coords */ - if (state->i >= state->user_tex_coords_len / 4) - in_tex_coords = default_tex_coords; - else - in_tex_coords = &state->user_tex_coords[state->i * 4]; - - out_tex_coords = &state->final_tex_coords[state->i * 4]; - - memcpy (out_tex_coords, in_tex_coords, sizeof (float) * 4); - - texture = cogl_pipeline_get_layer_texture (pipeline, layer_index); - - /* NB: NULL textures are handled by _cogl_pipeline_flush_gl_state */ - if (!texture) - return TRUE; - - /* Convert the texture coordinates to GL. - */ - transform_result = - _cogl_texture_transform_quad_coords_to_gl (texture, - out_tex_coords); - /* If the texture has waste or we are using GL_TEXTURE_RECT we - * can't handle texture repeating so we can't use the layer if - * repeating is required. - * - * NB: We already know that no texture matrix is being used if the - * texture doesn't support hardware repeat. - */ - if (transform_result == COGL_TRANSFORM_SOFTWARE_REPEAT) - { - if (state->i == 0) - { - if (state->n_layers > 1) - { - static gboolean warning_seen = FALSE; - if (!warning_seen) - g_warning ("Skipping layers 1..n of your material since " - "the first layer doesn't support hardware " - "repeat (e.g. because of waste or use of " - "GL_TEXTURE_RECTANGLE_ARB) and you supplied " - "texture coordinates outside the range [0,1]." - "Falling back to software repeat assuming " - "layer 0 is the most important one keep"); - warning_seen = TRUE; - } - - if (state->override_pipeline) - g_object_unref (state->override_pipeline); - state->needs_multiple_primitives = TRUE; - return FALSE; - } - else - { - static gboolean warning_seen = FALSE; - if (!warning_seen) - g_warning ("Skipping layer %d of your material " - "since you have supplied texture coords " - "outside the range [0,1] but the texture " - "doesn't support hardware repeat (e.g. " - "because of waste or use of " - "GL_TEXTURE_RECTANGLE_ARB). This isn't " - "supported with multi-texturing.", state->i); - warning_seen = TRUE; - - cogl_pipeline_set_layer_texture (pipeline, layer_index, NULL); - } - } - - /* By default WRAP_MODE_AUTOMATIC becomes to CLAMP_TO_EDGE. If - the texture coordinates need repeating then we'll override - this to GL_REPEAT. Otherwise we'll leave it at CLAMP_TO_EDGE - so that it won't blend in pixels from the opposite side when - the full texture is drawn with GL_LINEAR filter mode */ - if (transform_result == COGL_TRANSFORM_HARDWARE_REPEAT) - { - if (cogl_pipeline_get_layer_wrap_mode_s (pipeline, layer_index) == - COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - if (!state->override_pipeline) - state->override_pipeline = cogl_pipeline_copy (pipeline); - cogl_pipeline_set_layer_wrap_mode_s (state->override_pipeline, - layer_index, - COGL_PIPELINE_WRAP_MODE_REPEAT); - } - if (cogl_pipeline_get_layer_wrap_mode_t (pipeline, layer_index) == - COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - if (!state->override_pipeline) - state->override_pipeline = cogl_pipeline_copy (pipeline); - cogl_pipeline_set_layer_wrap_mode_t (state->override_pipeline, - layer_index, - COGL_PIPELINE_WRAP_MODE_REPEAT); - } - } - - return TRUE; -} - -/* This path supports multitexturing but only when each of the layers is - * handled with a single GL texture. Also if repeating is necessary then - * _cogl_texture_can_hardware_repeat() must return TRUE. - * This includes layers made from: - * - * - CoglTexture2DSliced: if only comprised of a single slice with optional - * waste, assuming the users given texture coordinates don't require - * repeating. - * - CoglTexture{1D,2D}: always. - * - CoglTexture2DAtlas: assuming the users given texture coordinates don't - * require repeating. - * - CoglTexturePixmap: assuming the users given texture coordinates don't - * require repeating. - */ -static gboolean -_cogl_multitexture_quad_single_primitive (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - const float *position, - const float *user_tex_coords, - int user_tex_coords_len) -{ - int n_layers = cogl_pipeline_get_n_layers (pipeline); - ValidateTexCoordsState state; - float *final_tex_coords = alloca (sizeof (float) * 4 * n_layers); - - state.i = -1; - state.n_layers = n_layers; - state.user_tex_coords = user_tex_coords; - state.user_tex_coords_len = user_tex_coords_len; - state.final_tex_coords = final_tex_coords; - state.override_pipeline = NULL; - state.needs_multiple_primitives = FALSE; - - cogl_pipeline_foreach_layer (pipeline, - validate_tex_coords_cb, - &state); - - if (state.needs_multiple_primitives) - return FALSE; - - if (state.override_pipeline) - pipeline = state.override_pipeline; - - _cogl_journal_log_quad (cogl_framebuffer_get_journal (framebuffer), - position, - pipeline, - n_layers, - NULL, /* no texture override */ - final_tex_coords, - n_layers * 4); - - if (state.override_pipeline) - g_object_unref (state.override_pipeline); - - return TRUE; -} - -typedef struct _ValidateLayerState -{ - CoglContext *ctx; - int i; - int first_layer; - CoglPipeline *override_source; - gboolean all_use_sliced_quad_fallback; -} ValidateLayerState; - -static gboolean -_cogl_rectangles_validate_layer_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - ValidateLayerState *state = user_data; - CoglTexture *texture; - - state->i++; - - /* We need to ensure the mipmaps are ready before deciding - * anything else about the texture because the texture storage - * could completely change if it needs to be migrated out of the - * atlas and will affect how we validate the layer. - * - * FIXME: this needs to be generalized. There could be any - * number of things that might require a shuffling of the - * underlying texture storage. We could add two mechanisms to - * generalize this a bit... - * - * 1) add a _cogl_pipeline_layer_update_storage() function that - * would for instance consider if mipmapping is necessary and - * potentially migrate the texture from an atlas. - * - * 2) allow setting of transient primitive-flags on a pipeline - * that may affect the outcome of _update_storage(). One flag - * could indicate that we expect to sample beyond the bounds of - * the texture border. - * - * flags = COGL_PIPELINE_PRIMITIVE_FLAG_VALID_BORDERS; - * _cogl_pipeline_layer_assert_primitive_flags (layer, flags) - * _cogl_pipeline_layer_update_storage (layer) - * enqueue primitive in journal - * - * when the primitive is dequeued and drawn we should: - * _cogl_pipeline_flush_gl_state (pipeline) - * draw primitive - * _cogl_pipeline_unassert_primitive_flags (layer, flags); - * - * _cogl_pipeline_layer_update_storage should take into - * consideration all the asserted primitive requirements. (E.g. - * there could be multiple primitives in the journal - or in a - * renderlist in the future - that need mipmaps or that need - * valid contents beyond their borders (for cogl_polygon) - * meaning they can't work with textures in an atas, so - * _cogl_pipeline_layer_update_storage would pass on these - * requirements to the texture atlas backend which would make - * sure the referenced texture is migrated out of the atlas and - * mipmaps are generated.) - */ - _cogl_pipeline_pre_paint_for_layer (pipeline, layer_index); - - texture = cogl_pipeline_get_layer_texture (pipeline, layer_index); - - /* NULL textures are handled by - * _cogl_pipeline_flush_gl_state */ - if (texture == NULL) - return TRUE; - - if (state->i == 0) - state->first_layer = layer_index; - - /* XXX: - * For now, if the first layer is sliced then all other layers are - * ignored since we currently don't support multi-texturing with - * sliced textures. If the first layer is not sliced then any other - * layers found to be sliced will be skipped. (with a warning) - * - * TODO: Add support for multi-texturing rectangles with sliced - * textures if no texture matrices are in use. - */ - if (cogl_texture_is_sliced (texture)) - { - if (state->i == 0) - { - if (cogl_pipeline_get_n_layers (pipeline) > 1) - { - static gboolean warning_seen = FALSE; - - if (!state->override_source) - state->override_source = cogl_pipeline_copy (pipeline); - _cogl_pipeline_prune_to_n_layers (state->override_source, 1); - - if (!warning_seen) - g_warning ("Skipping layers 1..n of your pipeline since " - "the first layer is sliced. We don't currently " - "support any multi-texturing with sliced " - "textures but assume layer 0 is the most " - "important to keep"); - warning_seen = TRUE; - } - - state->all_use_sliced_quad_fallback = TRUE; - - return FALSE; - } - else - { - static gboolean warning_seen = FALSE; - CoglTexture *tex_2d; - - if (!warning_seen) - g_warning ("Skipping layer %d of your pipeline consisting of " - "a sliced texture (unsupported for multi texturing)", - state->i); - warning_seen = TRUE; - - /* Note: currently only 2D textures can be sliced. */ - tex_2d = state->ctx->default_gl_texture_2d_tex; - cogl_pipeline_set_layer_texture (pipeline, layer_index, tex_2d); - return TRUE; - } - } - -#ifdef COGL_ENABLE_DEBUG - /* If the texture can't be repeated with the GPU (e.g. because it has - * waste or if using GL_TEXTURE_RECTANGLE_ARB) then if a texture matrix - * is also in use we don't know if the result will end up trying - * to texture from the waste area. - * - * Note: we check can_hardware_repeat() first since it's cheaper. - * - * Note: cases where the texture coordinates will require repeating - * will be caught by later validation. - */ - if (!_cogl_texture_can_hardware_repeat (texture) && - _cogl_pipeline_layer_has_user_matrix (pipeline, layer_index)) - { - static gboolean warning_seen = FALSE; - if (!warning_seen) - g_warning ("layer %d of your pipeline uses a custom " - "texture matrix but because the texture doesn't " - "support hardware repeating you may see artefacts " - "due to sampling beyond the texture's bounds.", - state->i); - warning_seen = TRUE; - } -#endif - - return TRUE; -} - -void -_cogl_framebuffer_draw_multitextured_rectangles ( - CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglMultiTexturedRect *rects, - int n_rects) -{ - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglPipeline *original_pipeline; - ValidateLayerState state; - int i; - - original_pipeline = pipeline; - - /* - * Validate all the layers of the current source pipeline... - */ - state.ctx = ctx; - state.i = -1; - state.first_layer = 0; - state.override_source = NULL; - state.all_use_sliced_quad_fallback = FALSE; - cogl_pipeline_foreach_layer (pipeline, - _cogl_rectangles_validate_layer_cb, - &state); - - if (state.override_source) - pipeline = state.override_source; - - /* - * Emit geometry for each of the rectangles... - */ - - for (i = 0; i < n_rects; i++) - { - CoglTexture *texture; - const float default_tex_coords[4] = {0.0, 0.0, 1.0, 1.0}; - const float *tex_coords; - - if (!state.all_use_sliced_quad_fallback) - { - gboolean success = - _cogl_multitexture_quad_single_primitive (framebuffer, - pipeline, - rects[i].position, - rects[i].tex_coords, - rects[i].tex_coords_len); - - /* NB: If _cogl_multitexture_quad_single_primitive fails then it - * means the user tried to use texture repeat with a texture that - * can't be repeated by the GPU (e.g. due to waste or use of - * GL_TEXTURE_RECTANGLE_ARB) */ - if (success) - continue; - } - - /* If multitexturing failed or we are drawing with a sliced texture - * then we only support a single layer so we pluck out the texture - * from the first pipeline layer... */ - texture = cogl_pipeline_get_layer_texture (pipeline, state.first_layer); - - if (rects[i].tex_coords) - tex_coords = rects[i].tex_coords; - else - tex_coords = default_tex_coords; - - COGL_NOTE (DRAW, "Drawing Tex Quad (Multi-Prim Mode)"); - - _cogl_texture_quad_multiple_primitives (framebuffer, - pipeline, - texture, - state.first_layer, - rects[i].position, - tex_coords[0], - tex_coords[1], - tex_coords[2], - tex_coords[3]); - } - - if (pipeline != original_pipeline) - g_object_unref (pipeline); -} - -void -cogl_2d_primitives_immediate (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - const CoglVertexP2 *vertices, - unsigned int n_vertices) -{ - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglAttributeBuffer *attribute_buffer; - CoglAttribute *attributes[1]; - size_t vertices_size = sizeof (CoglVertexP2) * n_vertices; - - attribute_buffer = - cogl_attribute_buffer_new (ctx, vertices_size, vertices); - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP2), /* stride */ - 0, /* offset */ - 2, /* n_components */ - COGL_ATTRIBUTE_TYPE_FLOAT); - - _cogl_framebuffer_draw_attributes (framebuffer, - pipeline, - mode, - 0, /* first_index */ - n_vertices, - attributes, - 1, - COGL_DRAW_SKIP_JOURNAL_FLUSH | - COGL_DRAW_SKIP_PIPELINE_VALIDATION | - COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH); - - - g_object_unref (attributes[0]); - g_object_unref (attribute_buffer); -} - -void -_cogl_rectangle_immediate (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2) -{ - CoglVertexP2 vertices[4] = - { - {x_1, y_1}, - {x_1, y_2}, - {x_2, y_1}, - {x_2, y_2} - }; - - cogl_2d_primitives_immediate (framebuffer, - pipeline, - COGL_VERTICES_MODE_TRIANGLE_STRIP, - vertices, - 4); -} diff --git a/mutter/cogl/cogl/cogl-private.h b/mutter/cogl/cogl/cogl-private.h deleted file mode 100644 index fb18c8b..0000000 --- a/mutter/cogl/cogl/cogl-private.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-pipeline.h" -#include "cogl/cogl-context.h" -#include "cogl/cogl-flags.h" - -G_BEGIN_DECLS - -#define I_(str) (g_intern_static_string ((str))) - -typedef enum -{ - COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE, - COGL_PRIVATE_FEATURE_MESA_PACK_INVERT, - COGL_PRIVATE_FEATURE_PBOS, - COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL, - COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL, - COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888, - COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE, - COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS, - COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_STRIDE, - COGL_PRIVATE_FEATURE_FORMAT_CONVERSION, - COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS, - COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS, - COGL_PRIVATE_FEATURE_ALPHA_TEXTURES, - COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE, - COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL, - COGL_PRIVATE_FEATURE_TEXTURE_LOD_BIAS, - COGL_PRIVATE_FEATURE_OES_EGL_SYNC, - /* If this is set then the winsys is responsible for queueing dirty - * events. Otherwise a dirty event will be queued when the onscreen - * is first allocated or when it is shown or resized */ - COGL_PRIVATE_FEATURE_DIRTY_EVENTS, - /* This feature allows for explicitly selecting a GL-based backend, - * as opposed to nop or (in the future) Vulkan. - */ - COGL_PRIVATE_FEATURE_ANY_GL, - - /* This is a Mali bug/quirk: */ - COGL_PRIVATE_QUIRK_GENERATE_MIPMAP_NEEDS_FLUSH, - - COGL_N_PRIVATE_FEATURES -} CoglPrivateFeature; - -void -_cogl_transform_point (const graphene_matrix_t *matrix_mv, - const graphene_matrix_t *matrix_p, - const float *viewport, - float *x, - float *y); - -gboolean -_cogl_check_extension (const char *name, char * const *ext); - -void -_cogl_init (void); - -#define _cogl_has_private_feature(ctx, feature) \ - COGL_FLAGS_GET ((ctx)->private_features, (feature)) - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-profile.c b/mutter/cogl/cogl/cogl-profile.c deleted file mode 100644 index 4d7af2c..0000000 --- a/mutter/cogl/cogl/cogl-profile.c +++ /dev/null @@ -1,122 +0,0 @@ -#include "config.h" - -#ifdef COGL_ENABLE_PROFILE - -#include "cogl/cogl-profile.h" -#include "cogl/cogl-debug.h" -#include "cogl/cogl-i18n-private.h" - -#include - -UProfContext *_cogl_uprof_context; - -static gboolean -debug_option_getter (void *user_data) -{ - unsigned int shift = GPOINTER_TO_UINT (user_data); - return COGL_DEBUG_ENABLED (shift); -} - -static void -debug_option_setter (gboolean value, void *user_data) -{ - unsigned int shift = GPOINTER_TO_UINT (user_data); - - if (value) - COGL_DEBUG_SET_FLAG (shift); - else - COGL_DEBUG_CLEAR_FLAG (shift); -} - -static void -print_exit_report (void) -{ - if (getenv ("COGL_PROFILE_OUTPUT_REPORT")) - { - UProfContext *mainloop_context; - UProfTimerResult *mainloop_timer; - UProfReport *report; - - /* NB: uprof provides a shared context for mainloop statistics - * which needs to be setup by the application which controls the - * mainloop. - * - * If no "Mainloop" timer has been setup then we print a warning - * since we can't provide a meaningful Cogl report without one. - */ - mainloop_context = uprof_get_mainloop_context (); - mainloop_timer = uprof_context_get_timer_result (mainloop_context, - "Mainloop"); - /* just bail out if the mainloop timer wasn't hit */ - if (!mainloop_timer) - { - g_warning ("\n\n" - "No UProf \"Mainloop\" timer was setup by the " - "application therefore we\ncan't provide a meaningful " - "profile report.\n" - "\n" - "This should be done automatically if you are using Clutter " - "(if\nbuilt with --enable-profile)\n" - "\n" - "If you aren't using Clutter then you can declare a " - "\"Mainloop\" UProf\ntimer in your application like this:\n\n" - " UPROF_STATIC_TIMER (mainloop_timer, \n" - " NULL,\n" - " \"Mainloop\",\n" - " \"Time in glib mainloop\",\n" - " 0);\n" - "\n" - "And start/stop it around your mainloop like this:\n" - "\n" - " UPROF_TIMER_START (uprof_get_mainloop_context (), mainloop_timer);\n" - " g_main_loop_run (loop);\n" - " UPROF_TIMER_STOP (uprof_get_mainloop_context (), mainloop_timer);\n"); - return; - } - - report = uprof_report_new ("Cogl report"); - uprof_report_add_context (report, _cogl_uprof_context); - uprof_report_print (report); - uprof_report_unref (report); - } - uprof_context_unref (_cogl_uprof_context); -} - -void -_cogl_uprof_init (void) -{ - _cogl_uprof_context = uprof_context_new ("Cogl"); - uprof_context_link (_cogl_uprof_context, uprof_get_mainloop_context ()); -#define OPT(MASK_NAME, GROUP, NAME, NAME_FORMATTED, DESCRIPTION) \ - G_STMT_START { \ - int shift = COGL_DEBUG_ ## MASK_NAME; \ - uprof_context_add_boolean_option (_cogl_uprof_context, \ - GROUP, \ - NAME, \ - NAME_FORMATTED, \ - DESCRIPTION, \ - debug_option_getter, \ - debug_option_setter, \ - GUINT_TO_POINTER (shift)); \ - } G_STMT_END; - -#include "cogl/cogl-debug-options.h" -#undef OPT - - atexit (print_exit_report); -} - -void -_cogl_profile_trace_message (const char *format, ...) -{ - va_list ap; - - va_start (ap, format); - g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, ap); - va_end (ap); - - if (_cogl_uprof_context) - uprof_context_vtrace_message (_cogl_uprof_context, format, ap); -} - -#endif diff --git a/mutter/cogl/cogl/cogl-profile.h b/mutter/cogl/cogl/cogl-profile.h deleted file mode 100644 index 2437c17..0000000 --- a/mutter/cogl/cogl/cogl-profile.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#ifdef COGL_ENABLE_PROFILE - -#include - -extern UProfContext *_cogl_uprof_context; - -#define COGL_STATIC_TIMER UPROF_STATIC_TIMER -#define COGL_STATIC_COUNTER UPROF_STATIC_COUNTER -#define COGL_COUNTER_INC UPROF_COUNTER_INC -#define COGL_COUNTER_DEC UPROF_COUNTER_DEC -#define COGL_TIMER_START UPROF_TIMER_START -#define COGL_TIMER_STOP UPROF_TIMER_STOP - -void -_cogl_uprof_init (void); - -COGL_EXPORT void -_cogl_profile_trace_message (const char *format, ...); - -#else - -#define COGL_STATIC_TIMER(A,B,C,D,E) G_STMT_START{ (void)0; }G_STMT_END -#define COGL_STATIC_COUNTER(A,B,C,D) G_STMT_START{ (void)0; }G_STMT_END -#define COGL_COUNTER_INC(A,B) G_STMT_START{ (void)0; }G_STMT_END -#define COGL_COUNTER_DEC(A,B) G_STMT_START{ (void)0; }G_STMT_END -#define COGL_TIMER_START(A,B) G_STMT_START{ (void)0; }G_STMT_END -#define COGL_TIMER_STOP(A,B) G_STMT_START{ (void)0; }G_STMT_END - -#define _cogl_profile_trace_message g_message - -#endif diff --git a/mutter/cogl/cogl/cogl-rectangle-map.c b/mutter/cogl/cogl/cogl-rectangle-map.c deleted file mode 100644 index ac0a587..0000000 --- a/mutter/cogl/cogl/cogl-rectangle-map.c +++ /dev/null @@ -1,594 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#include "config.h" - -#include - -#include "cogl/cogl-util.h" -#include "cogl/cogl-rectangle-map.h" -#include "cogl/cogl-debug.h" - -/* Implements a data structure which keeps track of unused - sub-rectangles within a larger rectangle using a binary tree - structure. The algorithm for this is based on the description here: - - http://www.blackpawn.com/texts/lightmaps/default.html -*/ - -typedef struct _CoglRectangleMapNode CoglRectangleMapNode; -typedef struct _CoglRectangleMapStackEntry CoglRectangleMapStackEntry; - -typedef void (* CoglRectangleMapInternalForeachCb) (CoglRectangleMapNode *node, - void *data); - -typedef enum -{ - COGL_RECTANGLE_MAP_BRANCH, - COGL_RECTANGLE_MAP_FILLED_LEAF, - COGL_RECTANGLE_MAP_EMPTY_LEAF -} CoglRectangleMapNodeType; - -struct _CoglRectangleMap -{ - CoglRectangleMapNode *root; - - unsigned int n_rectangles; - - unsigned int space_remaining; - - GDestroyNotify value_destroy_func; - - /* Stack used for walking the structure. This is only used during - the lifetime of a single function call but it is kept here as an - optimisation to avoid reallocating it every time it is needed */ - GArray *stack; -}; - -struct _CoglRectangleMapNode -{ - CoglRectangleMapNodeType type; - - CoglRectangleMapEntry rectangle; - - unsigned int largest_gap; - - CoglRectangleMapNode *parent; - - union - { - /* Fields used when this is a branch */ - struct - { - CoglRectangleMapNode *left; - CoglRectangleMapNode *right; - } branch; - - /* Field used when this is a filled leaf */ - void *data; - } d; -}; - -struct _CoglRectangleMapStackEntry -{ - /* The node to search */ - CoglRectangleMapNode *node; - /* Index of next branch of this node to explore. Basically either 0 - to go left or 1 to go right */ - gboolean next_index; -}; - -static CoglRectangleMapNode * -_cogl_rectangle_map_node_new (void) -{ - return g_new0 (CoglRectangleMapNode, 1); -} - -static void -_cogl_rectangle_map_node_free (CoglRectangleMapNode *node) -{ - g_free (node); -} - -CoglRectangleMap * -_cogl_rectangle_map_new (unsigned int width, - unsigned int height, - GDestroyNotify value_destroy_func) -{ - CoglRectangleMap *map = g_new (CoglRectangleMap, 1); - CoglRectangleMapNode *root = _cogl_rectangle_map_node_new (); - - root->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - root->parent = NULL; - root->rectangle.x = 0; - root->rectangle.y = 0; - root->rectangle.width = width; - root->rectangle.height = height; - root->largest_gap = width * height; - - map->root = root; - map->n_rectangles = 0; - map->value_destroy_func = value_destroy_func; - map->space_remaining = width * height; - - map->stack = g_array_new (FALSE, FALSE, sizeof (CoglRectangleMapStackEntry)); - - return map; -} - -static void -_cogl_rectangle_map_stack_push (GArray *stack, - CoglRectangleMapNode *node, - gboolean next_index) -{ - CoglRectangleMapStackEntry *new_entry; - - g_array_set_size (stack, stack->len + 1); - - new_entry = &g_array_index (stack, CoglRectangleMapStackEntry, - stack->len - 1); - - new_entry->node = node; - new_entry->next_index = next_index; -} - -static void -_cogl_rectangle_map_stack_pop (GArray *stack) -{ - g_array_set_size (stack, stack->len - 1); -} - -static CoglRectangleMapStackEntry * -_cogl_rectangle_map_stack_get_top (GArray *stack) -{ - return &g_array_index (stack, CoglRectangleMapStackEntry, - stack->len - 1); -} - -static CoglRectangleMapNode * -_cogl_rectangle_map_node_split_horizontally (CoglRectangleMapNode *node, - unsigned int left_width) -{ - /* Splits the node horizontally (according to emacs' definition, not - vim) by converting it to a branch and adding two new leaf - nodes. The leftmost branch will have the width left_width and - will be returned. If the node is already just the right size it - won't do anything */ - - CoglRectangleMapNode *left_node, *right_node; - - if (node->rectangle.width == left_width) - return node; - - left_node = _cogl_rectangle_map_node_new (); - left_node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - left_node->parent = node; - left_node->rectangle.x = node->rectangle.x; - left_node->rectangle.y = node->rectangle.y; - left_node->rectangle.width = left_width; - left_node->rectangle.height = node->rectangle.height; - left_node->largest_gap = (left_node->rectangle.width * - left_node->rectangle.height); - node->d.branch.left = left_node; - - right_node = _cogl_rectangle_map_node_new (); - right_node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - right_node->parent = node; - right_node->rectangle.x = node->rectangle.x + left_width; - right_node->rectangle.y = node->rectangle.y; - right_node->rectangle.width = node->rectangle.width - left_width; - right_node->rectangle.height = node->rectangle.height; - right_node->largest_gap = (right_node->rectangle.width * - right_node->rectangle.height); - node->d.branch.right = right_node; - - node->type = COGL_RECTANGLE_MAP_BRANCH; - - return left_node; -} - -static CoglRectangleMapNode * -_cogl_rectangle_map_node_split_vertically (CoglRectangleMapNode *node, - unsigned int top_height) -{ - /* Splits the node vertically (according to emacs' definition, not - vim) by converting it to a branch and adding two new leaf - nodes. The topmost branch will have the height top_height and - will be returned. If the node is already just the right size it - won't do anything */ - - CoglRectangleMapNode *top_node, *bottom_node; - - if (node->rectangle.height == top_height) - return node; - - top_node = _cogl_rectangle_map_node_new (); - top_node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - top_node->parent = node; - top_node->rectangle.x = node->rectangle.x; - top_node->rectangle.y = node->rectangle.y; - top_node->rectangle.width = node->rectangle.width; - top_node->rectangle.height = top_height; - top_node->largest_gap = (top_node->rectangle.width * - top_node->rectangle.height); - node->d.branch.left = top_node; - - bottom_node = _cogl_rectangle_map_node_new (); - bottom_node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - bottom_node->parent = node; - bottom_node->rectangle.x = node->rectangle.x; - bottom_node->rectangle.y = node->rectangle.y + top_height; - bottom_node->rectangle.width = node->rectangle.width; - bottom_node->rectangle.height = node->rectangle.height - top_height; - bottom_node->largest_gap = (bottom_node->rectangle.width * - bottom_node->rectangle.height); - node->d.branch.right = bottom_node; - - node->type = COGL_RECTANGLE_MAP_BRANCH; - - return top_node; -} - -gboolean -_cogl_rectangle_map_add (CoglRectangleMap *map, - unsigned int width, - unsigned int height, - void *data, - CoglRectangleMapEntry *rectangle) -{ - unsigned int rectangle_size = width * height; - /* Stack of nodes to search in */ - GArray *stack = map->stack; - CoglRectangleMapNode *found_node = NULL; - - /* Zero-sized rectangles break the algorithm for removing rectangles - so we'll disallow them */ - g_return_val_if_fail (width > 0 && height > 0, FALSE); - - /* Start with the root node */ - g_array_set_size (stack, 0); - _cogl_rectangle_map_stack_push (stack, map->root, FALSE); - - /* Depth-first search for an empty node that is big enough */ - while (stack->len > 0) - { - CoglRectangleMapStackEntry *stack_top; - CoglRectangleMapNode *node; - int next_index; - - /* Pop an entry off the stack */ - stack_top = _cogl_rectangle_map_stack_get_top (stack); - node = stack_top->node; - next_index = stack_top->next_index; - _cogl_rectangle_map_stack_pop (stack); - - /* Regardless of the type of the node, there's no point - descending any further if the new rectangle won't fit within - it */ - if (node->rectangle.width >= width && - node->rectangle.height >= height && - node->largest_gap >= rectangle_size) - { - if (node->type == COGL_RECTANGLE_MAP_EMPTY_LEAF) - { - /* We've found a node we can use */ - found_node = node; - break; - } - else if (node->type == COGL_RECTANGLE_MAP_BRANCH) - { - if (next_index) - /* Try the right branch */ - _cogl_rectangle_map_stack_push (stack, - node->d.branch.right, - 0); - else - { - /* Make sure we remember to try the right branch once - we've finished descending the left branch */ - _cogl_rectangle_map_stack_push (stack, - node, - 1); - /* Try the left branch */ - _cogl_rectangle_map_stack_push (stack, - node->d.branch.left, - 0); - } - } - } - } - - if (found_node) - { - CoglRectangleMapNode *node; - - /* Split according to whichever axis will leave us with the - largest space */ - if (found_node->rectangle.width - width > - found_node->rectangle.height - height) - { - found_node = - _cogl_rectangle_map_node_split_horizontally (found_node, width); - found_node = - _cogl_rectangle_map_node_split_vertically (found_node, height); - } - else - { - found_node = - _cogl_rectangle_map_node_split_vertically (found_node, height); - found_node = - _cogl_rectangle_map_node_split_horizontally (found_node, width); - } - - found_node->type = COGL_RECTANGLE_MAP_FILLED_LEAF; - found_node->d.data = data; - found_node->largest_gap = 0; - if (rectangle) - *rectangle = found_node->rectangle; - - /* Walk back up the tree and update the stored largest gap for - the node's sub tree */ - for (node = found_node->parent; node; node = node->parent) - { - /* This node is a parent so it should always be a branch */ - g_assert (node->type == COGL_RECTANGLE_MAP_BRANCH); - - node->largest_gap = MAX (node->d.branch.left->largest_gap, - node->d.branch.right->largest_gap); - } - - /* There is now an extra rectangle in the map */ - map->n_rectangles++; - /* and less space */ - map->space_remaining -= rectangle_size; - - return TRUE; - } - else - return FALSE; -} - -void -_cogl_rectangle_map_remove (CoglRectangleMap *map, - const CoglRectangleMapEntry *rectangle) -{ - CoglRectangleMapNode *node = map->root; - unsigned int rectangle_size = rectangle->width * rectangle->height; - - /* We can do a binary-chop down the search tree to find the rectangle */ - while (node->type == COGL_RECTANGLE_MAP_BRANCH) - { - CoglRectangleMapNode *left_node = node->d.branch.left; - - /* If and only if the rectangle is in the left node then the x,y - position of the rectangle will be within the node's - rectangle */ - if (rectangle->x < left_node->rectangle.x + left_node->rectangle.width && - rectangle->y < left_node->rectangle.y + left_node->rectangle.height) - /* Go left */ - node = left_node; - else - /* Go right */ - node = node->d.branch.right; - } - - /* Make sure we found the right node */ - if (node->type != COGL_RECTANGLE_MAP_FILLED_LEAF || - node->rectangle.x != rectangle->x || - node->rectangle.y != rectangle->y || - node->rectangle.width != rectangle->width || - node->rectangle.height != rectangle->height) - /* This should only happen if someone tried to remove a rectangle - that was not in the map so something has gone wrong */ - g_return_if_reached (); - else - { - /* Convert the node back to an empty node */ - if (map->value_destroy_func) - map->value_destroy_func (node->d.data); - node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - node->largest_gap = rectangle_size; - - /* Walk back up the tree combining branch nodes that have two - empty leaves back into a single empty leaf */ - for (node = node->parent; node; node = node->parent) - { - /* This node is a parent so it should always be a branch */ - g_assert (node->type == COGL_RECTANGLE_MAP_BRANCH); - - if (node->d.branch.left->type == COGL_RECTANGLE_MAP_EMPTY_LEAF && - node->d.branch.right->type == COGL_RECTANGLE_MAP_EMPTY_LEAF) - { - _cogl_rectangle_map_node_free (node->d.branch.left); - _cogl_rectangle_map_node_free (node->d.branch.right); - node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - - node->largest_gap = (node->rectangle.width * - node->rectangle.height); - } - else - break; - } - - /* Reduce the amount of space remaining in all of the parents - further up the chain */ - for (; node; node = node->parent) - node->largest_gap = MAX (node->d.branch.left->largest_gap, - node->d.branch.right->largest_gap); - - /* There is now one less rectangle */ - g_assert (map->n_rectangles > 0); - map->n_rectangles--; - /* and more space */ - map->space_remaining += rectangle_size; - } -} - -unsigned int -_cogl_rectangle_map_get_width (CoglRectangleMap *map) -{ - return map->root->rectangle.width; -} - -unsigned int -_cogl_rectangle_map_get_height (CoglRectangleMap *map) -{ - return map->root->rectangle.height; -} - -unsigned int -_cogl_rectangle_map_get_remaining_space (CoglRectangleMap *map) -{ - return map->space_remaining; -} - -unsigned int -_cogl_rectangle_map_get_n_rectangles (CoglRectangleMap *map) -{ - return map->n_rectangles; -} - -static void -_cogl_rectangle_map_internal_foreach (CoglRectangleMap *map, - CoglRectangleMapInternalForeachCb func, - void *data) -{ - /* Stack of nodes to search in */ - GArray *stack = map->stack; - - /* Start with the root node */ - g_array_set_size (stack, 0); - _cogl_rectangle_map_stack_push (stack, map->root, 0); - - /* Iterate all nodes depth-first */ - while (stack->len > 0) - { - CoglRectangleMapStackEntry *stack_top = - _cogl_rectangle_map_stack_get_top (stack); - CoglRectangleMapNode *node = stack_top->node; - - switch (node->type) - { - case COGL_RECTANGLE_MAP_BRANCH: - if (stack_top->next_index == 0) - { - /* Next time we come back to this node, go to the right */ - stack_top->next_index = 1; - - /* Explore the left branch next */ - _cogl_rectangle_map_stack_push (stack, - node->d.branch.left, - 0); - } - else if (stack_top->next_index == 1) - { - /* Next time we come back to this node, stop processing it */ - stack_top->next_index = 2; - - /* Explore the right branch next */ - _cogl_rectangle_map_stack_push (stack, - node->d.branch.right, - 0); - } - else - { - /* We're finished with this node so we can call the callback */ - func (node, data); - _cogl_rectangle_map_stack_pop (stack); - } - break; - - default: - /* Some sort of leaf node, just call the callback */ - func (node, data); - _cogl_rectangle_map_stack_pop (stack); - break; - } - } - - /* The stack should now be empty */ - g_assert (stack->len == 0); -} - -typedef struct _CoglRectangleMapForeachClosure -{ - CoglRectangleMapCallback callback; - void *data; -} CoglRectangleMapForeachClosure; - -static void -_cogl_rectangle_map_foreach_cb (CoglRectangleMapNode *node, void *data) -{ - CoglRectangleMapForeachClosure *closure = data; - - if (node->type == COGL_RECTANGLE_MAP_FILLED_LEAF) - closure->callback (&node->rectangle, node->d.data, closure->data); -} - -void -_cogl_rectangle_map_foreach (CoglRectangleMap *map, - CoglRectangleMapCallback callback, - void *data) -{ - CoglRectangleMapForeachClosure closure; - - closure.callback = callback; - closure.data = data; - - _cogl_rectangle_map_internal_foreach (map, - _cogl_rectangle_map_foreach_cb, - &closure); -} - -static void -_cogl_rectangle_map_free_cb (CoglRectangleMapNode *node, void *data) -{ - CoglRectangleMap *map = data; - - if (node->type == COGL_RECTANGLE_MAP_FILLED_LEAF && map->value_destroy_func) - map->value_destroy_func (node->d.data); - - _cogl_rectangle_map_node_free (node); -} - -void -_cogl_rectangle_map_free (CoglRectangleMap *map) -{ - _cogl_rectangle_map_internal_foreach (map, - _cogl_rectangle_map_free_cb, - map); - - g_array_free (map->stack, TRUE); - - g_free (map); -} diff --git a/mutter/cogl/cogl/cogl-rectangle-map.h b/mutter/cogl/cogl/cogl-rectangle-map.h deleted file mode 100644 index d1a69a2..0000000 --- a/mutter/cogl/cogl/cogl-rectangle-map.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#include - -#include "cogl/cogl-types.h" - -typedef struct _CoglRectangleMap CoglRectangleMap; -typedef struct _CoglRectangleMapEntry CoglRectangleMapEntry; - -typedef void (* CoglRectangleMapCallback) (const CoglRectangleMapEntry *entry, - void *rectangle_data, - void *user_data); - -struct _CoglRectangleMapEntry -{ - unsigned int x, y; - unsigned int width, height; -}; - -CoglRectangleMap * -_cogl_rectangle_map_new (unsigned int width, - unsigned int height, - GDestroyNotify value_destroy_func); - -gboolean -_cogl_rectangle_map_add (CoglRectangleMap *map, - unsigned int width, - unsigned int height, - void *data, - CoglRectangleMapEntry *rectangle); - -void -_cogl_rectangle_map_remove (CoglRectangleMap *map, - const CoglRectangleMapEntry *rectangle); - -unsigned int -_cogl_rectangle_map_get_width (CoglRectangleMap *map); - -unsigned int -_cogl_rectangle_map_get_height (CoglRectangleMap *map); - -unsigned int -_cogl_rectangle_map_get_remaining_space (CoglRectangleMap *map); - -unsigned int -_cogl_rectangle_map_get_n_rectangles (CoglRectangleMap *map); - -void -_cogl_rectangle_map_foreach (CoglRectangleMap *map, - CoglRectangleMapCallback callback, - void *data); - -void -_cogl_rectangle_map_free (CoglRectangleMap *map); diff --git a/mutter/cogl/cogl/cogl-renderer-private.h b/mutter/cogl/cogl/cogl-renderer-private.h deleted file mode 100644 index 8fd9155..0000000 --- a/mutter/cogl/cogl/cogl-renderer-private.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include - -#include "cogl/cogl-driver.h" -#include "cogl/cogl-texture-driver.h" -#include "cogl/cogl-context.h" -#include "cogl/cogl-closure-list-private.h" -#include "cogl/winsys/cogl-winsys-private.h" - -typedef const CoglWinsysVtable *(*CoglCustomWinsysVtableGetter) (CoglRenderer *renderer); - -struct _CoglRenderer -{ - GObject parent_instance; - gboolean connected; - CoglDriver driver_override; - const CoglDriverVtable *driver_vtable; - const CoglTextureDriver *texture_driver; - const CoglWinsysVtable *winsys_vtable; - void *custom_winsys_user_data; - CoglCustomWinsysVtableGetter custom_winsys_vtable_getter; - CoglWinsysID winsys_id_override; - GList *constraints; - - GArray *poll_fds; - int poll_fds_age; - GList *poll_sources; - - CoglList idle_closures; - - GList *outputs; - -#ifdef HAVE_X11 - Display *foreign_xdpy; - gboolean xlib_enable_event_retrieval; - gboolean xlib_want_reset_on_video_memory_purge; -#endif - - CoglDriver driver; - unsigned long private_features - [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)]; - GModule *libgl_module; - - /* List of callback functions that will be given every native event */ - GSList *event_filters; - void *winsys; -}; - -typedef CoglFilterReturn (* CoglNativeFilterFunc) (void *native_event, - void *data); - -CoglFilterReturn -_cogl_renderer_handle_native_event (CoglRenderer *renderer, - void *event); - -void -_cogl_renderer_add_native_filter (CoglRenderer *renderer, - CoglNativeFilterFunc func, - void *data); - -void -_cogl_renderer_remove_native_filter (CoglRenderer *renderer, - CoglNativeFilterFunc func, - void *data); - -void * -_cogl_renderer_get_proc_address (CoglRenderer *renderer, - const char *name); diff --git a/mutter/cogl/cogl/cogl-renderer.c b/mutter/cogl/cogl/cogl-renderer.c deleted file mode 100644 index 8e8bc4a..0000000 --- a/mutter/cogl/cogl/cogl-renderer.c +++ /dev/null @@ -1,798 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include -#include -#include - -#include "cogl/cogl-util.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-mutter.h" - -#include "cogl/cogl-renderer.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-display-private.h" - -#include "cogl/winsys/cogl-winsys-private.h" - -#ifdef HAVE_EGL_PLATFORM_XLIB -#include "cogl/winsys/cogl-winsys-egl-x11-private.h" -#endif -#ifdef HAVE_GLX -#include "cogl/winsys/cogl-winsys-glx-private.h" -#endif - -#ifdef HAVE_X11 -#include "cogl/cogl-xlib-renderer.h" -#endif - -#ifdef HAVE_GL -extern const CoglTextureDriver _cogl_texture_driver_gl; -extern const CoglDriverVtable _cogl_driver_gl; -#endif -#ifdef HAVE_GLES2 -extern const CoglTextureDriver _cogl_texture_driver_gles; -extern const CoglDriverVtable _cogl_driver_gles; -#endif - -extern const CoglDriverVtable _cogl_driver_nop; - -typedef struct _CoglDriverDescription -{ - CoglDriver id; - const char *name; - /* It would be nice to make this a pointer and then use a compound - * literal from C99 to initialise it but we probably can't get away - * with using C99 here. Instead we'll just use a fixed-size array. - * GCC should complain if someone adds an 8th feature to a - * driver. */ - const CoglPrivateFeature private_features[8]; - const CoglDriverVtable *vtable; - const CoglTextureDriver *texture_driver; - const char *libgl_name; -} CoglDriverDescription; - -static CoglDriverDescription _cogl_drivers[] = -{ -#ifdef HAVE_GL - { - COGL_DRIVER_GL3, - "gl3", - { COGL_PRIVATE_FEATURE_ANY_GL, - -1 }, - &_cogl_driver_gl, - &_cogl_texture_driver_gl, - COGL_GL_LIBNAME, - }, -#endif -#ifdef HAVE_GLES2 - { - COGL_DRIVER_GLES2, - "gles2", - { COGL_PRIVATE_FEATURE_ANY_GL, - -1 }, - &_cogl_driver_gles, - &_cogl_texture_driver_gles, - COGL_GLES2_LIBNAME, - }, -#endif - { - COGL_DRIVER_NOP, - "nop", - { -1 }, - &_cogl_driver_nop, - NULL, /* texture driver */ - NULL /* libgl_name */ - } -}; - -static CoglWinsysVtableGetter _cogl_winsys_vtable_getters[] = -{ -#ifdef HAVE_GLX - _cogl_winsys_glx_get_vtable, -#endif -#ifdef HAVE_EGL_PLATFORM_XLIB - _cogl_winsys_egl_xlib_get_vtable, -#endif -}; - -static const CoglWinsysVtable * -_cogl_renderer_get_winsys (CoglRenderer *renderer) -{ - return renderer->winsys_vtable; -} - -typedef struct _CoglNativeFilterClosure -{ - CoglNativeFilterFunc func; - void *data; -} CoglNativeFilterClosure; - -static void -native_filter_closure_free (CoglNativeFilterClosure *closure) -{ - g_free (closure); -} - -G_DEFINE_TYPE (CoglRenderer, cogl_renderer, G_TYPE_OBJECT); - -static void -cogl_renderer_dispose (GObject *object) -{ - CoglRenderer *renderer = COGL_RENDERER (object); - - const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); - - _cogl_closure_list_disconnect_all (&renderer->idle_closures); - - if (winsys) - winsys->renderer_disconnect (renderer); - - if (renderer->libgl_module) - g_module_close (renderer->libgl_module); - - g_slist_free_full (renderer->event_filters, - (GDestroyNotify) native_filter_closure_free); - - g_array_free (renderer->poll_fds, TRUE); - - G_OBJECT_CLASS (cogl_renderer_parent_class)->dispose (object); -} - -static void -cogl_renderer_init (CoglRenderer *renderer) -{ -} - -static void -cogl_renderer_class_init (CoglRendererClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = cogl_renderer_dispose; -} - -uint32_t -cogl_renderer_error_quark (void) -{ - return g_quark_from_static_string ("cogl-renderer-error-quark"); -} - -CoglRenderer * -cogl_renderer_new (void) -{ - CoglRenderer *renderer = g_object_new (COGL_TYPE_RENDERER, NULL); - - _cogl_init (); - - renderer->connected = FALSE; - renderer->event_filters = NULL; - - renderer->poll_fds = g_array_new (FALSE, TRUE, sizeof (CoglPollFD)); - - _cogl_list_init (&renderer->idle_closures); - -#ifdef HAVE_X11 - renderer->xlib_enable_event_retrieval = TRUE; -#endif - - return renderer; -} - -#ifdef HAVE_X11 -void -cogl_xlib_renderer_set_foreign_display (CoglRenderer *renderer, - Display *xdisplay) -{ - g_return_if_fail (COGL_IS_RENDERER (renderer)); - - /* NB: Renderers are considered immutable once connected */ - g_return_if_fail (!renderer->connected); - - renderer->foreign_xdpy = xdisplay; - - /* If the application is using a foreign display then we can assume - it will also do its own event retrieval */ - renderer->xlib_enable_event_retrieval = FALSE; -} - -Display * -cogl_xlib_renderer_get_foreign_display (CoglRenderer *renderer) -{ - g_return_val_if_fail (COGL_IS_RENDERER (renderer), NULL); - - return renderer->foreign_xdpy; -} - -void -cogl_xlib_renderer_request_reset_on_video_memory_purge (CoglRenderer *renderer, - gboolean enable) -{ - g_return_if_fail (COGL_IS_RENDERER (renderer)); - g_return_if_fail (!renderer->connected); - - renderer->xlib_want_reset_on_video_memory_purge = enable; -} -#endif /* HAVE_X11 */ - -gboolean -cogl_renderer_check_onscreen_template (CoglRenderer *renderer, - CoglOnscreenTemplate *onscreen_template, - GError **error) -{ - CoglDisplay *display; - - if (!cogl_renderer_connect (renderer, error)) - return FALSE; - - display = cogl_display_new (renderer, onscreen_template); - if (!cogl_display_setup (display, error)) - { - g_object_unref (display); - return FALSE; - } - - g_object_unref (display); - - return TRUE; -} - -typedef gboolean (*CoglDriverCallback) (CoglDriverDescription *description, - void *user_data); - -static void -foreach_driver_description (CoglDriver driver_override, - CoglDriverCallback callback, - void *user_data) -{ -#ifdef COGL_DEFAULT_DRIVER - const CoglDriverDescription *default_driver = NULL; -#endif - int i; - - if (driver_override != COGL_DRIVER_ANY) - { - for (i = 0; i < G_N_ELEMENTS (_cogl_drivers); i++) - { - if (_cogl_drivers[i].id == driver_override) - { - callback (&_cogl_drivers[i], user_data); - return; - } - } - - g_warn_if_reached (); - return; - } - -#ifdef COGL_DEFAULT_DRIVER - for (i = 0; i < G_N_ELEMENTS (_cogl_drivers); i++) - { - const CoglDriverDescription *desc = &_cogl_drivers[i]; - if (g_ascii_strcasecmp (desc->name, COGL_DEFAULT_DRIVER) == 0) - { - default_driver = desc; - break; - } - } - - if (default_driver) - { - if (!callback (default_driver, user_data)) - return; - } -#endif - - for (i = 0; i < G_N_ELEMENTS (_cogl_drivers); i++) - { -#ifdef COGL_DEFAULT_DRIVER - if (&_cogl_drivers[i] == default_driver) - continue; -#endif - - if (!callback (&_cogl_drivers[i], user_data)) - return; - } -} - -static CoglDriver -driver_name_to_id (const char *name) -{ - int i; - - for (i = 0; i < G_N_ELEMENTS (_cogl_drivers); i++) - { - if (g_ascii_strcasecmp (_cogl_drivers[i].name, name) == 0) - return _cogl_drivers[i].id; - } - - return COGL_DRIVER_ANY; -} - -static const char * -driver_id_to_name (CoglDriver id) -{ - switch (id) - { - case COGL_DRIVER_GL3: - return "gl3"; - case COGL_DRIVER_GLES2: - return "gles2"; - case COGL_DRIVER_NOP: - return "nop"; - case COGL_DRIVER_ANY: - g_warn_if_reached (); - return "any"; - } - - g_warn_if_reached (); - return "unknown"; -} - -typedef struct _SatisfyConstraintsState -{ - const CoglDriverDescription *driver_description; -} SatisfyConstraintsState; - -/* XXX this is still uglier than it needs to be */ -static gboolean -satisfy_constraints (CoglDriverDescription *description, - void *user_data) -{ - SatisfyConstraintsState *state = user_data; - - state->driver_description = description; - - return FALSE; -} - -static gboolean -_cogl_renderer_choose_driver (CoglRenderer *renderer, - GError **error) -{ - const char *driver_name = g_getenv ("COGL_DRIVER"); - CoglDriver driver_override = COGL_DRIVER_ANY; - const char *invalid_override = NULL; - const char *libgl_name; - SatisfyConstraintsState state; - const CoglDriverDescription *desc; - int i; - - if (driver_name) - { - driver_override = driver_name_to_id (driver_name); - if (driver_override == COGL_DRIVER_ANY) - invalid_override = driver_name; - } - - if (renderer->driver_override != COGL_DRIVER_ANY) - { - if (driver_override != COGL_DRIVER_ANY && - renderer->driver_override != driver_override) - { - g_set_error (error, COGL_RENDERER_ERROR, - COGL_RENDERER_ERROR_BAD_CONSTRAINT, - "Application driver selection conflicts with driver " - "specified in configuration"); - return FALSE; - } - - driver_override = renderer->driver_override; - } - - if (driver_override != COGL_DRIVER_ANY) - { - gboolean found = FALSE; - int i; - - for (i = 0; i < G_N_ELEMENTS (_cogl_drivers); i++) - { - if (_cogl_drivers[i].id == driver_override) - { - found = TRUE; - break; - } - } - if (!found) - invalid_override = driver_id_to_name (driver_override); - } - - if (invalid_override) - { - g_set_error (error, COGL_RENDERER_ERROR, - COGL_RENDERER_ERROR_BAD_CONSTRAINT, - "Driver \"%s\" is not available", - invalid_override); - return FALSE; - } - - state.driver_description = NULL; - - foreach_driver_description (driver_override, - satisfy_constraints, - &state); - - if (!state.driver_description) - { - g_set_error (error, COGL_RENDERER_ERROR, - COGL_RENDERER_ERROR_BAD_CONSTRAINT, - "No suitable driver found"); - return FALSE; - } - - desc = state.driver_description; - renderer->driver = desc->id; - renderer->driver_vtable = desc->vtable; - renderer->texture_driver = desc->texture_driver; - libgl_name = desc->libgl_name; - - memset(renderer->private_features, 0, sizeof (renderer->private_features)); - for (i = 0; desc->private_features[i] != -1; i++) - COGL_FLAGS_SET (renderer->private_features, - desc->private_features[i], TRUE); - - if (COGL_FLAGS_GET (renderer->private_features, - COGL_PRIVATE_FEATURE_ANY_GL)) - { - renderer->libgl_module = g_module_open (libgl_name, - G_MODULE_BIND_LAZY); - - if (renderer->libgl_module == NULL) - { - g_set_error (error, COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_FAILED_TO_LOAD_LIBRARY, - "Failed to dynamically open the GL library \"%s\"", - libgl_name); - return FALSE; - } - } - - return TRUE; -} - -/* Final connection API */ - -void -cogl_renderer_set_custom_winsys (CoglRenderer *renderer, - CoglCustomWinsysVtableGetter winsys_vtable_getter, - void *user_data) -{ - renderer->custom_winsys_user_data = user_data; - renderer->custom_winsys_vtable_getter = winsys_vtable_getter; -} - -static gboolean -connect_custom_winsys (CoglRenderer *renderer, - GError **error) -{ - const CoglWinsysVtable *winsys; - GError *tmp_error = NULL; - GString *error_message; - - winsys = renderer->custom_winsys_vtable_getter (renderer); - renderer->winsys_vtable = winsys; - - error_message = g_string_new (""); - if (!winsys->renderer_connect (renderer, &tmp_error)) - { - g_string_append_c (error_message, '\n'); - g_string_append (error_message, tmp_error->message); - g_error_free (tmp_error); - } - else - { - renderer->connected = TRUE; - g_string_free (error_message, TRUE); - return TRUE; - } - - renderer->winsys_vtable = NULL; - g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, - "Failed to connected to any renderer: %s", error_message->str); - g_string_free (error_message, TRUE); - return FALSE; -} - -gboolean -cogl_renderer_connect (CoglRenderer *renderer, GError **error) -{ - int i; - g_autoptr (GString) error_message = NULL; - gboolean constraints_failed = FALSE; - - if (renderer->connected) - return TRUE; - - /* The driver needs to be chosen before connecting the renderer - because eglInitialize requires the library containing the GL API - to be loaded before its called */ - if (!_cogl_renderer_choose_driver (renderer, error)) - return FALSE; - - if (renderer->custom_winsys_vtable_getter) - return connect_custom_winsys (renderer, error); - - error_message = g_string_new (""); - for (i = 0; i < G_N_ELEMENTS (_cogl_winsys_vtable_getters); i++) - { - const CoglWinsysVtable *winsys = _cogl_winsys_vtable_getters[i](); - GError *tmp_error = NULL; - GList *l; - gboolean skip_due_to_constraints = FALSE; - - if (renderer->winsys_id_override != COGL_WINSYS_ID_ANY) - { - if (renderer->winsys_id_override != winsys->id) - continue; - } - else - { - char *user_choice = getenv ("COGL_RENDERER"); - if (user_choice && - g_ascii_strcasecmp (winsys->name, user_choice) != 0) - continue; - } - - for (l = renderer->constraints; l; l = l->next) - { - CoglRendererConstraint constraint = GPOINTER_TO_UINT (l->data); - if (!(winsys->constraints & constraint)) - { - skip_due_to_constraints = TRUE; - break; - } - } - if (skip_due_to_constraints) - { - constraints_failed |= TRUE; - continue; - } - - /* At least temporarily we will associate this winsys with - * the renderer in-case ->renderer_connect calls API that - * wants to query the current winsys... */ - renderer->winsys_vtable = winsys; - - if (!winsys->renderer_connect (renderer, &tmp_error)) - { - g_string_append_c (error_message, '\n'); - g_string_append (error_message, tmp_error->message); - g_error_free (tmp_error); - } - else - { - renderer->connected = TRUE; - return TRUE; - } - } - - if (!renderer->connected) - { - if (constraints_failed) - { - g_set_error (error, COGL_RENDERER_ERROR, - COGL_RENDERER_ERROR_BAD_CONSTRAINT, - "Failed to connected to any renderer due to constraints"); - return FALSE; - } - - renderer->winsys_vtable = NULL; - g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, - "Failed to connected to any renderer: %s", - error_message->str); - return FALSE; - } - - return TRUE; -} - -CoglFilterReturn -_cogl_renderer_handle_native_event (CoglRenderer *renderer, - void *event) -{ - GSList *l, *next; - - /* Pass the event on to all of the registered filters in turn */ - for (l = renderer->event_filters; l; l = next) - { - CoglNativeFilterClosure *closure = l->data; - - /* The next pointer is taken now so that we can handle the - closure being removed during emission */ - next = l->next; - - if (closure->func (event, closure->data) == COGL_FILTER_REMOVE) - return COGL_FILTER_REMOVE; - } - - /* If the backend for the renderer also wants to see the events, it - should just register its own filter */ - - return COGL_FILTER_CONTINUE; -} - -void -_cogl_renderer_add_native_filter (CoglRenderer *renderer, - CoglNativeFilterFunc func, - void *data) -{ - CoglNativeFilterClosure *closure; - - closure = g_new0 (CoglNativeFilterClosure, 1); - closure->func = func; - closure->data = data; - - renderer->event_filters = g_slist_prepend (renderer->event_filters, closure); -} - -void -_cogl_renderer_remove_native_filter (CoglRenderer *renderer, - CoglNativeFilterFunc func, - void *data) -{ - GSList *l, *prev = NULL; - - for (l = renderer->event_filters; l; prev = l, l = l->next) - { - CoglNativeFilterClosure *closure = l->data; - - if (closure->func == func && closure->data == data) - { - native_filter_closure_free (closure); - if (prev) - prev->next = g_slist_delete_link (prev->next, l); - else - renderer->event_filters = - g_slist_delete_link (renderer->event_filters, l); - break; - } - } -} - -void -cogl_renderer_set_winsys_id (CoglRenderer *renderer, - CoglWinsysID winsys_id) -{ - g_return_if_fail (!renderer->connected); - - renderer->winsys_id_override = winsys_id; -} - -CoglWinsysID -cogl_renderer_get_winsys_id (CoglRenderer *renderer) -{ - g_return_val_if_fail (renderer->connected, 0); - - return renderer->winsys_vtable->id; -} - -void * -_cogl_renderer_get_proc_address (CoglRenderer *renderer, - const char *name) -{ - const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); - - return winsys->renderer_get_proc_address (renderer, name); -} - -void -cogl_renderer_add_constraint (CoglRenderer *renderer, - CoglRendererConstraint constraint) -{ - g_return_if_fail (!renderer->connected); - renderer->constraints = g_list_prepend (renderer->constraints, - GUINT_TO_POINTER (constraint)); -} - -void -cogl_renderer_remove_constraint (CoglRenderer *renderer, - CoglRendererConstraint constraint) -{ - g_return_if_fail (!renderer->connected); - renderer->constraints = g_list_remove (renderer->constraints, - GUINT_TO_POINTER (constraint)); -} - -void -cogl_renderer_set_driver (CoglRenderer *renderer, - CoglDriver driver) -{ - g_return_if_fail (!renderer->connected); - renderer->driver_override = driver; -} - -CoglDriver -cogl_renderer_get_driver (CoglRenderer *renderer) -{ - g_return_val_if_fail (renderer->connected, 0); - - return renderer->driver; -} - -void -cogl_renderer_foreach_output (CoglRenderer *renderer, - CoglOutputCallback callback, - void *user_data) -{ - GList *l; - - g_return_if_fail (renderer->connected); - g_return_if_fail (callback != NULL); - - for (l = renderer->outputs; l; l = l->next) - callback (l->data, user_data); -} - -CoglDmaBufHandle * -cogl_renderer_create_dma_buf (CoglRenderer *renderer, - CoglPixelFormat format, - uint64_t *modifiers, - int n_modifiers, - int width, - int height, - GError **error) -{ - const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); - - if (winsys->renderer_create_dma_buf) - return winsys->renderer_create_dma_buf (renderer, - format, - modifiers, n_modifiers, - width, height, - error); - - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "CoglRenderer doesn't support creating DMA buffers"); - - return NULL; -} - -gboolean -cogl_renderer_is_dma_buf_supported (CoglRenderer *renderer) -{ - const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); - - if (winsys->renderer_is_dma_buf_supported) - return winsys->renderer_is_dma_buf_supported (renderer); - else - return FALSE; -} - -void -cogl_renderer_bind_api (CoglRenderer *renderer) -{ - const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); - - winsys->renderer_bind_api (renderer); -} diff --git a/mutter/cogl/cogl/cogl-renderer.h b/mutter/cogl/cogl/cogl-renderer.h deleted file mode 100644 index d1b4789..0000000 --- a/mutter/cogl/cogl/cogl-renderer.h +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-types.h" -#include "cogl/cogl-onscreen-template.h" -#include "cogl/cogl-output.h" -#include "cogl/cogl-pixel-format.h" - -#include - -G_BEGIN_DECLS - -/** - * CoglRenderer: - * - * Choosing a means to render - * - * A #CoglRenderer represents a means to render. It encapsulates the - * selection of an underlying driver, such as OpenGL or OpenGL-ES and - * a selection of a window system binding API such as GLX or EGL. - * - * A #CoglRenderer has two states, "unconnected" and "connected". When - * a renderer is first instantiated using cogl_renderer_new() it is - * unconnected so that it can be configured and constraints can be - * specified for how the backend driver and window system should be - * chosen. - * - * After configuration a #CoglRenderer can (optionally) be explicitly - * connected using cogl_renderer_connect() which allows for the - * handling of connection errors so that fallback configurations can - * be tried if necessary. Applications that don't support any - * fallbacks though can skip using cogl_renderer_connect() and leave - * Cogl to automatically connect the renderer. - * - * Once you have a configured #CoglRenderer it can be used to create a - * #CoglDisplay object using cogl_display_new(). - */ - - -/** - * COGL_RENDERER_ERROR: - * - * An error domain for exceptions reported by Cogl - */ -#define COGL_RENDERER_ERROR cogl_renderer_error_quark () - -COGL_EXPORT uint32_t -cogl_renderer_error_quark (void); - -typedef struct _CoglRenderer CoglRenderer; - -#define COGL_TYPE_RENDERER (cogl_renderer_get_type ()) - -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglRenderer, - cogl_renderer, - COGL, - RENDERER, - GObject) - - -/** - * cogl_renderer_new: - * - * Instantiates a new (unconnected) #CoglRenderer object. A - * #CoglRenderer represents a means to render. It encapsulates the - * selection of an underlying driver, such as OpenGL or OpenGL-ES and - * a selection of a window system binding API such as GLX or EGL. - * - * While the renderer is unconnected it can be configured so that - * applications may specify backend constraints, such as "must use - * x11" for example via cogl_renderer_add_constraint(). - * - * There are also some platform specific configuration apis such - * as cogl_xlib_renderer_set_foreign_display() that may also be - * used while the renderer is unconnected. - * - * Once the renderer has been configured, then it may (optionally) be - * explicitly connected using cogl_renderer_connect() which allows - * errors to be handled gracefully and potentially fallback - * configurations can be tried out if there are initial failures. - * - * If a renderer is not explicitly connected then cogl_display_new() - * will automatically connect the renderer for you. If you don't - * have any code to deal with error/fallback situations then its fine - * to just let Cogl do the connection for you. - * - * Once you have setup your renderer then the next step is to create a - * #CoglDisplay using cogl_display_new(). - * - * Return value: (transfer full): A newly created #CoglRenderer. - */ -COGL_EXPORT CoglRenderer * -cogl_renderer_new (void); - -/* optional configuration APIs */ - -/** - * CoglWinsysID: - * @COGL_WINSYS_ID_ANY: Implies no preference for which backend is used - * @COGL_WINSYS_ID_STUB: Use the no-op stub backend - * @COGL_WINSYS_ID_GLX: Use the GLX window system binding API - * @COGL_WINSYS_ID_EGL_XLIB: Use EGL with the X window system via XLib - * - * Identifies specific window system backends that Cogl supports. - * - * These can be used to query what backend Cogl is using or to try and - * explicitly select a backend to use. - */ -typedef enum -{ - COGL_WINSYS_ID_ANY, - COGL_WINSYS_ID_STUB, - COGL_WINSYS_ID_GLX, - COGL_WINSYS_ID_EGL_XLIB, - COGL_WINSYS_ID_CUSTOM, -} CoglWinsysID; - -/** - * cogl_renderer_set_winsys_id: - * @renderer: A #CoglRenderer - * @winsys_id: An ID of the winsys you explicitly want to use. - * - * This allows you to explicitly select a winsys backend to use instead - * of letting Cogl automatically select a backend. - * - * if you select an unsupported backend then cogl_renderer_connect() - * will fail and report an error. - * - * This may only be called on an un-connected #CoglRenderer. - */ -COGL_EXPORT void -cogl_renderer_set_winsys_id (CoglRenderer *renderer, - CoglWinsysID winsys_id); - -/** - * cogl_renderer_get_winsys_id: - * @renderer: A #CoglRenderer - * - * Queries which window system backend Cogl has chosen to use. - * - * This may only be called on a connected #CoglRenderer. - * - * Returns: The #CoglWinsysID corresponding to the chosen window - * system backend. - */ -COGL_EXPORT CoglWinsysID -cogl_renderer_get_winsys_id (CoglRenderer *renderer); - -/** - * cogl_renderer_check_onscreen_template: - * @renderer: A #CoglRenderer - * @onscreen_template: A #CoglOnscreenTemplate - * @error: A pointer to a #GError for reporting exceptions - * - * Tests if a given @onscreen_template can be supported with the given - * @renderer. - * - * Return value: %TRUE if the @onscreen_template can be supported, - * else %FALSE. - */ -COGL_EXPORT gboolean -cogl_renderer_check_onscreen_template (CoglRenderer *renderer, - CoglOnscreenTemplate *onscreen_template, - GError **error); - -/* Final connection API */ - -/** - * cogl_renderer_connect: - * @renderer: An unconnected #CoglRenderer - * @error: a pointer to a #GError for reporting exceptions - * - * Connects the configured @renderer. Renderer connection isn't a - * very active process, it basically just means validating that - * any given constraint criteria can be satisfied and that a - * usable driver and window system backend can be found. - * - * Return value: %TRUE if there was no error while connecting the - * given @renderer. %FALSE if there was an error. - */ -COGL_EXPORT gboolean -cogl_renderer_connect (CoglRenderer *renderer, GError **error); - -/** - * CoglRendererConstraint: - * @COGL_RENDERER_CONSTRAINT_USES_X11: Require the renderer to be X11 based - * @COGL_RENDERER_CONSTRAINT_USES_XLIB: Require the renderer to be X11 - * based and use Xlib - * @COGL_RENDERER_CONSTRAINT_USES_EGL: Require the renderer to be EGL based - * - * These constraint flags are hard-coded features of the different renderer - * backends. Sometimes a platform may support multiple rendering options which - * Cogl will usually choose from automatically. Some of these features are - * important to higher level applications and frameworks though, such as - * whether a renderer is X11 based because an application might only support - * X11 based input handling. An application might also need to ensure EGL is - * used internally too if they depend on access to an EGLDisplay for some - * purpose. - * - * Applications should ideally minimize how many of these constraints - * they depend on to ensure maximum portability. - */ -typedef enum -{ - COGL_RENDERER_CONSTRAINT_USES_X11 = (1 << 0), - COGL_RENDERER_CONSTRAINT_USES_XLIB = (1 << 1), - COGL_RENDERER_CONSTRAINT_USES_EGL = (1 << 2), -} CoglRendererConstraint; - - -/** - * cogl_renderer_add_constraint: - * @renderer: An unconnected #CoglRenderer - * @constraint: A #CoglRendererConstraint to add - * - * This adds a renderer selection @constraint. - * - * Applications should ideally minimize how many of these constraints they - * depend on to ensure maximum portability. - */ -COGL_EXPORT void -cogl_renderer_add_constraint (CoglRenderer *renderer, - CoglRendererConstraint constraint); - -/** - * cogl_renderer_remove_constraint: - * @renderer: An unconnected #CoglRenderer - * @constraint: A #CoglRendererConstraint to remove - * - * This removes a renderer selection @constraint. - * - * Applications should ideally minimize how many of these constraints they - * depend on to ensure maximum portability. - */ -COGL_EXPORT void -cogl_renderer_remove_constraint (CoglRenderer *renderer, - CoglRendererConstraint constraint); - -/** - * CoglDriver: - * @COGL_DRIVER_ANY: Implies no preference for which driver is used - * @COGL_DRIVER_NOP: A No-Op driver. - * @COGL_DRIVER_GL3: An OpenGL driver using the core GL 3.1 profile - * @COGL_DRIVER_GLES2: An OpenGL ES 2.0 driver. - * - * Identifiers for underlying hardware drivers that may be used by - * Cogl for rendering. - */ -typedef enum -{ - COGL_DRIVER_ANY, - COGL_DRIVER_NOP, - COGL_DRIVER_GL3, - COGL_DRIVER_GLES2, -} CoglDriver; - -/** - * cogl_renderer_set_driver: - * @renderer: An unconnected #CoglRenderer - * - * Requests that Cogl should try to use a specific underlying driver - * for rendering. - * - * If you select an unsupported driver then cogl_renderer_connect() - * will fail and report an error. Most applications should not - * explicitly select a driver and should rely on Cogl automatically - * choosing the driver. - * - * This may only be called on an un-connected #CoglRenderer. - */ -COGL_EXPORT void -cogl_renderer_set_driver (CoglRenderer *renderer, - CoglDriver driver); - -/** - * cogl_renderer_get_driver: - * @renderer: A connected #CoglRenderer - * - * Queries what underlying driver is being used by Cogl. - * - * This may only be called on a connected #CoglRenderer. - */ -COGL_EXPORT CoglDriver -cogl_renderer_get_driver (CoglRenderer *renderer); - -/** - * CoglOutputCallback: - * @output: The current display output being iterated - * @user_data: The user pointer passed to - * cogl_renderer_foreach_output() - * - * A callback type that can be passed to - * cogl_renderer_foreach_output() for iterating display outputs for a - * given renderer. - */ -typedef void (*CoglOutputCallback) (CoglOutput *output, void *user_data); - -/** - * cogl_renderer_foreach_output: - * @renderer: A connected #CoglRenderer - * @callback: (scope call): A #CoglOutputCallback to be called for - * each display output - * @user_data: A user pointer to be passed to @callback - * - * Iterates all known display outputs for the given @renderer and - * passes a corresponding #CoglOutput pointer to the given @callback - * for each one, along with the given @user_data. - */ -COGL_EXPORT void -cogl_renderer_foreach_output (CoglRenderer *renderer, - CoglOutputCallback callback, - void *user_data); - -/** - * cogl_renderer_create_dma_buf: (skip) - * @renderer: A #CoglRenderer - * @format: A #CoglPixelFormat - * @modifiers: array of DRM format modifiers - * @n_modifiers: length of modifiers array - * @width: width of the new - * @height: height of the new - * @error: (nullable): return location for a #GError - * - * Creates a new #CoglFramebuffer with @width x @height, with pixel - * format @format, and exports the new framebuffer's DMA buffer - * handle. - * - * Passing an empty modifier array (passing a 0 n_modifiers) means implicit - * modifiers will be used. - * - * Returns: (nullable)(transfer full): a #CoglDmaBufHandle. The - * return result must be released with cogl_dma_buf_handle_free() - * after use. - */ -COGL_EXPORT CoglDmaBufHandle * -cogl_renderer_create_dma_buf (CoglRenderer *renderer, - CoglPixelFormat format, - uint64_t *modifiers, - int n_modifiers, - int width, - int height, - GError **error); - - -/** - * cogl_renderer_is_dma_buf_supported: - * @renderer: A #CoglRenderer - * - * Returns: %TRUE if DMA buffers can be allocated - */ -COGL_EXPORT gboolean -cogl_renderer_is_dma_buf_supported (CoglRenderer *renderer); - -/** - * cogl_renderer_bind_api: - */ -COGL_EXPORT void -cogl_renderer_bind_api (CoglRenderer *renderer); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-sampler-cache-private.h b/mutter/cogl/cogl/cogl-sampler-cache-private.h deleted file mode 100644 index 48dc736..0000000 --- a/mutter/cogl/cogl/cogl-sampler-cache-private.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-context.h" -#include "cogl/cogl-gl-header.h" - -/* These aren't defined in the GLES headers */ -#ifndef GL_CLAMP_TO_BORDER -#define GL_CLAMP_TO_BORDER 0x812d -#endif -#ifndef GL_MIRRORED_REPEAT -#define GL_MIRRORED_REPEAT 0x8370 -#endif - -/* GL_ALWAYS is just used here as a value that is known not to clash - * with any valid GL wrap modes. - * - * XXX: keep the values in sync with the CoglPipelineWrapMode enum - * so no conversion is actually needed. - */ -typedef enum _CoglSamplerCacheWrapMode -{ - COGL_SAMPLER_CACHE_WRAP_MODE_REPEAT = GL_REPEAT, - COGL_SAMPLER_CACHE_WRAP_MODE_MIRRORED_REPEAT = GL_MIRRORED_REPEAT, - COGL_SAMPLER_CACHE_WRAP_MODE_CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE, - COGL_SAMPLER_CACHE_WRAP_MODE_CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER, - COGL_SAMPLER_CACHE_WRAP_MODE_AUTOMATIC = GL_ALWAYS -} CoglSamplerCacheWrapMode; - -typedef struct _CoglSamplerCache CoglSamplerCache; - -typedef struct _CoglSamplerCacheEntry -{ - GLuint sampler_object; - - GLenum min_filter; - GLenum mag_filter; - - CoglSamplerCacheWrapMode wrap_mode_s; - CoglSamplerCacheWrapMode wrap_mode_t; -} CoglSamplerCacheEntry; - -CoglSamplerCache * -_cogl_sampler_cache_new (CoglContext *context); - -const CoglSamplerCacheEntry * -_cogl_sampler_cache_get_default_entry (CoglSamplerCache *cache); - -const CoglSamplerCacheEntry * -_cogl_sampler_cache_update_wrap_modes (CoglSamplerCache *cache, - const CoglSamplerCacheEntry *old_entry, - CoglSamplerCacheWrapMode wrap_mode_s, - CoglSamplerCacheWrapMode wrap_mode_t); - -const CoglSamplerCacheEntry * -_cogl_sampler_cache_update_filters (CoglSamplerCache *cache, - const CoglSamplerCacheEntry *old_entry, - GLenum min_filter, - GLenum mag_filter); - -void -_cogl_sampler_cache_free (CoglSamplerCache *cache); diff --git a/mutter/cogl/cogl/cogl-sampler-cache.c b/mutter/cogl/cogl/cogl-sampler-cache.c deleted file mode 100644 index 9ce249e..0000000 --- a/mutter/cogl/cogl/cogl-sampler-cache.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Neil Roberts - */ - -#include "config.h" - -#include "cogl/cogl-sampler-cache-private.h" -#include "cogl/cogl-context-private.h" - -struct _CoglSamplerCache -{ - CoglContext *context; - - /* The samplers are hashed in two tables. One is using the enum - values that Cogl exposes (so it can include the 'automatic' wrap - mode) and the other is using the converted values that will be - given to GL. The first is used to get a unique pointer for the - sampler state so that pipelines only need to store a single - pointer instead of the whole state and the second is used so that - only a single GL sampler object will be created for each unique - GL state. */ - GHashTable *hash_table_cogl; - GHashTable *hash_table_gl; -}; - -static CoglSamplerCacheWrapMode -get_real_wrap_mode (CoglSamplerCacheWrapMode wrap_mode) -{ - if (wrap_mode == COGL_SAMPLER_CACHE_WRAP_MODE_AUTOMATIC) - return COGL_SAMPLER_CACHE_WRAP_MODE_CLAMP_TO_EDGE; - - return wrap_mode; -} - -static void -canonicalize_key (CoglSamplerCacheEntry *key) -{ - /* This converts the wrap modes to the enums that will actually be - given to GL so that it can be used as a key to get a unique GL - sampler object for the state */ - key->wrap_mode_s = get_real_wrap_mode (key->wrap_mode_s); - key->wrap_mode_t = get_real_wrap_mode (key->wrap_mode_t); -} - -static gboolean -wrap_mode_equal_gl (CoglSamplerCacheWrapMode wrap_mode0, - CoglSamplerCacheWrapMode wrap_mode1) -{ - /* We want to compare the actual GLenum that will be used so that if - two different wrap_modes actually use the same GL state we'll - still use the same sampler object */ - return get_real_wrap_mode (wrap_mode0) == get_real_wrap_mode (wrap_mode1); -} - -static gboolean -sampler_state_equal_gl (const void *value0, - const void *value1) -{ - const CoglSamplerCacheEntry *state0 = value0; - const CoglSamplerCacheEntry *state1 = value1; - - return (state0->mag_filter == state1->mag_filter && - state0->min_filter == state1->min_filter && - wrap_mode_equal_gl (state0->wrap_mode_s, state1->wrap_mode_s) && - wrap_mode_equal_gl (state0->wrap_mode_t, state1->wrap_mode_t)); -} - -static unsigned int -hash_wrap_mode_gl (unsigned int hash, - CoglSamplerCacheWrapMode wrap_mode) -{ - /* We want to hash the actual GLenum that will be used so that if - two different wrap_modes actually use the same GL state we'll - still use the same sampler object */ - GLenum real_wrap_mode = get_real_wrap_mode (wrap_mode); - - return _cogl_util_one_at_a_time_hash (hash, - &real_wrap_mode, - sizeof (real_wrap_mode)); -} - -static unsigned int -hash_sampler_state_gl (const void *key) -{ - const CoglSamplerCacheEntry *entry = key; - unsigned int hash = 0; - - hash = _cogl_util_one_at_a_time_hash (hash, &entry->mag_filter, - sizeof (entry->mag_filter)); - hash = _cogl_util_one_at_a_time_hash (hash, &entry->min_filter, - sizeof (entry->min_filter)); - hash = hash_wrap_mode_gl (hash, entry->wrap_mode_s); - hash = hash_wrap_mode_gl (hash, entry->wrap_mode_t); - - return _cogl_util_one_at_a_time_mix (hash); -} - -static gboolean -sampler_state_equal_cogl (const void *value0, - const void *value1) -{ - const CoglSamplerCacheEntry *state0 = value0; - const CoglSamplerCacheEntry *state1 = value1; - - return (state0->mag_filter == state1->mag_filter && - state0->min_filter == state1->min_filter && - state0->wrap_mode_s == state1->wrap_mode_s && - state0->wrap_mode_t == state1->wrap_mode_t); -} - -static unsigned int -hash_sampler_state_cogl (const void *key) -{ - const CoglSamplerCacheEntry *entry = key; - unsigned int hash = 0; - - hash = _cogl_util_one_at_a_time_hash (hash, &entry->mag_filter, - sizeof (entry->mag_filter)); - hash = _cogl_util_one_at_a_time_hash (hash, &entry->min_filter, - sizeof (entry->min_filter)); - hash = _cogl_util_one_at_a_time_hash (hash, &entry->wrap_mode_s, - sizeof (entry->wrap_mode_s)); - hash = _cogl_util_one_at_a_time_hash (hash, &entry->wrap_mode_t, - sizeof (entry->wrap_mode_t)); - - return _cogl_util_one_at_a_time_mix (hash); -} - -CoglSamplerCache * -_cogl_sampler_cache_new (CoglContext *context) -{ - CoglSamplerCache *cache = g_new (CoglSamplerCache, 1); - - /* No reference is taken on the context because it would create a - circular reference */ - cache->context = context; - - cache->hash_table_gl = g_hash_table_new (hash_sampler_state_gl, - sampler_state_equal_gl); - cache->hash_table_cogl = g_hash_table_new (hash_sampler_state_cogl, - sampler_state_equal_cogl); - - return cache; -} - -static CoglSamplerCacheEntry * -_cogl_sampler_cache_get_entry_gl (CoglSamplerCache *cache, - const CoglSamplerCacheEntry *key) -{ - CoglSamplerCacheEntry *entry; - - entry = g_hash_table_lookup (cache->hash_table_gl, key); - - if (entry == NULL) - { - entry = g_memdup2 (key, sizeof (CoglSamplerCacheEntry)); - - cache->context->driver_vtable->sampler_init (cache->context, entry); - - g_hash_table_insert (cache->hash_table_gl, entry, entry); - } - - return entry; -} - -static CoglSamplerCacheEntry * -_cogl_sampler_cache_get_entry_cogl (CoglSamplerCache *cache, - const CoglSamplerCacheEntry *key) -{ - CoglSamplerCacheEntry *entry; - - entry = g_hash_table_lookup (cache->hash_table_cogl, key); - - if (entry == NULL) - { - CoglSamplerCacheEntry canonical_key; - CoglSamplerCacheEntry *gl_entry; - - entry = g_memdup2 (key, sizeof (CoglSamplerCacheEntry)); - - /* Get the sampler object number from the canonical GL version - of the sampler state cache */ - canonical_key = *key; - canonicalize_key (&canonical_key); - gl_entry = _cogl_sampler_cache_get_entry_gl (cache, &canonical_key); - entry->sampler_object = gl_entry->sampler_object; - - g_hash_table_insert (cache->hash_table_cogl, entry, entry); - } - - return entry; -} - -const CoglSamplerCacheEntry * -_cogl_sampler_cache_get_default_entry (CoglSamplerCache *cache) -{ - CoglSamplerCacheEntry key; - - key.wrap_mode_s = COGL_SAMPLER_CACHE_WRAP_MODE_AUTOMATIC; - key.wrap_mode_t = COGL_SAMPLER_CACHE_WRAP_MODE_AUTOMATIC; - - key.min_filter = GL_LINEAR; - key.mag_filter = GL_LINEAR; - - return _cogl_sampler_cache_get_entry_cogl (cache, &key); -} - -const CoglSamplerCacheEntry * -_cogl_sampler_cache_update_wrap_modes (CoglSamplerCache *cache, - const CoglSamplerCacheEntry *old_entry, - CoglSamplerCacheWrapMode wrap_mode_s, - CoglSamplerCacheWrapMode wrap_mode_t) -{ - CoglSamplerCacheEntry key = *old_entry; - - key.wrap_mode_s = wrap_mode_s; - key.wrap_mode_t = wrap_mode_t; - - return _cogl_sampler_cache_get_entry_cogl (cache, &key); -} - -const CoglSamplerCacheEntry * -_cogl_sampler_cache_update_filters (CoglSamplerCache *cache, - const CoglSamplerCacheEntry *old_entry, - GLenum min_filter, - GLenum mag_filter) -{ - CoglSamplerCacheEntry key = *old_entry; - - key.min_filter = min_filter; - key.mag_filter = mag_filter; - - return _cogl_sampler_cache_get_entry_cogl (cache, &key); -} - -static void -hash_table_free_gl_cb (void *key, - void *value, - void *user_data) -{ - CoglContext *context = user_data; - CoglSamplerCacheEntry *entry = value; - - context->driver_vtable->sampler_free (context, entry); - - g_free (entry); -} - -static void -hash_table_free_cogl_cb (void *key, - void *value, - void *user_data) -{ - CoglSamplerCacheEntry *entry = value; - - g_free (entry); -} - -void -_cogl_sampler_cache_free (CoglSamplerCache *cache) -{ - g_hash_table_foreach (cache->hash_table_gl, - hash_table_free_gl_cb, - cache->context); - - g_hash_table_destroy (cache->hash_table_gl); - - g_hash_table_foreach (cache->hash_table_cogl, - hash_table_free_cogl_cb, - cache->context); - - g_hash_table_destroy (cache->hash_table_cogl); - - g_free (cache); -} diff --git a/mutter/cogl/cogl/cogl-scanout.c b/mutter/cogl/cogl/cogl-scanout.c deleted file mode 100644 index 94f5d5d..0000000 --- a/mutter/cogl/cogl/cogl-scanout.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 2019 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - * - */ - -#include "config.h" - -#include "cogl/cogl-scanout.h" - -enum -{ - SCANOUT_FAILED, - - N_SIGNALS -}; - -static guint signals[N_SIGNALS]; - -G_DEFINE_INTERFACE (CoglScanoutBuffer, cogl_scanout_buffer, G_TYPE_OBJECT) - -struct _CoglScanout -{ - GObject parent; - - CoglScanoutBuffer *scanout_buffer; - - gboolean has_src_rect; - graphene_rect_t src_rect; - gboolean has_dst_rect; - MtkRectangle dst_rect; -}; - -G_DEFINE_FINAL_TYPE (CoglScanout, cogl_scanout, G_TYPE_OBJECT); - -static void -cogl_scanout_buffer_default_init (CoglScanoutBufferInterface *iface) -{ -} - -gboolean -cogl_scanout_blit_to_framebuffer (CoglScanout *scanout, - CoglFramebuffer *framebuffer, - int x, - int y, - GError **error) -{ - CoglScanoutBufferInterface *iface = - COGL_SCANOUT_BUFFER_GET_IFACE (scanout->scanout_buffer); - - return iface->blit_to_framebuffer (scanout, framebuffer, x, y, error); -} - -int -cogl_scanout_buffer_get_width (CoglScanoutBuffer *scanout_buffer) -{ - CoglScanoutBufferInterface *iface = - COGL_SCANOUT_BUFFER_GET_IFACE (scanout_buffer); - - return iface->get_width (scanout_buffer); -} - -int -cogl_scanout_buffer_get_height (CoglScanoutBuffer *scanout_buffer) -{ - CoglScanoutBufferInterface *iface = - COGL_SCANOUT_BUFFER_GET_IFACE (scanout_buffer); - - return iface->get_height (scanout_buffer); -} - -CoglScanoutBuffer * -cogl_scanout_get_buffer (CoglScanout *scanout) -{ - return scanout->scanout_buffer; -} - -void -cogl_scanout_notify_failed (CoglScanout *scanout, - CoglOnscreen *onscreen) -{ - g_signal_emit (scanout, signals[SCANOUT_FAILED], 0, onscreen); -} - -CoglScanout * -cogl_scanout_new (CoglScanoutBuffer *scanout_buffer) -{ - CoglScanout *scanout = g_object_new (COGL_TYPE_SCANOUT, NULL); - - scanout->scanout_buffer = scanout_buffer; - - return scanout; -} - -void -cogl_scanout_get_src_rect (CoglScanout *scanout, - graphene_rect_t *rect) -{ - if (scanout->has_src_rect) - { - *rect = scanout->src_rect; - return; - } - - rect->origin.x = 0; - rect->origin.y = 0; - rect->size.width = cogl_scanout_buffer_get_width (scanout->scanout_buffer); - rect->size.height = cogl_scanout_buffer_get_height (scanout->scanout_buffer); -} - -void -cogl_scanout_set_src_rect (CoglScanout *scanout, - const graphene_rect_t *rect) -{ - if (rect != NULL) - scanout->src_rect = *rect; - - scanout->has_src_rect = rect != NULL; -} - -void -cogl_scanout_get_dst_rect (CoglScanout *scanout, - MtkRectangle *rect) -{ - if (scanout->has_dst_rect) - { - *rect = scanout->dst_rect; - return; - } - - rect->x = 0; - rect->y = 0; - rect->width = cogl_scanout_buffer_get_width (scanout->scanout_buffer); - rect->height = cogl_scanout_buffer_get_height (scanout->scanout_buffer); -} - -void -cogl_scanout_set_dst_rect (CoglScanout *scanout, - const MtkRectangle *rect) -{ - if (rect != NULL) - scanout->dst_rect = *rect; - - scanout->has_dst_rect = rect != NULL; -} - -static void -cogl_scanout_finalize (GObject *object) -{ - CoglScanout *scanout = COGL_SCANOUT (object); - - g_clear_object (&scanout->scanout_buffer); - - G_OBJECT_CLASS (cogl_scanout_parent_class)->finalize (object); -} - -static void -cogl_scanout_class_init (CoglScanoutClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = cogl_scanout_finalize; - - signals[SCANOUT_FAILED] = - g_signal_new ("scanout-failed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, - COGL_TYPE_ONSCREEN); -} - -static void -cogl_scanout_init (CoglScanout *scanout) -{ -} diff --git a/mutter/cogl/cogl/cogl-scanout.h b/mutter/cogl/cogl/cogl-scanout.h deleted file mode 100644 index a62a7d7..0000000 --- a/mutter/cogl/cogl/cogl-scanout.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2019 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - * - */ - -#pragma once - -#include "cogl/cogl-types.h" -#include "cogl/cogl-framebuffer.h" -#include "cogl/cogl-onscreen.h" -#include "mtk/mtk.h" - -#include - -#define COGL_TYPE_SCANOUT (cogl_scanout_get_type ()) -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglScanout, cogl_scanout, - COGL, SCANOUT, GObject) - -#define COGL_TYPE_SCANOUT_BUFFER (cogl_scanout_buffer_get_type ()) -COGL_EXPORT -G_DECLARE_INTERFACE (CoglScanoutBuffer, cogl_scanout_buffer, - COGL, SCANOUT_BUFFER, GObject) - -struct _CoglScanoutBufferInterface -{ - GTypeInterface parent_iface; - - gboolean (*blit_to_framebuffer) (CoglScanout *scanout, - CoglFramebuffer *framebuffer, - int x, - int y, - GError **error); - - int (*get_width) (CoglScanoutBuffer *scanout_buffer); - int (*get_height) (CoglScanoutBuffer *scanout_buffer); -}; - -COGL_EXPORT -gboolean cogl_scanout_blit_to_framebuffer (CoglScanout *scanout, - CoglFramebuffer *framebuffer, - int x, - int y, - GError **error); - -int cogl_scanout_buffer_get_width (CoglScanoutBuffer *scanout_buffer); -int cogl_scanout_buffer_get_height (CoglScanoutBuffer *scanout_buffer); - -/** - * cogl_scanout_get_buffer: - * - * Returns: (transfer none): a #CoglScanoutBuffer - */ -COGL_EXPORT -CoglScanoutBuffer * cogl_scanout_get_buffer (CoglScanout *scanout); - -COGL_EXPORT -void cogl_scanout_notify_failed (CoglScanout *scanout, - CoglOnscreen *onscreen); - -COGL_EXPORT -CoglScanout * cogl_scanout_new (CoglScanoutBuffer *scanout_buffer); - -COGL_EXPORT -void cogl_scanout_get_src_rect (CoglScanout *scanout, - graphene_rect_t *rect); - -COGL_EXPORT -void cogl_scanout_set_src_rect (CoglScanout *scanout, - const graphene_rect_t *rect); - -COGL_EXPORT -void cogl_scanout_get_dst_rect (CoglScanout *scanout, - MtkRectangle *rect); - -COGL_EXPORT -void cogl_scanout_set_dst_rect (CoglScanout *scanout, - const MtkRectangle *rect); diff --git a/mutter/cogl/cogl/cogl-snippet-private.h b/mutter/cogl/cogl/cogl-snippet-private.h deleted file mode 100644 index ead7303..0000000 --- a/mutter/cogl/cogl/cogl-snippet-private.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#pragma once - -#include - -#include "cogl/cogl-snippet.h" - -/* These values are also used in the enum for CoglSnippetHook. They - are copied here because we don't really want these names to be part - of the public API */ -#define COGL_SNIPPET_HOOK_BAND_SIZE 2048 -#define COGL_SNIPPET_FIRST_PIPELINE_HOOK 0 -#define COGL_SNIPPET_FIRST_PIPELINE_VERTEX_HOOK \ - COGL_SNIPPET_FIRST_PIPELINE_HOOK -#define COGL_SNIPPET_FIRST_PIPELINE_FRAGMENT_HOOK \ - (COGL_SNIPPET_FIRST_PIPELINE_VERTEX_HOOK + COGL_SNIPPET_HOOK_BAND_SIZE) -#define COGL_SNIPPET_FIRST_LAYER_HOOK (COGL_SNIPPET_HOOK_BAND_SIZE * 2) -#define COGL_SNIPPET_FIRST_LAYER_VERTEX_HOOK COGL_SNIPPET_FIRST_LAYER_HOOK -#define COGL_SNIPPET_FIRST_LAYER_FRAGMENT_HOOK \ - (COGL_SNIPPET_FIRST_LAYER_VERTEX_HOOK + COGL_SNIPPET_HOOK_BAND_SIZE) - -struct _CoglSnippet -{ - GObject parent_instance; - - CoglSnippetHook hook; - - /* This is set to TRUE the first time the snippet is attached to the - pipeline. After that any attempts to modify the snippet will be - ignored. */ - gboolean immutable; - - char *declarations; - char *pre; - char *replace; - char *post; -}; - -void -_cogl_snippet_make_immutable (CoglSnippet *snippet); diff --git a/mutter/cogl/cogl/cogl-snippet.c b/mutter/cogl/cogl/cogl-snippet.c deleted file mode 100644 index 8e14d5d..0000000 --- a/mutter/cogl/cogl/cogl-snippet.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#include "config.h" - -#include "cogl/cogl-types.h" -#include "cogl/cogl-snippet-private.h" -#include "cogl/cogl-util.h" - -G_DEFINE_TYPE (CoglSnippet, cogl_snippet, G_TYPE_OBJECT); - - -static void -cogl_snippet_dispose (GObject *object) -{ - CoglSnippet *snippet = COGL_SNIPPET (object); - - g_free (snippet->declarations); - g_free (snippet->pre); - g_free (snippet->replace); - g_free (snippet->post); - - G_OBJECT_CLASS (cogl_snippet_parent_class)->dispose (object); -} - -static void -cogl_snippet_init (CoglSnippet *display) -{ -} - -static void -cogl_snippet_class_init (CoglSnippetClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = cogl_snippet_dispose; -} - - -CoglSnippet * -cogl_snippet_new (CoglSnippetHook hook, - const char *declarations, - const char *post) -{ - CoglSnippet *snippet = g_object_new (COGL_TYPE_SNIPPET, NULL); - - snippet->hook = hook; - - cogl_snippet_set_declarations (snippet, declarations); - cogl_snippet_set_post (snippet, post); - - return snippet; -} - -CoglSnippetHook -cogl_snippet_get_hook (CoglSnippet *snippet) -{ - g_return_val_if_fail (COGL_IS_SNIPPET (snippet), 0); - - return snippet->hook; -} - -static gboolean -_cogl_snippet_modify (CoglSnippet *snippet) -{ - if (snippet->immutable) - { - g_warning ("A CoglSnippet should not be modified once it has been " - "attached to a pipeline. Any modifications after that point " - "will be ignored."); - - return FALSE; - } - - return TRUE; -} - -void -cogl_snippet_set_declarations (CoglSnippet *snippet, - const char *declarations) -{ - g_return_if_fail (COGL_IS_SNIPPET (snippet)); - - if (!_cogl_snippet_modify (snippet)) - return; - - g_free (snippet->declarations); - snippet->declarations = declarations ? g_strdup (declarations) : NULL; -} - -const char * -cogl_snippet_get_declarations (CoglSnippet *snippet) -{ - g_return_val_if_fail (COGL_IS_SNIPPET (snippet), NULL); - - return snippet->declarations; -} - -void -cogl_snippet_set_pre (CoglSnippet *snippet, - const char *pre) -{ - g_return_if_fail (COGL_IS_SNIPPET (snippet)); - - if (!_cogl_snippet_modify (snippet)) - return; - - g_free (snippet->pre); - snippet->pre = pre ? g_strdup (pre) : NULL; -} - -const char * -cogl_snippet_get_pre (CoglSnippet *snippet) -{ - g_return_val_if_fail (COGL_IS_SNIPPET (snippet), NULL); - - return snippet->pre; -} - -void -cogl_snippet_set_replace (CoglSnippet *snippet, - const char *replace) -{ - g_return_if_fail (COGL_IS_SNIPPET (snippet)); - - if (!_cogl_snippet_modify (snippet)) - return; - - g_free (snippet->replace); - snippet->replace = replace ? g_strdup (replace) : NULL; -} - -const char * -cogl_snippet_get_replace (CoglSnippet *snippet) -{ - g_return_val_if_fail (COGL_IS_SNIPPET (snippet), NULL); - - return snippet->replace; -} - -void -cogl_snippet_set_post (CoglSnippet *snippet, - const char *post) -{ - g_return_if_fail (COGL_IS_SNIPPET (snippet)); - - if (!_cogl_snippet_modify (snippet)) - return; - - g_free (snippet->post); - snippet->post = post ? g_strdup (post) : NULL; -} - -const char * -cogl_snippet_get_post (CoglSnippet *snippet) -{ - g_return_val_if_fail (COGL_IS_SNIPPET (snippet), NULL); - - return snippet->post; -} - -void -_cogl_snippet_make_immutable (CoglSnippet *snippet) -{ - snippet->immutable = TRUE; -} diff --git a/mutter/cogl/cogl/cogl-snippet.h b/mutter/cogl/cogl/cogl-snippet.h deleted file mode 100644 index 03b0f92..0000000 --- a/mutter/cogl/cogl/cogl-snippet.h +++ /dev/null @@ -1,625 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011, 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -G_BEGIN_DECLS - -/** - * CoglSnippet: - * - * Functions for creating and manipulating shader snippets - * - * `CoglSnippet`s are used to modify or replace parts of a - * #CoglPipeline using GLSL. GLSL is a programming language supported - * by OpenGL on programmable hardware to provide a more flexible - * description of what should be rendered. A description of GLSL - * itself is outside the scope of this documentation but any good - * OpenGL book should help to describe it. - * - * Unlike in OpenGL, when using GLSL with Cogl it is possible to write - * short snippets to replace small sections of the pipeline instead of - * having to replace the whole of either the vertex or fragment - * pipelines. Of course it is also possible to replace the whole of - * the pipeline if needed. - * - * Each snippet is a standalone chunk of code which would attach to - * the pipeline at a particular point. The code is split into four - * separate strings (all of which are optional): - * - * - `declarations` - * The code in this string will be inserted outside of any function in - * the global scope of the shader. This can be used to declare - * uniforms, attributes, varyings and functions to be used by the - * snippet. - * - `pre` - * The code in this string will be inserted before the hook point. - * - `post` - * The code in this string will be inserted after the hook point. This - * can be used to modify the results of the builtin generated code for - * that hook point. - * - `replace - * If present the code in this string will replace the generated code - * for the hook point. - * - * All of the strings apart from the declarations string of a pipeline - * are generated in a single function so they can share variables - * declared from one string in another. The scope of the code is - * limited to each snippet so local variables declared in the snippet - * will not collide with variables declared in another - * snippet. However, code in the 'declarations' string is global to - * the shader so it is the application's responsibility to ensure that - * variables declared here will not collide with those from other - * snippets. - * - * The snippets can be added to a pipeline with - * cogl_pipeline_add_snippet() or - * cogl_pipeline_add_layer_snippet(). Which function to use depends on - * which hook the snippet is targeting. The snippets are all - * generated in the order they are added to the pipeline. That is, the - * post strings are executed in the order they are added to the - * pipeline and the pre strings are executed in reverse order. If any - * replace strings are given for a snippet then any other snippets - * with the same hook added before that snippet will be ignored. The - * different hooks are documented under #CoglSnippetHook. - * - * For portability with GLES2, it is recommended not to use the GLSL - * builtin names such as gl_FragColor. Instead there are replacement - * names under the cogl_* namespace which can be used instead. These - * are: - * - * - `uniform mat4 cogl_modelview_matrix - * The current modelview matrix. This is equivalent to - * #gl_ModelViewMatrix. - * - `uniform mat4 cogl_projection_matrix - * The current projection matrix. This is equivalent to - * #gl_ProjectionMatrix. - * - `uniform mat4 cogl_modelview_projection_matrix - * The combined modelview and projection matrix. A vertex shader - * would typically use this to transform the incoming vertex - * position. The separate modelview and projection matrices are - * usually only needed for lighting calculations. This is - * equivalent to #gl_ModelViewProjectionMatrix. - * - `uniform mat4 cogl_texture_matrix[] - * An array of matrices for transforming the texture - * coordinates. This is equivalent to #gl_TextureMatrix. - * - * In a vertex shader, the following are also available: - * - * - `attribute vec4 cogl_position_in - * The incoming vertex position. This is equivalent to #gl_Vertex. - * - `attribute vec4 cogl_color_in` - * The incoming vertex color. This is equivalent to #gl_Color. - * - `attribute vec4 cogl_tex_coord_in` - * The texture coordinate for layer 0. This is an alternative name - * for #cogl_tex_coord0_in. - * - `attribute vec4 cogl_tex_coord0_in - * The texture coordinate for the layer 0. This is equivalent to - * #gl_MultiTexCoord0. There will also be #cogl_tex_coord1_in and - * so on if more layers are added to the pipeline. - * - `attribute vec3 cogl_normal_in` - * The normal of the vertex. This is equivalent to #gl_Normal. - * - `vec4 cogl_position_out - * The calculated position of the vertex. This must be written to - * in all vertex shaders. This is equivalent to #gl_Position. - * - `float cogl_point_size_in - * The incoming point size from the cogl_point_size_in attribute. - * This is only available if - * cogl_pipeline_set_per_vertex_point_size() is set on the - * pipeline. - * - `float cogl_point_size_out` - * The calculated size of a point. This is equivalent to #gl_PointSize. - * - `varying vec4 cogl_color_out` - * The calculated color of a vertex. This is equivalent to #gl_FrontColor. - * - `varying vec4 cogl_tex_coord0_out` - * The calculated texture coordinate for layer 0 of the pipeline. - * This is equivalent to #gl_TexCoord[0]. There will also be - * #cogl_tex_coord1_out and so on if more layers are added to the - * pipeline. In the fragment shader, this varying is called - * #cogl_tex_coord0_in. - * - * In a fragment shader, the following are also available: - * - * - `varying vec4 cogl_color_in` - * The calculated color of a vertex. This is equivalent to #gl_FrontColor. - * - `varying vec4 cogl_tex_coord0_in` - * The texture coordinate for layer 0. This is equivalent to - * #gl_TexCoord[0]. There will also be #cogl_tex_coord1_in and so - * on if more layers are added to the pipeline. - * - `vec4 cogl_color_out` - * The final calculated color of the fragment. All fragment shaders - * must write to this variable. This is equivalent to - * #gl_FrontColor. - * - `float cogl_depth_out` - * An optional output variable specifying the depth value to use - * for this fragment. This is equivalent to #gl_FragDepth. - * - `bool cogl_front_facing` - * A readonly variable that will be true if the current primitive - * is front facing. This can be used to implement two-sided - * coloring algorithms. This is equivalent to #gl_FrontFacing. - * - `vec2 cogl_point_coord` - * When rendering points, this will contain a vec2 which represents - * the position within the point of the current fragment. - * vec2(0.0,0.0) will be the topleft of the point and vec2(1.0,1.0) - * will be the bottom right. Note that there is currently a bug in - * Cogl where when rendering to an offscreen buffer these - * coordinates will be upside-down. The value is undefined when not - * rendering points. - * - * Here is an example of using a snippet to add a desaturate effect to the - * generated color on a pipeline. - * - * ```c - * CoglPipeline *pipeline = cogl_pipeline_new (); - * - * /* Set up the pipeline here, ie by adding a texture or other - * layers */ - * - * /* Create the snippet. The first string is the declarations which - * we will use to add a uniform. The second is the 'post' string which - * will contain the code to perform the desaturation. */ - * CoglSnippet *snippet = - * cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, - * "uniform float factor;", - * "float gray = dot (vec3 (0.299, 0.587, 0.114), " - * " cogl_color_out.rgb);" - * "cogl_color_out.rgb = mix (vec3 (gray)," - * " cogl_color_out.rgb," - * " factor);"); - * - * /* Add it to the pipeline */ - * cogl_pipeline_add_snippet (pipeline, snippet); - * /* The pipeline keeps a reference to the snippet - * so we don't need to */ - * g_object_unref (snippet); - * - * /* Update the custom uniform on the pipeline */ - * int location = cogl_pipeline_get_uniform_location (pipeline, "factor"); - * cogl_pipeline_set_uniform_1f (pipeline, location, 0.5f); - * - * /* Now we can render with the snippet as usual */ - * cogl_push_source (pipeline); - * cogl_rectangle (0, 0, 10, 10); - * cogl_pop_source (); - * ``` - */ -typedef struct _CoglSnippet CoglSnippet; - -#define COGL_TYPE_SNIPPET (cogl_snippet_get_type ()) - -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglSnippet, - cogl_snippet, - COGL, - SNIPPET, - GObject) - -/* Enumeration of all the hook points that a snippet can be attached - to within a pipeline. */ -/** - * CoglSnippetHook: - * @COGL_SNIPPET_HOOK_VERTEX_GLOBALS: A hook for declaring global data - * that can be shared with all other snippets that are on a vertex - * hook. - * @COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS: A hook for declaring global - * data wthat can be shared with all other snippets that are on a - * fragment hook. - * @COGL_SNIPPET_HOOK_VERTEX: A hook for the entire vertex processing - * stage of the pipeline. - * @COGL_SNIPPET_HOOK_VERTEX_TRANSFORM: A hook for the vertex transformation. - * @COGL_SNIPPET_HOOK_POINT_SIZE: A hook for manipulating the point - * size of a vertex. This is only used if - * cogl_pipeline_set_per_vertex_point_size() is enabled on the - * pipeline. - * @COGL_SNIPPET_HOOK_FRAGMENT: A hook for the entire fragment - * processing stage of the pipeline. - * @COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM: A hook for applying the - * layer matrix to a texture coordinate for a layer. - * @COGL_SNIPPET_HOOK_LAYER_FRAGMENT: A hook for the fragment - * processing of a particular layer. - * @COGL_SNIPPET_HOOK_TEXTURE_LOOKUP: A hook for the texture lookup - * stage of a given layer in a pipeline. - * - * #CoglSnippetHook is used to specify a location within a - * #CoglPipeline where the code of the snippet should be used when it - * is attached to a pipeline. - * - * - `COGL_SNIPPET_HOOK_VERTEX_GLOBALS` - * - * Adds a shader snippet at the beginning of the global section of the - * shader for the vertex processing. Any declarations here can be - * shared with all other snippets that are attached to a vertex hook. - * Only the ‘declarations’ string is used and the other strings are - * ignored. - * - * - `COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS` - * - * Adds a shader snippet at the beginning of the global section of the - * shader for the fragment processing. Any declarations here can be - * shared with all other snippets that are attached to a fragment - * hook. Only the ‘declarations’ string is used and the other strings - * are ignored. - * - * - `COGL_SNIPPET_HOOK_VERTEX` - * - * Adds a shader snippet that will hook on to the vertex processing - * stage of the pipeline. This gives a chance for the application to - * modify the vertex attributes generated by the shader. Typically the - * snippet will modify cogl_color_out or cogl_position_out builtins. - * - * The ‘declarations’ string in @snippet will be inserted in the - * global scope of the shader. Use this to declare any uniforms, - * attributes or functions that the snippet requires. - * - * The ‘pre’ string in @snippet will be inserted at the top of the - * main() function before any vertex processing is done. - * - * The ‘replace’ string in @snippet will be used instead of the - * generated vertex processing if it is present. This can be used if - * the application wants to provide a complete vertex shader and - * doesn't need the generated output from Cogl. - * - * The ‘post’ string in @snippet will be inserted after all of the - * standard vertex processing is done. This can be used to modify the - * outputs. - * - * - `COGL_SNIPPET_HOOK_VERTEX_TRANSFORM` - * - * Adds a shader snippet that will hook on to the vertex transform stage. - * Typically the snippet will use the cogl_modelview_matrix, - * cogl_projection_matrix and cogl_modelview_projection_matrix matrices and the - * cogl_position_in attribute. The hook must write to cogl_position_out. - * The default processing for this hook will multiply cogl_position_in by - * the combined modelview-projection matrix and store it on cogl_position_out. - * - * The ‘declarations’ string in @snippet will be inserted in the - * global scope of the shader. Use this to declare any uniforms, - * attributes or functions that the snippet requires. - * - * The ‘pre’ string in @snippet will be inserted at the top of the - * main() function before the vertex transform is done. - * - * The ‘replace’ string in @snippet will be used instead of the - * generated vertex transform if it is present. - * - * The ‘post’ string in @snippet will be inserted after all of the - * standard vertex transformation is done. This can be used to modify the - * cogl_position_out in addition to the default processing. - * - * - `COGL_SNIPPET_HOOK_POINT_SIZE` - * - * Adds a shader snippet that will hook on to the point size - * calculation step within the vertex shader stage. The snippet should - * write to the builtin cogl_point_size_out with the new point size. - * The snippet can either read cogl_point_size_in directly and write a - * new value or first read an existing value in cogl_point_size_out - * that would be set by a previous snippet. Note that this hook is - * only used if cogl_pipeline_set_per_vertex_point_size() is enabled - * on the pipeline. - * - * The ‘declarations’ string in @snippet will be inserted in the - * global scope of the shader. Use this to declare any uniforms, - * attributes or functions that the snippet requires. - * - * The ‘pre’ string in @snippet will be inserted just before - * calculating the point size. - * - * The ‘replace’ string in @snippet will be used instead of the - * generated point size calculation if it is present. - * - * The ‘post’ string in @snippet will be inserted after the - * standard point size calculation is done. This can be used to modify - * cogl_point_size_out in addition to the default processing. - * - * - `COGL_SNIPPET_HOOK_FRAGMENT` - * - * Adds a shader snippet that will hook on to the fragment processing - * stage of the pipeline. This gives a chance for the application to - * modify the fragment color generated by the shader. Typically the - * snippet will modify cogl_color_out. - * - * The ‘declarations’ string in @snippet will be inserted in the - * global scope of the shader. Use this to declare any uniforms, - * attributes or functions that the snippet requires. - * - * The ‘pre’ string in @snippet will be inserted at the top of the - * main() function before any fragment processing is done. - * - * The ‘replace’ string in @snippet will be used instead of the - * generated fragment processing if it is present. This can be used if - * the application wants to provide a complete fragment shader and - * doesn't need the generated output from Cogl. - * - * The ‘post’ string in @snippet will be inserted after all of the - * standard fragment processing is done. At this point the generated - * value for the rest of the pipeline state will already be in - * cogl_color_out so the application can modify the result by altering - * this variable. - * - * - `COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM` - * - * Adds a shader snippet that will hook on to the texture coordinate - * transformation of a particular layer. This can be used to replace - * the processing for a layer or to modify the results. - * - * Within the snippet code for this hook there are two extra - * variables. The first is a mat4 called cogl_matrix which represents - * the user matrix for this layer. The second is called cogl_tex_coord - * and represents the incoming and outgoing texture coordinate. On - * entry to the hook, cogl_tex_coord contains the value of the - * corresponding texture coordinate attribute for this layer. The hook - * is expected to modify this variable. The output will be passed as a - * varying to the fragment processing stage. The default code will - * just multiply cogl_matrix by cogl_tex_coord and store the result in - * cogl_tex_coord. - * - * The ‘declarations’ string in @snippet will be inserted in the - * global scope of the shader. Use this to declare any uniforms, - * attributes or functions that the snippet requires. - * - * The ‘pre’ string in @snippet will be inserted just before the - * fragment processing for this layer. At this point cogl_tex_coord - * still contains the value of the texture coordinate attribute. - * If a ‘replace’ string is given then this will be used instead of - * the default fragment processing for this layer. The snippet can - * modify cogl_tex_coord or leave it as is to apply no transformation. - * - * The ‘post’ string in @snippet will be inserted just after the - * transformation. At this point cogl_tex_coord will contain the - * results of the transformation but it can be further modified by the - * snippet. - * - * - `COGL_SNIPPET_HOOK_LAYER_FRAGMENT` - * - * Adds a shader snippet that will hook on to the fragment processing - * of a particular layer. This can be used to replace the processing - * for a layer or to modify the results. - * - * Within the snippet code for this hook there is an extra vec4 - * variable called ‘cogl_layer’. This contains the resulting color - * that will be used for the layer. This can be modified in the ‘post’ - * section or it the default processing can be replaced entirely using - * the ‘replace’ section. - * - * The ‘declarations’ string in @snippet will be inserted in the - * global scope of the shader. Use this to declare any uniforms, - * attributes or functions that the snippet requires. - * - * The ‘pre’ string in @snippet will be inserted just before the - * fragment processing for this layer. - * - * If a ‘replace’ string is given then this will be used instead of - * the default fragment processing for this layer. The snippet must write to - * the ‘cogl_layer’ variable in that case. - * - * The ‘post’ string in @snippet will be inserted just after the - * fragment processing for the layer. The results can be modified by changing - * the value of the ‘cogl_layer’ variable. - * - * - `COGL_SNIPPET_HOOK_TEXTURE_LOOKUP` - * - * Adds a shader snippet that will hook on to the texture lookup part - * of a given layer. This gives a chance for the application to modify - * the coordinates that will be used for the texture lookup or to - * alter the returned texel. - * - * Within the snippet code for this hook there are three extra - * variables available. ‘cogl_sampler’ is a sampler object - * representing the sampler for the layer where the snippet is - * attached. ‘cogl_tex_coord’ is a vec4 which contains the texture - * coordinates that will be used for the texture lookup. This can be - * modified. ‘cogl_texel’ will contain the result of the texture - * lookup. This can also be modified. - * - * The ‘declarations’ string in @snippet will be inserted in the - * global scope of the shader. Use this to declare any uniforms, - * attributes or functions that the snippet requires. - * - * The ‘pre’ string in @snippet will be inserted at the top of the - * main() function before any fragment processing is done. This is a - * good place to modify the cogl_tex_coord variable. - * - * If a ‘replace’ string is given then this will be used instead of a - * the default texture lookup. The snippet would typically use its own - * sampler in this case. - * - * The ‘post’ string in @snippet will be inserted after texture lookup - * has been performed. Here the snippet can modify the cogl_texel - * variable to alter the returned texel. - */ -typedef enum -{ - /* Per pipeline vertex hooks */ - COGL_SNIPPET_HOOK_VERTEX = 0, - COGL_SNIPPET_HOOK_VERTEX_TRANSFORM, - COGL_SNIPPET_HOOK_VERTEX_GLOBALS, - COGL_SNIPPET_HOOK_POINT_SIZE, - - /* Per pipeline fragment hooks */ - COGL_SNIPPET_HOOK_FRAGMENT = 2048, - COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS, - - /* Per layer vertex hooks */ - COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM = 4096, - - /* Per layer fragment hooks */ - COGL_SNIPPET_HOOK_LAYER_FRAGMENT = 6144, - COGL_SNIPPET_HOOK_TEXTURE_LOOKUP -} CoglSnippetHook; - -/** - * cogl_snippet_new: - * @hook: The point in the pipeline that this snippet will wrap around - * or replace. - * @declarations: (nullable): The source code for the declarations for this - * snippet or %NULL. See cogl_snippet_set_declarations(). - * @post: (nullable): The source code to run after the hook point where this - * shader snippet is attached or %NULL. See cogl_snippet_set_post(). - * - * Allocates and initializes a new snippet with the given source strings. - * - * Returns: (transfer full): a pointer to a new #CoglSnippet - */ -COGL_EXPORT CoglSnippet * -cogl_snippet_new (CoglSnippetHook hook, - const char *declarations, - const char *post); - -/** - * cogl_snippet_get_hook: - * @snippet: A #CoglSnippet - * - * Returns: (transfer none): the hook that was set when cogl_snippet_new() - * was called. - */ -COGL_EXPORT CoglSnippetHook -cogl_snippet_get_hook (CoglSnippet *snippet); - -/** - * cogl_snippet_set_declarations: - * @snippet: A #CoglSnippet - * @declarations: The new source string for the declarations section - * of this snippet. - * - * Sets a source string that will be inserted in the global scope of - * the generated shader when this snippet is used on a pipeline. This - * string is typically used to declare uniforms, attributes or - * functions that will be used by the other parts of the snippets. - * - * This function should only be called before the snippet is attached - * to its first pipeline. After that the snippet should be considered - * immutable. - */ -COGL_EXPORT void -cogl_snippet_set_declarations (CoglSnippet *snippet, - const char *declarations); - -/** - * cogl_snippet_get_declarations: - * @snippet: A #CoglSnippet - * - * Returns: (transfer none): the source string that was set with - * cogl_snippet_set_declarations() or %NULL if none was set. - */ -COGL_EXPORT const char * -cogl_snippet_get_declarations (CoglSnippet *snippet); - -/** - * cogl_snippet_set_pre: - * @snippet: A #CoglSnippet - * @pre: The new source string for the pre section of this snippet. - * - * Sets a source string that will be inserted before the hook point in - * the generated shader for the pipeline that this snippet is attached - * to. Please see the documentation of each hook point in - * #CoglPipeline for a description of how this string should be used. - * - * This function should only be called before the snippet is attached - * to its first pipeline. After that the snippet should be considered - * immutable. - */ -COGL_EXPORT void -cogl_snippet_set_pre (CoglSnippet *snippet, - const char *pre); - -/** - * cogl_snippet_get_pre: - * @snippet: A #CoglSnippet - * - * Returns: (transfer none): the source string that was set with - * cogl_snippet_set_pre() or %NULL if none was set. - */ -COGL_EXPORT const char * -cogl_snippet_get_pre (CoglSnippet *snippet); - -/** - * cogl_snippet_set_replace: - * @snippet: A #CoglSnippet - * @replace: The new source string for the replace section of this snippet. - * - * Sets a source string that will be used instead of any generated - * source code or any previous snippets for this hook point. Please - * see the documentation of each hook point in #CoglPipeline for a - * description of how this string should be used. - * - * This function should only be called before the snippet is attached - * to its first pipeline. After that the snippet should be considered - * immutable. - */ -COGL_EXPORT void -cogl_snippet_set_replace (CoglSnippet *snippet, - const char *replace); - -/** - * cogl_snippet_get_replace: - * @snippet: A #CoglSnippet - * - * Returns: (transfer none): the source string that was set with - * cogl_snippet_set_replace() or %NULL if none was set. - */ -COGL_EXPORT const char * -cogl_snippet_get_replace (CoglSnippet *snippet); - -/** - * cogl_snippet_set_post: - * @snippet: A #CoglSnippet - * @post: The new source string for the post section of this snippet. - * - * Sets a source string that will be inserted after the hook point in - * the generated shader for the pipeline that this snippet is attached - * to. Please see the documentation of each hook point in - * #CoglPipeline for a description of how this string should be used. - * - * This function should only be called before the snippet is attached - * to its first pipeline. After that the snippet should be considered - * immutable. - */ -COGL_EXPORT void -cogl_snippet_set_post (CoglSnippet *snippet, - const char *post); - -/** - * cogl_snippet_get_post: - * @snippet: A #CoglSnippet - * - * Returns: (transfer none): the source string that was set with - * cogl_snippet_set_post() or %NULL if none was set. - */ -COGL_EXPORT const char * -cogl_snippet_get_post (CoglSnippet *snippet); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-soft-float.c b/mutter/cogl/cogl/cogl-soft-float.c deleted file mode 100644 index f261bbf..0000000 --- a/mutter/cogl/cogl/cogl-soft-float.c +++ /dev/null @@ -1,1733 +0,0 @@ -/* - * License for Berkeley SoftFloat Release 3e - * - * John R. Hauser - * 2018 January 20 - * - * The following applies to the whole of SoftFloat Release 3e as well as to - * each source file individually. - * - * Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the - * University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions, and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions, and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The functions listed in this file are modified versions of the ones - * from the Berkeley SoftFloat 3e Library. - * - * Their implementation correctness has been checked with the Berkeley - * TestFloat Release 3e tool for x86_64. - */ - -#include "config.h" - -#include "cogl/cogl-soft-float.h" - -#if G_BYTE_ORDER == G_BIG_ENDIAN -#define word_incr -1 -#define index_word(total, n) ((total) - 1 - (n)) -#define index_word_hi(total) 0 -#define index_word_lo(total) ((total) - 1) -#define index_multiword_hi(total, n) 0 -#define index_multiword_lo(total, n) ((total) - (n)) -#define index_multiword_hi_but(total, n) 0 -#define index_multiword_lo_but(total, n) (n) -#else -#define word_incr 1 -#define index_word(total, n) (n) -#define index_word_hi(total) ((total) - 1) -#define index_word_lo(total) 0 -#define index_multiword_hi(total, n) ((total) - (n)) -#define index_multiword_lo(total, n) 0 -#define index_multiword_hi_but(total, n) (n) -#define index_multiword_lo_but(total, n) 0 -#endif - -typedef union { double f; int64_t i; uint64_t u; } di_type; -typedef union { float f; int32_t i; uint32_t u; } fi_type; - -const uint8_t count_leading_zeros8[256] = { - 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/** - * \brief Shifts 'a' right by the number of bits given in 'dist', which must be in - * the range 1 to 63. If any nonzero bits are shifted off, they are "jammed" - * into the least-significant bit of the shifted value by setting the - * least-significant bit to 1. This shifted-and-jammed value is returned. - * - * From softfloat_shortShiftRightJam64 () - */ -static inline uint64_t -cogl_short_shift_right_jam64 (uint64_t a, - uint8_t dist) -{ - return a >> dist | ((a & (((uint64_t) 1 << dist) - 1)) != 0); -} - -/** - * \brief Shifts 'a' right by the number of bits given in 'dist', which must not - * be zero. If any nonzero bits are shifted off, they are "jammed" into the - * least-significant bit of the shifted value by setting the least-significant - * bit to 1. This shifted-and-jammed value is returned. - * The value of 'dist' can be arbitrarily large. In particular, if 'dist' is - * greater than 64, the result will be either 0 or 1, depending on whether 'a' - * is zero or nonzero. - * - * From softfloat_shiftRightJam64 () - */ -static inline uint64_t -cogl_shift_right_jam64 (uint64_t a, - uint32_t dist) -{ - return - (dist < 63) ? a >> dist | ((uint64_t) (a << (-dist & 63)) != 0) : (a != 0); -} - -/** - * \brief Shifts 'a' right by the number of bits given in 'dist', which must not be - * zero. If any nonzero bits are shifted off, they are "jammed" into the - * least-significant bit of the shifted value by setting the least-significant - * bit to 1. This shifted-and-jammed value is returned. - * The value of 'dist' can be arbitrarily large. In particular, if 'dist' is - * greater than 32, the result will be either 0 or 1, depending on whether 'a' - * is zero or nonzero. - * - * From softfloat_shiftRightJam32 () - */ -static inline uint32_t -cogl_shift_right_jam32 (uint32_t a, - uint16_t dist) -{ - return - (dist < 31) ? a >> dist | ((uint32_t) (a << (-dist & 31)) != 0) : (a != 0); -} - -/** - * \brief Extracted from softfloat_roundPackToF64 () - */ -static inline double -cogl_roundtozero_f64 (int64_t s, - int64_t e, - int64_t m) -{ - di_type result; - - if ((uint64_t) e >= 0x7fd) - { - if (e < 0) - { - m = cogl_shift_right_jam64 (m, -e); - e = 0; - } - else if ((e > 0x7fd) || (0x8000000000000000 <= m)) - { - e = 0x7ff; - m = 0; - result.u = (s << 63) + (e << 52) + m; - result.u -= 1; - return result.f; - } - } - - m >>= 10; - if (m == 0) - e = 0; - - result.u = (s << 63) + (e << 52) + m; - return result.f; -} - -/** - * \brief Extracted from softfloat_roundPackToF32 () - */ -static inline float -cogl_round_f32 (int32_t s, - int32_t e, - int32_t m, - gboolean rtz) -{ - fi_type result; - uint8_t round_increment = rtz ? 0 : 0x40; - - if ((uint32_t) e >= 0xfd) - { - if (e < 0) - { - m = cogl_shift_right_jam32 (m, -e); - e = 0; - } - else if ((e > 0xfd) || (0x80000000 <= m + round_increment)) - { - e = 0xff; - m = 0; - result.u = (s << 31) + (e << 23) + m; - result.u -= !round_increment; - return result.f; - } - } - - uint8_t round_bits; - round_bits = m & 0x7f; - m = ((uint32_t) m + round_increment) >> 7; - m &= ~(uint32_t) (!(round_bits ^ 0x40) & !rtz); - if (m == 0) - e = 0; - - result.u = (s << 31) + (e << 23) + m; - return result.f; -} - -/** - * \brief Extracted from softfloat_roundPackToF16 () - */ -static inline uint16_t -cogl_roundtozero_f16 (int16_t s, - int16_t e, - int16_t m) -{ - if ((uint16_t) e >= 0x1d) - { - if (e < 0) - { - m = cogl_shift_right_jam32 (m, -e); - e = 0; - } - else if (e > 0x1d) - { - e = 0x1f; - m = 0; - return (s << 15) + (e << 10) + m - 1; - } - } - - m >>= 4; - if (m == 0) - e = 0; - - return (s << 15) + (e << 10) + m; -} - -/** - * \brief Shifts the N-bit unsigned integer pointed to by 'a' left by the number of - * bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' - * must be in the range 1 to 31. Any nonzero bits shifted off are lost. The - * shifted N-bit result is stored at the location pointed to by 'm_out'. Each - * of 'a' and 'm_out' points to a 'size_words'-long array of 32-bit elements - * that concatenate in the platform's normal endian order to form an N-bit - * integer. - * - * From softfloat_shortShiftLeftM() - */ -static inline void -cogl_short_shift_left_m (uint8_t size_words, - const uint32_t *a, - uint8_t dist, - uint32_t *m_out) -{ - uint8_t neg_dist; - unsigned index, last_index; - uint32_t part_word, a_word; - - neg_dist = -dist; - index = index_word_hi (size_words); - last_index = index_word_lo (size_words); - part_word = a[index] << dist; - while (index != last_index) - { - a_word = a[index - word_incr]; - m_out[index] = part_word | a_word >> (neg_dist & 31); - index -= word_incr; - part_word = a_word << dist; - } - m_out[index] = part_word; -} - -/** - * \brief Shifts the N-bit unsigned integer pointed to by 'a' left by the number of - * bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' - * must not be zero. Any nonzero bits shifted off are lost. The shifted - * N-bit result is stored at the location pointed to by 'm_out'. Each of 'a' - * and 'm_out' points to a 'size_words'-long array of 32-bit elements that - * concatenate in the platform's normal endian order to form an N-bit - * integer. The value of 'dist' can be arbitrarily large. In particular, if - * 'dist' is greater than N, the stored result will be 0. - * - * From softfloat_shiftLeftM() - */ -static inline void -cogl_shift_left_m (uint8_t size_words, - const uint32_t *a, - uint32_t dist, - uint32_t *m_out) -{ - uint32_t word_dist; - uint8_t inner_dist; - uint8_t i; - - word_dist = dist >> 5; - if (word_dist < size_words) - { - a += index_multiword_lo_but (size_words, word_dist); - inner_dist = dist & 31; - if (inner_dist) - { - cogl_short_shift_left_m (size_words - word_dist, a, inner_dist, - m_out + index_multiword_hi_but (size_words, word_dist)); - if (!word_dist) - return; - } - else - { - uint32_t *dest = m_out + index_word_hi (size_words); - a += index_word_hi (size_words - word_dist); - for (i = size_words - word_dist; i; --i) - { - *dest = *a; - a -= word_incr; - dest -= word_incr; - } - } - m_out += index_multiword_lo (size_words, word_dist); - } - else - { - word_dist = size_words; - } - do - { - *m_out++ = 0; - --word_dist; - } while (word_dist); -} - -/** - * \brief Shifts the N-bit unsigned integer pointed to by 'a' right by the number of - * bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' - * must be in the range 1 to 31. Any nonzero bits shifted off are lost. The - * shifted N-bit result is stored at the location pointed to by 'm_out'. Each - * of 'a' and 'm_out' points to a 'size_words'-long array of 32-bit elements - * that concatenate in the platform's normal endian order to form an N-bit - * integer. - * - * From softfloat_shortShiftRightM() - */ -static inline void -cogl_short_shift_right_m (uint8_t size_words, - const uint32_t *a, - uint8_t dist, - uint32_t *m_out) -{ - uint8_t neg_dist; - unsigned index, last_index; - uint32_t part_word, a_word; - - neg_dist = -dist; - index = index_word_lo (size_words); - last_index = index_word_hi (size_words); - part_word = a[index] >> dist; - while (index != last_index) - { - a_word = a[index + word_incr]; - m_out[index] = a_word << (neg_dist & 31) | part_word; - index += word_incr; - part_word = a_word >> dist; - } - m_out[index] = part_word; -} - -/** - * \brief Shifts the N-bit unsigned integer pointed to by 'a' right by the number of - * bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' - * must be in the range 1 to 31. If any nonzero bits are shifted off, they - * are "jammed" into the least-significant bit of the shifted value by setting - * the least-significant bit to 1. This shifted-and-jammed N-bit result is - * stored at the location pointed to by 'm_out'. Each of 'a' and 'm_out' - * points to a 'size_words'-long array of 32-bit elements that concatenate in - * the platform's normal endian order to form an N-bit integer. - * - * - * From softfloat_shortShiftRightJamM() - */ -static inline void -cogl_short_shift_right_jam_m (uint8_t size_words, - const uint32_t *a, - uint8_t dist, - uint32_t *m_out) -{ - uint8_t neg_dist; - unsigned index, last_index; - uint64_t part_word, a_word; - - neg_dist = -dist; - index = index_word_lo (size_words); - last_index = index_word_hi (size_words); - a_word = a[index]; - part_word = a_word >> dist; - if (part_word << dist != a_word ) - part_word |= 1; - while (index != last_index) - { - a_word = a[index + word_incr]; - m_out[index] = a_word << (neg_dist & 31) | part_word; - index += word_incr; - part_word = a_word >> dist; - } - m_out[index] = part_word; -} - -/** - * \brief Shifts the N-bit unsigned integer pointed to by 'a' right by the number of - * bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' - * must not be zero. If any nonzero bits are shifted off, they are "jammed" - * into the least-significant bit of the shifted value by setting the - * least-significant bit to 1. This shifted-and-jammed N-bit result is stored - * at the location pointed to by 'm_out'. Each of 'a' and 'm_out' points to a - * 'size_words'-long array of 32-bit elements that concatenate in the - * platform's normal endian order to form an N-bit integer. The value of - * 'dist' can be arbitrarily large. In particular, if 'dist' is greater than - * N, the stored result will be either 0 or 1, depending on whether the - * original N bits are all zeros. - * - * From softfloat_shiftRightJamM() - */ -static inline void -cogl_shift_right_jam_m (uint8_t size_words, - const uint32_t *a, - uint32_t dist, - uint32_t *m_out) -{ - uint32_t word_jam, word_dist, *tmp; - uint8_t i, inner_dist; - - word_jam = 0; - word_dist = dist >> 5; - tmp = NULL; - if (word_dist) - { - if (size_words < word_dist) - word_dist = size_words; - tmp = (uint32_t *) (a + index_multiword_lo (size_words, word_dist)); - i = word_dist; - do - { - word_jam = *tmp++; - if (word_jam) - break; - --i; - } while (i); - tmp = m_out; - } - if (word_dist < size_words) - { - a += index_multiword_hi_but (size_words, word_dist); - inner_dist = dist & 31; - if (inner_dist) - { - cogl_short_shift_right_jam_m (size_words - word_dist, a, inner_dist, - m_out + index_multiword_lo_but (size_words, word_dist)); - if (!word_dist) - { - if (word_jam) - m_out[index_word_lo (size_words)] |= 1; - return; - } - } - else - { - a += index_word_lo (size_words - word_dist); - tmp = m_out + index_word_lo (size_words); - for (i = size_words - word_dist; i; --i) - { - *tmp = *a; - a += word_incr; - tmp += word_incr; - } - } - tmp = m_out + index_multiword_hi (size_words, word_dist); - } - if (tmp) - { - do - { - *tmp++ = 0; - --word_dist; - } while (word_dist); - } - if (word_jam) - m_out[index_word_lo (size_words)] |= 1; -} - -/** - * \brief Calculate a + b but rounding to zero. - * - * Notice that this mainly differs from the original Berkeley SoftFloat 3e - * implementation in that we don't really treat NaNs, Zeroes nor the - * signalling flags. Any NaN is good for us and the sign of the Zero is not - * important. - * - * From f64_add () - */ -double -cogl_double_add_rtz (double a, - double b) -{ - const di_type a_di = {a}; - uint64_t a_flt_m = a_di.u & 0x0fffffffffffff; - uint64_t a_flt_e = (a_di.u >> 52) & 0x7ff; - uint64_t a_flt_s = (a_di.u >> 63) & 0x1; - const di_type b_di = {b}; - uint64_t b_flt_m = b_di.u & 0x0fffffffffffff; - uint64_t b_flt_e = (b_di.u >> 52) & 0x7ff; - uint64_t b_flt_s = (b_di.u >> 63) & 0x1; - int64_t s, e, m = 0; - - s = a_flt_s; - - const int64_t exp_diff = a_flt_e - b_flt_e; - - /* Handle special cases */ - - if (a_flt_s != b_flt_s) - { - return cogl_double_sub_rtz (a, -b); - } - else if ((a_flt_e == 0) && (a_flt_m == 0)) - { - /* 'a' is zero, return 'b' */ - return b; - } - else if ((b_flt_e == 0) && (b_flt_m == 0)) - { - /* 'b' is zero, return 'a' */ - return a; - } - else if (a_flt_e == 0x7ff && a_flt_m != 0) - { - /* 'a' is a NaN, return NaN */ - return a; - } - else if (b_flt_e == 0x7ff && b_flt_m != 0) - { - /* 'b' is a NaN, return NaN */ - return b; - } - else if (a_flt_e == 0x7ff && a_flt_m == 0) - { - /* Inf + x = Inf */ - return a; - } - else if (b_flt_e == 0x7ff && b_flt_m == 0) - { - /* x + Inf = Inf */ - return b; - } - else if (exp_diff == 0 && a_flt_e == 0) - { - di_type result_di; - result_di.u = a_di.u + b_flt_m; - return result_di.f; - } - else if (exp_diff == 0) - { - e = a_flt_e; - m = 0x0020000000000000 + a_flt_m + b_flt_m; - m <<= 9; - } - else if (exp_diff < 0) - { - a_flt_m <<= 9; - b_flt_m <<= 9; - e = b_flt_e; - - if (a_flt_e != 0) - a_flt_m += 0x2000000000000000; - else - a_flt_m <<= 1; - - a_flt_m = cogl_shift_right_jam64 (a_flt_m, -exp_diff); - m = 0x2000000000000000 + a_flt_m + b_flt_m; - if (m < 0x4000000000000000) - { - --e; - m <<= 1; - } - } - else - { - a_flt_m <<= 9; - b_flt_m <<= 9; - e = a_flt_e; - - if (b_flt_e != 0) - b_flt_m += 0x2000000000000000; - else - b_flt_m <<= 1; - - b_flt_m = cogl_shift_right_jam64 (b_flt_m, exp_diff); - m = 0x2000000000000000 + a_flt_m + b_flt_m; - if (m < 0x4000000000000000) - { - --e; - m <<= 1; - } - } - - return cogl_roundtozero_f64 (s, e, m); -} - -/** - * \brief Returns the number of leading 0 bits before the most-significant 1 bit of - * 'a'. If 'a' is zero, 64 is returned. - */ -static inline unsigned -cogl_count_leading_zeros64 (uint64_t a) -{ - return __builtin_clzll (a); -} - -/** - * \brief Returns the number of leading 0 bits before the most-significant 1 bit of - * 'a'. If 'a' is zero, 32 is returned. - */ -static inline unsigned -cogl_count_leading_zeros32 (uint32_t a) -{ - return __builtin_clz (a); -} - -static inline double -cogl_norm_round_pack_f64 (int64_t s, - int64_t e, - int64_t m) -{ - int8_t shift_dist; - - shift_dist = cogl_count_leading_zeros64 (m) - 1; - e -= shift_dist; - if ((10 <= shift_dist) && ((unsigned) e < 0x7fd)) - { - di_type result; - result.u = (s << 63) + ((m ? e : 0) << 52) + (m << (shift_dist - 10)); - return result.f; - } - else - { - return cogl_roundtozero_f64 (s, e, m << shift_dist); - } -} - -/** - * \brief Replaces the N-bit unsigned integer pointed to by 'm_out' by the - * 2s-complement of itself, where N = 'size_words' * 32. Argument 'm_out' - * points to a 'size_words'-long array of 32-bit elements that concatenate in - * the platform's normal endian order to form an N-bit integer. - * - * From softfloat_negXM() - */ -static inline void -cogl_neg_x_m (uint8_t size_words, - uint32_t *m_out) -{ - unsigned index, last_index; - uint8_t carry; - uint32_t word; - - index = index_word_lo (size_words); - last_index = index_word_hi (size_words); - carry = 1; - for (;;) - { - word = ~m_out[index] + carry; - m_out[index] = word; - if (index == last_index) - break; - index += word_incr; - if (word) - carry = 0; - } -} - -/** - * \brief Adds the two N-bit integers pointed to by 'a' and 'b', where N = - * 'size_words' * 32. The addition is modulo 2^N, so any carry out is - * lost. The N-bit sum is stored at the location pointed to by 'm_out'. Each - * of 'a', 'b', and 'm_out' points to a 'size_words'-long array of 32-bit - * elements that concatenate in the platform's normal endian order to form an - * N-bit integer. - * - * From softfloat_addM() - */ -static inline void -cogl_add_m (uint8_t size_words, - const uint32_t *a, - const uint32_t *b, - uint32_t *m_out) -{ - unsigned index, last_index; - uint8_t carry; - uint32_t a_word, word; - - index = index_word_lo (size_words); - last_index = index_word_hi (size_words); - carry = 0; - for (;;) - { - a_word = a[index]; - word = a_word + b[index] + carry; - m_out[index] = word; - if (index == last_index) - break; - if (word != a_word) - carry = (word < a_word); - index += word_incr; - } -} - -/** - * \brief Subtracts the two N-bit integers pointed to by 'a' and 'b', where N = - * 'size_words' * 32. The subtraction is modulo 2^N, so any borrow out (carry - * out) is lost. The N-bit difference is stored at the location pointed to by - * 'm_out'. Each of 'a', 'b', and 'm_out' points to a 'size_words'-long array - * of 32-bit elements that concatenate in the platform's normal endian order - * to form an N-bit integer. - * - * From softfloat_subM() - */ -static inline void -cogl_sub_m (uint8_t size_words, - const uint32_t *a, - const uint32_t *b, - uint32_t *m_out) -{ - unsigned index, last_index; - uint8_t borrow; - uint32_t a_word, b_word; - - index = index_word_lo (size_words); - last_index = index_word_hi (size_words); - borrow = 0; - for (;;) - { - a_word = a[index]; - b_word = b[index]; - m_out[index] = a_word - b_word - borrow; - if (index == last_index) - break; - borrow = borrow ? (a_word <= b_word) : (a_word < b_word); - index += word_incr; - } -} - -/* Calculate a - b but rounding to zero. - * - * Notice that this mainly differs from the original Berkeley SoftFloat 3e - * implementation in that we don't really treat NaNs, Zeroes nor the - * signalling flags. Any NaN is good for us and the sign of the Zero is not - * important. - * - * From f64_sub () - */ -double -cogl_double_sub_rtz (double a, - double b) -{ - const di_type a_di = {a}; - uint64_t a_flt_m = a_di.u & 0x0fffffffffffff; - uint64_t a_flt_e = (a_di.u >> 52) & 0x7ff; - uint64_t a_flt_s = (a_di.u >> 63) & 0x1; - const di_type b_di = {b}; - uint64_t b_flt_m = b_di.u & 0x0fffffffffffff; - uint64_t b_flt_e = (b_di.u >> 52) & 0x7ff; - uint64_t b_flt_s = (b_di.u >> 63) & 0x1; - int64_t s, e, m = 0; - int64_t m_diff = 0; - unsigned shift_dist = 0; - - s = a_flt_s; - - const int64_t exp_diff = a_flt_e - b_flt_e; - - /* Handle special cases */ - - if (a_flt_s != b_flt_s) - { - return cogl_double_add_rtz (a, -b); - } - else if ((a_flt_e == 0) && (a_flt_m == 0)) - { - /* 'a' is zero, return '-b' */ - return -b; - } - else if ((b_flt_e == 0) && (b_flt_m == 0)) - { - /* 'b' is zero, return 'a' */ - return a; - } - else if (a_flt_e == 0x7ff && a_flt_m != 0) - { - /* 'a' is a NaN, return NaN */ - return a; - } - else if (b_flt_e == 0x7ff && b_flt_m != 0) - { - /* 'b' is a NaN, return NaN */ - return b; - } - else if (a_flt_e == 0x7ff && a_flt_m == 0) - { - if (b_flt_e == 0x7ff && b_flt_m == 0) - { - /* Inf - Inf = NaN */ - di_type result; - e = 0x7ff; - result.u = (s << 63) + (e << 52) + 0x1; - return result.f; - } - /* Inf - x = Inf */ - return a; - } - else if (b_flt_e == 0x7ff && b_flt_m == 0) - { - /* x - Inf = -Inf */ - return -b; - } - else if (exp_diff == 0) - { - m_diff = a_flt_m - b_flt_m; - - if (m_diff == 0) - return 0; - if (a_flt_e) - --a_flt_e; - if (m_diff < 0) - { - s = !s; - m_diff = -m_diff; - } - - shift_dist = cogl_count_leading_zeros64 (m_diff) - 11; - e = a_flt_e - shift_dist; - if (e < 0) - { - shift_dist = a_flt_e; - e = 0; - } - - di_type result; - result.u = (s << 63) + (e << 52) + (m_diff << shift_dist); - return result.f; - } - else if (exp_diff < 0) - { - a_flt_m <<= 10; - b_flt_m <<= 10; - s = !s; - - a_flt_m += (a_flt_e) ? 0x4000000000000000 : a_flt_m; - a_flt_m = cogl_shift_right_jam64 (a_flt_m, -exp_diff); - b_flt_m |= 0x4000000000000000; - e = b_flt_e; - m = b_flt_m - a_flt_m; - } - else - { - a_flt_m <<= 10; - b_flt_m <<= 10; - - b_flt_m += (b_flt_e) ? 0x4000000000000000 : b_flt_m; - b_flt_m = cogl_shift_right_jam64 (b_flt_m, exp_diff); - a_flt_m |= 0x4000000000000000; - e = a_flt_e; - m = a_flt_m - b_flt_m; - } - - return cogl_norm_round_pack_f64 (s, e - 1, m); -} - -static inline void -cogl_norm_subnormal_mantissa_f64 (uint64_t m, - uint64_t *exp, - uint64_t *m_out) -{ - int shift_dist; - - shift_dist = cogl_count_leading_zeros64 (m) - 11; - *exp = 1 - shift_dist; - *m_out = m << shift_dist; -} - -static inline void -cogl_norm_subnormal_mantissa_f32 (uint32_t m, - uint32_t *exp, - uint32_t *m_out) -{ - int shift_dist; - - shift_dist = cogl_count_leading_zeros32 (m) - 8; - *exp = 1 - shift_dist; - *m_out = m << shift_dist; -} - -/** - * \brief Multiplies 'a' and 'b' and stores the 128-bit product at the location - * pointed to by 'zPtr'. Argument 'zPtr' points to an array of four 32-bit - * elements that concatenate in the platform's normal endian order to form a - * 128-bit integer. - * - * From softfloat_mul64To128M() - */ -static inline void -cogl_softfloat_mul_f64_to_f128_m (uint64_t a, - uint64_t b, - uint32_t *m_out) -{ - uint32_t a32, a0, b32, b0; - uint64_t z0, mid1, z64, mid; - - a32 = a >> 32; - a0 = a; - b32 = b >> 32; - b0 = b; - z0 = (uint64_t) a0 * b0; - mid1 = (uint64_t) a32 * b0; - mid = mid1 + (uint64_t) a0 * b32; - z64 = (uint64_t) a32 * b32; - z64 += (uint64_t) (mid < mid1) << 32 | mid >> 32; - mid <<= 32; - z0 += mid; - m_out[index_word (4, 1)] = z0 >> 32; - m_out[index_word (4, 0)] = z0; - z64 += (z0 < mid); - m_out[index_word (4, 3)] = z64 >> 32; - m_out[index_word (4, 2)] = z64; -} - -/* Calculate a * b but rounding to zero. - * - * Notice that this mainly differs from the original Berkeley SoftFloat 3e - * implementation in that we don't really treat NaNs, Zeroes nor the - * signalling flags. Any NaN is good for us and the sign of the Zero is not - * important. - * - * From f64_mul () - */ -double -cogl_double_mul_rtz (double a, - double b) -{ - const di_type a_di = {a}; - uint64_t a_flt_m = a_di.u & 0x0fffffffffffff; - uint64_t a_flt_e = (a_di.u >> 52) & 0x7ff; - uint64_t a_flt_s = (a_di.u >> 63) & 0x1; - const di_type b_di = {b}; - uint64_t b_flt_m = b_di.u & 0x0fffffffffffff; - uint64_t b_flt_e = (b_di.u >> 52) & 0x7ff; - uint64_t b_flt_s = (b_di.u >> 63) & 0x1; - int64_t s, e, m = 0; - - s = a_flt_s ^ b_flt_s; - - if (a_flt_e == 0x7ff) - { - if (a_flt_m != 0) - { - /* 'a' is a NaN, return NaN */ - return a; - } - else if (b_flt_e == 0x7ff && b_flt_m != 0) - { - /* 'b' is a NaN, return NaN */ - return b; - } - - if (!(b_flt_e | b_flt_m)) - { - /* Inf * 0 = NaN */ - di_type result; - e = 0x7ff; - result.u = (s << 63) + (e << 52) + 0x1; - return result.f; - } - /* Inf * x = Inf */ - di_type result; - e = 0x7ff; - result.u = (s << 63) + (e << 52) + 0; - return result.f; - } - - if (b_flt_e == 0x7ff) - { - if (b_flt_m != 0) - { - /* 'b' is a NaN, return NaN */ - return b; - } - if (!(a_flt_e | a_flt_m)) - { - /* 0 * Inf = NaN */ - di_type result; - e = 0x7ff; - result.u = (s << 63) + (e << 52) + 0x1; - return result.f; - } - /* x * Inf = Inf */ - di_type result; - e = 0x7ff; - result.u = (s << 63) + (e << 52) + 0; - return result.f; - } - - if (a_flt_e == 0) - { - if (a_flt_m == 0) - { - /* 'a' is zero. Return zero */ - di_type result; - result.u = (s << 63) + 0; - return result.f; - } - cogl_norm_subnormal_mantissa_f64 (a_flt_m , &a_flt_e, &a_flt_m); - } - if (b_flt_e == 0) - { - if (b_flt_m == 0) - { - /* 'b' is zero. Return zero */ - di_type result; - result.u = (s << 63) + 0; - return result.f; - } - cogl_norm_subnormal_mantissa_f64 (b_flt_m , &b_flt_e, &b_flt_m); - } - - e = a_flt_e + b_flt_e - 0x3ff; - a_flt_m = (a_flt_m | 0x0010000000000000) << 10; - b_flt_m = (b_flt_m | 0x0010000000000000) << 11; - - uint32_t m_128[4]; - cogl_softfloat_mul_f64_to_f128_m (a_flt_m, b_flt_m, m_128); - - m = (uint64_t) m_128[index_word (4, 3)] << 32 | m_128[index_word (4, 2)]; - if (m_128[index_word (4, 1)] || m_128[index_word (4, 0)]) - m |= 1; - - if (m < 0x4000000000000000) - { - --e; - m <<= 1; - } - - return cogl_roundtozero_f64 (s, e, m); -} - - -/** - * \brief Calculate a * b + c but rounding to zero. - * - * Notice that this mainly differs from the original Berkeley SoftFloat 3e - * implementation in that we don't really treat NaNs, Zeroes nor the - * signalling flags. Any NaN is good for us and the sign of the Zero is not - * important. - * - * From f64_mulAdd () - */ -double -cogl_double_fma_rtz (double a, - double b, - double c) -{ - const di_type a_di = {a}; - uint64_t a_flt_m = a_di.u & 0x0fffffffffffff; - uint64_t a_flt_e = (a_di.u >> 52) & 0x7ff; - uint64_t a_flt_s = (a_di.u >> 63) & 0x1; - const di_type b_di = {b}; - uint64_t b_flt_m = b_di.u & 0x0fffffffffffff; - uint64_t b_flt_e = (b_di.u >> 52) & 0x7ff; - uint64_t b_flt_s = (b_di.u >> 63) & 0x1; - const di_type c_di = {c}; - uint64_t c_flt_m = c_di.u & 0x0fffffffffffff; - uint64_t c_flt_e = (c_di.u >> 52) & 0x7ff; - uint64_t c_flt_s = (c_di.u >> 63) & 0x1; - int64_t s, e, m = 0; - - c_flt_s ^= 0; - s = a_flt_s ^ b_flt_s ^ 0; - - if (a_flt_e == 0x7ff) - { - if (a_flt_m != 0) - { - /* 'a' is a NaN, return NaN */ - return a; - } - else if (b_flt_e == 0x7ff && b_flt_m != 0) - { - /* 'b' is a NaN, return NaN */ - return b; - } - else if (c_flt_e == 0x7ff && c_flt_m != 0) - { - /* 'c' is a NaN, return NaN */ - return c; - } - - if (!(b_flt_e | b_flt_m)) - { - /* Inf * 0 + y = NaN */ - di_type result; - e = 0x7ff; - result.u = (s << 63) + (e << 52) + 0x1; - return result.f; - } - - if ((c_flt_e == 0x7ff && c_flt_m == 0) && (s != c_flt_s)) - { - /* Inf * x - Inf = NaN */ - di_type result; - e = 0x7ff; - result.u = (s << 63) + (e << 52) + 0x1; - return result.f; - } - - /* Inf * x + y = Inf */ - di_type result; - e = 0x7ff; - result.u = (s << 63) + (e << 52) + 0; - return result.f; - } - - if (b_flt_e == 0x7ff) - { - if (b_flt_m != 0) - { - /* 'b' is a NaN, return NaN */ - return b; - } - else if (c_flt_e == 0x7ff && c_flt_m != 0) - { - /* 'c' is a NaN, return NaN */ - return c; - } - - if (!(a_flt_e | a_flt_m)) - { - /* 0 * Inf + y = NaN */ - di_type result; - e = 0x7ff; - result.u = (s << 63) + (e << 52) + 0x1; - return result.f; - } - - if ((c_flt_e == 0x7ff && c_flt_m == 0) && (s != c_flt_s)) - { - /* x * Inf - Inf = NaN */ - di_type result; - e = 0x7ff; - result.u = (s << 63) + (e << 52) + 0x1; - return result.f; - } - - /* x * Inf + y = Inf */ - di_type result; - e = 0x7ff; - result.u = (s << 63) + (e << 52) + 0; - return result.f; - } - - if (c_flt_e == 0x7ff) - { - if (c_flt_m != 0) - { - /* 'c' is a NaN, return NaN */ - return c; - } - - /* x * y + Inf = Inf */ - return c; - } - - if (a_flt_e == 0) - { - if (a_flt_m == 0) - { - /* 'a' is zero, return 'c' */ - return c; - } - cogl_norm_subnormal_mantissa_f64 (a_flt_m , &a_flt_e, &a_flt_m); - } - - if (b_flt_e == 0) - { - if (b_flt_m == 0) - { - /* 'b' is zero, return 'c' */ - return c; - } - cogl_norm_subnormal_mantissa_f64 (b_flt_m , &b_flt_e, &b_flt_m); - } - - e = a_flt_e + b_flt_e - 0x3fe; - a_flt_m = (a_flt_m | 0x0010000000000000) << 10; - b_flt_m = (b_flt_m | 0x0010000000000000) << 11; - - uint32_t m_128[4]; - cogl_softfloat_mul_f64_to_f128_m (a_flt_m, b_flt_m, m_128); - - m = (uint64_t) m_128[index_word (4, 3)] << 32 | m_128[index_word (4, 2)]; - - int64_t shift_dist = 0; - if (!(m & 0x4000000000000000)) - { - --e; - shift_dist = -1; - } - - if (c_flt_e == 0) - { - if (c_flt_m == 0) - { - /* 'c' is zero, return 'a * b' */ - if (shift_dist) - m <<= 1; - - if (m_128[index_word (4, 1)] || m_128[index_word (4, 0)]) - m |= 1; - return cogl_roundtozero_f64 (s, e - 1, m); - } - cogl_norm_subnormal_mantissa_f64 (c_flt_m , &c_flt_e, &c_flt_m); - } - c_flt_m = (c_flt_m | 0x0010000000000000) << 10; - - uint32_t c_flt_m_128[4]; - int64_t exp_diff = e - c_flt_e; - if (exp_diff < 0) - { - e = c_flt_e; - if ((s == c_flt_s) || (exp_diff < -1)) - { - shift_dist -= exp_diff; - if (shift_dist) - { - m = cogl_shift_right_jam64 (m, shift_dist); - } - } - else - { - if (!shift_dist) - { - cogl_short_shift_right_m (4, m_128, 1, m_128); - } - } - } - else - { - if (shift_dist) - cogl_add_m (4, m_128, m_128, m_128); - if (!exp_diff) - { - m = (uint64_t) m_128[index_word (4, 3)] << 32 - | m_128[index_word (4, 2)]; - } - else - { - c_flt_m_128[index_word (4, 3)] = c_flt_m >> 32; - c_flt_m_128[index_word (4, 2)] = c_flt_m; - c_flt_m_128[index_word (4, 1)] = 0; - c_flt_m_128[index_word (4, 0)] = 0; - cogl_shift_right_jam_m (4, c_flt_m_128, exp_diff, c_flt_m_128); - } - } - - if (s == c_flt_s) - { - if (exp_diff <= 0) - { - m += c_flt_m; - } - else - { - cogl_add_m (4, m_128, c_flt_m_128, m_128); - m = (uint64_t) m_128[index_word (4, 3)] << 32 - | m_128[index_word (4, 2)]; - } - if (m & 0x8000000000000000) - { - e++; - m = cogl_short_shift_right_jam64 (m, 1); - } - } - else - { - if (exp_diff < 0) - { - s = c_flt_s; - if (exp_diff < -1) - { - m = c_flt_m - m; - if (m_128[index_word (4, 1)] || m_128[index_word (4, 0)]) - { - m = (m - 1) | 1; - } - if (!(m & 0x4000000000000000)) - { - --e; - m <<= 1; - } - return cogl_roundtozero_f64 (s, e - 1, m); - } - else - { - c_flt_m_128[index_word (4, 3)] = c_flt_m >> 32; - c_flt_m_128[index_word (4, 2)] = c_flt_m; - c_flt_m_128[index_word (4, 1)] = 0; - c_flt_m_128[index_word (4, 0)] = 0; - cogl_sub_m (4, c_flt_m_128, m_128, m_128); - } - } - else if (!exp_diff) - { - m -= c_flt_m; - if (!m && !m_128[index_word (4, 1)] && !m_128[index_word (4, 0)]) - { - /* Return zero */ - di_type result; - result.u = (s << 63) + 0; - return result.f; - } - m_128[index_word (4, 3)] = m >> 32; - m_128[index_word (4, 2)] = m; - if (m & 0x8000000000000000) - { - s = !s; - cogl_neg_x_m (4, m_128); - } - } - else - { - cogl_sub_m (4, m_128, c_flt_m_128, m_128); - if (1 < exp_diff) - { - m = (uint64_t) m_128[index_word (4, 3)] << 32 - | m_128[index_word (4, 2)]; - if (!(m & 0x4000000000000000)) - { - --e; - m <<= 1; - } - if (m_128[index_word (4, 1)] || m_128[index_word (4, 0)]) - m |= 1; - return cogl_roundtozero_f64 (s, e - 1, m); - } - } - - shift_dist = 0; - m = (uint64_t) m_128[index_word (4, 3)] << 32 - | m_128[index_word (4, 2)]; - if (!m) - { - shift_dist = 64; - m = (uint64_t) m_128[index_word (4, 1)] << 32 - | m_128[index_word (4, 0)]; - } - shift_dist += cogl_count_leading_zeros64 (m) - 1; - if (shift_dist) - { - e -= shift_dist; - cogl_shift_left_m (4, m_128, shift_dist, m_128); - m = (uint64_t) m_128[index_word (4, 3)] << 32 - | m_128[index_word (4, 2)]; - } - } - - if (m_128[index_word (4, 1)] || m_128[index_word (4, 0)]) - m |= 1; - return cogl_roundtozero_f64 (s, e - 1, m); -} - - -/** - * \brief Calculate a * b + c but rounding to zero. - * - * Notice that this mainly differs from the original Berkeley SoftFloat 3e - * implementation in that we don't really treat NaNs, Zeroes nor the - * signalling flags. Any NaN is good for us and the sign of the Zero is not - * important. - * - * From f32_mulAdd () - */ -float -cogl_float_fma_rtz (float a, - float b, - float c) -{ - const fi_type a_fi = {a}; - uint32_t a_flt_m = a_fi.u & 0x07fffff; - uint32_t a_flt_e = (a_fi.u >> 23) & 0xff; - uint32_t a_flt_s = (a_fi.u >> 31) & 0x1; - const fi_type b_fi = {b}; - uint32_t b_flt_m = b_fi.u & 0x07fffff; - uint32_t b_flt_e = (b_fi.u >> 23) & 0xff; - uint32_t b_flt_s = (b_fi.u >> 31) & 0x1; - const fi_type c_fi = {c}; - uint32_t c_flt_m = c_fi.u & 0x07fffff; - uint32_t c_flt_e = (c_fi.u >> 23) & 0xff; - uint32_t c_flt_s = (c_fi.u >> 31) & 0x1; - int32_t s, e, m = 0; - - c_flt_s ^= 0; - s = a_flt_s ^ b_flt_s ^ 0; - - if (a_flt_e == 0xff) - { - if (a_flt_m != 0) - { - /* 'a' is a NaN, return NaN */ - return a; - } - else if (b_flt_e == 0xff && b_flt_m != 0) - { - /* 'b' is a NaN, return NaN */ - return b; - } - else if (c_flt_e == 0xff && c_flt_m != 0) - { - /* 'c' is a NaN, return NaN */ - return c; - } - - if (!(b_flt_e | b_flt_m)) - { - /* Inf * 0 + y = NaN */ - fi_type result; - e = 0xff; - result.u = (s << 31) + (e << 23) + 0x1; - return result.f; - } - - if ((c_flt_e == 0xff && c_flt_m == 0) && (s != c_flt_s)) - { - /* Inf * x - Inf = NaN */ - fi_type result; - e = 0xff; - result.u = (s << 31) + (e << 23) + 0x1; - return result.f; - } - - /* Inf * x + y = Inf */ - fi_type result; - e = 0xff; - result.u = (s << 31) + (e << 23) + 0; - return result.f; - } - - if (b_flt_e == 0xff) - { - if (b_flt_m != 0) - { - /* 'b' is a NaN, return NaN */ - return b; - } - else if (c_flt_e == 0xff && c_flt_m != 0) - { - /* 'c' is a NaN, return NaN */ - return c; - } - - if (!(a_flt_e | a_flt_m)) - { - /* 0 * Inf + y = NaN */ - fi_type result; - e = 0xff; - result.u = (s << 31) + (e << 23) + 0x1; - return result.f; - } - - if ((c_flt_e == 0xff && c_flt_m == 0) && (s != c_flt_s)) - { - /* x * Inf - Inf = NaN */ - fi_type result; - e = 0xff; - result.u = (s << 31) + (e << 23) + 0x1; - return result.f; - } - - /* x * Inf + y = Inf */ - fi_type result; - e = 0xff; - result.u = (s << 31) + (e << 23) + 0; - return result.f; - } - - if (c_flt_e == 0xff) - { - if (c_flt_m != 0) - { - /* 'c' is a NaN, return NaN */ - return c; - } - - /* x * y + Inf = Inf */ - return c; - } - - if (a_flt_e == 0) - { - if (a_flt_m == 0) - { - /* 'a' is zero, return 'c' */ - return c; - } - cogl_norm_subnormal_mantissa_f32 (a_flt_m , &a_flt_e, &a_flt_m); - } - - if (b_flt_e == 0) - { - if (b_flt_m == 0) - { - /* 'b' is zero, return 'c' */ - return c; - } - cogl_norm_subnormal_mantissa_f32 (b_flt_m , &b_flt_e, &b_flt_m); - } - - e = a_flt_e + b_flt_e - 0x7e; - a_flt_m = (a_flt_m | 0x00800000) << 7; - b_flt_m = (b_flt_m | 0x00800000) << 7; - - uint64_t m_64 = (uint64_t) a_flt_m * b_flt_m; - if (m_64 < 0x2000000000000000) - { - --e; - m_64 <<= 1; - } - - if (c_flt_e == 0) - { - if (c_flt_m == 0) - { - /* 'c' is zero, return 'a * b' */ - m = cogl_short_shift_right_jam64 (m_64, 31); - return cogl_round_f32 (s, e - 1, m, TRUE); - } - cogl_norm_subnormal_mantissa_f32 (c_flt_m , &c_flt_e, &c_flt_m); - } - c_flt_m = (c_flt_m | 0x00800000) << 6; - - int16_t exp_diff = e - c_flt_e; - if (s == c_flt_s) - { - if (exp_diff <= 0) - { - e = c_flt_e; - m = c_flt_m + cogl_shift_right_jam64 (m_64, 32 - exp_diff); - } - else - { - m_64 += cogl_shift_right_jam64 ((uint64_t) c_flt_m << 32, exp_diff); - m = cogl_short_shift_right_jam64 (m_64, 32); - } - if (m < 0x40000000) - { - --e; - m <<= 1; - } - } - else - { - uint64_t c_flt_m_64 = (uint64_t) c_flt_m << 32; - if (exp_diff < 0) - { - s = c_flt_s; - e = c_flt_e; - m_64 = c_flt_m_64 - cogl_shift_right_jam64 (m_64, -exp_diff); - } - else if (!exp_diff) - { - m_64 -= c_flt_m_64; - if (!m_64) - { - /* Return zero */ - fi_type result; - result.u = (s << 31) + 0; - return result.f; - } - if (m_64 & 0x8000000000000000) - { - s = !s; - m_64 = -m_64; - } - } - else - { - m_64 -= cogl_shift_right_jam64 (c_flt_m_64, exp_diff); - } - int8_t shift_dist = cogl_count_leading_zeros64 (m_64) - 1; - e -= shift_dist; - shift_dist -= 32; - if (shift_dist < 0) - { - m = cogl_short_shift_right_jam64 (m_64, -shift_dist); - } - else - { - m = (uint32_t) m_64 << shift_dist; - } - } - - return cogl_round_f32 (s, e, m, TRUE); -} - - -/** - * \brief Converts from 64bits to 32bits float and rounds according to - * instructed. - * - * From f64_to_f32 () - */ -float -cogl_double_to_f32 (double val, - gboolean rtz) -{ - const di_type di = {val}; - uint64_t flt_m = di.u & 0x0fffffffffffff; - uint64_t flt_e = (di.u >> 52) & 0x7ff; - uint64_t flt_s = (di.u >> 63) & 0x1; - int32_t s, e, m = 0; - - s = flt_s; - - if (flt_e == 0x7ff) - { - if (flt_m != 0) - { - /* 'val' is a NaN, return NaN */ - fi_type result; - e = 0xff; - m = 0x1; - result.u = (s << 31) + (e << 23) + m; - return result.f; - } - - /* 'val' is Inf, return Inf */ - fi_type result; - e = 0xff; - result.u = (s << 31) + (e << 23) + m; - return result.f; - } - - if (!(flt_e | flt_m)) - { - /* 'val' is zero, return zero */ - fi_type result; - e = 0; - result.u = (s << 31) + (e << 23) + m; - return result.f; - } - - m = cogl_short_shift_right_jam64 (flt_m, 22); - if (!(flt_e | m)) - { - /* 'val' is denorm, return zero */ - fi_type result; - e = 0; - result.u = (s << 31) + (e << 23) + m; - return result.f; - } - - return cogl_round_f32 (s, flt_e - 0x381, m | 0x40000000, rtz); -} - - -/** - * \brief Converts from 32bits to 16bits float and rounds the result to zero. - * - * From f32_to_f16 () - */ -uint16_t -cogl_float_to_half_rtz_slow (float val) -{ - const fi_type fi = {val}; - const uint32_t flt_m = fi.u & 0x7fffff; - const uint32_t flt_e = (fi.u >> 23) & 0xff; - const uint32_t flt_s = (fi.u >> 31) & 0x1; - int16_t s, e, m = 0; - - s = flt_s; - - if (flt_e == 0xff) - { - if (flt_m != 0) - { - /* 'val' is a NaN, return NaN */ - e = 0x1f; - /* Retain the top bits of a NaN to make sure that the quiet/signaling - * status stays the same. - */ - m = flt_m >> 13; - if (!m) - m = 1; - return (s << 15) + (e << 10) + m; - } - - /* 'val' is Inf, return Inf */ - e = 0x1f; - return (s << 15) + (e << 10) + m; - } - - if (!(flt_e | flt_m)) - { - /* 'val' is zero, return zero */ - e = 0; - return (s << 15) + (e << 10) + m; - } - - m = flt_m >> 9 | ((flt_m & 0x1ff) != 0); - if (!(flt_e | m)) - { - /* 'val' is denorm, return zero */ - e = 0; - return (s << 15) + (e << 10) + m; - } - - return cogl_roundtozero_f16 (s, flt_e - 0x71, m | 0x4000); -} diff --git a/mutter/cogl/cogl/cogl-soft-float.h b/mutter/cogl/cogl/cogl-soft-float.h deleted file mode 100644 index a222e09..0000000 --- a/mutter/cogl/cogl/cogl-soft-float.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * License for Berkeley SoftFloat Release 3e - * - * John R. Hauser - * 2018 January 20 - * - * The following applies to the whole of SoftFloat Release 3e as well as to - * each source file individually. - * - * Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the - * University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions, and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions, and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The functions listed in this file are modified versions of the ones - * from the Berkeley SoftFloat 3e Library. - */ - -#ifndef COGL_SOFT_FLOAT_H -#define COGL_SOFT_FLOAT_H - -#include -#include - -double cogl_double_add_rtz (double a, - double b); - -double cogl_double_sub_rtz (double a, - double b); - -double cogl_double_mul_rtz (double a, - double b); - -double cogl_double_fma_rtz (double a, - double b, - double c); - -float cogl_float_fma_rtz (float a, - float b, - float c); - -float cogl_double_to_f32 (double x, - gboolean rtz); - -uint16_t cogl_float_to_half_rtz_slow (float x); - -#endif /* COGL_SOFT_FLOAT_H */ diff --git a/mutter/cogl/cogl/cogl-spans.c b/mutter/cogl/cogl/cogl-spans.c deleted file mode 100644 index 4604d1c..0000000 --- a/mutter/cogl/cogl/cogl-spans.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include "math.h" - -#include "cogl/cogl-util.h" -#include "cogl/cogl-spans.h" - -void -_cogl_span_iter_update (CoglSpanIter *iter) -{ - /* Pick current span */ - iter->span = &iter->spans[iter->index]; - - /* Offset next position by span size */ - iter->next_pos = iter->pos + iter->span->size - iter->span->waste; - - /* Check if span intersects the area to cover */ - if (iter->next_pos <= iter->cover_start || - iter->pos >= iter->cover_end) - { - /* Intersection undefined */ - iter->intersects = FALSE; - return; - } - - iter->intersects = TRUE; - - /* Clip start position to coverage area */ - if (iter->pos < iter->cover_start) - iter->intersect_start = iter->cover_start; - else - iter->intersect_start = iter->pos; - - /* Clip end position to coverage area */ - if (iter->next_pos > iter->cover_end) - iter->intersect_end = iter->cover_end; - else - iter->intersect_end = iter->next_pos; -} - -void -_cogl_span_iter_begin (CoglSpanIter *iter, - const CoglSpan *spans, - int n_spans, - float normalize_factor, - float cover_start, - float cover_end, - CoglPipelineWrapMode wrap_mode) -{ - /* XXX: If CLAMP_TO_EDGE needs to be emulated then it needs to be - * done at a higher level than here... */ - g_return_if_fail (wrap_mode == COGL_PIPELINE_WRAP_MODE_REPEAT || - wrap_mode == COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT); - - iter->span = NULL; - - iter->spans = spans; - iter->n_spans = n_spans; - - /* We always iterate in a positive direction from the origin. If - * iter->flipped == TRUE that means whoever is using this API should - * interpreted the current span as extending in the opposite direction. I.e. - * it extends to the left if iterating the X axis, or up if the Y axis. */ - if (cover_start > cover_end) - { - float tmp = cover_start; - cover_start = cover_end; - cover_end = tmp; - iter->flipped = TRUE; - } - else - iter->flipped = FALSE; - - /* The texture spans cover the normalized texture coordinate space ranging - * from [0,1] but to help support repeating of sliced textures we allow - * iteration of any range so we need to relate the start of the range to the - * nearest point equivalent to 0. - */ - if (normalize_factor != 1.0) - { - float cover_start_normalized = cover_start / normalize_factor; - iter->origin = floorf (cover_start_normalized) * normalize_factor; - } - else - iter->origin = floorf (cover_start); - - iter->wrap_mode = wrap_mode; - - if (wrap_mode == COGL_PIPELINE_WRAP_MODE_REPEAT) - iter->index = 0; - else if (wrap_mode == COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT) - { - if ((int)iter->origin % 2) - { - iter->index = iter->n_spans - 1; - iter->mirror_direction = -1; - iter->flipped = !iter->flipped; - } - else - { - iter->index = 0; - iter->mirror_direction = 1; - } - } - else - g_warn_if_reached (); - - iter->cover_start = cover_start; - iter->cover_end = cover_end; - iter->pos = iter->origin; - - /* Update intersection */ - _cogl_span_iter_update (iter); - - while (iter->next_pos <= iter->cover_start) - _cogl_span_iter_next (iter); -} - -void -_cogl_span_iter_next (CoglSpanIter *iter) -{ - /* Move current position */ - iter->pos = iter->next_pos; - - if (iter->wrap_mode == COGL_PIPELINE_WRAP_MODE_REPEAT) - iter->index = (iter->index + 1) % iter->n_spans; - else if (iter->wrap_mode == COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT) - { - iter->index += iter->mirror_direction; - if (iter->index == iter->n_spans || iter->index == -1) - { - iter->mirror_direction = -iter->mirror_direction; - iter->index += iter->mirror_direction; - iter->flipped = !iter->flipped; - } - } - else - g_warn_if_reached (); - - /* Update intersection */ - _cogl_span_iter_update (iter); -} - -gboolean -_cogl_span_iter_end (CoglSpanIter *iter) -{ - /* End reached when whole area covered */ - return iter->pos >= iter->cover_end; -} - - diff --git a/mutter/cogl/cogl/cogl-spans.h b/mutter/cogl/cogl/cogl-spans.h deleted file mode 100644 index f245d0c..0000000 --- a/mutter/cogl/cogl/cogl-spans.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-pipeline-layer-state.h" - -typedef struct _CoglSpan -{ - float start; - float size; - float waste; -} CoglSpan; - -typedef struct _CoglSpanIter -{ - int index; - const CoglSpan *spans; - int n_spans; - const CoglSpan *span; - float pos; - float next_pos; - float origin; - float cover_start; - float cover_end; - float intersect_start; - float intersect_end; - gboolean intersects; - gboolean flipped; - CoglPipelineWrapMode wrap_mode; - int mirror_direction; -} CoglSpanIter; - -void -_cogl_span_iter_update (CoglSpanIter *iter); - -void -_cogl_span_iter_begin (CoglSpanIter *iter, - const CoglSpan *spans, - int n_spans, - float normalize_factor, - float cover_start, - float cover_end, - CoglPipelineWrapMode wrap_mode); - -void -_cogl_span_iter_next (CoglSpanIter *iter); - -gboolean -_cogl_span_iter_end (CoglSpanIter *iter); diff --git a/mutter/cogl/cogl/cogl-sub-texture-private.h b/mutter/cogl/cogl/cogl-sub-texture-private.h deleted file mode 100644 index 45c9002..0000000 --- a/mutter/cogl/cogl/cogl-sub-texture-private.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-texture-private.h" - -#include - -struct _CoglSubTexture -{ - CoglTexture parent_instance; - - /* This is the texture that was passed in to - _cogl_sub_texture_new. If this is also a sub texture then we will - use the full texture from that to render instead of making a - chain. However we want to preserve the next texture in case the - user is expecting us to keep a reference and also so that we can - later add a cogl_sub_texture_get_parent_texture() function. */ - CoglTexture *next_texture; - /* This is the texture that will actually be used to draw. It will - point to the end of the chain if a sub texture of a sub texture - is created */ - CoglTexture *full_texture; - - /* The offset of the region represented by this sub-texture. This is - * the offset in full_texture which won't necessarily be the same as - * the offset passed to _cogl_sub_texture_new if next_texture is - * actually already a sub texture */ - int sub_x; - int sub_y; -}; - -struct _CoglSubTextureClass -{ - CoglTextureClass parent_class; -}; diff --git a/mutter/cogl/cogl/cogl-sub-texture.c b/mutter/cogl/cogl/cogl-sub-texture.c deleted file mode 100644 index f02c8f8..0000000 --- a/mutter/cogl/cogl/cogl-sub-texture.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009,2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#include "config.h" - -#include "cogl/cogl-util.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-sub-texture-private.h" -#include "cogl/cogl-sub-texture.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-texture-driver.h" -#include "cogl/cogl-texture-2d.h" -#include "cogl/driver/gl/cogl-texture-gl-private.h" - -#include -#include - - -G_DEFINE_FINAL_TYPE (CoglSubTexture, cogl_sub_texture, COGL_TYPE_TEXTURE) - -static void -cogl_sub_texture_dispose (GObject *object) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (object); - - g_object_unref (sub_tex->next_texture); - g_object_unref (sub_tex->full_texture); - - G_OBJECT_CLASS (cogl_sub_texture_parent_class)->dispose (object); -} - -static void -_cogl_sub_texture_unmap_quad (CoglSubTexture *sub_tex, - float *coords) -{ - CoglTexture *tex = COGL_TEXTURE (sub_tex); - float width = cogl_texture_get_width (sub_tex->full_texture); - float height = cogl_texture_get_height (sub_tex->full_texture); - - coords[0] = (coords[0] * width - sub_tex->sub_x) / cogl_texture_get_width (tex); - coords[1] = (coords[1] * height - sub_tex->sub_y) / cogl_texture_get_height (tex); - coords[2] = (coords[2] * width - sub_tex->sub_x) / cogl_texture_get_width (tex); - coords[3] = (coords[3] * height - sub_tex->sub_y) / cogl_texture_get_height (tex); -} - -static void -_cogl_sub_texture_map_quad (CoglSubTexture *sub_tex, - float *coords) -{ - CoglTexture *tex = COGL_TEXTURE (sub_tex); - float width = cogl_texture_get_width (sub_tex->full_texture); - float height = cogl_texture_get_height (sub_tex->full_texture); - - coords[0] = (coords[0] * cogl_texture_get_width (tex) + sub_tex->sub_x) / width; - coords[1] = (coords[1] * cogl_texture_get_height (tex) + sub_tex->sub_y) / height; - coords[2] = (coords[2] * cogl_texture_get_width (tex) + sub_tex->sub_x) / width; - coords[3] = (coords[3] * cogl_texture_get_height (tex) + sub_tex->sub_y) / height; -} - -typedef struct _CoglSubTextureForeachData -{ - CoglSubTexture *sub_tex; - CoglMetaTextureCallback callback; - void *user_data; -} CoglSubTextureForeachData; - -static void -unmap_coords_cb (CoglTexture *slice_texture, - const float *slice_texture_coords, - const float *meta_coords, - void *user_data) -{ - CoglSubTextureForeachData *data = user_data; - float unmapped_coords[4]; - - memcpy (unmapped_coords, meta_coords, sizeof (unmapped_coords)); - - _cogl_sub_texture_unmap_quad (data->sub_tex, unmapped_coords); - - data->callback (slice_texture, - slice_texture_coords, - unmapped_coords, - data->user_data); -} - -static void -_cogl_sub_texture_foreach_sub_texture_in_region ( - CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglMetaTextureCallback callback, - void *user_data) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - CoglTexture *full_texture = sub_tex->full_texture; - float mapped_coords[4] = - { virtual_tx_1, virtual_ty_1, virtual_tx_2, virtual_ty_2}; - float virtual_coords[4] = - { virtual_tx_1, virtual_ty_1, virtual_tx_2, virtual_ty_2}; - - /* map the virtual coordinates to ->full_texture coordinates */ - _cogl_sub_texture_map_quad (sub_tex, mapped_coords); - - /* TODO: Add something like cogl_is_low_level_texture() */ - if (COGL_IS_TEXTURE_2D (full_texture)) - { - callback (sub_tex->full_texture, - mapped_coords, - virtual_coords, - user_data); - } - else - { - CoglSubTextureForeachData data; - - data.sub_tex = sub_tex; - data.callback = callback; - data.user_data = user_data; - - cogl_meta_texture_foreach_in_region (full_texture, - mapped_coords[0], - mapped_coords[1], - mapped_coords[2], - mapped_coords[3], - COGL_PIPELINE_WRAP_MODE_REPEAT, - COGL_PIPELINE_WRAP_MODE_REPEAT, - unmap_coords_cb, - &data); - } -} - -static void -_cogl_sub_texture_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - _cogl_texture_gl_flush_legacy_texobj_wrap_modes (sub_tex->full_texture, - wrap_mode_s, - wrap_mode_t); -} - -static gboolean -_cogl_sub_texture_allocate (CoglTexture *tex, - GError **error) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - gboolean status = cogl_texture_allocate (sub_tex->full_texture, error); - - _cogl_texture_set_allocated (tex, - _cogl_texture_get_format (sub_tex->full_texture), - cogl_texture_get_width (tex), - cogl_texture_get_height (tex)); - - return status; -} - -static int -_cogl_sub_texture_get_max_waste (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return cogl_texture_get_max_waste (sub_tex->full_texture); -} - -static gboolean -_cogl_sub_texture_is_sliced (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return cogl_texture_is_sliced (sub_tex->full_texture); -} - -static gboolean -_cogl_sub_texture_can_hardware_repeat (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - /* We can hardware repeat if the subtexture actually represents all of the - of the full texture */ - return (cogl_texture_get_width (tex) == - cogl_texture_get_width (sub_tex->full_texture) && - cogl_texture_get_height (tex) == - cogl_texture_get_height (sub_tex->full_texture) && - _cogl_texture_can_hardware_repeat (sub_tex->full_texture)); -} - -static void -_cogl_sub_texture_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - /* This won't work if the sub texture is not the size of the full - texture and the coordinates are outside the range [0,1] */ - *s = ((*s * cogl_texture_get_width (tex) + sub_tex->sub_x) / - cogl_texture_get_width (sub_tex->full_texture)); - *t = ((*t * cogl_texture_get_height (tex) + sub_tex->sub_y) / - cogl_texture_get_height (sub_tex->full_texture)); - - _cogl_texture_transform_coords_to_gl (sub_tex->full_texture, s, t); -} - -static CoglTransformResult -_cogl_sub_texture_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - int i; - - /* We can't support repeating with this method. In this case - cogl-primitives will resort to manual repeating */ - for (i = 0; i < 4; i++) - if (coords[i] < 0.0f || coords[i] > 1.0f) - return COGL_TRANSFORM_SOFTWARE_REPEAT; - - _cogl_sub_texture_map_quad (sub_tex, coords); - - return _cogl_texture_transform_quad_coords_to_gl (sub_tex->full_texture, - coords); -} - -static gboolean -_cogl_sub_texture_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return cogl_texture_get_gl_texture (sub_tex->full_texture, - out_gl_handle, - out_gl_target); -} - -static void -_cogl_sub_texture_gl_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - _cogl_texture_gl_flush_legacy_texobj_filters (sub_tex->full_texture, - min_filter, mag_filter); -} - -static void -_cogl_sub_texture_pre_paint (CoglTexture *tex, - CoglTexturePrePaintFlags flags) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - _cogl_texture_pre_paint (sub_tex->full_texture, flags); -} - -static void -_cogl_sub_texture_ensure_non_quad_rendering (CoglTexture *tex) -{ -} - -static gboolean -_cogl_sub_texture_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int dst_width, - int dst_height, - int level, - CoglBitmap *bmp, - GError **error) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - if (level != 0) - { - int full_width = cogl_texture_get_width (sub_tex->full_texture); - int full_height = cogl_texture_get_width (sub_tex->full_texture); - - g_return_val_if_fail (sub_tex->sub_x == 0 && - cogl_texture_get_width (tex) == full_width, - FALSE); - g_return_val_if_fail (sub_tex->sub_y == 0 && - cogl_texture_get_height (tex) == full_height, - FALSE); - } - - return _cogl_texture_set_region_from_bitmap (sub_tex->full_texture, - src_x, src_y, - dst_width, dst_height, - bmp, - dst_x + sub_tex->sub_x, - dst_y + sub_tex->sub_y, - level, - error); -} - -static gboolean -_cogl_sub_texture_is_get_data_supported (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return cogl_texture_is_get_data_supported (sub_tex->full_texture); -} - -static CoglPixelFormat -_cogl_sub_texture_get_format (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return _cogl_texture_get_format (sub_tex->full_texture); -} - -static GLenum -_cogl_sub_texture_get_gl_format (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return _cogl_texture_gl_get_format (sub_tex->full_texture); -} - -static void -cogl_sub_texture_class_init (CoglSubTextureClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - CoglTextureClass *texture_class = COGL_TEXTURE_CLASS (klass); - - gobject_class->dispose = cogl_sub_texture_dispose; - - texture_class->allocate = _cogl_sub_texture_allocate; - texture_class->set_region = _cogl_sub_texture_set_region; - texture_class->is_get_data_supported = _cogl_sub_texture_is_get_data_supported; - texture_class->foreach_sub_texture_in_region = _cogl_sub_texture_foreach_sub_texture_in_region; - texture_class->get_max_waste = _cogl_sub_texture_get_max_waste; - texture_class->is_sliced = _cogl_sub_texture_is_sliced; - texture_class->can_hardware_repeat = _cogl_sub_texture_can_hardware_repeat; - texture_class->transform_coords_to_gl = _cogl_sub_texture_transform_coords_to_gl; - texture_class->transform_quad_coords_to_gl = _cogl_sub_texture_transform_quad_coords_to_gl; - texture_class->get_gl_texture = _cogl_sub_texture_get_gl_texture; - texture_class->gl_flush_legacy_texobj_filters = _cogl_sub_texture_gl_flush_legacy_texobj_filters; - texture_class->pre_paint = _cogl_sub_texture_pre_paint; - texture_class->ensure_non_quad_rendering = _cogl_sub_texture_ensure_non_quad_rendering; - texture_class->gl_flush_legacy_texobj_wrap_modes = _cogl_sub_texture_gl_flush_legacy_texobj_wrap_modes; - texture_class->get_format = _cogl_sub_texture_get_format; - texture_class->get_gl_format = _cogl_sub_texture_get_gl_format; -} - -static void -cogl_sub_texture_init (CoglSubTexture *self) -{ - CoglTexture *texture = COGL_TEXTURE (self); - - texture->is_primitive = FALSE; -} - -CoglTexture * -cogl_sub_texture_new (CoglContext *ctx, - CoglTexture *next_texture, - int sub_x, int sub_y, - int sub_width, int sub_height) -{ - CoglTexture *full_texture; - CoglSubTexture *sub_tex; - unsigned int next_width, next_height; - - next_width = cogl_texture_get_width (next_texture); - next_height = cogl_texture_get_height (next_texture); - - /* The region must specify a non-zero subset of the full texture */ - g_return_val_if_fail (sub_x >= 0 && sub_y >= 0, NULL); - g_return_val_if_fail (sub_width > 0 && sub_height > 0, NULL); - g_return_val_if_fail (sub_x + sub_width <= next_width, NULL); - g_return_val_if_fail (sub_y + sub_height <= next_height, NULL); - - sub_tex = g_object_new (COGL_TYPE_SUB_TEXTURE, - "context", ctx, - "width", sub_width, - "height", sub_height, - "format", _cogl_texture_get_format (next_texture), - NULL); - - /* If the next texture is also a sub texture we can avoid one level - of indirection by referencing the full texture of that texture - instead. */ - if (COGL_IS_SUB_TEXTURE (next_texture)) - { - CoglSubTexture *other_sub_tex = COGL_SUB_TEXTURE (next_texture); - full_texture = other_sub_tex->full_texture; - sub_x += other_sub_tex->sub_x; - sub_y += other_sub_tex->sub_y; - } - else - full_texture = next_texture; - - sub_tex->next_texture = g_object_ref (next_texture); - sub_tex->full_texture = g_object_ref (full_texture); - - sub_tex->sub_x = sub_x; - sub_tex->sub_y = sub_y; - - return COGL_TEXTURE (sub_tex); -} - -CoglTexture * -cogl_sub_texture_get_parent (CoglSubTexture *sub_texture) -{ - return sub_texture->next_texture; -} diff --git a/mutter/cogl/cogl/cogl-sub-texture.h b/mutter/cogl/cogl/cogl-sub-texture.h deleted file mode 100644 index b207ef3..0000000 --- a/mutter/cogl/cogl/cogl-sub-texture.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Neil Roberts - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -G_BEGIN_DECLS - -/** - * CoglSubTexture: - * - * Functions for creating and manipulating sub-textures. - * - * These functions allow high-level textures to be created that - * represent a sub-region of another texture. For example these - * can be used to implement custom texture atlasing schemes. - */ -#define COGL_TYPE_SUB_TEXTURE (cogl_sub_texture_get_type ()) -#define COGL_SUB_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_SUB_TEXTURE, CoglSubTexture)) -#define COGL_SUB_TEXTURE_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_SUB_TEXTURE, CoglSubTexture const)) -#define COGL_SUB_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_TYPE_SUB_TEXTURE, CoglSubTextureClass)) -#define COGL_IS_SUB_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_TYPE_SUB_TEXTURE)) -#define COGL_IS_SUB_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_TYPE_SUB_TEXTURE)) -#define COGL_SUB_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COGL_TYPE_SUB_TEXTURE, CoglSubTextureClass)) - -typedef struct _CoglSubTextureClass CoglSubTextureClass; -typedef struct _CoglSubTexture CoglSubTexture; - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (CoglSubTexture, g_object_unref) - -COGL_EXPORT -GType cogl_sub_texture_get_type (void) G_GNUC_CONST; -/** - * cogl_sub_texture_new: - * @ctx: A #CoglContext pointer - * @parent_texture: The full texture containing a sub-region you want - * to make a #CoglSubTexture from. - * @sub_x: The top-left x coordinate of the parent region to make - * a texture from. - * @sub_y: The top-left y coordinate of the parent region to make - * a texture from. - * @sub_width: The width of the parent region to make a texture from. - * @sub_height: The height of the parent region to make a texture - * from. - * - * Creates a high-level #CoglSubTexture representing a sub-region of - * any other #CoglTexture. The sub-region must strictly lye within the - * bounds of the @parent_texture. The returned texture implements the - * #CoglMetaTexture interface because it's not a low level texture - * that hardware can understand natively. - * - * Remember: Unless you are using high level drawing APIs such - * as cogl_rectangle() or other APIs documented to understand the - * #CoglMetaTexture interface then you need to use the - * #CoglMetaTexture interface to resolve a #CoglSubTexture into a - * low-level texture before drawing. - * - * Return value: (transfer full): A newly allocated #CoglSubTexture - * representing a sub-region of @parent_texture. - */ -COGL_EXPORT CoglTexture * -cogl_sub_texture_new (CoglContext *ctx, - CoglTexture *parent_texture, - int sub_x, - int sub_y, - int sub_width, - int sub_height); - -/** - * cogl_sub_texture_get_parent: - * @sub_texture: A pointer to a #CoglSubTexture - * - * Retrieves the parent texture that @sub_texture derives its content - * from. This is the texture that was passed to - * cogl_sub_texture_new() as the parent_texture argument. - * - * Return value: (transfer none): The parent texture that @sub_texture - * derives its content from. - */ -COGL_EXPORT CoglTexture * -cogl_sub_texture_get_parent (CoglSubTexture *sub_texture); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-swap-chain-private.h b/mutter/cogl/cogl/cogl-swap-chain-private.h deleted file mode 100644 index 0c34fe6..0000000 --- a/mutter/cogl/cogl/cogl-swap-chain-private.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include - -struct _CoglSwapChain -{ - GObject parent_instance; - - int length; -}; diff --git a/mutter/cogl/cogl/cogl-swap-chain.c b/mutter/cogl/cogl/cogl-swap-chain.c deleted file mode 100644 index 0919c64..0000000 --- a/mutter/cogl/cogl/cogl-swap-chain.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-swap-chain-private.h" -#include "cogl/cogl-swap-chain.h" - -G_DEFINE_TYPE (CoglSwapChain, cogl_swap_chain, G_TYPE_OBJECT); - -static void -cogl_swap_chain_init (CoglSwapChain *swap_chain) -{ -} - -static void -cogl_swap_chain_class_init (CoglSwapChainClass *class) -{ -} - -CoglSwapChain * -cogl_swap_chain_new (void) -{ - CoglSwapChain *swap_chain = g_object_new (COGL_TYPE_SWAP_CHAIN, NULL); - - swap_chain->length = -1; /* no preference */ - - return swap_chain; -} - -void -cogl_swap_chain_set_length (CoglSwapChain *swap_chain, - int length) -{ - swap_chain->length = length; -} diff --git a/mutter/cogl/cogl/cogl-swap-chain.h b/mutter/cogl/cogl/cogl-swap-chain.h deleted file mode 100644 index ecd0845..0000000 --- a/mutter/cogl/cogl/cogl-swap-chain.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-types.h" - -#include - -G_BEGIN_DECLS - -typedef struct _CoglSwapChain CoglSwapChain; - -#define COGL_TYPE_SWAP_CHAIN (cogl_swap_chain_get_type ()) - -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglSwapChain, cogl_swap_chain, - COGL, SWAP_CHAIN, GObject) - - -COGL_EXPORT CoglSwapChain * -cogl_swap_chain_new (void); - -COGL_EXPORT void -cogl_swap_chain_set_has_alpha (CoglSwapChain *swap_chain, - gboolean has_alpha); - -COGL_EXPORT void -cogl_swap_chain_set_length (CoglSwapChain *swap_chain, - int length); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-texture-2d-private.h b/mutter/cogl/cogl/cogl-texture-2d-private.h deleted file mode 100644 index 0b976f2..0000000 --- a/mutter/cogl/cogl/cogl-texture-2d-private.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-texture-2d.h" - -struct _CoglTexture2D -{ - CoglTexture parent_instance; - - /* The internal format of the GL texture represented as a - CoglPixelFormat */ - CoglPixelFormat internal_format; - - gboolean auto_mipmap; - gboolean mipmaps_dirty; - gboolean is_get_data_supported; - - /* TODO: factor out these OpenGL specific members into some form - * of driver private state. */ - - /* The internal format of the GL texture represented as a GL enum */ - GLenum gl_internal_format; - /* The texture object number */ - GLuint gl_texture; - GLenum gl_target; - GLenum gl_legacy_texobj_min_filter; - GLenum gl_legacy_texobj_mag_filter; - GLint gl_legacy_texobj_wrap_mode_s; - GLint gl_legacy_texobj_wrap_mode_t; - CoglTexturePixel first_pixel; - - struct { - void *user_data; - GDestroyNotify destroy; - } egl_image_external; -}; - -struct _CoglTexture2DClass -{ - CoglTextureClass parent_class; -}; - -CoglTexture * -_cogl_texture_2d_create_base (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format, - CoglTextureLoader *loader); - -void -_cogl_texture_2d_set_auto_mipmap (CoglTexture *tex, - gboolean value); - -/* - * _cogl_texture_2d_externally_modified: - * @texture: A #CoglTexture2D object - * - * This should be called whenever the texture is modified other than - * by using cogl_texture_set_region. It will cause the mipmaps to be - * invalidated - */ -void -_cogl_texture_2d_externally_modified (CoglTexture *texture); - -/* - * _cogl_texture_2d_copy_from_framebuffer: - * @texture: A #CoglTexture2D pointer - * @src_x: X-position to within the framebuffer to read from - * @src_y: Y-position to within the framebuffer to read from - * @width: width of the rectangle to copy - * @height: height of the rectangle to copy - * @src_fb: A source #CoglFramebuffer to copy from - * @dst_x: X-position to store the image within the texture - * @dst_y: Y-position to store the image within the texture - * @level: The mipmap level of @texture to copy too - * - * This copies a portion of the given @src_fb into the - * texture. - */ -void -_cogl_texture_2d_copy_from_framebuffer (CoglTexture2D *texture, - int src_x, - int src_y, - int width, - int height, - CoglFramebuffer *src_fb, - int dst_x, - int dst_y, - int level); diff --git a/mutter/cogl/cogl/cogl-texture-2d-sliced-private.h b/mutter/cogl/cogl/cogl-texture-2d-sliced-private.h deleted file mode 100644 index d7f391d..0000000 --- a/mutter/cogl/cogl/cogl-texture-2d-sliced-private.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-bitmap-private.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-texture-2d-sliced.h" - -#include - -struct _CoglTexture2DSliced -{ - CoglTexture parent_instance; - - GArray *slice_x_spans; - GArray *slice_y_spans; - GArray *slice_textures; - int max_waste; - CoglPixelFormat internal_format; -}; - -struct _CoglTexture2DSlicedClass -{ - CoglTextureClass parent_class; -}; diff --git a/mutter/cogl/cogl/cogl-texture-2d-sliced.c b/mutter/cogl/cogl/cogl-texture-2d-sliced.c deleted file mode 100644 index 13411c4..0000000 --- a/mutter/cogl/cogl/cogl-texture-2d-sliced.c +++ /dev/null @@ -1,1314 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Matthew Allum - * Neil Roberts - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-debug.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-bitmap.h" -#include "cogl/cogl-bitmap-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-texture-2d-private.h" -#include "cogl/cogl-texture-2d-sliced-private.h" -#include "cogl/cogl-texture-driver.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-spans.h" -#include "cogl/cogl-journal-private.h" -#include "cogl/cogl-primitive-texture.h" -#include "cogl/driver/gl/cogl-texture-gl-private.h" - -#include -#include -#include - -G_DEFINE_FINAL_TYPE (CoglTexture2DSliced, cogl_texture_2d_sliced, COGL_TYPE_TEXTURE) - -typedef struct _ForeachData -{ - CoglMetaTextureCallback callback; - void *user_data; - float x_normalize_factor; - float y_normalize_factor; -} ForeachData; - - -static void -free_spans (CoglTexture2DSliced *tex_2ds) -{ - if (tex_2ds->slice_x_spans != NULL) - { - g_array_free (tex_2ds->slice_x_spans, TRUE); - tex_2ds->slice_x_spans = NULL; - } - - if (tex_2ds->slice_y_spans != NULL) - { - g_array_free (tex_2ds->slice_y_spans, TRUE); - tex_2ds->slice_y_spans = NULL; - } -} - -static void -free_slices (CoglTexture2DSliced *tex_2ds) -{ - if (tex_2ds->slice_textures != NULL) - { - int i; - - for (i = 0; i < tex_2ds->slice_textures->len; i++) - { - CoglTexture2D *slice_tex = - g_array_index (tex_2ds->slice_textures, CoglTexture2D *, i); - g_object_unref (slice_tex); - } - - g_array_free (tex_2ds->slice_textures, TRUE); - tex_2ds->slice_textures = NULL; - } - - free_spans (tex_2ds); -} - -static void -cogl_texture_2d_sliced_dispose (GObject *object) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (object); - - free_slices (tex_2ds); - - G_OBJECT_CLASS (cogl_texture_2d_sliced_parent_class)->dispose (object); -} - -static int -_cogl_rect_slices_for_size (int size_to_fill, - int max_span_size, - int max_waste, - GArray *out_spans) -{ - int n_spans = 0; - CoglSpan span; - - /* Init first slice span */ - span.start = 0; - span.size = max_span_size; - span.waste = 0; - - /* Repeat until whole area covered */ - while (size_to_fill >= span.size) - { - /* Add another slice span of same size */ - if (out_spans) - g_array_append_val (out_spans, span); - span.start += span.size; - size_to_fill -= span.size; - n_spans++; - } - - /* Add one last smaller slice span */ - if (size_to_fill > 0) - { - span.size = size_to_fill; - if (out_spans) - g_array_append_val (out_spans, span); - n_spans++; - } - - return n_spans; -} - -static gboolean -setup_spans (CoglContext *ctx, - CoglTexture2DSliced *tex_2ds, - int width, - int height, - int max_waste, - CoglPixelFormat internal_format, - GError **error) -{ - int max_width; - int max_height; - int n_x_slices; - int n_y_slices; - - int (*slices_for_size) (int, int, int, GArray*); - - /* Initialize size of largest slice according to supported features */ - max_width = width; - max_height = height; - slices_for_size = _cogl_rect_slices_for_size; - - /* Negative number means no slicing forced by the user */ - if (max_waste <= -1) - { - CoglSpan span; - - /* Check if size supported else bail out */ - if (!ctx->driver_vtable->texture_2d_can_create (ctx, - max_width, - max_height, - internal_format)) - { - g_set_error (error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE, - "Sliced texture size of %d x %d not possible " - "with max waste set to -1", - width, - height); - return FALSE; - } - - n_x_slices = 1; - n_y_slices = 1; - - /* Init span arrays */ - tex_2ds->slice_x_spans = g_array_sized_new (FALSE, FALSE, - sizeof (CoglSpan), - 1); - - tex_2ds->slice_y_spans = g_array_sized_new (FALSE, FALSE, - sizeof (CoglSpan), - 1); - - /* Add a single span for width and height */ - span.start = 0; - span.size = max_width; - span.waste = max_width - width; - g_array_append_val (tex_2ds->slice_x_spans, span); - - span.size = max_height; - span.waste = max_height - height; - g_array_append_val (tex_2ds->slice_y_spans, span); - } - else - { - /* Decrease the size of largest slice until supported by GL */ - while (!ctx->driver_vtable->texture_2d_can_create (ctx, - max_width, - max_height, - internal_format)) - { - /* Alternate between width and height */ - if (max_width > max_height) - max_width /= 2; - else - max_height /= 2; - - if (max_width == 0 || max_height == 0) - { - /* Maybe it would be ok to just g_warn_if_reached() for this - * codepath */ - g_set_error (error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE, - "No suitable slice geometry found"); - free_spans (tex_2ds); - return FALSE; - } - } - - /* Determine the slices required to cover the bitmap area */ - n_x_slices = slices_for_size (width, - max_width, max_waste, - NULL); - - n_y_slices = slices_for_size (height, - max_height, max_waste, - NULL); - - /* Init span arrays with reserved size */ - tex_2ds->slice_x_spans = g_array_sized_new (FALSE, FALSE, - sizeof (CoglSpan), - n_x_slices); - - tex_2ds->slice_y_spans = g_array_sized_new (FALSE, FALSE, - sizeof (CoglSpan), - n_y_slices); - - /* Fill span arrays with info */ - slices_for_size (width, - max_width, max_waste, - tex_2ds->slice_x_spans); - - slices_for_size (height, - max_height, max_waste, - tex_2ds->slice_y_spans); - } - - return TRUE; -} - -static gboolean -allocate_slices (CoglTexture2DSliced *tex_2ds, - int width, - int height, - int max_waste, - CoglPixelFormat internal_format, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2ds); - CoglContext *ctx = cogl_texture_get_context (tex); - int n_x_slices; - int n_y_slices; - int n_slices; - int x, y; - CoglSpan *x_span; - CoglSpan *y_span; - - tex_2ds->internal_format = internal_format; - - if (!setup_spans (ctx, tex_2ds, - width, - height, - max_waste, - internal_format, - error)) - { - return FALSE; - } - - n_x_slices = tex_2ds->slice_x_spans->len; - n_y_slices = tex_2ds->slice_y_spans->len; - n_slices = n_x_slices * n_y_slices; - - tex_2ds->slice_textures = g_array_sized_new (FALSE, FALSE, - sizeof (CoglTexture2D *), - n_slices); - - /* Allocate each slice */ - for (y = 0; y < n_y_slices; ++y) - { - y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, y); - - for (x = 0; x < n_x_slices; ++x) - { - CoglTexture *slice; - - x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, x); - - COGL_NOTE (SLICING, "CREATE SLICE (%d,%d)\tsize (%d,%d)", - x, y, - (int)(x_span->size - x_span->waste), - (int)(y_span->size - y_span->waste)); - - slice = - cogl_texture_2d_new_with_size (ctx, - x_span->size, y_span->size); - - _cogl_texture_copy_internal_format (tex, slice); - - g_array_append_val (tex_2ds->slice_textures, slice); - if (!cogl_texture_allocate (slice, error)) - { - free_slices (tex_2ds); - return FALSE; - } - } - } - - return TRUE; -} - -static gboolean -allocate_with_size (CoglTexture2DSliced *tex_2ds, - CoglTextureLoader *loader, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2ds); - CoglPixelFormat internal_format; - - g_warn_if_fail (loader->src.sized.format == COGL_PIXEL_FORMAT_ANY); - - internal_format = - _cogl_texture_determine_internal_format (tex, COGL_PIXEL_FORMAT_ANY); - - if (allocate_slices (tex_2ds, - loader->src.sized.width, - loader->src.sized.height, - tex_2ds->max_waste, - internal_format, - error)) - { - _cogl_texture_set_allocated (tex, - internal_format, - loader->src.sized.width, - loader->src.sized.height); - return TRUE; - } - else - return FALSE; -} - -static uint8_t * -_cogl_texture_2d_sliced_allocate_waste_buffer (CoglTexture2DSliced *tex_2ds, - CoglPixelFormat format) -{ - CoglSpan *last_x_span; - CoglSpan *last_y_span; - uint8_t *waste_buf = NULL; - - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); - - /* If the texture has any waste then allocate a buffer big enough to - fill the gaps */ - last_x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, - tex_2ds->slice_x_spans->len - 1); - last_y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, - tex_2ds->slice_y_spans->len - 1); - if (last_x_span->waste > 0 || last_y_span->waste > 0) - { - int bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); - CoglSpan *first_x_span - = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, 0); - CoglSpan *first_y_span - = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, 0); - unsigned int right_size = first_y_span->size * last_x_span->waste; - unsigned int bottom_size = first_x_span->size * last_y_span->waste; - - waste_buf = g_malloc (MAX (right_size, bottom_size) * bpp); - } - - return waste_buf; -} - -static gboolean -_cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds, - CoglBitmap *source_bmp, - CoglTexture2D *slice_tex, - uint8_t *waste_buf, - CoglSpan *x_span, - CoglSpan *y_span, - CoglSpanIter *x_iter, - CoglSpanIter *y_iter, - int src_x, - int src_y, - int dst_x, - int dst_y, - GError **error) -{ - gboolean need_x, need_y; - CoglContext *ctx = cogl_texture_get_context (COGL_TEXTURE (tex_2ds)); - - /* If the x_span is sliced and the upload touches the - rightmost pixels then fill the waste with copies of the - pixels */ - need_x = x_span->waste > 0 && - x_iter->intersect_end - x_iter->pos >= x_span->size - x_span->waste; - - /* same for the bottom-most pixels */ - need_y = y_span->waste > 0 && - y_iter->intersect_end - y_iter->pos >= y_span->size - y_span->waste; - - if (need_x || need_y) - { - int bmp_rowstride = cogl_bitmap_get_rowstride (source_bmp); - CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp; - uint8_t *bmp_data; - const uint8_t *src; - uint8_t *dst; - unsigned int wy, wx; - CoglBitmap *waste_bmp; - - /* We only support single plane formats here */ - if (cogl_pixel_format_get_n_planes (source_format) == 1) - return FALSE; - - bmp_data = _cogl_bitmap_map (source_bmp, COGL_BUFFER_ACCESS_READ, 0, error); - if (bmp_data == NULL) - return FALSE; - - bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0); - - if (need_x) - { - src = (bmp_data + ((src_y + (int) y_iter->intersect_start - dst_y) * - bmp_rowstride) + - (src_x + (int)x_span->start + (int)x_span->size - - (int)x_span->waste - dst_x - 1) * bpp); - - dst = waste_buf; - - for (wy = 0; - wy < y_iter->intersect_end - y_iter->intersect_start; - wy++) - { - for (wx = 0; wx < x_span->waste; wx++) - { - memcpy (dst, src, bpp); - dst += bpp; - } - src += bmp_rowstride; - } - - waste_bmp = cogl_bitmap_new_for_data (ctx, - x_span->waste, - y_iter->intersect_end - - y_iter->intersect_start, - source_format, - x_span->waste * bpp, - waste_buf); - - if (!_cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex), - 0, /* src_x */ - 0, /* src_y */ - x_span->waste, /* width */ - /* height */ - y_iter->intersect_end - - y_iter->intersect_start, - waste_bmp, - /* dst_x */ - x_span->size - x_span->waste, - y_iter->intersect_start - - y_span->start, /* dst_y */ - 0, /* level */ - error)) - { - g_object_unref (waste_bmp); - _cogl_bitmap_unmap (source_bmp); - return FALSE; - } - - g_object_unref (waste_bmp); - } - - if (need_y) - { - unsigned int copy_width, intersect_width; - - src = (bmp_data + ((src_x + (int) x_iter->intersect_start - dst_x) * - bpp) + - (src_y + (int)y_span->start + (int)y_span->size - - (int)y_span->waste - dst_y - 1) * bmp_rowstride); - - dst = waste_buf; - - if (x_iter->intersect_end - x_iter->pos - >= x_span->size - x_span->waste) - copy_width = x_span->size + x_iter->pos - x_iter->intersect_start; - else - copy_width = x_iter->intersect_end - x_iter->intersect_start; - - intersect_width = x_iter->intersect_end - x_iter->intersect_start; - - for (wy = 0; wy < y_span->waste; wy++) - { - memcpy (dst, src, intersect_width * bpp); - dst += intersect_width * bpp; - - for (wx = intersect_width; wx < copy_width; wx++) - { - memcpy (dst, dst - bpp, bpp); - dst += bpp; - } - } - - waste_bmp = cogl_bitmap_new_for_data (ctx, - copy_width, - y_span->waste, - source_format, - copy_width * bpp, - waste_buf); - - if (!_cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex), - 0, /* src_x */ - 0, /* src_y */ - copy_width, /* width */ - y_span->waste, /* height */ - waste_bmp, - /* dst_x */ - x_iter->intersect_start - - x_iter->pos, - /* dst_y */ - y_span->size - y_span->waste, - 0, /* level */ - error)) - { - g_object_unref (waste_bmp); - _cogl_bitmap_unmap (source_bmp); - return FALSE; - } - - g_object_unref (waste_bmp); - } - - _cogl_bitmap_unmap (source_bmp); - } - - return TRUE; -} - -static gboolean -_cogl_texture_2d_sliced_upload_bitmap (CoglTexture2DSliced *tex_2ds, - CoglBitmap *bmp, - GError **error) -{ - CoglSpan *x_span; - CoglSpan *y_span; - CoglTexture2D *slice_tex; - int x, y; - uint8_t *waste_buf; - CoglPixelFormat bmp_format; - - bmp_format = cogl_bitmap_get_format (bmp); - - waste_buf = _cogl_texture_2d_sliced_allocate_waste_buffer (tex_2ds, - bmp_format); - - /* Iterate vertical slices */ - for (y = 0; y < tex_2ds->slice_y_spans->len; ++y) - { - y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, y); - - /* Iterate horizontal slices */ - for (x = 0; x < tex_2ds->slice_x_spans->len; ++x) - { - int slice_num = y * tex_2ds->slice_x_spans->len + x; - CoglSpanIter x_iter, y_iter; - - x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, x); - - /* Pick the gl texture object handle */ - slice_tex = g_array_index (tex_2ds->slice_textures, - CoglTexture2D *, slice_num); - - if (!_cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex), - x_span->start, /* src x */ - y_span->start, /* src y */ - x_span->size - - x_span->waste, /* width */ - y_span->size - - y_span->waste, /* height */ - bmp, - 0, /* dst x */ - 0, /* dst y */ - 0, /* level */ - error)) - { - if (waste_buf) - g_free (waste_buf); - return FALSE; - } - - /* Set up a fake iterator that covers the whole slice */ - x_iter.intersect_start = x_span->start; - x_iter.intersect_end = (x_span->start + - x_span->size - - x_span->waste); - x_iter.pos = x_span->start; - - y_iter.intersect_start = y_span->start; - y_iter.intersect_end = (y_span->start + - y_span->size - - y_span->waste); - y_iter.pos = y_span->start; - - if (!_cogl_texture_2d_sliced_set_waste (tex_2ds, - bmp, - slice_tex, - waste_buf, - x_span, y_span, - &x_iter, &y_iter, - 0, /* src_x */ - 0, /* src_y */ - 0, /* dst_x */ - 0, - error)) /* dst_y */ - { - if (waste_buf) - g_free (waste_buf); - return FALSE; - } - } - } - - if (waste_buf) - g_free (waste_buf); - - return TRUE; -} - -static gboolean -allocate_from_bitmap (CoglTexture2DSliced *tex_2ds, - CoglTextureLoader *loader, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2ds); - CoglBitmap *bmp = loader->src.bitmap.bitmap; - int width = cogl_bitmap_get_width (bmp); - int height = cogl_bitmap_get_height (bmp); - CoglPixelFormat internal_format; - CoglBitmap *upload_bmp; - - g_return_val_if_fail (tex_2ds->slice_textures == NULL, FALSE); - - internal_format = - _cogl_texture_determine_internal_format (tex, - cogl_bitmap_get_format (bmp)); - - upload_bmp = _cogl_bitmap_convert_for_upload (bmp, - internal_format, - error); - if (upload_bmp == NULL) - return FALSE; - - if (!allocate_slices (tex_2ds, - width, - height, - tex_2ds->max_waste, - internal_format, - error)) - { - g_object_unref (upload_bmp); - return FALSE; - } - - if (!_cogl_texture_2d_sliced_upload_bitmap (tex_2ds, - upload_bmp, - error)) - { - free_slices (tex_2ds); - g_object_unref (upload_bmp); - return FALSE; - } - - g_object_unref (upload_bmp); - - _cogl_texture_set_allocated (tex, internal_format, width, height); - - return TRUE; -} - -static gboolean -_cogl_texture_2d_sliced_allocate (CoglTexture *tex, - GError **error) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglTextureLoader *loader = cogl_texture_get_loader (tex); - - g_return_val_if_fail (loader, FALSE); - - switch (loader->src_type) - { - case COGL_TEXTURE_SOURCE_TYPE_SIZE: - return allocate_with_size (tex_2ds, loader, error); - case COGL_TEXTURE_SOURCE_TYPE_BITMAP: - return allocate_from_bitmap (tex_2ds, loader, error); - default: - break; - } - - g_return_val_if_reached (FALSE); -} - -static int -_cogl_texture_2d_sliced_get_max_waste (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - - return tex_2ds->max_waste; -} - -static gboolean -_cogl_texture_2d_sliced_is_sliced (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - - /* It's only after allocating a sliced texture that we will know - * whether it really needed to be sliced... */ - if (!tex->allocated) - cogl_texture_allocate (tex, NULL); - - if (tex_2ds->slice_x_spans->len != 1 || - tex_2ds->slice_y_spans->len != 1) - return TRUE; - else - return FALSE; -} - -static gboolean -_cogl_texture_2d_sliced_can_hardware_repeat (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglTexture2D *slice_tex; - CoglSpan *x_span; - CoglSpan *y_span; - - /* If there's more than one texture then we can't hardware repeat */ - if (tex_2ds->slice_textures->len != 1) - return FALSE; - - /* If there's any waste then we can't hardware repeat */ - x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, 0); - y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, 0); - if (x_span->waste > 0 || y_span->waste > 0) - return FALSE; - - /* Otherwise pass the query on to the single slice texture */ - slice_tex = g_array_index (tex_2ds->slice_textures, CoglTexture2D *, 0); - return _cogl_texture_can_hardware_repeat (COGL_TEXTURE (slice_tex)); -} - -static void -_cogl_texture_2d_sliced_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglSpan *x_span; - CoglSpan *y_span; - CoglTexture2D *slice_tex; - - g_assert (!_cogl_texture_2d_sliced_is_sliced (tex)); - - /* Don't include the waste in the texture coordinates */ - x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, 0); - y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, 0); - - *s *= cogl_texture_get_width (tex) / (float)x_span->size; - *t *= cogl_texture_get_height (tex) / (float)y_span->size; - - /* Let the child texture further transform the coords */ - slice_tex = g_array_index (tex_2ds->slice_textures, CoglTexture2D *, 0); - _cogl_texture_transform_coords_to_gl (COGL_TEXTURE (slice_tex), s, t); -} - -static CoglTransformResult -_cogl_texture_2d_sliced_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - gboolean need_repeat = FALSE; - int i; - - /* This is a bit lazy - in the case where the quad lies entirely - * within a single slice we could avoid the fallback. But that - * could likely lead to visual inconsistency if the fallback involves - * dropping layers, so this might be the right thing to do anyways. - */ - if (_cogl_texture_2d_sliced_is_sliced (tex)) - return COGL_TRANSFORM_SOFTWARE_REPEAT; - - for (i = 0; i < 4; i++) - if (coords[i] < 0.0f || coords[i] > 1.0f) - need_repeat = TRUE; - - if (need_repeat && !_cogl_texture_2d_sliced_can_hardware_repeat (tex)) - return COGL_TRANSFORM_SOFTWARE_REPEAT; - - _cogl_texture_2d_sliced_transform_coords_to_gl (tex, coords + 0, coords + 1); - _cogl_texture_2d_sliced_transform_coords_to_gl (tex, coords + 2, coords + 3); - - return (need_repeat - ? COGL_TRANSFORM_HARDWARE_REPEAT : COGL_TRANSFORM_NO_REPEAT); -} - -static gboolean -_cogl_texture_2d_sliced_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglTexture2D *slice_tex; - - if (tex_2ds->slice_textures == NULL) - return FALSE; - - if (tex_2ds->slice_textures->len < 1) - return FALSE; - - slice_tex = g_array_index (tex_2ds->slice_textures, CoglTexture2D *, 0); - - return cogl_texture_get_gl_texture (COGL_TEXTURE (slice_tex), - out_gl_handle, out_gl_target); -} - -static void -_cogl_texture_2d_sliced_gl_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglTexture2D *slice_tex; - int i; - - g_return_if_fail (tex_2ds->slice_textures != NULL); - - /* Apply new filters to every slice. The slice texture itself should - cache the value and avoid resubmitting the same filter value to - GL */ - for (i = 0; i < tex_2ds->slice_textures->len; i++) - { - slice_tex = g_array_index (tex_2ds->slice_textures, CoglTexture2D *, i); - _cogl_texture_gl_flush_legacy_texobj_filters (COGL_TEXTURE (slice_tex), - min_filter, mag_filter); - } -} - -static void -_cogl_texture_2d_sliced_pre_paint (CoglTexture *tex, - CoglTexturePrePaintFlags flags) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - int i; - - g_return_if_fail (tex_2ds->slice_textures != NULL); - - /* Pass the pre-paint on to every slice */ - for (i = 0; i < tex_2ds->slice_textures->len; i++) - { - CoglTexture2D *slice_tex = g_array_index (tex_2ds->slice_textures, - CoglTexture2D *, i); - _cogl_texture_pre_paint (COGL_TEXTURE (slice_tex), flags); - } -} - -static void -_cogl_texture_2d_sliced_ensure_non_quad_rendering (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - int i; - - g_return_if_fail (tex_2ds->slice_textures != NULL); - - /* Pass the call on to every slice */ - for (i = 0; i < tex_2ds->slice_textures->len; i++) - { - CoglTexture2D *slice_tex = g_array_index (tex_2ds->slice_textures, - CoglTexture2D *, i); - _cogl_texture_ensure_non_quad_rendering (COGL_TEXTURE (slice_tex)); - } -} - -static void -_cogl_texture_2d_sliced_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - int i; - - /* Pass the set wrap mode on to all of the child textures */ - for (i = 0; i < tex_2ds->slice_textures->len; i++) - { - CoglTexture2D *slice_tex = g_array_index (tex_2ds->slice_textures, - CoglTexture2D *, - i); - - _cogl_texture_gl_flush_legacy_texobj_wrap_modes (COGL_TEXTURE (slice_tex), - wrap_mode_s, - wrap_mode_t); - } -} - -static GLenum -_cogl_texture_2d_sliced_get_gl_format (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglTexture2D *slice_tex; - - /* Assert that we've allocated our slices at this point */ - cogl_texture_allocate (tex, NULL); /* (abort on error) */ - - /* Pass the call on to the first slice */ - slice_tex = g_array_index (tex_2ds->slice_textures, CoglTexture2D *, 0); - return _cogl_texture_gl_get_format (COGL_TEXTURE (slice_tex)); -} - -static gboolean -_cogl_texture_2d_sliced_upload_subregion (CoglTexture2DSliced *tex_2ds, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - CoglBitmap *source_bmp, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2ds); - CoglSpan *x_span; - CoglSpan *y_span; - CoglSpanIter x_iter; - CoglSpanIter y_iter; - CoglTexture2D *slice_tex; - int source_x = 0, source_y = 0; - int inter_w = 0, inter_h = 0; - int local_x = 0, local_y = 0; - uint8_t *waste_buf; - CoglPixelFormat source_format; - - source_format = cogl_bitmap_get_format (source_bmp); - - waste_buf = - _cogl_texture_2d_sliced_allocate_waste_buffer (tex_2ds, source_format); - - /* Iterate vertical spans */ - for (source_y = src_y, - _cogl_span_iter_begin (&y_iter, - (CoglSpan *)tex_2ds->slice_y_spans->data, - tex_2ds->slice_y_spans->len, - cogl_texture_get_height (tex), - dst_y, - dst_y + height, - COGL_PIPELINE_WRAP_MODE_REPEAT); - - !_cogl_span_iter_end (&y_iter); - - _cogl_span_iter_next (&y_iter), - source_y += inter_h ) - { - y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, - y_iter.index); - - /* Iterate horizontal spans */ - for (source_x = src_x, - _cogl_span_iter_begin (&x_iter, - (CoglSpan *)tex_2ds->slice_x_spans->data, - tex_2ds->slice_x_spans->len, - cogl_texture_get_width (tex), - dst_x, - dst_x + width, - COGL_PIPELINE_WRAP_MODE_REPEAT); - - !_cogl_span_iter_end (&x_iter); - - _cogl_span_iter_next (&x_iter), - source_x += inter_w ) - { - int slice_num; - - x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, - x_iter.index); - - /* Pick intersection width and height */ - inter_w = (x_iter.intersect_end - x_iter.intersect_start); - inter_h = (y_iter.intersect_end - y_iter.intersect_start); - - /* Localize intersection top-left corner to slice*/ - local_x = (x_iter.intersect_start - x_iter.pos); - local_y = (y_iter.intersect_start - y_iter.pos); - - slice_num = y_iter.index * tex_2ds->slice_x_spans->len + x_iter.index; - - /* Pick slice texture */ - slice_tex = g_array_index (tex_2ds->slice_textures, - CoglTexture2D *, slice_num); - - if (!_cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex), - source_x, - source_y, - inter_w, /* width */ - inter_h, /* height */ - source_bmp, - local_x, /* dst x */ - local_y, /* dst y */ - 0, /* level */ - error)) - { - if (waste_buf) - g_free (waste_buf); - return FALSE; - } - - if (!_cogl_texture_2d_sliced_set_waste (tex_2ds, - source_bmp, - slice_tex, - waste_buf, - x_span, y_span, - &x_iter, &y_iter, - src_x, src_y, - dst_x, dst_y, - error)) - { - if (waste_buf) - g_free (waste_buf); - return FALSE; - } - } - } - - if (waste_buf) - g_free (waste_buf); - - return TRUE; -} - -static gboolean -_cogl_texture_2d_sliced_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int dst_width, - int dst_height, - int level, - CoglBitmap *bmp, - GError **error) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglBitmap *upload_bmp; - gboolean status; - - upload_bmp = _cogl_bitmap_convert_for_upload (bmp, - _cogl_texture_get_format (tex), - error); - if (!upload_bmp) - return FALSE; - - status = _cogl_texture_2d_sliced_upload_subregion (tex_2ds, - src_x, src_y, - dst_x, dst_y, - dst_width, dst_height, - upload_bmp, - error); - g_object_unref (upload_bmp); - - return status; -} - -static void -re_normalize_sub_texture_coords_cb (CoglTexture *sub_texture, - const float *sub_texture_coords, - const float *meta_coords, - void *user_data) -{ - ForeachData *data = user_data; - /* The coordinates passed to the span iterating code were - * un-normalized so we need to renormalize them before passing them - * on */ - float re_normalized_coords[4] = - { - meta_coords[0] * data->x_normalize_factor, - meta_coords[1] * data->y_normalize_factor, - meta_coords[2] * data->x_normalize_factor, - meta_coords[3] * data->y_normalize_factor - }; - - data->callback (sub_texture, sub_texture_coords, re_normalized_coords, - data->user_data); -} - -static void -_cogl_texture_2d_sliced_foreach_sub_texture_in_region ( - CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglMetaTextureCallback callback, - void *user_data) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglSpan *x_spans = (CoglSpan *)tex_2ds->slice_x_spans->data; - CoglSpan *y_spans = (CoglSpan *)tex_2ds->slice_y_spans->data; - CoglTexture **textures = (CoglTexture **)tex_2ds->slice_textures->data; - float un_normalized_coords[4]; - ForeachData data; - - /* NB: its convenient for us to store non-normalized coordinates in - * our CoglSpans but that means we need to un-normalize the incoming - * virtual coordinates and make sure we re-normalize the coordinates - * before calling the given callback. - */ - - data.callback = callback; - data.user_data = user_data; - data.x_normalize_factor = 1.0f / cogl_texture_get_width (tex); - data.y_normalize_factor = 1.0f / cogl_texture_get_height (tex); - - un_normalized_coords[0] = virtual_tx_1 * cogl_texture_get_width (tex); - un_normalized_coords[1] = virtual_ty_1 * cogl_texture_get_height (tex); - un_normalized_coords[2] = virtual_tx_2 * cogl_texture_get_width (tex); - un_normalized_coords[3] = virtual_ty_2 * cogl_texture_get_height (tex); - - /* Note that the normalize factors passed here are the reciprocal of - * the factors calculated above because the span iterating code - * normalizes by dividing by the factor instead of multiplying */ - _cogl_texture_spans_foreach_in_region (x_spans, - tex_2ds->slice_x_spans->len, - y_spans, - tex_2ds->slice_y_spans->len, - textures, - un_normalized_coords, - cogl_texture_get_width (tex), - cogl_texture_get_height (tex), - COGL_PIPELINE_WRAP_MODE_REPEAT, - COGL_PIPELINE_WRAP_MODE_REPEAT, - re_normalize_sub_texture_coords_cb, - &data); -} - -static CoglPixelFormat -_cogl_texture_2d_sliced_get_format (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - - return tex_2ds->internal_format; -} - -static void -cogl_texture_2d_sliced_class_init (CoglTexture2DSlicedClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - CoglTextureClass *texture_class = COGL_TEXTURE_CLASS (klass); - - gobject_class->dispose = cogl_texture_2d_sliced_dispose; - - texture_class->allocate = _cogl_texture_2d_sliced_allocate; - texture_class->set_region = _cogl_texture_2d_sliced_set_region; - texture_class->foreach_sub_texture_in_region = _cogl_texture_2d_sliced_foreach_sub_texture_in_region; - texture_class->get_max_waste = _cogl_texture_2d_sliced_get_max_waste; - texture_class->is_sliced = _cogl_texture_2d_sliced_is_sliced; - texture_class->can_hardware_repeat = _cogl_texture_2d_sliced_can_hardware_repeat; - texture_class->transform_coords_to_gl = _cogl_texture_2d_sliced_transform_coords_to_gl; - texture_class->transform_quad_coords_to_gl = _cogl_texture_2d_sliced_transform_quad_coords_to_gl; - texture_class->get_gl_texture = _cogl_texture_2d_sliced_get_gl_texture; - texture_class->gl_flush_legacy_texobj_filters = _cogl_texture_2d_sliced_gl_flush_legacy_texobj_filters; - texture_class->pre_paint = _cogl_texture_2d_sliced_pre_paint; - texture_class->ensure_non_quad_rendering = _cogl_texture_2d_sliced_ensure_non_quad_rendering; - texture_class->gl_flush_legacy_texobj_wrap_modes = _cogl_texture_2d_sliced_gl_flush_legacy_texobj_wrap_modes; - texture_class->get_format = _cogl_texture_2d_sliced_get_format; - texture_class->get_gl_format = _cogl_texture_2d_sliced_get_gl_format; -} - -static void -cogl_texture_2d_sliced_init (CoglTexture2DSliced *self) -{ - CoglTexture *texture = COGL_TEXTURE (self); - - texture->is_primitive = FALSE; -} - -static CoglTexture * -_cogl_texture_2d_sliced_create_base (CoglContext *ctx, - int width, - int height, - int max_waste, - CoglPixelFormat internal_format, - CoglTextureLoader *loader) -{ - CoglTexture2DSliced *tex_2ds = g_object_new (COGL_TYPE_TEXTURE_2D_SLICED, - "context", ctx, - "width", width, - "height", height, - "loader", loader, - "format", internal_format, - NULL); - - tex_2ds->max_waste = max_waste; - - return COGL_TEXTURE (tex_2ds); -} - -CoglTexture * -cogl_texture_2d_sliced_new_with_size (CoglContext *ctx, - int width, - int height, - int max_waste) -{ - CoglTextureLoader *loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_SIZE; - loader->src.sized.width = width; - loader->src.sized.height = height; - loader->src.sized.format = COGL_PIXEL_FORMAT_ANY; - - return _cogl_texture_2d_sliced_create_base (ctx, - width, - height, - max_waste, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - loader); -} - -CoglTexture * -cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, - int max_waste) -{ - CoglTextureLoader *loader; - - g_return_val_if_fail (COGL_IS_BITMAP (bmp), NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_BITMAP; - loader->src.bitmap.bitmap = g_object_ref (bmp); - - return _cogl_texture_2d_sliced_create_base (_cogl_bitmap_get_context (bmp), - cogl_bitmap_get_width (bmp), - cogl_bitmap_get_height (bmp), - max_waste, - cogl_bitmap_get_format (bmp), - loader); -} - -CoglTexture * -cogl_texture_2d_sliced_new_from_data (CoglContext *ctx, - int width, - int height, - int max_waste, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - GError **error) -{ - CoglBitmap *bmp; - CoglTexture *tex_2ds; - - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); - g_return_val_if_fail (data != NULL, NULL); - - /* Rowstride from width if not given */ - if (rowstride == 0) - rowstride = width * cogl_pixel_format_get_bytes_per_pixel (format, 0); - - /* Wrap the data into a bitmap */ - bmp = cogl_bitmap_new_for_data (ctx, - width, height, - format, - rowstride, - (uint8_t *) data); - - tex_2ds = cogl_texture_2d_sliced_new_from_bitmap (bmp, max_waste); - - g_object_unref (bmp); - - if (tex_2ds && - !cogl_texture_allocate (COGL_TEXTURE (tex_2ds), error)) - { - g_object_unref (tex_2ds); - return NULL; - } - - return tex_2ds; -} - diff --git a/mutter/cogl/cogl/cogl-texture-2d-sliced.h b/mutter/cogl/cogl/cogl-texture-2d-sliced.h deleted file mode 100644 index 3effb10..0000000 --- a/mutter/cogl/cogl/cogl-texture-2d-sliced.h +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-context.h" -#include "cogl/cogl-types.h" - -/** - * CoglTexture2DSliced: - * - * Functions for creating and manipulating 2D meta textures - * that may internally be comprised of multiple 2D textures - * with power-of-two sizes. - * - * These functions allow high-level meta textures (See the - * #CoglMetaTexture interface) to be allocated that may internally be - * comprised of multiple 2D texture "slices" with power-of-two sizes. - * - * This API can be useful when working with GPUs that don't have - * native support for non-power-of-two textures or if you want to load - * a texture that is larger than the GPUs maximum texture size limits. - * - * The algorithm for slicing works by first trying to map a virtual - * size to the next larger power-of-two size and then seeing how many - * wasted pixels that would result in. For example if you have a - * virtual texture that's 259 texels wide, the next pot size = 512 and - * the amount of waste would be 253 texels. If the amount of waste is - * above a max-waste threshold then we would next slice that texture - * into one that's 256 texels and then looking at how many more texels - * remain unallocated after that we choose the next power-of-two size. - * For the example of a 259 texel image that would mean having a 256 - * texel wide texture, leaving 3 texels unallocated so we'd then - * create a 4 texel wide texture - now there is only one texel of - * waste. The algorithm continues to slice the right most textures - * until the amount of waste is less than or equal to a specified - * max-waste threshold. The same logic for slicing from left to right - * is also applied from top to bottom. - */ -#define COGL_TYPE_TEXTURE_2D_SLICED (cogl_texture_2d_sliced_get_type ()) -#define COGL_TEXTURE_2D_SLICED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_TEXTURE_2D_SLICED, CoglTexture2DSliced)) -#define COGL_TEXTURE_2D_SLICED_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_TEXTURE_2D_SLICED, CoglTexture2DSliced const)) -#define COGL_TEXTURE_2D_SLICED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_TYPE_TEXTURE_2D_SLICED, CoglTexture2DSlicedClass)) -#define COGL_IS_TEXTURE_2D_SLICED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_TYPE_TEXTURE_2D_SLICED)) -#define COGL_IS_TEXTURE_2D_SLICED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_TYPE_TEXTURE_2D_SLICED)) -#define COGL_TEXTURE_2D_SLICED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COGL_TYPE_TEXTURE_2D_SLICED, CoglTexture2DSlicedClass)) - -typedef struct _CoglTexture2DSlicedClass CoglTexture2DSlicedClass; -typedef struct _CoglTexture2DSliced CoglTexture2DSliced; - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (CoglTexture2DSliced, g_object_unref) - -COGL_EXPORT -GType cogl_texture_2d_sliced_get_type (void) G_GNUC_CONST; - -/** - * cogl_texture_2d_sliced_new_with_size: - * @ctx: A #CoglContext - * @width: The virtual width of your sliced texture. - * @height: The virtual height of your sliced texture. - * @max_waste: The threshold of how wide a strip of wasted texels - * are allowed along the right and bottom textures before - * they must be sliced to reduce the amount of waste. A - * negative can be passed to disable slicing. - * - * Creates a #CoglTexture2DSliced that may internally be comprised of - * 1 or more #CoglTexture2D textures depending on GPU limitations. - * For example if the GPU only supports power-of-two sized textures - * then a sliced texture will turn a non-power-of-two size into a - * combination of smaller power-of-two sized textures. If the - * requested texture size is larger than is supported by the hardware - * then the texture will be sliced into smaller textures that can be - * accessed by the hardware. - * - * @max_waste is used as a threshold for recursively slicing the - * right-most or bottom-most slices into smaller sizes until the - * wasted padding at the bottom and right of the textures is less than - * specified. A negative @max_waste will disable slicing. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or let Cogl automatically allocate - * storage lazily. - * - * It's possible for the allocation of a sliced texture to fail - * later due to impossible slicing constraints if a negative - * @max_waste value is given. If the given virtual texture size size - * is larger than is supported by the hardware but slicing is disabled - * the texture size would be too large to handle. - * - * Returns: (transfer full): A new #CoglTexture2DSliced object with no storage - * allocated yet. - */ -COGL_EXPORT CoglTexture * -cogl_texture_2d_sliced_new_with_size (CoglContext *ctx, - int width, - int height, - int max_waste); - -/** - * cogl_texture_2d_sliced_new_from_data: - * @ctx: A #CoglContext - * @width: width of texture in pixels - * @height: height of texture in pixels - * @format: the #CoglPixelFormat the buffer is stored in in RAM - * @max_waste: The threshold of how wide a strip of wasted texels - * are allowed along the right and bottom textures before - * they must be sliced to reduce the amount of waste. A - * negative can be passed to disable slicing. - * @rowstride: the memory offset in bytes between the start of each - * row in @data. A value of 0 will make Cogl automatically - * calculate @rowstride from @width and @format. - * @data: (array): pointer the memory region where the source buffer resides - * @error: A #GError to catch exceptional errors or %NULL - * - * Creates a new #CoglTexture2DSliced texture based on data residing - * in memory. - * - * A #CoglTexture2DSliced may internally be comprised of 1 or more - * #CoglTexture2D textures depending on GPU limitations. For example - * if the GPU only supports power-of-two sized textures then a sliced - * texture will turn a non-power-of-two size into a combination of - * smaller power-of-two sized textures. If the requested texture size - * is larger than is supported by the hardware then the texture will - * be sliced into smaller textures that can be accessed by the - * hardware. - * - * @max_waste is used as a threshold for recursively slicing the - * right-most or bottom-most slices into smaller sizes until the - * wasted padding at the bottom and right of the textures is less than - * specified. A negative @max_waste will disable slicing. - * - * This api will always immediately allocate GPU memory for all - * the required texture slices and upload the given data so that the - * @data pointer does not need to remain valid once this function - * returns. This means it is not possible to configure the texture - * before it is allocated. If you do need to configure the texture - * before allocation (to specify constraints on the internal format - * for example) then you can instead create a #CoglBitmap for your - * data and use cogl_texture_2d_sliced_new_from_bitmap() or use - * cogl_texture_2d_sliced_new_with_size() and then upload data using - * cogl_texture_set_data() - * - * It's possible for the allocation of a sliced texture to fail - * due to impossible slicing constraints if a negative @max_waste - * value is given. If the given virtual texture size is larger than is - * supported by the hardware but slicing is disabled the texture size - * would be too large to handle. - * - * Return value: (transfer full): A newly created #CoglTexture2DSliced - * or %NULL on failure and @error will be updated. - */ -COGL_EXPORT CoglTexture * -cogl_texture_2d_sliced_new_from_data (CoglContext *ctx, - int width, - int height, - int max_waste, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - GError **error); - -/** - * cogl_texture_2d_sliced_new_from_bitmap: - * @bmp: A #CoglBitmap - * @max_waste: The threshold of how wide a strip of wasted texels - * are allowed along the right and bottom textures before - * they must be sliced to reduce the amount of waste. A - * negative can be passed to disable slicing. - * - * Creates a new #CoglTexture2DSliced texture based on data residing - * in a bitmap. - * - * A #CoglTexture2DSliced may internally be comprised of 1 or more - * #CoglTexture2D textures depending on GPU limitations. For example - * if the GPU only supports power-of-two sized textures then a sliced - * texture will turn a non-power-of-two size into a combination of - * smaller power-of-two sized textures. If the requested texture size - * is larger than is supported by the hardware then the texture will - * be sliced into smaller textures that can be accessed by the - * hardware. - * - * @max_waste is used as a threshold for recursively slicing the - * right-most or bottom-most slices into smaller sizes until the - * wasted padding at the bottom and right of the textures is less than - * specified. A negative @max_waste will disable slicing. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or let Cogl automatically allocate - * storage lazily. - * - * It's possible for the allocation of a sliced texture to fail - * later due to impossible slicing constraints if a negative - * @max_waste value is given. If the given virtual texture size is - * larger than is supported by the hardware but slicing is disabled - * the texture size would be too large to handle. - * - * Return value: (transfer full): A newly created #CoglTexture2DSliced - * or %NULL on failure and @error will be updated. - */ -COGL_EXPORT CoglTexture * -cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, - int max_waste); diff --git a/mutter/cogl/cogl/cogl-texture-2d.c b/mutter/cogl/cogl/cogl-texture-2d.c deleted file mode 100644 index b58e9da..0000000 --- a/mutter/cogl/cogl/cogl-texture-2d.c +++ /dev/null @@ -1,505 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#include "config.h" - -#include "cogl/cogl-private.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-texture-2d-private.h" -#include "cogl/cogl-texture-driver.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-journal-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/driver/gl/cogl-texture-2d-gl-private.h" -#ifdef HAVE_EGL -#include "cogl/winsys/cogl-winsys-egl-private.h" -#endif - -#include -#include - -G_DEFINE_FINAL_TYPE (CoglTexture2D, cogl_texture_2d, COGL_TYPE_TEXTURE) - - -static void -cogl_texture_2d_dispose (GObject *object) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (object); - CoglContext *ctx = cogl_texture_get_context (COGL_TEXTURE (tex_2d)); - - ctx->driver_vtable->texture_2d_free (tex_2d); - - G_OBJECT_CLASS (cogl_texture_2d_parent_class)->dispose (object); -} - -void -_cogl_texture_2d_set_auto_mipmap (CoglTexture *tex, - gboolean value) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - - tex_2d->auto_mipmap = value; -} - -CoglTexture * -_cogl_texture_2d_create_base (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format, - CoglTextureLoader *loader) -{ - CoglTexture2D *tex_2d = g_object_new (COGL_TYPE_TEXTURE_2D, - "context", ctx, - "width", width, - "height", height, - "loader", loader, - "format", internal_format, - NULL); - tex_2d->mipmaps_dirty = TRUE; - tex_2d->auto_mipmap = TRUE; - tex_2d->is_get_data_supported = TRUE; - - tex_2d->gl_target = GL_TEXTURE_2D; - - ctx->driver_vtable->texture_2d_init (tex_2d); - - return COGL_TEXTURE (tex_2d); -} - -static gboolean -_cogl_texture_2d_allocate (CoglTexture *tex, - GError **error) -{ - CoglContext *ctx = cogl_texture_get_context (tex); - - return ctx->driver_vtable->texture_2d_allocate (tex, error); -} - -void -_cogl_texture_2d_copy_from_framebuffer (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglFramebuffer *src_fb, - int dst_x, - int dst_y, - int level) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2d); - CoglContext *ctx = cogl_texture_get_context (tex); - - /* Assert that the storage for this texture has been allocated */ - cogl_texture_allocate (tex, NULL); /* (abort on error) */ - - ctx->driver_vtable->texture_2d_copy_from_framebuffer (tex_2d, - src_x, - src_y, - width, - height, - src_fb, - dst_x, - dst_y, - level); - - tex_2d->mipmaps_dirty = TRUE; -} - -static int -_cogl_texture_2d_get_max_waste (CoglTexture *tex) -{ - return -1; -} - -static gboolean -_cogl_texture_2d_is_sliced (CoglTexture *tex) -{ - return FALSE; -} - -static gboolean -_cogl_texture_2d_can_hardware_repeat (CoglTexture *tex) -{ - return TRUE; -} - -static void -_cogl_texture_2d_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - /* The texture coordinates map directly so we don't need to do - anything */ -} - -static CoglTransformResult -_cogl_texture_2d_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - /* The texture coordinates map directly so we don't need to do - anything other than check for repeats */ - - int i; - - for (i = 0; i < 4; i++) - if (coords[i] < 0.0f || coords[i] > 1.0f) - { - /* Repeat is needed */ - return (_cogl_texture_2d_can_hardware_repeat (tex) ? - COGL_TRANSFORM_HARDWARE_REPEAT : - COGL_TRANSFORM_SOFTWARE_REPEAT); - } - - /* No repeat is needed */ - return COGL_TRANSFORM_NO_REPEAT; -} - -static gboolean -_cogl_texture_2d_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglContext *ctx = cogl_texture_get_context (tex); - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - - if (ctx->driver_vtable->texture_2d_get_gl_handle) - { - GLuint handle; - - if (out_gl_target) - *out_gl_target = tex_2d->gl_target; - - handle = ctx->driver_vtable->texture_2d_get_gl_handle (tex_2d); - - if (out_gl_handle) - *out_gl_handle = handle; - - return handle ? TRUE : FALSE; - } - else - return FALSE; -} - -static void -_cogl_texture_2d_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - - /* Only update if the mipmaps are dirty */ - if ((flags & COGL_TEXTURE_NEEDS_MIPMAP) && - tex_2d->auto_mipmap && tex_2d->mipmaps_dirty) - { - CoglContext *ctx = cogl_texture_get_context (tex); - - /* Since we are about to ask the GPU to generate mipmaps of tex, we - * better make sure tex is up-to-date. - */ - _cogl_texture_flush_journal_rendering (tex); - - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_QUIRK_GENERATE_MIPMAP_NEEDS_FLUSH) && - _cogl_texture_get_associated_framebuffers (tex)) - ctx->glFlush (); - - ctx->driver_vtable->texture_2d_generate_mipmap (tex_2d); - - tex_2d->mipmaps_dirty = FALSE; - } -} - -static void -_cogl_texture_2d_ensure_non_quad_rendering (CoglTexture *tex) -{ - /* Nothing needs to be done */ -} - -static gboolean -_cogl_texture_2d_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - int level, - CoglBitmap *bmp, - GError **error) -{ - CoglContext *ctx = cogl_texture_get_context (tex); - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - - if (!ctx->driver_vtable->texture_2d_copy_from_bitmap (tex_2d, - src_x, - src_y, - width, - height, - bmp, - dst_x, - dst_y, - level, - error)) - { - return FALSE; - } - - tex_2d->mipmaps_dirty = TRUE; - - return TRUE; -} - -static gboolean -_cogl_texture_2d_is_get_data_supported (CoglTexture *tex) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - CoglContext *ctx = cogl_texture_get_context (tex); - - return ctx->driver_vtable->texture_2d_is_get_data_supported (tex_2d); -} - -static gboolean -_cogl_texture_2d_get_data (CoglTexture *tex, - CoglPixelFormat format, - int rowstride, - uint8_t *data) -{ - CoglContext *ctx = cogl_texture_get_context (tex); - - if (ctx->driver_vtable->texture_2d_get_data) - { - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - ctx->driver_vtable->texture_2d_get_data (tex_2d, format, rowstride, data); - return TRUE; - } - else - return FALSE; -} - -static CoglPixelFormat -_cogl_texture_2d_get_format (CoglTexture *tex) -{ - return COGL_TEXTURE_2D (tex)->internal_format; -} - -static GLenum -_cogl_texture_2d_get_gl_format (CoglTexture *tex) -{ - return COGL_TEXTURE_2D (tex)->gl_internal_format; -} - -static void -cogl_texture_2d_class_init (CoglTexture2DClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - CoglTextureClass *texture_class = COGL_TEXTURE_CLASS (klass); - - gobject_class->dispose = cogl_texture_2d_dispose; - - texture_class->allocate = _cogl_texture_2d_allocate; - texture_class->set_region = _cogl_texture_2d_set_region; - texture_class->is_get_data_supported = _cogl_texture_2d_is_get_data_supported; - texture_class->get_data = _cogl_texture_2d_get_data; - texture_class->get_max_waste = _cogl_texture_2d_get_max_waste; - texture_class->is_sliced = _cogl_texture_2d_is_sliced; - texture_class->can_hardware_repeat = _cogl_texture_2d_can_hardware_repeat; - texture_class->transform_coords_to_gl = _cogl_texture_2d_transform_coords_to_gl; - texture_class->transform_quad_coords_to_gl = _cogl_texture_2d_transform_quad_coords_to_gl; - texture_class->get_gl_texture = _cogl_texture_2d_get_gl_texture; - texture_class->gl_flush_legacy_texobj_filters = _cogl_texture_2d_gl_flush_legacy_texobj_filters; - texture_class->pre_paint = _cogl_texture_2d_pre_paint; - texture_class->ensure_non_quad_rendering = _cogl_texture_2d_ensure_non_quad_rendering; - texture_class->gl_flush_legacy_texobj_wrap_modes = _cogl_texture_2d_gl_flush_legacy_texobj_wrap_modes; - texture_class->get_format = _cogl_texture_2d_get_format; - texture_class->get_gl_format = _cogl_texture_2d_get_gl_format; - texture_class->set_auto_mipmap = _cogl_texture_2d_set_auto_mipmap; -} - -static void -cogl_texture_2d_init (CoglTexture2D *self) -{ - CoglTexture *texture = COGL_TEXTURE (self); - - texture->is_primitive = TRUE; -} - -CoglTexture * -cogl_texture_2d_new_with_format (CoglContext *ctx, - int width, - int height, - CoglPixelFormat format) -{ - CoglTextureLoader *loader; - - g_return_val_if_fail (width >= 1, NULL); - g_return_val_if_fail (height >= 1, NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_SIZE; - loader->src.sized.width = width; - loader->src.sized.height = height; - loader->src.sized.format = format; - - return _cogl_texture_2d_create_base (ctx, width, height, format, loader); -} - -CoglTexture * -cogl_texture_2d_new_with_size (CoglContext *ctx, - int width, - int height) -{ - CoglTextureLoader *loader; - - g_return_val_if_fail (width >= 1, NULL); - g_return_val_if_fail (height >= 1, NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_SIZE; - loader->src.sized.width = width; - loader->src.sized.height = height; - loader->src.sized.format = COGL_PIXEL_FORMAT_ANY; - - return _cogl_texture_2d_create_base (ctx, width, height, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, loader); -} - -CoglTexture * -cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp) -{ - CoglTextureLoader *loader; - - g_return_val_if_fail (bmp != NULL, NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_BITMAP; - loader->src.bitmap.bitmap = g_object_ref (bmp); - - return _cogl_texture_2d_create_base (_cogl_bitmap_get_context (bmp), - cogl_bitmap_get_width (bmp), - cogl_bitmap_get_height (bmp), - cogl_bitmap_get_format (bmp), - loader); -} - -CoglTexture * -cogl_texture_2d_new_from_data (CoglContext *ctx, - int width, - int height, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - GError **error) -{ - CoglBitmap *bmp; - CoglTexture *tex_2d; - - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); - g_return_val_if_fail (data != NULL, NULL); - - /* Rowstride from width if not given */ - if (rowstride == 0) - rowstride = width * cogl_pixel_format_get_bytes_per_pixel (format, 0); - - /* Wrap the data into a bitmap */ - bmp = cogl_bitmap_new_for_data (ctx, - width, height, - format, - rowstride, - (uint8_t *) data); - - tex_2d = cogl_texture_2d_new_from_bitmap (bmp); - - g_object_unref (bmp); - - if (tex_2d && - !cogl_texture_allocate (COGL_TEXTURE (tex_2d), error)) - { - g_object_unref (tex_2d); - return NULL; - } - - return tex_2d; -} - -#if defined (HAVE_EGL) && defined (EGL_KHR_image_base) -/* NB: The reason we require the width, height and format to be passed - * even though they may seem redundant is because GLES 1/2 don't - * provide a way to query these properties. */ -CoglTexture * -cogl_egl_texture_2d_new_from_image (CoglContext *ctx, - int width, - int height, - CoglPixelFormat format, - EGLImageKHR image, - CoglEglImageFlags flags, - GError **error) -{ - CoglTextureLoader *loader; - CoglTexture *tex; - - g_return_val_if_fail (_cogl_context_get_winsys (ctx)->constraints & - COGL_RENDERER_CONSTRAINT_USES_EGL, - NULL); - - g_return_val_if_fail (_cogl_has_private_feature - (ctx, - COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE), - NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE; - loader->src.egl_image.image = image; - loader->src.egl_image.width = width; - loader->src.egl_image.height = height; - loader->src.egl_image.format = format; - loader->src.egl_image.flags = flags; - - tex = _cogl_texture_2d_create_base (ctx, width, height, format, loader); - - if (!cogl_texture_allocate (COGL_TEXTURE (tex), error)) - { - g_object_unref (tex); - return NULL; - } - - return tex; -} -#endif /* defined (HAVE_EGL) && defined (EGL_KHR_image_base) */ - -void -_cogl_texture_2d_externally_modified (CoglTexture *texture) -{ - if (!COGL_IS_TEXTURE_2D (texture)) - return; - - COGL_TEXTURE_2D (texture)->mipmaps_dirty = TRUE; -} diff --git a/mutter/cogl/cogl/cogl-texture-2d.h b/mutter/cogl/cogl/cogl-texture-2d.h deleted file mode 100644 index 27797e6..0000000 --- a/mutter/cogl/cogl/cogl-texture-2d.h +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-context.h" -#include "cogl/cogl-bitmap.h" - -#ifdef HAVE_EGL -#include "cogl/cogl-egl.h" -#endif - -G_BEGIN_DECLS - -/** - * CoglTexture2D: - * - * Functions for creating and manipulating 2D textures - * - * These functions allow low-level 2D textures to be allocated. These - * differ from sliced textures for example which may internally be - * made up of multiple 2D textures, or atlas textures where Cogl must - * internally modify user texture coordinates before they can be used - * by the GPU. - */ - -#define COGL_TYPE_TEXTURE_2D (cogl_texture_2d_get_type ()) -#define COGL_TEXTURE_2D(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_TEXTURE_2D, CoglTexture2D)) -#define COGL_TEXTURE_2D_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_TEXTURE_2D, CoglTexture2D const)) -#define COGL_TEXTURE_2D_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_TYPE_TEXTURE_2D, CoglTexture2DClass)) -#define COGL_IS_TEXTURE_2D(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_TYPE_TEXTURE_2D)) -#define COGL_IS_TEXTURE_2D_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_TYPE_TEXTURE_2D)) -#define COGL_TEXTURE_2D_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COGL_TYPE_TEXTURE_2D, CoglTexture2DClass)) - -typedef struct _CoglTexture2DClass CoglTexture2DClass; -typedef struct _CoglTexture2D CoglTexture2D; - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (CoglTexture2D, g_object_unref) - -COGL_EXPORT -GType cogl_texture_2d_get_type (void) G_GNUC_CONST; - -typedef enum _CoglEglImageFlags -{ - COGL_EGL_IMAGE_FLAG_NONE = 0, - COGL_EGL_IMAGE_FLAG_NO_GET_DATA = 1 << 0, -} CoglEglImageFlags; - -/** - * cogl_texture_2d_new_with_format: - * @ctx: A #CoglContext - * @width: Width of the texture to allocate - * @height: Height of the texture to allocate - * @format: format of the texture to allocate - * - * Creates a low-level #CoglTexture2D texture with a given @width and - * @height that your GPU can texture from directly. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or preferably let Cogl - * automatically allocate storage lazily when it may know more about - * how the texture is being used and can optimize how it is allocated. - * - * The texture is still configurable until it has been allocated so - * for example you can influence the internal format of the texture - * using cogl_texture_set_components() and - * cogl_texture_set_premultiplied(). - * - * Returns: (transfer full): A new #CoglTexture2D object with no storage yet allocated. - * - * Since: 2.0 - */ -COGL_EXPORT CoglTexture * -cogl_texture_2d_new_with_format (CoglContext *ctx, - int width, - int height, - CoglPixelFormat format); - -/** - * cogl_texture_2d_new_with_size: - * @ctx: A #CoglContext - * @width: Width of the texture to allocate - * @height: Height of the texture to allocate - * - * Creates a low-level #CoglTexture2D texture with a given @width and - * @height that your GPU can texture from directly. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or preferably let Cogl - * automatically allocate storage lazily when it may know more about - * how the texture is being used and can optimize how it is allocated. - * - * The texture is still configurable until it has been allocated so - * for example you can influence the internal format of the texture - * using cogl_texture_set_components() and - * cogl_texture_set_premultiplied(). - * - * Returns: (transfer full): A new #CoglTexture2D object with no storage yet allocated. - */ -COGL_EXPORT CoglTexture * -cogl_texture_2d_new_with_size (CoglContext *ctx, - int width, - int height); - -/** - * cogl_texture_2d_new_from_data: - * @ctx: A #CoglContext - * @width: width of texture in pixels - * @height: height of texture in pixels - * @format: the #CoglPixelFormat the buffer is stored in in RAM - * @rowstride: the memory offset in bytes between the starts of - * scanlines in @data. A value of 0 will make Cogl automatically - * calculate @rowstride from @width and @format. - * @data: (array): pointer the memory region where the source buffer resides - * @error: A #GError for exceptions - * - * Creates a low-level #CoglTexture2D texture based on data residing - * in memory. - * - * This api will always immediately allocate GPU memory for the - * texture and upload the given data so that the @data pointer does - * not need to remain valid once this function returns. This means it - * is not possible to configure the texture before it is allocated. If - * you do need to configure the texture before allocation (to specify - * constraints on the internal format for example) then you can - * instead create a #CoglBitmap for your data and use - * cogl_texture_2d_new_from_bitmap() or use - * cogl_texture_2d_new_with_size() and then upload data using - * cogl_texture_set_data() - * - * Returns: (transfer full): A newly allocated #CoglTexture2D, or if - * the size is not supported (because it is too large or a - * non-power-of-two size that the hardware doesn't support) - * it will return %NULL and set @error. - */ -COGL_EXPORT CoglTexture * -cogl_texture_2d_new_from_data (CoglContext *ctx, - int width, - int height, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - GError **error); - -/** - * cogl_texture_2d_new_from_bitmap: - * @bitmap: A #CoglBitmap - * - * Creates a low-level #CoglTexture2D texture based on data residing - * in a #CoglBitmap. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or preferably let Cogl - * automatically allocate storage lazily when it may know more about - * how the texture is being used and can optimize how it is allocated. - * - * The texture is still configurable until it has been allocated so - * for example you can influence the internal format of the texture - * using cogl_texture_set_components() and - * cogl_texture_set_premultiplied(). - * - * Returns: (transfer full): A newly allocated #CoglTexture2D - */ -COGL_EXPORT CoglTexture * -cogl_texture_2d_new_from_bitmap (CoglBitmap *bitmap); - -/** - * cogl_egl_texture_2d_new_from_image: (skip) - */ -#if defined (HAVE_EGL) && defined (EGL_KHR_image_base) -/* NB: The reason we require the width, height and format to be passed - * even though they may seem redundant is because GLES 1/2 don't - * provide a way to query these properties. */ -COGL_EXPORT CoglTexture * -cogl_egl_texture_2d_new_from_image (CoglContext *ctx, - int width, - int height, - CoglPixelFormat format, - EGLImageKHR image, - CoglEglImageFlags flags, - GError **error); - -typedef gboolean (*CoglTexture2DEGLImageExternalAlloc) (CoglTexture2D *tex_2d, - gpointer user_data, - GError **error); - -/** - * cogl_texture_2d_new_from_egl_image_external: (skip) - */ -COGL_EXPORT CoglTexture * -cogl_texture_2d_new_from_egl_image_external (CoglContext *ctx, - int width, - int height, - CoglTexture2DEGLImageExternalAlloc alloc, - gpointer user_data, - GDestroyNotify destroy, - GError **error); - -COGL_EXPORT void -cogl_texture_2d_egl_image_external_bind (CoglTexture2D *tex_2d); - -COGL_EXPORT void -cogl_texture_2d_egl_image_external_alloc_finish (CoglTexture2D *tex_2d, - void *user_data, - GDestroyNotify destroy); -#endif - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-texture-driver.h b/mutter/cogl/cogl/cogl-texture-driver.h deleted file mode 100644 index 1759a8b..0000000 --- a/mutter/cogl/cogl/cogl-texture-driver.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -typedef struct _CoglTextureDriver CoglTextureDriver; - -struct _CoglTextureDriver -{ - /* - * A very small wrapper around glGenTextures() that ensures we default to - * non-mipmap filters when creating textures. This is to save some memory as - * the driver will not allocate room for the mipmap tree. - */ - GLuint - (* gen) (CoglContext *ctx, - GLenum gl_target, - CoglPixelFormat internal_format); - - /* - * This uploads a sub-region from source_bmp to a single GL texture - * handle (i.e a single CoglTexture slice) - * - * It also updates the array of tex->first_pixels[slice_index] if - * dst_{x,y} == 0 - * - * The driver abstraction is in place because GLES doesn't support the pixel - * store options required to source from a subregion, so for GLES we have - * to manually create a transient source bitmap. - * - * XXX: sorry for the ridiculous number of arguments :-( - */ - gboolean - (* upload_subregion_to_gl) (CoglContext *ctx, - CoglTexture *texture, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - int level, - CoglBitmap *source_bmp, - GLuint source_gl_format, - GLuint source_gl_type, - GError **error); - - /* - * Replaces the contents of the GL texture with the entire bitmap. On - * GL this just directly calls glTexImage2D, but under GLES it needs - * to copy the bitmap if the rowstride is not a multiple of a possible - * alignment value because there is no GL_UNPACK_ROW_LENGTH - */ - gboolean - (* upload_to_gl) (CoglContext *ctx, - GLenum gl_target, - GLuint gl_handle, - CoglBitmap *source_bmp, - GLint internal_gl_format, - GLuint source_gl_format, - GLuint source_gl_type, - GError **error); - - /* - * This sets up the glPixelStore state for an download to a destination with - * the same size, and with no offset. - */ - /* NB: GLES can't download pixel data into a sub region of a larger - * destination buffer, the GL driver has a more flexible version of - * this function that it uses internally. */ - void - (* prep_gl_for_pixels_download) (CoglContext *ctx, - int image_width, - int pixels_rowstride, - int pixels_bpp); - - /* - * This driver abstraction is needed because GLES doesn't support - * glGetTexImage (). On GLES this currently just returns FALSE which - * will lead to a generic fallback path being used that simply - * renders the texture and reads it back from the framebuffer. (See - * _cogl_texture_draw_and_read () ) - */ - gboolean - (* gl_get_tex_image) (CoglContext *ctx, - GLenum gl_target, - GLenum dest_gl_format, - GLenum dest_gl_type, - uint8_t *dest); - - /* - * It may depend on the driver as to what texture sizes are supported... - */ - gboolean - (* size_supported) (CoglContext *ctx, - GLenum gl_target, - GLenum gl_intformat, - GLenum gl_format, - GLenum gl_type, - int width, - int height); - - - gboolean - (* format_supports_upload) (CoglContext *ctx, - CoglPixelFormat format); - - /* - * The driver may impose constraints on what formats can be used to store - * texture data read from textures. For example GLES currently only supports - * RGBA_8888, and so we need to manually convert the data if the final - * destination has another format. - */ - CoglPixelFormat - (* find_best_gl_get_data_format) (CoglContext *context, - CoglPixelFormat format, - GLenum *closest_gl_format, - GLenum *closest_gl_type); -}; diff --git a/mutter/cogl/cogl/cogl-texture-private.h b/mutter/cogl/cogl/cogl-texture-private.h deleted file mode 100644 index 6338a1c..0000000 --- a/mutter/cogl/cogl/cogl-texture-private.h +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-bitmap-private.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-spans.h" -#include "cogl/cogl-meta-texture.h" -#include "cogl/cogl-framebuffer.h" -#include "cogl/cogl-texture-2d.h" - -#ifdef HAVE_EGL -#include "cogl/cogl-egl.h" -#endif - -/* Encodes three possibiloities result of transforming a quad */ -typedef enum -{ - /* quad doesn't cross the boundaries of a texture */ - COGL_TRANSFORM_NO_REPEAT, - /* quad crosses boundaries, hardware wrap mode can handle */ - COGL_TRANSFORM_HARDWARE_REPEAT, - /* quad crosses boundaries, needs software fallback; - * for a sliced texture, this might not actually involve - * repeating, just a quad crossing multiple slices */ - COGL_TRANSFORM_SOFTWARE_REPEAT, -} CoglTransformResult; - -/* Flags given to the pre_paint method */ -typedef enum -{ - /* The texture is going to be used with filters that require - mipmapping. This gives the texture the opportunity to - automatically update the mipmap tree */ - COGL_TEXTURE_NEEDS_MIPMAP = 1 -} CoglTexturePrePaintFlags; - - -typedef enum _CoglTextureSourceType { - COGL_TEXTURE_SOURCE_TYPE_SIZE = 1, - COGL_TEXTURE_SOURCE_TYPE_BITMAP, - COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE, - COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE_EXTERNAL -} CoglTextureSourceType; - -typedef struct _CoglTextureLoader -{ - CoglTextureSourceType src_type; - union { - struct { - int width; - int height; - int depth; /* for 3d textures */ - CoglPixelFormat format; - } sized; - struct { - CoglBitmap *bitmap; - int height; /* for 3d textures */ - int depth; /* for 3d textures */ - } bitmap; -#if defined (HAVE_EGL) && defined (EGL_KHR_image_base) - struct { - EGLImageKHR image; - int width; - int height; - CoglPixelFormat format; - CoglEglImageFlags flags; - } egl_image; -#endif -#if defined (HAVE_EGL) - struct { - int width; - int height; - CoglTexture2DEGLImageExternalAlloc alloc; - CoglPixelFormat format; - } egl_image_external; -#endif - struct { - int width; - int height; - unsigned int gl_handle; - CoglPixelFormat format; - } gl_foreign; - } src; -} CoglTextureLoader; - -struct _CoglTexture -{ - GObject parent_instance; - - CoglContext *context; - gboolean is_primitive; - CoglTextureLoader *loader; - GList *framebuffers; - int max_level_set; - int max_level_requested; - int width; - int height; - gboolean allocated; - - /* - * Internal format - */ - CoglTextureComponents components; - unsigned int premultiplied : 1; -}; - -struct _CoglTextureClass -{ - GObjectClass parent_class; - gboolean (* allocate) (CoglTexture *tex, - GError **error); - - /* This should update the specified sub region of the texture with a - sub region of the given bitmap. The bitmap is not converted - before being set so the caller is expected to have called - _cogl_bitmap_convert_for_upload with a suitable internal_format - before passing here */ - gboolean (* set_region) (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int dst_width, - int dst_height, - int level, - CoglBitmap *bitmap, - GError **error); - - gboolean (* is_get_data_supported) (CoglTexture *texture); - - /* This should copy the image data of the texture into @data. The - requested format will have been first passed through - ctx->texture_driver->find_best_gl_get_data_format so it should - always be a format that is valid for GL (ie, no conversion should - be necessary). */ - gboolean (* get_data) (CoglTexture *tex, - CoglPixelFormat format, - int rowstride, - uint8_t *data); - - void (* foreach_sub_texture_in_region) (CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglMetaTextureCallback callback, - void *user_data); - - int (* get_max_waste) (CoglTexture *tex); - - gboolean (* is_sliced) (CoglTexture *tex); - - gboolean (* can_hardware_repeat) (CoglTexture *tex); - - void (* transform_coords_to_gl) (CoglTexture *tex, - float *s, - float *t); - CoglTransformResult (* transform_quad_coords_to_gl) (CoglTexture *tex, - float *coords); - - gboolean (* get_gl_texture) (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target); - - /* OpenGL driver specific virtual function */ - void (* gl_flush_legacy_texobj_filters) (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter); - - void (* pre_paint) (CoglTexture *tex, - CoglTexturePrePaintFlags flags); - void (* ensure_non_quad_rendering) (CoglTexture *tex); - - /* OpenGL driver specific virtual function */ - void (* gl_flush_legacy_texobj_wrap_modes) (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t); - - CoglPixelFormat (* get_format) (CoglTexture *tex); - GLenum (* get_gl_format) (CoglTexture *tex); - - /* Only needs to be implemented if is_primitive == TRUE */ - void (* set_auto_mipmap) (CoglTexture *texture, - gboolean value); -}; - -typedef enum _CoglTextureChangeFlags -{ - /* Whenever the internals of a texture are changed such that the - * underlying GL textures that represent the CoglTexture change then - * we notify cogl-material.c via - * _cogl_pipeline_texture_pre_change_notify - */ - COGL_TEXTURE_CHANGE_GL_TEXTURES - -} CoglTextureChangeFlags; - -typedef struct _CoglTexturePixel CoglTexturePixel; - -/* This is used by the texture backends to store the first pixel of - each GL texture. This is only used when glGenerateMipmap is not - available so that we can temporarily set GL_GENERATE_MIPMAP and - reupload a pixel */ -struct _CoglTexturePixel -{ - /* We need to store the format of the pixel because we store the - data in the source format which might end up being different for - each slice if a subregion is updated with a different format */ - GLenum gl_format; - GLenum gl_type; - uint8_t data[4]; -}; - -gboolean -_cogl_texture_can_hardware_repeat (CoglTexture *texture); - -void -_cogl_texture_transform_coords_to_gl (CoglTexture *texture, - float *s, - float *t); -CoglTransformResult -_cogl_texture_transform_quad_coords_to_gl (CoglTexture *texture, - float *coords); - -void -_cogl_texture_pre_paint (CoglTexture *texture, CoglTexturePrePaintFlags flags); - -void -_cogl_texture_ensure_non_quad_rendering (CoglTexture *texture); - -/* - * This determines a CoglPixelFormat according to texture::components - * and texture::premultiplied (i.e. the user required components and - * whether the texture should be considered premultiplied) - * - * A reference/source format can be given (or COGL_PIXEL_FORMAT_ANY) - * and wherever possible this function tries to simply return the - * given source format if its compatible with the required components. - * - * Texture backends can call this when allocating a texture to know - * how to convert a source image in preparation for uploading. - */ -CoglPixelFormat -_cogl_texture_determine_internal_format (CoglTexture *texture, - CoglPixelFormat src_format); - -/* This is called by texture backends when they have successfully - * allocated a texture. - * - * Most texture backends currently track the internal layout of - * textures using a CoglPixelFormat which will be finalized when a - * texture is allocated. At this point we need to update - * texture::components and texture::premultiplied according to the - * determined layout. - * - * XXX: Going forward we should probably aim to stop using - * CoglPixelFormat at all for tracking the internal layout of - * textures. - */ -void -_cogl_texture_set_internal_format (CoglTexture *texture, - CoglPixelFormat internal_format); - -void -_cogl_texture_associate_framebuffer (CoglTexture *texture, - CoglFramebuffer *framebuffer); - -const GList * -_cogl_texture_get_associated_framebuffers (CoglTexture *texture); - -void -_cogl_texture_flush_journal_rendering (CoglTexture *texture); - -void -_cogl_texture_spans_foreach_in_region (CoglSpan *x_spans, - int n_x_spans, - CoglSpan *y_spans, - int n_y_spans, - CoglTexture **textures, - float *virtual_coords, - float x_normalize_factor, - float y_normalize_factor, - CoglPipelineWrapMode wrap_x, - CoglPipelineWrapMode wrap_y, - CoglMetaTextureCallback callback, - void *user_data); - -COGL_EXPORT gboolean -_cogl_texture_set_region (CoglTexture *texture, - int width, - int height, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - int dst_x, - int dst_y, - int level, - GError **error); - -gboolean -_cogl_texture_set_region_from_bitmap (CoglTexture *texture, - int src_x, - int src_y, - int width, - int height, - CoglBitmap *bmp, - int dst_x, - int dst_y, - int level, - GError **error); - -gboolean -_cogl_texture_needs_premult_conversion (CoglPixelFormat src_format, - CoglPixelFormat dst_format); - -int -_cogl_texture_get_n_levels (CoglTexture *texture); - -void -cogl_texture_set_max_level (CoglTexture *texture, - int max_level); - -void -_cogl_texture_get_level_size (CoglTexture *texture, - int level, - int *width, - int *height, - int *depth); - -void -_cogl_texture_set_allocated (CoglTexture *texture, - CoglPixelFormat internal_format, - int width, - int height); - -COGL_EXPORT CoglPixelFormat -_cogl_texture_get_format (CoglTexture *texture); - -CoglTextureLoader * -_cogl_texture_create_loader (void); - -void -_cogl_texture_copy_internal_format (CoglTexture *src, - CoglTexture *dest); - -CoglContext * -cogl_texture_get_context (CoglTexture *texture); - -CoglTextureLoader * -cogl_texture_get_loader (CoglTexture *texture); - -int -cogl_texture_get_max_level_set (CoglTexture *texture); - -void -cogl_texture_set_max_level_set (CoglTexture *texture, - int max_level_set); diff --git a/mutter/cogl/cogl/cogl-texture.c b/mutter/cogl/cogl/cogl-texture.c deleted file mode 100644 index 32d72a3..0000000 --- a/mutter/cogl/cogl/cogl-texture.c +++ /dev/null @@ -1,1321 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * Copyright (C) 2010 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Matthew Allum - * Neil Roberts - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-util.h" -#include "cogl/cogl-bitmap.h" -#include "cogl/cogl-bitmap-private.h" -#include "cogl/cogl-buffer-private.h" -#include "cogl/cogl-enum-types.h" -#include "cogl/cogl-pixel-buffer-private.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-texture-driver.h" -#include "cogl/cogl-texture-2d-sliced-private.h" -#include "cogl/cogl-texture-2d-private.h" -#include "cogl/cogl-sub-texture-private.h" -#include "cogl/cogl-atlas-texture-private.h" -#include "cogl/cogl-pipeline.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-offscreen-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl1-context.h" -#include "cogl/cogl-sub-texture.h" -#include "cogl/cogl-primitive-texture.h" - -#include -#include -#include - -G_DEFINE_ABSTRACT_TYPE (CoglTexture, cogl_texture, G_TYPE_OBJECT) - -enum -{ - PROP_0, - - PROP_CONTEXT, - PROP_WIDTH, - PROP_HEIGHT, - PROP_LOADER, - PROP_FORMAT, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -static void -_cogl_texture_free_loader (CoglTexture *texture) -{ - if (texture->loader) - { - CoglTextureLoader *loader = texture->loader; - switch (loader->src_type) - { - case COGL_TEXTURE_SOURCE_TYPE_SIZE: - case COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE: - case COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE_EXTERNAL: - break; - case COGL_TEXTURE_SOURCE_TYPE_BITMAP: - g_object_unref (loader->src.bitmap.bitmap); - break; - } - g_free (loader); - texture->loader = NULL; - } -} - -static void -cogl_texture_dispose (GObject *object) -{ - CoglTexture *texture = COGL_TEXTURE (object); - - _cogl_texture_free_loader (texture); - - G_OBJECT_CLASS (cogl_texture_parent_class)->dispose (object); -} - -static void -cogl_texture_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - CoglTexture *texture = COGL_TEXTURE (gobject); - - switch (prop_id) - { - case PROP_CONTEXT: - texture->context = g_value_get_object (value); - break; - - case PROP_WIDTH: - texture->width = g_value_get_int (value); - break; - - case PROP_HEIGHT: - texture->height = g_value_get_int (value); - break; - - case PROP_LOADER: - texture->loader = g_value_get_pointer (value); - break; - - case PROP_FORMAT: - _cogl_texture_set_internal_format (texture, g_value_get_enum (value)); - /* Although we want to initialize texture::components according - * to the source format, we always want the internal layout to - * be considered premultiplied by default. - * - * NB: this ->premultiplied state is user configurable so to avoid - * awkward documentation, setting this to 'true' does not depend on - * ->components having an alpha component (we will simply ignore the - * premultiplied status later if there is no alpha component). - * This way we don't have to worry about updating the - * ->premultiplied state in _set_components(). Similarly we don't - * have to worry about updating the ->components state in - * _set_premultiplied(). - */ - texture->premultiplied = TRUE; - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -cogl_texture_class_init (CoglTextureClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->dispose = cogl_texture_dispose; - gobject_class->set_property = cogl_texture_set_property; - - obj_props[PROP_CONTEXT] = - g_param_spec_object ("context", NULL, NULL, - COGL_TYPE_CONTEXT, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_WIDTH] = - g_param_spec_int ("width", NULL, NULL, - -1, G_MAXINT, - -1, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_HEIGHT] = - g_param_spec_int ("height", NULL, NULL, - -1, G_MAXINT, - -1, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_LOADER] = - g_param_spec_pointer ("loader", NULL, NULL, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_FORMAT] = - g_param_spec_enum ("format", NULL, NULL, - COGL_TYPE_PIXEL_FORMAT, - COGL_PIXEL_FORMAT_ANY, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (gobject_class, - PROP_LAST, - obj_props); -} - -static void -cogl_texture_init (CoglTexture *texture) -{ - texture->max_level_set = 0; - texture->max_level_requested = 1000; /* OpenGL default GL_TEXTURE_MAX_LEVEL */ - texture->allocated = FALSE; - texture->framebuffers = NULL; -} - -uint32_t -cogl_texture_error_quark (void) -{ - return g_quark_from_static_string ("cogl-texture-error-quark"); -} - -CoglTextureLoader * -_cogl_texture_create_loader (void) -{ - return g_new0 (CoglTextureLoader, 1); -} - -gboolean -_cogl_texture_needs_premult_conversion (CoglPixelFormat src_format, - CoglPixelFormat dst_format) -{ - return ((src_format & dst_format & COGL_A_BIT) && - src_format != COGL_PIXEL_FORMAT_A_8 && - dst_format != COGL_PIXEL_FORMAT_A_8 && - (src_format & COGL_PREMULT_BIT) != - (dst_format & COGL_PREMULT_BIT)); -} - -gboolean -cogl_texture_is_get_data_supported (CoglTexture *texture) -{ - if (COGL_TEXTURE_GET_CLASS (texture)->is_get_data_supported) - return COGL_TEXTURE_GET_CLASS (texture)->is_get_data_supported (texture); - else - return TRUE; -} - -unsigned int -cogl_texture_get_width (CoglTexture *texture) -{ - g_return_val_if_fail (COGL_IS_TEXTURE (texture), 0); - - return texture->width; -} - -unsigned int -cogl_texture_get_height (CoglTexture *texture) -{ - g_return_val_if_fail (COGL_IS_TEXTURE (texture), 0); - - return texture->height; -} - -CoglPixelFormat -_cogl_texture_get_format (CoglTexture *texture) -{ - if (!texture->allocated) - cogl_texture_allocate (texture, NULL); - - return COGL_TEXTURE_GET_CLASS (texture)->get_format (texture); -} - -int -cogl_texture_get_max_waste (CoglTexture *texture) -{ - g_return_val_if_fail (COGL_IS_TEXTURE (texture), 0); - - return COGL_TEXTURE_GET_CLASS (texture)->get_max_waste (texture); -} - -int -_cogl_texture_get_n_levels (CoglTexture *texture) -{ - int width = cogl_texture_get_width (texture); - int height = cogl_texture_get_height (texture); - int max_dimension = MAX (width, height); - int n_levels = _cogl_util_fls (max_dimension); - - return MIN (n_levels, texture->max_level_requested + 1); -} - -void -cogl_texture_set_max_level (CoglTexture *texture, - int max_level) -{ - texture->max_level_requested = max_level; -} - -void -_cogl_texture_get_level_size (CoglTexture *texture, - int level, - int *width, - int *height, - int *depth) -{ - int current_width = cogl_texture_get_width (texture); - int current_height = cogl_texture_get_height (texture); - int current_depth = 0; - int i; - - /* NB: The OpenGL spec (like D3D) uses a floor() convention to - * round down the size of a mipmap level when dividing the size - * of the previous level results in a fraction... - */ - for (i = 0; i < level; i++) - { - current_width = MAX (1, current_width >> 1); - current_height = MAX (1, current_height >> 1); - current_depth = MAX (1, current_depth >> 1); - } - - if (width) - *width = current_width; - if (height) - *height = current_height; - if (depth) - *depth = current_depth; -} - -gboolean -cogl_texture_is_sliced (CoglTexture *texture) -{ - g_return_val_if_fail (COGL_IS_TEXTURE (texture), FALSE); - - if (!texture->allocated) - cogl_texture_allocate (texture, NULL); - - return COGL_TEXTURE_GET_CLASS (texture)->is_sliced (texture); -} - -/* If this returns FALSE, that implies _foreach_sub_texture_in_region - * will be needed to iterate over multiple sub textures for regions whose - * texture coordinates extend out of the range [0,1] - */ -gboolean -_cogl_texture_can_hardware_repeat (CoglTexture *texture) -{ - if (!texture->allocated) - cogl_texture_allocate (texture, NULL); - return COGL_TEXTURE_GET_CLASS (texture)->can_hardware_repeat (texture); -} - -/* NB: You can't use this with textures comprised of multiple sub textures (use - * cogl_texture_is_sliced() to check) since coordinate transformation for such - * textures will be different for each slice. */ -void -_cogl_texture_transform_coords_to_gl (CoglTexture *texture, - float *s, - float *t) -{ - COGL_TEXTURE_GET_CLASS (texture)->transform_coords_to_gl (texture, s, t); -} - -CoglTransformResult -_cogl_texture_transform_quad_coords_to_gl (CoglTexture *texture, - float *coords) -{ - return COGL_TEXTURE_GET_CLASS (texture)->transform_quad_coords_to_gl (texture, coords); -} - -gboolean -cogl_texture_get_gl_texture (CoglTexture *texture, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - g_return_val_if_fail (COGL_IS_TEXTURE (texture), FALSE); - - if (!texture->allocated) - cogl_texture_allocate (texture, NULL); - - return COGL_TEXTURE_GET_CLASS (texture)->get_gl_texture (texture, - out_gl_handle, - out_gl_target); -} - -void -_cogl_texture_pre_paint (CoglTexture *texture, CoglTexturePrePaintFlags flags) -{ - /* Assert that the storage for the texture exists already if we're - * about to reference it for painting. - * - * Note: we abort on error here since it's a bit late to do anything - * about it if we fail to allocate the texture and the app could - * have explicitly allocated the texture earlier to handle problems - * gracefully. - * - * XXX: Maybe it could even be considered a programmer error if the - * texture hasn't been allocated by this point since it implies we - * are about to paint with undefined texture contents? - */ - cogl_texture_allocate (texture, NULL); - - COGL_TEXTURE_GET_CLASS (texture)->pre_paint (texture, - flags); -} - -void -_cogl_texture_ensure_non_quad_rendering (CoglTexture *texture) -{ - COGL_TEXTURE_GET_CLASS (texture)->ensure_non_quad_rendering (texture); -} - -gboolean -_cogl_texture_set_region_from_bitmap (CoglTexture *texture, - int src_x, - int src_y, - int width, - int height, - CoglBitmap *bmp, - int dst_x, - int dst_y, - int level, - GError **error) -{ - g_return_val_if_fail (cogl_bitmap_get_width (bmp) - src_x >= width, FALSE); - g_return_val_if_fail (cogl_bitmap_get_height (bmp) - src_y >= height, FALSE); - g_return_val_if_fail (width > 0, FALSE); - g_return_val_if_fail (height > 0, FALSE); - - /* Assert that the storage for this texture has been allocated */ - if (!cogl_texture_allocate (texture, error)) - return FALSE; - - /* Note that we don't prepare the bitmap for upload here because - some backends may be internally using a different format for the - actual GL texture than that reported by - _cogl_texture_get_format. For example the atlas textures are - always stored in an RGBA texture even if the texture format is - advertised as RGB. */ - - return COGL_TEXTURE_GET_CLASS (texture)->set_region (texture, - src_x, src_y, - dst_x, dst_y, - width, height, - level, - bmp, - error); -} - -gboolean -cogl_texture_set_region_from_bitmap (CoglTexture *texture, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - CoglBitmap *bitmap) -{ - GError *ignore_error = NULL; - gboolean status; - - g_return_val_if_fail (COGL_IS_TEXTURE (texture), FALSE); - - status = _cogl_texture_set_region_from_bitmap (texture, - src_x, src_y, - dst_width, dst_height, - bitmap, - dst_x, dst_y, - 0, /* level */ - &ignore_error); - - g_clear_error (&ignore_error); - return status; -} - -gboolean -_cogl_texture_set_region (CoglTexture *texture, - int width, - int height, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - int dst_x, - int dst_y, - int level, - GError **error) -{ - CoglContext *ctx = cogl_texture_get_context (texture); - CoglBitmap *source_bmp; - gboolean ret; - - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); - - /* Rowstride from width if none specified */ - if (rowstride == 0) - rowstride = cogl_pixel_format_get_bytes_per_pixel (format, 0) * width; - - /* Init source bitmap */ - source_bmp = cogl_bitmap_new_for_data (ctx, - width, height, - format, - rowstride, - (uint8_t *) data); - - ret = _cogl_texture_set_region_from_bitmap (texture, - 0, 0, - width, height, - source_bmp, - dst_x, dst_y, - level, - error); - - g_object_unref (source_bmp); - - return ret; -} - -gboolean -cogl_texture_set_region (CoglTexture *texture, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - int width, - int height, - CoglPixelFormat format, - unsigned int rowstride, - const uint8_t *data) -{ - GError *ignore_error = NULL; - const uint8_t *first_pixel; - int bytes_per_pixel; - gboolean status; - - g_return_val_if_fail (COGL_IS_TEXTURE (texture), FALSE); - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); - - /* Rowstride from width if none specified */ - bytes_per_pixel = cogl_pixel_format_get_bytes_per_pixel (format, 0); - if (rowstride == 0) - rowstride = bytes_per_pixel * width; - - first_pixel = data + rowstride * src_y + bytes_per_pixel * src_x; - - status = _cogl_texture_set_region (texture, - dst_width, - dst_height, - format, - rowstride, - first_pixel, - dst_x, - dst_y, - 0, - &ignore_error); - g_clear_error (&ignore_error); - return status; -} - -gboolean -cogl_texture_set_data (CoglTexture *texture, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - int level, - GError **error) -{ - int level_width; - int level_height; - - g_return_val_if_fail (COGL_IS_TEXTURE (texture), FALSE); - - _cogl_texture_get_level_size (texture, - level, - &level_width, - &level_height, - NULL); - - return _cogl_texture_set_region (texture, - level_width, - level_height, - format, - rowstride, - data, - 0, 0, /* dest x, y */ - level, - error); -} - -static gboolean -get_texture_bits_via_offscreen (CoglTexture *meta_texture, - CoglTexture *sub_texture, - int x, - int y, - int width, - int height, - uint8_t *dst_bits, - unsigned int dst_rowstride, - CoglPixelFormat closest_format) -{ - CoglContext *ctx = cogl_texture_get_context (sub_texture); - CoglOffscreen *offscreen; - CoglFramebuffer *framebuffer; - CoglBitmap *bitmap; - gboolean ret; - GError *ignore_error = NULL; - CoglPixelFormat real_format; - - offscreen = _cogl_offscreen_new_with_texture_full - (sub_texture, - COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, - 0); - - framebuffer = COGL_FRAMEBUFFER (offscreen); - if (!cogl_framebuffer_allocate (framebuffer, &ignore_error)) - { - g_error_free (ignore_error); - return FALSE; - } - - /* Currently the framebuffer's internal format corresponds to the - * internal format of @sub_texture but in the case of atlas textures - * it's possible that this format doesn't reflect the correct - * premultiplied alpha status or what components are valid since - * atlas textures are always stored in a shared texture with a - * format of _RGBA_8888. - * - * Here we override the internal format to make sure the - * framebuffer's internal format matches the internal format of the - * parent meta_texture instead. - */ - real_format = _cogl_texture_get_format (meta_texture); - _cogl_framebuffer_set_internal_format (framebuffer, real_format); - - bitmap = cogl_bitmap_new_for_data (ctx, - width, height, - closest_format, - dst_rowstride, - dst_bits); - ret = _cogl_framebuffer_read_pixels_into_bitmap (framebuffer, - x, y, - COGL_READ_PIXELS_COLOR_BUFFER, - bitmap, - &ignore_error); - - g_clear_error (&ignore_error); - - g_object_unref (bitmap); - - g_object_unref (framebuffer); - - return ret; -} - -static gboolean -get_texture_bits_via_copy (CoglTexture *texture, - int x, - int y, - int width, - int height, - uint8_t *dst_bits, - unsigned int dst_rowstride, - CoglPixelFormat dst_format) -{ - unsigned int full_rowstride; - uint8_t *full_bits; - gboolean ret = TRUE; - int bpp; - int full_tex_width, full_tex_height; - - g_return_val_if_fail (dst_format != COGL_PIXEL_FORMAT_ANY, FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (dst_format) == 1, FALSE); - - full_tex_width = cogl_texture_get_width (texture); - full_tex_height = cogl_texture_get_height (texture); - - bpp = cogl_pixel_format_get_bytes_per_pixel (dst_format, 0); - - full_rowstride = bpp * full_tex_width; - full_bits = g_malloc (full_rowstride * full_tex_height); - - if (COGL_TEXTURE_GET_CLASS (texture)->get_data (texture, - dst_format, - full_rowstride, - full_bits)) - { - uint8_t *dst = dst_bits; - uint8_t *src = full_bits + x * bpp + y * full_rowstride; - int i; - - for (i = 0; i < height; i++) - { - memcpy (dst, src, bpp * width); - dst += dst_rowstride; - src += full_rowstride; - } - } - else - ret = FALSE; - - g_free (full_bits); - - return ret; -} - -typedef struct -{ - CoglTexture *meta_texture; - int orig_width; - int orig_height; - CoglBitmap *target_bmp; - uint8_t *target_bits; - gboolean success; - GError *error; -} CoglTextureGetData; - -static void -texture_get_cb (CoglTexture *subtexture, - const float *subtexture_coords, - const float *virtual_coords, - void *user_data) -{ - CoglTextureGetData *tg_data = user_data; - CoglTexture *meta_texture = tg_data->meta_texture; - CoglPixelFormat closest_format = cogl_bitmap_get_format (tg_data->target_bmp); - /* We already asserted that we have a single plane format */ - int bpp = cogl_pixel_format_get_bytes_per_pixel (closest_format, 0); - unsigned int rowstride = cogl_bitmap_get_rowstride (tg_data->target_bmp); - int subtexture_width = cogl_texture_get_width (subtexture); - int subtexture_height = cogl_texture_get_height (subtexture); - - int x_in_subtexture = (int) (0.5 + subtexture_width * subtexture_coords[0]); - int y_in_subtexture = (int) (0.5 + subtexture_height * subtexture_coords[1]); - int width = ((int) (0.5 + subtexture_width * subtexture_coords[2]) - - x_in_subtexture); - int height = ((int) (0.5 + subtexture_height * subtexture_coords[3]) - - y_in_subtexture); - int x_in_bitmap = (int) (0.5 + tg_data->orig_width * virtual_coords[0]); - int y_in_bitmap = (int) (0.5 + tg_data->orig_height * virtual_coords[1]); - - uint8_t *dst_bits; - - if (!tg_data->success) - return; - - dst_bits = tg_data->target_bits + x_in_bitmap * bpp + y_in_bitmap * rowstride; - - /* If we can read everything as a single slice, then go ahead and do that - * to avoid allocating an FBO. We'll leave it up to the GL implementation to - * do glGetTexImage as efficiently as possible. (GLES doesn't have that, - * so we'll fall through) - */ - if (x_in_subtexture == 0 && y_in_subtexture == 0 && - width == subtexture_width && height == subtexture_height) - { - if (COGL_TEXTURE_GET_CLASS (subtexture)->get_data (subtexture, - closest_format, - rowstride, - dst_bits)) - return; - } - - /* Next best option is a FBO and glReadPixels */ - if (get_texture_bits_via_offscreen (meta_texture, - subtexture, - x_in_subtexture, y_in_subtexture, - width, height, - dst_bits, - rowstride, - closest_format)) - return; - - /* Getting ugly: read the entire texture, copy out the part we want */ - if (get_texture_bits_via_copy (subtexture, - x_in_subtexture, y_in_subtexture, - width, height, - dst_bits, - rowstride, - closest_format)) - return; - - /* No luck, the caller will fall back to the draw-to-backbuffer and - * read implementation */ - tg_data->success = FALSE; -} - -int -cogl_texture_get_data (CoglTexture *texture, - CoglPixelFormat format, - unsigned int rowstride, - uint8_t *data) -{ - CoglContext *ctx; - int bpp; - int byte_size; - CoglPixelFormat closest_format; - GLenum closest_gl_format; - GLenum closest_gl_type; - CoglBitmap *target_bmp; - int tex_width; - int tex_height; - CoglPixelFormat texture_format; - GError *ignore_error = NULL; - CoglTextureGetData tg_data; - - g_return_val_if_fail (COGL_IS_TEXTURE (texture), 0); - - texture_format = _cogl_texture_get_format (texture); - - /* Default to internal format if none specified */ - if (format == COGL_PIXEL_FORMAT_ANY) - format = texture_format; - - /* We only support single plane formats */ - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, 0); - - tex_width = cogl_texture_get_width (texture); - tex_height = cogl_texture_get_height (texture); - - /* Rowstride from texture width if none specified */ - bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); - if (rowstride == 0) - rowstride = tex_width * bpp; - - /* Return byte size if only that requested */ - byte_size = tex_height * rowstride; - if (data == NULL) - return byte_size; - - ctx = cogl_texture_get_context (texture); - closest_format = - ctx->texture_driver->find_best_gl_get_data_format (ctx, - format, - &closest_gl_format, - &closest_gl_type); - - /* We can assume that whatever data GL gives us will have the - premult status of the original texture */ - if (COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (closest_format)) - closest_format = ((closest_format & ~COGL_PREMULT_BIT) | - (texture_format & COGL_PREMULT_BIT)); - - /* If the application is requesting a conversion from a - * component-alpha texture and the driver doesn't support them - * natively then we can only read into an alpha-format buffer. In - * this case the driver will be faking the alpha textures with a - * red-component texture and it won't swizzle to the correct format - * while reading */ - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES)) - { - if (texture_format == COGL_PIXEL_FORMAT_A_8) - { - closest_format = COGL_PIXEL_FORMAT_A_8; - } - else if (format == COGL_PIXEL_FORMAT_A_8) - { - /* If we are converting to a component-alpha texture then we - * need to read all of the components to a temporary buffer - * because there is no way to get just the 4th component. - * Note: it doesn't matter whether the texture is - * pre-multiplied here because we're only going to look at - * the alpha component */ - closest_format = COGL_PIXEL_FORMAT_RGBA_8888; - } - } - - /* Is the requested format supported? */ - if (closest_format == format) - /* Target user data directly */ - target_bmp = cogl_bitmap_new_for_data (ctx, - tex_width, - tex_height, - format, - rowstride, - data); - else - { - target_bmp = _cogl_bitmap_new_with_malloc_buffer (ctx, - tex_width, tex_height, - closest_format, - &ignore_error); - if (!target_bmp) - { - g_error_free (ignore_error); - return 0; - } - } - - tg_data.target_bits = _cogl_bitmap_map (target_bmp, COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD, - &ignore_error); - if (tg_data.target_bits) - { - tg_data.meta_texture = texture; - tg_data.orig_width = tex_width; - tg_data.orig_height = tex_height; - tg_data.target_bmp = target_bmp; - tg_data.error = NULL; - tg_data.success = TRUE; - - /* If there are any dependent framebuffers on the texture then we - need to flush their journals so the texture contents will be - up-to-date */ - _cogl_texture_flush_journal_rendering (texture); - - /* Iterating through the subtextures allows piecing together - * the data for a sliced texture, and allows us to do the - * read-from-framebuffer logic here in a simple fashion rather than - * passing offsets down through the code. */ - cogl_meta_texture_foreach_in_region (texture, - 0, 0, 1, 1, - COGL_PIPELINE_WRAP_MODE_REPEAT, - COGL_PIPELINE_WRAP_MODE_REPEAT, - texture_get_cb, - &tg_data); - - _cogl_bitmap_unmap (target_bmp); - } - else - { - g_error_free (ignore_error); - tg_data.success = FALSE; - } - - /* XXX: In some cases this api may fail to read back the texture - * data; such as for GLES which doesn't support glGetTexImage - */ - if (!tg_data.success) - { - g_object_unref (target_bmp); - return 0; - } - - /* Was intermediate used? */ - if (closest_format != format) - { - CoglBitmap *new_bmp; - gboolean result; - GError *error = NULL; - - /* Convert to requested format directly into the user's buffer */ - new_bmp = cogl_bitmap_new_for_data (ctx, - tex_width, tex_height, - format, - rowstride, - data); - result = _cogl_bitmap_convert_into_bitmap (target_bmp, new_bmp, &error); - - if (!result) - { - g_error_free (error); - /* Return failure after cleaning up */ - byte_size = 0; - } - - g_object_unref (new_bmp); - } - - g_object_unref (target_bmp); - - return byte_size; -} - -static void -on_framebuffer_destroy (CoglFramebuffer *framebuffer, - CoglTexture *texture) -{ - texture->framebuffers = g_list_remove (texture->framebuffers, framebuffer); -} - -void -_cogl_texture_associate_framebuffer (CoglTexture *texture, - CoglFramebuffer *framebuffer) -{ - /* Note: we don't take a reference on the framebuffer here because - * that would introduce a circular reference. */ - texture->framebuffers = g_list_prepend (texture->framebuffers, framebuffer); - - g_signal_connect (framebuffer, "destroy", - G_CALLBACK (on_framebuffer_destroy), - texture); -} - -const GList * -_cogl_texture_get_associated_framebuffers (CoglTexture *texture) -{ - return texture->framebuffers; -} - -void -_cogl_texture_flush_journal_rendering (CoglTexture *texture) -{ - const GList *l; - - /* It could be that a referenced texture is part of a framebuffer - * which has an associated journal that must be flushed before it - * can be sampled from by the current primitive... */ - for (l = _cogl_texture_get_associated_framebuffers (texture); l; l = l->next) - _cogl_framebuffer_flush_journal (l->data); -} - -/* This function lets you define a meta texture as a grid of textures - * whereby the x and y grid-lines are defined by an array of - * CoglSpans. With that grid based description this function can then - * iterate all the cells of the grid that lye within a region - * specified as virtual, meta-texture, coordinates. This function can - * also cope with regions that extend beyond the original meta-texture - * grid by iterating cells repeatedly according to the wrap_x/y - * arguments. - * - * To differentiate between texture coordinates of a specific, real, - * slice texture and the texture coordinates of a composite, meta - * texture, the coordinates of the meta texture are called "virtual" - * coordinates and the coordinates of spans are called "slice" - * coordinates. - * - * Note: no guarantee is given about the order in which the slices - * will be visited. - * - * Note: The slice coordinates passed to @callback are always - * normalized coordinates even if the span coordinates aren't - * normalized. - */ -void -_cogl_texture_spans_foreach_in_region (CoglSpan *x_spans, - int n_x_spans, - CoglSpan *y_spans, - int n_y_spans, - CoglTexture **textures, - float *virtual_coords, - float x_normalize_factor, - float y_normalize_factor, - CoglPipelineWrapMode wrap_x, - CoglPipelineWrapMode wrap_y, - CoglMetaTextureCallback callback, - void *user_data) -{ - CoglSpanIter iter_x; - CoglSpanIter iter_y; - float slice_coords[4]; - float span_virtual_coords[4]; - - /* Iterate the y axis of the virtual rectangle */ - for (_cogl_span_iter_begin (&iter_y, - y_spans, - n_y_spans, - y_normalize_factor, - virtual_coords[1], - virtual_coords[3], - wrap_y); - !_cogl_span_iter_end (&iter_y); - _cogl_span_iter_next (&iter_y)) - { - if (iter_y.flipped) - { - slice_coords[1] = iter_y.intersect_end; - slice_coords[3] = iter_y.intersect_start; - span_virtual_coords[1] = iter_y.intersect_end; - span_virtual_coords[3] = iter_y.intersect_start; - } - else - { - slice_coords[1] = iter_y.intersect_start; - slice_coords[3] = iter_y.intersect_end; - span_virtual_coords[1] = iter_y.intersect_start; - span_virtual_coords[3] = iter_y.intersect_end; - } - - /* Map the current intersection to normalized slice coordinates */ - slice_coords[1] = (slice_coords[1] - iter_y.pos) / iter_y.span->size; - slice_coords[3] = (slice_coords[3] - iter_y.pos) / iter_y.span->size; - - /* Iterate the x axis of the virtual rectangle */ - for (_cogl_span_iter_begin (&iter_x, - x_spans, - n_x_spans, - x_normalize_factor, - virtual_coords[0], - virtual_coords[2], - wrap_x); - !_cogl_span_iter_end (&iter_x); - _cogl_span_iter_next (&iter_x)) - { - CoglTexture *span_tex; - - if (iter_x.flipped) - { - slice_coords[0] = iter_x.intersect_end; - slice_coords[2] = iter_x.intersect_start; - span_virtual_coords[0] = iter_x.intersect_end; - span_virtual_coords[2] = iter_x.intersect_start; - } - else - { - slice_coords[0] = iter_x.intersect_start; - slice_coords[2] = iter_x.intersect_end; - span_virtual_coords[0] = iter_x.intersect_start; - span_virtual_coords[2] = iter_x.intersect_end; - } - - /* Map the current intersection to normalized slice coordinates */ - slice_coords[0] = (slice_coords[0] - iter_x.pos) / iter_x.span->size; - slice_coords[2] = (slice_coords[2] - iter_x.pos) / iter_x.span->size; - - /* Pluck out the cogl texture for this span */ - span_tex = textures[iter_y.index * n_x_spans + iter_x.index]; - - callback (COGL_TEXTURE (span_tex), - slice_coords, - span_virtual_coords, - user_data); - } - } -} - -void -_cogl_texture_set_allocated (CoglTexture *texture, - CoglPixelFormat internal_format, - int width, - int height) -{ - _cogl_texture_set_internal_format (texture, internal_format); - - texture->width = width; - texture->height = height; - texture->allocated = TRUE; - - _cogl_texture_free_loader (texture); -} - -gboolean -cogl_texture_allocate (CoglTexture *texture, - GError **error) -{ - g_return_val_if_fail (COGL_IS_TEXTURE (texture), FALSE); - - if (texture->allocated) - return TRUE; - - if (texture->components == COGL_TEXTURE_COMPONENTS_RG && - !cogl_has_feature (texture->context, COGL_FEATURE_ID_TEXTURE_RG)) - g_set_error (error, - COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_FORMAT, - "A red-green texture was requested but the driver " - "does not support them"); - - texture->allocated = COGL_TEXTURE_GET_CLASS (texture)->allocate (texture, error); - - return texture->allocated; -} - -void -_cogl_texture_set_internal_format (CoglTexture *texture, - CoglPixelFormat internal_format) -{ - texture->premultiplied = FALSE; - - if (internal_format == COGL_PIXEL_FORMAT_ANY) - internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE; - - if (internal_format == COGL_PIXEL_FORMAT_A_8) - { - texture->components = COGL_TEXTURE_COMPONENTS_A; - return; - } - else if (internal_format == COGL_PIXEL_FORMAT_RG_88) - { - texture->components = COGL_TEXTURE_COMPONENTS_RG; - return; - } - else if (internal_format & COGL_DEPTH_BIT) - { - texture->components = COGL_TEXTURE_COMPONENTS_DEPTH; - return; - } - else if (internal_format & COGL_A_BIT) - { - texture->components = COGL_TEXTURE_COMPONENTS_RGBA; - if (internal_format & COGL_PREMULT_BIT) - texture->premultiplied = TRUE; - return; - } - else - texture->components = COGL_TEXTURE_COMPONENTS_RGB; -} - -CoglPixelFormat -_cogl_texture_determine_internal_format (CoglTexture *texture, - CoglPixelFormat src_format) -{ - switch (cogl_texture_get_components (texture)) - { - case COGL_TEXTURE_COMPONENTS_DEPTH: - if (src_format & COGL_DEPTH_BIT) - return src_format; - else - { - CoglContext *ctx = cogl_texture_get_context (texture); - - if (_cogl_has_private_feature (ctx, - COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL) || - _cogl_has_private_feature (ctx, - COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL)) - { - return COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8; - } - else - return COGL_PIXEL_FORMAT_DEPTH_16; - } - case COGL_TEXTURE_COMPONENTS_A: - return COGL_PIXEL_FORMAT_A_8; - case COGL_TEXTURE_COMPONENTS_RG: - return COGL_PIXEL_FORMAT_RG_88; - case COGL_TEXTURE_COMPONENTS_RGB: - if (src_format != COGL_PIXEL_FORMAT_ANY && - !(src_format & COGL_A_BIT) && !(src_format & COGL_DEPTH_BIT)) - return src_format; - else - return COGL_PIXEL_FORMAT_RGB_888; - case COGL_TEXTURE_COMPONENTS_RGBA: - { - CoglPixelFormat format; - - if (src_format != COGL_PIXEL_FORMAT_ANY && - (src_format & COGL_A_BIT) && src_format != COGL_PIXEL_FORMAT_A_8) - format = src_format; - else - format = COGL_PIXEL_FORMAT_RGBA_8888; - - if (cogl_texture_get_premultiplied (texture)) - { - if (COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (format)) - return format |= COGL_PREMULT_BIT; - else - return COGL_PIXEL_FORMAT_RGBA_8888_PRE; - } - else - return format & ~COGL_PREMULT_BIT; - } - } - - g_return_val_if_reached (COGL_PIXEL_FORMAT_RGBA_8888_PRE); -} - -void -cogl_texture_set_components (CoglTexture *texture, - CoglTextureComponents components) -{ - g_return_if_fail (COGL_IS_TEXTURE (texture)); - g_return_if_fail (!texture->allocated); - - if (texture->components == components) - return; - - texture->components = components; -} - -CoglTextureComponents -cogl_texture_get_components (CoglTexture *texture) -{ - g_return_val_if_fail (COGL_IS_TEXTURE (texture), 0); - - return texture->components; -} - -void -cogl_texture_set_premultiplied (CoglTexture *texture, - gboolean premultiplied) -{ - g_return_if_fail (COGL_IS_TEXTURE (texture)); - g_return_if_fail (!texture->allocated); - - premultiplied = !!premultiplied; - - if (texture->premultiplied == premultiplied) - return; - - texture->premultiplied = premultiplied; -} - -gboolean -cogl_texture_get_premultiplied (CoglTexture *texture) -{ - g_return_val_if_fail (COGL_IS_TEXTURE (texture), FALSE); - - return texture->premultiplied; -} - -void -_cogl_texture_copy_internal_format (CoglTexture *src, - CoglTexture *dest) -{ - cogl_texture_set_components (dest, cogl_texture_get_components (src)); - cogl_texture_set_premultiplied (dest, cogl_texture_get_premultiplied (src)); -} - -CoglContext * -cogl_texture_get_context (CoglTexture *texture) -{ - return texture->context; -} - -CoglTextureLoader * -cogl_texture_get_loader (CoglTexture *texture) -{ - return texture->loader; -} - -int -cogl_texture_get_max_level_set (CoglTexture *texture) -{ - return texture->max_level_set; -} - -void -cogl_texture_set_max_level_set (CoglTexture *texture, - int max_level_set) -{ - texture->max_level_set = max_level_set; -} \ No newline at end of file diff --git a/mutter/cogl/cogl/cogl-texture.h b/mutter/cogl/cogl/cogl-texture.h deleted file mode 100644 index e353b1a..0000000 --- a/mutter/cogl/cogl/cogl-texture.h +++ /dev/null @@ -1,469 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-macros.h" -#include "cogl/cogl-pixel-buffer.h" -#include "cogl/cogl-pixel-format.h" -#include "cogl/cogl-bitmap.h" - -#include - -G_BEGIN_DECLS - -/** - * CoglTexture: - * - * Functions for creating and manipulating textures - * - * Cogl allows creating and manipulating textures using a uniform - * API that tries to hide all the various complexities of creating, - * loading and manipulating textures. - */ - -#define COGL_TYPE_TEXTURE (cogl_texture_get_type ()) -#define COGL_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_TEXTURE, CoglTexture)) -#define COGL_TEXTURE_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_TEXTURE, CoglTexture const)) -#define COGL_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_TYPE_TEXTURE, CoglTextureClass)) -#define COGL_IS_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_TYPE_TEXTURE)) -#define COGL_IS_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_TYPE_TEXTURE)) -#define COGL_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COGL_TYPE_TEXTURE, CoglTextureClass)) - -typedef struct _CoglTextureClass CoglTextureClass; -typedef struct _CoglTexture CoglTexture; - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (CoglTexture, g_object_unref) - -COGL_EXPORT -GType cogl_texture_get_type (void) G_GNUC_CONST; - -#define COGL_TEXTURE_MAX_WASTE 127 - -/** - * COGL_TEXTURE_ERROR: - * - * #GError domain for texture errors. - */ -#define COGL_TEXTURE_ERROR (cogl_texture_error_quark ()) - -/** - * CoglTextureError: - * @COGL_TEXTURE_ERROR_SIZE: Unsupported size - * @COGL_TEXTURE_ERROR_FORMAT: Unsupported format - * @COGL_TEXTURE_ERROR_TYPE: A primitive texture type that is - * unsupported by the driver was used - * - * Error codes that can be thrown when allocating textures. - */ -typedef enum -{ - COGL_TEXTURE_ERROR_SIZE, - COGL_TEXTURE_ERROR_FORMAT, - COGL_TEXTURE_ERROR_BAD_PARAMETER, - COGL_TEXTURE_ERROR_TYPE -} CoglTextureError; - -COGL_EXPORT -uint32_t cogl_texture_error_quark (void); - - -/** - * CoglTextureComponents: - * @COGL_TEXTURE_COMPONENTS_A: Only the alpha component - * @COGL_TEXTURE_COMPONENTS_RG: Red and green components. Note that - * this can only be used if the %COGL_FEATURE_ID_TEXTURE_RG feature - * is advertised. - * @COGL_TEXTURE_COMPONENTS_RGB: Red, green and blue components - * @COGL_TEXTURE_COMPONENTS_RGBA: Red, green, blue and alpha components - * @COGL_TEXTURE_COMPONENTS_DEPTH: Only a depth component - * - * See cogl_texture_set_components(). - */ -typedef enum _CoglTextureComponents -{ - COGL_TEXTURE_COMPONENTS_A = 1, - COGL_TEXTURE_COMPONENTS_RG, - COGL_TEXTURE_COMPONENTS_RGB, - COGL_TEXTURE_COMPONENTS_RGBA, - COGL_TEXTURE_COMPONENTS_DEPTH -} CoglTextureComponents; - -/** - * cogl_texture_set_components: - * @texture: a #CoglTexture pointer. - * - * Affects the internal storage format for this texture by specifying - * what components will be required for sampling later. - * - * This api affects how data is uploaded to the GPU since unused - * components can potentially be discarded from source data. - * - * For textures created by the ‘_with_size’ constructors the default - * is %COGL_TEXTURE_COMPONENTS_RGBA. The other constructors which take - * a %CoglBitmap or a data pointer default to the same components as - * the pixel format of the data. - * - * Note that the %COGL_TEXTURE_COMPONENTS_RG format is not available - * on all drivers. The availability can be determined by checking for - * the %COGL_FEATURE_ID_TEXTURE_RG feature. If this format is used on - * a driver where it is not available then %COGL_TEXTURE_ERROR_FORMAT - * will be raised when the texture is allocated. Even if the feature - * is not available then %COGL_PIXEL_FORMAT_RG_88 can still be used as - * an image format as long as %COGL_TEXTURE_COMPONENTS_RG isn't used - * as the texture's components. - */ -COGL_EXPORT void -cogl_texture_set_components (CoglTexture *texture, - CoglTextureComponents components); - -/** - * cogl_texture_get_components: - * @texture: a #CoglTexture pointer. - * - * Queries what components the given @texture stores internally as set - * via cogl_texture_set_components(). - * - * For textures created by the ‘_with_size’ constructors the default - * is %COGL_TEXTURE_COMPONENTS_RGBA. The other constructors which take - * a %CoglBitmap or a data pointer default to the same components as - * the pixel format of the data. - */ -COGL_EXPORT CoglTextureComponents -cogl_texture_get_components (CoglTexture *texture); - -/** - * cogl_texture_set_premultiplied: - * @texture: a #CoglTexture pointer. - * @premultiplied: Whether any internally stored red, green or blue - * components are pre-multiplied by an alpha - * component. - * - * Affects the internal storage format for this texture by specifying - * whether red, green and blue color components should be stored as - * pre-multiplied alpha values. - * - * This api affects how data is uploaded to the GPU since Cogl will - * convert source data to have premultiplied or unpremultiplied - * components according to this state. - * - * For example if you create a texture via - * cogl_texture_2d_new_with_size() and then upload data via - * cogl_texture_set_data() passing a source format of - * %COGL_PIXEL_FORMAT_RGBA_8888 then Cogl will internally multiply the - * red, green and blue components of the source data by the alpha - * component, for each pixel so that the internally stored data has - * pre-multiplied alpha components. If you instead upload data that - * already has pre-multiplied components by passing - * %COGL_PIXEL_FORMAT_RGBA_8888_PRE as the source format to - * cogl_texture_set_data() then the data can be uploaded without being - * converted. - * - * By default the @premultipled state is @TRUE. - */ -COGL_EXPORT void -cogl_texture_set_premultiplied (CoglTexture *texture, - gboolean premultiplied); - -/** - * cogl_texture_get_premultiplied: - * @texture: a #CoglTexture pointer. - * - * Queries the pre-multiplied alpha status for internally stored red, - * green and blue components for the given @texture as set by - * cogl_texture_set_premultiplied(). - * - * By default the pre-multiplied state is @TRUE. - * - * Return value: %TRUE if red, green and blue components are - * internally stored pre-multiplied by the alpha - * value or %FALSE if not. - */ -COGL_EXPORT gboolean -cogl_texture_get_premultiplied (CoglTexture *texture); - -/** - * cogl_texture_get_width: - * @texture: a #CoglTexture pointer. - * - * Queries the width of a cogl texture. - * - * Return value: the width of the GPU side texture in pixels - */ -COGL_EXPORT unsigned int -cogl_texture_get_width (CoglTexture *texture); - -/** - * cogl_texture_get_height: - * @texture: a #CoglTexture pointer. - * - * Queries the height of a cogl texture. - * - * Return value: the height of the GPU side texture in pixels - */ -COGL_EXPORT unsigned int -cogl_texture_get_height (CoglTexture *texture); - -/** - * cogl_texture_get_max_waste: - * @texture: a #CoglTexture pointer. - * - * Queries the maximum wasted (unused) pixels in one dimension of a GPU side - * texture. - * - * Return value: the maximum waste - */ -COGL_EXPORT int -cogl_texture_get_max_waste (CoglTexture *texture); - -/** - * cogl_texture_is_sliced: - * @texture: a #CoglTexture pointer. - * - * Queries if a texture is sliced (stored as multiple GPU side tecture - * objects). - * - * Return value: %TRUE if the texture is sliced, %FALSE if the texture - * is stored as a single GPU texture - */ -COGL_EXPORT gboolean -cogl_texture_is_sliced (CoglTexture *texture); - -/** - * cogl_texture_get_gl_texture: - * @texture: a #CoglTexture pointer. - * @out_gl_handle: (out) (allow-none): pointer to return location for the - * textures GL handle, or %NULL. - * @out_gl_target: (out) (allow-none): pointer to return location for the - * GL target type, or %NULL. - * - * Queries the GL handles for a GPU side texture through its #CoglTexture. - * - * If the texture is spliced the data for the first sub texture will be - * queried. - * - * Return value: %TRUE if the handle was successfully retrieved, %FALSE - * if the handle was invalid - */ -COGL_EXPORT gboolean -cogl_texture_get_gl_texture (CoglTexture *texture, - unsigned int *out_gl_handle, - unsigned int *out_gl_target); - -/** - * cogl_texture_get_data: - * @texture: a #CoglTexture pointer. - * @format: the #CoglPixelFormat to store the texture as. - * @rowstride: the rowstride of @data in bytes or pass 0 to calculate - * from the bytes-per-pixel of @format multiplied by the - * @texture width. - * @data: (array) (nullable): memory location to write the @texture's contents, - * or %NULL to only query the data size through the return value. - * - * Copies the pixel data from a cogl texture to system memory. - * - * Don't pass the value of cogl_texture_get_rowstride() as the - * @rowstride argument, the rowstride should be the rowstride you - * want for the destination @data buffer not the rowstride of the - * source texture - * - * Return value: the size of the texture data in bytes - */ -COGL_EXPORT int -cogl_texture_get_data (CoglTexture *texture, - CoglPixelFormat format, - unsigned int rowstride, - uint8_t *data); - -/** - * cogl_texture_set_region: - * @texture: a #CoglTexture. - * @src_x: upper left coordinate to use from source data. - * @src_y: upper left coordinate to use from source data. - * @dst_x: upper left destination horizontal coordinate. - * @dst_y: upper left destination vertical coordinate. - * @dst_width: width of destination region to write. (Must be less - * than or equal to @width) - * @dst_height: height of destination region to write. (Must be less - * than or equal to @height) - * @width: width of source data buffer. - * @height: height of source data buffer. - * @format: the #CoglPixelFormat used in the source buffer. - * @rowstride: rowstride of source buffer (computed from width if none - * specified) - * @data: (array): the actual pixel data. - * - * Sets the pixels in a rectangular subregion of @texture from an in-memory - * buffer containing pixel data. - * - * The region set can't be larger than the source @data - * - * Return value: %TRUE if the subregion upload was successful, and - * %FALSE otherwise - */ -COGL_EXPORT gboolean -cogl_texture_set_region (CoglTexture *texture, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - int width, - int height, - CoglPixelFormat format, - unsigned int rowstride, - const uint8_t *data); - -/** - * cogl_texture_set_data: - * @texture a #CoglTexture. - * @format: the #CoglPixelFormat used in the source @data buffer. - * @rowstride: rowstride of the source @data buffer (computed from - * the texture width and @format if it equals 0) - * @data: (array): the source data, pointing to the first top-left pixel to set - * @level: The mipmap level to update (Normally 0 for the largest, - * base texture) - * @error: A #GError to return exceptional errors - * - * Sets all the pixels for a given mipmap @level by copying the pixel - * data pointed to by the @data argument into the given @texture. - * - * @data should point to the first pixel to copy corresponding - * to the top left of the mipmap @level being set. - * - * If @rowstride equals 0 then it will be automatically calculated - * from the width of the mipmap level and the bytes-per-pixel for the - * given @format. - * - * A mipmap @level of 0 corresponds to the largest, base image of a - * texture and @level 1 is half the width and height of level 0. If - * dividing any dimension of the previous level by two results in a - * fraction then round the number down (floor()), but clamp to 1 - * something like this: - * - * ``` - * next_width = MAX (1, floor (prev_width)); - * ``` - * - * You can determine the number of mipmap levels for a given texture - * like this: - * - * ``` - * n_levels = 1 + floor (log2 (max_dimension)); - * ``` - * - * Where %max_dimension is the larger of cogl_texture_get_width() and - * cogl_texture_get_height(). - * - * It is an error to pass a @level number >= the number of levels that - * @texture can have according to the above calculation. - * - * Since the storage for a #CoglTexture is allocated lazily then - * if the given @texture has not previously been allocated then this - * api can return %FALSE and throw an exceptional @error if there is - * not enough memory to allocate storage for @texture. - * - * Return value: %TRUE if the data upload was successful, and - * %FALSE otherwise - */ -COGL_EXPORT gboolean -cogl_texture_set_data (CoglTexture *texture, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - int level, - GError **error); - -/** - * cogl_texture_set_region_from_bitmap: - * @texture: a #CoglTexture pointer - * @src_x: upper left coordinate to use from the source bitmap. - * @src_y: upper left coordinate to use from the source bitmap - * @dst_x: upper left destination horizontal coordinate. - * @dst_y: upper left destination vertical coordinate. - * @dst_width: width of destination region to write. (Must be less - * than or equal to the bitmap width) - * @dst_height: height of destination region to write. (Must be less - * than or equal to the bitmap height) - * @bitmap: The source bitmap to read from - * - * Copies a specified source region from @bitmap to the position - * (@src_x, @src_y) of the given destination texture @handle. - * - * The region updated can't be larger than the source - * bitmap - * - * Return value: %TRUE if the subregion upload was successful, and - * %FALSE otherwise - */ -COGL_EXPORT gboolean -cogl_texture_set_region_from_bitmap (CoglTexture *texture, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - CoglBitmap *bitmap); - -/** - * cogl_texture_allocate: - * @texture: A #CoglTexture - * @error: A #GError to return exceptional errors or %NULL - * - * Explicitly allocates the storage for the given @texture which - * allows you to be sure that there is enough memory for the - * texture and if not then the error can be handled gracefully. - * - * Normally applications don't need to use this api directly - * since the texture will be implicitly allocated when data is set on - * the texture, or if the texture is attached to a #CoglOffscreen - * framebuffer and rendered too. - * - * Return value: %TRUE if the texture was successfully allocated, - * otherwise %FALSE and @error will be updated if it - * wasn't %NULL. - */ -COGL_EXPORT gboolean -cogl_texture_allocate (CoglTexture *texture, - GError **error); - -/** - * cogl_texture_is_get_data_supported: - */ -COGL_EXPORT gboolean -cogl_texture_is_get_data_supported (CoglTexture *texture); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-trace.c b/mutter/cogl/cogl/cogl-trace.c deleted file mode 100644 index 3d47b2e..0000000 --- a/mutter/cogl/cogl/cogl-trace.c +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Copyright 2018 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - * - */ - -#include "config.h" - -#include "cogl/cogl-trace.h" - -#ifdef HAVE_PROFILER - -#include -#include -#include -#include -#include -#include - -#define COGL_TRACE_OUTPUT_FILE "cogl-trace-sp-capture.syscap" -#define BUFFER_LENGTH (4096 * 4) - -struct _CoglTraceContext -{ - gatomicrefcount ref_count; - SysprofCaptureWriter *writer; -}; - -typedef struct _CoglTraceThreadContext -{ - int cpu_id; - GPid pid; - char *group; - CoglTraceContext *trace_context; -} CoglTraceThreadContext; - -typedef struct -{ - char *group; - CoglTraceContext *trace_context; -} TraceData; - -static void cogl_trace_context_unref (CoglTraceContext *trace_context); - -static void -trace_data_free (gpointer user_data) -{ - TraceData *data = user_data; - - g_clear_pointer (&data->group, g_free); - g_clear_pointer (&data->trace_context, cogl_trace_context_unref); - g_free (data); -} - -static void cogl_trace_thread_context_free (gpointer data); - -GPrivate cogl_trace_thread_data = G_PRIVATE_INIT (cogl_trace_thread_context_free); -CoglTraceContext *cogl_trace_context; -GMutex cogl_trace_mutex; - -static CoglTraceContext * -cogl_trace_context_new (int fd, - const char *filename) -{ - CoglTraceContext *context; - SysprofCaptureWriter *writer; - - if (fd != -1) - { - g_debug ("Initializing trace context with fd=%d", fd); - writer = sysprof_capture_writer_new_from_fd (fd, BUFFER_LENGTH); - } - else if (filename != NULL) - { - g_debug ("Initializing trace context with filename='%s'", filename); - writer = sysprof_capture_writer_new (filename, BUFFER_LENGTH); - } - else - { - g_debug ("Initializing trace context with default filename"); - writer = sysprof_capture_writer_new (COGL_TRACE_OUTPUT_FILE, BUFFER_LENGTH); - } - - if (!writer) - return NULL; - - context = g_new0 (CoglTraceContext, 1); - context->writer = writer; - g_atomic_ref_count_init (&context->ref_count); - return context; -} - -static void -cogl_trace_context_unref (CoglTraceContext *trace_context) -{ - if (g_atomic_ref_count_dec (&trace_context->ref_count)) - { - if (trace_context->writer) - sysprof_capture_writer_flush (trace_context->writer); - g_clear_pointer (&trace_context->writer, sysprof_capture_writer_unref); - g_free (trace_context); - } -} - -static CoglTraceContext * -cogl_trace_context_ref (CoglTraceContext *trace_context) -{ - g_atomic_ref_count_inc (&trace_context->ref_count); - return trace_context; -} - -static gboolean -setup_trace_context (int fd, - const char *filename, - GError **error) -{ - g_autoptr (GMutexLocker) locker = NULL; - - locker = g_mutex_locker_new (&cogl_trace_mutex); - if (cogl_trace_context) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Trace context already setup"); - return FALSE; - } - - cogl_trace_context = cogl_trace_context_new (fd, filename); - - if (!cogl_trace_context) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Failed to setup trace context"); - return FALSE; - } - - return TRUE; -} - -static CoglTraceThreadContext * -cogl_trace_thread_context_new (const char *group, - CoglTraceContext *trace_context) -{ - CoglTraceThreadContext *thread_context; - pid_t tid; - - tid = (pid_t) syscall (SYS_gettid); - - thread_context = g_new0 (CoglTraceThreadContext, 1); - thread_context->cpu_id = -1; - thread_context->pid = getpid (); - thread_context->group = - group ? g_strdup (group) : g_strdup_printf ("t:%d", tid); - thread_context->trace_context = cogl_trace_context_ref (trace_context); - - return thread_context; -} - -static gboolean -enable_tracing_idle_callback (gpointer user_data) -{ - CoglTraceThreadContext *thread_context = - g_private_get (&cogl_trace_thread_data); - TraceData *data = user_data; - - if (thread_context) - { - g_warning ("Tracing already enabled"); - return G_SOURCE_REMOVE; - } - - thread_context = cogl_trace_thread_context_new (data->group, - data->trace_context); - g_private_set (&cogl_trace_thread_data, thread_context); - - return G_SOURCE_REMOVE; -} - -static void -cogl_trace_thread_context_free (gpointer data) -{ - CoglTraceThreadContext *thread_context = data; - - if (!thread_context) - return; - - g_free (thread_context->group); - g_free (thread_context); -} - -static gboolean -disable_tracing_idle_callback (gpointer user_data) -{ - CoglTraceThreadContext *thread_context = - g_private_get (&cogl_trace_thread_data); - - if (!thread_context) - { - g_warning ("Tracing not enabled"); - return G_SOURCE_REMOVE; - } - - g_private_replace (&cogl_trace_thread_data, NULL); - - return G_SOURCE_REMOVE; -} - -gboolean -cogl_start_tracing_with_path (const char *filename, - GError **error) -{ - return setup_trace_context (-1, filename, error); -} - -gboolean -cogl_start_tracing_with_fd (int fd, - GError **error) -{ - return setup_trace_context (fd, NULL, error); -} - -void -cogl_stop_tracing (void) -{ - g_mutex_lock (&cogl_trace_mutex); - g_clear_pointer (&cogl_trace_context, cogl_trace_context_unref); - g_mutex_unlock (&cogl_trace_mutex); -} - -void -cogl_set_tracing_enabled_on_thread (GMainContext *main_context, - const char *group) -{ - TraceData *data; - - g_return_if_fail (cogl_trace_context); - - data = g_new0 (TraceData, 1); - data->group = group ? strdup (group) : NULL; - data->trace_context = cogl_trace_context_ref (cogl_trace_context); - - if (main_context == g_main_context_get_thread_default ()) - { - enable_tracing_idle_callback (data); - trace_data_free (data); - } - else - { - GSource *source; - source = g_idle_source_new (); - - g_source_set_callback (source, - enable_tracing_idle_callback, - data, - trace_data_free); - - g_source_attach (source, main_context); - g_source_unref (source); - } -} - -void -cogl_set_tracing_disabled_on_thread (GMainContext *main_context) -{ - if (g_main_context_get_thread_default () == main_context) - { - disable_tracing_idle_callback (NULL); - } - else - { - GSource *source; - - source = g_idle_source_new (); - - g_source_set_callback (source, disable_tracing_idle_callback, NULL, NULL); - - g_source_attach (source, main_context); - g_source_unref (source); - } -} - -static void -cogl_trace_end_with_description (CoglTraceHead *head, - const char *description) -{ - SysprofTimeStamp end_time; - CoglTraceContext *trace_context; - CoglTraceThreadContext *trace_thread_context; - - end_time = g_get_monotonic_time () * 1000; - trace_thread_context = g_private_get (&cogl_trace_thread_data); - trace_context = trace_thread_context->trace_context; - - g_mutex_lock (&cogl_trace_mutex); - if (!sysprof_capture_writer_add_mark (trace_context->writer, - head->begin_time, - trace_thread_context->cpu_id, - trace_thread_context->pid, - (uint64_t) end_time - head->begin_time, - trace_thread_context->group, - head->name, - description)) - { - /* XXX: g_main_context_get_thread_default() might be wrong, it probably - * needs to store the GMainContext in CoglTraceThreadContext when creating - * and use it here. - */ - if (errno == EPIPE) - cogl_set_tracing_disabled_on_thread (g_main_context_get_thread_default ()); - } - g_mutex_unlock (&cogl_trace_mutex); -} - -void -cogl_trace_end (CoglTraceHead *head) -{ - cogl_trace_end_with_description (head, head->description); - g_free (head->description); -} - -void -cogl_trace_mark (const char *name, - const char *description) -{ - SysprofTimeStamp time; - CoglTraceContext *trace_context; - CoglTraceThreadContext *trace_thread_context; - - time = g_get_monotonic_time () * 1000; - trace_thread_context = g_private_get (&cogl_trace_thread_data); - trace_context = trace_thread_context->trace_context; - - g_mutex_lock (&cogl_trace_mutex); - if (!sysprof_capture_writer_add_mark (trace_context->writer, - time, - trace_thread_context->cpu_id, - trace_thread_context->pid, - 0, - trace_thread_context->group, - name, - description)) - { - /* XXX: g_main_context_get_thread_default() might be wrong, it probably - * needs to store the GMainContext in CoglTraceThreadContext when creating - * and use it here. - */ - if (errno == EPIPE) - cogl_set_tracing_disabled_on_thread (g_main_context_get_thread_default ()); - } - g_mutex_unlock (&cogl_trace_mutex); -} - -void -cogl_trace_describe (CoglTraceHead *head, - const char *description) -{ - if (head->description) - { - char *old_description = head->description; - head->description = - g_strdup_printf ("%s, %s", old_description, description); - g_free (old_description); - } - else - head->description = g_strdup (description); -} - -#else - -#include -#include - -gboolean -cogl_start_tracing_with_path (const char *filename, - GError **error) -{ - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "Tracing disabled at build time"); - return FALSE; -} - -gboolean -cogl_start_tracing_with_fd (int fd, - GError **error) -{ - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "Tracing disabled at build time"); - return FALSE; -} - -void -cogl_stop_tracing (void) -{ - fprintf (stderr, "Tracing not enabled"); -} - -void -cogl_set_tracing_enabled_on_thread (void *data, - const char *group) -{ - fprintf (stderr, "Tracing not enabled"); -} - -void -cogl_set_tracing_disabled_on_thread (void *data) -{ - fprintf (stderr, "Tracing not enabled"); -} - -#endif /* HAVE_PROFILER */ diff --git a/mutter/cogl/cogl/cogl-trace.h b/mutter/cogl/cogl/cogl-trace.h deleted file mode 100644 index fe811d9..0000000 --- a/mutter/cogl/cogl/cogl-trace.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2018 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - * - */ - -#pragma once - -#include -#include -#include -#include - -#include "cogl/cogl-macros.h" - -#ifdef HAVE_PROFILER - -typedef struct _CoglTraceContext CoglTraceContext; - -typedef struct _CoglTraceHead -{ - uint64_t begin_time; - const char *name; - char *description; -} CoglTraceHead; - -COGL_EXPORT -GPrivate cogl_trace_thread_data; -COGL_EXPORT -CoglTraceContext *cogl_trace_context; -COGL_EXPORT -GMutex cogl_trace_mutex; - -COGL_EXPORT -gboolean cogl_start_tracing_with_path (const char *filename, - GError **error); - -COGL_EXPORT -gboolean cogl_start_tracing_with_fd (int fd, - GError **error); - -COGL_EXPORT -void cogl_stop_tracing (void); - -COGL_EXPORT -void cogl_set_tracing_enabled_on_thread (GMainContext *main_context, - const char *group); - -COGL_EXPORT -void cogl_set_tracing_disabled_on_thread (GMainContext *main_context); - -static inline void -cogl_trace_begin (CoglTraceHead *head, - const char *name) -{ - head->begin_time = g_get_monotonic_time () * 1000; - head->name = name; -} - -COGL_EXPORT void -cogl_trace_end (CoglTraceHead *head); - -COGL_EXPORT void -cogl_trace_describe (CoglTraceHead *head, - const char *description); - -COGL_EXPORT void -cogl_trace_mark (const char *name, - const char *description); - -static inline void -cogl_auto_trace_end_helper (CoglTraceHead **head) -{ - if (*head) - cogl_trace_end (*head); -} - -static inline gboolean -cogl_is_tracing_enabled (void) -{ - return !!g_private_get (&cogl_trace_thread_data); -} - -#define COGL_TRACE_BEGIN_SCOPED(Name, name) \ - CoglTraceHead CoglTrace##Name = { 0 }; \ - __attribute__((cleanup (cogl_auto_trace_end_helper))) \ - CoglTraceHead *ScopedCoglTrace##Name = NULL; \ - if (cogl_is_tracing_enabled ()) \ - { \ - cogl_trace_begin (&CoglTrace##Name, name); \ - ScopedCoglTrace##Name = &CoglTrace##Name; \ - } - -#define COGL_TRACE_END(Name)\ - if (cogl_is_tracing_enabled ()) \ - { \ - cogl_trace_end (&CoglTrace##Name); \ - ScopedCoglTrace##Name = NULL; \ - } - -#define COGL_TRACE_DESCRIBE(Name, description)\ - if (cogl_is_tracing_enabled ()) \ - cogl_trace_describe (&CoglTrace##Name, description); - -#define COGL_TRACE_SCOPED_ANCHOR(Name) \ - CoglTraceHead G_GNUC_UNUSED CoglTrace##Name = { 0 }; \ - __attribute__((cleanup (cogl_auto_trace_end_helper))) \ - CoglTraceHead *ScopedCoglTrace##Name = NULL; \ - -#define COGL_TRACE_BEGIN_ANCHORED(Name, name) \ - if (cogl_is_tracing_enabled ()) \ - { \ - cogl_trace_begin (&CoglTrace##Name, name); \ - ScopedCoglTrace##Name = &CoglTrace##Name; \ - } - -#define COGL_TRACE_MESSAGE(name, ...) \ - G_STMT_START \ - { \ - if (cogl_is_tracing_enabled ()) \ - { \ - g_autofree char *CoglTraceMessage = g_strdup_printf (__VA_ARGS__); \ - cogl_trace_mark (name, CoglTraceMessage); \ - } \ - } \ - G_STMT_END - -#else /* HAVE_PROFILER */ - -#include - -#define COGL_TRACE_BEGIN_SCOPED(Name, name) (void) 0 -#define COGL_TRACE_END(Name) (void) 0 -#define COGL_TRACE_DESCRIBE(Name, description) (void) 0 -#define COGL_TRACE_SCOPED_ANCHOR(Name) (void) 0 -#define COGL_TRACE_BEGIN_ANCHORED(Name, name) (void) 0 -#define COGL_TRACE_MESSAGE(name, ...) (void) 0 - -COGL_EXPORT -gboolean cogl_start_tracing_with_path (const char *filename, - GError **error); - -COGL_EXPORT -gboolean cogl_start_tracing_with_fd (int fd, - GError **error); - -COGL_EXPORT -void cogl_stop_tracing (void); - -COGL_EXPORT -void cogl_set_tracing_enabled_on_thread (void *data, - const char *group); - -COGL_EXPORT -void cogl_set_tracing_disabled_on_thread (void *data); - -#endif /* HAVE_PROFILER */ diff --git a/mutter/cogl/cogl/cogl-types.h b/mutter/cogl/cogl/cogl-types.h deleted file mode 100644 index 589dab5..0000000 --- a/mutter/cogl/cogl/cogl-types.h +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - - -#include -#include - -#include "cogl/cogl-macros.h" -#include - -#include -#include - -G_BEGIN_DECLS - -/* Some structures are meant to be opaque but they have public - definitions because we want the size to be public so they can be - allocated on the stack. This macro is used to ensure that users - don't accidentally access private members */ -#ifdef COGL_COMPILATION -#define COGL_PRIVATE(x) x -#else -#define COGL_PRIVATE(x) private_member_ ## x -#endif - -#ifndef __GI_SCANNER__ -/* To help catch accidental changes to public structs that should - * be stack allocated we use this macro to compile time assert that - * a struct size is as expected. - */ -#define COGL_STRUCT_SIZE_ASSERT(TYPE, SIZE) \ -typedef struct { \ - char compile_time_assert_ ## TYPE ## _size[ \ - (sizeof (TYPE) == (SIZE)) ? 1 : -1]; \ - } _ ## TYPE ## SizeCheck -#else -#define COGL_STRUCT_SIZE_ASSERT(TYPE, SIZE) -#endif - -typedef struct _CoglFramebuffer CoglFramebuffer; - -typedef struct _CoglColor CoglColor; -typedef struct _CoglTextureVertex CoglTextureVertex; - -/** - * CoglDmaBufHandle: (free-func cogl_dma_buf_handle_free) - * - * An opaque type that tracks the lifetime of a DMA buffer fd. Release - * with cogl_dma_buf_handle_free(). - */ -typedef struct _CoglDmaBufHandle CoglDmaBufHandle; - -/* Enum declarations */ - -#define COGL_A_BIT (1 << 4) -#define COGL_BGR_BIT (1 << 5) -#define COGL_AFIRST_BIT (1 << 6) -#define COGL_PREMULT_BIT (1 << 7) -#define COGL_DEPTH_BIT (1 << 8) -#define COGL_STENCIL_BIT (1 << 9) - -/** - * CoglBufferTarget: - * @COGL_WINDOW_BUFFER: FIXME - * @COGL_OFFSCREEN_BUFFER: FIXME - * - * Target flags for FBOs. - */ -typedef enum -{ - COGL_WINDOW_BUFFER = (1 << 1), - COGL_OFFSCREEN_BUFFER = (1 << 2) -} CoglBufferTarget; - -struct _CoglColor -{ - /*< private >*/ - uint8_t COGL_PRIVATE (red); - uint8_t COGL_PRIVATE (green); - uint8_t COGL_PRIVATE (blue); - - uint8_t COGL_PRIVATE (alpha); -}; -COGL_STRUCT_SIZE_ASSERT (CoglColor, 4); - -/** - * CoglTextureVertex: - * @x: Model x-coordinate - * @y: Model y-coordinate - * @z: Model z-coordinate - * @tx: Texture x-coordinate - * @ty: Texture y-coordinate - * @color: The color to use at this vertex. This is ignored if - * use_color is %FALSE when calling cogl_polygon() - * - * Used to specify vertex information when calling cogl_polygon() - */ -struct _CoglTextureVertex -{ - float x, y, z; - float tx, ty; - - CoglColor color; -}; -COGL_STRUCT_SIZE_ASSERT (CoglTextureVertex, 24); - -/** - * COGL_BLEND_STRING_ERROR: - * - * #GError domain for blend string parser errors - */ -#define COGL_BLEND_STRING_ERROR (cogl_blend_string_error_quark ()) - -/** - * CoglBlendStringError: - * @COGL_BLEND_STRING_ERROR_PARSE_ERROR: Generic parse error - * @COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR: Argument parse error - * @COGL_BLEND_STRING_ERROR_INVALID_ERROR: Internal parser error - * @COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR: Blend string not - * supported by the GPU - * - * Error enumeration for the blend strings parser - */ -typedef enum /*< prefix=COGL_BLEND_STRING_ERROR >*/ -{ - COGL_BLEND_STRING_ERROR_PARSE_ERROR, - COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR, - COGL_BLEND_STRING_ERROR_INVALID_ERROR, - COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR -} CoglBlendStringError; - -COGL_EXPORT uint32_t -cogl_blend_string_error_quark (void); - -#define COGL_SYSTEM_ERROR (_cogl_system_error_quark ()) - -/** - * CoglSystemError: - * @COGL_SYSTEM_ERROR_UNSUPPORTED: You tried to use a feature or - * configuration not currently available. - * @COGL_SYSTEM_ERROR_NO_MEMORY: You tried to allocate a resource - * such as a texture and there wasn't enough memory. - * - * Error enumeration for Cogl - * - * The @COGL_SYSTEM_ERROR_UNSUPPORTED error can be thrown for a - * variety of reasons. For example: - * - * - You've tried to use a feature that is not advertised by - * [func@Cogl.has_feature]. - * - The GPU can not handle the configuration you have requested. - * An example might be if you try to use too many texture - * layers in a single #CoglPipeline - * - The driver does not support some configuration. - * - * Currently this is only used by Cogl API marked as experimental so - * this enum should also be considered experimental. - */ -typedef enum /*< prefix=COGL_ERROR >*/ -{ - COGL_SYSTEM_ERROR_UNSUPPORTED, - COGL_SYSTEM_ERROR_NO_MEMORY -} CoglSystemError; - -COGL_EXPORT uint32_t -_cogl_system_error_quark (void); - -/** - * CoglAttributeType: - * @COGL_ATTRIBUTE_TYPE_BYTE: Data is the same size of a byte - * @COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE: Data is the same size of an - * unsigned byte - * @COGL_ATTRIBUTE_TYPE_SHORT: Data is the same size of a short integer - * @COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT: Data is the same size of - * an unsigned short integer - * @COGL_ATTRIBUTE_TYPE_FLOAT: Data is the same size of a float - * - * Data types for the components of a vertex attribute. - */ -typedef enum -{ - COGL_ATTRIBUTE_TYPE_BYTE = 0x1400, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE = 0x1401, - COGL_ATTRIBUTE_TYPE_SHORT = 0x1402, - COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT = 0x1403, - COGL_ATTRIBUTE_TYPE_FLOAT = 0x1406 -} CoglAttributeType; - -/** - * CoglIndicesType: - * @COGL_INDICES_TYPE_UNSIGNED_BYTE: Your indices are unsigned bytes - * @COGL_INDICES_TYPE_UNSIGNED_SHORT: Your indices are unsigned shorts - * @COGL_INDICES_TYPE_UNSIGNED_INT: Your indices are unsigned ints - * - * You should aim to use the smallest data type that gives you enough - * range, since it reduces the size of your index array and can help - * reduce the demand on memory bandwidth. - * - * Note that %COGL_INDICES_TYPE_UNSIGNED_INT is only supported if the - * %COGL_FEATURE_ID_UNSIGNED_INT_INDICES feature is available. This - * should always be available on OpenGL but on OpenGL ES it will only - * be available if the GL_OES_element_index_uint extension is - * advertized. - */ -typedef enum -{ - COGL_INDICES_TYPE_UNSIGNED_BYTE, - COGL_INDICES_TYPE_UNSIGNED_SHORT, - COGL_INDICES_TYPE_UNSIGNED_INT -} CoglIndicesType; - -/** - * CoglVerticesMode: - * @COGL_VERTICES_MODE_POINTS: FIXME, equivalent to `GL_POINTS` - * @COGL_VERTICES_MODE_LINES: FIXME, equivalent to `GL_LINES` - * @COGL_VERTICES_MODE_LINE_LOOP: FIXME, equivalent to `GL_LINE_LOOP` - * @COGL_VERTICES_MODE_LINE_STRIP: FIXME, equivalent to `GL_LINE_STRIP` - * @COGL_VERTICES_MODE_TRIANGLES: FIXME, equivalent to `GL_TRIANGLES` - * @COGL_VERTICES_MODE_TRIANGLE_STRIP: FIXME, equivalent to `GL_TRIANGLE_STRIP` - * @COGL_VERTICES_MODE_TRIANGLE_FAN: FIXME, equivalent to `GL_TRIANGLE_FAN` - * - * Different ways of interpreting vertices when drawing. - */ -typedef enum -{ - COGL_VERTICES_MODE_POINTS = 0x0000, - COGL_VERTICES_MODE_LINES = 0x0001, - COGL_VERTICES_MODE_LINE_LOOP = 0x0002, - COGL_VERTICES_MODE_LINE_STRIP = 0x0003, - COGL_VERTICES_MODE_TRIANGLES = 0x0004, - COGL_VERTICES_MODE_TRIANGLE_STRIP = 0x0005, - COGL_VERTICES_MODE_TRIANGLE_FAN = 0x0006 -} CoglVerticesMode; - -/* NB: The above definitions are taken from gl.h equivalents */ - - -/* XXX: should this be CoglMaterialDepthTestFunction? - * It makes it very verbose but would be consistent with - * CoglMaterialWrapMode */ - -/** - * CoglDepthTestFunction: - * @COGL_DEPTH_TEST_FUNCTION_NEVER: Never passes. - * @COGL_DEPTH_TEST_FUNCTION_LESS: Passes if the fragment's depth - * value is less than the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_EQUAL: Passes if the fragment's depth - * value is equal to the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_LEQUAL: Passes if the fragment's depth - * value is less or equal to the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_GREATER: Passes if the fragment's depth - * value is greater than the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_NOTEQUAL: Passes if the fragment's depth - * value is not equal to the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_GEQUAL: Passes if the fragment's depth - * value greater than or equal to the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_ALWAYS: Always passes. - * - * When using depth testing one of these functions is used to compare - * the depth of an incoming fragment against the depth value currently - * stored in the depth buffer. The function is changed using - * cogl_depth_state_set_test_function(). - * - * The test is only done when depth testing is explicitly enabled. (See - * cogl_depth_state_set_test_enabled()) - */ -typedef enum -{ - COGL_DEPTH_TEST_FUNCTION_NEVER = 0x0200, - COGL_DEPTH_TEST_FUNCTION_LESS = 0x0201, - COGL_DEPTH_TEST_FUNCTION_EQUAL = 0x0202, - COGL_DEPTH_TEST_FUNCTION_LEQUAL = 0x0203, - COGL_DEPTH_TEST_FUNCTION_GREATER = 0x0204, - COGL_DEPTH_TEST_FUNCTION_NOTEQUAL = 0x0205, - COGL_DEPTH_TEST_FUNCTION_GEQUAL = 0x0206, - COGL_DEPTH_TEST_FUNCTION_ALWAYS = 0x0207 -} CoglDepthTestFunction; -/* NB: The above definitions are taken from gl.h equivalents */ - -typedef enum /*< prefix=COGL_RENDERER_ERROR >*/ -{ - COGL_RENDERER_ERROR_XLIB_DISPLAY_OPEN, - COGL_RENDERER_ERROR_BAD_CONSTRAINT -} CoglRendererError; - -/** - * CoglFilterReturn: - * @COGL_FILTER_CONTINUE: The event was not handled, continues the - * processing - * @COGL_FILTER_REMOVE: Remove the event, stops the processing - * - * Return values for the #CoglXlibFilterFunc and #CoglWin32FilterFunc functions. - */ -typedef enum _CoglFilterReturn { /*< prefix=COGL_FILTER >*/ - COGL_FILTER_CONTINUE, - COGL_FILTER_REMOVE -} CoglFilterReturn; - -typedef enum _CoglWinsysFeature -{ - /* Available if its possible to query a counter that - * increments at each vblank. */ - COGL_WINSYS_FEATURE_VBLANK_COUNTER, - - /* Available if its possible to wait until the next vertical - * blank period */ - COGL_WINSYS_FEATURE_VBLANK_WAIT, - - /* Available if the window system supports mapping native - * pixmaps to textures. */ - COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP, - - /* Available if the window system supports reporting an event - * for swap buffer completions. */ - COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT, - - /* Available if it's possible to swap a list of sub rectangles - * from the back buffer to the front buffer */ - COGL_WINSYS_FEATURE_SWAP_REGION, - - /* Available if swap_region requests can be automatically throttled - * to the vblank frequency. */ - COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, - - /* Available if the swap region implementation won't tear and thus - * only needs to be throttled to the framerate */ - COGL_WINSYS_FEATURE_SWAP_REGION_SYNCHRONIZED, - - /* Available if the age of the back buffer can be queried */ - COGL_WINSYS_FEATURE_BUFFER_AGE, - - /* Available if the winsys directly handles _SYNC and _COMPLETE events */ - COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT, - - COGL_WINSYS_FEATURE_N_FEATURES -} CoglWinsysFeature; - -/** - * CoglWinding: - * @COGL_WINDING_CLOCKWISE: Vertices are in a clockwise order - * @COGL_WINDING_COUNTER_CLOCKWISE: Vertices are in a counter-clockwise order - * - * Enum used to represent the two directions of rotation. This can be - * used to set the front face for culling by calling - * cogl_pipeline_set_front_face_winding(). - */ -typedef enum -{ - COGL_WINDING_CLOCKWISE, - COGL_WINDING_COUNTER_CLOCKWISE -} CoglWinding; - -/** - * CoglBufferBit: - * @COGL_BUFFER_BIT_COLOR: Selects the primary color buffer - * @COGL_BUFFER_BIT_DEPTH: Selects the depth buffer - * @COGL_BUFFER_BIT_STENCIL: Selects the stencil buffer - * - * Types of auxiliary buffers - */ -typedef enum -{ - COGL_BUFFER_BIT_COLOR = 1L<<0, - COGL_BUFFER_BIT_DEPTH = 1L<<1, - COGL_BUFFER_BIT_STENCIL = 1L<<2 -} CoglBufferBit; - -/** - * CoglReadPixelsFlags: - * @COGL_READ_PIXELS_COLOR_BUFFER: Read from the color buffer - * - * Flags for cogl_framebuffer_read_pixels_into_bitmap() - */ -typedef enum /*< prefix=COGL_READ_PIXELS >*/ -{ - COGL_READ_PIXELS_COLOR_BUFFER = 1L << 0 -} CoglReadPixelsFlags; - -/** - * CoglStereoMode: - * @COGL_STEREO_BOTH: draw to both stereo buffers - * @COGL_STEREO_LEFT: draw only to the left stereo buffer - * @COGL_STEREO_RIGHT: draw only to the left stereo buffer - * - * Represents how draw should affect the two buffers - * of a stereo framebuffer. See cogl_framebuffer_set_stereo_mode(). - */ -typedef enum -{ - COGL_STEREO_BOTH, - COGL_STEREO_LEFT, - COGL_STEREO_RIGHT -} CoglStereoMode; - -typedef struct _CoglScanout CoglScanout; -typedef struct _CoglScanoutBuffer CoglScanoutBuffer; - -#define COGL_SCANOUT_ERROR (cogl_scanout_error_quark ()) - -/** - * CoglScanoutError: - * @COGL_SCANOUT_ERROR_INHIBITED: Scanout inhibited - */ -typedef enum _CoglScanoutError -{ - COGL_SCANOUT_ERROR_INHIBITED, -} CoglScanoutError; - -COGL_EXPORT GQuark -cogl_scanout_error_quark (void); - -G_END_DECLS diff --git a/mutter/cogl/cogl/cogl-util.c b/mutter/cogl/cogl/cogl-util.c deleted file mode 100644 index 4dffa82..0000000 --- a/mutter/cogl/cogl/cogl-util.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include - -#include "cogl/cogl-util.h" -#include "cogl/cogl-private.h" - -unsigned int -_cogl_util_one_at_a_time_mix (unsigned int hash) -{ - hash += ( hash << 3 ); - hash ^= ( hash >> 11 ); - hash += ( hash << 15 ); - - return hash; -} - -/* Given a set of red, green and blue component masks, a depth and - * bits per pixel this function tries to determine a corresponding - * CoglPixelFormat. - * - * The depth is measured in bits not including padding for un-used - * alpha. The bits per pixel (bpp) does include padding for un-used - * alpha. - * - * This function firstly aims to match formats with RGB ordered - * components and only considers alpha coming first, in the most - * significant bits. If the function fails to match then it recurses - * by either switching the r and b masks around to check for BGR - * ordered formats or it recurses with the masks shifted to check for - * formats where the alpha component is the least significant bits. - */ -static CoglPixelFormat -_cogl_util_pixel_format_from_masks_real (unsigned long r_mask, - unsigned long g_mask, - unsigned long b_mask, - int depth, int bpp, - gboolean check_bgr, - gboolean check_afirst, - int recursion_depth) -{ - CoglPixelFormat image_format; - - if (depth == 24 && bpp == 24 && - r_mask == 0xff0000 && g_mask == 0xff00 && b_mask == 0xff) - { - return COGL_PIXEL_FORMAT_RGB_888; - } - else if ((depth == 24 || depth == 32) && bpp == 32 && - r_mask == 0xff0000 && g_mask == 0xff00 && b_mask == 0xff) - { - return COGL_PIXEL_FORMAT_ARGB_8888_PRE; - } - else if ((depth == 30 || depth == 32) && - r_mask == 0x3ff00000 && g_mask == 0xffc00 && b_mask == 0x3ff) - { - return COGL_PIXEL_FORMAT_ARGB_2101010_PRE; - } - else if (depth == 16 && bpp == 16 && - r_mask == 0xf800 && g_mask == 0x7e0 && b_mask == 0x1f) - { - return COGL_PIXEL_FORMAT_RGB_565; - } - - if (recursion_depth == 2) - return 0; - - /* Check for BGR ordering if we didn't find a match */ - if (check_bgr) - { - image_format = - _cogl_util_pixel_format_from_masks_real (b_mask, g_mask, r_mask, - depth, bpp, - FALSE, - TRUE, - recursion_depth + 1); - if (image_format) - return image_format ^ COGL_BGR_BIT; - } - - /* Check for alpha in the least significant bits if we still - * haven't found a match... */ - if (check_afirst && depth != bpp) - { - int shift = bpp - depth; - - image_format = - _cogl_util_pixel_format_from_masks_real (r_mask >> shift, - g_mask >> shift, - b_mask >> shift, - depth, bpp, - TRUE, - FALSE, - recursion_depth + 1); - if (image_format) - return image_format ^ COGL_AFIRST_BIT; - } - - return 0; -} - -CoglPixelFormat -_cogl_util_pixel_format_from_masks (unsigned long r_mask, - unsigned long g_mask, - unsigned long b_mask, - int depth, int bpp, - gboolean byte_order_is_lsb_first) -{ - CoglPixelFormat image_format = - _cogl_util_pixel_format_from_masks_real (r_mask, g_mask, b_mask, - depth, bpp, - TRUE, - TRUE, - 0); - - if (!image_format) - { - const char *byte_order[] = { "MSB first", "LSB first" }; - g_warning ("Could not find a matching pixel format for red mask=0x%lx," - "green mask=0x%lx, blue mask=0x%lx at depth=%d, bpp=%d " - "and byte order=%s\n", r_mask, g_mask, b_mask, depth, bpp, - byte_order[!!byte_order_is_lsb_first]); - return 0; - } - - /* If the image is in little-endian then the order in memory is - reversed */ - if (byte_order_is_lsb_first && - _cogl_pixel_format_is_endian_dependant (image_format)) - { - image_format ^= COGL_BGR_BIT; - if (image_format & COGL_A_BIT) - image_format ^= COGL_AFIRST_BIT; - } - - return image_format; -} diff --git a/mutter/cogl/cogl/cogl-util.h b/mutter/cogl/cogl/cogl-util.h deleted file mode 100644 index f1009d4..0000000 --- a/mutter/cogl/cogl/cogl-util.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include -#include - -#include "cogl/cogl-pixel-format.h" -#include "cogl/cogl-types.h" - -#include - -/* This is a replacement for the nearbyint function which always - rounds to the nearest integer. nearbyint is apparently a C99 - function so it might not always be available but also it seems in - glibc it is defined as a function call so this macro could end up - faster anyway. We can't just add 0.5f because it will break for - negative numbers. */ -#define COGL_UTIL_NEARBYINT(x) ((int) ((x) < 0.0f ? (x) - 0.5f : (x) + 0.5f)) - - -/* Split Bob Jenkins' One-at-a-Time hash - * - * This uses the One-at-a-Time hash algorithm designed by Bob Jenkins - * but the mixing step is split out so the function can be used in a - * more incremental fashion. - */ -static inline unsigned int -_cogl_util_one_at_a_time_hash (unsigned int hash, - const void *key, - size_t bytes) -{ - const unsigned char *p = key; - size_t i; - - for (i = 0; i < bytes; i++) - { - hash += p[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - - return hash; -} - -unsigned int -_cogl_util_one_at_a_time_mix (unsigned int hash); - - -#define _cogl_util_ffsl __builtin_ffsl - -static inline unsigned int -_cogl_util_fls (unsigned int n) -{ - return n == 0 ? 0 : sizeof (unsigned int) * 8 - __builtin_clz (n); -} - -#define _cogl_util_popcountl __builtin_popcountl - -/* Match a CoglPixelFormat according to channel masks, color depth, - * bits per pixel and byte order. These information are provided by - * the Visual and XImage structures. - * - * If no specific pixel format could be found, COGL_PIXEL_FORMAT_ANY - * is returned. - */ -CoglPixelFormat -_cogl_util_pixel_format_from_masks (unsigned long r_mask, - unsigned long g_mask, - unsigned long b_mask, - int depth, int bpp, - int byte_order); - -/* _COGL_STATIC_ASSERT: - * @expression: An expression to assert evaluates to true at compile - * time. - * @message: A message to print to the console if the assertion fails - * at compile time. - * - * Allows you to assert that an expression evaluates to true at - * compile time and aborts compilation if not. If possible message - * will also be printed if the assertion fails. - */ -#define _COGL_STATIC_ASSERT(EXPRESSION, MESSAGE) \ - _Static_assert (EXPRESSION, MESSAGE); - -static inline void -_cogl_util_scissor_intersect (int rect_x0, - int rect_y0, - int rect_x1, - int rect_y1, - int *scissor_x0, - int *scissor_y0, - int *scissor_x1, - int *scissor_y1) -{ - *scissor_x0 = MAX (*scissor_x0, rect_x0); - *scissor_y0 = MAX (*scissor_y0, rect_y0); - *scissor_x1 = MIN (*scissor_x1, rect_x1); - *scissor_y1 = MIN (*scissor_y1, rect_y1); -} diff --git a/mutter/cogl/cogl/cogl-x11-onscreen.c b/mutter/cogl/cogl/cogl-x11-onscreen.c deleted file mode 100644 index d355061..0000000 --- a/mutter/cogl/cogl/cogl-x11-onscreen.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2020 Red Hat Inc. - * - * 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, see . - * - */ - -#include "config.h" - -#include "cogl/cogl-x11-onscreen.h" - -G_DEFINE_INTERFACE (CoglX11Onscreen, cogl_x11_onscreen, - G_TYPE_OBJECT) - -Window -cogl_x11_onscreen_get_x11_window (CoglX11Onscreen *x11_onscreen) -{ - CoglX11OnscreenInterface *iface = - COGL_X11_ONSCREEN_GET_IFACE (x11_onscreen); - - return iface->get_x11_window (x11_onscreen); -} - -static void -cogl_x11_onscreen_default_init (CoglX11OnscreenInterface *iface) -{ -} diff --git a/mutter/cogl/cogl/cogl-x11-onscreen.h b/mutter/cogl/cogl/cogl-x11-onscreen.h deleted file mode 100644 index 93abecc..0000000 --- a/mutter/cogl/cogl/cogl-x11-onscreen.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2020 Red Hat Inc. - * - * 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, see . - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include -#include - -#include "cogl/cogl-macros.h" - -#define COGL_TYPE_X11_ONSCREEN (cogl_x11_onscreen_get_type ()) -COGL_EXPORT -G_DECLARE_INTERFACE (CoglX11Onscreen, cogl_x11_onscreen, - COGL, X11_ONSCREEN, - GObject) - -struct _CoglX11OnscreenInterface -{ - GTypeInterface parent_iface; - - Window (* get_x11_window) (CoglX11Onscreen *x11_onscreen); -}; - -COGL_EXPORT -Window cogl_x11_onscreen_get_x11_window (CoglX11Onscreen *x11_onscreen); diff --git a/mutter/cogl/cogl/cogl-x11-renderer-private.h b/mutter/cogl/cogl/cogl-x11-renderer-private.h deleted file mode 100644 index 5a05595..0000000 --- a/mutter/cogl/cogl/cogl-x11-renderer-private.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -typedef struct _CoglX11Renderer -{ - int damage_base; - int randr_base; -} CoglX11Renderer; diff --git a/mutter/cogl/cogl/cogl-xlib-renderer-private.h b/mutter/cogl/cogl/cogl-xlib-renderer-private.h deleted file mode 100644 index 8169129..0000000 --- a/mutter/cogl/cogl/cogl-xlib-renderer-private.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include - -#include "cogl/cogl-x11-renderer-private.h" -#include "cogl/cogl-context.h" -#include "cogl/cogl-output.h" - -typedef struct _CoglXlibRenderer -{ - CoglX11Renderer _parent; - - Display *xdpy; - - unsigned long outputs_update_serial; -} CoglXlibRenderer; - -gboolean -_cogl_xlib_renderer_connect (CoglRenderer *renderer, GError **error); - -void -_cogl_xlib_renderer_disconnect (CoglRenderer *renderer); - -CoglXlibRenderer * -_cogl_xlib_renderer_get_data (CoglRenderer *renderer); - -CoglOutput * -_cogl_xlib_renderer_output_for_rectangle (CoglRenderer *renderer, - int x, - int y, - int width, - int height); diff --git a/mutter/cogl/cogl/cogl-xlib-renderer.c b/mutter/cogl/cogl/cogl-xlib-renderer.c deleted file mode 100644 index 71cb43e..0000000 --- a/mutter/cogl/cogl/cogl-xlib-renderer.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-xlib-renderer.h" -#include "cogl/cogl-util.h" - -#include "cogl/cogl-output-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-xlib-renderer-private.h" -#include "cogl/cogl-x11-renderer-private.h" -#include "cogl/cogl-poll-private.h" -#include "cogl/winsys/cogl-winsys-private.h" -#include "mtk/mtk-x11.h" - -#include -#include -#include - -#include -#include - -static char *_cogl_x11_display_name = NULL; -static GList *_cogl_xlib_renderers = NULL; - -static void -_xlib_renderer_data_free (CoglXlibRenderer *data) -{ - g_free (data); -} - -CoglXlibRenderer * -_cogl_xlib_renderer_get_data (CoglRenderer *renderer) -{ - /* Constructs a CoglXlibRenderer struct on demand and attaches it to - the object using user data. It's done this way instead of using a - subclassing hierarchy in the winsys data because all EGL winsys's - need the EGL winsys data but only one of them wants the Xlib - data. */ - - if (!renderer->custom_winsys_user_data) - renderer->custom_winsys_user_data = g_new0 (CoglXlibRenderer, 1); - - return renderer->custom_winsys_user_data; -} - -static void -register_xlib_renderer (CoglRenderer *renderer) -{ - GList *l; - - for (l = _cogl_xlib_renderers; l; l = l->next) - if (l->data == renderer) - return; - - _cogl_xlib_renderers = g_list_prepend (_cogl_xlib_renderers, renderer); -} - -static void -unregister_xlib_renderer (CoglRenderer *renderer) -{ - _cogl_xlib_renderers = g_list_remove (_cogl_xlib_renderers, renderer); -} - -static Display * -assert_xlib_display (CoglRenderer *renderer, GError **error) -{ - Display *xdpy = cogl_xlib_renderer_get_foreign_display (renderer); - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - /* A foreign display may have already been set... */ - if (xdpy) - { - xlib_renderer->xdpy = xdpy; - return xdpy; - } - - xdpy = XOpenDisplay (_cogl_x11_display_name); - if (xdpy == NULL) - { - g_set_error (error, - COGL_RENDERER_ERROR, - COGL_RENDERER_ERROR_XLIB_DISPLAY_OPEN, - "Failed to open X Display %s", _cogl_x11_display_name); - return NULL; - } - - xlib_renderer->xdpy = xdpy; - return xdpy; -} - -static int -compare_outputs (CoglOutput *a, - CoglOutput *b) -{ - return strcmp (a->name, b->name); -} - -#define CSO(X) COGL_SUBPIXEL_ORDER_ ## X -static CoglSubpixelOrder subpixel_map[6][6] = { - { CSO(UNKNOWN), CSO(NONE), CSO(HORIZONTAL_RGB), CSO(HORIZONTAL_BGR), - CSO(VERTICAL_RGB), CSO(VERTICAL_BGR) }, /* 0 */ - { CSO(UNKNOWN), CSO(NONE), CSO(VERTICAL_RGB), CSO(VERTICAL_BGR), - CSO(HORIZONTAL_BGR), CSO(HORIZONTAL_RGB) }, /* 90 */ - { CSO(UNKNOWN), CSO(NONE), CSO(HORIZONTAL_BGR), CSO(HORIZONTAL_RGB), - CSO(VERTICAL_BGR), CSO(VERTICAL_RGB) }, /* 180 */ - { CSO(UNKNOWN), CSO(NONE), CSO(VERTICAL_BGR), CSO(VERTICAL_RGB), - CSO(HORIZONTAL_RGB), CSO(HORIZONTAL_BGR) }, /* 270 */ - { CSO(UNKNOWN), CSO(NONE), CSO(HORIZONTAL_BGR), CSO(HORIZONTAL_RGB), - CSO(VERTICAL_RGB), CSO(VERTICAL_BGR) }, /* Reflect_X */ - { CSO(UNKNOWN), CSO(NONE), CSO(HORIZONTAL_RGB), CSO(HORIZONTAL_BGR), - CSO(VERTICAL_BGR), CSO(VERTICAL_RGB) }, /* Reflect_Y */ -}; -#undef CSO - -static void -update_outputs (CoglRenderer *renderer, - gboolean notify) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - XRRScreenResources *resources; - gboolean error = FALSE; - GList *new_outputs = NULL; - GList *l, *m; - gboolean changed = FALSE; - int i; - - xlib_renderer->outputs_update_serial = XNextRequest (xlib_renderer->xdpy); - - resources = XRRGetScreenResources (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy)); - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - for (i = 0; resources && i < resources->ncrtc && !error; i++) - { - XRRCrtcInfo *crtc_info = NULL; - XRROutputInfo *output_info = NULL; - CoglOutput *output; - float refresh_rate = 0; - int j; - - crtc_info = XRRGetCrtcInfo (xlib_renderer->xdpy, - resources, resources->crtcs[i]); - if (crtc_info == NULL) - { - error = TRUE; - goto next; - } - - if (crtc_info->mode == None) - goto next; - - for (j = 0; j < resources->nmode; j++) - { - if (resources->modes[j].id == crtc_info->mode) - refresh_rate = (resources->modes[j].dotClock / - ((float)resources->modes[j].hTotal * - resources->modes[j].vTotal)); - } - - output_info = XRRGetOutputInfo (xlib_renderer->xdpy, - resources, - crtc_info->outputs[0]); - if (output_info == NULL) - { - error = TRUE; - goto next; - } - - output = _cogl_output_new (output_info->name); - output->x = crtc_info->x; - output->y = crtc_info->y; - output->width = crtc_info->width; - output->height = crtc_info->height; - if ((crtc_info->rotation & (RR_Rotate_90 | RR_Rotate_270)) != 0) - { - output->mm_width = output_info->mm_height; - output->mm_height = output_info->mm_width; - } - else - { - output->mm_width = output_info->mm_width; - output->mm_height = output_info->mm_height; - } - - output->refresh_rate = refresh_rate; - - switch (output_info->subpixel_order) - { - case SubPixelUnknown: - default: - output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; - break; - case SubPixelNone: - output->subpixel_order = COGL_SUBPIXEL_ORDER_NONE; - break; - case SubPixelHorizontalRGB: - output->subpixel_order = COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB; - break; - case SubPixelHorizontalBGR: - output->subpixel_order = COGL_SUBPIXEL_ORDER_HORIZONTAL_BGR; - break; - case SubPixelVerticalRGB: - output->subpixel_order = COGL_SUBPIXEL_ORDER_VERTICAL_RGB; - break; - case SubPixelVerticalBGR: - output->subpixel_order = COGL_SUBPIXEL_ORDER_VERTICAL_BGR; - break; - } - - output->subpixel_order = COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB; - - /* Handle the effect of rotation and reflection on subpixel order (ugh) */ - for (j = 0; j < 6; j++) - { - if ((crtc_info->rotation & (1 << j)) != 0) - output->subpixel_order = subpixel_map[j][output->subpixel_order]; - } - - new_outputs = g_list_prepend (new_outputs, output); - - next: - if (crtc_info != NULL) - XFree (crtc_info); - - if (output_info != NULL) - XFree (output_info); - } - - XFree (resources); - - if (!error) - { - new_outputs = g_list_sort (new_outputs, (GCompareFunc)compare_outputs); - - l = new_outputs; - m = renderer->outputs; - - while (l || m) - { - int cmp; - CoglOutput *output_l = l ? (CoglOutput *)l->data : NULL; - CoglOutput *output_m = m ? (CoglOutput *)m->data : NULL; - - if (l && m) - cmp = compare_outputs (output_l, output_m); - else if (l) - cmp = -1; - else - cmp = 1; - - if (cmp == 0) - { - GList *m_next = m->next; - - if (!_cogl_output_values_equal (output_l, output_m)) - { - renderer->outputs = g_list_remove_link (renderer->outputs, m); - renderer->outputs = g_list_insert_before (renderer->outputs, - m_next, output_l); - g_object_ref (output_l); - - changed = TRUE; - } - - l = l->next; - m = m_next; - } - else if (cmp < 0) - { - renderer->outputs = - g_list_insert_before (renderer->outputs, m, output_l); - g_object_ref (output_l); - changed = TRUE; - l = l->next; - } - else - { - GList *m_next = m->next; - renderer->outputs = g_list_remove_link (renderer->outputs, m); - changed = TRUE; - m = m_next; - } - } - } - - g_list_free_full (new_outputs, (GDestroyNotify)g_object_unref); - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - - if (changed) - { - const CoglWinsysVtable *winsys = renderer->winsys_vtable; - - if (notify) - COGL_NOTE (WINSYS, "Outputs changed:"); - else - COGL_NOTE (WINSYS, "Outputs:"); - - for (l = renderer->outputs; l; l = l->next) - { - CoglOutput *output = l->data; - const char *subpixel_string; - - switch (output->subpixel_order) - { - case COGL_SUBPIXEL_ORDER_UNKNOWN: - default: - subpixel_string = "unknown"; - break; - case COGL_SUBPIXEL_ORDER_NONE: - subpixel_string = "none"; - break; - case COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB: - subpixel_string = "horizontal_rgb"; - break; - case COGL_SUBPIXEL_ORDER_HORIZONTAL_BGR: - subpixel_string = "horizontal_bgr"; - break; - case COGL_SUBPIXEL_ORDER_VERTICAL_RGB: - subpixel_string = "vertical_rgb"; - break; - case COGL_SUBPIXEL_ORDER_VERTICAL_BGR: - subpixel_string = "vertical_bgr"; - break; - } - - COGL_NOTE (WINSYS, - " %10s: +%d+%dx%dx%d mm=%dx%d dpi=%.1fx%.1f " - "subpixel_order=%s refresh_rate=%.3f", - output->name, - output->x, output->y, output->width, output->height, - output->mm_width, output->mm_height, - output->width / (output->mm_width / 25.4), - output->height / (output->mm_height / 25.4), - subpixel_string, - output->refresh_rate); - } - - if (notify && winsys->renderer_outputs_changed != NULL) - winsys->renderer_outputs_changed (renderer); - } -} - -static CoglFilterReturn -randr_filter (XEvent *event, - void *data) -{ - CoglRenderer *renderer = data; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - CoglX11Renderer *x11_renderer = - (CoglX11Renderer *) xlib_renderer; - - if (x11_renderer->randr_base != -1 && - (event->xany.type == x11_renderer->randr_base + RRScreenChangeNotify || - event->xany.type == x11_renderer->randr_base + RRNotify) && - event->xany.serial >= xlib_renderer->outputs_update_serial) - update_outputs (renderer, TRUE); - - return COGL_FILTER_CONTINUE; -} - -static int64_t -prepare_xlib_events_timeout (void *user_data) -{ - CoglRenderer *renderer = user_data; - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - return XPending (xlib_renderer->xdpy) ? 0 : -1; -} - -static void -dispatch_xlib_events (void *user_data, int revents) -{ - CoglRenderer *renderer = user_data; - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - if (renderer->xlib_enable_event_retrieval) - while (XPending (xlib_renderer->xdpy)) - { - XEvent xevent; - - XNextEvent (xlib_renderer->xdpy, &xevent); - - cogl_xlib_renderer_handle_event (renderer, &xevent); - } -} - -gboolean -_cogl_xlib_renderer_connect (CoglRenderer *renderer, GError **error) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - CoglX11Renderer *x11_renderer = - (CoglX11Renderer *) xlib_renderer; - int damage_error; - int randr_error; - - if (!assert_xlib_display (renderer, error)) - return FALSE; - - if (getenv ("COGL_X11_SYNC")) - XSynchronize (xlib_renderer->xdpy, TRUE); - - /* Check whether damage events are supported on this display */ - if (!XDamageQueryExtension (xlib_renderer->xdpy, - &x11_renderer->damage_base, - &damage_error)) - x11_renderer->damage_base = -1; - - /* Check whether randr is supported on this display */ - if (!XRRQueryExtension (xlib_renderer->xdpy, - &x11_renderer->randr_base, - &randr_error)) - x11_renderer->randr_base = -1; - - if (renderer->xlib_enable_event_retrieval) - { - _cogl_poll_renderer_add_fd (renderer, - ConnectionNumber (xlib_renderer->xdpy), - COGL_POLL_FD_EVENT_IN, - prepare_xlib_events_timeout, - dispatch_xlib_events, - renderer); - } - - XRRSelectInput(xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - RRScreenChangeNotifyMask - | RRCrtcChangeNotifyMask - | RROutputPropertyNotifyMask); - update_outputs (renderer, FALSE); - - register_xlib_renderer (renderer); - - cogl_xlib_renderer_add_filter (renderer, - randr_filter, - renderer); - - return TRUE; -} - -void -_cogl_xlib_renderer_disconnect (CoglRenderer *renderer) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - - g_list_free_full (renderer->outputs, (GDestroyNotify)g_object_unref); - renderer->outputs = NULL; - - if (!renderer->foreign_xdpy && xlib_renderer->xdpy) - XCloseDisplay (xlib_renderer->xdpy); - - g_clear_pointer (&renderer->custom_winsys_user_data, _xlib_renderer_data_free); - - unregister_xlib_renderer (renderer); -} - -Display * -cogl_xlib_renderer_get_display (CoglRenderer *renderer) -{ - CoglXlibRenderer *xlib_renderer; - - g_return_val_if_fail (COGL_IS_RENDERER (renderer), NULL); - - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - return xlib_renderer->xdpy; -} - -CoglFilterReturn -cogl_xlib_renderer_handle_event (CoglRenderer *renderer, - XEvent *event) -{ - return _cogl_renderer_handle_native_event (renderer, event); -} - -void -cogl_xlib_renderer_add_filter (CoglRenderer *renderer, - CoglXlibFilterFunc func, - void *data) -{ - _cogl_renderer_add_native_filter (renderer, - (CoglNativeFilterFunc)func, data); -} - -void -cogl_xlib_renderer_remove_filter (CoglRenderer *renderer, - CoglXlibFilterFunc func, - void *data) -{ - _cogl_renderer_remove_native_filter (renderer, - (CoglNativeFilterFunc)func, data); -} - -CoglOutput * -_cogl_xlib_renderer_output_for_rectangle (CoglRenderer *renderer, - int x, - int y, - int width, - int height) -{ - int max_overlap = 0; - CoglOutput *max_overlapped = NULL; - GList *l; - int xa1 = x, xa2 = x + width; - int ya1 = y, ya2 = y + height; - - for (l = renderer->outputs; l; l = l->next) - { - CoglOutput *output = l->data; - int xb1 = output->x, xb2 = output->x + output->width; - int yb1 = output->y, yb2 = output->y + output->height; - - int overlap_x = MIN(xa2, xb2) - MAX(xa1, xb1); - int overlap_y = MIN(ya2, yb2) - MAX(ya1, yb1); - - if (overlap_x > 0 && overlap_y > 0) - { - int overlap = overlap_x * overlap_y; - if (overlap > max_overlap) - { - max_overlap = overlap; - max_overlapped = output; - } - } - } - - return max_overlapped; -} diff --git a/mutter/cogl/cogl/cogl-xlib-renderer.h b/mutter/cogl/cogl/cogl-xlib-renderer.h deleted file mode 100644 index ac6a0ee..0000000 --- a/mutter/cogl/cogl/cogl-xlib-renderer.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#if !defined(__COGL_XLIB_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include -#include - -/* NB: this is a top-level header that can be included directly but we - * want to be careful not to define __COGL_H_INSIDE__ when this is - * included internally while building Cogl itself since - * __COGL_H_INSIDE__ is used in headers to guard public vs private api - * definitions - */ -#ifndef COGL_COMPILATION - -/* Note: When building Cogl .gir we explicitly define - * __COGL_H_INSIDE__ */ -#ifndef __COGL_H_INSIDE__ -#define __COGL_H_INSIDE__ -#define __COGL_XLIB_RENDERER_H_MUST_UNDEF_COGL_H_INSIDE_COGL_XLIB_RENDERER_ -#endif - -#endif /* COGL_COMPILATION */ - -#include "cogl/cogl-renderer.h" - -G_BEGIN_DECLS - -/** - * cogl_xlib_renderer_handle_event: (skip) - * @renderer: a #CoglRenderer - * @event: pointer to an XEvent structure - * - * This function processes a single event; it can be used to hook into - * external event retrieval (for example that done by Clutter or - * GDK). - * - * Return value: #CoglFilterReturn. %COGL_FILTER_REMOVE indicates that - * Cogl has internally handled the event and the caller should do no - * further processing. %COGL_FILTER_CONTINUE indicates that Cogl is - * either not interested in the event, or has used the event to update - * internal state without taking any exclusive action. - */ -COGL_EXPORT CoglFilterReturn -cogl_xlib_renderer_handle_event (CoglRenderer *renderer, - XEvent *event); - -/* - * CoglXlibFilterFunc: - * @event: pointer to an XEvent structure - * @data: the data that was given when the filter was added - * - * A callback function that can be registered with - * cogl_xlib_renderer_add_filter(). The function should return - * %COGL_FILTER_REMOVE if it wants to prevent further processing or - * %COGL_FILTER_CONTINUE otherwise. - */ -typedef CoglFilterReturn (* CoglXlibFilterFunc) (XEvent *event, - void *data); - -/** - * cogl_xlib_renderer_add_filter: (skip) - * @renderer: a #CoglRenderer - * @func: the callback function - * @data: user data passed to @func when called - * - * Adds a callback function that will receive all native events. The - * function can stop further processing of the event by return - * %COGL_FILTER_REMOVE. - */ -COGL_EXPORT void -cogl_xlib_renderer_add_filter (CoglRenderer *renderer, - CoglXlibFilterFunc func, - void *data); - -/** - * cogl_xlib_renderer_remove_filter: (skip) - * @renderer: a #CoglRenderer - * @func: the callback function - * @data: user data given when the callback was installed - * - * Removes a callback that was previously added with - * cogl_xlib_renderer_add_filter(). - */ -COGL_EXPORT void -cogl_xlib_renderer_remove_filter (CoglRenderer *renderer, - CoglXlibFilterFunc func, - void *data); - -/** - * cogl_xlib_renderer_get_foreign_display: (skip) - * @renderer: a #CoglRenderer - * - * Return value: the foreign Xlib display that will be used by any Xlib based - * winsys backend. The display needs to be set with - * cogl_xlib_renderer_set_foreign_display() before this function is called. - */ -COGL_EXPORT Display * -cogl_xlib_renderer_get_foreign_display (CoglRenderer *renderer); - -/** - * cogl_xlib_renderer_set_foreign_display: (skip) - * @renderer: a #CoglRenderer - * - * Sets a foreign Xlib display that Cogl will use for and Xlib based winsys - * backend. - * - * Note that calling this function will automatically disable Cogl's - * event retrieval. Cogl still needs to see all of the X events so the - * application should also use cogl_xlib_renderer_handle_event() if it - * uses this function. - */ -COGL_EXPORT void -cogl_xlib_renderer_set_foreign_display (CoglRenderer *renderer, - Display *display); - -/** - * cogl_xlib_renderer_get_display: (skip) - */ -COGL_EXPORT Display * -cogl_xlib_renderer_get_display (CoglRenderer *renderer); - -/** - * cogl_xlib_renderer_request_reset_on_video_memory_purge: (skip) - * @renderer: a #CoglRenderer - * @enable: The new value - * - * Sets whether Cogl should make use of the - * NV_robustness_video_memory_purge extension, if exposed by the - * driver, by initializing the GLX context appropriately. - * - * The extension is only useful when running on certain versions of - * the NVIDIA driver. Quoting from the spec: - * - * "The NVIDIA OpenGL driver architecture on Linux has a limitation: - * resources located in video memory are not persistent across certain - * events. VT switches, suspend/resume events, and mode switching - * events may erase the contents of video memory. Any resource that - * is located exclusively in video memory, such as framebuffer objects - * (FBOs), will be lost." - * - * "This extension provides a way for applications to discover when video - * memory content has been lost, so that the application can re-populate - * the video memory content as necessary." - * - * "Any driver that exposes this extension is a driver that considers - * video memory to be volatile. Once the driver stack has been - * improved, the extension will no longer be exposed." - * - * cogl_get_graphics_reset_status() needs to be called at least once - * every frame to find out if video memory was purged. - * - * Note that this doesn't cause Cogl to enable robust buffer access - * but other context reset errors may still happen and be reported via - * cogl_get_graphics_reset_status() if external factors cause the - * driver to trigger them. - * - * This defaults to %FALSE and is effective only if called before - * cogl_display_setup() . - */ -COGL_EXPORT void -cogl_xlib_renderer_request_reset_on_video_memory_purge (CoglRenderer *renderer, - gboolean enable); -G_END_DECLS - -/* The gobject introspection scanner seems to parse public headers in - * isolation which means we need to be extra careful about how we - * define and undefine __COGL_H_INSIDE__ used to detect when internal - * headers are incorrectly included by developers. In the gobject - * introspection case we have to manually define __COGL_H_INSIDE__ as - * a commandline argument for the scanner which means we must be - * careful not to undefine it in a header... - */ -#ifdef __COGL_XLIB_RENDERER_H_MUST_UNDEF_COGL_H_INSIDE_COGL_XLIB_RENDERER_ -#undef __COGL_H_INSIDE__ -#undef __COGL_XLIB_RENDERER_H_MUST_UNDEF_COGL_H_INSIDE_COGL_XLIB_RENDERER_ -#endif diff --git a/mutter/cogl/cogl/cogl-xlib.h b/mutter/cogl/cogl/cogl-xlib.h deleted file mode 100644 index 0e65991..0000000 --- a/mutter/cogl/cogl/cogl-xlib.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#include - -/* NB: this is a top-level header that can be included directly but we - * want to be careful not to define __COGL_H_INSIDE__ when this is - * included internally while building Cogl itself since - * __COGL_H_INSIDE__ is used in headers to guard public vs private api - * definitions - */ -#ifndef COGL_COMPILATION - -/* Note: When building Cogl .gir we explicitly define - * __COGL_XLIB_H_INSIDE__ */ -#ifndef __COGL_XLIB_H_INSIDE__ -#define __COGL_XLIB_H_INSIDE__ -#endif - -/* Note: When building Cogl .gir we explicitly define - * __COGL_H_INSIDE__ */ -#ifndef __COGL_H_INSIDE__ -#define __COGL_H_INSIDE__ -#define __COGL_XLIB_H_MUST_UNDEF_COGL_H_INSIDE__ -#endif - -#endif /* COGL_COMPILATION */ - -#include "cogl/cogl-types.h" -#include "cogl/cogl-xlib-renderer.h" -#include "cogl/cogl-macros.h" - -/* The gobject introspection scanner seems to parse public headers in - * isolation which means we need to be extra careful about how we - * define and undefine __COGL_H_INSIDE__ used to detect when internal - * headers are incorrectly included by developers. In the gobject - * introspection case we have to manually define __COGL_H_INSIDE__ as - * a commandline argument for the scanner which means we must be - * careful not to undefine it in a header... - */ -#ifdef __COGL_XLIB_H_MUST_UNDEF_COGL_H_INSIDE__ -#undef __COGL_H_INSIDE__ -#undef __COGL_XLIB_H_INSIDE__ -#undef __COGL_XLIB_H_MUST_UNDEF_COGL_H_INSIDE__ -#endif diff --git a/mutter/cogl/cogl/cogl.c b/mutter/cogl/cogl/cogl.c deleted file mode 100644 index 924e18e..0000000 --- a/mutter/cogl/cogl/cogl.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include -#include -#include - -#include "cogl/cogl-i18n-private.h" -#include "cogl/cogl-cpu-caps.h" -#include "cogl/cogl-debug.h" -#include "cogl/cogl-graphene.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-journal-private.h" -#include "cogl/cogl-bitmap-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-texture-driver.h" -#include "cogl/cogl-attribute-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl1-context.h" -#include "cogl/cogl-offscreen.h" -#include "cogl/winsys/cogl-winsys-private.h" - -GCallback -cogl_get_proc_address (const char* name) -{ - _COGL_GET_CONTEXT (ctx, NULL); - - return _cogl_renderer_get_proc_address (ctx->display->renderer, name); -} - -gboolean -_cogl_check_extension (const char *name, char * const *ext) -{ - while (*ext) - if (!strcmp (name, *ext)) - return TRUE; - else - ext++; - - return FALSE; -} - -gboolean -cogl_has_feature (CoglContext *ctx, CoglFeatureID feature) -{ - return COGL_FLAGS_GET (ctx->features, feature); -} - -gboolean -cogl_has_features (CoglContext *ctx, ...) -{ - va_list args; - CoglFeatureID feature; - - va_start (args, ctx); - while ((feature = va_arg (args, CoglFeatureID))) - if (!cogl_has_feature (ctx, feature)) - return FALSE; - va_end (args); - - return TRUE; -} - -void -cogl_foreach_feature (CoglContext *ctx, - CoglFeatureCallback callback, - void *user_data) -{ - int i; - for (i = 0; i < _COGL_N_FEATURE_IDS; i++) - if (COGL_FLAGS_GET (ctx->features, i)) - callback (i, user_data); -} - -void -cogl_flush (void) -{ - GList *l; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - for (l = ctx->framebuffers; l; l = l->next) - _cogl_framebuffer_flush_journal (l->data); -} - -uint32_t -_cogl_driver_error_quark (void) -{ - return g_quark_from_static_string ("cogl-driver-error-quark"); -} - -/* Scale from OpenGL normalized device coordinates (ranging from -1 to 1) - * to Cogl window/framebuffer coordinates (ranging from 0 to buffer-size) with - * (0,0) being top left. */ -#define VIEWPORT_TRANSFORM_X(x, vp_origin_x, vp_width) \ - ( ( ((x) + 1.0) * ((vp_width) / 2.0) ) + (vp_origin_x) ) -/* Note: for Y we first flip all coordinates around the X axis while in - * normalized device coordinates */ -#define VIEWPORT_TRANSFORM_Y(y, vp_origin_y, vp_height) \ - ( ( ((-(y)) + 1.0) * ((vp_height) / 2.0) ) + (vp_origin_y) ) - -/* Transform a homogeneous vertex position from model space to Cogl - * window coordinates (with 0,0 being top left) */ -void -_cogl_transform_point (const graphene_matrix_t *matrix_mv, - const graphene_matrix_t *matrix_p, - const float *viewport, - float *x, - float *y) -{ - float z = 0; - float w = 1; - - /* Apply the modelview matrix transform */ - cogl_graphene_matrix_project_point (matrix_mv, x, y, &z, &w); - - /* Apply the projection matrix transform */ - cogl_graphene_matrix_project_point (matrix_p, x, y, &z, &w); - - /* Perform perspective division */ - *x /= w; - *y /= w; - - /* Apply viewport transform */ - *x = VIEWPORT_TRANSFORM_X (*x, viewport[0], viewport[2]); - *y = VIEWPORT_TRANSFORM_Y (*y, viewport[1], viewport[3]); -} - -#undef VIEWPORT_TRANSFORM_X -#undef VIEWPORT_TRANSFORM_Y - -uint32_t -_cogl_system_error_quark (void) -{ - return g_quark_from_static_string ("cogl-system-error-quark"); -} - -void -_cogl_init (void) -{ - static gboolean initialized = FALSE; - - if (initialized == FALSE) - { - _cogl_debug_check_environment (); - cogl_init_cpu_caps (); - initialized = TRUE; - } -} diff --git a/mutter/cogl/cogl/cogl.h b/mutter/cogl/cogl/cogl.h deleted file mode 100644 index 50f042c..0000000 --- a/mutter/cogl/cogl/cogl.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#ifdef COGL_COMPILATION -#error " shouldn't be included internally" -#endif - -/* Note: When building Cogl .gir we explicitly define - * __COGL_H_INSIDE__ */ -#ifndef __COGL_H_INSIDE__ -#define __COGL_H_INSIDE__ -#define __COGL_MUST_UNDEF_COGL_H_INSIDE__ -#endif - -#include - -#include "cogl/cogl-macros.h" - -#include "cogl/cogl1-context.h" -#include "cogl/cogl-bitmap.h" -#include "cogl/cogl-color.h" -#include "cogl/cogl-dma-buf-handle.h" -#include "cogl/cogl-matrix-stack.h" -#include "cogl/cogl-offscreen.h" -#include "cogl/cogl-pixel-format.h" -#include "cogl/cogl-texture.h" -#include "cogl/cogl-types.h" - - -#include "cogl/deprecated/cogl-shader.h" - -#ifdef COGL_ENABLE_MUTTER_API -#include "cogl/cogl-mutter.h" -#endif - -#include "cogl/cogl-swap-chain.h" -#include "cogl/cogl-renderer.h" -#include "cogl/cogl-output.h" -#include "cogl/cogl-display.h" -#include "cogl/cogl-context.h" -#include "cogl/cogl-buffer.h" -#include "cogl/cogl-pixel-buffer.h" -#include "cogl/cogl-texture-2d.h" -#include "cogl/cogl-texture-2d-sliced.h" -#include "cogl/cogl-sub-texture.h" -#include "cogl/cogl-atlas-texture.h" -#include "cogl/cogl-meta-texture.h" -#include "cogl/cogl-primitive-texture.h" -#include "cogl/cogl-enum-types.h" -#include "cogl/cogl-index-buffer.h" -#include "cogl/cogl-attribute-buffer.h" -#include "cogl/cogl-indices.h" -#include "cogl/cogl-attribute.h" -#include "cogl/cogl-primitive.h" -#include "cogl/cogl-depth-state.h" -#include "cogl/cogl-pipeline.h" -#include "cogl/cogl-pipeline-state.h" -#include "cogl/cogl-pipeline-layer-state.h" -#include "cogl/cogl-snippet.h" -#include "cogl/cogl-framebuffer.h" -#include "cogl/cogl-onscreen.h" -#include "cogl/cogl-frame-info.h" -#include "cogl/cogl-poll.h" -#include "cogl/cogl-fence.h" -#include "cogl/cogl-glib-source.h" -#include "cogl/cogl-trace.h" -#include "cogl/cogl-scanout.h" -#include "cogl/cogl-graphene.h" -/* XXX: This will definitely go away once all the Clutter winsys - * code has been migrated down into Cogl! */ -#include "cogl/deprecated/cogl-clutter.h" - -/* The gobject introspection scanner seems to parse public headers in - * isolation which means we need to be extra careful about how we - * define and undefine __COGL_H_INSIDE__ used to detect when internal - * headers are incorrectly included by developers. In the gobject - * introspection case we have to manually define __COGL_H_INSIDE__ as - * a commandline argument for the scanner which means we must be - * careful not to undefine it in a header... - */ -#ifdef __COGL_MUST_UNDEF_COGL_H_INSIDE__ -#undef __COGL_H_INSIDE__ -#undef __COGL_MUST_UNDEF_COGL_H_INSIDE__ -#endif diff --git a/mutter/cogl/cogl/cogl1-context.h b/mutter/cogl/cogl/cogl1-context.h deleted file mode 100644 index 9164ea7..0000000 --- a/mutter/cogl/cogl/cogl1-context.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-types.h" -#include "cogl/cogl-texture.h" -#include "cogl/cogl-framebuffer.h" -#include "cogl/cogl-macros.h" - -G_BEGIN_DECLS - -/* Misc */ -/** - * cogl_get_proc_address: (skip) - * @name: the name of the function. - * - * Gets a pointer to a given GL or GL ES extension function. This acts - * as a wrapper around glXGetProcAddress() or whatever is the - * appropriate function for the current backend. - * - * This function should not be used to query core opengl API - * symbols since eglGetProcAddress for example doesn't allow this and - * and may return a junk pointer if you do. - * - * Return value: a pointer to the requested function or %NULL if the - * function is not available. - */ -COGL_EXPORT GCallback -cogl_get_proc_address (const char *name); - -/** - * cogl_flush: - * - * This function should only need to be called in exceptional circumstances. - * - * As an optimization Cogl drawing functions may batch up primitives - * internally, so if you are trying to use raw GL outside of Cogl you stand a - * better chance of being successful if you ask Cogl to flush any batched - * geometry before making your state changes. - * - * It only ensure that the underlying driver is issued all the commands - * necessary to draw the batched primitives. It provides no guarantees about - * when the driver will complete the rendering. - * - * This provides no guarantees about the GL state upon returning and to avoid - * confusing Cogl you should aim to restore any changes you make before - * resuming use of Cogl. - * - * If you are making state changes with the intention of affecting Cogl drawing - * primitives you are 100% on your own since you stand a good chance of - * conflicting with Cogl internals. For example clutter-gst which currently - * uses direct GL calls to bind ARBfp programs will very likely break when Cogl - * starts to use ARBfb programs itself for the material API. - */ -COGL_EXPORT void -cogl_flush (void); - -G_END_DECLS diff --git a/mutter/cogl/cogl/deprecated/cogl-clutter.c b/mutter/cogl/cogl/deprecated/cogl-clutter.c deleted file mode 100644 index f1fc685..0000000 --- a/mutter/cogl/cogl/deprecated/cogl-clutter.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include -#include - -#include "cogl/cogl-util.h" -#include "cogl/cogl-types.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-onscreen-private.h" -#ifdef HAVE_X11 -#include "cogl/cogl-xlib-renderer.h" -#endif -#include "cogl/winsys/cogl-winsys-private.h" -#include "cogl/deprecated/cogl-clutter.h" - -gboolean -cogl_clutter_winsys_has_feature (CoglWinsysFeature feature) -{ - return _cogl_winsys_has_feature (feature); -} diff --git a/mutter/cogl/cogl/deprecated/cogl-clutter.h b/mutter/cogl/cogl/deprecated/cogl-clutter.h deleted file mode 100644 index 604ad3f..0000000 --- a/mutter/cogl/cogl/deprecated/cogl-clutter.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -G_BEGIN_DECLS - -COGL_DEPRECATED_FOR (cogl_has_feature) -COGL_EXPORT gboolean -cogl_clutter_winsys_has_feature (CoglWinsysFeature feature); - -G_END_DECLS diff --git a/mutter/cogl/cogl/deprecated/cogl-program-private.h b/mutter/cogl/cogl/deprecated/cogl-program-private.h deleted file mode 100644 index 761d8d8..0000000 --- a/mutter/cogl/cogl/deprecated/cogl-program-private.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-boxed-value.h" - -typedef struct _CoglProgram CoglProgram; - -struct _CoglProgram -{ - GObject parent_instance; - - GSList *attached_shaders; - - GArray *custom_uniforms; - - /* An age counter that changes whenever the list of shaders is modified */ - unsigned int age; -}; - - -typedef struct _CoglProgramUniform CoglProgramUniform; - -struct _CoglProgramUniform -{ - char *name; - CoglBoxedValue value; - /* The cached GL location for this uniform. This is only valid - between calls to _cogl_program_dirty_all_uniforms */ - GLint location; - /* Whether we have a location yet */ - unsigned int location_valid : 1; - /* Whether the uniform value has changed since the last time the - uniforms were flushed */ - unsigned int dirty : 1; -}; - -/* Internal function to flush the custom uniforms for the given use - program. This assumes the target GL program is already bound. The - gl_program still needs to be passed so that CoglProgram can query - the uniform locations. gl_program_changed should be set to TRUE if - we are flushing the uniforms against a different GL program from - the last time it was flushed. This will cause it to requery all of - the locations and assume that all uniforms are dirty */ -void -_cogl_program_flush_uniforms (CoglProgram *program, - GLuint gl_program, - gboolean gl_program_changed); - -gboolean -_cogl_program_has_fragment_shader (CoglProgram *self); - -gboolean -_cogl_program_has_vertex_shader (CoglProgram *self); diff --git a/mutter/cogl/cogl/deprecated/cogl-program.c b/mutter/cogl/cogl/deprecated/cogl-program.c deleted file mode 100644 index 9d257fd..0000000 --- a/mutter/cogl/cogl/deprecated/cogl-program.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include "cogl/cogl-util.h" -#include "cogl/cogl-context-private.h" - -#include "cogl/deprecated/cogl-shader-private.h" -#include "cogl/deprecated/cogl-program-private.h" - -#include - -G_DEFINE_TYPE (CoglProgram, cogl_program, G_TYPE_OBJECT); - -static void -cogl_program_dispose (GObject *object) -{ - CoglProgram *program = COGL_PROGRAM (object); - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Unref all of the attached shaders and destroy the list */ - g_slist_free_full (program->attached_shaders, g_object_unref); - - for (i = 0; i < program->custom_uniforms->len; i++) - { - CoglProgramUniform *uniform = - &g_array_index (program->custom_uniforms, CoglProgramUniform, i); - - g_free (uniform->name); - - if (uniform->value.count > 1) - g_free (uniform->value.v.array); - } - - g_array_free (program->custom_uniforms, TRUE); - - G_OBJECT_CLASS (cogl_program_parent_class)->dispose (object); -} - -static void -cogl_program_init (CoglProgram *program) -{ -} - -static void -cogl_program_class_init (CoglProgramClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = cogl_program_dispose; -} - -/* A CoglProgram is effectively just a list of shaders that will be - used together and a set of values for the custom uniforms. No - actual GL program is created - instead this is the responsibility - of the GLSL material backend. The uniform values are collected in - an array and then flushed whenever the material backend requests - it. */ - -CoglProgram* -cogl_create_program (void) -{ - CoglProgram *program; - - program = g_object_new (COGL_TYPE_PROGRAM, NULL); - - program->custom_uniforms = - g_array_new (FALSE, FALSE, sizeof (CoglProgramUniform)); - program->age = 0; - - return program; -} - -void -cogl_program_attach_shader (CoglProgram *program, - CoglShader *shader) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!COGL_IS_PROGRAM (program) || !COGL_IS_SHADER (shader)) - return; - - program->attached_shaders - = g_slist_prepend (program->attached_shaders, - g_object_ref (shader)); - - program->age++; -} - -void -cogl_program_link (CoglProgram *program) -{ - /* There's no point in linking the program here because it will have - to be relinked with a different fixed functionality shader - whenever the settings change */ -} - -int -cogl_program_get_uniform_location (CoglProgram *program, - const char *uniform_name) -{ - g_return_val_if_fail (COGL_IS_PROGRAM (program), -1); - - int i; - CoglProgramUniform *uniform; - - /* We can't just ask the GL program object for the uniform location - directly because it will change every time the program is linked - with a different shader. Instead we make our own mapping of - uniform numbers and cache the names */ - for (i = 0; i < program->custom_uniforms->len; i++) - { - uniform = &g_array_index (program->custom_uniforms, - CoglProgramUniform, i); - - if (!strcmp (uniform->name, uniform_name)) - return i; - } - - /* Create a new uniform with the given name */ - g_array_set_size (program->custom_uniforms, - program->custom_uniforms->len + 1); - uniform = &g_array_index (program->custom_uniforms, - CoglProgramUniform, - program->custom_uniforms->len - 1); - - uniform->name = g_strdup (uniform_name); - memset (&uniform->value, 0, sizeof (CoglBoxedValue)); - uniform->dirty = TRUE; - uniform->location_valid = FALSE; - - return program->custom_uniforms->len - 1; -} - -static CoglProgramUniform * -cogl_program_modify_uniform (CoglProgram *program, - int uniform_no) -{ - CoglProgramUniform *uniform; - - g_return_val_if_fail (COGL_IS_PROGRAM (program), NULL); - g_return_val_if_fail (uniform_no >= 0 && - uniform_no < program->custom_uniforms->len, - NULL); - - uniform = &g_array_index (program->custom_uniforms, - CoglProgramUniform, uniform_no); - uniform->dirty = TRUE; - - return uniform; -} - -void -cogl_program_set_uniform_1f (CoglProgram *program, - int uniform_location, - float value) -{ - CoglProgramUniform *uniform; - - uniform = cogl_program_modify_uniform (program, uniform_location); - _cogl_boxed_value_set_1f (&uniform->value, value); -} - -void -cogl_program_set_uniform_1i (CoglProgram *program, - int uniform_location, - int value) -{ - CoglProgramUniform *uniform; - - uniform = cogl_program_modify_uniform (program, uniform_location); - _cogl_boxed_value_set_1i (&uniform->value, value); -} - -void -cogl_program_set_uniform_float (CoglProgram *program, - int uniform_location, - int n_components, - int count, - const float *value) -{ - CoglProgramUniform *uniform; - - uniform = cogl_program_modify_uniform (program, uniform_location); - _cogl_boxed_value_set_float (&uniform->value, n_components, count, value); -} - -void -cogl_program_set_uniform_int (CoglProgram *program, - int uniform_location, - int n_components, - int count, - const int *value) -{ - CoglProgramUniform *uniform; - - uniform = cogl_program_modify_uniform (program, uniform_location); - _cogl_boxed_value_set_int (&uniform->value, n_components, count, value); -} - -void -cogl_program_set_uniform_matrix (CoglProgram *program, - int uniform_location, - int dimensions, - int count, - gboolean transpose, - const float *value) -{ - CoglProgramUniform *uniform; - - uniform = cogl_program_modify_uniform (program, uniform_location); - _cogl_boxed_value_set_matrix (&uniform->value, - dimensions, - count, - transpose, - value); -} - -void -_cogl_program_flush_uniforms (CoglProgram *program, - GLuint gl_program, - gboolean gl_program_changed) -{ - CoglProgramUniform *uniform; - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - for (i = 0; i < program->custom_uniforms->len; i++) - { - uniform = &g_array_index (program->custom_uniforms, - CoglProgramUniform, i); - - if (gl_program_changed || uniform->dirty) - { - if (gl_program_changed || !uniform->location_valid) - { - uniform->location = - ctx->glGetUniformLocation (gl_program, uniform->name); - - uniform->location_valid = TRUE; - } - - /* If the uniform isn't really in the program then there's - no need to actually set it */ - if (uniform->location != -1) - { - _cogl_boxed_value_set_uniform (ctx, - uniform->location, - &uniform->value); - } - - uniform->dirty = FALSE; - } - } -} - -static gboolean -_cogl_program_has_shader_type (CoglProgram *program, - CoglShaderType type) -{ - GSList *l; - - for (l = program->attached_shaders; l; l = l->next) - { - CoglShader *shader = l->data; - - if (shader->type == type) - return TRUE; - } - - return FALSE; -} - -gboolean -_cogl_program_has_fragment_shader (CoglProgram *program) -{ - return _cogl_program_has_shader_type (program, COGL_SHADER_TYPE_FRAGMENT); -} - -gboolean -_cogl_program_has_vertex_shader (CoglProgram *program) -{ - return _cogl_program_has_shader_type (program, COGL_SHADER_TYPE_VERTEX); -} diff --git a/mutter/cogl/cogl/deprecated/cogl-program.h b/mutter/cogl/cogl/deprecated/cogl-program.h deleted file mode 100644 index 0929511..0000000 --- a/mutter/cogl/cogl/deprecated/cogl-program.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#define COGL_TYPE_PROGRAM (cogl_program_get_type ()) - -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglProgram, - cogl_program, - COGL, - PROGRAM, - GObject) diff --git a/mutter/cogl/cogl/deprecated/cogl-shader-private.h b/mutter/cogl/cogl/deprecated/cogl-shader-private.h deleted file mode 100644 index e5c0d43..0000000 --- a/mutter/cogl/cogl/deprecated/cogl-shader-private.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/deprecated/cogl-shader.h" -#include "cogl/cogl-gl-header.h" -#include "cogl/cogl-pipeline.h" - -typedef struct _CoglShader CoglShader; - -struct _CoglShader -{ - GObject parent_instance; - - GLuint gl_handle; - CoglPipeline *compilation_pipeline; - CoglShaderType type; - char *source; -}; diff --git a/mutter/cogl/cogl/deprecated/cogl-shader.c b/mutter/cogl/cogl/deprecated/cogl-shader.c deleted file mode 100644 index 85d4d8a..0000000 --- a/mutter/cogl/cogl/deprecated/cogl-shader.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-glsl-shader-boilerplate.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" -#include "cogl/deprecated/cogl-shader-private.h" - -#include - -#include - -G_DEFINE_TYPE (CoglShader, cogl_shader, G_TYPE_OBJECT); - -static void -cogl_shader_dispose (GObject *object) -{ - CoglShader *shader = COGL_SHADER (object); - - /* Frees shader resources but its handle is not - released! Do that separately before this! */ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (shader->gl_handle) - GE (ctx, glDeleteShader (shader->gl_handle)); - - G_OBJECT_CLASS (cogl_shader_parent_class)->dispose (object); -} - -static void -cogl_shader_init (CoglShader *shader) -{ -} - -static void -cogl_shader_class_init (CoglShaderClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = cogl_shader_dispose; -} - -CoglShader* -cogl_create_shader (CoglShaderType type) -{ - CoglShader *shader; - - _COGL_GET_CONTEXT (ctx, NULL); - - switch (type) - { - case COGL_SHADER_TYPE_VERTEX: - case COGL_SHADER_TYPE_FRAGMENT: - break; - default: - g_warning ("Unexpected shader type (0x%08lX) given to " - "cogl_create_shader", (unsigned long) type); - return NULL; - } - - shader = g_object_new (COGL_TYPE_SHADER, NULL); - shader->gl_handle = 0; - shader->compilation_pipeline = NULL; - shader->type = type; - - return shader; -} - -void -cogl_shader_source (CoglShader *self, - const char *source) -{ - g_return_if_fail (COGL_IS_SHADER (self)); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - self->source = g_strdup (source); -} - -CoglShaderType -cogl_shader_get_shader_type (CoglShader *self) -{ - g_return_val_if_fail (COGL_IS_SHADER (self), COGL_SHADER_TYPE_VERTEX); - - _COGL_GET_CONTEXT (ctx, COGL_SHADER_TYPE_VERTEX); - - return self->type; -} diff --git a/mutter/cogl/cogl/deprecated/cogl-shader.h b/mutter/cogl/cogl/deprecated/cogl-shader.h deleted file mode 100644 index 4875403..0000000 --- a/mutter/cogl/cogl/deprecated/cogl-shader.h +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include "cogl/cogl-types.h" -#include "cogl/cogl-macros.h" -#include "cogl/deprecated/cogl-program.h" - -G_BEGIN_DECLS - -/** - * CoglShader: - * - * Functions for accessing the programmable GL pipeline - * - * Cogl allows accessing the GL programmable pipeline in order to create - * vertex and fragment shaders. - * - * When using GLSL Cogl provides replacement names for most of the - * builtin varyings and uniforms. It is recommended to use these names - * wherever possible to increase portability between OpenGL 2.0 and - * GLES 2.0. GLES 2.0 does not have most of the builtins under their - * original names so they will only work with the Cogl names. - * - * For use in all GLSL shaders, the Cogl builtins are as follows: - * - * - `uniform mat4 cogl_modelview_matrix` - * The current modelview matrix. This is equivalent to - * #gl_ModelViewMatrix. - * - `uniform mat4 cogl_projection_matrix` - * The current projection matrix. This is equivalent to - * #gl_ProjectionMatrix. -* - `uniform mat4 cogl_modelview_projection_matrix` - * The combined modelview and projection matrix. A vertex shader - * would typically use this to transform the incoming vertex - * position. The separate modelview and projection matrices are - * usually only needed for lighting calculations. This is - * equivalent to #gl_ModelViewProjectionMatrix. - * - `uniform mat4 cogl_texture_matrix[]` - * An array of matrices for transforming the texture - * coordinates. This is equivalent to #gl_TextureMatrix. - * - * In a vertex shader, the following are also available: - * - * - `attribute vec4 cogl_position_in` - * The incoming vertex position. This is equivalent to #gl_Vertex. - * - `attribute vec4 cogl_color_in` - * The incoming vertex color. This is equivalent to #gl_Color. - * - `attribute vec4 cogl_tex_coord_in` - * The texture coordinate for the first texture unit. This is - * equivalent to #gl_MultiTexCoord0. - * - `attribute vec4 cogl_tex_coord0_in` - * The texture coordinate for the first texture unit. This is - * equivalent to #gl_MultiTexCoord0. There is also - * #cogl_tex_coord1_in and so on. - * - `attribute vec3 cogl_normal_in` - * The normal of the vertex. This is equivalent to #gl_Normal. - * - `vec4 cogl_position_out` - * The calculated position of the vertex. This must be written to - * in all vertex shaders. This is equivalent to #gl_Position. - * - `float cogl_point_size_out` - * The calculated size of a point. This is equivalent to #gl_PointSize. - * - `varying vec4 cogl_color_out` - * The calculated color of a vertex. This is equivalent to #gl_FrontColor. - * - `varying vec4 cogl_tex_coord_out[]` - * An array of calculated texture coordinates for a vertex. This is - * equivalent to #gl_TexCoord. - * - * In a fragment shader, the following are also available: - * - * - `varying vec4 cogl_color_in` - * The calculated color of a vertex. This is equivalent to #gl_FrontColor. - * - `varying vec4 cogl_tex_coord_in[]` - * An array of calculated texture coordinates for a vertex. This is - * equivalent to #gl_TexCoord. - * - `vec4 cogl_color_out` - * The final calculated color of the fragment. All fragment shaders - * must write to this variable. This is equivalent to - * #gl_FrontColor. - * - `float cogl_depth_out` - * An optional output variable specifying the depth value to use - * for this fragment. This is equivalent to #gl_FragDepth. - * - `bool cogl_front_facing` - * A readonly variable that will be true if the current primitive - * is front facing. This can be used to implement two-sided - * coloring algorithms. This is equivalent to #gl_FrontFacing. - * - * It's worth nothing that this API isn't what Cogl would like to have - * in the long term and it may be removed in Cogl 2.0. The - * experimental #CoglShader API is the proposed replacement. - */ - -#define COGL_TYPE_SHADER (cogl_shader_get_type ()) - -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglShader, - cogl_shader, - COGL, - SHADER, - GObject) - -/** - * CoglShaderType: - * @COGL_SHADER_TYPE_VERTEX: A program for processing vertices - * @COGL_SHADER_TYPE_FRAGMENT: A program for processing fragments - * - * Types of shaders - */ -typedef enum -{ - COGL_SHADER_TYPE_VERTEX, - COGL_SHADER_TYPE_FRAGMENT -} CoglShaderType; - -/** - * cogl_create_shader: - * @shader_type: COGL_SHADER_TYPE_VERTEX or COGL_SHADER_TYPE_FRAGMENT. - * - * Create a new shader handle, use cogl_shader_source() to set the - * source code to be used on it. - * - * Returns: (transfer full): a new shader handle. - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT CoglShader* -cogl_create_shader (CoglShaderType shader_type); - -/** - * cogl_shader_source: - * @self: A shader. - * @source: Shader source. - * - * Replaces the current source associated with a shader with a new - * one. - * - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_shader_source (CoglShader *self, - const char *source); - -/** - * cogl_shader_get_shader_type: - * @self: #CoglShader for a shader. - * - * Retrieves the type of a shader - * - * Return value: %COGL_SHADER_TYPE_VERTEX if the shader is a vertex processor - * or %COGL_SHADER_TYPE_FRAGMENT if the shader is a fragment processor - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT CoglShaderType -cogl_shader_get_shader_type (CoglShader *self); - -/** - * cogl_create_program: - * - * Create a new cogl program object that can be used to replace parts of the GL - * rendering pipeline with custom code. - * - * Returns: (transfer full): a new cogl program. - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT CoglProgram* -cogl_create_program (void); - -/** - * cogl_program_attach_shader: - * @program: a #CoglProgram for a shader program. - * @shader: a #CoglShader for a vertex of fragment shader. - * - * Attaches a shader to a program object. A program can have multiple - * vertex or fragment shaders but only one of them may provide a - * main() function. It is allowed to use a program with only a vertex - * shader or only a fragment shader. - * - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_program_attach_shader (CoglProgram *program, - CoglShader *shader); - -/** - * cogl_program_link: - * @program: A shader program. - * - * Links a program making it ready for use. Note that calling this - * function is optional. If it is not called the program will - * automatically be linked the first time it is used. - * - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_program_link (CoglProgram *program); - -/** - * cogl_program_get_uniform_location: - * @program: A shader program. - * @uniform_name: the name of a uniform. - * - * Retrieve the location (offset) of a uniform variable in a shader program, - * a uniform is a variable that is constant for all vertices/fragments for a - * shader object and is possible to modify as an external parameter. - * - * Return value: the offset of a uniform in a specified program. - * Deprecated: 1.16: Use #CoglSnippet api instead - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT int -cogl_program_get_uniform_location (CoglProgram *program, - const char *uniform_name); - -/** - * cogl_program_set_uniform_1f: - * @program: A linked program - * @uniform_location: the uniform location retrieved from - * [method@Program.get_uniform_location]. - * @value: the new value of the uniform. - * - * Changes the value of a floating point uniform for the given linked - * @program. - * Deprecated: 1.16: Use #CoglSnippet api instead - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_program_set_uniform_1f (CoglProgram *program, - int uniform_location, - float value); - -/** - * cogl_program_set_uniform_1i: - * @program: A linked program - * @uniform_location: the uniform location retrieved from - * [method@Program.get_uniform_location]. - * @value: the new value of the uniform. - * - * Changes the value of an integer uniform for the given linked - * @program. - * Deprecated: 1.16: Use #CoglSnippet api instead - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_program_set_uniform_1i (CoglProgram *program, - int uniform_location, - int value); - -/** - * cogl_program_set_uniform_float: - * @program: A linked program - * @uniform_location: the uniform location retrieved from - * [method@Program.get_uniform_location]. - * @n_components: The number of components for the uniform. For - * example with glsl you'd use 3 for a vec3 or 4 for a vec4. - * @count: For uniform arrays this is the array length otherwise just - * pass 1 - * @value: (array length=count): the new value of the uniform[s]. - * - * Changes the value of a float vector uniform, or uniform array for - * the given linked @program. - * Deprecated: 1.16: Use #CoglSnippet api instead - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_program_set_uniform_float (CoglProgram *program, - int uniform_location, - int n_components, - int count, - const float *value); - -/** - * cogl_program_set_uniform_int: - * @program: A linked program - * @uniform_location: the uniform location retrieved from - * [method@Program.get_uniform_location]. - * @n_components: The number of components for the uniform. For - * example with glsl you'd use 3 for a vec3 or 4 for a vec4. - * @count: For uniform arrays this is the array length otherwise just - * pass 1 - * @value: (array length=count): the new value of the uniform[s]. - * - * Changes the value of a int vector uniform, or uniform array for - * the given linked @program. - * Deprecated: 1.16: Use #CoglSnippet api instead - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_program_set_uniform_int (CoglProgram *program, - int uniform_location, - int n_components, - int count, - const int *value); - -/** - * cogl_program_set_uniform_matrix: - * @program: A linked program - * @uniform_location: the uniform location retrieved from - * [method@Program.get_uniform_location]. - * @dimensions: The dimensions of the matrix. So for for example pass - * 2 for a 2x2 matrix or 3 for 3x3. - * @count: For uniform arrays this is the array length otherwise just - * pass 1 - * @transpose: Whether to transpose the matrix when setting the uniform. - * @value: (array length=count): the new value of the uniform. - * - * Changes the value of a matrix uniform, or uniform array in the - * given linked @program. - * Deprecated: 1.16: Use #CoglSnippet api instead - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_program_set_uniform_matrix (CoglProgram *program, - int uniform_location, - int dimensions, - int count, - gboolean transpose, - const float *value); - -G_END_DECLS diff --git a/mutter/cogl/cogl/driver/gl/cogl-attribute-gl-private.h b/mutter/cogl/cogl/driver/gl/cogl-attribute-gl-private.h deleted file mode 100644 index 50fb3a2..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-attribute-gl-private.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-types.h" -#include "cogl/cogl-framebuffer.h" -#include "cogl/cogl-attribute.h" -#include "cogl/cogl-attribute-private.h" - -void -_cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglFlushLayerState *layers_state, - CoglDrawFlags flags, - CoglAttribute **attributes, - int n_attributes); diff --git a/mutter/cogl/cogl/driver/gl/cogl-attribute-gl.c b/mutter/cogl/cogl/driver/gl/cogl-attribute-gl.c deleted file mode 100644 index 53fed2a..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-attribute-gl.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010,2011,2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - * Robert Bragg - */ - -#include "config.h" - -#include - -#include "cogl/cogl-private.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-attribute.h" -#include "cogl/cogl-attribute-private.h" -#include "cogl/driver/gl/cogl-attribute-gl-private.h" -#include "cogl/driver/gl/cogl-buffer-gl-private.h" -#include "cogl/driver/gl/cogl-pipeline-opengl-private.h" -#include "cogl/driver/gl/cogl-pipeline-progend-glsl-private.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" - -typedef struct _ForeachChangedBitState -{ - CoglContext *context; - const CoglBitmask *new_bits; - CoglPipeline *pipeline; -} ForeachChangedBitState; - -static gboolean -toggle_custom_attribute_enabled_cb (int bit_num, void *user_data) -{ - ForeachChangedBitState *state = user_data; - gboolean enabled = _cogl_bitmask_get (state->new_bits, bit_num); - CoglContext *context = state->context; - - if (enabled) - GE( context, glEnableVertexAttribArray (bit_num) ); - else - GE( context, glDisableVertexAttribArray (bit_num) ); - - return TRUE; -} - -static void -foreach_changed_bit_and_save (CoglContext *context, - CoglBitmask *current_bits, - const CoglBitmask *new_bits, - CoglBitmaskForeachFunc callback, - ForeachChangedBitState *state) -{ - /* Get the list of bits that are different */ - _cogl_bitmask_clear_all (&context->changed_bits_tmp); - _cogl_bitmask_set_bits (&context->changed_bits_tmp, current_bits); - _cogl_bitmask_xor_bits (&context->changed_bits_tmp, new_bits); - - /* Iterate over each bit to change */ - state->new_bits = new_bits; - _cogl_bitmask_foreach (&context->changed_bits_tmp, - callback, - state); - - /* Store the new values */ - _cogl_bitmask_clear_all (current_bits); - _cogl_bitmask_set_bits (current_bits, new_bits); -} - -static void -setup_generic_buffered_attribute (CoglContext *context, - CoglPipeline *pipeline, - CoglAttribute *attribute, - uint8_t *base) -{ - int name_index = attribute->name_state->name_index; - int attrib_location = - _cogl_pipeline_progend_glsl_get_attrib_location (pipeline, name_index); - - if (attrib_location == -1) - return; - - GE( context, glVertexAttribPointer (attrib_location, - attribute->d.buffered.n_components, - attribute->d.buffered.type, - attribute->normalized, - attribute->d.buffered.stride, - base + attribute->d.buffered.offset) ); - _cogl_bitmask_set (&context->enable_custom_attributes_tmp, - attrib_location, TRUE); -} - -static void -setup_generic_const_attribute (CoglContext *context, - CoglPipeline *pipeline, - CoglAttribute *attribute) -{ - int name_index = attribute->name_state->name_index; - int attrib_location = - _cogl_pipeline_progend_glsl_get_attrib_location (pipeline, name_index); - int columns; - int i; - - if (attrib_location == -1) - return; - - if (attribute->d.constant.boxed.type == COGL_BOXED_MATRIX) - columns = attribute->d.constant.boxed.size; - else - columns = 1; - - /* Note: it's ok to access a COGL_BOXED_FLOAT as a matrix with only - * one column... */ - - switch (attribute->d.constant.boxed.size) - { - case 1: - GE( context, glVertexAttrib1fv (attrib_location, - attribute->d.constant.boxed.v.matrix)); - break; - case 2: - for (i = 0; i < columns; i++) - GE( context, glVertexAttrib2fv (attrib_location + i, - attribute->d.constant.boxed.v.matrix)); - break; - case 3: - for (i = 0; i < columns; i++) - GE( context, glVertexAttrib3fv (attrib_location + i, - attribute->d.constant.boxed.v.matrix)); - break; - case 4: - for (i = 0; i < columns; i++) - GE( context, glVertexAttrib4fv (attrib_location + i, - attribute->d.constant.boxed.v.matrix)); - break; - default: - g_warn_if_reached (); - } -} - -static void -apply_attribute_enable_updates (CoglContext *context, - CoglPipeline *pipeline) -{ - ForeachChangedBitState changed_bits_state; - - changed_bits_state.context = context; - changed_bits_state.pipeline = pipeline; - changed_bits_state.new_bits = &context->enable_custom_attributes_tmp; - foreach_changed_bit_and_save (context, - &context->enabled_custom_attributes, - &context->enable_custom_attributes_tmp, - toggle_custom_attribute_enabled_cb, - &changed_bits_state); -} - -void -_cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglFlushLayerState *layers_state, - CoglDrawFlags flags, - CoglAttribute **attributes, - int n_attributes) -{ - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - int i; - gboolean with_color_attrib = FALSE; - gboolean unknown_color_alpha = FALSE; - CoglPipeline *copy = NULL; - - /* Iterate the attributes to see if we have a color attribute which - * may affect our decision to enable blending or not. - * - * We need to do this before flushing the pipeline. */ - for (i = 0; i < n_attributes; i++) - switch (attributes[i]->name_state->name_id) - { - case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY: - if ((flags & COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE) == 0 && - _cogl_attribute_get_n_components (attributes[i]) == 4) - unknown_color_alpha = TRUE; - with_color_attrib = TRUE; - break; - - default: - break; - } - - if (G_UNLIKELY (layers_state->options.flags)) - { - /* If we haven't already created a derived pipeline... */ - if (!copy) - { - copy = cogl_pipeline_copy (pipeline); - pipeline = copy; - } - _cogl_pipeline_apply_overrides (pipeline, &layers_state->options); - - /* TODO: - * overrides = cogl_pipeline_get_data (pipeline, - * last_overrides_key); - * if (overrides) - * { - * age = cogl_pipeline_get_age (pipeline); - * XXX: actually we also need to check for legacy_state - * if (overrides->ags != age || - * memcmp (&overrides->options, &options, - * sizeof (options) != 0) - * { - * g_object_unref (overrides->weak_pipeline); - * g_free (overrides); - * overrides = NULL; - * } - * } - * if (!overrides) - * { - * overrides = g_new0 (Overrides, 1); - * overrides->weak_pipeline = - * cogl_pipeline_weak_copy (pipeline); - * _cogl_pipeline_apply_overrides (overrides->weak_pipeline, - * &options); - * - * cogl_pipeline_set_data (pipeline, last_overrides_key, - * weak_overrides, - * free_overrides_cb, - * NULL); - * } - * pipeline = overrides->weak_pipeline; - */ - } - - _cogl_pipeline_flush_gl_state (ctx, - pipeline, - framebuffer, - with_color_attrib, - unknown_color_alpha); - - _cogl_bitmask_clear_all (&ctx->enable_custom_attributes_tmp); - - /* Bind the attribute pointers. We need to do this after the - * pipeline is flushed because when using GLSL that is the only - * point when we can determine the attribute locations */ - - for (i = 0; i < n_attributes; i++) - { - CoglAttribute *attribute = attributes[i]; - CoglAttributeBuffer *attribute_buffer; - CoglBuffer *buffer; - uint8_t *base; - - if (attribute->is_buffered) - { - attribute_buffer = cogl_attribute_get_buffer (attribute); - buffer = COGL_BUFFER (attribute_buffer); - - /* Note: we don't try and catch errors with binding buffers - * here since OOM errors at this point indicate that nothing - * has yet been uploaded to attribute buffer which we - * consider to be a programmer error. - */ - base = - _cogl_buffer_gl_bind (buffer, - COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER, - NULL); - - setup_generic_buffered_attribute (ctx, pipeline, attribute, base); - - _cogl_buffer_gl_unbind (buffer); - } - else - { - setup_generic_const_attribute (ctx, pipeline, attribute); - } - } - - apply_attribute_enable_updates (ctx, pipeline); - - if (copy) - g_object_unref (copy); -} diff --git a/mutter/cogl/cogl/driver/gl/cogl-bitmap-gl-private.h b/mutter/cogl/cogl/driver/gl/cogl-bitmap-gl-private.h deleted file mode 100644 index 3b12f16..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-bitmap-gl-private.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007 OpenedHand - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-bitmap-private.h" - -/* These two are replacements for map and unmap that should used when - * the pointer is going to be passed to GL for pixel packing or - * unpacking. The address might not be valid for reading if the bitmap - * was created with new_from_buffer but it will however be good to - * pass to glTexImage2D for example. The access should be READ for - * unpacking and WRITE for packing. It can not be both - */ -uint8_t * -_cogl_bitmap_gl_bind (CoglBitmap *bitmap, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error); - -void -_cogl_bitmap_gl_unbind (CoglBitmap *bitmap); diff --git a/mutter/cogl/cogl/driver/gl/cogl-bitmap-gl.c b/mutter/cogl/cogl/driver/gl/cogl-bitmap-gl.c deleted file mode 100644 index 9019b46..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-bitmap-gl.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include "cogl/cogl-util.h" -#include "cogl/cogl-debug.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl-bitmap-private.h" -#include "cogl/cogl-buffer-private.h" -#include "cogl/cogl-pixel-buffer.h" -#include "cogl/cogl-context-private.h" -#include "cogl/driver/gl/cogl-buffer-gl-private.h" -#include "cogl/driver/gl/cogl-bitmap-gl-private.h" - -uint8_t * -_cogl_bitmap_gl_bind (CoglBitmap *bitmap, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error) -{ - uint8_t *ptr; - GError *internal_error = NULL; - - g_return_val_if_fail (access & (COGL_BUFFER_ACCESS_READ | - COGL_BUFFER_ACCESS_WRITE), - NULL); - - /* Divert to another bitmap if this data is shared */ - if (bitmap->shared_bmp) - return _cogl_bitmap_gl_bind (bitmap->shared_bmp, access, hints, error); - - g_return_val_if_fail (!bitmap->bound, NULL); - - /* If the bitmap wasn't created from a buffer then the - implementation of bind is the same as map */ - if (bitmap->buffer == NULL) - { - uint8_t *data = _cogl_bitmap_map (bitmap, access, hints, error); - if (data) - bitmap->bound = TRUE; - return data; - } - - if (access == COGL_BUFFER_ACCESS_READ) - ptr = _cogl_buffer_gl_bind (bitmap->buffer, - COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK, - &internal_error); - else if (access == COGL_BUFFER_ACCESS_WRITE) - ptr = _cogl_buffer_gl_bind (bitmap->buffer, - COGL_BUFFER_BIND_TARGET_PIXEL_PACK, - &internal_error); - else - { - ptr = NULL; - g_assert_not_reached (); - return NULL; - } - - /* NB: _cogl_buffer_gl_bind() may return NULL in non-error - * conditions so we have to explicitly check internal_error to see - * if an exception was thrown */ - if (internal_error) - { - g_propagate_error (error, internal_error); - return NULL; - } - - bitmap->bound = TRUE; - - /* The data pointer actually stores the offset */ - return ptr + GPOINTER_TO_INT (bitmap->data); -} - -void -_cogl_bitmap_gl_unbind (CoglBitmap *bitmap) -{ - /* Divert to another bitmap if this data is shared */ - if (bitmap->shared_bmp) - { - _cogl_bitmap_gl_unbind (bitmap->shared_bmp); - return; - } - - g_assert (bitmap->bound); - bitmap->bound = FALSE; - - /* If the bitmap wasn't created from a pixel array then the - implementation of unbind is the same as unmap */ - if (bitmap->buffer) - _cogl_buffer_gl_unbind (bitmap->buffer); - else - _cogl_bitmap_unmap (bitmap); -} diff --git a/mutter/cogl/cogl/driver/gl/cogl-buffer-gl-private.h b/mutter/cogl/cogl/driver/gl/cogl-buffer-gl-private.h deleted file mode 100644 index f9c11ed..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-buffer-gl-private.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-types.h" -#include "cogl/cogl-context.h" -#include "cogl/cogl-buffer.h" -#include "cogl/cogl-buffer-private.h" - -void -_cogl_buffer_gl_create (CoglBuffer *buffer); - -void -_cogl_buffer_gl_destroy (CoglBuffer *buffer); - -void * -_cogl_buffer_gl_map_range (CoglBuffer *buffer, - size_t offset, - size_t size, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error); - -void -_cogl_buffer_gl_unmap (CoglBuffer *buffer); - -gboolean -_cogl_buffer_gl_set_data (CoglBuffer *buffer, - unsigned int offset, - const void *data, - unsigned int size, - GError **error); - -void * -_cogl_buffer_gl_bind (CoglBuffer *buffer, - CoglBufferBindTarget target, - GError **error); - -void -_cogl_buffer_gl_unbind (CoglBuffer *buffer); diff --git a/mutter/cogl/cogl/driver/gl/cogl-buffer-gl.c b/mutter/cogl/cogl/driver/gl/cogl-buffer-gl.c deleted file mode 100644 index fd62a7b..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-buffer-gl.c +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010,2011,2012,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Damien Lespiau - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/driver/gl/cogl-buffer-gl-private.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" - -/* - * GL/GLES compatibility defines for the buffer API: - */ - -#ifndef GL_PIXEL_PACK_BUFFER -#define GL_PIXEL_PACK_BUFFER 0x88EB -#endif -#ifndef GL_PIXEL_UNPACK_BUFFER -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#endif -#ifndef GL_ARRAY_BUFFER -#define GL_ARRAY_BUFFER 0x8892 -#endif -#ifndef GL_ELEMENT_ARRAY_BUFFER -#define GL_ARRAY_BUFFER 0x8893 -#endif -#ifndef GL_READ_ONLY -#define GL_READ_ONLY 0x88B8 -#endif -#ifndef GL_WRITE_ONLY -#define GL_WRITE_ONLY 0x88B9 -#endif -#ifndef GL_READ_WRITE -#define GL_READ_WRITE 0x88BA -#endif -#ifndef GL_MAP_READ_BIT -#define GL_MAP_READ_BIT 0x0001 -#endif -#ifndef GL_MAP_WRITE_BIT -#define GL_MAP_WRITE_BIT 0x0002 -#endif -#ifndef GL_MAP_INVALIDATE_RANGE_BIT -#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 -#endif -#ifndef GL_MAP_INVALIDATE_BUFFER_BIT -#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 -#endif - -void -_cogl_buffer_gl_create (CoglBuffer *buffer) -{ - CoglContext *ctx = buffer->context; - - GE (ctx, glGenBuffers (1, &buffer->gl_handle)); -} - -void -_cogl_buffer_gl_destroy (CoglBuffer *buffer) -{ - GE( buffer->context, glDeleteBuffers (1, &buffer->gl_handle) ); -} - -static GLenum -update_hints_to_gl_enum (CoglBuffer *buffer) -{ - /* usage hint is always DRAW for now */ - switch (buffer->update_hint) - { - case COGL_BUFFER_UPDATE_HINT_STATIC: - return GL_STATIC_DRAW; - case COGL_BUFFER_UPDATE_HINT_DYNAMIC: - return GL_DYNAMIC_DRAW; - case COGL_BUFFER_UPDATE_HINT_STREAM: - return GL_STREAM_DRAW; - } - - g_assert_not_reached (); - return 0; -} - -static GLenum -convert_bind_target_to_gl_target (CoglBufferBindTarget target) -{ - switch (target) - { - case COGL_BUFFER_BIND_TARGET_PIXEL_PACK: - return GL_PIXEL_PACK_BUFFER; - case COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK: - return GL_PIXEL_UNPACK_BUFFER; - case COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER: - return GL_ARRAY_BUFFER; - case COGL_BUFFER_BIND_TARGET_INDEX_BUFFER: - return GL_ELEMENT_ARRAY_BUFFER; - default: - g_return_val_if_reached (COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK); - } -} - -static gboolean -recreate_store (CoglBuffer *buffer, - GError **error) -{ - CoglContext *ctx = buffer->context; - GLenum gl_target; - GLenum gl_enum; - - /* This assumes the buffer is already bound */ - - gl_target = convert_bind_target_to_gl_target (buffer->last_target); - gl_enum = update_hints_to_gl_enum (buffer); - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glBufferData (gl_target, - buffer->size, - NULL, - gl_enum); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - return FALSE; - - buffer->store_created = TRUE; - return TRUE; -} - -static GLenum -_cogl_buffer_access_to_gl_enum (CoglBufferAccess access) -{ - if ((access & COGL_BUFFER_ACCESS_READ_WRITE) == COGL_BUFFER_ACCESS_READ_WRITE) - return GL_READ_WRITE; - else if (access & COGL_BUFFER_ACCESS_WRITE) - return GL_WRITE_ONLY; - else - return GL_READ_ONLY; -} - -static void * -_cogl_buffer_bind_no_create (CoglBuffer *buffer, - CoglBufferBindTarget target) -{ - CoglContext *ctx = buffer->context; - - g_return_val_if_fail (buffer != NULL, NULL); - - /* Don't allow binding the buffer to multiple targets at the same time */ - g_return_val_if_fail (ctx->current_buffer[buffer->last_target] != buffer, - NULL); - - /* Don't allow nesting binds to the same target */ - g_return_val_if_fail (ctx->current_buffer[target] == NULL, NULL); - - buffer->last_target = target; - ctx->current_buffer[target] = buffer; - - if (buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT) - { - GLenum gl_target = convert_bind_target_to_gl_target (buffer->last_target); - GE( ctx, glBindBuffer (gl_target, buffer->gl_handle) ); - return NULL; - } - else - return buffer->data; -} - -void * -_cogl_buffer_gl_map_range (CoglBuffer *buffer, - size_t offset, - size_t size, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error) -{ - uint8_t *data; - CoglBufferBindTarget target; - GLenum gl_target; - CoglContext *ctx = buffer->context; - - if (((access & COGL_BUFFER_ACCESS_READ) && - !cogl_has_feature (ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_READ)) || - ((access & COGL_BUFFER_ACCESS_WRITE) && - !cogl_has_feature (ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE))) - { - g_set_error_literal (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Tried to map a buffer with unsupported access mode"); - return NULL; - } - - target = buffer->last_target; - _cogl_buffer_bind_no_create (buffer, target); - - gl_target = convert_bind_target_to_gl_target (target); - - if ((hints & COGL_BUFFER_MAP_HINT_DISCARD_RANGE) && - offset == 0 && size >= buffer->size) - hints |= COGL_BUFFER_MAP_HINT_DISCARD; - - /* If the map buffer range extension is supported then we will - * always use it even if we are mapping the full range because the - * normal mapping function doesn't support passing the discard - * hints */ - if (ctx->glMapBufferRange) - { - GLbitfield gl_access = 0; - gboolean should_recreate_store = !buffer->store_created; - - if ((access & COGL_BUFFER_ACCESS_READ)) - gl_access |= GL_MAP_READ_BIT; - if ((access & COGL_BUFFER_ACCESS_WRITE)) - gl_access |= GL_MAP_WRITE_BIT; - - if ((hints & COGL_BUFFER_MAP_HINT_DISCARD)) - { - /* glMapBufferRange generates an error if you pass the - * discard hint along with asking for read access. However - * it can make sense to ask for both if write access is also - * requested so that the application can immediately read - * back what it just wrote. To work around the restriction - * in GL we just recreate the buffer storage in that case - * which is an alternative way to indicate that the buffer - * contents can be discarded. */ - if ((access & COGL_BUFFER_ACCESS_READ)) - should_recreate_store = TRUE; - else - gl_access |= GL_MAP_INVALIDATE_BUFFER_BIT; - } - else if ((hints & COGL_BUFFER_MAP_HINT_DISCARD_RANGE) && - !(access & COGL_BUFFER_ACCESS_READ)) - gl_access |= GL_MAP_INVALIDATE_RANGE_BIT; - - if (should_recreate_store) - { - if (!recreate_store (buffer, error)) - { - _cogl_buffer_gl_unbind (buffer); - return NULL; - } - } - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - data = ctx->glMapBufferRange (gl_target, - offset, - size, - gl_access); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - { - _cogl_buffer_gl_unbind (buffer); - return NULL; - } - - g_return_val_if_fail (data != NULL, NULL); - } - else - { - /* create an empty store if we don't have one yet. creating the store - * lazily allows the user of the CoglBuffer to set a hint before the - * store is created. */ - if (!buffer->store_created || - (hints & COGL_BUFFER_MAP_HINT_DISCARD)) - { - if (!recreate_store (buffer, error)) - { - _cogl_buffer_gl_unbind (buffer); - return NULL; - } - } - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - data = ctx->glMapBuffer (gl_target, - _cogl_buffer_access_to_gl_enum (access)); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - { - _cogl_buffer_gl_unbind (buffer); - return NULL; - } - - g_return_val_if_fail (data != NULL, NULL); - - data += offset; - } - - if (data) - buffer->flags |= COGL_BUFFER_FLAG_MAPPED; - - _cogl_buffer_gl_unbind (buffer); - - return data; -} - -void -_cogl_buffer_gl_unmap (CoglBuffer *buffer) -{ - CoglContext *ctx = buffer->context; - - _cogl_buffer_bind_no_create (buffer, buffer->last_target); - - GE( ctx, glUnmapBuffer (convert_bind_target_to_gl_target - (buffer->last_target)) ); - buffer->flags &= ~COGL_BUFFER_FLAG_MAPPED; - - _cogl_buffer_gl_unbind (buffer); -} - -gboolean -_cogl_buffer_gl_set_data (CoglBuffer *buffer, - unsigned int offset, - const void *data, - unsigned int size, - GError **error) -{ - CoglBufferBindTarget target; - GLenum gl_target; - CoglContext *ctx = buffer->context; - gboolean status = TRUE; - GError *internal_error = NULL; - - target = buffer->last_target; - - _cogl_buffer_gl_bind (buffer, target, &internal_error); - - /* NB: _cogl_buffer_gl_bind() may return NULL in non-error - * conditions so we have to explicitly check internal_error - * to see if an exception was thrown. - */ - if (internal_error) - { - g_propagate_error (error, internal_error); - return FALSE; - } - - gl_target = convert_bind_target_to_gl_target (target); - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glBufferSubData (gl_target, offset, size, data); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - status = FALSE; - - _cogl_buffer_gl_unbind (buffer); - - return status; -} - -void * -_cogl_buffer_gl_bind (CoglBuffer *buffer, - CoglBufferBindTarget target, - GError **error) -{ - void *ret; - - ret = _cogl_buffer_bind_no_create (buffer, target); - - /* create an empty store if we don't have one yet. creating the store - * lazily allows the user of the CoglBuffer to set a hint before the - * store is created. */ - if ((buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT) && - !buffer->store_created) - { - if (!recreate_store (buffer, error)) - { - _cogl_buffer_gl_unbind (buffer); - return NULL; - } - } - - return ret; -} - -void -_cogl_buffer_gl_unbind (CoglBuffer *buffer) -{ - CoglContext *ctx = buffer->context; - - g_return_if_fail (buffer != NULL); - - /* the unbind should pair up with a previous bind */ - g_return_if_fail (ctx->current_buffer[buffer->last_target] == buffer); - - if (buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT) - { - GLenum gl_target = convert_bind_target_to_gl_target (buffer->last_target); - GE( ctx, glBindBuffer (gl_target, 0) ); - } - - ctx->current_buffer[buffer->last_target] = NULL; -} diff --git a/mutter/cogl/cogl/driver/gl/cogl-clip-stack-gl-private.h b/mutter/cogl/cogl/driver/gl/cogl-clip-stack-gl-private.h deleted file mode 100644 index c240cb0..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-clip-stack-gl-private.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-types.h" -#include "cogl/cogl-framebuffer.h" -#include "cogl/cogl-clip-stack.h" - -void -_cogl_clip_stack_gl_flush (CoglClipStack *stack, - CoglFramebuffer *framebuffer); diff --git a/mutter/cogl/cogl/driver/gl/cogl-clip-stack-gl.c b/mutter/cogl/cogl/driver/gl/cogl-clip-stack-gl.c deleted file mode 100644 index a1fe259..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-clip-stack-gl.c +++ /dev/null @@ -1,543 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010,2011,2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - * Robert Bragg - */ - - -#include "config.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-graphene.h" -#include "cogl/cogl-primitives-private.h" -#include "cogl/cogl-primitive-private.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" -#include "cogl/driver/gl/cogl-pipeline-opengl-private.h" -#include "cogl/driver/gl/cogl-clip-stack-gl-private.h" -#include "mtk/mtk.h" - -static void -add_stencil_clip_rectangle (CoglFramebuffer *framebuffer, - CoglMatrixEntry *modelview_entry, - float x_1, - float y_1, - float x_2, - float y_2, - gboolean merge) -{ - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglMatrixEntry *old_projection_entry, *old_modelview_entry; - - /* NB: This can be called while flushing the journal so we need - * to be very conservative with what state we change. - */ - old_projection_entry = g_steal_pointer (&ctx->current_projection_entry); - old_modelview_entry = g_steal_pointer (&ctx->current_modelview_entry); - - ctx->current_projection_entry = projection_stack->last_entry; - ctx->current_modelview_entry = modelview_entry; - - GE( ctx, glColorMask (FALSE, FALSE, FALSE, FALSE) ); - GE( ctx, glDepthMask (FALSE) ); - GE( ctx, glStencilMask (0x3) ); - - if (merge) - { - /* Add one to every pixel of the stencil buffer in the - rectangle */ - GE( ctx, glStencilFunc (GL_NEVER, 0x1, 0x3) ); - GE( ctx, glStencilOp (GL_INCR, GL_INCR, GL_INCR) ); - _cogl_rectangle_immediate (framebuffer, - ctx->stencil_pipeline, - x_1, y_1, x_2, y_2); - - /* Subtract one from all pixels in the stencil buffer so that - only pixels where both the original stencil buffer and the - rectangle are set will be valid */ - GE( ctx, glStencilOp (GL_DECR, GL_DECR, GL_DECR) ); - - ctx->current_projection_entry = &ctx->identity_entry; - ctx->current_modelview_entry = &ctx->identity_entry; - - _cogl_rectangle_immediate (framebuffer, - ctx->stencil_pipeline, - -1.0, -1.0, 1.0, 1.0); - } - else - { - GE( ctx, glEnable (GL_STENCIL_TEST) ); - - /* Initially disallow everything */ - GE( ctx, glClearStencil (0) ); - GE( ctx, glClear (GL_STENCIL_BUFFER_BIT) ); - - /* Punch out a hole to allow the rectangle */ - GE( ctx, glStencilFunc (GL_ALWAYS, 0x1, 0x1) ); - GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE) ); - _cogl_rectangle_immediate (framebuffer, - ctx->stencil_pipeline, - x_1, y_1, x_2, y_2); - } - - ctx->current_projection_entry = old_projection_entry; - ctx->current_modelview_entry = old_modelview_entry; - - /* Restore the stencil mode */ - GE( ctx, glDepthMask (TRUE) ); - GE( ctx, glColorMask (TRUE, TRUE, TRUE, TRUE) ); - GE( ctx, glStencilMask (0x0) ); - GE( ctx, glStencilFunc (GL_EQUAL, 0x1, 0x1) ); - GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) ); -} - -static void -add_stencil_clip_region (CoglFramebuffer *framebuffer, - MtkRegion *region, - gboolean merge) -{ - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglMatrixEntry *old_projection_entry, *old_modelview_entry; - graphene_matrix_t matrix; - int num_rectangles = mtk_region_num_rectangles (region); - int i; - CoglVertexP2 *vertices; - graphene_point3d_t p; - - /* NB: This can be called while flushing the journal so we need - * to be very conservative with what state we change. - */ - old_projection_entry = g_steal_pointer (&ctx->current_projection_entry); - old_modelview_entry = g_steal_pointer (&ctx->current_modelview_entry); - - ctx->current_projection_entry = &ctx->identity_entry; - ctx->current_modelview_entry = &ctx->identity_entry; - - /* The coordinates in the region are meant to be window coordinates, - * make a matrix that translates those across the viewport, and into - * the default [-1, -1, 1, 1] range. - */ - graphene_point3d_init (&p, - - cogl_framebuffer_get_viewport_x (framebuffer), - - cogl_framebuffer_get_viewport_y (framebuffer), - 0); - - graphene_matrix_init_translate (&matrix, &p); - graphene_matrix_scale (&matrix, - 2.0 / cogl_framebuffer_get_viewport_width (framebuffer), - - 2.0 / cogl_framebuffer_get_viewport_height (framebuffer), - 1); - graphene_matrix_translate (&matrix, &GRAPHENE_POINT3D_INIT (-1.f, 1.f, 0.f)); - - GE( ctx, glColorMask (FALSE, FALSE, FALSE, FALSE) ); - GE( ctx, glDepthMask (FALSE) ); - GE( ctx, glStencilMask (0x3) ); - - if (merge) - { - GE( ctx, glStencilFunc (GL_ALWAYS, 0x1, 0x3) ); - GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_INCR) ); - } - else - { - GE( ctx, glEnable (GL_STENCIL_TEST) ); - - /* Initially disallow everything */ - GE( ctx, glClearStencil (0) ); - GE( ctx, glClear (GL_STENCIL_BUFFER_BIT) ); - - /* Punch out holes to allow the rectangles */ - GE( ctx, glStencilFunc (GL_ALWAYS, 0x1, 0x1) ); - GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE) ); - } - - vertices = g_alloca (sizeof (CoglVertexP2) * num_rectangles * 6); - - for (i = 0; i < num_rectangles; i++) - { - MtkRectangle rect; - float x1, y1, z1, w1; - float x2, y2, z2, w2; - CoglVertexP2 *v = vertices + i * 6; - - rect = mtk_region_get_rectangle (region, i); - - x1 = rect.x; - y1 = rect.y; - z1 = 0.f; - w1 = 1.f; - - x2 = rect.x + rect.width; - y2 = rect.y + rect.height; - z2 = 0.f; - w2 = 1.f; - - cogl_graphene_matrix_project_point (&matrix, &x1, &y1, &z1, &w1); - cogl_graphene_matrix_project_point (&matrix, &x2, &y2, &z2, &w2); - - v[0].x = x1; - v[0].y = y1; - v[1].x = x1; - v[1].y = y2; - v[2].x = x2; - v[2].y = y1; - v[3].x = x1; - v[3].y = y2; - v[4].x = x2; - v[4].y = y2; - v[5].x = x2; - v[5].y = y1; - } - - cogl_2d_primitives_immediate (framebuffer, - ctx->stencil_pipeline, - COGL_VERTICES_MODE_TRIANGLES, - vertices, - 6 * num_rectangles); - - if (merge) - { - /* Subtract one from all pixels in the stencil buffer so that - * only pixels where both the original stencil buffer and the - * region are set will be valid - */ - GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_DECR) ); - _cogl_rectangle_immediate (framebuffer, - ctx->stencil_pipeline, - -1.0, -1.0, 1.0, 1.0); - } - - ctx->current_projection_entry = old_projection_entry; - ctx->current_modelview_entry = old_modelview_entry; - - /* Restore the stencil mode */ - GE (ctx, glDepthMask (TRUE)); - GE (ctx, glColorMask (TRUE, TRUE, TRUE, TRUE)); - GE( ctx, glStencilMask (0x0) ); - GE( ctx, glStencilFunc (GL_EQUAL, 0x1, 0x1) ); - GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) ); -} - -typedef void (*SilhouettePaintCallback) (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - void *user_data); - -static void -add_stencil_clip_silhouette (CoglFramebuffer *framebuffer, - SilhouettePaintCallback silhouette_callback, - CoglMatrixEntry *modelview_entry, - float bounds_x1, - float bounds_y1, - float bounds_x2, - float bounds_y2, - gboolean merge, - gboolean need_clear, - void *user_data) -{ - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglMatrixEntry *old_projection_entry, *old_modelview_entry; - - /* NB: This can be called while flushing the journal so we need - * to be very conservative with what state we change. - */ - old_projection_entry = g_steal_pointer (&ctx->current_projection_entry); - old_modelview_entry = g_steal_pointer (&ctx->current_modelview_entry); - - ctx->current_projection_entry = projection_stack->last_entry; - ctx->current_modelview_entry = modelview_entry; - - _cogl_pipeline_flush_gl_state (ctx, ctx->stencil_pipeline, - framebuffer, FALSE, FALSE); - - GE( ctx, glEnable (GL_STENCIL_TEST) ); - - GE( ctx, glColorMask (FALSE, FALSE, FALSE, FALSE) ); - GE( ctx, glDepthMask (FALSE) ); - - if (merge) - { - GE (ctx, glStencilMask (2)); - GE (ctx, glStencilFunc (GL_LEQUAL, 0x2, 0x6)); - } - else - { - /* If we're not using the stencil buffer for clipping then we - don't need to clear the whole stencil buffer, just the area - that will be drawn */ - if (need_clear) - /* If this is being called from the clip stack code then it - will have set up a scissor for the minimum bounding box of - all of the clips. That box will likely mean that this - _cogl_clear won't need to clear the entire - buffer. _cogl_framebuffer_clear_without_flush4f is used instead - of cogl_clear because it won't try to flush the journal */ - _cogl_framebuffer_clear_without_flush4f (framebuffer, - COGL_BUFFER_BIT_STENCIL, - 0, 0, 0, 0); - else - { - /* Just clear the bounding box */ - GE( ctx, glStencilMask (~(GLuint) 0) ); - GE( ctx, glStencilOp (GL_ZERO, GL_ZERO, GL_ZERO) ); - _cogl_rectangle_immediate (framebuffer, - ctx->stencil_pipeline, - bounds_x1, bounds_y1, - bounds_x2, bounds_y2); - } - GE (ctx, glStencilMask (1)); - GE (ctx, glStencilFunc (GL_LEQUAL, 0x1, 0x3)); - } - - GE (ctx, glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT)); - - silhouette_callback (framebuffer, ctx->stencil_pipeline, user_data); - - if (merge) - { - /* Now we have the new stencil buffer in bit 1 and the old - stencil buffer in bit 0 so we need to intersect them */ - GE (ctx, glStencilMask (3)); - GE (ctx, glStencilFunc (GL_NEVER, 0x2, 0x3)); - GE (ctx, glStencilOp (GL_DECR, GL_DECR, GL_DECR)); - /* Decrement all of the bits twice so that only pixels where the - value is 3 will remain */ - - ctx->current_projection_entry = &ctx->identity_entry; - ctx->current_modelview_entry = &ctx->identity_entry; - - _cogl_rectangle_immediate (framebuffer, ctx->stencil_pipeline, - -1.0, -1.0, 1.0, 1.0); - _cogl_rectangle_immediate (framebuffer, ctx->stencil_pipeline, - -1.0, -1.0, 1.0, 1.0); - } - - ctx->current_projection_entry = old_projection_entry; - ctx->current_modelview_entry = old_modelview_entry; - - GE (ctx, glStencilMask (~(GLuint) 0)); - GE (ctx, glDepthMask (TRUE)); - GE (ctx, glColorMask (TRUE, TRUE, TRUE, TRUE)); - - GE (ctx, glStencilFunc (GL_EQUAL, 0x1, 0x1)); - GE (ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP)); -} - -static void -paint_primitive_silhouette (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - void *user_data) -{ - _cogl_primitive_draw (user_data, - framebuffer, - pipeline, - COGL_DRAW_SKIP_JOURNAL_FLUSH | - COGL_DRAW_SKIP_PIPELINE_VALIDATION | - COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH); -} - -static void -add_stencil_clip_primitive (CoglFramebuffer *framebuffer, - CoglMatrixEntry *modelview_entry, - CoglPrimitive *primitive, - float bounds_x1, - float bounds_y1, - float bounds_x2, - float bounds_y2, - gboolean merge, - gboolean need_clear) -{ - add_stencil_clip_silhouette (framebuffer, - paint_primitive_silhouette, - modelview_entry, - bounds_x1, - bounds_y1, - bounds_x2, - bounds_y2, - merge, - need_clear, - primitive); -} - -void -_cogl_clip_stack_gl_flush (CoglClipStack *stack, - CoglFramebuffer *framebuffer) -{ - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - gboolean using_stencil_buffer = FALSE; - int scissor_x0; - int scissor_y0; - int scissor_x1; - int scissor_y1; - CoglClipStack *entry; - int scissor_y_start; - - /* If we have already flushed this state then we don't need to do - anything */ - if (ctx->current_clip_stack_valid) - { - if (ctx->current_clip_stack == stack) - return; - - _cogl_clip_stack_unref (ctx->current_clip_stack); - } - - ctx->current_clip_stack_valid = TRUE; - ctx->current_clip_stack = _cogl_clip_stack_ref (stack); - - GE( ctx, glDisable (GL_STENCIL_TEST) ); - - /* If the stack is empty then there's nothing else to do - */ - if (stack == NULL) - { - COGL_NOTE (CLIPPING, "Flushed empty clip stack"); - - GE (ctx, glDisable (GL_SCISSOR_TEST)); - return; - } - - /* Calculate the scissor rect first so that if we eventually have to - clear the stencil buffer then the clear will be clipped to the - intersection of all of the bounding boxes. This saves having to - clear the whole stencil buffer */ - _cogl_clip_stack_get_bounds (stack, - &scissor_x0, &scissor_y0, - &scissor_x1, &scissor_y1); - - /* Enable scissoring as soon as possible */ - if (scissor_x0 >= scissor_x1 || scissor_y0 >= scissor_y1) - scissor_x0 = scissor_y0 = scissor_x1 = scissor_y1 = scissor_y_start = 0; - else - { - /* We store the entry coordinates in Cogl coordinate space - * but OpenGL requires the window origin to be the bottom - * left so we may need to convert the incoming coordinates. - * - * NB: Cogl forces all offscreen rendering to be done upside - * down so in this case no conversion is needed. - */ - - if (cogl_framebuffer_is_y_flipped (framebuffer)) - { - scissor_y_start = scissor_y0; - } - else - { - int framebuffer_height = - cogl_framebuffer_get_height (framebuffer); - - scissor_y_start = framebuffer_height - scissor_y1; - } - } - - COGL_NOTE (CLIPPING, "Flushing scissor to (%i, %i, %i, %i)", - scissor_x0, scissor_y0, - scissor_x1, scissor_y1); - - GE (ctx, glEnable (GL_SCISSOR_TEST)); - GE (ctx, glScissor (scissor_x0, scissor_y_start, - scissor_x1 - scissor_x0, - scissor_y1 - scissor_y0)); - - /* Add all of the entries. This will end up adding them in the - reverse order that they were specified but as all of the clips - are intersecting it should work out the same regardless of the - order */ - for (entry = stack; entry; entry = entry->parent) - { - switch (entry->type) - { - case COGL_CLIP_STACK_PRIMITIVE: - { - CoglClipStackPrimitive *primitive_entry = - (CoglClipStackPrimitive *) entry; - - COGL_NOTE (CLIPPING, "Adding stencil clip for primitive"); - - add_stencil_clip_primitive (framebuffer, - primitive_entry->matrix_entry, - primitive_entry->primitive, - primitive_entry->bounds_x1, - primitive_entry->bounds_y1, - primitive_entry->bounds_x2, - primitive_entry->bounds_y2, - using_stencil_buffer, - TRUE); - - using_stencil_buffer = TRUE; - break; - } - case COGL_CLIP_STACK_RECT: - { - CoglClipStackRect *rect = (CoglClipStackRect *) entry; - - /* We don't need to do anything extra if the clip for this - rectangle was entirely described by its scissor bounds */ - if (!rect->can_be_scissor || - G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_STENCILLING))) - { - COGL_NOTE (CLIPPING, "Adding stencil clip for rectangle"); - - add_stencil_clip_rectangle (framebuffer, - rect->matrix_entry, - rect->x0, - rect->y0, - rect->x1, - rect->y1, - using_stencil_buffer); - using_stencil_buffer = TRUE; - } - break; - } - case COGL_CLIP_STACK_REGION: - { - CoglClipStackRegion *region = (CoglClipStackRegion *) entry; - - /* If nrectangles <= 1, it can be fully represented with the - * scissor clip. - */ - if (mtk_region_num_rectangles (region->region) > 1 || - G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_STENCILLING))) - { - COGL_NOTE (CLIPPING, "Adding stencil clip for region"); - - add_stencil_clip_region (framebuffer, region->region, - using_stencil_buffer); - using_stencil_buffer = TRUE; - } - break; - } - } - } -} diff --git a/mutter/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h b/mutter/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h deleted file mode 100644 index 9918952..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-attribute-private.h" -#include "cogl/cogl-framebuffer-driver.h" -#include "cogl/cogl-gl-header.h" - -#define COGL_TYPE_GL_FRAMEBUFFER (cogl_gl_framebuffer_get_type ()) -G_DECLARE_DERIVABLE_TYPE (CoglGlFramebuffer, cogl_gl_framebuffer, - COGL, GL_FRAMEBUFFER, - CoglFramebufferDriver) - -struct _CoglGlFramebufferClass -{ - CoglFramebufferDriverClass parent_class; - - void (* bind) (CoglGlFramebuffer *gl_framebuffer, - GLenum target); - - void (* flush_stereo_mode_state) (CoglGlFramebuffer *gl_framebuffer); -}; - -void -cogl_gl_framebuffer_bind (CoglGlFramebuffer *gl_framebuffer, - GLenum target); - -void -cogl_gl_framebuffer_flush_state_differences (CoglGlFramebuffer *gl_framebuffer, - unsigned long differences); diff --git a/mutter/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/mutter/cogl/cogl/driver/gl/cogl-framebuffer-gl.c deleted file mode 100644 index f175ad0..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-framebuffer-gl.c +++ /dev/null @@ -1,676 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2012 Intel Corporation. - * Copyright (C) 2018 DisplayLink (UK) Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-framebuffer.h" -#include "cogl/cogl-offscreen-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" -#include "cogl/driver/gl/cogl-framebuffer-gl-private.h" -#include "cogl/driver/gl/cogl-bitmap-gl-private.h" -#include "cogl/driver/gl/cogl-buffer-gl-private.h" - -#include -#include - -G_DEFINE_ABSTRACT_TYPE (CoglGlFramebuffer, cogl_gl_framebuffer, - COGL_TYPE_FRAMEBUFFER_DRIVER) - -static CoglContext * -context_from_driver (CoglFramebufferDriver *driver) -{ - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - - return cogl_framebuffer_get_context (framebuffer); -} - -static void -cogl_gl_framebuffer_flush_viewport_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - float viewport_x, viewport_y, viewport_width, viewport_height; - float gl_viewport_y; - - cogl_framebuffer_get_viewport4f (framebuffer, - &viewport_x, - &viewport_y, - &viewport_width, - &viewport_height); - - g_return_if_fail (viewport_width >= 0); - g_return_if_fail (viewport_height >= 0); - - /* Convert the Cogl viewport y offset to an OpenGL viewport y offset - * NB: OpenGL defines its window and viewport origins to be bottom - * left, while Cogl defines them to be top left. - */ - if (cogl_framebuffer_is_y_flipped (framebuffer)) - gl_viewport_y = viewport_y; - else - gl_viewport_y = - cogl_framebuffer_get_height (framebuffer) - - (viewport_y + viewport_height); - - COGL_NOTE (OPENGL, "Calling glViewport(%f, %f, %f, %f)", - viewport_x, - gl_viewport_y, - viewport_width, - viewport_height); - - GE (cogl_framebuffer_get_context (framebuffer), - glViewport (viewport_x, - gl_viewport_y, - viewport_width, - viewport_height)); -} - -static void -cogl_gl_framebuffer_flush_clip_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - - _cogl_clip_stack_flush (_cogl_framebuffer_get_clip_stack (framebuffer), - framebuffer); -} - -static void -cogl_gl_framebuffer_flush_dither_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - gboolean is_dither_enabled; - - is_dither_enabled = cogl_framebuffer_get_dither_enabled (framebuffer); - if (ctx->current_gl_dither_enabled != is_dither_enabled) - { - if (is_dither_enabled) - GE (ctx, glEnable (GL_DITHER)); - else - GE (ctx, glDisable (GL_DITHER)); - ctx->current_gl_dither_enabled = is_dither_enabled; - } -} - -static void -cogl_gl_framebuffer_flush_modelview_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglMatrixEntry *modelview_entry = - _cogl_framebuffer_get_modelview_entry (framebuffer); - - _cogl_context_set_current_modelview_entry (ctx, modelview_entry); -} - -static void -cogl_gl_framebuffer_flush_projection_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglMatrixEntry *projection_entry = - _cogl_framebuffer_get_projection_entry (framebuffer); - - _cogl_context_set_current_projection_entry (ctx, projection_entry); -} - -static void -cogl_gl_framebuffer_flush_front_face_winding_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglPipelineCullFaceMode mode; - - /* NB: The face winding state is actually owned by the current - * CoglPipeline. - * - * If we don't have a current pipeline then we can just assume that - * when we later do flush a pipeline we will check the current - * framebuffer to know how to setup the winding */ - if (!context->current_pipeline) - return; - - mode = cogl_pipeline_get_cull_face_mode (context->current_pipeline); - - /* If the current CoglPipeline has a culling mode that doesn't care - * about the winding we can avoid forcing an update of the state and - * bail out. */ - if (mode == COGL_PIPELINE_CULL_FACE_MODE_NONE || - mode == COGL_PIPELINE_CULL_FACE_MODE_BOTH) - return; - - /* Since the winding state is really owned by the current pipeline - * the way we "flush" an updated winding is to dirty the pipeline - * state... */ - context->current_pipeline_changes_since_flush |= - COGL_PIPELINE_STATE_CULL_FACE; - context->current_pipeline_age--; -} - -static void -cogl_gl_framebuffer_flush_stereo_mode_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglGlFramebufferClass *klass = - COGL_GL_FRAMEBUFFER_GET_CLASS (gl_framebuffer); - - klass->flush_stereo_mode_state (gl_framebuffer); -} - -void -cogl_gl_framebuffer_flush_state_differences (CoglGlFramebuffer *gl_framebuffer, - unsigned long differences) -{ - int bit; - - COGL_FLAGS_FOREACH_START (&differences, 1, bit) - { - /* XXX: We considered having an array of callbacks for each state index - * that we'd call here but decided that this way the compiler is more - * likely going to be able to in-line the flush functions and use the - * index to jump straight to the required code. */ - switch (bit) - { - case COGL_FRAMEBUFFER_STATE_INDEX_VIEWPORT: - cogl_gl_framebuffer_flush_viewport_state (gl_framebuffer); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_CLIP: - cogl_gl_framebuffer_flush_clip_state (gl_framebuffer); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_DITHER: - cogl_gl_framebuffer_flush_dither_state (gl_framebuffer); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_MODELVIEW: - cogl_gl_framebuffer_flush_modelview_state (gl_framebuffer); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION: - cogl_gl_framebuffer_flush_projection_state (gl_framebuffer); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING: - cogl_gl_framebuffer_flush_front_face_winding_state (gl_framebuffer); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE: - /* Nothing to do for depth write state change; the state will always - * be taken into account when flushing the pipeline's depth state. */ - break; - case COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE: - cogl_gl_framebuffer_flush_stereo_mode_state (gl_framebuffer); - break; - default: - g_warn_if_reached (); - } - } - COGL_FLAGS_FOREACH_END; -} - -void -cogl_gl_framebuffer_bind (CoglGlFramebuffer *gl_framebuffer, - GLenum target) -{ - COGL_GL_FRAMEBUFFER_GET_CLASS (gl_framebuffer)->bind (gl_framebuffer, - target); -} - -static void -cogl_gl_framebuffer_clear (CoglFramebufferDriver *driver, - unsigned long buffers, - float red, - float green, - float blue, - float alpha) -{ - CoglContext *ctx = context_from_driver (driver); - GLbitfield gl_buffers = 0; - - if (buffers & COGL_BUFFER_BIT_COLOR) - { - GE( ctx, glClearColor (red, green, blue, alpha) ); - gl_buffers |= GL_COLOR_BUFFER_BIT; - } - - if (buffers & COGL_BUFFER_BIT_DEPTH) - { - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - gboolean is_depth_writing_enabled; - - gl_buffers |= GL_DEPTH_BUFFER_BIT; - - is_depth_writing_enabled = - cogl_framebuffer_get_depth_write_enabled (framebuffer); - if (ctx->depth_writing_enabled_cache != is_depth_writing_enabled) - { - GE( ctx, glDepthMask (is_depth_writing_enabled)); - - ctx->depth_writing_enabled_cache = is_depth_writing_enabled; - - /* Make sure the DepthMask is updated when the next primitive is drawn */ - ctx->current_pipeline_changes_since_flush |= - COGL_PIPELINE_STATE_DEPTH; - ctx->current_pipeline_age--; - } - } - - if (buffers & COGL_BUFFER_BIT_STENCIL) - gl_buffers |= GL_STENCIL_BUFFER_BIT; - - - GE (ctx, glClear (gl_buffers)); -} - -static void -cogl_gl_framebuffer_finish (CoglFramebufferDriver *driver) -{ - CoglContext *ctx = context_from_driver (driver); - - ctx->glFinish (); -} - -static void -cogl_gl_framebuffer_flush (CoglFramebufferDriver *driver) -{ - CoglContext *ctx = context_from_driver (driver); - - ctx->glFlush (); -} - -static void -cogl_gl_framebuffer_draw_attributes (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags) -{ - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - - _cogl_flush_attributes_state (framebuffer, pipeline, flags, - attributes, n_attributes); - - GE (cogl_framebuffer_get_context (framebuffer), - glDrawArrays ((GLenum)mode, first_vertex, n_vertices)); -} - -static size_t -sizeof_index_type (CoglIndicesType type) -{ - switch (type) - { - case COGL_INDICES_TYPE_UNSIGNED_BYTE: - return 1; - case COGL_INDICES_TYPE_UNSIGNED_SHORT: - return 2; - case COGL_INDICES_TYPE_UNSIGNED_INT: - return 4; - } - g_return_val_if_reached (0); -} - -static void -cogl_gl_framebuffer_draw_indexed_attributes (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags) -{ - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglBuffer *buffer; - uint8_t *base; - size_t buffer_offset; - size_t index_size; - GLenum indices_gl_type = 0; - - _cogl_flush_attributes_state (framebuffer, pipeline, flags, - attributes, n_attributes); - - buffer = COGL_BUFFER (cogl_indices_get_buffer (indices)); - - /* Note: we don't try and catch errors with binding the index buffer - * here since OOM errors at this point indicate that nothing has yet - * been uploaded to the indices buffer which we consider to be a - * programmer error. - */ - base = _cogl_buffer_gl_bind (buffer, - COGL_BUFFER_BIND_TARGET_INDEX_BUFFER, NULL); - buffer_offset = cogl_indices_get_offset (indices); - index_size = sizeof_index_type (cogl_indices_get_indices_type (indices)); - - switch (cogl_indices_get_indices_type (indices)) - { - case COGL_INDICES_TYPE_UNSIGNED_BYTE: - indices_gl_type = GL_UNSIGNED_BYTE; - break; - case COGL_INDICES_TYPE_UNSIGNED_SHORT: - indices_gl_type = GL_UNSIGNED_SHORT; - break; - case COGL_INDICES_TYPE_UNSIGNED_INT: - indices_gl_type = GL_UNSIGNED_INT; - break; - } - - GE (cogl_framebuffer_get_context (framebuffer), - glDrawElements ((GLenum)mode, - n_vertices, - indices_gl_type, - base + buffer_offset + index_size * first_vertex)); - - _cogl_buffer_gl_unbind (buffer); -} - -static gboolean -cogl_gl_framebuffer_read_pixels_into_bitmap (CoglFramebufferDriver *driver, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap, - GError **error) -{ - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - int framebuffer_height = cogl_framebuffer_get_height (framebuffer); - int width = cogl_bitmap_get_width (bitmap); - int height = cogl_bitmap_get_height (bitmap); - CoglPixelFormat format = cogl_bitmap_get_format (bitmap); - CoglPixelFormat internal_format = - cogl_framebuffer_get_internal_format (framebuffer); - CoglPixelFormat read_format; - GLenum gl_format; - GLenum gl_type; - GLenum gl_pack_enum = GL_FALSE; - int bytes_per_pixel; - gboolean format_mismatch; - gboolean stride_mismatch; - gboolean pack_invert_set; - int status = FALSE; - - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); - - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - - /* The y coordinate should be given in OpenGL's coordinate system - * so 0 is the bottom row. - */ - if (!cogl_framebuffer_is_y_flipped (framebuffer)) - y = framebuffer_height - y - height; - - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_MESA_PACK_INVERT) && - (source & COGL_READ_PIXELS_NO_FLIP) == 0 && - !cogl_framebuffer_is_y_flipped (framebuffer)) - { - if (ctx->driver == COGL_DRIVER_GLES2) - gl_pack_enum = GL_PACK_REVERSE_ROW_ORDER_ANGLE; - else - gl_pack_enum = GL_PACK_INVERT_MESA; - - GE (ctx, glPixelStorei (gl_pack_enum, TRUE)); - pack_invert_set = TRUE; - } - else - pack_invert_set = FALSE; - - read_format = ctx->driver_vtable->get_read_pixels_format (ctx, - internal_format, - format, - &gl_format, - &gl_type); - - format_mismatch = - (read_format & ~COGL_PREMULT_BIT) != (format & ~COGL_PREMULT_BIT); - - bytes_per_pixel = cogl_pixel_format_get_bytes_per_pixel (format, 0); - stride_mismatch = - !_cogl_has_private_feature (ctx, - COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_STRIDE) && - (cogl_bitmap_get_rowstride (bitmap) != bytes_per_pixel * width); - - if (format_mismatch || stride_mismatch) - { - CoglBitmap *tmp_bmp; - int bpp, rowstride; - uint8_t *tmp_data; - gboolean succeeded; - - if (COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (read_format)) - { - read_format = ((read_format & ~COGL_PREMULT_BIT) | - (internal_format & COGL_PREMULT_BIT)); - } - - tmp_bmp = _cogl_bitmap_new_with_malloc_buffer (ctx, - width, height, - read_format, - error); - if (!tmp_bmp) - goto EXIT; - - bpp = cogl_pixel_format_get_bytes_per_pixel (read_format, 0); - rowstride = cogl_bitmap_get_rowstride (tmp_bmp); - - ctx->texture_driver->prep_gl_for_pixels_download (ctx, - rowstride, - width, - bpp); - - /* Note: we don't worry about catching errors here since we know - * we won't be lazily allocating storage for this buffer so it - * won't fail due to lack of memory. */ - tmp_data = _cogl_bitmap_gl_bind (tmp_bmp, - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD, - NULL); - - GE( ctx, glReadPixels (x, y, width, height, - gl_format, gl_type, - tmp_data) ); - - _cogl_bitmap_gl_unbind (tmp_bmp); - - if (!(internal_format & COGL_A_BIT)) - { - _cogl_bitmap_set_format (tmp_bmp, read_format & ~COGL_PREMULT_BIT); - _cogl_bitmap_set_format (bitmap, format & ~COGL_PREMULT_BIT); - } - - succeeded = _cogl_bitmap_convert_into_bitmap (tmp_bmp, bitmap, error); - - _cogl_bitmap_set_format (bitmap, format); - - g_object_unref (tmp_bmp); - - if (!succeeded) - goto EXIT; - } - else - { - CoglBitmap *shared_bmp; - CoglPixelFormat bmp_format; - int bpp, rowstride; - gboolean succeeded = FALSE; - uint8_t *pixels; - GError *internal_error = NULL; - - rowstride = cogl_bitmap_get_rowstride (bitmap); - - /* We match the premultiplied state of the target buffer to the - * premultiplied state of the framebuffer so that it will get - * converted to the right format below */ - if (COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (format)) - bmp_format = ((format & ~COGL_PREMULT_BIT) | - (internal_format & COGL_PREMULT_BIT)); - else - bmp_format = format; - - if (bmp_format != format) - shared_bmp = _cogl_bitmap_new_shared (bitmap, - bmp_format, - width, height, - rowstride); - else - shared_bmp = g_object_ref (bitmap); - - bpp = cogl_pixel_format_get_bytes_per_pixel (bmp_format, 0); - - ctx->texture_driver->prep_gl_for_pixels_download (ctx, - rowstride, - width, - bpp); - - pixels = _cogl_bitmap_gl_bind (shared_bmp, - COGL_BUFFER_ACCESS_WRITE, - 0, /* hints */ - &internal_error); - /* NB: _cogl_bitmap_gl_bind() can return NULL in successful - * cases so we have to explicitly check the cogl error pointer - * to know if there was a problem */ - if (internal_error) - { - g_object_unref (shared_bmp); - g_propagate_error (error, internal_error); - goto EXIT; - } - - GE( ctx, glReadPixels (x, y, - width, height, - gl_format, gl_type, - pixels) ); - - _cogl_bitmap_gl_unbind (shared_bmp); - - /* Convert to the premult format specified by the caller - in-place. This will do nothing if the premult status is already - correct. */ - if (!(internal_format & COGL_A_BIT) || - _cogl_bitmap_convert_premult_status (shared_bmp, format, error)) - succeeded = TRUE; - - g_object_unref (shared_bmp); - - if (!succeeded) - goto EXIT; - } - - if (!cogl_framebuffer_is_y_flipped (framebuffer) && - (source & COGL_READ_PIXELS_NO_FLIP) == 0 && - !pack_invert_set) - { - uint8_t *temprow; - int rowstride; - uint8_t *pixels; - - rowstride = cogl_bitmap_get_rowstride (bitmap); - pixels = _cogl_bitmap_map (bitmap, - COGL_BUFFER_ACCESS_READ | - COGL_BUFFER_ACCESS_WRITE, - 0, /* hints */ - error); - - if (pixels == NULL) - goto EXIT; - - temprow = g_alloca (rowstride * sizeof (uint8_t)); - - /* vertically flip the buffer in-place */ - for (y = 0; y < height / 2; y++) - { - if (y != height - y - 1) /* skip center row */ - { - memcpy (temprow, - pixels + y * rowstride, rowstride); - memcpy (pixels + y * rowstride, - pixels + (height - y - 1) * rowstride, rowstride); - memcpy (pixels + (height - y - 1) * rowstride, - temprow, - rowstride); - } - } - - _cogl_bitmap_unmap (bitmap); - } - - status = TRUE; - -EXIT: - - /* Currently this function owns the pack_invert state and we don't want this - * to interfere with other Cogl components so all other code can assume that - * we leave the pack_invert state off. */ - if (pack_invert_set) - GE (ctx, glPixelStorei (gl_pack_enum, FALSE)); - - return status; -} - -static void -cogl_gl_framebuffer_init (CoglGlFramebuffer *gl_framebuffer) -{ -} - -static void -cogl_gl_framebuffer_class_init (CoglGlFramebufferClass *klass) -{ - CoglFramebufferDriverClass *driver_class = - COGL_FRAMEBUFFER_DRIVER_CLASS (klass); - - driver_class->clear = cogl_gl_framebuffer_clear; - driver_class->finish = cogl_gl_framebuffer_finish; - driver_class->flush = cogl_gl_framebuffer_flush; - driver_class->draw_attributes = cogl_gl_framebuffer_draw_attributes; - driver_class->draw_indexed_attributes = - cogl_gl_framebuffer_draw_indexed_attributes; - driver_class->read_pixels_into_bitmap = - cogl_gl_framebuffer_read_pixels_into_bitmap; -} diff --git a/mutter/cogl/cogl/driver/gl/cogl-gl-framebuffer-back.c b/mutter/cogl/cogl/driver/gl/cogl-gl-framebuffer-back.c deleted file mode 100644 index a5bcd53..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-gl-framebuffer-back.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2012 Intel Corporation. - * Copyright (C) 2018 DisplayLink (UK) Ltd. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "config.h" - -#include "cogl/driver/gl/cogl-gl-framebuffer-back.h" - -#include - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-offscreen-private.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" - -struct _CoglGlFramebufferBack -{ - CoglGlFramebuffer parent; - - gboolean dirty_bitmasks; - CoglFramebufferBits bits; -}; - -G_DEFINE_TYPE (CoglGlFramebufferBack, cogl_gl_framebuffer_back, - COGL_TYPE_GL_FRAMEBUFFER) - -static gboolean -ensure_bits_initialized (CoglGlFramebufferBack *gl_framebuffer_back) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer_back); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglFramebufferBits *bits = &gl_framebuffer_back->bits; - g_autoptr (GError) error = NULL; - - if (!gl_framebuffer_back->dirty_bitmasks) - return TRUE; - - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS)) - { - const struct { - GLenum attachment, pname; - size_t offset; - } params[] = { - { - .attachment = GL_BACK_LEFT, - .pname = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, - .offset = offsetof (CoglFramebufferBits, red), - }, - { - .attachment = GL_BACK_LEFT, - .pname = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, - .offset = offsetof (CoglFramebufferBits, green), - }, - { - .attachment = GL_BACK_LEFT, - .pname = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, - .offset = offsetof (CoglFramebufferBits, blue), - }, - { - .attachment = GL_BACK_LEFT, - .pname = GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, - .offset = offsetof (CoglFramebufferBits, alpha), - }, - { - .attachment = GL_DEPTH, - .pname = GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, - .offset = offsetof (CoglFramebufferBits, depth), - }, - { - .attachment = GL_STENCIL, - .pname = GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, - .offset = offsetof (CoglFramebufferBits, stencil), - }, - }; - int i; - - for (i = 0; i < G_N_ELEMENTS (params); i++) - { - int *value = - (int *) ((uint8_t *) bits + params[i].offset); - - GE (ctx, glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, - params[i].attachment, - params[i].pname, - value)); - } - } - else - { - return FALSE; - } - - COGL_NOTE (FRAMEBUFFER, - "RGBA/D/S Bits for framebuffer[%p, %s]: %d, %d, %d, %d, %d, %d", - framebuffer, - G_OBJECT_TYPE_NAME (framebuffer), - bits->red, - bits->blue, - bits->green, - bits->alpha, - bits->depth, - bits->stencil); - - gl_framebuffer_back->dirty_bitmasks = FALSE; - - return TRUE; -} - -static void -cogl_gl_framebuffer_back_query_bits (CoglFramebufferDriver *driver, - CoglFramebufferBits *bits) -{ - CoglGlFramebufferBack *gl_framebuffer_back = COGL_GL_FRAMEBUFFER_BACK (driver); - - if (!ensure_bits_initialized (gl_framebuffer_back)) - return; - - *bits = gl_framebuffer_back->bits; -} - -static void -cogl_gl_framebuffer_back_discard_buffers (CoglFramebufferDriver *driver, - unsigned long buffers) -{ - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - GLenum attachments[3]; - int i = 0; - - if (!ctx->glDiscardFramebuffer) - return; - - if (buffers & COGL_BUFFER_BIT_COLOR) - attachments[i++] = GL_COLOR; - if (buffers & COGL_BUFFER_BIT_DEPTH) - attachments[i++] = GL_DEPTH; - if (buffers & COGL_BUFFER_BIT_STENCIL) - attachments[i++] = GL_STENCIL; - - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - GE (ctx, glDiscardFramebuffer (GL_FRAMEBUFFER, i, attachments)); -} - -static void -cogl_gl_framebuffer_back_bind (CoglGlFramebuffer *gl_framebuffer, - GLenum target) -{ - CoglGlFramebufferBack *gl_framebuffer_back = - COGL_GL_FRAMEBUFFER_BACK (gl_framebuffer); - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer_back); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - cogl_onscreen_bind (COGL_ONSCREEN (framebuffer)); - - GE (ctx, glBindFramebuffer (target, 0)); - - /* Initialise the glDrawBuffer state the first time the context - * is bound to the default framebuffer. If the winsys is using a - * surfaceless context for the initial make current then the - * default draw buffer will be GL_NONE so we need to correct - * that. We can't do it any earlier because binding GL_BACK when - * there is no default framebuffer won't work */ - if (!ctx->was_bound_to_onscreen) - { - if (ctx->glDrawBuffer) - { - GE (ctx, glDrawBuffer (GL_BACK)); - } - else if (ctx->glDrawBuffers) - { - /* glDrawBuffer isn't available on GLES 3.0 so we need - * to be able to use glDrawBuffers as well. On GLES 2 - * neither is available but the state should always be - * GL_BACK anyway so we don't need to set anything. On - * desktop GL this must be GL_BACK_LEFT instead of - * GL_BACK but as this code path will only be hit for - * GLES we can just use GL_BACK. */ - static const GLenum buffers[] = { GL_BACK }; - - GE (ctx, glDrawBuffers (G_N_ELEMENTS (buffers), buffers)); - } - - ctx->was_bound_to_onscreen = TRUE; - } -} - -static void -cogl_gl_framebuffer_back_flush_stereo_mode_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - GLenum draw_buffer = GL_BACK; - - if (!ctx->glDrawBuffer) - return; - - /* The one-shot default draw buffer setting in _cogl_framebuffer_gl_bind - * must have already happened. If not it would override what we set here. */ - g_assert (ctx->was_bound_to_onscreen); - - switch (cogl_framebuffer_get_stereo_mode (framebuffer)) - { - case COGL_STEREO_BOTH: - draw_buffer = GL_BACK; - break; - case COGL_STEREO_LEFT: - draw_buffer = GL_BACK_LEFT; - break; - case COGL_STEREO_RIGHT: - draw_buffer = GL_BACK_RIGHT; - break; - } - - if (ctx->current_gl_draw_buffer != draw_buffer) - { - GE (ctx, glDrawBuffer (draw_buffer)); - ctx->current_gl_draw_buffer = draw_buffer; - } -} - -CoglGlFramebufferBack * -cogl_gl_framebuffer_back_new (CoglFramebuffer *framebuffer, - const CoglFramebufferDriverConfig *driver_config, - GError **error) -{ - if (!COGL_IS_ONSCREEN (framebuffer)) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Incompatible framebuffer"); - return NULL; - } - - return g_object_new (COGL_TYPE_GL_FRAMEBUFFER_BACK, - "framebuffer", framebuffer, - NULL); -} - -static void -cogl_gl_framebuffer_back_init (CoglGlFramebufferBack *gl_framebuffer_back) -{ - gl_framebuffer_back->dirty_bitmasks = TRUE; -} - -static void -cogl_gl_framebuffer_back_class_init (CoglGlFramebufferBackClass *klass) -{ - CoglFramebufferDriverClass *driver_class = - COGL_FRAMEBUFFER_DRIVER_CLASS (klass); - CoglGlFramebufferClass *gl_framebuffer_class = - COGL_GL_FRAMEBUFFER_CLASS (klass); - - driver_class->query_bits = cogl_gl_framebuffer_back_query_bits; - driver_class->discard_buffers = cogl_gl_framebuffer_back_discard_buffers; - - gl_framebuffer_class->bind = cogl_gl_framebuffer_back_bind; - gl_framebuffer_class->flush_stereo_mode_state = - cogl_gl_framebuffer_back_flush_stereo_mode_state; -} diff --git a/mutter/cogl/cogl/driver/gl/cogl-gl-framebuffer-back.h b/mutter/cogl/cogl/driver/gl/cogl-gl-framebuffer-back.h deleted file mode 100644 index 293d339..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-gl-framebuffer-back.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#pragma once - -#include "cogl/driver/gl/cogl-framebuffer-gl-private.h" - -#define COGL_TYPE_GL_FRAMEBUFFER_BACK (cogl_gl_framebuffer_back_get_type ()) -G_DECLARE_FINAL_TYPE (CoglGlFramebufferBack, cogl_gl_framebuffer_back, - COGL, GL_FRAMEBUFFER_BACK, - CoglGlFramebuffer) - -CoglGlFramebufferBack * -cogl_gl_framebuffer_back_new (CoglFramebuffer *framebuffer, - const CoglFramebufferDriverConfig *driver_config, - GError **error); diff --git a/mutter/cogl/cogl/driver/gl/cogl-gl-framebuffer-fbo.c b/mutter/cogl/cogl/driver/gl/cogl-gl-framebuffer-fbo.c deleted file mode 100644 index 6880e4a..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-gl-framebuffer-fbo.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2012 Intel Corporation. - * Copyright (C) 2018 DisplayLink (UK) Ltd. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "config.h" - -#include "cogl/driver/gl/cogl-gl-framebuffer-fbo.h" - -#include - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-offscreen-private.h" -#include "cogl/driver/gl/cogl-texture-gl-private.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" - -typedef struct _CoglGlFbo -{ - GLuint fbo_handle; - GList *renderbuffers; - int samples_per_pixel; -} CoglGlFbo; - -struct _CoglGlFramebufferFbo -{ - CoglGlFramebuffer parent; - - CoglGlFbo gl_fbo; - - gboolean dirty_bitmasks; - CoglFramebufferBits bits; -}; - -G_DEFINE_TYPE (CoglGlFramebufferFbo, cogl_gl_framebuffer_fbo, - COGL_TYPE_GL_FRAMEBUFFER) - -static gboolean -ensure_bits_initialized (CoglGlFramebufferFbo *gl_framebuffer_fbo) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer_fbo); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglFramebufferBits *bits = &gl_framebuffer_fbo->bits; - g_autoptr (GError) error = NULL; - - if (!gl_framebuffer_fbo->dirty_bitmasks) - return TRUE; - - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS)) - { - const struct { - GLenum attachment, pname; - size_t offset; - } params[] = { - { - .attachment = GL_COLOR_ATTACHMENT0, - .pname = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, - .offset = offsetof (CoglFramebufferBits, red), - }, - { - .attachment = GL_COLOR_ATTACHMENT0, - .pname = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, - .offset = offsetof (CoglFramebufferBits, green), - }, - { - .attachment = GL_COLOR_ATTACHMENT0, - .pname = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, - .offset = offsetof (CoglFramebufferBits, blue), - }, - { - .attachment = GL_COLOR_ATTACHMENT0, - .pname = GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, - .offset = offsetof (CoglFramebufferBits, alpha), - }, - { - .attachment = GL_DEPTH_ATTACHMENT, - .pname = GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, - .offset = offsetof (CoglFramebufferBits, depth), - }, - { - .attachment = GL_STENCIL_ATTACHMENT, - .pname = GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, - .offset = offsetof (CoglFramebufferBits, stencil), - }, - }; - int i; - - for (i = 0; i < G_N_ELEMENTS (params); i++) - { - int *value = - (int *) ((uint8_t *) bits + params[i].offset); - - GE (ctx, glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, - params[i].attachment, - params[i].pname, - value)); - } - } - else - { - return FALSE; - } - - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) && - (cogl_framebuffer_get_internal_format (framebuffer) == - COGL_PIXEL_FORMAT_A_8)) - { - bits->alpha = bits->red; - bits->red = 0; - } - - COGL_NOTE (FRAMEBUFFER, - "RGBA/D/S Bits for framebuffer[%p, %s]: %d, %d, %d, %d, %d, %d", - framebuffer, - G_OBJECT_TYPE_NAME (framebuffer), - bits->red, - bits->blue, - bits->green, - bits->alpha, - bits->depth, - bits->stencil); - - gl_framebuffer_fbo->dirty_bitmasks = FALSE; - - return TRUE; -} - -static void -cogl_gl_framebuffer_fbo_query_bits (CoglFramebufferDriver *driver, - CoglFramebufferBits *bits) -{ - CoglGlFramebufferFbo *gl_framebuffer_fbo = COGL_GL_FRAMEBUFFER_FBO (driver); - - if (!ensure_bits_initialized (gl_framebuffer_fbo)) - return; - - *bits = gl_framebuffer_fbo->bits; -} - -static void -cogl_gl_framebuffer_fbo_discard_buffers (CoglFramebufferDriver *driver, - unsigned long buffers) -{ - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - GLenum attachments[3]; - int i = 0; - - if (!ctx->glDiscardFramebuffer) - return; - - if (buffers & COGL_BUFFER_BIT_COLOR) - attachments[i++] = GL_COLOR_ATTACHMENT0; - if (buffers & COGL_BUFFER_BIT_DEPTH) - attachments[i++] = GL_DEPTH_ATTACHMENT; - if (buffers & COGL_BUFFER_BIT_STENCIL) - attachments[i++] = GL_STENCIL_ATTACHMENT; - - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - GE (ctx, glDiscardFramebuffer (GL_FRAMEBUFFER, i, attachments)); -} - -static void -cogl_gl_framebuffer_fbo_bind (CoglGlFramebuffer *gl_framebuffer, - GLenum target) -{ - CoglGlFramebufferFbo *gl_framebuffer_fbo = - COGL_GL_FRAMEBUFFER_FBO (gl_framebuffer); - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer_fbo); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - GE (ctx, glBindFramebuffer (target, gl_framebuffer_fbo->gl_fbo.fbo_handle)); -} - -static void -cogl_gl_framebuffer_fbo_flush_stereo_mode_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - - switch (cogl_framebuffer_get_stereo_mode (framebuffer)) - { - case COGL_STEREO_BOTH: - break; - case COGL_STEREO_LEFT: - case COGL_STEREO_RIGHT: - g_warn_if_reached (); - break; - } -} - -static GList * -try_creating_renderbuffers (CoglContext *ctx, - int width, - int height, - CoglOffscreenAllocateFlags flags, - int n_samples) -{ - GList *renderbuffers = NULL; - GLuint gl_depth_stencil_handle; - - if (flags & COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL) - { - GLenum format; - - /* WebGL adds a GL_DEPTH_STENCIL_ATTACHMENT and requires that we - * use the GL_DEPTH_STENCIL format. */ - /* Although GL_OES_packed_depth_stencil is mostly equivalent to - * GL_EXT_packed_depth_stencil, one notable difference is that - * GL_OES_packed_depth_stencil doesn't allow GL_DEPTH_STENCIL to - * be passed as an internal format to glRenderbufferStorage. - */ - if (_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL)) - format = GL_DEPTH_STENCIL; - else - { - g_return_val_if_fail ( - _cogl_has_private_feature (ctx, - COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL), - NULL); - format = GL_DEPTH24_STENCIL8; - } - - /* Create a renderbuffer for depth and stenciling */ - GE (ctx, glGenRenderbuffers (1, &gl_depth_stencil_handle)); - GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, gl_depth_stencil_handle)); - if (n_samples) - GE (ctx, glRenderbufferStorageMultisampleIMG (GL_RENDERBUFFER, - n_samples, - format, - width, height)); - else - GE (ctx, glRenderbufferStorage (GL_RENDERBUFFER, format, - width, height)); - GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, 0)); - - - GE (ctx, glFramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, - gl_depth_stencil_handle)); - GE (ctx, glFramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, - gl_depth_stencil_handle)); - renderbuffers = - g_list_prepend (renderbuffers, - GUINT_TO_POINTER (gl_depth_stencil_handle)); - } - - if (flags & COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH) - { - GLuint gl_depth_handle; - - GE (ctx, glGenRenderbuffers (1, &gl_depth_handle)); - GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, gl_depth_handle)); - /* For now we just ask for GL_DEPTH_COMPONENT16 since this is all that's - * available under GLES */ - if (n_samples) - GE (ctx, glRenderbufferStorageMultisampleIMG (GL_RENDERBUFFER, - n_samples, - GL_DEPTH_COMPONENT16, - width, height)); - else - GE (ctx, glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, - width, height)); - GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, 0)); - GE (ctx, glFramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, gl_depth_handle)); - renderbuffers = - g_list_prepend (renderbuffers, GUINT_TO_POINTER (gl_depth_handle)); - } - - if (flags & COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL) - { - GLuint gl_stencil_handle; - - GE (ctx, glGenRenderbuffers (1, &gl_stencil_handle)); - GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, gl_stencil_handle)); - if (n_samples) - GE (ctx, glRenderbufferStorageMultisampleIMG (GL_RENDERBUFFER, - n_samples, - GL_STENCIL_INDEX8, - width, height)); - else - GE (ctx, glRenderbufferStorage (GL_RENDERBUFFER, GL_STENCIL_INDEX8, - width, height)); - GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, 0)); - GE (ctx, glFramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, gl_stencil_handle)); - renderbuffers = - g_list_prepend (renderbuffers, GUINT_TO_POINTER (gl_stencil_handle)); - } - - return renderbuffers; -} - -static void -delete_renderbuffers (CoglContext *ctx, - GList *renderbuffers) -{ - GList *l; - - for (l = renderbuffers; l; l = l->next) - { - GLuint renderbuffer = GPOINTER_TO_UINT (l->data); - GE (ctx, glDeleteRenderbuffers (1, &renderbuffer)); - } - - g_list_free (renderbuffers); -} - -/* - * NB: This function may be called with a standalone GLES2 context - * bound so we can create a shadow framebuffer that wraps the same - * CoglTexture as the given CoglOffscreen. This function shouldn't - * modify anything in - */ -static gboolean -try_creating_fbo (CoglContext *ctx, - CoglTexture *texture, - int texture_level, - int texture_level_width, - int texture_level_height, - const CoglFramebufferConfig *config, - CoglOffscreenAllocateFlags flags, - CoglGlFbo *gl_fbo) -{ - GLuint tex_gl_handle; - GLenum tex_gl_target; - GLenum status; - int n_samples; - - if (!cogl_texture_get_gl_texture (texture, &tex_gl_handle, &tex_gl_target)) - return FALSE; - - if (tex_gl_target != GL_TEXTURE_2D -#ifdef HAVE_GL - && tex_gl_target != GL_TEXTURE_RECTANGLE_ARB -#endif - ) - return FALSE; - - if (config->samples_per_pixel) - { - if (!ctx->glFramebufferTexture2DMultisampleIMG) - return FALSE; - n_samples = config->samples_per_pixel; - } - else - n_samples = 0; - - /* We are about to generate and bind a new fbo, so we pretend to - * change framebuffer state so that the old framebuffer will be - * rebound again before drawing. */ - ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_BIND; - - /* Generate framebuffer */ - ctx->glGenFramebuffers (1, &gl_fbo->fbo_handle); - GE (ctx, glBindFramebuffer (GL_FRAMEBUFFER, gl_fbo->fbo_handle)); - - if (n_samples) - { - GE (ctx, glFramebufferTexture2DMultisampleIMG (GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - tex_gl_target, tex_gl_handle, - n_samples, - texture_level)); - } - else - GE (ctx, glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - tex_gl_target, tex_gl_handle, - texture_level)); - - if (flags) - { - gl_fbo->renderbuffers = - try_creating_renderbuffers (ctx, - texture_level_width, - texture_level_height, - flags, - n_samples); - } - - /* Make sure it's complete */ - status = ctx->glCheckFramebufferStatus (GL_FRAMEBUFFER); - - if (status != GL_FRAMEBUFFER_COMPLETE) - { - GE (ctx, glDeleteFramebuffers (1, &gl_fbo->fbo_handle)); - - delete_renderbuffers (ctx, gl_fbo->renderbuffers); - gl_fbo->renderbuffers = NULL; - - return FALSE; - } - - /* Update the real number of samples_per_pixel now that we have a - * complete framebuffer */ - if (n_samples) - { - GLenum attachment = GL_COLOR_ATTACHMENT0; - GLenum pname = GL_TEXTURE_SAMPLES_IMG; - int texture_samples; - - GE( ctx, glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, - attachment, - pname, - &texture_samples) ); - gl_fbo->samples_per_pixel = texture_samples; - } - - return TRUE; -} - -CoglGlFramebufferFbo * -cogl_gl_framebuffer_fbo_new (CoglFramebuffer *framebuffer, - const CoglFramebufferDriverConfig *driver_config, - GError **error) -{ - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglOffscreen *offscreen; - CoglTexture *texture; - int texture_level; - int level_width; - int level_height; - const CoglFramebufferConfig *config; - CoglGlFbo *gl_fbo; - CoglGlFramebufferFbo *gl_framebuffer_fbo; - CoglOffscreenAllocateFlags allocate_flags; - - if (!COGL_IS_OFFSCREEN (framebuffer)) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Incompatible framebuffer"); - return NULL; - } - - offscreen = COGL_OFFSCREEN (framebuffer); - texture = cogl_offscreen_get_texture (offscreen); - texture_level = cogl_offscreen_get_texture_level (offscreen); - - g_return_val_if_fail (texture_level < _cogl_texture_get_n_levels (texture), - NULL); - - _cogl_texture_get_level_size (texture, - texture_level, - &level_width, - &level_height, - NULL); - - /* XXX: The framebuffer_object spec isn't clear in defining whether attaching - * a texture as a renderbuffer with mipmap filtering enabled while the - * mipmaps have not been uploaded should result in an incomplete framebuffer - * object. (different drivers make different decisions) - * - * To avoid an error with drivers that do consider this a problem we - * explicitly set non mipmapped filters here. These will later be reset when - * the texture is actually used for rendering according to the filters set on - * the corresponding CoglPipeline. - */ - _cogl_texture_gl_flush_legacy_texobj_filters (texture, - GL_NEAREST, GL_NEAREST); - - config = cogl_framebuffer_get_config (framebuffer); - - gl_framebuffer_fbo = g_object_new (COGL_TYPE_GL_FRAMEBUFFER_FBO, - "framebuffer", framebuffer, - NULL); - gl_fbo = &gl_framebuffer_fbo->gl_fbo; - - if ((driver_config->disable_depth_and_stencil && - try_creating_fbo (context, - texture, - texture_level, - level_width, - level_height, - config, - allocate_flags = 0, - gl_fbo)) || - - (context->have_last_offscreen_allocate_flags && - try_creating_fbo (context, - texture, - texture_level, - level_width, - level_height, - config, - allocate_flags = context->last_offscreen_allocate_flags, - gl_fbo)) || - - ( - /* NB: WebGL introduces a DEPTH_STENCIL_ATTACHMENT and doesn't - * need an extension to handle _FLAG_DEPTH_STENCIL */ - (_cogl_has_private_feature - (context, COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL) || - _cogl_has_private_feature - (context, COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL)) && - try_creating_fbo (context, - texture, - texture_level, - level_width, - level_height, - config, - allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL, - gl_fbo)) || - - try_creating_fbo (context, - texture, - texture_level, - level_width, - level_height, - config, - allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH | - COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL, - gl_fbo) || - - try_creating_fbo (context, - texture, - texture_level, - level_width, - level_height, - config, - allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL, - gl_fbo) || - - try_creating_fbo (context, - texture, - texture_level, - level_width, - level_height, - config, - allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH, - gl_fbo) || - - try_creating_fbo (context, - texture, - texture_level, - level_width, - level_height, - config, - allocate_flags = 0, - gl_fbo)) - { - cogl_framebuffer_update_samples_per_pixel (framebuffer, - gl_fbo->samples_per_pixel); - - if (!driver_config->disable_depth_and_stencil) - { - /* Record that the last set of flags succeeded so that we can - try that set first next time */ - context->last_offscreen_allocate_flags = allocate_flags; - context->have_last_offscreen_allocate_flags = TRUE; - } - - return gl_framebuffer_fbo; - } - else - { - g_object_unref (gl_framebuffer_fbo); - g_set_error (error, COGL_FRAMEBUFFER_ERROR, - COGL_FRAMEBUFFER_ERROR_ALLOCATE, - "Failed to create an OpenGL framebuffer object"); - return NULL; - } -} - -static void -cogl_gl_framebuffer_fbo_dispose (GObject *object) -{ - CoglGlFramebufferFbo *gl_framebuffer_fbo = COGL_GL_FRAMEBUFFER_FBO (object); - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer_fbo); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - delete_renderbuffers (ctx, gl_framebuffer_fbo->gl_fbo.renderbuffers); - gl_framebuffer_fbo->gl_fbo.renderbuffers = NULL; - - if (gl_framebuffer_fbo->gl_fbo.fbo_handle) - { - GE (ctx, glDeleteFramebuffers (1, - &gl_framebuffer_fbo->gl_fbo.fbo_handle)); - gl_framebuffer_fbo->gl_fbo.fbo_handle = 0; - } - - G_OBJECT_CLASS (cogl_gl_framebuffer_fbo_parent_class)->dispose (object); -} - -static void -cogl_gl_framebuffer_fbo_init (CoglGlFramebufferFbo *gl_framebuffer_fbo) -{ - gl_framebuffer_fbo->dirty_bitmasks = TRUE; -} - -static void -cogl_gl_framebuffer_fbo_class_init (CoglGlFramebufferFboClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - CoglFramebufferDriverClass *driver_class = - COGL_FRAMEBUFFER_DRIVER_CLASS (klass); - CoglGlFramebufferClass *gl_framebuffer_class = - COGL_GL_FRAMEBUFFER_CLASS (klass); - - object_class->dispose = cogl_gl_framebuffer_fbo_dispose; - - driver_class->query_bits = cogl_gl_framebuffer_fbo_query_bits; - driver_class->discard_buffers = cogl_gl_framebuffer_fbo_discard_buffers; - - gl_framebuffer_class->bind = cogl_gl_framebuffer_fbo_bind; - gl_framebuffer_class->flush_stereo_mode_state = - cogl_gl_framebuffer_fbo_flush_stereo_mode_state; -} diff --git a/mutter/cogl/cogl/driver/gl/cogl-gl-framebuffer-fbo.h b/mutter/cogl/cogl/driver/gl/cogl-gl-framebuffer-fbo.h deleted file mode 100644 index cc15989..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-gl-framebuffer-fbo.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#pragma once - -#include "cogl/driver/gl/cogl-framebuffer-gl-private.h" - -#define COGL_TYPE_GL_FRAMEBUFFER_FBO (cogl_gl_framebuffer_fbo_get_type ()) -G_DECLARE_FINAL_TYPE (CoglGlFramebufferFbo, cogl_gl_framebuffer_fbo, - COGL, GL_FRAMEBUFFER_FBO, - CoglGlFramebuffer) - -CoglGlFramebufferFbo * -cogl_gl_framebuffer_fbo_new (CoglFramebuffer *framebuffer, - const CoglFramebufferDriverConfig *driver_config, - GError **error); diff --git a/mutter/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl-private.h b/mutter/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl-private.h deleted file mode 100644 index cee0268..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl-private.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-pipeline-private.h" - -extern const CoglPipelineFragend _cogl_pipeline_glsl_fragend; - -GLuint -_cogl_pipeline_fragend_glsl_get_shader (CoglPipeline *pipeline); diff --git a/mutter/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c b/mutter/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c deleted file mode 100644 index 0a16f46..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c +++ /dev/null @@ -1,1135 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - * Neil Roberts - */ - -#include "config.h" - -#include - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-pipeline-layer-private.h" -#include "cogl/cogl-blend-string.h" -#include "cogl/cogl-snippet-private.h" -#include "cogl/cogl-list.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" -#include "cogl/driver/gl/cogl-pipeline-opengl-private.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-pipeline-cache.h" -#include "cogl/driver/gl/cogl-pipeline-fragend-glsl-private.h" -#include "deprecated/cogl-shader-private.h" -#include "deprecated/cogl-program-private.h" - -#include - -/* - * GL/GLES compatibility defines for pipeline thingies: - */ - -/* This might not be defined on GLES */ -#ifndef GL_TEXTURE_3D -#define GL_TEXTURE_3D 0x806F -#endif - -const CoglPipelineFragend _cogl_pipeline_glsl_backend; - -typedef struct _UnitState -{ - unsigned int sampled:1; - unsigned int combine_constant_used:1; -} UnitState; - -typedef struct _LayerData -{ - CoglList link; - - /* Layer index for the for the previous layer. This isn't - necessarily the same as this layer's index - 1 because the - indices can have gaps. If this is the first layer then it will be - -1 */ - int previous_layer_index; - - CoglPipelineLayer *layer; -} LayerData; - -typedef struct -{ - int ref_count; - - GLuint gl_shader; - GString *header, *source; - UnitState *unit_state; - - /* List of layers that we haven't generated code for yet. These are - in reverse order. As soon as we're about to generate code for - layer we'll remove it from the list so we don't generate it - again */ - CoglList layers; - - CoglPipelineCacheEntry *cache_entry; -} CoglPipelineFragendShaderState; - -static GQuark shader_state_key = 0; - -static void -ensure_layer_generated (CoglPipeline *pipeline, - int layer_num); - -static CoglPipelineFragendShaderState * -shader_state_new (int n_layers, - CoglPipelineCacheEntry *cache_entry) -{ - CoglPipelineFragendShaderState *shader_state; - - shader_state = g_new0 (CoglPipelineFragendShaderState, 1); - shader_state->ref_count = 1; - shader_state->unit_state = g_new0 (UnitState, n_layers); - shader_state->cache_entry = cache_entry; - - return shader_state; -} -typedef struct -{ - CoglPipelineFragendShaderState *shader_state; - CoglPipeline *instance; -} CoglPipelineFragendShaderStateCache; - -static GQuark -get_cache_key (void) -{ - if (G_UNLIKELY (shader_state_key == 0)) - shader_state_key = g_quark_from_static_string ("shader-state-key"); - - return shader_state_key; -} - -static CoglPipelineFragendShaderState * -get_shader_state (CoglPipeline *pipeline) -{ - CoglPipelineFragendShaderStateCache *cache; - cache = g_object_get_qdata (G_OBJECT (pipeline), get_cache_key ()); - if (cache) - return cache->shader_state; - return NULL; -} - -static void -destroy_shader_state (void *user_data) -{ - CoglPipelineFragendShaderStateCache *cache = user_data; - CoglPipelineFragendShaderState *shader_state = cache->shader_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (shader_state->cache_entry && - shader_state->cache_entry->pipeline != cache->instance) - shader_state->cache_entry->usage_count--; - - if (--shader_state->ref_count == 0) - { - if (shader_state->gl_shader) - GE( ctx, glDeleteShader (shader_state->gl_shader) ); - - g_free (shader_state->unit_state); - - g_free (shader_state); - } - - g_free (cache); -} - -static void -set_shader_state (CoglPipeline *pipeline, CoglPipelineFragendShaderState *shader_state) -{ - if (shader_state) - { - shader_state->ref_count++; - - /* If we're not setting the state on the template pipeline then - * mark it as a usage of the pipeline cache entry */ - if (shader_state->cache_entry && - shader_state->cache_entry->pipeline != pipeline) - shader_state->cache_entry->usage_count++; - } - CoglPipelineFragendShaderStateCache *cache = g_new0 (CoglPipelineFragendShaderStateCache, 1); - cache->instance = pipeline; - cache->shader_state = shader_state; - - g_object_set_qdata_full (G_OBJECT (pipeline), - get_cache_key (), - cache, - destroy_shader_state); -} - -static void -dirty_shader_state (CoglPipeline *pipeline) -{ - g_object_set_qdata_full (G_OBJECT (pipeline), - get_cache_key (), - NULL, - NULL); -} - -GLuint -_cogl_pipeline_fragend_glsl_get_shader (CoglPipeline *pipeline) -{ - CoglPipelineFragendShaderState *shader_state = get_shader_state (pipeline); - - if (shader_state) - return shader_state->gl_shader; - else - return 0; -} - -static CoglPipelineSnippetList * -get_fragment_snippets (CoglPipeline *pipeline) -{ - pipeline = - _cogl_pipeline_get_authority (pipeline, - COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS); - - return &pipeline->big_state->fragment_snippets; -} - -static CoglPipelineSnippetList * -get_layer_fragment_snippets (CoglPipelineLayer *layer) -{ - unsigned long state = COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS; - layer = _cogl_pipeline_layer_get_authority (layer, state); - - return &layer->big_state->fragment_snippets; -} - -static gboolean -has_replace_hook (CoglPipelineLayer *layer, - CoglSnippetHook hook) -{ - GList *l; - - for (l = get_layer_fragment_snippets (layer)->entries; l; l = l->next) - { - CoglSnippet *snippet = l->data; - - if (snippet->hook == hook && snippet->replace) - return TRUE; - } - - return FALSE; -} - -static gboolean -add_layer_declaration_cb (CoglPipelineLayer *layer, - void *user_data) -{ - CoglPipelineFragendShaderState *shader_state = user_data; - - g_string_append_printf (shader_state->header, - "uniform sampler2D cogl_sampler%i;\n", - layer->index); - - return TRUE; -} - -static void -add_layer_declarations (CoglPipeline *pipeline, - CoglPipelineFragendShaderState *shader_state) -{ - /* We always emit sampler uniforms in case there will be custom - * layer snippets that want to sample arbitrary layers. */ - - _cogl_pipeline_foreach_layer_internal (pipeline, - add_layer_declaration_cb, - shader_state); -} - -static void -add_global_declarations (CoglPipeline *pipeline, - CoglPipelineFragendShaderState *shader_state) -{ - CoglSnippetHook hook = COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS; - CoglPipelineSnippetList *snippets = get_fragment_snippets (pipeline); - - /* Add the global data hooks. All of the code in these snippets is - * always added and only the declarations data is used */ - - _cogl_pipeline_snippet_generate_declarations (shader_state->header, - hook, - snippets); -} - -static void -_cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference) -{ - CoglPipelineFragendShaderState *shader_state; - CoglPipeline *authority; - CoglPipelineCacheEntry *cache_entry = NULL; - CoglProgram *user_program = cogl_pipeline_get_user_program (pipeline); - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Now lookup our glsl backend private state */ - shader_state = get_shader_state (pipeline); - - if (shader_state == NULL) - { - /* If we don't have an associated glsl shader yet then find the - * glsl-authority (the oldest ancestor whose state will result in - * the same shader being generated as for this pipeline). - * - * We always make sure to associate new shader with the - * glsl-authority to maximize the chance that other pipelines can - * share it. - */ - authority = _cogl_pipeline_find_equivalent_parent - (pipeline, - _cogl_pipeline_get_state_for_fragment_codegen (ctx) & - ~COGL_PIPELINE_STATE_LAYERS, - _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx)); - - shader_state = get_shader_state (authority); - - /* If we don't have an existing program associated with the - * glsl-authority then start generating code for a new shader... - */ - if (shader_state == NULL) - { - /* Check if there is already a similar cached pipeline whose - shader state we can share */ - if (G_LIKELY (!(COGL_DEBUG_ENABLED - (COGL_DEBUG_DISABLE_PROGRAM_CACHES)))) - { - cache_entry = - _cogl_pipeline_cache_get_fragment_template (ctx->pipeline_cache, - authority); - - shader_state = get_shader_state (cache_entry->pipeline); - } - - if (shader_state) - shader_state->ref_count++; - else - shader_state = shader_state_new (n_layers, cache_entry); - - set_shader_state (authority, shader_state); - - shader_state->ref_count--; - - if (cache_entry) - set_shader_state (cache_entry->pipeline, shader_state); - } - - /* If the pipeline isn't actually its own glsl-authority - * then take a reference to the program state associated - * with the glsl-authority... */ - if (authority != pipeline) - set_shader_state (pipeline, shader_state); - } - - if (user_program) - { - /* If the user program contains a fragment shader then we don't need - to generate one */ - if (_cogl_program_has_fragment_shader (user_program)) - { - if (shader_state->gl_shader) - { - GE( ctx, glDeleteShader (shader_state->gl_shader) ); - shader_state->gl_shader = 0; - } - return; - } - } - - if (shader_state->gl_shader) - return; - - /* If we make it here then we have a glsl_shader_state struct - without a gl_shader either because this is the first time we've - encountered it or because the user program has changed */ - - /* We reuse two grow-only GStrings for code-gen. One string - contains the uniform and attribute declarations while the - other contains the main function. We need two strings - because we need to dynamically declare attributes as the - add_layer callback is invoked */ - g_string_set_size (ctx->codegen_header_buffer, 0); - g_string_set_size (ctx->codegen_source_buffer, 0); - shader_state->header = ctx->codegen_header_buffer; - shader_state->source = ctx->codegen_source_buffer; - _cogl_list_init (&shader_state->layers); - - add_layer_declarations (pipeline, shader_state); - add_global_declarations (pipeline, shader_state); - - g_string_append (shader_state->source, - "void\n" - "cogl_generated_source ()\n" - "{\n"); - - for (i = 0; i < n_layers; i++) - { - shader_state->unit_state[i].sampled = FALSE; - shader_state->unit_state[i].combine_constant_used = FALSE; - } -} - -static void -add_constant_lookup (CoglPipelineFragendShaderState *shader_state, - CoglPipeline *pipeline, - CoglPipelineLayer *layer, - const char *swizzle) -{ - g_string_append_printf (shader_state->header, - "_cogl_layer_constant_%i.%s", - layer->index, swizzle); -} - -static void -ensure_texture_lookup_generated (CoglPipelineFragendShaderState *shader_state, - CoglPipeline *pipeline, - CoglPipelineLayer *layer) -{ - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - CoglPipelineSnippetData snippet_data; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (shader_state->unit_state[unit_index].sampled) - return; - - shader_state->unit_state[unit_index].sampled = TRUE; - - g_string_append_printf (shader_state->header, - "vec4 cogl_texel%i;\n", - layer->index); - - g_string_append_printf (shader_state->source, - " cogl_texel%i = cogl_texture_lookup%i (" - "cogl_sampler%i, ", - layer->index, - layer->index, - layer->index); - - if (cogl_pipeline_get_layer_point_sprite_coords_enabled (pipeline, - layer->index)) - g_string_append_printf (shader_state->source, - "vec4 (cogl_point_coord, 0.0, 1.0)"); - else - g_string_append_printf (shader_state->source, - "cogl_tex_coord%i_in", - layer->index); - - g_string_append (shader_state->source, ");\n"); - - /* There's no need to generate the real texture lookup if it's going - to be replaced */ - if (!has_replace_hook (layer, COGL_SNIPPET_HOOK_TEXTURE_LOOKUP)) - { - g_string_append_printf (shader_state->header, - "vec4\n" - "cogl_real_texture_lookup%i (sampler2D tex,\n" - " vec4 coords)\n" - "{\n" - " return ", - layer->index); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING))) - g_string_append (shader_state->header, - "vec4 (1.0, 1.0, 1.0, 1.0);\n"); - else - g_string_append (shader_state->header, - "texture2D (tex, coords.st);\n"); - - g_string_append (shader_state->header, "}\n"); - } - - /* Wrap the texture lookup in any snippets that have been hooked */ - memset (&snippet_data, 0, sizeof (snippet_data)); - snippet_data.snippets = get_layer_fragment_snippets (layer); - snippet_data.hook = COGL_SNIPPET_HOOK_TEXTURE_LOOKUP; - snippet_data.chain_function = g_strdup_printf ("cogl_real_texture_lookup%i", - layer->index); - snippet_data.final_name = g_strdup_printf ("cogl_texture_lookup%i", - layer->index); - snippet_data.function_prefix = g_strdup_printf ("cogl_texture_lookup_hook%i", - layer->index); - snippet_data.return_type = "vec4"; - snippet_data.return_variable = "cogl_texel"; - snippet_data.arguments = "cogl_sampler, cogl_tex_coord"; - snippet_data.argument_declarations = - g_strdup ("sampler2D cogl_sampler, vec4 cogl_tex_coord"); - snippet_data.source_buf = shader_state->header; - - _cogl_pipeline_snippet_generate_code (&snippet_data); - - g_free ((char *) snippet_data.chain_function); - g_free ((char *) snippet_data.final_name); - g_free ((char *) snippet_data.function_prefix); - g_free ((char *) snippet_data.argument_declarations); -} - -static void -add_arg (CoglPipelineFragendShaderState *shader_state, - CoglPipeline *pipeline, - CoglPipelineLayer *layer, - int previous_layer_index, - CoglPipelineCombineSource src, - CoglPipelineCombineOp operand, - const char *swizzle) -{ - GString *shader_source = shader_state->header; - char alpha_swizzle[5] = "aaaa"; - - g_string_append_c (shader_source, '('); - - if (operand == COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_COLOR || - operand == COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA) - g_string_append_printf (shader_source, - "vec4(1.0, 1.0, 1.0, 1.0).%s - ", - swizzle); - - /* If the operand is reading from the alpha then replace the swizzle - with the same number of copies of the alpha */ - if (operand == COGL_PIPELINE_COMBINE_OP_SRC_ALPHA || - operand == COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA) - { - alpha_swizzle[strlen (swizzle)] = '\0'; - swizzle = alpha_swizzle; - } - - switch (src) - { - case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE: - g_string_append_printf (shader_source, - "cogl_texel%i.%s", - layer->index, - swizzle); - break; - - case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT: - add_constant_lookup (shader_state, - pipeline, - layer, - swizzle); - break; - - case COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS: - if (previous_layer_index >= 0) - { - g_string_append_printf (shader_source, - "cogl_layer%i.%s", - previous_layer_index, - swizzle); - break; - } - G_GNUC_FALLTHROUGH; - case COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR: - g_string_append_printf (shader_source, "cogl_color_in.%s", swizzle); - break; - - default: - { - int layer_num = src - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0; - CoglPipelineGetLayerFlags flags = COGL_PIPELINE_GET_LAYER_NO_CREATE; - CoglPipelineLayer *other_layer = - _cogl_pipeline_get_layer_with_flags (pipeline, layer_num, flags); - - if (other_layer == NULL) - { - static gboolean warning_seen = FALSE; - if (!warning_seen) - { - g_warning ("The application is trying to use a texture " - "combine with a layer number that does not exist"); - warning_seen = TRUE; - } - g_string_append_printf (shader_source, - "vec4 (1.0, 1.0, 1.0, 1.0).%s", - swizzle); - } - else - g_string_append_printf (shader_source, - "cogl_texel%i.%s", - other_layer->index, - swizzle); - } - break; - } - - g_string_append_c (shader_source, ')'); -} - -static void -ensure_arg_generated (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - int previous_layer_index, - CoglPipelineCombineSource src) -{ - CoglPipelineFragendShaderState *shader_state = get_shader_state (pipeline); - - switch (src) - { - case COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR: - /* This doesn't involve any other layers */ - break; - - case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT: - { - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - /* Create a sampler uniform for this layer if we haven't already */ - if (!shader_state->unit_state[unit_index].combine_constant_used) - { - g_string_append_printf (shader_state->header, - "uniform vec4 _cogl_layer_constant_%i;\n", - layer->index); - shader_state->unit_state[unit_index].combine_constant_used = TRUE; - } - } - break; - - case COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS: - if (previous_layer_index >= 0) - ensure_layer_generated (pipeline, previous_layer_index); - break; - - case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE: - ensure_texture_lookup_generated (shader_state, - pipeline, - layer); - break; - - default: - if (src >= COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0) - { - int layer_num = src - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0; - CoglPipelineGetLayerFlags flags = COGL_PIPELINE_GET_LAYER_NO_CREATE; - CoglPipelineLayer *other_layer = - _cogl_pipeline_get_layer_with_flags (pipeline, layer_num, flags); - - if (other_layer) - ensure_texture_lookup_generated (shader_state, - pipeline, - other_layer); - } - break; - } -} - -static void -ensure_args_for_func (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - int previous_layer_index, - CoglPipelineCombineFunc function, - CoglPipelineCombineSource *src) -{ - int n_args = _cogl_get_n_args_for_combine_func (function); - int i; - - for (i = 0; i < n_args; i++) - ensure_arg_generated (pipeline, layer, previous_layer_index, src[i]); -} - -static void -append_masked_combine (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - int previous_layer_index, - const char *swizzle, - CoglPipelineCombineFunc function, - CoglPipelineCombineSource *src, - CoglPipelineCombineOp *op) -{ - CoglPipelineFragendShaderState *shader_state = get_shader_state (pipeline); - GString *shader_source = shader_state->header; - - g_string_append_printf (shader_state->header, - " cogl_layer.%s = ", - swizzle); - - switch (function) - { - case COGL_PIPELINE_COMBINE_FUNC_REPLACE: - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], swizzle); - break; - - case COGL_PIPELINE_COMBINE_FUNC_MODULATE: - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], swizzle); - g_string_append (shader_source, " * "); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[1], op[1], swizzle); - break; - - case COGL_PIPELINE_COMBINE_FUNC_ADD: - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], swizzle); - g_string_append (shader_source, " + "); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[1], op[1], swizzle); - break; - - case COGL_PIPELINE_COMBINE_FUNC_ADD_SIGNED: - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], swizzle); - g_string_append (shader_source, " + "); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[1], op[1], swizzle); - g_string_append_printf (shader_source, - " - vec4(0.5, 0.5, 0.5, 0.5).%s", - swizzle); - break; - - case COGL_PIPELINE_COMBINE_FUNC_SUBTRACT: - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], swizzle); - g_string_append (shader_source, " - "); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[1], op[1], swizzle); - break; - - case COGL_PIPELINE_COMBINE_FUNC_INTERPOLATE: - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], swizzle); - g_string_append (shader_source, " * "); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[2], op[2], swizzle); - g_string_append (shader_source, " + "); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[1], op[1], swizzle); - g_string_append_printf (shader_source, - " * (vec4(1.0, 1.0, 1.0, 1.0).%s - ", - swizzle); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[2], op[2], swizzle); - g_string_append_c (shader_source, ')'); - break; - - case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGB: - case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA: - g_string_append (shader_source, "vec4(4.0 * (("); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], "r"); - g_string_append (shader_source, " - 0.5) * ("); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[1], op[1], "r"); - g_string_append (shader_source, " - 0.5) + ("); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], "g"); - g_string_append (shader_source, " - 0.5) * ("); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[1], op[1], "g"); - g_string_append (shader_source, " - 0.5) + ("); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], "b"); - g_string_append (shader_source, " - 0.5) * ("); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[1], op[1], "b"); - g_string_append_printf (shader_source, " - 0.5))).%s", swizzle); - break; - } - - g_string_append_printf (shader_source, ";\n"); -} - -static void -ensure_layer_generated (CoglPipeline *pipeline, - int layer_index) -{ - CoglPipelineFragendShaderState *shader_state = get_shader_state (pipeline); - CoglPipelineLayer *combine_authority; - CoglPipelineLayerBigState *big_state; - CoglPipelineLayer *layer; - CoglPipelineSnippetData snippet_data; - LayerData *layer_data; - - /* Find the layer that corresponds to this layer_num */ - _cogl_list_for_each (layer_data, &shader_state->layers, link) - { - layer = layer_data->layer; - - if (layer->index == layer_index) - goto found; - } - - /* If we didn't find it then we can assume the layer has already - been generated */ - return; - - found: - - /* Remove the layer from the list so we don't generate it again */ - _cogl_list_remove (&layer_data->link); - - combine_authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_COMBINE); - big_state = combine_authority->big_state; - - /* Make a global variable for the result of the layer code */ - g_string_append_printf (shader_state->header, - "vec4 cogl_layer%i;\n", - layer_index); - - /* Skip the layer generation if there is a snippet that replaces the - default layer code. This is important because generating this - code may cause the code for other layers to be generated and - stored in the global variable. If this code isn't actually used - then the global variables would be uninitialised and they may be - used from other layers */ - if (!has_replace_hook (layer, COGL_SNIPPET_HOOK_LAYER_FRAGMENT)) - { - ensure_args_for_func (pipeline, - layer, - layer_data->previous_layer_index, - big_state->texture_combine_rgb_func, - big_state->texture_combine_rgb_src); - ensure_args_for_func (pipeline, - layer, - layer_data->previous_layer_index, - big_state->texture_combine_alpha_func, - big_state->texture_combine_alpha_src); - - g_string_append_printf (shader_state->header, - "vec4\n" - "cogl_real_generate_layer%i ()\n" - "{\n" - " vec4 cogl_layer;\n", - layer_index); - - if (!_cogl_pipeline_layer_needs_combine_separate (combine_authority) || - /* GL_DOT3_RGBA Is a bit weird as a GL_COMBINE_RGB function - * since if you use it, it overrides your ALPHA function... - */ - big_state->texture_combine_rgb_func == - COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA) - append_masked_combine (pipeline, - layer, - layer_data->previous_layer_index, - "rgba", - big_state->texture_combine_rgb_func, - big_state->texture_combine_rgb_src, - big_state->texture_combine_rgb_op); - else - { - append_masked_combine (pipeline, - layer, - layer_data->previous_layer_index, - "rgb", - big_state->texture_combine_rgb_func, - big_state->texture_combine_rgb_src, - big_state->texture_combine_rgb_op); - append_masked_combine (pipeline, - layer, - layer_data->previous_layer_index, - "a", - big_state->texture_combine_alpha_func, - big_state->texture_combine_alpha_src, - big_state->texture_combine_alpha_op); - } - - g_string_append (shader_state->header, - " return cogl_layer;\n" - "}\n"); - } - - /* Wrap the layer code in any snippets that have been hooked */ - memset (&snippet_data, 0, sizeof (snippet_data)); - snippet_data.snippets = get_layer_fragment_snippets (layer); - snippet_data.hook = COGL_SNIPPET_HOOK_LAYER_FRAGMENT; - snippet_data.chain_function = g_strdup_printf ("cogl_real_generate_layer%i", - layer_index); - snippet_data.final_name = g_strdup_printf ("cogl_generate_layer%i", - layer_index); - snippet_data.function_prefix = g_strdup_printf ("cogl_generate_layer%i", - layer_index); - snippet_data.return_type = "vec4"; - snippet_data.return_variable = "cogl_layer"; - snippet_data.source_buf = shader_state->header; - - _cogl_pipeline_snippet_generate_code (&snippet_data); - - g_free ((char *) snippet_data.chain_function); - g_free ((char *) snippet_data.final_name); - g_free ((char *) snippet_data.function_prefix); - - g_string_append_printf (shader_state->source, - " cogl_layer%i = cogl_generate_layer%i ();\n", - layer_index, - layer_index); - - g_free (layer_data); -} - -static gboolean -_cogl_pipeline_fragend_glsl_add_layer (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference) -{ - CoglPipelineFragendShaderState *shader_state = get_shader_state (pipeline); - LayerData *layer_data; - - if (!shader_state->source) - return TRUE; - - /* Store the layers in reverse order */ - layer_data = g_new0 (LayerData, 1); - layer_data->layer = layer; - - if (_cogl_list_empty (&shader_state->layers)) - { - layer_data->previous_layer_index = -1; - } - else - { - LayerData *first = - _cogl_container_of (shader_state->layers.next, LayerData, link); - layer_data->previous_layer_index = first->layer->index; - } - - _cogl_list_insert (&shader_state->layers, &layer_data->link); - - return TRUE; -} - -static void -add_alpha_test_snippet (CoglPipeline *pipeline, - CoglPipelineFragendShaderState *shader_state) -{ - CoglPipelineAlphaFunc alpha_func; - - alpha_func = cogl_pipeline_get_alpha_test_function (pipeline); - - if (alpha_func == COGL_PIPELINE_ALPHA_FUNC_ALWAYS) - /* Do nothing */ - return; - - if (alpha_func == COGL_PIPELINE_ALPHA_FUNC_NEVER) - { - /* Always discard the fragment */ - g_string_append (shader_state->source, - " discard;\n"); - return; - } - - /* For all of the other alpha functions we need a uniform for the - reference */ - - g_string_append (shader_state->header, - "uniform float _cogl_alpha_test_ref;\n"); - - g_string_append (shader_state->source, - " if (cogl_color_out.a "); - - switch (alpha_func) - { - case COGL_PIPELINE_ALPHA_FUNC_LESS: - g_string_append (shader_state->source, ">="); - break; - case COGL_PIPELINE_ALPHA_FUNC_EQUAL: - g_string_append (shader_state->source, "!="); - break; - case COGL_PIPELINE_ALPHA_FUNC_LEQUAL: - g_string_append (shader_state->source, ">"); - break; - case COGL_PIPELINE_ALPHA_FUNC_GREATER: - g_string_append (shader_state->source, "<="); - break; - case COGL_PIPELINE_ALPHA_FUNC_NOTEQUAL: - g_string_append (shader_state->source, "=="); - break; - case COGL_PIPELINE_ALPHA_FUNC_GEQUAL: - g_string_append (shader_state->source, "< "); - break; - - case COGL_PIPELINE_ALPHA_FUNC_ALWAYS: - case COGL_PIPELINE_ALPHA_FUNC_NEVER: - g_assert_not_reached (); - break; - } - - g_string_append (shader_state->source, - " _cogl_alpha_test_ref)\n discard;\n"); -} - -static gboolean -_cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline, - unsigned long pipelines_difference) -{ - CoglPipelineFragendShaderState *shader_state = get_shader_state (pipeline); - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (shader_state->source) - { - const char *source_strings[2]; - GLint lengths[2]; - GLint compile_status; - GLuint shader; - CoglPipelineSnippetData snippet_data; - - COGL_STATIC_COUNTER (fragend_glsl_compile_counter, - "glsl fragment compile counter", - "Increments each time a new GLSL " - "fragment shader is compiled", - 0 /* no application private data */); - COGL_COUNTER_INC (_cogl_uprof_context, fragend_glsl_compile_counter); - - /* We only need to generate code to calculate the fragment value - for the last layer. If the value of this layer depends on any - previous layers then it will recursively generate the code - for those layers */ - if (!_cogl_list_empty (&shader_state->layers)) - { - CoglPipelineLayer *last_layer; - LayerData *layer_data, *tmp; - - layer_data = _cogl_container_of (shader_state->layers.next, - LayerData, - link); - last_layer = layer_data->layer; - - ensure_layer_generated (pipeline, last_layer->index); - g_string_append_printf (shader_state->source, - " cogl_color_out = cogl_layer%i;\n", - last_layer->index); - - _cogl_list_for_each_safe (layer_data, - tmp, - &shader_state->layers, - link) - g_free (layer_data); - } - else - g_string_append (shader_state->source, - " cogl_color_out = cogl_color_in;\n"); - - add_alpha_test_snippet (pipeline, shader_state); - - /* Close the function surrounding the generated fragment processing */ - g_string_append (shader_state->source, "}\n"); - - /* Add all of the hooks for fragment processing */ - memset (&snippet_data, 0, sizeof (snippet_data)); - snippet_data.snippets = get_fragment_snippets (pipeline); - snippet_data.hook = COGL_SNIPPET_HOOK_FRAGMENT; - snippet_data.chain_function = "cogl_generated_source"; - snippet_data.final_name = "main"; - snippet_data.function_prefix = "cogl_fragment_hook"; - snippet_data.source_buf = shader_state->source; - _cogl_pipeline_snippet_generate_code (&snippet_data); - - GE_RET( shader, ctx, glCreateShader (GL_FRAGMENT_SHADER) ); - - lengths[0] = shader_state->header->len; - source_strings[0] = shader_state->header->str; - lengths[1] = shader_state->source->len; - source_strings[1] = shader_state->source->str; - - _cogl_glsl_shader_set_source_with_boilerplate (ctx, - shader, GL_FRAGMENT_SHADER, - pipeline, - 2, /* count */ - source_strings, lengths); - - GE( ctx, glCompileShader (shader) ); - GE( ctx, glGetShaderiv (shader, GL_COMPILE_STATUS, &compile_status) ); - - if (!compile_status) - { - GLint len = 0; - char *shader_log; - - GE( ctx, glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &len) ); - shader_log = g_alloca (len); - GE( ctx, glGetShaderInfoLog (shader, len, &len, shader_log) ); - g_warning ("Shader compilation failed:\n%s", shader_log); - } - - shader_state->header = NULL; - shader_state->source = NULL; - shader_state->gl_shader = shader; - } - - return TRUE; -} - -static void -_cogl_pipeline_fragend_glsl_pre_change_notify (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if ((change & _cogl_pipeline_get_state_for_fragment_codegen (ctx))) - dirty_shader_state (pipeline); -} - -/* NB: layers are considered immutable once they have any dependants - * so although multiple pipelines can end up depending on a single - * static layer, we can guarantee that if a layer is being *changed* - * then it can only have one pipeline depending on it. - * - * XXX: Don't forget this is *pre* change, we can't read the new value - * yet! - */ -static void -_cogl_pipeline_fragend_glsl_layer_pre_change_notify ( - CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if ((change & _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx))) - { - dirty_shader_state (owner); - return; - } - - /* TODO: we could be saving snippets of texture combine code along - * with each layer and then when a layer changes we would just free - * the snippet. */ -} - -const CoglPipelineFragend _cogl_pipeline_glsl_fragend = -{ - _cogl_pipeline_fragend_glsl_start, - _cogl_pipeline_fragend_glsl_add_layer, - _cogl_pipeline_fragend_glsl_end, - _cogl_pipeline_fragend_glsl_pre_change_notify, - _cogl_pipeline_fragend_glsl_layer_pre_change_notify -}; diff --git a/mutter/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h b/mutter/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h deleted file mode 100644 index 187baf1..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-matrix-stack.h" - -/* - * cogl-pipeline.c owns the GPU's texture unit state so we have some - * private structures for describing the current state of a texture - * unit that we track in a per context array (ctx->texture_units) that - * grows according to the largest texture unit used so far... - * - * Roughly speaking the members in this structure are of two kinds: - * either they are a low level reflection of the state we send to - * OpenGL or they are for high level meta data associated with the - * texture unit when flushing CoglPipelineLayers that is typically - * used to optimize subsequent re-flushing of the same layer. - * - * The low level members are at the top, and the high level members - * start with the .layer member. - */ -typedef struct _CoglTextureUnit -{ - /* The base 0 texture unit index which can be used with - * glActiveTexture () */ - int index; - - /* The GL target currently glEnabled or 0 if nothing is - * enabled. This is only used by the fixed pipeline fragend */ - GLenum enabled_gl_target; - - /* The raw GL texture object name for which we called glBindTexture when - * we flushed the last layer. (NB: The CoglTexture associated - * with a layer may represent more than one GL texture) */ - GLuint gl_texture; - /* The target of the GL texture object. This is just used so that we - * can quickly determine the intended target to flush when - * dirty_gl_texture == TRUE */ - GLenum gl_target; - - /* We have many components in Cogl that need to temporarily bind arbitrary - * textures e.g. to query texture object parameters and since we don't - * want that to result in too much redundant reflushing of layer state - * when all that's needed is to re-bind the layer's gl_texture we use this - * to track when the unit->gl_texture state is out of sync with the GL - * texture object really bound too (GL_TEXTURE0+unit->index). - * - * XXX: as a further optimization cogl-pipeline.c uses a convention - * of always using texture unit 1 for these transient bindings so we - * can assume this is only ever TRUE for unit 1. - */ - gboolean dirty_gl_texture; - - /* A matrix stack giving us the means to associate a texture - * transform matrix with the texture unit. */ - CoglMatrixStack *matrix_stack; - - /* - * Higher level layer state associated with the unit... - */ - - /* The CoglPipelineLayer whose state was flushed to update this - * texture unit last. - * - * This will be set to NULL if the layer is modified or freed which - * means when we come to flush a layer; if this pointer is still - * valid and == to the layer being flushed we don't need to update - * any texture unit state. */ - CoglPipelineLayer *layer; - - /* To help minimize the state changes required we track the - * difference flags associated with the layer whose state was last - * flushed to update this texture unit. - * - * Note: we track this explicitly because .layer may get invalidated - * if that layer is modified or deleted. Even if the layer is - * invalidated though these flags can be used to optimize the state - * flush of the next layer - */ - unsigned long layer_changes_since_flush; - - /* Whenever a CoglTexture's internal GL texture storage changes - * cogl-pipeline.c is notified with a call to - * _cogl_pipeline_texture_storage_change_notify which inturn sets - * this to TRUE for each texture unit that it is currently bound - * too. When we later come to flush some pipeline state then we will - * always check this to potentially force an update of the texture - * state even if the pipeline hasn't changed. */ - gboolean texture_storage_changed; - -} CoglTextureUnit; - -CoglTextureUnit * -_cogl_get_texture_unit (int index_); - -void -_cogl_destroy_texture_units (CoglContext *ctx); - -void -_cogl_set_active_texture_unit (int unit_index); - -void -_cogl_bind_gl_texture_transient (GLenum gl_target, - GLuint gl_texture); - -void -_cogl_delete_gl_texture (GLuint gl_texture); - -void -_cogl_pipeline_flush_gl_state (CoglContext *context, - CoglPipeline *pipeline, - CoglFramebuffer *framebuffer, - gboolean skip_gl_state, - gboolean unknown_color_alpha); - -void -_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx, - GLuint shader_gl_handle, - GLenum shader_gl_type, - CoglPipeline *pipeline, - GLsizei count_in, - const char **strings_in, - const GLint *lengths_in); - -void -_cogl_sampler_gl_init (CoglContext *context, - CoglSamplerCacheEntry *entry); - -void -_cogl_sampler_gl_free (CoglContext *context, - CoglSamplerCacheEntry *entry); - -void -_cogl_gl_set_uniform (CoglContext *ctx, - GLint location, - const CoglBoxedValue *value); diff --git a/mutter/cogl/cogl/driver/gl/cogl-pipeline-opengl.c b/mutter/cogl/cogl/driver/gl/cogl-pipeline-opengl.c deleted file mode 100644 index 3deef74..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-pipeline-opengl.c +++ /dev/null @@ -1,1243 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-debug.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-offscreen.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" -#include "cogl/driver/gl/cogl-pipeline-opengl-private.h" -#include "cogl/driver/gl/cogl-texture-gl-private.h" - -#include "cogl/driver/gl/cogl-pipeline-progend-glsl-private.h" - -#include -#include - -/* - * GL/GLES compatibility defines for pipeline thingies: - */ - -/* These aren't defined in the GLES headers */ -#ifndef GL_POINT_SPRITE -#define GL_POINT_SPRITE 0x8861 -#endif -#ifndef GL_COORD_REPLACE -#define GL_COORD_REPLACE 0x8862 -#endif -#ifndef GL_CLAMP_TO_BORDER -#define GL_CLAMP_TO_BORDER 0x812d -#endif - -static void -texture_unit_init (CoglContext *ctx, - CoglTextureUnit *unit, - int index_) -{ - unit->index = index_; - unit->enabled_gl_target = 0; - unit->gl_texture = 0; - unit->gl_target = 0; - unit->dirty_gl_texture = FALSE; - unit->matrix_stack = cogl_matrix_stack_new (ctx); - - unit->layer = NULL; - unit->layer_changes_since_flush = 0; - unit->texture_storage_changed = FALSE; -} - -static void -texture_unit_free (CoglTextureUnit *unit) -{ - if (unit->layer) - g_object_unref (unit->layer); - g_object_unref (unit->matrix_stack); -} - -CoglTextureUnit * -_cogl_get_texture_unit (int index_) -{ - _COGL_GET_CONTEXT (ctx, NULL); - CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - - if (glctx->texture_units->len < (index_ + 1)) - { - int i; - int prev_len = glctx->texture_units->len; - glctx->texture_units = g_array_set_size (glctx->texture_units, - index_ + 1); - for (i = prev_len; i <= index_; i++) - { - CoglTextureUnit *unit = - &g_array_index (glctx->texture_units, CoglTextureUnit, i); - - texture_unit_init (ctx, unit, i); - } - } - - return &g_array_index (glctx->texture_units, CoglTextureUnit, index_); -} - -void -_cogl_destroy_texture_units (CoglContext *ctx) -{ - int i; - CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - - for (i = 0; i < glctx->texture_units->len; i++) - { - CoglTextureUnit *unit = - &g_array_index (glctx->texture_units, CoglTextureUnit, i); - texture_unit_free (unit); - } - g_array_free (glctx->texture_units, TRUE); -} - -void -_cogl_set_active_texture_unit (int unit_index) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - - if (glctx->active_texture_unit != unit_index) - { - GE (ctx, glActiveTexture (GL_TEXTURE0 + unit_index)); - glctx->active_texture_unit = unit_index; - } -} - -/* Note: _cogl_bind_gl_texture_transient conceptually has slightly - * different semantics to OpenGL's glBindTexture because Cogl never - * cares about tracking multiple textures bound to different targets - * on the same texture unit. - * - * glBindTexture lets you bind multiple textures to a single texture - * unit if they are bound to different targets. So it does something - * like: - * unit->current_texture[target] = texture; - * - * Cogl only lets you associate one texture with the currently active - * texture unit, so the target is basically a redundant parameter - * that's implicitly set on that texture. - * - * Technically this is just a thin wrapper around glBindTexture so - * actually it does have the GL semantics but it seems worth - * mentioning the conceptual difference in case anyone wonders why we - * don't associate the gl_texture with a gl_target in the - * CoglTextureUnit. - */ -void -_cogl_bind_gl_texture_transient (GLenum gl_target, - GLuint gl_texture) -{ - CoglTextureUnit *unit; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* We choose to always make texture unit 1 active for transient - * binds so that in the common case where multitexturing isn't used - * we can simply ignore the state of this texture unit. Notably we - * didn't use a large texture unit (.e.g. (GL_MAX_TEXTURE_UNITS - 1) - * in case the driver doesn't have a sparse data structure for - * texture units. - */ - _cogl_set_active_texture_unit (1); - unit = _cogl_get_texture_unit (1); - - if (unit->gl_texture == gl_texture && !unit->dirty_gl_texture) - return; - - GE (ctx, glBindTexture (gl_target, gl_texture)); - - unit->dirty_gl_texture = TRUE; -} - -void -_cogl_delete_gl_texture (GLuint gl_texture) -{ - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - - for (i = 0; i < glctx->texture_units->len; i++) - { - CoglTextureUnit *unit = - &g_array_index (glctx->texture_units, CoglTextureUnit, i); - - if (unit->gl_texture == gl_texture) - { - unit->gl_texture = 0; - unit->gl_target = 0; - unit->dirty_gl_texture = FALSE; - } - } - - GE (ctx, glDeleteTextures (1, &gl_texture)); -} - -/* Whenever the underlying GL texture storage of a CoglTexture is - * changed (e.g. due to migration out of a texture atlas) then we are - * notified. This lets us ensure that we reflush that texture's state - * if it is reused again with the same texture unit. - */ -void -_cogl_pipeline_texture_storage_change_notify (CoglTexture *texture) -{ - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - - for (i = 0; i < glctx->texture_units->len; i++) - { - CoglTextureUnit *unit = - &g_array_index (glctx->texture_units, CoglTextureUnit, i); - - if (unit->layer && - _cogl_pipeline_layer_get_texture (unit->layer) == texture) - unit->texture_storage_changed = TRUE; - - /* NB: the texture may be bound to multiple texture units so - * we continue to check the rest */ - } -} - -static gboolean -blend_factor_uses_constant (GLenum blend_factor) -{ - return (blend_factor == GL_CONSTANT_COLOR || - blend_factor == GL_ONE_MINUS_CONSTANT_COLOR || - blend_factor == GL_CONSTANT_ALPHA || - blend_factor == GL_ONE_MINUS_CONSTANT_ALPHA); -} - -static void -flush_depth_state (CoglContext *ctx, - CoglDepthState *depth_state) -{ - gboolean depth_writing_enabled = depth_state->write_enabled; - - if (ctx->current_draw_buffer) - { - depth_writing_enabled &= - cogl_framebuffer_get_depth_write_enabled (ctx->current_draw_buffer); - } - - if (ctx->depth_test_enabled_cache != depth_state->test_enabled) - { - if (depth_state->test_enabled == TRUE) - { - GE (ctx, glEnable (GL_DEPTH_TEST)); - if (ctx->current_draw_buffer) - cogl_framebuffer_set_depth_buffer_clear_needed (ctx->current_draw_buffer); - } - else - GE (ctx, glDisable (GL_DEPTH_TEST)); - ctx->depth_test_enabled_cache = depth_state->test_enabled; - } - - if (ctx->depth_test_function_cache != depth_state->test_function && - depth_state->test_enabled == TRUE) - { - GE (ctx, glDepthFunc (depth_state->test_function)); - ctx->depth_test_function_cache = depth_state->test_function; - } - - if (ctx->depth_writing_enabled_cache != depth_writing_enabled) - { - GE (ctx, glDepthMask (depth_writing_enabled ? - GL_TRUE : GL_FALSE)); - ctx->depth_writing_enabled_cache = depth_writing_enabled; - } - - if ((ctx->depth_range_near_cache != depth_state->range_near || - ctx->depth_range_far_cache != depth_state->range_far)) - { - if (ctx->driver == COGL_DRIVER_GLES2) - GE (ctx, glDepthRangef (depth_state->range_near, - depth_state->range_far)); - else - GE (ctx, glDepthRange (depth_state->range_near, - depth_state->range_far)); - - ctx->depth_range_near_cache = depth_state->range_near; - ctx->depth_range_far_cache = depth_state->range_far; - } -} - -static void -_cogl_pipeline_flush_color_blend_alpha_depth_state ( - CoglPipeline *pipeline, - unsigned long pipelines_difference, - gboolean with_color_attrib) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (pipelines_difference & COGL_PIPELINE_STATE_BLEND) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND); - CoglPipelineBlendState *blend_state = - &authority->big_state->blend_state; - - if (blend_factor_uses_constant (blend_state->blend_src_factor_rgb) || - blend_factor_uses_constant (blend_state - ->blend_src_factor_alpha) || - blend_factor_uses_constant (blend_state->blend_dst_factor_rgb) || - blend_factor_uses_constant (blend_state->blend_dst_factor_alpha)) - { - float red = cogl_color_get_red (&blend_state->blend_constant); - float green = cogl_color_get_green (&blend_state->blend_constant); - float blue = cogl_color_get_blue (&blend_state->blend_constant); - float alpha = cogl_color_get_alpha (&blend_state->blend_constant); - - - GE (ctx, glBlendColor (red, green, blue, alpha)); - } - - GE (ctx, glBlendEquationSeparate (blend_state->blend_equation_rgb, - blend_state->blend_equation_alpha)); - - GE (ctx, glBlendFuncSeparate (blend_state->blend_src_factor_rgb, - blend_state->blend_dst_factor_rgb, - blend_state->blend_src_factor_alpha, - blend_state->blend_dst_factor_alpha)); - } - - if (pipelines_difference & COGL_PIPELINE_STATE_DEPTH) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH); - CoglDepthState *depth_state = &authority->big_state->depth_state; - - flush_depth_state (ctx, depth_state); - } - - if (pipelines_difference & COGL_PIPELINE_STATE_CULL_FACE) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_CULL_FACE); - CoglPipelineCullFaceState *cull_face_state - = &authority->big_state->cull_face_state; - - if (cull_face_state->mode == COGL_PIPELINE_CULL_FACE_MODE_NONE) - GE( ctx, glDisable (GL_CULL_FACE) ); - else - { - gboolean invert_winding; - - GE( ctx, glEnable (GL_CULL_FACE) ); - - switch (cull_face_state->mode) - { - case COGL_PIPELINE_CULL_FACE_MODE_NONE: - g_assert_not_reached (); - - case COGL_PIPELINE_CULL_FACE_MODE_FRONT: - GE( ctx, glCullFace (GL_FRONT) ); - break; - - case COGL_PIPELINE_CULL_FACE_MODE_BACK: - GE( ctx, glCullFace (GL_BACK) ); - break; - - case COGL_PIPELINE_CULL_FACE_MODE_BOTH: - GE( ctx, glCullFace (GL_FRONT_AND_BACK) ); - break; - } - - invert_winding = - cogl_framebuffer_is_y_flipped (ctx->current_draw_buffer); - - switch (cull_face_state->front_winding) - { - case COGL_WINDING_CLOCKWISE: - GE( ctx, glFrontFace (invert_winding ? GL_CCW : GL_CW) ); - break; - - case COGL_WINDING_COUNTER_CLOCKWISE: - GE( ctx, glFrontFace (invert_winding ? GL_CW : GL_CCW) ); - break; - } - } - } - - if (pipeline->real_blend_enable != ctx->gl_blend_enable_cache) - { - if (pipeline->real_blend_enable) - GE (ctx, glEnable (GL_BLEND)); - else - GE (ctx, glDisable (GL_BLEND)); - /* XXX: we shouldn't update any other blend state if blending - * is disabled! */ - ctx->gl_blend_enable_cache = pipeline->real_blend_enable; - } -} - -static int -get_max_activateable_texture_units (void) -{ - _COGL_GET_CONTEXT (ctx, 0); - - if (G_UNLIKELY (ctx->max_activateable_texture_units == -1)) - { - GLint values[3]; - int n_values = 0; - int i; - -#ifdef HAVE_GL - if (ctx->driver != COGL_DRIVER_GLES2) - { - /* GL_MAX_TEXTURE_COORDS defines the number of texture coordinates - * that can be uploaded (but doesn't necessarily relate to how many - * texture images can be sampled) */ - GE (ctx, glGetIntegerv (GL_MAX_TEXTURE_COORDS, values + n_values++)); - - GE (ctx, glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, - values + n_values++)); - } -#endif /* HAVE_GL */ - -#ifdef HAVE_GLES2 - if (ctx->driver == COGL_DRIVER_GLES2) - { - GE (ctx, glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, values + n_values)); - /* Two of the vertex attribs need to be used for the position - and color */ - values[n_values++] -= 2; - - GE (ctx, glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, - values + n_values++)); - } -#endif - - g_assert (n_values <= G_N_ELEMENTS (values) && - n_values > 0); - - /* Use the maximum value */ - ctx->max_activateable_texture_units = values[0]; - for (i = 1; i < n_values; i++) - ctx->max_activateable_texture_units = - MAX (values[i], ctx->max_activateable_texture_units); - } - - return ctx->max_activateable_texture_units; -} - -typedef struct -{ - int i; - unsigned long *layer_differences; -} CoglPipelineFlushLayerState; - -static gboolean -flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglPipelineFlushLayerState *flush_state = user_data; - int unit_index = flush_state->i; - CoglTextureUnit *unit = _cogl_get_texture_unit (unit_index); - unsigned long layers_difference = - flush_state->layer_differences[unit_index]; - - _COGL_GET_CONTEXT (ctx, FALSE); - - /* There may not be enough texture units so we can bail out if - * that's the case... - */ - if (G_UNLIKELY (unit_index >= get_max_activateable_texture_units ())) - { - static gboolean shown_warning = FALSE; - - if (!shown_warning) - { - g_warning ("Your hardware does not have enough texture units" - "to handle this many texture layers"); - shown_warning = TRUE; - } - return FALSE; - } - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA) - { - CoglTexture *texture = _cogl_pipeline_layer_get_texture_real (layer); - GLuint gl_texture; - GLenum gl_target; - - if (texture == NULL) - texture = ctx->default_gl_texture_2d_tex; - - cogl_texture_get_gl_texture (texture, - &gl_texture, - &gl_target); - - _cogl_set_active_texture_unit (unit_index); - - /* NB: There are several Cogl components and some code in - * Clutter that will temporarily bind arbitrary GL textures to - * query and modify texture object parameters. If you look at - * _cogl_bind_gl_texture_transient() you can see we make sure - * that such code always binds to texture unit 1 which means we - * can't rely on the unit->gl_texture state if unit->index == 1. - * - * Because texture unit 1 is a bit special we actually defer any - * necessary glBindTexture for it until the end of - * _cogl_pipeline_flush_gl_state(). - * - * NB: we get notified whenever glDeleteTextures is used (see - * _cogl_delete_gl_texture()) where we invalidate - * unit->gl_texture references to deleted textures so it's safe - * to compare unit->gl_texture with gl_texture. (Without the - * hook it would be possible to delete a GL texture and create a - * new one with the same name and comparing unit->gl_texture and - * gl_texture wouldn't detect that.) - * - * NB: for foreign textures we don't know how the deletion of - * the GL texture objects correspond to the deletion of the - * CoglTextures so if there was previously a foreign texture - * associated with the texture unit then we can't assume that we - * aren't seeing a recycled texture name so we have to bind. - */ - if (unit->gl_texture != gl_texture) - { - if (unit_index == 1) - unit->dirty_gl_texture = TRUE; - else - GE (ctx, glBindTexture (gl_target, gl_texture)); - unit->gl_texture = gl_texture; - unit->gl_target = gl_target; - } - - /* The texture_storage_changed boolean indicates if the - * CoglTexture's underlying GL texture storage has changed since - * it was flushed to the texture unit. We've just flushed the - * latest state so we can reset this. */ - unit->texture_storage_changed = FALSE; - } - - if ((layers_difference & COGL_PIPELINE_LAYER_STATE_SAMPLER) && - _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS)) - { - const CoglSamplerCacheEntry *sampler_state; - - sampler_state = _cogl_pipeline_layer_get_sampler_state (layer); - - GE( ctx, glBindSampler (unit_index, sampler_state->sampler_object) ); - } - - g_object_ref (layer); - if (unit->layer != NULL) - g_object_unref (unit->layer); - - unit->layer = layer; - unit->layer_changes_since_flush = 0; - - flush_state->i++; - - return TRUE; -} - -static void -_cogl_pipeline_flush_common_gl_state (CoglPipeline *pipeline, - unsigned long pipelines_difference, - unsigned long *layer_differences, - gboolean with_color_attrib) -{ - CoglPipelineFlushLayerState state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _cogl_pipeline_flush_color_blend_alpha_depth_state (pipeline, - pipelines_difference, - with_color_attrib); - - state.i = 0; - state.layer_differences = layer_differences; - _cogl_pipeline_foreach_layer_internal (pipeline, - flush_layers_common_gl_state_cb, - &state); -} - -/* Re-assert the layer's wrap modes on the given CoglTexture. - * - * Note: we don't simply forward the wrap modes to layer->texture - * since the actual texture being used may have been overridden. - */ -static void -_cogl_pipeline_layer_forward_wrap_modes (CoglPipelineLayer *layer, - CoglTexture *texture) -{ - CoglSamplerCacheWrapMode wrap_mode_s, wrap_mode_t; - GLenum gl_wrap_mode_s, gl_wrap_mode_t; - - if (texture == NULL) - return; - - _cogl_pipeline_layer_get_wrap_modes (layer, - &wrap_mode_s, - &wrap_mode_t); - - /* Update the wrap mode on the texture object. The texture backend - should cache the value so that it will be a no-op if the object - already has the same wrap mode set. The backend is best placed to - do this because it knows how many of the coordinates will - actually be used (ie, a 1D texture only cares about the 's' - coordinate but a 3D texture would use all three). GL uses the - wrap mode as part of the texture object state but we are - pretending it's part of the per-layer environment state. This - will break if the application tries to use different modes in - different layers using the same texture. */ - - if (wrap_mode_s == COGL_SAMPLER_CACHE_WRAP_MODE_AUTOMATIC) - gl_wrap_mode_s = GL_CLAMP_TO_EDGE; - else - gl_wrap_mode_s = wrap_mode_s; - - if (wrap_mode_t == COGL_SAMPLER_CACHE_WRAP_MODE_AUTOMATIC) - gl_wrap_mode_t = GL_CLAMP_TO_EDGE; - else - gl_wrap_mode_t = wrap_mode_t; - - _cogl_texture_gl_flush_legacy_texobj_wrap_modes (texture, - gl_wrap_mode_s, - gl_wrap_mode_t); -} - -void -_cogl_sampler_gl_init (CoglContext *context, CoglSamplerCacheEntry *entry) -{ - if (_cogl_has_private_feature (context, - COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS)) - { - GE( context, glGenSamplers (1, &entry->sampler_object) ); - - GE( context, glSamplerParameteri (entry->sampler_object, - GL_TEXTURE_MIN_FILTER, - entry->min_filter) ); - GE( context, glSamplerParameteri (entry->sampler_object, - GL_TEXTURE_MAG_FILTER, - entry->mag_filter) ); - - GE (context, glSamplerParameteri (entry->sampler_object, - GL_TEXTURE_WRAP_S, - entry->wrap_mode_s) ); - GE (context, glSamplerParameteri (entry->sampler_object, - GL_TEXTURE_WRAP_T, - entry->wrap_mode_t) ); - - /* While COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS implies support for - * GL_TEXTURE_LOD_BIAS in GL, the same is not true in GLES. So check, - * and also only apply GL_TEXTURE_LOD_BIAS in mipmap modes: - */ - if (_cogl_has_private_feature (context, - COGL_PRIVATE_FEATURE_TEXTURE_LOD_BIAS) && - entry->min_filter != GL_NEAREST && - entry->min_filter != GL_LINEAR) - { - GLfloat bias = _cogl_texture_min_filter_get_lod_bias (entry->min_filter); - - GE (context, glSamplerParameterf (entry->sampler_object, - GL_TEXTURE_LOD_BIAS, - bias)); - } - } - else - { - CoglGLContext *gl_context = context->driver_context; - - /* If sampler objects aren't supported then we'll invent a - unique number so that pipelines can still compare the - unique state just by comparing the sampler object - numbers */ - entry->sampler_object = gl_context->next_fake_sampler_object_number++; - } -} - -void -_cogl_sampler_gl_free (CoglContext *context, CoglSamplerCacheEntry *entry) -{ - if (_cogl_has_private_feature (context, - COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS)) - GE( context, glDeleteSamplers (1, &entry->sampler_object) ); -} - -/* OpenGL associates the min/mag filters and repeat modes with the - * texture object not the texture unit so we always have to re-assert - * the filter and repeat modes whenever we use a texture since it may - * be referenced by multiple pipelines with different modes. - * - * This function is bypassed in favour of sampler objects if - * GL_ARB_sampler_objects is advertised. This fallback won't work if - * the same texture is bound to multiple layers with different sampler - * state. - */ -static void -foreach_texture_unit_update_filter_and_wrap_modes (void) -{ - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - - for (i = 0; i < glctx->texture_units->len; i++) - { - CoglTextureUnit *unit = - &g_array_index (glctx->texture_units, CoglTextureUnit, i); - - if (unit->layer) - { - CoglTexture *texture = _cogl_pipeline_layer_get_texture (unit->layer); - - if (texture != NULL) - { - CoglPipelineFilter min; - CoglPipelineFilter mag; - - _cogl_pipeline_layer_get_filters (unit->layer, &min, &mag); - _cogl_texture_gl_flush_legacy_texobj_filters (texture, min, mag); - - _cogl_pipeline_layer_forward_wrap_modes (unit->layer, texture); - } - } - } -} - -typedef struct -{ - int i; - unsigned long *layer_differences; -} CoglPipelineCompareLayersState; - -static gboolean -compare_layer_differences_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglPipelineCompareLayersState *state = user_data; - CoglTextureUnit *unit = _cogl_get_texture_unit (state->i); - - if (unit->layer == layer) - state->layer_differences[state->i] = unit->layer_changes_since_flush; - else if (unit->layer) - { - state->layer_differences[state->i] = unit->layer_changes_since_flush; - state->layer_differences[state->i] |= - _cogl_pipeline_layer_compare_differences (layer, unit->layer); - } - else - state->layer_differences[state->i] = COGL_PIPELINE_LAYER_STATE_ALL_SPARSE; - - /* XXX: There is always a possibility that a CoglTexture's - * underlying GL texture storage has been changed since it was last - * bound to a texture unit which is why we have a callback into - * _cogl_pipeline_texture_storage_change_notify whenever a textures - * underlying GL texture storage changes which will set the - * unit->texture_intern_changed flag. If we see that's been set here - * then we force an update of the texture state... - */ - if (unit->texture_storage_changed) - state->layer_differences[state->i] |= - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA; - - state->i++; - - return TRUE; -} - -typedef struct -{ - CoglFramebuffer *framebuffer; - const CoglPipelineVertend *vertend; - const CoglPipelineFragend *fragend; - CoglPipeline *pipeline; - unsigned long *layer_differences; - gboolean error_adding_layer; - gboolean added_layer; -} CoglPipelineAddLayerState; - -static gboolean -vertend_add_layer_cb (CoglPipelineLayer *layer, - void *user_data) -{ - CoglPipelineAddLayerState *state = user_data; - const CoglPipelineVertend *vertend = state->vertend; - CoglPipeline *pipeline = state->pipeline; - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - - /* Either generate per layer code snippets or setup the - * fixed function glTexEnv for each layer... */ - if (G_LIKELY (vertend->add_layer (pipeline, - layer, - state->layer_differences[unit_index], - state->framebuffer))) - state->added_layer = TRUE; - else - { - state->error_adding_layer = TRUE; - return FALSE; - } - - return TRUE; -} - -static gboolean -fragend_add_layer_cb (CoglPipelineLayer *layer, - void *user_data) -{ - CoglPipelineAddLayerState *state = user_data; - const CoglPipelineFragend *fragend = state->fragend; - CoglPipeline *pipeline = state->pipeline; - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - - /* Either generate per layer code snippets or setup the - * fixed function glTexEnv for each layer... */ - if (G_LIKELY (fragend->add_layer (pipeline, - layer, - state->layer_differences[unit_index]))) - state->added_layer = TRUE; - else - { - state->error_adding_layer = TRUE; - return FALSE; - } - - return TRUE; -} - -/* - * _cogl_pipeline_flush_gl_state: - * - * Details of override options: - * ->fallback_mask: is a bitmask of the pipeline layers that need to be - * replaced with the default, fallback textures. The fallback textures are - * fully transparent textures so they hopefully won't contribute to the - * texture combining. - * - * The intention of fallbacks is to try and preserve - * the number of layers the user is expecting so that texture coordinates - * they gave will mostly still correspond to the textures they intended, and - * have a fighting chance of looking close to their originally intended - * result. - * - * ->disable_mask: is a bitmask of the pipeline layers that will simply have - * texturing disabled. It's only really intended for disabling all layers - * > X; i.e. we'd expect to see a contiguous run of 0 starting from the LSB - * and at some point the remaining bits flip to 1. It might work to disable - * arbitrary layers; though I'm not sure a.t.m how OpenGL would take to - * that. - * - * The intention of the disable_mask is for emitting geometry when the user - * hasn't supplied enough texture coordinates for all the layers and it's - * not possible to auto generate default texture coordinates for those - * layers. - * - * ->layer0_override_texture: forcibly tells us to bind this GL texture name for - * layer 0 instead of plucking the gl_texture from the CoglTexture of layer - * 0. - * - * The intention of this is for any primitives that supports sliced textures. - * The code will can iterate each of the slices and re-flush the pipeline - * forcing the GL texture of each slice in turn. - * - * ->wrap_mode_overrides: overrides the wrap modes set on each - * layer. This is used to implement the automatic wrap mode. - * - * XXX: It might also help if we could specify a texture matrix for code - * dealing with slicing that would be multiplied with the users own matrix. - * - * Normally texture coords in the range [0, 1] refer to the extents of the - * texture, but when your GL texture represents a slice of the real texture - * (from the users POV) then a texture matrix would be a neat way of - * transforming the mapping for each slice. - * - * Currently for textured rectangles we manually calculate the texture - * coords for each slice based on the users given coords, but this solution - * isn't ideal. - */ -void -_cogl_pipeline_flush_gl_state (CoglContext *ctx, - CoglPipeline *pipeline, - CoglFramebuffer *framebuffer, - gboolean with_color_attrib, - gboolean unknown_color_alpha) -{ - CoglPipeline *current_pipeline = ctx->current_pipeline; - unsigned long pipelines_difference; - int n_layers; - unsigned long *layer_differences; - CoglTextureUnit *unit1; - const CoglPipelineProgend *progend; - - COGL_STATIC_TIMER (pipeline_flush_timer, - "Mainloop", /* parent */ - "Material Flush", - "The time spent flushing material state", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, pipeline_flush_timer); - - /* Bail out asap if we've been asked to re-flush the already current - * pipeline and we can see the pipeline hasn't changed */ - if (current_pipeline == pipeline && - ctx->current_pipeline_age == pipeline->age && - ctx->current_pipeline_with_color_attrib == with_color_attrib && - ctx->current_pipeline_unknown_color_alpha == unknown_color_alpha) - goto done; - else - { - /* Update derived state (currently just the 'real_blend_enable' - * state) and determine a mask of state that differs between the - * current pipeline and the one we are flushing. - * - * Note updating the derived state is done before doing any - * pipeline comparisons so that we can correctly compare the - * 'real_blend_enable' state itself. - */ - - if (current_pipeline == pipeline) - { - pipelines_difference = ctx->current_pipeline_changes_since_flush; - - if (pipelines_difference & COGL_PIPELINE_STATE_AFFECTS_BLENDING || - pipeline->unknown_color_alpha != unknown_color_alpha) - { - gboolean save_real_blend_enable = pipeline->real_blend_enable; - - _cogl_pipeline_update_real_blend_enable (pipeline, - unknown_color_alpha); - - if (save_real_blend_enable != pipeline->real_blend_enable) - pipelines_difference |= COGL_PIPELINE_STATE_REAL_BLEND_ENABLE; - } - } - else if (current_pipeline) - { - pipelines_difference = ctx->current_pipeline_changes_since_flush; - - _cogl_pipeline_update_real_blend_enable (pipeline, - unknown_color_alpha); - - pipelines_difference |= - _cogl_pipeline_compare_differences (ctx->current_pipeline, - pipeline); - } - else - { - _cogl_pipeline_update_real_blend_enable (pipeline, - unknown_color_alpha); - - pipelines_difference = COGL_PIPELINE_STATE_ALL; - } - } - - /* Get a layer_differences mask for each layer to be flushed */ - n_layers = cogl_pipeline_get_n_layers (pipeline); - if (n_layers) - { - CoglPipelineCompareLayersState state; - layer_differences = g_alloca (sizeof (unsigned long) * n_layers); - memset (layer_differences, 0, sizeof (unsigned long) * n_layers); - state.i = 0; - state.layer_differences = layer_differences; - _cogl_pipeline_foreach_layer_internal (pipeline, - compare_layer_differences_cb, - &state); - } - else - layer_differences = NULL; - - /* First flush everything that's the same regardless of which - * pipeline backend is being used... - * - * 1) top level state: - * glColor (or skip if a vertex attribute is being used for color) - * blend state - * alpha test state (except for GLES 2.0) - * - * 2) then foreach layer: - * determine gl_target/gl_texture - * bind texture - * - * Note: After _cogl_pipeline_flush_common_gl_state you can expect - * all state of the layers corresponding texture unit to be - * updated. - */ - _cogl_pipeline_flush_common_gl_state (pipeline, - pipelines_difference, - layer_differences, - with_color_attrib); - - /* Now flush the fragment, vertex and program state according to the - * current progend backend. - * - * Note: Some backends may not support the current pipeline - * configuration and in that case it will report and error and we - * will look for a different backend. - * - * NB: if pipeline->progend != COGL_PIPELINE_PROGEND_UNDEFINED then - * we have previously managed to successfully flush this pipeline - * with the given progend so we will simply use that to avoid - * fallback code paths. - */ - - do - { - const CoglPipelineVertend *vertend; - const CoglPipelineFragend *fragend; - CoglPipelineAddLayerState state; - - progend = _cogl_pipeline_progend; - - if (G_UNLIKELY (!progend->start (pipeline))) - continue; - - vertend = _cogl_pipeline_vertend; - - vertend->start (pipeline, - n_layers, - pipelines_difference); - - state.framebuffer = framebuffer; - state.vertend = vertend; - state.pipeline = pipeline; - state.layer_differences = layer_differences; - state.error_adding_layer = FALSE; - state.added_layer = FALSE; - - _cogl_pipeline_foreach_layer_internal (pipeline, - vertend_add_layer_cb, - &state); - - if (G_UNLIKELY (state.error_adding_layer)) - continue; - - if (G_UNLIKELY (!vertend->end (pipeline, pipelines_difference))) - continue; - - /* Now prepare the fragment processing state (fragend) - * - * NB: We can't combine the setup of the vertend and fragend - * since the backends that do code generation share - * ctx->codegen_source_buffer as a scratch buffer. - */ - - fragend = _cogl_pipeline_fragend; - state.fragend = fragend; - - fragend->start (pipeline, - n_layers, - pipelines_difference); - - _cogl_pipeline_foreach_layer_internal (pipeline, - fragend_add_layer_cb, - &state); - - if (G_UNLIKELY (state.error_adding_layer)) - continue; - - if (G_UNLIKELY (!fragend->end (pipeline, pipelines_difference))) - continue; - - if (progend->end) - progend->end (pipeline, pipelines_difference); - break; - } - while (0); - - /* FIXME: This reference is actually resulting in lots of - * copy-on-write reparenting because one-shot pipelines end up - * living for longer than necessary and so any later modification of - * the parent will cause a copy-on-write. - * - * XXX: The issue should largely go away when we switch to using - * weak pipelines for overrides. - */ - g_object_ref (pipeline); - if (ctx->current_pipeline != NULL) - g_object_unref (ctx->current_pipeline); - ctx->current_pipeline = pipeline; - ctx->current_pipeline_changes_since_flush = 0; - ctx->current_pipeline_with_color_attrib = with_color_attrib; - ctx->current_pipeline_unknown_color_alpha = unknown_color_alpha; - ctx->current_pipeline_age = pipeline->age; - -done: - - progend = _cogl_pipeline_progend; - - /* We can't assume the color will be retained between flushes when - * using the glsl progend because the generic attribute values are - * not stored as part of the program object so they could be - * overridden by any attribute changes in another program */ - if (!with_color_attrib) - { - int attribute; - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR); - int name_index = COGL_ATTRIBUTE_COLOR_NAME_INDEX; - - attribute = - _cogl_pipeline_progend_glsl_get_attrib_location (pipeline, name_index); - if (attribute != -1) - GE (ctx, - glVertexAttrib4f (attribute, - cogl_color_get_red (&authority->color), - cogl_color_get_green (&authority->color), - cogl_color_get_blue (&authority->color), - cogl_color_get_alpha (&authority->color))); - } - - /* Give the progend a chance to update any uniforms that might not - * depend on the material state. This is used on GLES2 to update the - * matrices */ - if (progend->pre_paint) - progend->pre_paint (pipeline, framebuffer); - - /* Handle the fact that OpenGL associates texture filter and wrap - * modes with the texture objects not the texture units... */ - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS)) - foreach_texture_unit_update_filter_and_wrap_modes (); - - /* If this pipeline has more than one layer then we always need - * to make sure we rebind the texture for unit 1. - * - * NB: various components of Cogl may temporarily bind arbitrary - * textures to texture unit 1 so they can query and modify texture - * object parameters. cogl-pipeline.c (See - * _cogl_bind_gl_texture_transient) - */ - unit1 = _cogl_get_texture_unit (1); - if (cogl_pipeline_get_n_layers (pipeline) > 1 && unit1->dirty_gl_texture) - { - _cogl_set_active_texture_unit (1); - GE (ctx, glBindTexture (unit1->gl_target, unit1->gl_texture)); - unit1->dirty_gl_texture = FALSE; - } - - COGL_TIMER_STOP (_cogl_uprof_context, pipeline_flush_timer); -} - -void -_cogl_gl_set_uniform (CoglContext *ctx, - GLint location, - const CoglBoxedValue *value) -{ - switch (value->type) - { - case COGL_BOXED_NONE: - break; - - case COGL_BOXED_INT: - { - const int *ptr; - - if (value->count == 1) - ptr = value->v.int_value; - else - ptr = value->v.int_array; - - switch (value->size) - { - case 1: - GE( ctx, glUniform1iv (location, value->count, ptr) ); - break; - case 2: - GE( ctx, glUniform2iv (location, value->count, ptr) ); - break; - case 3: - GE( ctx, glUniform3iv (location, value->count, ptr) ); - break; - case 4: - GE( ctx, glUniform4iv (location, value->count, ptr) ); - break; - } - } - break; - - case COGL_BOXED_FLOAT: - { - const float *ptr; - - if (value->count == 1) - ptr = value->v.float_value; - else - ptr = value->v.float_array; - - switch (value->size) - { - case 1: - GE( ctx, glUniform1fv (location, value->count, ptr) ); - break; - case 2: - GE( ctx, glUniform2fv (location, value->count, ptr) ); - break; - case 3: - GE( ctx, glUniform3fv (location, value->count, ptr) ); - break; - case 4: - GE( ctx, glUniform4fv (location, value->count, ptr) ); - break; - } - } - break; - - case COGL_BOXED_MATRIX: - { - const float *ptr; - - if (value->count == 1) - ptr = value->v.matrix; - else - ptr = value->v.float_array; - - switch (value->size) - { - case 2: - GE( ctx, glUniformMatrix2fv (location, value->count, - FALSE, ptr) ); - break; - case 3: - GE( ctx, glUniformMatrix3fv (location, value->count, - FALSE, ptr) ); - break; - case 4: - GE( ctx, glUniformMatrix4fv (location, value->count, - FALSE, ptr) ); - break; - } - } - break; - } -} diff --git a/mutter/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl-private.h b/mutter/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl-private.h deleted file mode 100644 index e5e1138..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl-private.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#pragma once - -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-attribute-private.h" - -extern const CoglPipelineProgend _cogl_pipeline_glsl_progend; - -int -_cogl_pipeline_progend_glsl_get_attrib_location (CoglPipeline *pipeline, - int name_index); diff --git a/mutter/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c b/mutter/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c deleted file mode 100644 index 59159d1..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c +++ /dev/null @@ -1,1169 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#include "config.h" - -#include - -#include "cogl/cogl-util.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/cogl-offscreen.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" -#include "cogl/driver/gl/cogl-pipeline-opengl-private.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-pipeline-cache.h" -#include "cogl/cogl-pipeline-state-private.h" -#include "cogl/cogl-attribute-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/driver/gl/cogl-pipeline-fragend-glsl-private.h" -#include "cogl/driver/gl/cogl-pipeline-vertend-glsl-private.h" -#include "cogl/driver/gl/cogl-pipeline-progend-glsl-private.h" -#include "deprecated/cogl-program-private.h" -#include "deprecated/cogl-shader-private.h" - -/* These are used to generalise updating some uniforms that are - required when building for drivers missing some fixed function - state that we use */ - -typedef void (* UpdateUniformFunc) (CoglPipeline *pipeline, - int uniform_location, - void *getter_func); - -static void update_float_uniform (CoglPipeline *pipeline, - int uniform_location, - void *getter_func); - -typedef struct -{ - const char *uniform_name; - void *getter_func; - UpdateUniformFunc update_func; - CoglPipelineState change; -} BuiltinUniformData; - -static BuiltinUniformData builtin_uniforms[] = - { - { "cogl_point_size_in", - cogl_pipeline_get_point_size, update_float_uniform, - COGL_PIPELINE_STATE_POINT_SIZE }, - { "_cogl_alpha_test_ref", - cogl_pipeline_get_alpha_test_reference, update_float_uniform, - COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE }, - }; - -const CoglPipelineProgend _cogl_pipeline_glsl_progend; - -typedef struct _UnitState -{ - unsigned int dirty_combine_constant:1; - unsigned int dirty_texture_matrix:1; - - GLint combine_constant_uniform; - - GLint texture_matrix_uniform; -} UnitState; - -typedef struct -{ - unsigned int ref_count; - - /* Age that the user program had last time we generated a GL - program. If it's different then we need to relink the program */ - unsigned int user_program_age; - - GLuint program; - - unsigned long dirty_builtin_uniforms; - GLint builtin_uniform_locations[G_N_ELEMENTS (builtin_uniforms)]; - - GLint modelview_uniform; - GLint projection_uniform; - GLint mvp_uniform; - - CoglMatrixEntryCache projection_cache; - CoglMatrixEntryCache modelview_cache; - - /* We need to track the last pipeline that the program was used with - * so know if we need to update all of the uniforms */ - CoglPipeline *last_used_for_pipeline; - - /* Array of GL uniform locations indexed by Cogl's uniform - location. We are careful only to allocated this array if a custom - uniform is actually set */ - GArray *uniform_locations; - - /* Array of attribute locations. */ - GArray *attribute_locations; - - /* The 'flip' uniform is used to flip the geometry upside-down when - the framebuffer requires it only when there are vertex - snippets. Otherwise this is achieved using the projection - matrix */ - GLint flip_uniform; - int flushed_flip_state; - - UnitState *unit_state; - - CoglPipelineCacheEntry *cache_entry; -} CoglPipelineProgramState; - -static GQuark program_state_key = 0; - -typedef struct -{ - CoglPipelineProgramState *program_state; - CoglPipeline *instance; -} CoglPipelineProgramStateCache; - -static GQuark -get_cache_key (void) -{ - if (G_UNLIKELY (program_state_key == 0)) - program_state_key = g_quark_from_static_string ("program-state-progend-key"); - - return program_state_key; -} - -static CoglPipelineProgramState * -get_program_state (CoglPipeline *pipeline) -{ - CoglPipelineProgramStateCache *cache; - cache = g_object_get_qdata (G_OBJECT (pipeline), get_cache_key ()); - if (cache) - return cache->program_state; - return NULL; -} - -#define UNIFORM_LOCATION_UNKNOWN -2 - -#define ATTRIBUTE_LOCATION_UNKNOWN -2 - -/* Under GLES2 the vertex attribute API needs to query the attribute - numbers because it can't used the fixed function API to set the - builtin attributes. We cache the attributes here because the - progend knows when the program is changed so it can clear the - cache. This should always be called after the pipeline is flushed - so they can assert that the gl program is valid */ - -/* All attributes names get internally mapped to a global set of - * sequential indices when they are setup which we need to need to - * then be able to map to a GL attribute location once we have - * a linked GLSL program */ - -int -_cogl_pipeline_progend_glsl_get_attrib_location (CoglPipeline *pipeline, - int name_index) -{ - CoglPipelineProgramState *program_state = get_program_state (pipeline); - int *locations; - - _COGL_GET_CONTEXT (ctx, -1); - - g_return_val_if_fail (program_state != NULL, -1); - g_return_val_if_fail (program_state->program != 0, -1); - - if (G_UNLIKELY (program_state->attribute_locations == NULL)) - program_state->attribute_locations = - g_array_new (FALSE, FALSE, sizeof (int)); - - if (G_UNLIKELY (program_state->attribute_locations->len <= name_index)) - { - int i = program_state->attribute_locations->len; - g_array_set_size (program_state->attribute_locations, name_index + 1); - for (; i < program_state->attribute_locations->len; i++) - g_array_index (program_state->attribute_locations, int, i) - = ATTRIBUTE_LOCATION_UNKNOWN; - } - - locations = &g_array_index (program_state->attribute_locations, int, 0); - - if (locations[name_index] == ATTRIBUTE_LOCATION_UNKNOWN) - { - CoglAttributeNameState *name_state = - g_array_index (ctx->attribute_name_index_map, - CoglAttributeNameState *, name_index); - - g_return_val_if_fail (name_state != NULL, 0); - - GE_RET( locations[name_index], - ctx, glGetAttribLocation (program_state->program, - name_state->name) ); - } - - return locations[name_index]; -} - -static void -clear_attribute_cache (CoglPipelineProgramState *program_state) -{ - if (program_state->attribute_locations) - { - g_array_free (program_state->attribute_locations, TRUE); - program_state->attribute_locations = NULL; - } -} - -static void -clear_flushed_matrix_stacks (CoglPipelineProgramState *program_state) -{ - _cogl_matrix_entry_cache_destroy (&program_state->projection_cache); - _cogl_matrix_entry_cache_init (&program_state->projection_cache); - _cogl_matrix_entry_cache_destroy (&program_state->modelview_cache); - _cogl_matrix_entry_cache_init (&program_state->modelview_cache); -} - -static CoglPipelineProgramState * -program_state_new (int n_layers, - CoglPipelineCacheEntry *cache_entry) -{ - CoglPipelineProgramState *program_state; - - program_state = g_new0 (CoglPipelineProgramState, 1); - program_state->ref_count = 1; - program_state->program = 0; - program_state->unit_state = g_new (UnitState, n_layers); - program_state->uniform_locations = NULL; - program_state->attribute_locations = NULL; - program_state->cache_entry = cache_entry; - _cogl_matrix_entry_cache_init (&program_state->modelview_cache); - _cogl_matrix_entry_cache_init (&program_state->projection_cache); - - return program_state; -} - -static void -destroy_program_state (void *user_data) -{ - CoglPipelineProgramStateCache *cache = user_data; - CoglPipelineProgramState *program_state = cache->program_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* If the program state was last used for this pipeline then clear - it so that if same address gets used again for a new pipeline - then we won't think it's the same pipeline and avoid updating the - uniforms */ - if (program_state->last_used_for_pipeline == cache->instance) - program_state->last_used_for_pipeline = NULL; - - if (program_state->cache_entry && - program_state->cache_entry->pipeline != cache->instance) - program_state->cache_entry->usage_count--; - - if (--program_state->ref_count == 0) - { - clear_attribute_cache (program_state); - - _cogl_matrix_entry_cache_destroy (&program_state->projection_cache); - _cogl_matrix_entry_cache_destroy (&program_state->modelview_cache); - - if (program_state->program) - GE( ctx, glDeleteProgram (program_state->program) ); - - g_free (program_state->unit_state); - - if (program_state->uniform_locations) - g_array_free (program_state->uniform_locations, TRUE); - - g_free (program_state); - } - - g_free (cache); -} - -static void -set_program_state (CoglPipeline *pipeline, - CoglPipelineProgramState *program_state) -{ - if (program_state) - { - program_state->ref_count++; - - /* If we're not setting the state on the template pipeline then - * mark it as a usage of the pipeline cache entry */ - if (program_state->cache_entry && - program_state->cache_entry->pipeline != pipeline) - program_state->cache_entry->usage_count++; - } - - CoglPipelineProgramStateCache *cache = g_new0 (CoglPipelineProgramStateCache, 1); - cache->instance = pipeline; - cache->program_state = program_state; - - g_object_set_qdata_full (G_OBJECT (pipeline), - get_cache_key (), - cache, - destroy_program_state); -} - -static void -dirty_program_state (CoglPipeline *pipeline) -{ - g_object_set_qdata_full (G_OBJECT (pipeline), - get_cache_key (), - NULL, - NULL); -} - -static void -link_program (GLint gl_program) -{ - GLint link_status; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - GE( ctx, glLinkProgram (gl_program) ); - - GE( ctx, glGetProgramiv (gl_program, GL_LINK_STATUS, &link_status) ); - - if (!link_status) - { - GLint log_length; - GLsizei out_log_length; - char *log; - - GE( ctx, glGetProgramiv (gl_program, GL_INFO_LOG_LENGTH, &log_length) ); - - log = g_malloc (log_length); - - GE( ctx, glGetProgramInfoLog (gl_program, log_length, - &out_log_length, log) ); - - g_warning ("Failed to link GLSL program:\n%.*s\n", - log_length, log); - - g_free (log); - } -} - -typedef struct -{ - int unit; - GLuint gl_program; - gboolean update_all; - CoglPipelineProgramState *program_state; -} UpdateUniformsState; - -static gboolean -get_uniform_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - UpdateUniformsState *state = user_data; - CoglPipelineProgramState *program_state = state->program_state; - UnitState *unit_state = &program_state->unit_state[state->unit]; - GLint uniform_location; - - _COGL_GET_CONTEXT (ctx, FALSE); - - /* We can reuse the source buffer to create the uniform name because - the program has now been linked */ - g_string_set_size (ctx->codegen_source_buffer, 0); - g_string_append_printf (ctx->codegen_source_buffer, - "cogl_sampler%i", layer_index); - - GE_RET( uniform_location, - ctx, glGetUniformLocation (state->gl_program, - ctx->codegen_source_buffer->str) ); - - /* We can set the uniform immediately because the samplers are the - unit index not the texture object number so it will never - change. Unfortunately GL won't let us use a constant instead of a - uniform */ - if (uniform_location != -1) - GE( ctx, glUniform1i (uniform_location, state->unit) ); - - g_string_set_size (ctx->codegen_source_buffer, 0); - g_string_append_printf (ctx->codegen_source_buffer, - "_cogl_layer_constant_%i", layer_index); - - GE_RET( uniform_location, - ctx, glGetUniformLocation (state->gl_program, - ctx->codegen_source_buffer->str) ); - - unit_state->combine_constant_uniform = uniform_location; - - g_string_set_size (ctx->codegen_source_buffer, 0); - g_string_append_printf (ctx->codegen_source_buffer, - "cogl_texture_matrix[%i]", layer_index); - - GE_RET( uniform_location, - ctx, glGetUniformLocation (state->gl_program, - ctx->codegen_source_buffer->str) ); - - unit_state->texture_matrix_uniform = uniform_location; - - state->unit++; - - return TRUE; -} - -static gboolean -update_constants_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - UpdateUniformsState *state = user_data; - CoglPipelineProgramState *program_state = state->program_state; - UnitState *unit_state = &program_state->unit_state[state->unit++]; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (unit_state->combine_constant_uniform != -1 && - (state->update_all || unit_state->dirty_combine_constant)) - { - float constant[4]; - _cogl_pipeline_get_layer_combine_constant (pipeline, - layer_index, - constant); - GE (ctx, glUniform4fv (unit_state->combine_constant_uniform, - 1, constant)); - unit_state->dirty_combine_constant = FALSE; - } - - if (unit_state->texture_matrix_uniform != -1 && - (state->update_all || unit_state->dirty_texture_matrix)) - { - const graphene_matrix_t *matrix; - float array[16]; - - matrix = _cogl_pipeline_get_layer_matrix (pipeline, layer_index); - graphene_matrix_to_float (matrix, array); - GE (ctx, glUniformMatrix4fv (unit_state->texture_matrix_uniform, - 1, FALSE, array)); - unit_state->dirty_texture_matrix = FALSE; - } - - return TRUE; -} - -static void -update_builtin_uniforms (CoglContext *context, - CoglPipeline *pipeline, - GLuint gl_program, - CoglPipelineProgramState *program_state) -{ - int i; - - if (program_state->dirty_builtin_uniforms == 0) - return; - - for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++) - if ((program_state->dirty_builtin_uniforms & (1 << i)) && - program_state->builtin_uniform_locations[i] != -1) - builtin_uniforms[i].update_func (pipeline, - program_state - ->builtin_uniform_locations[i], - builtin_uniforms[i].getter_func); - - program_state->dirty_builtin_uniforms = 0; -} - -typedef struct -{ - CoglPipelineProgramState *program_state; - unsigned long *uniform_differences; - int n_differences; - CoglContext *ctx; - const CoglBoxedValue *values; - int value_index; -} FlushUniformsClosure; - -static gboolean -flush_uniform_cb (int uniform_num, void *user_data) -{ - FlushUniformsClosure *data = user_data; - - if (COGL_FLAGS_GET (data->uniform_differences, uniform_num)) - { - GArray *uniform_locations; - GLint uniform_location; - - if (data->program_state->uniform_locations == NULL) - data->program_state->uniform_locations = - g_array_new (FALSE, FALSE, sizeof (GLint)); - - uniform_locations = data->program_state->uniform_locations; - - if (uniform_locations->len <= uniform_num) - { - unsigned int old_len = uniform_locations->len; - - g_array_set_size (uniform_locations, uniform_num + 1); - - while (old_len <= uniform_num) - { - g_array_index (uniform_locations, GLint, old_len) = - UNIFORM_LOCATION_UNKNOWN; - old_len++; - } - } - - uniform_location = g_array_index (uniform_locations, GLint, uniform_num); - - if (uniform_location == UNIFORM_LOCATION_UNKNOWN) - { - const char *uniform_name = - g_ptr_array_index (data->ctx->uniform_names, uniform_num); - - uniform_location = - data->ctx->glGetUniformLocation (data->program_state->program, - uniform_name); - g_array_index (uniform_locations, GLint, uniform_num) = - uniform_location; - } - - if (uniform_location != -1) - _cogl_boxed_value_set_uniform (data->ctx, - uniform_location, - data->values + data->value_index); - - data->n_differences--; - COGL_FLAGS_SET (data->uniform_differences, uniform_num, FALSE); - } - - data->value_index++; - - return data->n_differences > 0; -} - -static void -_cogl_pipeline_progend_glsl_flush_uniforms (CoglPipeline *pipeline, - CoglPipelineProgramState * - program_state, - GLuint gl_program, - gboolean program_changed) -{ - CoglPipelineUniformsState *uniforms_state; - FlushUniformsClosure data; - int n_uniform_longs; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (pipeline->differences & COGL_PIPELINE_STATE_UNIFORMS) - uniforms_state = &pipeline->big_state->uniforms_state; - else - uniforms_state = NULL; - - data.program_state = program_state; - data.ctx = ctx; - - n_uniform_longs = COGL_FLAGS_N_LONGS_FOR_SIZE (ctx->n_uniform_names); - - data.uniform_differences = g_newa (unsigned long, n_uniform_longs); - - /* Try to find a common ancestor for the values that were already - flushed on the pipeline that this program state was last used for - so we can avoid flushing those */ - - if (program_changed || program_state->last_used_for_pipeline == NULL) - { - if (program_changed) - { - /* The program has changed so all of the uniform locations - are invalid */ - if (program_state->uniform_locations) - g_array_set_size (program_state->uniform_locations, 0); - } - - /* We need to flush everything so mark all of the uniforms as - dirty */ - memset (data.uniform_differences, 0xff, - n_uniform_longs * sizeof (unsigned long)); - data.n_differences = G_MAXINT; - } - else if (program_state->last_used_for_pipeline) - { - int i; - - memset (data.uniform_differences, 0, - n_uniform_longs * sizeof (unsigned long)); - _cogl_pipeline_compare_uniform_differences - (data.uniform_differences, - program_state->last_used_for_pipeline, - pipeline); - - /* We need to be sure to flush any uniforms that have changed - since the last flush */ - if (uniforms_state) - _cogl_bitmask_set_flags (&uniforms_state->changed_mask, - data.uniform_differences); - - /* Count the number of differences. This is so we can stop early - when we've flushed all of them */ - data.n_differences = 0; - - for (i = 0; i < n_uniform_longs; i++) - data.n_differences += - _cogl_util_popcountl (data.uniform_differences[i]); - } - - while (pipeline && data.n_differences > 0) - { - if (pipeline->differences & COGL_PIPELINE_STATE_UNIFORMS) - { - const CoglPipelineUniformsState *parent_uniforms_state = - &pipeline->big_state->uniforms_state; - - data.values = parent_uniforms_state->override_values; - data.value_index = 0; - - _cogl_bitmask_foreach (&parent_uniforms_state->override_mask, - flush_uniform_cb, - &data); - } - - pipeline = _cogl_pipeline_get_parent (pipeline); - } - - if (uniforms_state) - _cogl_bitmask_clear_all (&uniforms_state->changed_mask); -} - -static gboolean -_cogl_pipeline_progend_glsl_start (CoglPipeline *pipeline) -{ - return TRUE; -} - -static void -_cogl_shader_compile_real (CoglShader *shader, - CoglPipeline *pipeline) -{ - GLenum gl_type; - GLint status; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (shader->gl_handle) - { - CoglPipeline *prev = shader->compilation_pipeline; - - /* XXX: currently the only things that will affect the - * boilerplate for user shaders, apart from driver features, - * are the pipeline layer-indices and texture-unit-indices - */ - if (pipeline == prev || - _cogl_pipeline_layer_and_unit_numbers_equal (prev, pipeline)) - return; - - GE (ctx, glDeleteShader (shader->gl_handle)); - shader->gl_handle = 0; - - if (shader->compilation_pipeline) - { - g_object_unref (shader->compilation_pipeline); - shader->compilation_pipeline = NULL; - } - } - - switch (shader->type) - { - case COGL_SHADER_TYPE_VERTEX: - gl_type = GL_VERTEX_SHADER; - break; - case COGL_SHADER_TYPE_FRAGMENT: - gl_type = GL_FRAGMENT_SHADER; - break; - default: - g_assert_not_reached (); - break; - } - - shader->gl_handle = ctx->glCreateShader (gl_type); - - _cogl_glsl_shader_set_source_with_boilerplate (ctx, - shader->gl_handle, - gl_type, - pipeline, - 1, - (const char **) - &shader->source, - NULL); - GE (ctx, glCompileShader (shader->gl_handle)); - - shader->compilation_pipeline = g_object_ref (pipeline); - - GE (ctx, glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status)); - if (!status) - { - char buffer[512]; - int len = 0; - - ctx->glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer); - buffer[len] = '\0'; - - g_warning ("Failed to compile GLSL program:\n" - "src:\n%s\n" - "error:\n%s\n", - shader->source, - buffer); - } -} - -static void -_cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline, - unsigned long pipelines_difference) -{ - CoglPipelineProgramState *program_state; - GLuint gl_program; - gboolean program_changed = FALSE; - UpdateUniformsState state; - CoglProgram *user_program; - CoglPipelineCacheEntry *cache_entry = NULL; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - program_state = get_program_state (pipeline); - - user_program = cogl_pipeline_get_user_program (pipeline); - - if (program_state == NULL) - { - CoglPipeline *authority; - - /* Get the authority for anything affecting program state. This - should include both fragment codegen state and vertex codegen - state */ - authority = _cogl_pipeline_find_equivalent_parent - (pipeline, - (_cogl_pipeline_get_state_for_vertex_codegen (ctx) | - _cogl_pipeline_get_state_for_fragment_codegen (ctx)) & - ~COGL_PIPELINE_STATE_LAYERS, - _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx) | - COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN); - - program_state = get_program_state (authority); - - if (program_state == NULL) - { - /* Check if there is already a similar cached pipeline whose - program state we can share */ - if (G_LIKELY (!(COGL_DEBUG_ENABLED - (COGL_DEBUG_DISABLE_PROGRAM_CACHES)))) - { - cache_entry = - _cogl_pipeline_cache_get_combined_template (ctx->pipeline_cache, - authority); - - program_state = get_program_state (cache_entry->pipeline); - } - - if (program_state) - program_state->ref_count++; - else - program_state - = program_state_new (cogl_pipeline_get_n_layers (authority), - cache_entry); - - set_program_state (authority, program_state); - - program_state->ref_count--; - - if (cache_entry) - set_program_state (cache_entry->pipeline, program_state); - } - - if (authority != pipeline) - set_program_state (pipeline, program_state); - } - - /* If the program has changed since the last link then we do - * need to relink */ - if (program_state->program && user_program && - user_program->age != program_state->user_program_age) - { - GE( ctx, glDeleteProgram (program_state->program) ); - program_state->program = 0; - } - - if (program_state->program == 0) - { - GLuint backend_shader; - GSList *l; - - GE_RET( program_state->program, ctx, glCreateProgram () ); - - /* Attach all of the shader from the user program */ - if (user_program) - { - for (l = user_program->attached_shaders; l; l = l->next) - { - CoglShader *shader = l->data; - - _cogl_shader_compile_real (shader, pipeline); - - GE( ctx, glAttachShader (program_state->program, - shader->gl_handle) ); - } - - program_state->user_program_age = user_program->age; - } - - /* Attach any shaders from the GLSL backends */ - if ((backend_shader = _cogl_pipeline_fragend_glsl_get_shader (pipeline))) - GE( ctx, glAttachShader (program_state->program, backend_shader) ); - if ((backend_shader = _cogl_pipeline_vertend_glsl_get_shader (pipeline))) - GE( ctx, glAttachShader (program_state->program, backend_shader) ); - - /* XXX: OpenGL as a special case requires the vertex position to - * be bound to generic attribute 0 so for simplicity we - * unconditionally bind the cogl_position_in attribute here... - */ - GE( ctx, glBindAttribLocation (program_state->program, - 0, "cogl_position_in")); - - link_program (program_state->program); - - program_changed = TRUE; - } - - gl_program = program_state->program; - - if (ctx->current_gl_program != gl_program) - { - _cogl_gl_util_clear_gl_errors (ctx); - ctx->glUseProgram (gl_program); - if (_cogl_gl_util_get_error (ctx) == GL_NO_ERROR) - ctx->current_gl_program = gl_program; - else - { - GE( ctx, glUseProgram (0) ); - ctx->current_gl_program = 0; - } - } - - state.unit = 0; - state.gl_program = gl_program; - state.program_state = program_state; - - if (program_changed) - { - cogl_pipeline_foreach_layer (pipeline, - get_uniform_cb, - &state); - clear_attribute_cache (program_state); - - GE_RET (program_state->flip_uniform, - ctx, glGetUniformLocation (gl_program, "_cogl_flip_vector")); - program_state->flushed_flip_state = -1; - } - - state.unit = 0; - state.update_all = (program_changed || - program_state->last_used_for_pipeline != pipeline); - - cogl_pipeline_foreach_layer (pipeline, - update_constants_cb, - &state); - - if (program_changed) - { - int i; - - clear_flushed_matrix_stacks (program_state); - - for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++) - GE_RET( program_state->builtin_uniform_locations[i], ctx, - glGetUniformLocation (gl_program, - builtin_uniforms[i].uniform_name) ); - - GE_RET( program_state->modelview_uniform, ctx, - glGetUniformLocation (gl_program, - "cogl_modelview_matrix") ); - - GE_RET( program_state->projection_uniform, ctx, - glGetUniformLocation (gl_program, - "cogl_projection_matrix") ); - - GE_RET( program_state->mvp_uniform, ctx, - glGetUniformLocation (gl_program, - "cogl_modelview_projection_matrix") ); - } - - if (program_changed || - program_state->last_used_for_pipeline != pipeline) - program_state->dirty_builtin_uniforms = ~(unsigned long) 0; - - update_builtin_uniforms (ctx, pipeline, gl_program, program_state); - - _cogl_pipeline_progend_glsl_flush_uniforms (pipeline, - program_state, - gl_program, - program_changed); - - if (user_program) - _cogl_program_flush_uniforms (user_program, - gl_program, - program_changed); - - /* We need to track the last pipeline that the program was used with - * so know if we need to update all of the uniforms */ - program_state->last_used_for_pipeline = pipeline; -} - -static void -_cogl_pipeline_progend_glsl_pre_change_notify (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if ((change & (_cogl_pipeline_get_state_for_vertex_codegen (ctx) | - _cogl_pipeline_get_state_for_fragment_codegen (ctx)))) - { - dirty_program_state (pipeline); - } - else - { - int i; - - for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++) - if (change & builtin_uniforms[i].change) - { - CoglPipelineProgramState *program_state - = get_program_state (pipeline); - if (program_state) - program_state->dirty_builtin_uniforms |= 1 << i; - return; - } - } -} - -/* NB: layers are considered immutable once they have any dependants - * so although multiple pipelines can end up depending on a single - * static layer, we can guarantee that if a layer is being *changed* - * then it can only have one pipeline depending on it. - * - * XXX: Don't forget this is *pre* change, we can't read the new value - * yet! - */ -static void -_cogl_pipeline_progend_glsl_layer_pre_change_notify ( - CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - CoglTextureUnit *unit; - - if ((change & (_cogl_pipeline_get_layer_state_for_fragment_codegen (ctx) | - COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN))) - { - dirty_program_state (owner); - } - else if (change & COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT) - { - CoglPipelineProgramState *program_state = get_program_state (owner); - if (program_state) - { - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - program_state->unit_state[unit_index].dirty_combine_constant = TRUE; - } - } - else if (change & COGL_PIPELINE_LAYER_STATE_USER_MATRIX) - { - CoglPipelineProgramState *program_state = get_program_state (owner); - if (program_state) - { - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - program_state->unit_state[unit_index].dirty_texture_matrix = TRUE; - } - } - - /* If the layer being changed is the same as the last layer we - * flushed to the corresponding texture unit then we keep a track of - * the changes so we can try to minimize redundant OpenGL calls if - * the same layer is flushed again. - */ - unit = _cogl_get_texture_unit (_cogl_pipeline_layer_get_unit_index (layer)); - if (unit->layer == layer) - unit->layer_changes_since_flush |= change; -} - -static void -_cogl_pipeline_progend_glsl_pre_paint (CoglPipeline *pipeline, - CoglFramebuffer *framebuffer) -{ - gboolean needs_flip; - CoglMatrixEntry *projection_entry; - CoglMatrixEntry *modelview_entry; - CoglPipelineProgramState *program_state; - gboolean modelview_changed; - gboolean projection_changed; - gboolean need_modelview; - gboolean need_projection; - graphene_matrix_t modelview, projection; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - program_state = get_program_state (pipeline); - - projection_entry = ctx->current_projection_entry; - modelview_entry = ctx->current_modelview_entry; - - /* An initial pipeline is flushed while creating the context. At - this point there are no matrices selected so we can't do - anything */ - if (modelview_entry == NULL || projection_entry == NULL) - return; - - needs_flip = cogl_framebuffer_is_y_flipped (ctx->current_draw_buffer); - - projection_changed = - _cogl_matrix_entry_cache_maybe_update (&program_state->projection_cache, - projection_entry, - (needs_flip && - program_state->flip_uniform == - -1)); - - modelview_changed = - _cogl_matrix_entry_cache_maybe_update (&program_state->modelview_cache, - modelview_entry, - /* never flip modelview */ - FALSE); - - if (modelview_changed || projection_changed) - { - float v[16]; - - if (program_state->mvp_uniform != -1) - need_modelview = need_projection = TRUE; - else - { - need_projection = (program_state->projection_uniform != -1 && - projection_changed); - need_modelview = (program_state->modelview_uniform != -1 && - modelview_changed); - } - - if (need_modelview) - cogl_matrix_entry_get (modelview_entry, &modelview); - if (need_projection) - { - if (needs_flip && program_state->flip_uniform == -1) - { - graphene_matrix_t tmp_matrix; - cogl_matrix_entry_get (projection_entry, &tmp_matrix); - graphene_matrix_multiply (&tmp_matrix, - &ctx->y_flip_matrix, - &projection); - } - else - cogl_matrix_entry_get (projection_entry, &projection); - } - - if (projection_changed && program_state->projection_uniform != -1) - { - graphene_matrix_to_float (&projection, v); - GE (ctx, glUniformMatrix4fv (program_state->projection_uniform, - 1, /* count */ - FALSE, /* transpose */ - v)); - } - - if (modelview_changed && program_state->modelview_uniform != -1) - { - graphene_matrix_to_float (&modelview,v); - GE (ctx, glUniformMatrix4fv (program_state->modelview_uniform, - 1, /* count */ - FALSE, /* transpose */ - v)); - } - - if (program_state->mvp_uniform != -1) - { - /* The journal usually uses an identity matrix for the - modelview so we can optimise this common case by - avoiding the matrix multiplication */ - if (cogl_matrix_entry_is_identity (modelview_entry)) - { - graphene_matrix_to_float (&projection, v); - GE (ctx, - glUniformMatrix4fv (program_state->mvp_uniform, - 1, /* count */ - FALSE, /* transpose */ - v)); - } - else - { - graphene_matrix_t combined; - - graphene_matrix_multiply (&modelview, &projection, &combined); - graphene_matrix_to_float (&combined, v); - - GE (ctx, - glUniformMatrix4fv (program_state->mvp_uniform, - 1, /* count */ - FALSE, /* transpose */ - v)); - } - } - } - - if (program_state->flip_uniform != -1 - && program_state->flushed_flip_state != needs_flip) - { - static const float do_flip[4] = { 1.0f, -1.0f, 1.0f, 1.0f }; - static const float dont_flip[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - GE( ctx, glUniform4fv (program_state->flip_uniform, - 1, /* count */ - needs_flip ? do_flip : dont_flip) ); - program_state->flushed_flip_state = needs_flip; - } -} - -static void -update_float_uniform (CoglPipeline *pipeline, - int uniform_location, - void *getter_func) -{ - float (* float_getter_func) (CoglPipeline *) = getter_func; - float value; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - value = float_getter_func (pipeline); - GE( ctx, glUniform1f (uniform_location, value) ); -} - -const CoglPipelineProgend _cogl_pipeline_glsl_progend = - { - _cogl_pipeline_progend_glsl_start, - _cogl_pipeline_progend_glsl_end, - _cogl_pipeline_progend_glsl_pre_change_notify, - _cogl_pipeline_progend_glsl_layer_pre_change_notify, - _cogl_pipeline_progend_glsl_pre_paint - }; diff --git a/mutter/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl-private.h b/mutter/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl-private.h deleted file mode 100644 index 543a252..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl-private.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-pipeline-private.h" - -typedef struct _CoglPipelineVertendShaderState CoglPipelineVertendShaderState; - -extern const CoglPipelineVertend _cogl_pipeline_glsl_vertend; - -GLuint -_cogl_pipeline_vertend_glsl_get_shader (CoglPipeline *pipeline); - -COGL_EXPORT_TEST -CoglPipelineVertendShaderState * cogl_pipeline_vertend_glsl_get_shader_state (CoglPipeline *pipeline); diff --git a/mutter/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c b/mutter/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c deleted file mode 100644 index 6b5671b..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c +++ /dev/null @@ -1,773 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#include "config.h" - -#include - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-pipeline-private.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" -#include "cogl/driver/gl/cogl-pipeline-opengl-private.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-pipeline-state-private.h" -#include "cogl/cogl-glsl-shader-boilerplate.h" -#include "cogl/driver/gl/cogl-pipeline-vertend-glsl-private.h" -#include "deprecated/cogl-program-private.h" - -const CoglPipelineVertend _cogl_pipeline_glsl_vertend; - -struct _CoglPipelineVertendShaderState -{ - unsigned int ref_count; - - GLuint gl_shader; - GString *header, *source; - - CoglPipelineCacheEntry *cache_entry; -}; - -static GQuark shader_state_key = 0; - -static CoglPipelineVertendShaderState * -shader_state_new (CoglPipelineCacheEntry *cache_entry) -{ - CoglPipelineVertendShaderState *shader_state; - - shader_state = g_new0 (CoglPipelineVertendShaderState, 1); - shader_state->ref_count = 1; - shader_state->cache_entry = cache_entry; - - return shader_state; -} - -typedef struct -{ - CoglPipelineVertendShaderState *shader_state; - CoglPipeline *instance; -} CoglPipelineVertendShaderStateCache; - -static GQuark -get_cache_key (void) -{ - if (G_UNLIKELY (shader_state_key == 0)) - shader_state_key = g_quark_from_static_string ("shader-vertend-state-key"); - - return shader_state_key; -} - -static CoglPipelineVertendShaderState * -get_shader_state (CoglPipeline *pipeline) -{ - CoglPipelineVertendShaderStateCache * cache; - cache = g_object_get_qdata (G_OBJECT (pipeline), get_cache_key ()); - if (cache) - return cache->shader_state; - return NULL; -} - -CoglPipelineVertendShaderState * -cogl_pipeline_vertend_glsl_get_shader_state (CoglPipeline *pipeline) -{ - return get_shader_state (pipeline); -} - -static void -destroy_shader_state (void *user_data) -{ - CoglPipelineVertendShaderStateCache *cache = user_data; - CoglPipelineVertendShaderState *shader_state = cache->shader_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (shader_state->cache_entry && - shader_state->cache_entry->pipeline != cache->instance) - shader_state->cache_entry->usage_count--; - - if (--shader_state->ref_count == 0) - { - if (shader_state->gl_shader) - GE( ctx, glDeleteShader (shader_state->gl_shader) ); - - g_free (shader_state); - } - - g_free (cache); -} - -static void -set_shader_state (CoglPipeline *pipeline, - CoglPipelineVertendShaderState *shader_state) -{ - if (shader_state) - { - shader_state->ref_count++; - - /* If we're not setting the state on the template pipeline then - * mark it as a usage of the pipeline cache entry */ - if (shader_state->cache_entry && - shader_state->cache_entry->pipeline != pipeline) - shader_state->cache_entry->usage_count++; - } - - CoglPipelineVertendShaderStateCache *cache = g_new0 (CoglPipelineVertendShaderStateCache, 1); - cache->instance = pipeline; - cache->shader_state = shader_state; - g_object_set_qdata_full (G_OBJECT (pipeline), - get_cache_key (), - cache, - destroy_shader_state); -} - -static void -dirty_shader_state (CoglPipeline *pipeline) -{ - g_object_set_qdata_full (G_OBJECT (pipeline), - get_cache_key (), - NULL, - NULL); -} - -static gboolean -add_layer_vertex_boilerplate_cb (CoglPipelineLayer *layer, - void *user_data) -{ - GString *layer_declarations = user_data; - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - g_string_append_printf (layer_declarations, - "attribute vec4 cogl_tex_coord%d_in;\n" - "#define cogl_texture_matrix%i cogl_texture_matrix[%i]\n" - "#define cogl_tex_coord%i_out _cogl_tex_coord[%i]\n", - layer->index, - layer->index, - unit_index, - layer->index, - unit_index); - return TRUE; -} - -static gboolean -add_layer_fragment_boilerplate_cb (CoglPipelineLayer *layer, - void *user_data) -{ - GString *layer_declarations = user_data; - g_string_append_printf (layer_declarations, - "#define cogl_tex_coord%i_in _cogl_tex_coord[%i]\n", - layer->index, - _cogl_pipeline_layer_get_unit_index (layer)); - return TRUE; -} - -void -_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx, - GLuint shader_gl_handle, - GLenum shader_gl_type, - CoglPipeline *pipeline, - GLsizei count_in, - const char **strings_in, - const GLint *lengths_in) -{ - const char *vertex_boilerplate; - const char *fragment_boilerplate; - - const char **strings = g_alloca (sizeof (char *) * (count_in + 4)); - GLint *lengths = g_alloca (sizeof (GLint) * (count_in + 4)); - char *version_string; - int count = 0; - - int n_layers; - - vertex_boilerplate = _COGL_VERTEX_SHADER_BOILERPLATE; - fragment_boilerplate = _COGL_FRAGMENT_SHADER_BOILERPLATE; - - version_string = g_strdup_printf ("#version %i\n\n", - ctx->glsl_version_to_use); - strings[count] = version_string; - lengths[count++] = -1; - - if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL)) - { - static const char image_external_extension[] = - "#extension GL_OES_EGL_image_external : require\n"; - strings[count] = image_external_extension; - lengths[count++] = sizeof (image_external_extension) - 1; - } - - if (shader_gl_type == GL_VERTEX_SHADER) - { - strings[count] = vertex_boilerplate; - lengths[count++] = strlen (vertex_boilerplate); - } - else if (shader_gl_type == GL_FRAGMENT_SHADER) - { - strings[count] = fragment_boilerplate; - lengths[count++] = strlen (fragment_boilerplate); - } - - n_layers = cogl_pipeline_get_n_layers (pipeline); - if (n_layers) - { - GString *layer_declarations = ctx->codegen_boilerplate_buffer; - g_string_set_size (layer_declarations, 0); - - g_string_append_printf (layer_declarations, - "varying vec4 _cogl_tex_coord[%d];\n", - n_layers); - - if (shader_gl_type == GL_VERTEX_SHADER) - { - g_string_append_printf (layer_declarations, - "uniform mat4 cogl_texture_matrix[%d];\n", - n_layers); - - _cogl_pipeline_foreach_layer_internal (pipeline, - add_layer_vertex_boilerplate_cb, - layer_declarations); - } - else if (shader_gl_type == GL_FRAGMENT_SHADER) - { - _cogl_pipeline_foreach_layer_internal (pipeline, - add_layer_fragment_boilerplate_cb, - layer_declarations); - } - - strings[count] = layer_declarations->str; - lengths[count++] = -1; /* null terminated */ - } - - memcpy (strings + count, strings_in, sizeof (char *) * count_in); - if (lengths_in) - memcpy (lengths + count, lengths_in, sizeof (GLint) * count_in); - else - { - int i; - - for (i = 0; i < count_in; i++) - lengths[count + i] = -1; /* null terminated */ - } - count += count_in; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SHOW_SOURCE))) - { - GString *buf; - g_auto (GStrv) lines = NULL; - int i; - - buf = g_string_new (NULL); - for (i = 0; i < count; i++) - if (lengths[i] != -1) - g_string_append_len (buf, strings[i], lengths[i]); - else - g_string_append (buf, strings[i]); - - lines = g_strsplit (buf->str, "\n", 0); - g_string_free (buf, TRUE); - - buf = g_string_new (NULL); - for (i = 0; lines[i]; i++) - g_string_append_printf (buf, "%4d: %s\n", i + 1, lines[i]); - - g_message ("%s shader:\n%s", - shader_gl_type == GL_VERTEX_SHADER ? - "vertex" : "fragment", - buf->str); - g_string_free (buf, TRUE); - } - - GE( ctx, glShaderSource (shader_gl_handle, count, - (const char **) strings, lengths) ); - - g_free (version_string); -} -GLuint -_cogl_pipeline_vertend_glsl_get_shader (CoglPipeline *pipeline) -{ - CoglPipelineVertendShaderState *shader_state = get_shader_state (pipeline); - - if (shader_state) - return shader_state->gl_shader; - else - return 0; -} - -static CoglPipelineSnippetList * -get_vertex_snippets (CoglPipeline *pipeline) -{ - pipeline = - _cogl_pipeline_get_authority (pipeline, - COGL_PIPELINE_STATE_VERTEX_SNIPPETS); - - return &pipeline->big_state->vertex_snippets; -} - -static CoglPipelineSnippetList * -get_layer_vertex_snippets (CoglPipelineLayer *layer) -{ - unsigned long state = COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS; - layer = _cogl_pipeline_layer_get_authority (layer, state); - - return &layer->big_state->vertex_snippets; -} - -static gboolean -add_layer_declaration_cb (CoglPipelineLayer *layer, - void *user_data) -{ - CoglPipelineVertendShaderState *shader_state = user_data; - - g_string_append_printf (shader_state->header, - "uniform sampler2D cogl_sampler%i;\n", - layer->index); - - return TRUE; -} - -static void -add_layer_declarations (CoglPipeline *pipeline, - CoglPipelineVertendShaderState *shader_state) -{ - /* We always emit sampler uniforms in case there will be custom - * layer snippets that want to sample arbitrary layers. */ - - _cogl_pipeline_foreach_layer_internal (pipeline, - add_layer_declaration_cb, - shader_state); -} - -static void -add_global_declarations (CoglPipeline *pipeline, - CoglPipelineVertendShaderState *shader_state) -{ - CoglSnippetHook hook = COGL_SNIPPET_HOOK_VERTEX_GLOBALS; - CoglPipelineSnippetList *snippets = get_vertex_snippets (pipeline); - - /* Add the global data hooks. All of the code in these snippets is - * always added and only the declarations data is used */ - - _cogl_pipeline_snippet_generate_declarations (shader_state->header, - hook, - snippets); -} - -static void -_cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference) -{ - CoglPipelineVertendShaderState *shader_state; - CoglPipelineCacheEntry *cache_entry = NULL; - CoglProgram *user_program = cogl_pipeline_get_user_program (pipeline); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Now lookup our glsl backend private state (allocating if - * necessary) */ - shader_state = get_shader_state (pipeline); - - if (shader_state == NULL) - { - CoglPipeline *authority; - - /* Get the authority for anything affecting vertex shader - state */ - authority = _cogl_pipeline_find_equivalent_parent - (pipeline, - _cogl_pipeline_get_state_for_vertex_codegen (ctx) & - ~COGL_PIPELINE_STATE_LAYERS, - COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN); - - shader_state = get_shader_state (authority); - - if (shader_state == NULL) - { - /* Check if there is already a similar cached pipeline whose - shader state we can share */ - if (G_LIKELY (!(COGL_DEBUG_ENABLED - (COGL_DEBUG_DISABLE_PROGRAM_CACHES)))) - { - cache_entry = - _cogl_pipeline_cache_get_vertex_template (ctx->pipeline_cache, - authority); - - shader_state = get_shader_state (cache_entry->pipeline); - } - - if (shader_state) - shader_state->ref_count++; - else - shader_state = shader_state_new (cache_entry); - - set_shader_state (authority, shader_state); - - shader_state->ref_count--; - - if (cache_entry) - set_shader_state (cache_entry->pipeline, shader_state); - } - - if (authority != pipeline) - set_shader_state (pipeline, shader_state); - } - - if (user_program) - { - /* If the user program contains a vertex shader then we don't need - to generate one */ - if (_cogl_program_has_vertex_shader (user_program)) - { - if (shader_state->gl_shader) - { - GE( ctx, glDeleteShader (shader_state->gl_shader) ); - shader_state->gl_shader = 0; - } - return; - } - } - - if (shader_state->gl_shader) - return; - - /* If we make it here then we have a shader_state struct without a gl_shader - either because this is the first time we've encountered it or - because the user program has changed */ - - /* We reuse two grow-only GStrings for code-gen. One string - contains the uniform and attribute declarations while the - other contains the main function. We need two strings - because we need to dynamically declare attributes as the - add_layer callback is invoked */ - g_string_set_size (ctx->codegen_header_buffer, 0); - g_string_set_size (ctx->codegen_source_buffer, 0); - shader_state->header = ctx->codegen_header_buffer; - shader_state->source = ctx->codegen_source_buffer; - - add_layer_declarations (pipeline, shader_state); - add_global_declarations (pipeline, shader_state); - - g_string_append (shader_state->source, - "void\n" - "cogl_generated_source ()\n" - "{\n"); - - if (cogl_pipeline_get_per_vertex_point_size (pipeline)) - g_string_append (shader_state->header, - "attribute float cogl_point_size_in;\n"); - else - { - /* There is no builtin uniform for the point size on GLES2 so we - need to copy it from the custom uniform in the vertex shader - if we're not using per-vertex point sizes, however we'll only - do this if the point-size is non-zero. Toggle the point size - between zero and non-zero causes a state change which - generates a new program */ - if (cogl_pipeline_get_point_size (pipeline) > 0.0f) - { - g_string_append (shader_state->header, - "uniform float cogl_point_size_in;\n"); - g_string_append (shader_state->source, - " cogl_point_size_out = cogl_point_size_in;\n"); - } - } -} - -static gboolean -_cogl_pipeline_vertend_glsl_add_layer (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference, - CoglFramebuffer *framebuffer) -{ - CoglPipelineVertendShaderState *shader_state; - CoglPipelineSnippetData snippet_data; - int layer_index = layer->index; - - _COGL_GET_CONTEXT (ctx, FALSE); - - shader_state = get_shader_state (pipeline); - - if (shader_state->source == NULL) - return TRUE; - - /* Transform the texture coordinates by the layer's user matrix. - * - * FIXME: this should avoid doing the transform if there is no user - * matrix set. This might need a separate layer state flag for - * whether there is a user matrix - * - * FIXME: we could be more clever here and try to detect if the - * fragment program is going to use the texture coordinates and - * avoid setting them if not - */ - - g_string_append_printf (shader_state->header, - "vec4\n" - "cogl_real_transform_layer%i (mat4 matrix, " - "vec4 tex_coord)\n" - "{\n" - " return matrix * tex_coord;\n" - "}\n", - layer_index); - - /* Wrap the layer code in any snippets that have been hooked */ - memset (&snippet_data, 0, sizeof (snippet_data)); - snippet_data.snippets = get_layer_vertex_snippets (layer); - snippet_data.hook = COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM; - snippet_data.chain_function = g_strdup_printf ("cogl_real_transform_layer%i", - layer_index); - snippet_data.final_name = g_strdup_printf ("cogl_transform_layer%i", - layer_index); - snippet_data.function_prefix = g_strdup_printf ("cogl_transform_layer%i", - layer_index); - snippet_data.return_type = "vec4"; - snippet_data.return_variable = "cogl_tex_coord"; - snippet_data.return_variable_is_argument = TRUE; - snippet_data.arguments = "cogl_matrix, cogl_tex_coord"; - snippet_data.argument_declarations = "mat4 cogl_matrix, vec4 cogl_tex_coord"; - snippet_data.source_buf = shader_state->header; - - _cogl_pipeline_snippet_generate_code (&snippet_data); - - g_free ((char *) snippet_data.chain_function); - g_free ((char *) snippet_data.final_name); - g_free ((char *) snippet_data.function_prefix); - - g_string_append_printf (shader_state->source, - " cogl_tex_coord%i_out = " - "cogl_transform_layer%i (cogl_texture_matrix%i,\n" - " " - " cogl_tex_coord%i_in);\n", - layer_index, - layer_index, - layer_index, - layer_index); - - return TRUE; -} - -static gboolean -_cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline, - unsigned long pipelines_difference) -{ - CoglPipelineVertendShaderState *shader_state; - - _COGL_GET_CONTEXT (ctx, FALSE); - - shader_state = get_shader_state (pipeline); - - if (shader_state->source) - { - const char *source_strings[2]; - GLint lengths[2]; - GLint compile_status; - GLuint shader; - CoglPipelineSnippetData snippet_data; - CoglPipelineSnippetList *vertex_snippets; - gboolean has_per_vertex_point_size = - cogl_pipeline_get_per_vertex_point_size (pipeline); - - COGL_STATIC_COUNTER (vertend_glsl_compile_counter, - "glsl vertex compile counter", - "Increments each time a new GLSL " - "vertex shader is compiled", - 0 /* no application private data */); - COGL_COUNTER_INC (_cogl_uprof_context, vertend_glsl_compile_counter); - - g_string_append (shader_state->header, - "void\n" - "cogl_real_vertex_transform ()\n" - "{\n" - " cogl_position_out = " - "cogl_modelview_projection_matrix * " - "cogl_position_in;\n" - "}\n"); - - g_string_append (shader_state->source, - " cogl_vertex_transform ();\n"); - - if (has_per_vertex_point_size) - { - g_string_append (shader_state->header, - "void\n" - "cogl_real_point_size_calculation ()\n" - "{\n" - " cogl_point_size_out = cogl_point_size_in;\n" - "}\n"); - g_string_append (shader_state->source, - " cogl_point_size_calculation ();\n"); - } - - g_string_append (shader_state->source, - " cogl_color_out = cogl_color_in;\n" - "}\n"); - - vertex_snippets = get_vertex_snippets (pipeline); - - /* Add hooks for the vertex transform part */ - memset (&snippet_data, 0, sizeof (snippet_data)); - snippet_data.snippets = vertex_snippets; - snippet_data.hook = COGL_SNIPPET_HOOK_VERTEX_TRANSFORM; - snippet_data.chain_function = "cogl_real_vertex_transform"; - snippet_data.final_name = "cogl_vertex_transform"; - snippet_data.function_prefix = "cogl_vertex_transform"; - snippet_data.source_buf = shader_state->header; - _cogl_pipeline_snippet_generate_code (&snippet_data); - - /* Add hooks for the point size calculation part */ - if (has_per_vertex_point_size) - { - memset (&snippet_data, 0, sizeof (snippet_data)); - snippet_data.snippets = vertex_snippets; - snippet_data.hook = COGL_SNIPPET_HOOK_POINT_SIZE; - snippet_data.chain_function = "cogl_real_point_size_calculation"; - snippet_data.final_name = "cogl_point_size_calculation"; - snippet_data.function_prefix = "cogl_point_size_calculation"; - snippet_data.source_buf = shader_state->header; - _cogl_pipeline_snippet_generate_code (&snippet_data); - } - - /* Add all of the hooks for vertex processing */ - memset (&snippet_data, 0, sizeof (snippet_data)); - snippet_data.snippets = vertex_snippets; - snippet_data.hook = COGL_SNIPPET_HOOK_VERTEX; - snippet_data.chain_function = "cogl_generated_source"; - snippet_data.final_name = "cogl_vertex_hook"; - snippet_data.function_prefix = "cogl_vertex_hook"; - snippet_data.source_buf = shader_state->source; - _cogl_pipeline_snippet_generate_code (&snippet_data); - - g_string_append (shader_state->source, - "void\n" - "main ()\n" - "{\n" - " cogl_vertex_hook ();\n"); - - /* If there are any snippets then we can't rely on the - projection matrix to flip the rendering for offscreen buffers - so we'll need to flip it using an extra statement and a - uniform */ - if (_cogl_pipeline_has_vertex_snippets (pipeline)) - { - g_string_append (shader_state->header, - "uniform vec4 _cogl_flip_vector;\n"); - g_string_append (shader_state->source, - " cogl_position_out *= _cogl_flip_vector;\n"); - } - - g_string_append (shader_state->source, - "}\n"); - - GE_RET( shader, ctx, glCreateShader (GL_VERTEX_SHADER) ); - - lengths[0] = shader_state->header->len; - source_strings[0] = shader_state->header->str; - lengths[1] = shader_state->source->len; - source_strings[1] = shader_state->source->str; - - _cogl_glsl_shader_set_source_with_boilerplate (ctx, - shader, GL_VERTEX_SHADER, - pipeline, - 2, /* count */ - source_strings, lengths); - - GE( ctx, glCompileShader (shader) ); - GE( ctx, glGetShaderiv (shader, GL_COMPILE_STATUS, &compile_status) ); - - if (!compile_status) - { - GLint len = 0; - char *shader_log; - - GE( ctx, glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &len) ); - shader_log = g_alloca (len); - GE( ctx, glGetShaderInfoLog (shader, len, &len, shader_log) ); - g_warning ("Shader compilation failed:\n%s", shader_log); - } - - shader_state->header = NULL; - shader_state->source = NULL; - shader_state->gl_shader = shader; - } - - return TRUE; -} - -static void -_cogl_pipeline_vertend_glsl_pre_change_notify (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if ((change & _cogl_pipeline_get_state_for_vertex_codegen (ctx))) - dirty_shader_state (pipeline); -} - -/* NB: layers are considered immutable once they have any dependants - * so although multiple pipelines can end up depending on a single - * static layer, we can guarantee that if a layer is being *changed* - * then it can only have one pipeline depending on it. - * - * XXX: Don't forget this is *pre* change, we can't read the new value - * yet! - */ -static void -_cogl_pipeline_vertend_glsl_layer_pre_change_notify ( - CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - CoglPipelineVertendShaderState *shader_state; - - shader_state = get_shader_state (owner); - if (!shader_state) - return; - - if ((change & COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN)) - { - dirty_shader_state (owner); - return; - } - - /* TODO: we could be saving snippets of texture combine code along - * with each layer and then when a layer changes we would just free - * the snippet. */ -} - -const CoglPipelineVertend _cogl_pipeline_glsl_vertend = - { - _cogl_pipeline_vertend_glsl_start, - _cogl_pipeline_vertend_glsl_add_layer, - _cogl_pipeline_vertend_glsl_end, - _cogl_pipeline_vertend_glsl_pre_change_notify, - _cogl_pipeline_vertend_glsl_layer_pre_change_notify - }; diff --git a/mutter/cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h b/mutter/cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h deleted file mode 100644 index 881bcf0..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-types.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-texture.h" - -void -_cogl_texture_2d_gl_free (CoglTexture2D *tex_2d); - -gboolean -_cogl_texture_2d_gl_can_create (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format); - -void -_cogl_texture_2d_gl_init (CoglTexture2D *tex_2d); - -gboolean -_cogl_texture_2d_gl_allocate (CoglTexture *tex, - GError **error); - -#if defined (HAVE_EGL) -gboolean -cogl_texture_2d_gl_bind_egl_image (CoglTexture2D *tex_2d, - EGLImageKHR image, - GError **error); -#endif - -#if defined (HAVE_EGL) && defined (EGL_KHR_image_base) -CoglTexture2D * -_cogl_egl_texture_2d_gl_new_from_image (CoglContext *ctx, - int width, - int height, - CoglPixelFormat format, - EGLImageKHR image, - GError **error); -#endif - -void -_cogl_texture_2d_gl_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter); - -void -_cogl_texture_2d_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t); - -void -_cogl_texture_2d_gl_copy_from_framebuffer (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglFramebuffer *src_fb, - int dst_x, - int dst_y, - int level); - -unsigned int -_cogl_texture_2d_gl_get_gl_handle (CoglTexture2D *tex_2d); - -void -_cogl_texture_2d_gl_generate_mipmap (CoglTexture2D *tex_2d); - -gboolean -_cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglBitmap *bitmap, - int dst_x, - int dst_y, - int level, - GError **error); - -gboolean -_cogl_texture_2d_gl_is_get_data_supported (CoglTexture2D *tex_2d); - -void -_cogl_texture_2d_gl_get_data (CoglTexture2D *tex_2d, - CoglPixelFormat format, - int rowstride, - uint8_t *data); diff --git a/mutter/cogl/cogl/driver/gl/cogl-texture-2d-gl.c b/mutter/cogl/cogl/driver/gl/cogl-texture-2d-gl.c deleted file mode 100644 index e2bb41c..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-texture-2d-gl.c +++ /dev/null @@ -1,656 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009,2010,2011,2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - * Robert Bragg - */ - -#include "config.h" - -#include - -#include "cogl/cogl-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-texture-2d-private.h" -#include "cogl/driver/gl/cogl-texture-2d-gl-private.h" -#include "cogl/driver/gl/cogl-texture-gl-private.h" -#include "cogl/driver/gl/cogl-pipeline-opengl-private.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" - -#if defined (HAVE_EGL) - -/* We need this define from GLES2, but can't include the header - as its type definitions may conflict with the GL ones - */ -#ifndef GL_OES_EGL_image_external -#define GL_OES_EGL_image_external 1 -#define GL_TEXTURE_EXTERNAL_OES 0x8D65 -#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 -#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 -#define GL_SAMPLER_EXTERNAL_OES 0x8D66 -#endif /* GL_OES_EGL_image_external */ - -#endif /* defined (HAVE_EGL) */ - -void -_cogl_texture_2d_gl_free (CoglTexture2D *tex_2d) -{ - if (tex_2d->gl_texture) - _cogl_delete_gl_texture (tex_2d->gl_texture); - -#if defined (HAVE_EGL) - g_clear_pointer (&tex_2d->egl_image_external.user_data, - tex_2d->egl_image_external.destroy); -#endif -} - -gboolean -_cogl_texture_2d_gl_can_create (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format) -{ - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - - /* We only support single plane formats for now */ - if (cogl_pixel_format_get_n_planes (internal_format) != 1) - return FALSE; - - ctx->driver_vtable->pixel_format_to_gl (ctx, - internal_format, - &gl_intformat, - &gl_format, - &gl_type); - - /* Check that the driver can create a texture with that size */ - if (!ctx->texture_driver->size_supported (ctx, - GL_TEXTURE_2D, - gl_intformat, - gl_format, - gl_type, - width, - height)) - return FALSE; - - return TRUE; -} - -void -_cogl_texture_2d_gl_init (CoglTexture2D *tex_2d) -{ - tex_2d->gl_texture = 0; - - /* We default to GL_LINEAR for both filters */ - tex_2d->gl_legacy_texobj_min_filter = GL_LINEAR; - tex_2d->gl_legacy_texobj_mag_filter = GL_LINEAR; - - /* Wrap mode not yet set */ - tex_2d->gl_legacy_texobj_wrap_mode_s = GL_FALSE; - tex_2d->gl_legacy_texobj_wrap_mode_t = GL_FALSE; - - tex_2d->egl_image_external.user_data = NULL; - tex_2d->egl_image_external.destroy = NULL; -} - -static gboolean -allocate_with_size (CoglTexture2D *tex_2d, - CoglTextureLoader *loader, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2d); - CoglPixelFormat internal_format; - int width = loader->src.sized.width; - int height = loader->src.sized.height; - CoglContext *ctx = cogl_texture_get_context (tex); - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - GLenum gl_texture; - - internal_format = - _cogl_texture_determine_internal_format (tex, loader->src.sized.format); - - if (!_cogl_texture_2d_gl_can_create (ctx, - width, - height, - internal_format)) - { - g_set_error_literal (error, COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_SIZE, - "Failed to create texture 2d due to size/format" - " constraints"); - return FALSE; - } - - ctx->driver_vtable->pixel_format_to_gl (ctx, - internal_format, - &gl_intformat, - &gl_format, - &gl_type); - - gl_texture = ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, internal_format); - - tex_2d->gl_internal_format = gl_intformat; - - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - gl_texture); - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glTexImage2D (GL_TEXTURE_2D, 0, gl_intformat, - width, height, 0, gl_format, gl_type, NULL); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - { - GE( ctx, glDeleteTextures (1, &gl_texture) ); - return FALSE; - } - - tex_2d->gl_texture = gl_texture; - tex_2d->gl_internal_format = gl_intformat; - - tex_2d->internal_format = internal_format; - - _cogl_texture_set_allocated (tex, internal_format, width, height); - - return TRUE; -} - -static gboolean -allocate_from_bitmap (CoglTexture2D *tex_2d, - CoglTextureLoader *loader, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2d); - CoglBitmap *bmp = loader->src.bitmap.bitmap; - CoglContext *ctx = _cogl_bitmap_get_context (bmp); - CoglPixelFormat internal_format; - int width = cogl_bitmap_get_width (bmp); - int height = cogl_bitmap_get_height (bmp); - CoglBitmap *upload_bmp; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - - internal_format = - _cogl_texture_determine_internal_format (tex, cogl_bitmap_get_format (bmp)); - - if (!_cogl_texture_2d_gl_can_create (ctx, - width, - height, - internal_format)) - { - g_set_error_literal (error, COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_SIZE, - "Failed to create texture 2d due to size/format" - " constraints"); - return FALSE; - } - - upload_bmp = _cogl_bitmap_convert_for_upload (bmp, - internal_format, - error); - if (upload_bmp == NULL) - return FALSE; - - ctx->driver_vtable->pixel_format_to_gl (ctx, - cogl_bitmap_get_format (upload_bmp), - NULL, /* internal format */ - &gl_format, - &gl_type); - ctx->driver_vtable->pixel_format_to_gl (ctx, - internal_format, - &gl_intformat, - NULL, - NULL); - - tex_2d->gl_texture = - ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, internal_format); - if (!ctx->texture_driver->upload_to_gl (ctx, - GL_TEXTURE_2D, - tex_2d->gl_texture, - upload_bmp, - gl_intformat, - gl_format, - gl_type, - error)) - { - g_object_unref (upload_bmp); - return FALSE; - } - - tex_2d->gl_internal_format = gl_intformat; - - g_object_unref (upload_bmp); - - tex_2d->internal_format = internal_format; - - _cogl_texture_set_allocated (tex, internal_format, width, height); - - return TRUE; -} - -#if defined (HAVE_EGL) && defined (EGL_KHR_image_base) -static gboolean -allocate_from_egl_image (CoglTexture2D *tex_2d, - CoglTextureLoader *loader, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2d); - CoglContext *ctx = cogl_texture_get_context (tex); - CoglPixelFormat internal_format = loader->src.egl_image.format; - - tex_2d->gl_texture = - ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, internal_format); - - if (!cogl_texture_2d_gl_bind_egl_image (tex_2d, - loader->src.egl_image.image, - error)) - { - GE( ctx, glDeleteTextures (1, &tex_2d->gl_texture) ); - return FALSE; - } - - tex_2d->internal_format = internal_format; - tex_2d->is_get_data_supported = - !(loader->src.egl_image.flags & COGL_EGL_IMAGE_FLAG_NO_GET_DATA); - - _cogl_texture_set_allocated (tex, - internal_format, - loader->src.egl_image.width, - loader->src.egl_image.height); - - return TRUE; -} -#endif - -#if defined (HAVE_EGL) -static gboolean -allocate_custom_egl_image_external (CoglTexture2D *tex_2d, - CoglTextureLoader *loader, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2d); - CoglContext *ctx = cogl_texture_get_context (tex); - CoglPixelFormat external_format; - CoglPixelFormat internal_format; - - external_format = loader->src.egl_image_external.format; - internal_format = _cogl_texture_determine_internal_format (tex, - external_format); - - _cogl_gl_util_clear_gl_errors (ctx); - - GE (ctx, glActiveTexture (GL_TEXTURE0)); - GE (ctx, glGenTextures (1, &tex_2d->gl_texture)); - - GE (ctx, glBindTexture (GL_TEXTURE_EXTERNAL_OES, - tex_2d->gl_texture)); - - if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR) - { - g_set_error_literal (error, - COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_BAD_PARAMETER, - "Could not create a CoglTexture2D from a given " - "EGLImage"); - GE( ctx, glDeleteTextures (1, &tex_2d->gl_texture) ); - return FALSE; - } - - GE (ctx, glTexParameteri(GL_TEXTURE_EXTERNAL_OES, - GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); - GE (ctx, glTexParameteri(GL_TEXTURE_EXTERNAL_OES, - GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); - - if (!loader->src.egl_image_external.alloc (tex_2d, - tex_2d->egl_image_external.user_data, - error)) - { - GE (ctx, glBindTexture (GL_TEXTURE_EXTERNAL_OES, 0)); - GE (ctx, glDeleteTextures (1, &tex_2d->gl_texture)); - return FALSE; - } - - GE (ctx, glBindTexture (GL_TEXTURE_EXTERNAL_OES, 0)); - - tex_2d->internal_format = internal_format; - tex_2d->gl_target = GL_TEXTURE_EXTERNAL_OES; - tex_2d->is_get_data_supported = FALSE; - - return TRUE; -} - -gboolean -cogl_texture_2d_gl_bind_egl_image (CoglTexture2D *tex_2d, - EGLImageKHR image, - GError **error) -{ - CoglContext *ctx = cogl_texture_get_context (COGL_TEXTURE (tex_2d)); - - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture); - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glEGLImageTargetTexture2D (GL_TEXTURE_2D, image); - if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR) - { - g_set_error_literal (error, - COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_BAD_PARAMETER, - "Could not bind the given EGLImage to a " - "CoglTexture2D"); - return FALSE; - } - - return TRUE; -} - -CoglTexture * -cogl_texture_2d_new_from_egl_image_external (CoglContext *ctx, - int width, - int height, - CoglTexture2DEGLImageExternalAlloc alloc, - gpointer user_data, - GDestroyNotify destroy, - GError **error) -{ - CoglTextureLoader *loader; - CoglTexture2D *tex_2d; - CoglPixelFormat internal_format = COGL_PIXEL_FORMAT_ANY; - - g_return_val_if_fail (_cogl_context_get_winsys (ctx)->constraints & - COGL_RENDERER_CONSTRAINT_USES_EGL, - NULL); - - g_return_val_if_fail (cogl_has_feature (ctx, - COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL), - NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE_EXTERNAL; - loader->src.egl_image_external.width = width; - loader->src.egl_image_external.height = height; - loader->src.egl_image_external.alloc = alloc; - loader->src.egl_image_external.format = internal_format; - - tex_2d = COGL_TEXTURE_2D (_cogl_texture_2d_create_base (ctx, width, height, - internal_format, loader)); - - - tex_2d->egl_image_external.user_data = user_data; - tex_2d->egl_image_external.destroy = destroy; - - return COGL_TEXTURE (tex_2d); -} -#endif /* defined (HAVE_EGL) */ - -gboolean -_cogl_texture_2d_gl_allocate (CoglTexture *tex, - GError **error) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - CoglTextureLoader *loader = cogl_texture_get_loader (tex); - - g_return_val_if_fail (loader, FALSE); - - switch (loader->src_type) - { - case COGL_TEXTURE_SOURCE_TYPE_SIZE: - return allocate_with_size (tex_2d, loader, error); - case COGL_TEXTURE_SOURCE_TYPE_BITMAP: - return allocate_from_bitmap (tex_2d, loader, error); - case COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE: -#if defined (HAVE_EGL) && defined (EGL_KHR_image_base) - return allocate_from_egl_image (tex_2d, loader, error); -#else - g_return_val_if_reached (FALSE); -#endif - case COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE_EXTERNAL: -#if defined (HAVE_EGL) - return allocate_custom_egl_image_external (tex_2d, loader, error); -#else - g_return_val_if_reached (FALSE); -#endif - } - - g_return_val_if_reached (FALSE); -} - -void -_cogl_texture_2d_gl_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - CoglContext *ctx = cogl_texture_get_context (tex); - - if (min_filter == tex_2d->gl_legacy_texobj_min_filter - && mag_filter == tex_2d->gl_legacy_texobj_mag_filter) - return; - - /* Store new values */ - tex_2d->gl_legacy_texobj_min_filter = min_filter; - tex_2d->gl_legacy_texobj_mag_filter = mag_filter; - - /* Apply new filters to the texture */ - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture); - GE( ctx, glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter) ); - GE( ctx, glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter) ); - - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_LOD_BIAS) && - min_filter != GL_NEAREST && - min_filter != GL_LINEAR) - { - GLfloat bias = _cogl_texture_min_filter_get_lod_bias (min_filter); - - GE (ctx, glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, bias)); - } -} - -void -_cogl_texture_2d_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - CoglContext *ctx = cogl_texture_get_context (tex); - - /* Only set the wrap mode if it's different from the current value - to avoid too many GL calls. Texture 2D doesn't make use of the r - coordinate so we can ignore its wrap mode */ - if (tex_2d->gl_legacy_texobj_wrap_mode_s != wrap_mode_s || - tex_2d->gl_legacy_texobj_wrap_mode_t != wrap_mode_t) - { - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture); - GE( ctx, glTexParameteri (GL_TEXTURE_2D, - GL_TEXTURE_WRAP_S, - wrap_mode_s) ); - GE( ctx, glTexParameteri (GL_TEXTURE_2D, - GL_TEXTURE_WRAP_T, - wrap_mode_t) ); - - tex_2d->gl_legacy_texobj_wrap_mode_s = wrap_mode_s; - tex_2d->gl_legacy_texobj_wrap_mode_t = wrap_mode_t; - } -} - -void -_cogl_texture_2d_gl_copy_from_framebuffer (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglFramebuffer *src_fb, - int dst_x, - int dst_y, - int level) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2d); - CoglContext *ctx = cogl_texture_get_context (tex); - - /* Make sure the current framebuffers are bound, though we don't need to - * flush the clip state here since we aren't going to draw to the - * framebuffer. */ - cogl_context_flush_framebuffer_state (ctx, - ctx->current_draw_buffer, - src_fb, - (COGL_FRAMEBUFFER_STATE_ALL & - ~COGL_FRAMEBUFFER_STATE_CLIP)); - - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture); - - ctx->glCopyTexSubImage2D (GL_TEXTURE_2D, - 0, /* level */ - dst_x, dst_y, - src_x, src_y, - width, height); -} - -unsigned int -_cogl_texture_2d_gl_get_gl_handle (CoglTexture2D *tex_2d) -{ - return tex_2d->gl_texture; -} - -void -_cogl_texture_2d_gl_generate_mipmap (CoglTexture2D *tex_2d) -{ - _cogl_texture_gl_generate_mipmaps (COGL_TEXTURE (tex_2d)); -} - -gboolean -_cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglBitmap *bmp, - int dst_x, - int dst_y, - int level, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2d); - CoglContext *ctx = cogl_texture_get_context (tex); - CoglBitmap *upload_bmp; - CoglPixelFormat upload_format; - GLenum gl_format; - GLenum gl_type; - gboolean status = TRUE; - - upload_bmp = - _cogl_bitmap_convert_for_upload (bmp, - _cogl_texture_get_format (tex), - error); - if (upload_bmp == NULL) - return FALSE; - - upload_format = cogl_bitmap_get_format (upload_bmp); - - /* Only support single plane formats */ - if (upload_format == COGL_PIXEL_FORMAT_ANY || - cogl_pixel_format_get_n_planes (upload_format) != 1) - return FALSE; - - ctx->driver_vtable->pixel_format_to_gl (ctx, - upload_format, - NULL, /* internal gl format */ - &gl_format, - &gl_type); - - if (cogl_texture_get_max_level_set (tex) < level) - cogl_texture_gl_set_max_level (tex, level); - - status = ctx->texture_driver->upload_subregion_to_gl (ctx, - tex, - src_x, src_y, - dst_x, dst_y, - width, height, - level, - upload_bmp, - gl_format, - gl_type, - error); - - g_object_unref (upload_bmp); - - return status; -} - -gboolean -_cogl_texture_2d_gl_is_get_data_supported (CoglTexture2D *tex_2d) -{ - return tex_2d->is_get_data_supported; -} - -void -_cogl_texture_2d_gl_get_data (CoglTexture2D *tex_2d, - CoglPixelFormat format, - int rowstride, - uint8_t *data) -{ - CoglContext *ctx = cogl_texture_get_context (COGL_TEXTURE (tex_2d)); - uint8_t bpp; - int width = cogl_texture_get_width (COGL_TEXTURE (tex_2d)); - GLenum gl_format; - GLenum gl_type; - - g_return_if_fail (format != COGL_PIXEL_FORMAT_ANY); - g_return_if_fail (cogl_pixel_format_get_n_planes (format) == 1); - - bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); - - ctx->driver_vtable->pixel_format_to_gl (ctx, - format, - NULL, /* internal format */ - &gl_format, - &gl_type); - - ctx->texture_driver->prep_gl_for_pixels_download (ctx, - rowstride, - width, - bpp); - - _cogl_bind_gl_texture_transient (tex_2d->gl_target, - tex_2d->gl_texture); - - ctx->texture_driver->gl_get_tex_image (ctx, - tex_2d->gl_target, - gl_format, - gl_type, - data); -} diff --git a/mutter/cogl/cogl/driver/gl/cogl-texture-gl-private.h b/mutter/cogl/cogl/driver/gl/cogl-texture-gl-private.h deleted file mode 100644 index 3c2c3c3..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-texture-gl-private.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#pragma once - -#include "cogl/cogl-context.h" - -void -_cogl_texture_gl_prep_alignment_for_pixels_upload (CoglContext *ctx, - int pixels_rowstride); - -void -_cogl_texture_gl_prep_alignment_for_pixels_download (CoglContext *ctx, - int bpp, - int width, - int rowstride); - -void -_cogl_texture_gl_flush_legacy_texobj_wrap_modes (CoglTexture *texture, - unsigned int wrap_mode_s, - unsigned int wrap_mode_t); - -void -_cogl_texture_gl_flush_legacy_texobj_filters (CoglTexture *texture, - unsigned int min_filter, - unsigned int mag_filter); - -void -cogl_texture_gl_set_max_level (CoglTexture *texture, - int max_level); - -void -_cogl_texture_gl_generate_mipmaps (CoglTexture *texture); - -GLenum -_cogl_texture_gl_get_format (CoglTexture *texture); - -static inline GLfloat -_cogl_texture_min_filter_get_lod_bias (GLenum min_filter) -{ - return (min_filter == GL_NEAREST_MIPMAP_NEAREST || - min_filter == GL_LINEAR_MIPMAP_NEAREST) ? -0.5f : 0.0f; -} diff --git a/mutter/cogl/cogl/driver/gl/cogl-texture-gl.c b/mutter/cogl/cogl/driver/gl/cogl-texture-gl.c deleted file mode 100644 index c90835d..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-texture-gl.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "config.h" - -#include - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-util.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" -#include "cogl/driver/gl/cogl-texture-gl-private.h" -#include "cogl/driver/gl/cogl-pipeline-opengl-private.h" - -static inline int -calculate_alignment (int rowstride) -{ - int alignment = 1 << (ffs (rowstride) - 1); - - return MIN (alignment, 8); -} - -void -_cogl_texture_gl_prep_alignment_for_pixels_upload (CoglContext *ctx, - int pixels_rowstride) -{ - GE( ctx, glPixelStorei (GL_UNPACK_ALIGNMENT, - calculate_alignment (pixels_rowstride)) ); -} - -void -_cogl_texture_gl_prep_alignment_for_pixels_download (CoglContext *ctx, - int bpp, - int width, - int rowstride) -{ - int alignment; - - /* If no padding is needed then we can always use an alignment of 1. - * We want to do this even though it is equivalent to the alignment - * of the rowstride because the Intel driver in Mesa currently has - * an optimisation when reading data into a PBO that only works if - * the alignment is exactly 1. - * - * https://bugs.freedesktop.org/show_bug.cgi?id=46632 - */ - - if (rowstride == bpp * width) - alignment = 1; - else - alignment = calculate_alignment (rowstride); - - GE( ctx, glPixelStorei (GL_PACK_ALIGNMENT, alignment) ); -} - -void -_cogl_texture_gl_flush_legacy_texobj_wrap_modes (CoglTexture *texture, - unsigned int wrap_mode_s, - unsigned int wrap_mode_t) -{ - COGL_TEXTURE_GET_CLASS (texture)->gl_flush_legacy_texobj_wrap_modes (texture, - wrap_mode_s, - wrap_mode_t); -} - -void -_cogl_texture_gl_flush_legacy_texobj_filters (CoglTexture *texture, - unsigned int min_filter, - unsigned int mag_filter) -{ - COGL_TEXTURE_GET_CLASS (texture)->gl_flush_legacy_texobj_filters (texture, - min_filter, - mag_filter); -} - -/* GL and GLES3 have this by default, but GLES2 does not except via extension. - * So really it's probably always available. Even if we used it and it wasn't - * available in some driver then there are no adverse consequences to the - * command simply being ignored... - */ -#ifndef GL_TEXTURE_MAX_LEVEL -#define GL_TEXTURE_MAX_LEVEL 0x813D -#endif - -void -cogl_texture_gl_set_max_level (CoglTexture *texture, - int max_level) -{ - CoglContext *ctx = cogl_texture_get_context (texture); - - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL)) - { - GLuint gl_handle; - GLenum gl_target; - - cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target); - - cogl_texture_set_max_level_set (texture, max_level); - - _cogl_bind_gl_texture_transient (gl_target, - gl_handle); - - GE( ctx, glTexParameteri (gl_target, - GL_TEXTURE_MAX_LEVEL, cogl_texture_get_max_level_set (texture))); - } -} - -void -_cogl_texture_gl_generate_mipmaps (CoglTexture *texture) -{ - CoglContext *ctx = cogl_texture_get_context (texture); - int n_levels = _cogl_texture_get_n_levels (texture); - GLuint gl_handle; - GLenum gl_target; - - if (cogl_texture_get_max_level_set (texture) != n_levels - 1) - cogl_texture_gl_set_max_level (texture, n_levels - 1); - - cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target); - - _cogl_bind_gl_texture_transient (gl_target, - gl_handle); - GE( ctx, glGenerateMipmap (gl_target) ); -} - -GLenum -_cogl_texture_gl_get_format (CoglTexture *texture) -{ - return COGL_TEXTURE_GET_CLASS (texture)->get_gl_format (texture); -} diff --git a/mutter/cogl/cogl/driver/gl/cogl-util-gl-private.h b/mutter/cogl/cogl/driver/gl/cogl-util-gl-private.h deleted file mode 100644 index 5e78d2b..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-util-gl-private.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012, 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-types.h" -#include "cogl/cogl-context.h" -#include "cogl/cogl-gl-header.h" -#include "cogl/cogl-texture.h" - -/* In OpenGL ES context, GL_CONTEXT_LOST has a _KHR prefix */ -#ifndef GL_CONTEXT_LOST -#define GL_CONTEXT_LOST GL_CONTEXT_LOST_KHR -#endif - -#ifdef COGL_GL_DEBUG - -const char * -_cogl_gl_error_to_string (GLenum error_code); - -#define GE(ctx, x) G_STMT_START { \ - GLenum __err; \ - (ctx)->x; \ - while ((__err = (ctx)->glGetError ()) != GL_NO_ERROR && __err != GL_CONTEXT_LOST) \ - { \ - g_warning ("%s: GL error (%d): %s\n", \ - G_STRLOC, \ - __err, \ - _cogl_gl_error_to_string (__err)); \ - } } G_STMT_END - -#define GE_RET(ret, ctx, x) G_STMT_START { \ - GLenum __err; \ - ret = (ctx)->x; \ - while ((__err = (ctx)->glGetError ()) != GL_NO_ERROR && __err != GL_CONTEXT_LOST) \ - { \ - g_warning ("%s: GL error (%d): %s\n", \ - G_STRLOC, \ - __err, \ - _cogl_gl_error_to_string (__err)); \ - } } G_STMT_END - -#else /* !COGL_GL_DEBUG */ - -#define GE(ctx, x) ((ctx)->x) -#define GE_RET(ret, ctx, x) (ret = ((ctx)->x)) - -#endif /* COGL_GL_DEBUG */ - -typedef struct _CoglGLContext { - GArray *texture_units; - int active_texture_unit; - - /* This is used for generated fake unique sampler object numbers - when the sampler object extension is not supported */ - GLuint next_fake_sampler_object_number; -} CoglGLContext; - -CoglGLContext * -_cogl_driver_gl_context (CoglContext *context); - -gboolean -_cogl_driver_gl_context_init (CoglContext *context); - -void -_cogl_driver_gl_context_deinit (CoglContext *context); - -void -_cogl_driver_gl_flush_framebuffer_state (CoglContext *context, - CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer, - CoglFramebufferState state); - -CoglFramebufferDriver * -_cogl_driver_gl_create_framebuffer_driver (CoglContext *context, - CoglFramebuffer *framebuffer, - const CoglFramebufferDriverConfig *driver_config, - GError **error); - -GLenum -_cogl_gl_util_get_error (CoglContext *ctx); - -void -_cogl_gl_util_clear_gl_errors (CoglContext *ctx); - -gboolean -_cogl_gl_util_catch_out_of_memory (CoglContext *ctx, GError **error); - -gboolean -_cogl_driver_gl_is_hardware_accelerated (CoglContext *context); - -/* - * _cogl_context_get_gl_extensions: - * @context: A CoglContext - * - * Return value: a NULL-terminated array of strings representing the - * supported extensions by the current driver. This array is owned - * by the caller and should be freed with g_strfreev(). - */ -char ** -_cogl_context_get_gl_extensions (CoglContext *context); - -const char * -_cogl_context_get_gl_version (CoglContext *context); - -/* Parses a GL version number stored in a string. @version_string must - * point to the beginning of the version number (ie, it can't point to - * the "OpenGL ES" part on GLES). The version number can be followed - * by the end of the string, a space or a full stop. Anything else - * will be treated as invalid. Returns TRUE and sets major_out and - * minor_out if it is successfully parsed or FALSE otherwise. */ -gboolean -_cogl_gl_util_parse_gl_version (const char *version_string, - int *major_out, - int *minor_out); - -CoglGraphicsResetStatus -_cogl_gl_get_graphics_reset_status (CoglContext *context); - -CoglTimestampQuery * -cogl_gl_create_timestamp_query (CoglContext *context); - -void -cogl_gl_free_timestamp_query (CoglContext *context, - CoglTimestampQuery *query); - -int64_t -cogl_gl_timestamp_query_get_time_ns (CoglContext *context, - CoglTimestampQuery *query); - -int64_t -cogl_gl_get_gpu_time_ns (CoglContext *context); - -#ifndef GL_FRAMEBUFFER -#define GL_FRAMEBUFFER 0x8D40 -#endif -#ifndef GL_RENDERBUFFER -#define GL_RENDERBUFFER 0x8D41 -#endif -#ifndef GL_STENCIL_ATTACHMENT -#define GL_STENCIL_ATTACHMENT 0x8D00 -#endif -#ifndef GL_COLOR_ATTACHMENT0 -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#endif -#ifndef GL_FRAMEBUFFER_COMPLETE -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#endif -#ifndef GL_STENCIL_INDEX8 -#define GL_STENCIL_INDEX8 0x8D48 -#endif -#ifndef GL_DEPTH_STENCIL -#define GL_DEPTH_STENCIL 0x84F9 -#endif -#ifndef GL_DEPTH24_STENCIL8 -#define GL_DEPTH24_STENCIL8 0x88F0 -#endif -#ifndef GL_DEPTH_ATTACHMENT -#define GL_DEPTH_ATTACHMENT 0x8D00 -#endif -#ifndef GL_DEPTH_STENCIL_ATTACHMENT -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#endif -#ifndef GL_DEPTH_COMPONENT16 -#define GL_DEPTH_COMPONENT16 0x81A5 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 -#endif -#ifndef GL_READ_FRAMEBUFFER -#define GL_READ_FRAMEBUFFER 0x8CA8 -#endif -#ifndef GL_DRAW_FRAMEBUFFER -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#endif -#ifndef GL_TEXTURE_SAMPLES_IMG -#define GL_TEXTURE_SAMPLES_IMG 0x9136 -#endif -#ifndef GL_PACK_INVERT_MESA -#define GL_PACK_INVERT_MESA 0x8758 -#endif -#ifndef GL_PACK_REVERSE_ROW_ORDER_ANGLE -#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 -#endif -#ifndef GL_BACK_LEFT -#define GL_BACK_LEFT 0x0402 -#endif -#ifndef GL_BACK_RIGHT -#define GL_BACK_RIGHT 0x0403 -#endif - -#ifndef GL_COLOR -#define GL_COLOR 0x1800 -#endif -#ifndef GL_DEPTH -#define GL_DEPTH 0x1801 -#endif -#ifndef GL_STENCIL -#define GL_STENCIL 0x1802 -#endif - -#ifndef GL_TIMESTAMP -#define GL_TIMESTAMP 0x8E28 -#endif -#ifndef GL_QUERY_RESULT -#define GL_QUERY_RESULT 0x8866 -#endif - -#ifndef GL_TEXTURE_LOD_BIAS -#define GL_TEXTURE_LOD_BIAS 0x8501 -#endif diff --git a/mutter/cogl/cogl/driver/gl/cogl-util-gl.c b/mutter/cogl/cogl/driver/gl/cogl-util-gl.c deleted file mode 100644 index b6ce928..0000000 --- a/mutter/cogl/cogl/driver/gl/cogl-util-gl.c +++ /dev/null @@ -1,566 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012, 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-types.h" -#include "cogl/cogl-context-private.h" -#include "cogl/driver/gl/cogl-framebuffer-gl-private.h" -#include "cogl/driver/gl/cogl-gl-framebuffer-fbo.h" -#include "cogl/driver/gl/cogl-gl-framebuffer-back.h" -#include "cogl/driver/gl/cogl-pipeline-opengl-private.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" - -/* This is a relatively new extension */ -#ifndef GL_PURGED_CONTEXT_RESET_NV -#define GL_PURGED_CONTEXT_RESET_NV 0x92BB -#endif - -/* These aren't defined in the GLES2 headers */ -#ifndef GL_GUILTY_CONTEXT_RESET_ARB -#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 -#endif - -#ifndef GL_INNOCENT_CONTEXT_RESET_ARB -#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 -#endif - -#ifndef GL_UNKNOWN_CONTEXT_RESET_ARB -#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 -#endif - -#ifdef COGL_GL_DEBUG -/* GL error to string conversion */ -static const struct { - GLuint error_code; - const char *error_string; -} gl_errors[] = { - { GL_NO_ERROR, "No error" }, - { GL_INVALID_ENUM, "Invalid enumeration value" }, - { GL_INVALID_VALUE, "Invalid value" }, - { GL_INVALID_OPERATION, "Invalid operation" }, -#ifdef HAVE_GL - { GL_STACK_OVERFLOW, "Stack overflow" }, - { GL_STACK_UNDERFLOW, "Stack underflow" }, -#endif - { GL_OUT_OF_MEMORY, "Out of memory" }, - -#ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT - { GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "Invalid framebuffer operation" } -#endif -}; - -static const unsigned int n_gl_errors = G_N_ELEMENTS (gl_errors); - -const char * -_cogl_gl_error_to_string (GLenum error_code) -{ - int i; - - for (i = 0; i < n_gl_errors; i++) - { - if (gl_errors[i].error_code == error_code) - return gl_errors[i].error_string; - } - - return "Unknown GL error"; -} -#endif /* COGL_GL_DEBUG */ - -CoglGLContext * -_cogl_driver_gl_context (CoglContext *context) -{ - return context->driver_context; -} - -gboolean -_cogl_driver_gl_context_init (CoglContext *context) -{ - CoglGLContext *gl_context; - - if (!context->driver_context) - context->driver_context = g_new0 (CoglGLContext, 1); - - gl_context = _cogl_driver_gl_context (context); - if (!gl_context) - return FALSE; - - gl_context->next_fake_sampler_object_number = 1; - gl_context->texture_units = - g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit)); - - /* See cogl-pipeline.c for more details about why we leave texture unit 1 - * active by default... */ - gl_context->active_texture_unit = 1; - GE (context, glActiveTexture (GL_TEXTURE1)); - - return TRUE; -} - -void -_cogl_driver_gl_context_deinit (CoglContext *context) -{ - _cogl_destroy_texture_units (context); - g_free (context->driver_context); -} - -CoglFramebufferDriver * -_cogl_driver_gl_create_framebuffer_driver (CoglContext *context, - CoglFramebuffer *framebuffer, - const CoglFramebufferDriverConfig *driver_config, - GError **error) -{ - g_return_val_if_fail (driver_config, NULL); - - switch (driver_config->type) - { - case COGL_FRAMEBUFFER_DRIVER_TYPE_FBO: - { - CoglGlFramebufferFbo *gl_framebuffer_fbo; - - gl_framebuffer_fbo = cogl_gl_framebuffer_fbo_new (framebuffer, - driver_config, - error); - if (!gl_framebuffer_fbo) - return NULL; - - return COGL_FRAMEBUFFER_DRIVER (gl_framebuffer_fbo); - } - case COGL_FRAMEBUFFER_DRIVER_TYPE_BACK: - { - CoglGlFramebufferBack *gl_framebuffer_back; - - gl_framebuffer_back = cogl_gl_framebuffer_back_new (framebuffer, - driver_config, - error); - if (!gl_framebuffer_back) - return NULL; - - return COGL_FRAMEBUFFER_DRIVER (gl_framebuffer_back); - } - } - - g_assert_not_reached (); - return NULL; -} - -void -_cogl_driver_gl_flush_framebuffer_state (CoglContext *ctx, - CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer, - CoglFramebufferState state) -{ - CoglGlFramebuffer *draw_gl_framebuffer; - CoglGlFramebuffer *read_gl_framebuffer; - unsigned long differences; - - /* We can assume that any state that has changed for the current - * framebuffer is different to the currently flushed value. */ - differences = ctx->current_draw_buffer_changes; - - /* Any state of the current framebuffer that hasn't already been - * flushed is assumed to be unknown so we will always flush that - * state if asked. */ - differences |= ~ctx->current_draw_buffer_state_flushed; - - /* We only need to consider the state we've been asked to flush */ - differences &= state; - - if (ctx->current_draw_buffer != draw_buffer) - { - /* If the previous draw buffer is NULL then we'll assume - everything has changed. This can happen if a framebuffer is - destroyed while it is the last flushed draw buffer. In that - case the framebuffer destructor will set - ctx->current_draw_buffer to NULL */ - if (ctx->current_draw_buffer == NULL) - differences |= state; - else - /* NB: we only need to compare the state we're being asked to flush - * and we don't need to compare the state we've already decided - * we will definitely flush... */ - differences |= _cogl_framebuffer_compare (ctx->current_draw_buffer, - draw_buffer, - state & ~differences); - - /* NB: we don't take a reference here, to avoid a circular - * reference. */ - ctx->current_draw_buffer = draw_buffer; - ctx->current_draw_buffer_state_flushed = 0; - } - - if (ctx->current_read_buffer != read_buffer && - state & COGL_FRAMEBUFFER_STATE_BIND) - { - differences |= COGL_FRAMEBUFFER_STATE_BIND; - /* NB: we don't take a reference here, to avoid a circular - * reference. */ - ctx->current_read_buffer = read_buffer; - } - - if (!differences) - return; - - /* Lazily ensure the framebuffers have been allocated */ - if (G_UNLIKELY (!cogl_framebuffer_is_allocated (draw_buffer))) - cogl_framebuffer_allocate (draw_buffer, NULL); - if (G_UNLIKELY (!cogl_framebuffer_is_allocated (read_buffer))) - cogl_framebuffer_allocate (read_buffer, NULL); - - draw_gl_framebuffer = - COGL_GL_FRAMEBUFFER (cogl_framebuffer_get_driver (draw_buffer)); - read_gl_framebuffer = - COGL_GL_FRAMEBUFFER (cogl_framebuffer_get_driver (read_buffer)); - - /* We handle buffer binding separately since the method depends on whether - * we are binding the same buffer for read and write or not unlike all - * other state that only relates to the draw_buffer. */ - if (differences & COGL_FRAMEBUFFER_STATE_BIND) - { - if (draw_buffer == read_buffer) - { - cogl_gl_framebuffer_bind (draw_gl_framebuffer, GL_FRAMEBUFFER); - } - else - { - /* NB: Currently we only take advantage of binding separate - * read/write buffers for framebuffer blit purposes. */ - g_return_if_fail (cogl_has_feature - (ctx, COGL_FEATURE_ID_BLIT_FRAMEBUFFER)); - - cogl_gl_framebuffer_bind (draw_gl_framebuffer, GL_DRAW_FRAMEBUFFER); - cogl_gl_framebuffer_bind (read_gl_framebuffer, GL_READ_FRAMEBUFFER); - } - - differences &= ~COGL_FRAMEBUFFER_STATE_BIND; - } - - cogl_gl_framebuffer_flush_state_differences (draw_gl_framebuffer, - differences); - - ctx->current_draw_buffer_state_flushed |= state; - ctx->current_draw_buffer_changes &= ~state; -} - -GLenum -_cogl_gl_util_get_error (CoglContext *ctx) -{ - GLenum gl_error = ctx->glGetError (); - - if (gl_error != GL_NO_ERROR && gl_error != GL_CONTEXT_LOST) - return gl_error; - else - return GL_NO_ERROR; -} - -void -_cogl_gl_util_clear_gl_errors (CoglContext *ctx) -{ - GLenum gl_error; - - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR && gl_error != GL_CONTEXT_LOST) - ; -} - -gboolean -_cogl_gl_util_catch_out_of_memory (CoglContext *ctx, GError **error) -{ - GLenum gl_error; - gboolean out_of_memory = FALSE; - - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR && gl_error != GL_CONTEXT_LOST) - { - if (gl_error == GL_OUT_OF_MEMORY) - out_of_memory = TRUE; -#ifdef COGL_GL_DEBUG - else - { - g_warning ("%s: GL error (%d): %s\n", - G_STRLOC, - gl_error, - _cogl_gl_error_to_string (gl_error)); - } -#endif - } - - if (out_of_memory) - { - g_set_error_literal (error, COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_NO_MEMORY, - "Out of memory"); - return TRUE; - } - - return FALSE; -} - -char ** -_cogl_context_get_gl_extensions (CoglContext *context) -{ - const char *env_disabled_extensions; - char **ret; - - /* In GL 3, querying GL_EXTENSIONS is deprecated so we have to build - * the array using glGetStringi instead */ -#ifdef HAVE_GL - if (context->driver == COGL_DRIVER_GL3) - { - int num_extensions, i; - - context->glGetIntegerv (GL_NUM_EXTENSIONS, &num_extensions); - - ret = g_malloc (sizeof (char *) * (num_extensions + 1)); - - for (i = 0; i < num_extensions; i++) - { - const char *ext = - (const char *) context->glGetStringi (GL_EXTENSIONS, i); - ret[i] = g_strdup (ext); - } - - ret[num_extensions] = NULL; - } - else -#endif - { - const char *all_extensions = - (const char *) context->glGetString (GL_EXTENSIONS); - - ret = g_strsplit (all_extensions, " ", 0 /* max tokens */); - } - - if ((env_disabled_extensions = g_getenv ("COGL_DISABLE_GL_EXTENSIONS"))) - { - char **split_env_disabled_extensions; - char **src, **dst; - - if (*env_disabled_extensions) - { - split_env_disabled_extensions = - g_strsplit (env_disabled_extensions, - ",", - 0 /* no max tokens */); - } - else - { - split_env_disabled_extensions = NULL; - } - - for (dst = ret, src = ret; - *src; - src++) - { - char **d; - - if (split_env_disabled_extensions) - for (d = split_env_disabled_extensions; *d; d++) - if (!strcmp (*src, *d)) - goto disabled; - - *(dst++) = *src; - continue; - - disabled: - g_free (*src); - continue; - } - - *dst = NULL; - - if (split_env_disabled_extensions) - g_strfreev (split_env_disabled_extensions); - } - - return ret; -} - -const char * -_cogl_context_get_gl_version (CoglContext *context) -{ - const char *version_override; - - if ((version_override = g_getenv ("COGL_OVERRIDE_GL_VERSION"))) - return version_override; - else - return (const char *) context->glGetString (GL_VERSION); - -} - -gboolean -_cogl_gl_util_parse_gl_version (const char *version_string, - int *major_out, - int *minor_out) -{ - const char *major_end, *minor_end; - int major = 0, minor = 0; - - /* Extract the major number */ - for (major_end = version_string; *major_end >= '0' - && *major_end <= '9'; major_end++) - major = (major * 10) + *major_end - '0'; - /* If there were no digits or the major number isn't followed by a - dot then it is invalid */ - if (major_end == version_string || *major_end != '.') - return FALSE; - - /* Extract the minor number */ - for (minor_end = major_end + 1; *minor_end >= '0' - && *minor_end <= '9'; minor_end++) - minor = (minor * 10) + *minor_end - '0'; - /* If there were no digits or there is an unexpected character then - it is invalid */ - if (minor_end == major_end + 1 - || (*minor_end && *minor_end != ' ' && *minor_end != '.')) - return FALSE; - - *major_out = major; - *minor_out = minor; - - return TRUE; -} - -/* - * This should arguably use something like GLX_MESA_query_renderer, but - * a) that's GLX-only, and you could add it to EGL too but - * b) that'd make this a winsys query when really it's not a property of - * the winsys but the renderer, and - * c) only Mesa really supports it anyway, and - * d) Mesa is the only software renderer of interest. - * - * So instead just check a list of known software renderer strings. - */ -gboolean -_cogl_driver_gl_is_hardware_accelerated (CoglContext *ctx) -{ - const char *renderer = (const char *) ctx->glGetString (GL_RENDERER); - gboolean software; - - if (!renderer) - { - g_warning ("OpenGL driver returned NULL as the renderer, " - "something is wrong"); - return TRUE; - } - - software = strstr (renderer, "llvmpipe") != NULL || - strstr (renderer, "softpipe") != NULL || - strstr (renderer, "software rasterizer") != NULL || - strstr (renderer, "Software Rasterizer") != NULL || - strstr (renderer, "SWR"); - - return !software; -} - -CoglGraphicsResetStatus -_cogl_gl_get_graphics_reset_status (CoglContext *context) -{ - if (!context->glGetGraphicsResetStatus) - return COGL_GRAPHICS_RESET_STATUS_NO_ERROR; - - switch (context->glGetGraphicsResetStatus ()) - { - case GL_GUILTY_CONTEXT_RESET_ARB: - return COGL_GRAPHICS_RESET_STATUS_GUILTY_CONTEXT_RESET; - - case GL_INNOCENT_CONTEXT_RESET_ARB: - return COGL_GRAPHICS_RESET_STATUS_INNOCENT_CONTEXT_RESET; - - case GL_UNKNOWN_CONTEXT_RESET_ARB: - return COGL_GRAPHICS_RESET_STATUS_UNKNOWN_CONTEXT_RESET; - - case GL_PURGED_CONTEXT_RESET_NV: - return COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET; - - default: - return COGL_GRAPHICS_RESET_STATUS_NO_ERROR; - } -} - -CoglTimestampQuery * -cogl_gl_create_timestamp_query (CoglContext *context) -{ - CoglTimestampQuery *query; - - g_return_val_if_fail (cogl_has_feature (context, - COGL_FEATURE_ID_TIMESTAMP_QUERY), - NULL); - - query = g_new0 (CoglTimestampQuery, 1); - - GE (context, glGenQueries (1, &query->id)); - GE (context, glQueryCounter (query->id, GL_TIMESTAMP)); - - /* Flush right away so GL knows about our timestamp query. - * - * E.g. the direct scanout path doesn't call SwapBuffers or any other - * glFlush-inducing operation, and skipping explicit glFlush here results in - * the timestamp query being placed at the point of glGetQueryObject much - * later, resulting in a GPU timestamp much later on in time. - */ - context->glFlush (); - - return query; -} - -void -cogl_gl_free_timestamp_query (CoglContext *context, - CoglTimestampQuery *query) -{ - GE (context, glDeleteQueries (1, &query->id)); - g_free (query); -} - -int64_t -cogl_gl_timestamp_query_get_time_ns (CoglContext *context, - CoglTimestampQuery *query) -{ - int64_t query_time_ns; - - GE (context, glGetQueryObjecti64v (query->id, - GL_QUERY_RESULT, - &query_time_ns)); - - return query_time_ns; -} - -int64_t -cogl_gl_get_gpu_time_ns (CoglContext *context) -{ - int64_t gpu_time_ns; - - g_return_val_if_fail (cogl_has_feature (context, - COGL_FEATURE_ID_TIMESTAMP_QUERY), - 0); - - GE (context, glGetInteger64v (GL_TIMESTAMP, &gpu_time_ns)); - return gpu_time_ns; -} diff --git a/mutter/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/mutter/cogl/cogl/driver/gl/gl/cogl-driver-gl.c deleted file mode 100644 index 84ddfce..0000000 --- a/mutter/cogl/cogl/driver/gl/gl/cogl-driver-gl.c +++ /dev/null @@ -1,597 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include - -#include "cogl/cogl-private.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-feature-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" -#include "cogl/driver/gl/cogl-framebuffer-gl-private.h" -#include "cogl/driver/gl/cogl-texture-2d-gl-private.h" -#include "cogl/driver/gl/cogl-attribute-gl-private.h" -#include "cogl/driver/gl/cogl-clip-stack-gl-private.h" -#include "cogl/driver/gl/cogl-buffer-gl-private.h" -#include "cogl/driver/gl/cogl-pipeline-opengl-private.h" - -static gboolean -_cogl_driver_gl_real_context_init (CoglContext *context) -{ - GLuint vertex_array; - - _cogl_driver_gl_context_init (context); - - /* In a forward compatible context, GL 3 doesn't support rendering - * using the default vertex array object. Cogl doesn't use vertex - * array objects yet so for now we just create a dummy array - * object that we will use as our own default object. Eventually - * it could be good to attach the vertex array objects to - * CoglPrimitives */ - context->glGenVertexArrays (1, &vertex_array); - context->glBindVertexArray (vertex_array); - - /* There's no enable for this in GLES2, it's always on */ - GE (context, glEnable (GL_PROGRAM_POINT_SIZE) ); - - return TRUE; -} - -static CoglPixelFormat -_cogl_driver_pixel_format_to_gl (CoglContext *context, - CoglPixelFormat format, - GLenum *out_glintformat, - GLenum *out_glformat, - GLenum *out_gltype) -{ - CoglPixelFormat required_format; - GLenum glintformat = 0; - GLenum glformat = 0; - GLenum gltype = 0; - - required_format = format; - - /* For a pixel format to be used as a framebuffer attachment the corresponding - * GL internal format must be color-renderable. - * - * GL core 3.1 - * The following base internal formats from table 3.11 are color-renderable: - * RED, RG, RGB, and RGBA. The sized internal formats from table 3.12 that - * have a color-renderable base internal format are also color-renderable. No - * other formats, including compressed internal formats, are color-renderable. - * - * All sized formats from table 3.12 have a color-renderable base internal - * format and are therefore color-renderable. - * - * Only a subset of those formats are required to be supported as - * color-renderable (3.8.1 Required Texture Formats). Notably absent from the - * required renderbuffer color formats are RGB8, RGB16F and GL_RGB10. They are - * required to be supported as texture-renderable though, so using those - * internal formats is okay but allocating a framebuffer with those formats - * might fail. - */ - - /* Find GL equivalents */ - switch (format) - { - case COGL_PIXEL_FORMAT_A_8: - /* The driver doesn't natively support alpha textures so we - * will use a red component texture with a swizzle to implement - * the texture */ - glintformat = GL_R8; - glformat = GL_RED; - gltype = GL_UNSIGNED_BYTE; - break; - case COGL_PIXEL_FORMAT_R_8: - glintformat = GL_R8; - glformat = GL_RED; - gltype = GL_UNSIGNED_BYTE; - break; - - case COGL_PIXEL_FORMAT_RG_88: - glintformat = GL_RG8; - glformat = GL_RG; - gltype = GL_UNSIGNED_BYTE; - break; - - case COGL_PIXEL_FORMAT_RGB_888: - glintformat = GL_RGBA8; - glformat = GL_RGB; - gltype = GL_UNSIGNED_BYTE; - break; - case COGL_PIXEL_FORMAT_BGR_888: - glintformat = GL_RGBA8; - glformat = GL_BGR; - gltype = GL_UNSIGNED_BYTE; - break; - case COGL_PIXEL_FORMAT_RGBX_8888: - glintformat = GL_RGB8; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_BYTE; - break; - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - glintformat = GL_RGBA8; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_BYTE; - break; - case COGL_PIXEL_FORMAT_BGRX_8888: - glintformat = GL_RGB8; - glformat = GL_BGRA; - gltype = GL_UNSIGNED_BYTE; - break; - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - glintformat = GL_RGBA8; - glformat = GL_BGRA; - gltype = GL_UNSIGNED_BYTE; - break; - - /* The following two types of channel ordering - * have no GL equivalent unless defined using - * system word byte ordering */ - case COGL_PIXEL_FORMAT_XRGB_8888: - glintformat = GL_RGB8; - glformat = GL_BGRA; -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - gltype = GL_UNSIGNED_INT_8_8_8_8; -#else - gltype = GL_UNSIGNED_INT_8_8_8_8_REV; -#endif - break; - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - glintformat = GL_RGBA8; - glformat = GL_BGRA; -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - gltype = GL_UNSIGNED_INT_8_8_8_8; -#else - gltype = GL_UNSIGNED_INT_8_8_8_8_REV; -#endif - break; - - case COGL_PIXEL_FORMAT_XBGR_8888: - glintformat = GL_RGB8; - glformat = GL_RGBA; -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - gltype = GL_UNSIGNED_INT_8_8_8_8; -#else - gltype = GL_UNSIGNED_INT_8_8_8_8_REV; -#endif - break; - case COGL_PIXEL_FORMAT_ABGR_8888: - case COGL_PIXEL_FORMAT_ABGR_8888_PRE: - glintformat = GL_RGBA8; - glformat = GL_RGBA; -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - gltype = GL_UNSIGNED_INT_8_8_8_8; -#else - gltype = GL_UNSIGNED_INT_8_8_8_8_REV; -#endif - break; - - case COGL_PIXEL_FORMAT_RGBA_1010102: - case COGL_PIXEL_FORMAT_RGBA_1010102_PRE: - glintformat = GL_RGB10_A2; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_INT_10_10_10_2; - break; - - case COGL_PIXEL_FORMAT_BGRA_1010102: - case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: - glintformat = GL_RGB10_A2; - glformat = GL_BGRA; - gltype = GL_UNSIGNED_INT_10_10_10_2; - break; - - case COGL_PIXEL_FORMAT_XBGR_2101010: - glintformat = GL_RGB10; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_INT_2_10_10_10_REV; - break; - case COGL_PIXEL_FORMAT_ABGR_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: - glintformat = GL_RGB10_A2; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_INT_2_10_10_10_REV; - break; - - case COGL_PIXEL_FORMAT_XRGB_2101010: - glintformat = GL_RGB10; - glformat = GL_BGRA; - gltype = GL_UNSIGNED_INT_2_10_10_10_REV; - break; - case COGL_PIXEL_FORMAT_ARGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: - glintformat = GL_RGB10_A2; - glformat = GL_BGRA; - gltype = GL_UNSIGNED_INT_2_10_10_10_REV; - break; - - /* The following three types of channel ordering - * are always defined using system word byte - * ordering (even according to GLES spec) */ - case COGL_PIXEL_FORMAT_RGB_565: - glintformat = GL_RGB; - glformat = GL_RGB; - gltype = GL_UNSIGNED_SHORT_5_6_5; - break; - case COGL_PIXEL_FORMAT_RGBA_4444: - case COGL_PIXEL_FORMAT_RGBA_4444_PRE: - glintformat = GL_RGBA4; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_SHORT_4_4_4_4; - break; - case COGL_PIXEL_FORMAT_RGBA_5551: - case COGL_PIXEL_FORMAT_RGBA_5551_PRE: - glintformat = GL_RGB5_A1; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_SHORT_5_5_5_1; - break; - - case COGL_PIXEL_FORMAT_RGBX_FP_16161616: - glintformat = GL_RGB16F; - glformat = GL_RGBA; - gltype = GL_HALF_FLOAT; - break; - case COGL_PIXEL_FORMAT_RGBA_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: - glintformat = GL_RGBA16F; - glformat = GL_RGBA; - gltype = GL_HALF_FLOAT; - break; - case COGL_PIXEL_FORMAT_BGRX_FP_16161616: - glintformat = GL_RGB16F; - glformat = GL_BGRA; - gltype = GL_HALF_FLOAT; - break; - case COGL_PIXEL_FORMAT_BGRA_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: - glintformat = GL_RGBA16F; - glformat = GL_BGRA; - gltype = GL_HALF_FLOAT; - break; - case COGL_PIXEL_FORMAT_ARGB_FP_16161616: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: - required_format = - _cogl_driver_pixel_format_to_gl (context, - COGL_PIXEL_FORMAT_RGBA_FP_16161616 | - (format & COGL_PREMULT_BIT), - &glintformat, - &glformat, - &gltype); - break; - case COGL_PIXEL_FORMAT_XRGB_FP_16161616: - case COGL_PIXEL_FORMAT_XBGR_FP_16161616: - required_format = - _cogl_driver_pixel_format_to_gl (context, - COGL_PIXEL_FORMAT_RGBX_FP_16161616, - &glintformat, - &glformat, - &gltype); - break; - - case COGL_PIXEL_FORMAT_RGBA_FP_32323232: - case COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE: - glintformat = GL_RGBA32F; - glformat = GL_RGBA; - gltype = GL_FLOAT; - break; - - case COGL_PIXEL_FORMAT_R_16: - glintformat = GL_R16; - glformat = GL_RED; - gltype = GL_UNSIGNED_SHORT; - break; - case COGL_PIXEL_FORMAT_RG_1616: - glintformat = GL_RG16; - glformat = GL_RG; - gltype = GL_UNSIGNED_SHORT; - break; - case COGL_PIXEL_FORMAT_RGBA_16161616: - case COGL_PIXEL_FORMAT_RGBA_16161616_PRE: - glintformat = GL_RGBA16; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_SHORT; - break; - - case COGL_PIXEL_FORMAT_DEPTH_16: - glintformat = GL_DEPTH_COMPONENT16; - glformat = GL_DEPTH_COMPONENT; - gltype = GL_UNSIGNED_SHORT; - break; - - case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: - glintformat = GL_DEPTH24_STENCIL8; - glformat = GL_DEPTH_STENCIL; - gltype = GL_UNSIGNED_INT_24_8; - break; - - case COGL_PIXEL_FORMAT_ANY: - case COGL_PIXEL_FORMAT_YUV: - g_assert_not_reached (); - break; - } - - /* All of the pixel formats are handled above so if this hits then - we've been given an invalid pixel format */ - g_assert (glformat != 0); - - if (out_glintformat != NULL) - *out_glintformat = glintformat; - if (out_glformat != NULL) - *out_glformat = glformat; - if (out_gltype != NULL) - *out_gltype = gltype; - - return required_format; -} - -static CoglPixelFormat -_cogl_driver_get_read_pixels_format (CoglContext *context, - CoglPixelFormat from, - CoglPixelFormat to, - GLenum *gl_format_out, - GLenum *gl_type_out) -{ - return _cogl_driver_pixel_format_to_gl (context, - to, - NULL, - gl_format_out, - gl_type_out); -} - -static gboolean -_cogl_get_gl_version (CoglContext *ctx, - int *major_out, - int *minor_out) -{ - const char *version_string; - - /* Get the OpenGL version number */ - if ((version_string = _cogl_context_get_gl_version (ctx)) == NULL) - return FALSE; - - return _cogl_gl_util_parse_gl_version (version_string, major_out, minor_out); -} - -static gboolean -check_gl_version (CoglContext *ctx, - char **gl_extensions, - GError **error) -{ - int major, minor; - - if (!_cogl_get_gl_version (ctx, &major, &minor)) - { - g_set_error (error, - COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_UNKNOWN_VERSION, - "The OpenGL version could not be determined"); - return FALSE; - } - - if (!COGL_CHECK_GL_VERSION (major, minor, 3, 1)) - { - g_set_error (error, - COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_INVALID_VERSION, - "OpenGL 3.1 or better is required"); - return FALSE; - } - - return TRUE; -} - -static gboolean -_cogl_driver_update_features (CoglContext *ctx, - GError **error) -{ - unsigned long private_features - [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)] = { 0 }; - char **gl_extensions; - const char *glsl_version; - int gl_major = 0, gl_minor = 0; - int i; - - /* We have to special case getting the pointer to the glGetString* - functions because we need to use them to determine what functions - we can expect */ - ctx->glGetString = - (void *) _cogl_renderer_get_proc_address (ctx->display->renderer, - "glGetString"); - ctx->glGetStringi = - (void *) _cogl_renderer_get_proc_address (ctx->display->renderer, - "glGetStringi"); - ctx->glGetIntegerv = - (void *) _cogl_renderer_get_proc_address (ctx->display->renderer, - "glGetIntegerv"); - - gl_extensions = _cogl_context_get_gl_extensions (ctx); - - if (!check_gl_version (ctx, gl_extensions, error)) - return FALSE; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WINSYS))) - { - char *all_extensions = g_strjoinv (" ", gl_extensions); - - COGL_NOTE (WINSYS, - "Checking features\n" - " GL_VENDOR: %s\n" - " GL_RENDERER: %s\n" - " GL_VERSION: %s\n" - " GL_EXTENSIONS: %s", - ctx->glGetString (GL_VENDOR), - ctx->glGetString (GL_RENDERER), - _cogl_context_get_gl_version (ctx), - all_extensions); - - g_free (all_extensions); - } - - _cogl_get_gl_version (ctx, &gl_major, &gl_minor); - - ctx->glsl_major = 1; - ctx->glsl_minor = 2; - ctx->glsl_version_to_use = 120; - - glsl_version = (char *)ctx->glGetString (GL_SHADING_LANGUAGE_VERSION); - _cogl_gl_util_parse_gl_version (glsl_version, - &ctx->glsl_major, - &ctx->glsl_minor); - - COGL_FLAGS_SET (ctx->features, - COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE); - - _cogl_feature_check_ext_functions (ctx, - gl_major, - gl_minor, - gl_extensions); - - if (_cogl_check_extension ("GL_MESA_pack_invert", gl_extensions)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_MESA_PACK_INVERT, TRUE); - - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS, - TRUE); - - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_BLIT_FRAMEBUFFER, TRUE); - - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_PBOS, TRUE); - - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_MAP_BUFFER_FOR_READ, TRUE); - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE); - - if (ctx->glEGLImageTargetTexture2D) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE, TRUE); - - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL, TRUE); - - if (ctx->glGenSamplers) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS, TRUE); - - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 3) || - _cogl_check_extension ("GL_ARB_texture_swizzle", gl_extensions) || - _cogl_check_extension ("GL_EXT_texture_swizzle", gl_extensions)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE, TRUE); - - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_STRIDE, TRUE); - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ANY_GL, TRUE); - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_FORMAT_CONVERSION, TRUE); - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS, TRUE); - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL, TRUE); - - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_TEXTURE_LOD_BIAS, TRUE); - - if (ctx->glFenceSync) - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_FENCE, TRUE); - - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_RG, TRUE); - - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_RGBA1010102, TRUE); - - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_HALF_FLOAT, TRUE); - - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_NORM16, TRUE); - - if (ctx->glGenQueries && ctx->glQueryCounter && ctx->glGetInteger64v) - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TIMESTAMP_QUERY, TRUE); - - /* Cache features */ - for (i = 0; i < G_N_ELEMENTS (private_features); i++) - ctx->private_features[i] |= private_features[i]; - - g_strfreev (gl_extensions); - - if (!COGL_FLAGS_GET (private_features, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE)) - { - g_set_error (error, - COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_NO_SUITABLE_DRIVER_FOUND, - "The GL_ARB_texture_swizzle extension is required " - "to use the GL3 driver"); - return FALSE; - } - - return TRUE; -} - -const CoglDriverVtable -_cogl_driver_gl = - { - _cogl_driver_gl_real_context_init, - _cogl_driver_gl_context_deinit, - _cogl_driver_gl_is_hardware_accelerated, - _cogl_gl_get_graphics_reset_status, - _cogl_driver_pixel_format_to_gl, - _cogl_driver_get_read_pixels_format, - _cogl_driver_update_features, - _cogl_driver_gl_create_framebuffer_driver, - _cogl_driver_gl_flush_framebuffer_state, - _cogl_texture_2d_gl_free, - _cogl_texture_2d_gl_can_create, - _cogl_texture_2d_gl_init, - _cogl_texture_2d_gl_allocate, - _cogl_texture_2d_gl_copy_from_framebuffer, - _cogl_texture_2d_gl_get_gl_handle, - _cogl_texture_2d_gl_generate_mipmap, - _cogl_texture_2d_gl_copy_from_bitmap, - _cogl_texture_2d_gl_is_get_data_supported, - _cogl_texture_2d_gl_get_data, - _cogl_gl_flush_attributes_state, - _cogl_clip_stack_gl_flush, - _cogl_buffer_gl_create, - _cogl_buffer_gl_destroy, - _cogl_buffer_gl_map_range, - _cogl_buffer_gl_unmap, - _cogl_buffer_gl_set_data, - _cogl_sampler_gl_init, - _cogl_sampler_gl_free, - _cogl_gl_set_uniform, /* XXX name is weird... */ - cogl_gl_create_timestamp_query, - cogl_gl_free_timestamp_query, - cogl_gl_timestamp_query_get_time_ns, - cogl_gl_get_gpu_time_ns, - }; diff --git a/mutter/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c b/mutter/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c deleted file mode 100644 index dd19d95..0000000 --- a/mutter/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Matthew Allum - * Neil Roberts - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-private.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-bitmap.h" -#include "cogl/cogl-bitmap-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-pipeline.h" -#include "cogl/cogl-context-private.h" -#include "cogl/driver/gl/cogl-pipeline-opengl-private.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" -#include "cogl/driver/gl/cogl-texture-gl-private.h" -#include "cogl/driver/gl/cogl-bitmap-gl-private.h" - -#include -#include -#include - -#ifndef GL_TEXTURE_SWIZZLE_RGBA -#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 -#endif - -static GLuint -_cogl_texture_driver_gen (CoglContext *ctx, - GLenum gl_target, - CoglPixelFormat internal_format) -{ - GLuint tex; - - GE (ctx, glGenTextures (1, &tex)); - - _cogl_bind_gl_texture_transient (gl_target, tex); - - switch (gl_target) - { - case GL_TEXTURE_2D: - /* In case automatic mipmap generation gets disabled for this - * texture but a minification filter depending on mipmap - * interpolation is selected then we initialize the max mipmap - * level to 0 so OpenGL will consider the texture storage to be - * "complete". - */ - GE( ctx, glTexParameteri (gl_target, GL_TEXTURE_MAX_LEVEL, 0)); - - /* GL_TEXTURE_MAG_FILTER defaults to GL_LINEAR, no need to set it */ - GE( ctx, glTexParameteri (gl_target, - GL_TEXTURE_MIN_FILTER, - GL_LINEAR) ); - break; - - case GL_TEXTURE_RECTANGLE_ARB: - /* Texture rectangles already default to GL_LINEAR so nothing - needs to be done */ - break; - - default: - g_assert_not_reached(); - } - - /* As the driver doesn't support alpha textures directly then we'll - * fake them by setting the swizzle parameters */ - if (internal_format == COGL_PIXEL_FORMAT_A_8 && - _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE)) - { - static const GLint red_swizzle[] = { GL_ZERO, GL_ZERO, GL_ZERO, GL_RED }; - - GE( ctx, glTexParameteriv (gl_target, - GL_TEXTURE_SWIZZLE_RGBA, - red_swizzle) ); - } - - return tex; -} - -/* OpenGL - unlike GLES - can upload a sub region of pixel data from a larger - * source buffer */ -static void -prep_gl_for_pixels_upload_full (CoglContext *ctx, - int pixels_rowstride, - int image_height, - int pixels_src_x, - int pixels_src_y, - int pixels_bpp) -{ - GE( ctx, glPixelStorei (GL_UNPACK_ROW_LENGTH, - pixels_rowstride / pixels_bpp) ); - - GE( ctx, glPixelStorei (GL_UNPACK_SKIP_PIXELS, pixels_src_x) ); - GE( ctx, glPixelStorei (GL_UNPACK_SKIP_ROWS, pixels_src_y) ); - - _cogl_texture_gl_prep_alignment_for_pixels_upload (ctx, pixels_rowstride); -} - -/* OpenGL - unlike GLES - can download pixel data into a sub region of - * a larger destination buffer */ -static void -prep_gl_for_pixels_download_full (CoglContext *ctx, - int image_width, - int pixels_rowstride, - int image_height, - int pixels_src_x, - int pixels_src_y, - int pixels_bpp) -{ - GE( ctx, glPixelStorei (GL_PACK_ROW_LENGTH, pixels_rowstride / pixels_bpp) ); - - GE( ctx, glPixelStorei (GL_PACK_SKIP_PIXELS, pixels_src_x) ); - GE( ctx, glPixelStorei (GL_PACK_SKIP_ROWS, pixels_src_y) ); - - _cogl_texture_gl_prep_alignment_for_pixels_download (ctx, - pixels_bpp, - image_width, - pixels_rowstride); -} - -static void -_cogl_texture_driver_prep_gl_for_pixels_download (CoglContext *ctx, - int image_width, - int pixels_rowstride, - int pixels_bpp) -{ - prep_gl_for_pixels_download_full (ctx, - pixels_rowstride, - image_width, - 0 /* image height */, - 0, 0, /* pixels_src_x/y */ - pixels_bpp); -} - -static gboolean -_cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, - CoglTexture *texture, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - int level, - CoglBitmap *source_bmp, - GLuint source_gl_format, - GLuint source_gl_type, - GError **error) -{ - GLenum gl_target; - GLuint gl_handle; - uint8_t *data; - CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp; - gboolean status = TRUE; - GError *internal_error = NULL; - int level_width; - int level_height; - - g_return_val_if_fail (source_format != COGL_PIXEL_FORMAT_ANY, FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (source_format) == 1, - FALSE); - - bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0); - cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target); - - data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0, &internal_error); - - /* NB: _cogl_bitmap_gl_bind() may return NULL when successful so we - * have to explicitly check the cogl error pointer to catch - * problems... */ - if (internal_error) - { - g_propagate_error (error, internal_error); - return FALSE; - } - - /* Setup gl alignment to match rowstride and top-left corner */ - prep_gl_for_pixels_upload_full (ctx, - cogl_bitmap_get_rowstride (source_bmp), - 0, - src_x, - src_y, - bpp); - - _cogl_bind_gl_texture_transient (gl_target, gl_handle); - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - _cogl_texture_get_level_size (texture, - level, - &level_width, - &level_height, - NULL); - - if (level_width == width && level_height == height) - { - /* GL gets upset if you use glTexSubImage2D to initialize the - * contents of a mipmap level so we make sure to use - * glTexImage2D if we are uploading a full mipmap level. - */ - ctx->glTexImage2D (gl_target, - level, - _cogl_texture_gl_get_format (texture), - width, - height, - 0, - source_gl_format, - source_gl_type, - data); - - } - else - { - /* GL gets upset if you use glTexSubImage2D to initialize the - * contents of a mipmap level so if this is the first time - * we've seen a request to upload to this level we call - * glTexImage2D first to assert that the storage for this - * level exists. - */ - if (cogl_texture_get_max_level_set (texture) < level) - { - ctx->glTexImage2D (gl_target, - level, - _cogl_texture_gl_get_format (texture), - level_width, - level_height, - 0, - source_gl_format, - source_gl_type, - NULL); - } - - ctx->glTexSubImage2D (gl_target, - level, - dst_x, dst_y, - width, height, - source_gl_format, - source_gl_type, - data); - } - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - status = FALSE; - - _cogl_bitmap_gl_unbind (source_bmp); - - return status; -} - -static gboolean -_cogl_texture_driver_upload_to_gl (CoglContext *ctx, - GLenum gl_target, - GLuint gl_handle, - CoglBitmap *source_bmp, - GLint internal_gl_format, - GLuint source_gl_format, - GLuint source_gl_type, - GError **error) -{ - uint8_t *data; - CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp; - gboolean status = TRUE; - GError *internal_error = NULL; - - g_return_val_if_fail (source_format != COGL_PIXEL_FORMAT_ANY, FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (source_format) == 1, - FALSE); - - bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0); - - data = _cogl_bitmap_gl_bind (source_bmp, - COGL_BUFFER_ACCESS_READ, - 0, /* hints */ - &internal_error); - - /* NB: _cogl_bitmap_gl_bind() may return NULL when successful so we - * have to explicitly check the cogl error pointer to catch - * problems... */ - if (internal_error) - { - g_propagate_error (error, internal_error); - return FALSE; - } - - /* Setup gl alignment to match rowstride and top-left corner */ - prep_gl_for_pixels_upload_full (ctx, - cogl_bitmap_get_rowstride (source_bmp), - 0, 0, 0, bpp); - - _cogl_bind_gl_texture_transient (gl_target, gl_handle); - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glTexImage2D (gl_target, 0, - internal_gl_format, - cogl_bitmap_get_width (source_bmp), - cogl_bitmap_get_height (source_bmp), - 0, - source_gl_format, - source_gl_type, - data); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - status = FALSE; - - _cogl_bitmap_gl_unbind (source_bmp); - - return status; -} - -static gboolean -_cogl_texture_driver_gl_get_tex_image (CoglContext *ctx, - GLenum gl_target, - GLenum dest_gl_format, - GLenum dest_gl_type, - uint8_t *dest) -{ - GE (ctx, glGetTexImage (gl_target, - 0, /* level */ - dest_gl_format, - dest_gl_type, - (GLvoid *)dest)); - return TRUE; -} - -static gboolean -_cogl_texture_driver_size_supported (CoglContext *ctx, - GLenum gl_target, - GLenum gl_intformat, - GLenum gl_format, - GLenum gl_type, - int width, - int height) -{ - GLenum proxy_target; - GLint new_width = 0; - - if (gl_target == GL_TEXTURE_2D) - proxy_target = GL_PROXY_TEXTURE_2D; - else if (gl_target == GL_TEXTURE_RECTANGLE_ARB) - proxy_target = GL_PROXY_TEXTURE_RECTANGLE_ARB; - else - /* Unknown target, assume it's not supported */ - return FALSE; - - /* Proxy texture allows for a quick check for supported size */ - GE( ctx, glTexImage2D (proxy_target, 0, gl_intformat, - width, height, 0 /* border */, - gl_format, gl_type, NULL) ); - - GE( ctx, glGetTexLevelParameteriv (proxy_target, 0, - GL_TEXTURE_WIDTH, &new_width) ); - - return new_width != 0; -} - -static gboolean -_cogl_texture_driver_upload_supported (CoglContext *ctx, - CoglPixelFormat format) -{ - switch (format) - { - case COGL_PIXEL_FORMAT_A_8: - case COGL_PIXEL_FORMAT_R_8: - case COGL_PIXEL_FORMAT_RG_88: - case COGL_PIXEL_FORMAT_BGRX_8888: - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - case COGL_PIXEL_FORMAT_RGB_888: - case COGL_PIXEL_FORMAT_BGR_888: - case COGL_PIXEL_FORMAT_RGBA_1010102: - case COGL_PIXEL_FORMAT_RGBA_1010102_PRE: - case COGL_PIXEL_FORMAT_BGRA_1010102: - case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: - case COGL_PIXEL_FORMAT_XBGR_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: - case COGL_PIXEL_FORMAT_XRGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: - case COGL_PIXEL_FORMAT_RGBX_8888: - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - case COGL_PIXEL_FORMAT_XRGB_8888: - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - case COGL_PIXEL_FORMAT_XBGR_8888: - case COGL_PIXEL_FORMAT_ABGR_8888: - case COGL_PIXEL_FORMAT_ABGR_8888_PRE: - case COGL_PIXEL_FORMAT_RGB_565: - case COGL_PIXEL_FORMAT_RGBA_4444: - case COGL_PIXEL_FORMAT_RGBA_4444_PRE: - case COGL_PIXEL_FORMAT_RGBA_5551: - case COGL_PIXEL_FORMAT_RGBA_5551_PRE: - case COGL_PIXEL_FORMAT_BGRX_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616: - case COGL_PIXEL_FORMAT_XRGB_FP_16161616: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616: - case COGL_PIXEL_FORMAT_XBGR_FP_16161616: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_RGBX_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_RGBA_FP_32323232: - case COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE: - case COGL_PIXEL_FORMAT_R_16: - case COGL_PIXEL_FORMAT_RG_1616: - case COGL_PIXEL_FORMAT_RGBA_16161616: - case COGL_PIXEL_FORMAT_RGBA_16161616_PRE: - return TRUE; - case COGL_PIXEL_FORMAT_DEPTH_16: - case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: - case COGL_PIXEL_FORMAT_ANY: - case COGL_PIXEL_FORMAT_YUV: - g_assert_not_reached (); - return FALSE; - } - - g_assert_not_reached (); - return FALSE; -} - -static CoglPixelFormat -_cogl_texture_driver_find_best_gl_get_data_format - (CoglContext *context, - CoglPixelFormat format, - GLenum *closest_gl_format, - GLenum *closest_gl_type) -{ - return context->driver_vtable->pixel_format_to_gl (context, - format, - NULL, /* don't need */ - closest_gl_format, - closest_gl_type); -} - -const CoglTextureDriver -_cogl_texture_driver_gl = - { - _cogl_texture_driver_gen, - _cogl_texture_driver_upload_subregion_to_gl, - _cogl_texture_driver_upload_to_gl, - _cogl_texture_driver_prep_gl_for_pixels_download, - _cogl_texture_driver_gl_get_tex_image, - _cogl_texture_driver_size_supported, - _cogl_texture_driver_upload_supported, - _cogl_texture_driver_find_best_gl_get_data_format - }; diff --git a/mutter/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/mutter/cogl/cogl/driver/gl/gles/cogl-driver-gles.c deleted file mode 100644 index 2931e8f..0000000 --- a/mutter/cogl/cogl/driver/gl/gles/cogl-driver-gles.c +++ /dev/null @@ -1,802 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-feature-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-private.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" -#include "cogl/driver/gl/cogl-framebuffer-gl-private.h" -#include "cogl/driver/gl/cogl-texture-2d-gl-private.h" -#include "cogl/driver/gl/cogl-attribute-gl-private.h" -#include "cogl/driver/gl/cogl-clip-stack-gl-private.h" -#include "cogl/driver/gl/cogl-buffer-gl-private.h" -#include "cogl/driver/gl/cogl-pipeline-opengl-private.h" - -#ifndef GL_UNSIGNED_INT_24_8 -#define GL_UNSIGNED_INT_24_8 0x84FA -#endif -#ifndef GL_DEPTH_STENCIL -#define GL_DEPTH_STENCIL 0x84F9 -#endif -#ifndef GL_RG -#define GL_RG 0x8227 -#endif -#ifndef GL_RGB8 -#define GL_RGB8 0x8051 -#endif -#ifndef GL_RGBA8 -#define GL_RGBA8 0x8058 -#endif -#ifndef GL_RGB10_A2 -#define GL_RGB10_A2 0x8059 -#endif -#ifndef GL_UNSIGNED_INT_2_10_10_10_REV -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#endif -#ifndef GL_RGBA16F -#define GL_RGBA16F 0x881A -#endif -#ifndef GL_RGBA32F -#define GL_RGBA32F 0x8814 -#endif -#ifndef GL_HALF_FLOAT -#define GL_HALF_FLOAT 0x140B -#endif -#ifndef GL_UNSIGNED_INT_2_10_10_10_REV -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#endif -#ifndef GL_R16 -#define GL_R16 0x822A -#endif -#ifndef GL_RG16 -#define GL_RG16 0x822C -#endif -#ifndef GL_RED -#define GL_RED 0x1903 -#endif -#ifndef GL_RGBA16 -#define GL_RGBA16 0x805B -#endif - -static CoglPixelFormat -_cogl_driver_pixel_format_to_gl (CoglContext *context, - CoglPixelFormat format, - GLenum *out_glintformat, - GLenum *out_glformat, - GLenum *out_gltype) -{ - CoglPixelFormat required_format; - GLenum glintformat; - GLenum glformat = 0; - GLenum gltype; - - required_format = format; - - /* For a pixel format to be used as a framebuffer attachment the corresponding - * GL internal format must be color-renderable. - * - * GLES 3.0: - * An internal format is color-renderable if it is one of the formats from ta- - * ble 3.13 noted as color-renderable or if it is unsized format RGBA or RGB - * - * Sized formats from table 3.13: - * R8, RG8, RGB8, RGB565, RGBA4, RGB5_A1, RGBA8, RGB10_A2, RGB10_A2UI, - * SRGB8_ALPHA8, R8I, R8UI, R16I, R16UI, R32I, R32UI, RG8I, RG8UI, RG16I, - * RG16UI, RG32I, RG32UI, RGBA8I, RGBA8UI, RGBA16I, RGBA16UI, RGBA32I, - * RGBA32UI - * - * GLES 2.0: - * Formats not listed in table 4.5, including compressed internal formats. are - * not color-, depth-, or stencil-renderable, no matter which components they - * contain. - * - * Sized formats from table 4.5: - * RGBA4, RGB5_A1, RGB565 - * - * More color-renderable formats from extensions: - * - * OES_rgb8_rgba8 - * adds RGB8, RGBA8 as color-renderable internal formats - * - * EXT_texture_format_BGRA8888 - * adds BGRA_EXT as internal and external color-renderable format - * - * EXT_color_buffer_half_float (requires OES_texture_half_float) - * adds R16F, RG16F (required EXT_texture_rg) and RGB16F, RGBA16F - * as internal color-renderable formats - * - * => We require GLES 2 + OES_rgb8_rgba8 or GLES 3 which gives us at least: - * RGB8, RGBA8, RGBA4, RGB5_A1, RGB565 - */ - - /* We try to use the exact matching GL format but if that's not possible - * because the driver doesn't support it, we fall back to the next best match - * by calling this function again. This works for all formats which are - * <= 8 bpc with any R, G, B, A channels because we require RGBA8888. - */ - - /* Find GL equivalents */ - switch (format) - { - case COGL_PIXEL_FORMAT_A_8: - glintformat = GL_ALPHA; - glformat = GL_ALPHA; - gltype = GL_UNSIGNED_BYTE; - break; - - case COGL_PIXEL_FORMAT_R_8: - glintformat = GL_LUMINANCE; - glformat = GL_LUMINANCE; - gltype = GL_UNSIGNED_BYTE; - break; - - case COGL_PIXEL_FORMAT_RG_88: - if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_RG)) - { - glintformat = GL_RG8_EXT; - glformat = GL_RG; - gltype = GL_UNSIGNED_BYTE; - } - else - { - required_format = - _cogl_driver_pixel_format_to_gl (context, - COGL_PIXEL_FORMAT_RGB_888, - &glintformat, - &glformat, - &gltype); - } - break; - - case COGL_PIXEL_FORMAT_RGB_888: - glintformat = GL_RGB8; - glformat = GL_RGB; - gltype = GL_UNSIGNED_BYTE; - break; - - case COGL_PIXEL_FORMAT_BGR_888: - required_format = - _cogl_driver_pixel_format_to_gl (context, - COGL_PIXEL_FORMAT_RGB_888, - &glintformat, - &glformat, - &gltype); - break; - - case COGL_PIXEL_FORMAT_R_16: - if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_NORM16)) - { - glintformat = GL_R16; - glformat = GL_RED; - gltype = GL_UNSIGNED_SHORT; - break; - } - else - { - g_assert_not_reached (); - } - break; - - case COGL_PIXEL_FORMAT_RG_1616: - if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_NORM16)) - { - /* NORM16 implies RG for GLES */ - g_assert (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_RG)); - glintformat = GL_RG16; - glformat = GL_RG; - gltype = GL_UNSIGNED_SHORT; - break; - } - else - { - g_assert_not_reached (); - } - break; - - case COGL_PIXEL_FORMAT_RGBA_16161616: - case COGL_PIXEL_FORMAT_RGBA_16161616_PRE: - if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_NORM16)) - { - glintformat = GL_RGBA16; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_SHORT; - break; - } - else - { - g_assert_not_reached (); - } - break; - - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - if (_cogl_has_private_feature - (context, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888)) - { - glintformat = GL_BGRA_EXT; - glformat = GL_BGRA_EXT; - gltype = GL_UNSIGNED_BYTE; - } - else - { - required_format = - _cogl_driver_pixel_format_to_gl (context, - COGL_PIXEL_FORMAT_RGBA_8888, - &glintformat, - &glformat, - &gltype); - } - break; - - case COGL_PIXEL_FORMAT_BGRX_8888: - case COGL_PIXEL_FORMAT_RGBX_8888: - case COGL_PIXEL_FORMAT_XRGB_8888: - case COGL_PIXEL_FORMAT_XBGR_8888: - required_format = - _cogl_driver_pixel_format_to_gl (context, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - &glintformat, - &glformat, - &gltype); - break; - - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - case COGL_PIXEL_FORMAT_ABGR_8888: - case COGL_PIXEL_FORMAT_ABGR_8888_PRE: - required_format = - _cogl_driver_pixel_format_to_gl (context, - COGL_PIXEL_FORMAT_RGBA_8888 | - (format & COGL_PREMULT_BIT), - &glintformat, - &glformat, - &gltype); - break; - - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - glintformat = GL_RGBA8; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_BYTE; - break; - - /* The following three types of channel ordering - * are always defined using system word byte - * ordering (even according to GLES spec) */ - case COGL_PIXEL_FORMAT_RGB_565: - glintformat = GL_RGB565; - glformat = GL_RGB; - gltype = GL_UNSIGNED_SHORT_5_6_5; - break; - - case COGL_PIXEL_FORMAT_RGBA_4444: - case COGL_PIXEL_FORMAT_RGBA_4444_PRE: - glintformat = GL_RGBA4; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_SHORT_4_4_4_4; - break; - - case COGL_PIXEL_FORMAT_RGBA_5551: - case COGL_PIXEL_FORMAT_RGBA_5551_PRE: - glintformat = GL_RGB5_A1; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_SHORT_5_5_5_1; - break; - - case COGL_PIXEL_FORMAT_ABGR_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_RGBA1010102)) - { - glintformat = GL_RGB10_A2; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_INT_2_10_10_10_REV; - break; - } - else -#endif - { - g_assert_not_reached (); - } - break; - - case COGL_PIXEL_FORMAT_RGBA_1010102: - case COGL_PIXEL_FORMAT_RGBA_1010102_PRE: - case COGL_PIXEL_FORMAT_BGRA_1010102: - case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: - case COGL_PIXEL_FORMAT_XBGR_2101010: - case COGL_PIXEL_FORMAT_XRGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: - required_format = - _cogl_driver_pixel_format_to_gl (context, - COGL_PIXEL_FORMAT_ABGR_2101010 | - (format & COGL_PREMULT_BIT), - &glintformat, - &glformat, - &gltype); - break; - - case COGL_PIXEL_FORMAT_RGBX_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: - if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_HALF_FLOAT)) - { - glintformat = GL_RGBA16F; - glformat = GL_RGBA; - gltype = GL_HALF_FLOAT; - } - else - { - g_assert_not_reached (); - } - break; - - case COGL_PIXEL_FORMAT_BGRX_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616: - case COGL_PIXEL_FORMAT_XRGB_FP_16161616: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616: - case COGL_PIXEL_FORMAT_XBGR_FP_16161616: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: - required_format = - _cogl_driver_pixel_format_to_gl (context, - COGL_PIXEL_FORMAT_RGBA_FP_16161616 | - (format & COGL_PREMULT_BIT), - &glintformat, - &glformat, - &gltype); - break; - - case COGL_PIXEL_FORMAT_RGBA_FP_32323232: - case COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE: - if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_HALF_FLOAT)) - { - glintformat = GL_RGBA32F; - glformat = GL_RGBA; - gltype = GL_FLOAT; - } - else - { - g_assert_not_reached (); - } - break; - - case COGL_PIXEL_FORMAT_DEPTH_16: - glintformat = GL_DEPTH_COMPONENT; - glformat = GL_DEPTH_COMPONENT; - gltype = GL_UNSIGNED_SHORT; - break; - - case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: - glintformat = GL_DEPTH_STENCIL; - glformat = GL_DEPTH_STENCIL; - gltype = GL_UNSIGNED_INT_24_8; - break; - - case COGL_PIXEL_FORMAT_ANY: - case COGL_PIXEL_FORMAT_YUV: - g_assert_not_reached (); - break; - } - - /* All of the pixel formats are handled above so if this hits then - we've been given an invalid pixel format */ - g_assert (glformat != 0); - - if (out_glintformat != NULL) - *out_glintformat = glintformat; - if (out_glformat != NULL) - *out_glformat = glformat; - if (out_gltype != NULL) - *out_gltype = gltype; - - return required_format; -} - -static CoglPixelFormat -_cogl_driver_get_read_pixels_format (CoglContext *context, - CoglPixelFormat from, - CoglPixelFormat to, - GLenum *gl_format_out, - GLenum *gl_type_out) -{ - CoglPixelFormat required_format = 0; - GLenum required_gl_format = 0; - GLenum required_gl_type = 0; - CoglPixelFormat to_required_format; - GLenum to_gl_format; - GLenum to_gl_type; - - switch (from) - { - /* fixed point normalized */ - case COGL_PIXEL_FORMAT_A_8: - case COGL_PIXEL_FORMAT_R_8: - case COGL_PIXEL_FORMAT_RG_88: - case COGL_PIXEL_FORMAT_RGB_888: - case COGL_PIXEL_FORMAT_BGR_888: - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - case COGL_PIXEL_FORMAT_BGRX_8888: - case COGL_PIXEL_FORMAT_RGBX_8888: - case COGL_PIXEL_FORMAT_XRGB_8888: - case COGL_PIXEL_FORMAT_XBGR_8888: - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - case COGL_PIXEL_FORMAT_ABGR_8888: - case COGL_PIXEL_FORMAT_ABGR_8888_PRE: - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - case COGL_PIXEL_FORMAT_RGB_565: - case COGL_PIXEL_FORMAT_RGBA_4444: - case COGL_PIXEL_FORMAT_RGBA_4444_PRE: - case COGL_PIXEL_FORMAT_RGBA_5551: - case COGL_PIXEL_FORMAT_RGBA_5551_PRE: - required_gl_format = GL_RGBA; - required_gl_type = GL_UNSIGNED_BYTE; - required_format = COGL_PIXEL_FORMAT_RGBA_8888; - break; - - /* fixed point normalized, 10bpc special case */ - case COGL_PIXEL_FORMAT_ABGR_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: - case COGL_PIXEL_FORMAT_RGBA_1010102: - case COGL_PIXEL_FORMAT_RGBA_1010102_PRE: - case COGL_PIXEL_FORMAT_BGRA_1010102: - case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: - case COGL_PIXEL_FORMAT_XBGR_2101010: - case COGL_PIXEL_FORMAT_XRGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: - required_gl_format = GL_RGBA; - required_gl_type = GL_UNSIGNED_INT_2_10_10_10_REV; - required_format = COGL_PIXEL_FORMAT_ABGR_2101010; - break; - - /* floating point */ - case COGL_PIXEL_FORMAT_RGBX_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_BGRX_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616: - case COGL_PIXEL_FORMAT_XRGB_FP_16161616: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616: - case COGL_PIXEL_FORMAT_XBGR_FP_16161616: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_RGBA_FP_32323232: - case COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE: - required_gl_format = GL_RGBA; - required_gl_type = GL_FLOAT; - required_format = COGL_PIXEL_FORMAT_RGBA_FP_32323232; - break; - - /* fixed point normalized 16bpc */ - case COGL_PIXEL_FORMAT_R_16: - case COGL_PIXEL_FORMAT_RG_1616: - case COGL_PIXEL_FORMAT_RGBA_16161616: - case COGL_PIXEL_FORMAT_RGBA_16161616_PRE: - required_gl_format = GL_RGBA; - required_gl_type = GL_UNSIGNED_SHORT; - required_format = COGL_PIXEL_FORMAT_RGBA_16161616; - break; - - case COGL_PIXEL_FORMAT_DEPTH_16: - case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: - case COGL_PIXEL_FORMAT_ANY: - case COGL_PIXEL_FORMAT_YUV: - g_assert_not_reached (); - break; - } - - g_assert (required_format != 0); - - to_required_format = _cogl_driver_pixel_format_to_gl (context, - to, - NULL, - &to_gl_format, - &to_gl_type); - - *gl_format_out = required_gl_format; - *gl_type_out = required_gl_type; - - if (to_required_format != to || - to_gl_format != required_gl_format || - to_gl_type != required_gl_type) - return required_format; - - return to_required_format; -} - -static gboolean -_cogl_get_gl_version (CoglContext *ctx, - int *major_out, - int *minor_out) -{ - const char *version_string; - - /* Get the OpenGL version number */ - if ((version_string = _cogl_context_get_gl_version (ctx)) == NULL) - return FALSE; - - if (!g_str_has_prefix (version_string, "OpenGL ES ")) - return FALSE; - - return _cogl_gl_util_parse_gl_version (version_string + 10, - major_out, - minor_out); -} - -static gboolean -_cogl_driver_update_features (CoglContext *context, - GError **error) -{ - unsigned long private_features - [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)] = { 0 }; - char **gl_extensions; - int gl_major, gl_minor; - int i; - - /* We have to special case getting the pointer to the glGetString - function because we need to use it to determine what functions we - can expect */ - context->glGetString = - (void *) _cogl_renderer_get_proc_address (context->display->renderer, - "glGetString"); - context->glGetStringi = - (void *) _cogl_renderer_get_proc_address (context->display->renderer, - "glGetStringi"); - - gl_extensions = _cogl_context_get_gl_extensions (context); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WINSYS))) - { - char *all_extensions = g_strjoinv (" ", gl_extensions); - - COGL_NOTE (WINSYS, - "Checking features\n" - " GL_VENDOR: %s\n" - " GL_RENDERER: %s\n" - " GL_VERSION: %s\n" - " GL_EXTENSIONS: %s", - context->glGetString (GL_VENDOR), - context->glGetString (GL_RENDERER), - _cogl_context_get_gl_version (context), - all_extensions); - - g_free (all_extensions); - } - - context->glsl_major = 1; - context->glsl_minor = 0; - context->glsl_version_to_use = 100; - - if (!_cogl_get_gl_version (context, &gl_major, &gl_minor)) - { - gl_major = 1; - gl_minor = 1; - } - - if (!COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0)) - { - g_set_error (error, - COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_INVALID_VERSION, - "OpenGL ES 2.0 or better is required"); - g_strfreev (gl_extensions); - return FALSE; - } - - _cogl_feature_check_ext_functions (context, - gl_major, - gl_minor, - gl_extensions); - - if (!_cogl_check_extension ("GL_OES_rgb8_rgba8", gl_extensions) && - !COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 0)) - { - g_set_error (error, - COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_INVALID_VERSION, - "GL_OES_rgb8_rgba8 is required for GLES 2"); - g_strfreev (gl_extensions); - return FALSE; - } - - if (_cogl_check_extension ("GL_ANGLE_pack_reverse_row_order", gl_extensions)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_MESA_PACK_INVERT, TRUE); - - /* Note GLES 2 core doesn't support mipmaps for npot textures or - * repeat modes other than CLAMP_TO_EDGE. */ - - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ANY_GL, TRUE); - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES, TRUE); - - if (context->glGenSamplers) - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS, TRUE); - - if (context->glBlitFramebuffer) - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_BLIT_FRAMEBUFFER, TRUE); - - if (_cogl_check_extension ("GL_OES_element_index_uint", gl_extensions)) - { - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE); - } - - if (context->glMapBuffer) - { - /* The GL_OES_mapbuffer extension doesn't support mapping for - read */ - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE); - } - - if (context->glMapBufferRange) - { - /* MapBufferRange in ES3+ does support mapping for read */ - COGL_FLAGS_SET(context->features, - COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE); - COGL_FLAGS_SET(context->features, - COGL_FEATURE_ID_MAP_BUFFER_FOR_READ, TRUE); - } - - if (context->glEGLImageTargetTexture2D) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE, TRUE); - - if (_cogl_check_extension ("GL_OES_packed_depth_stencil", gl_extensions)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL, TRUE); - - if (_cogl_check_extension ("GL_EXT_texture_format_BGRA8888", gl_extensions)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888, TRUE); - -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 0)) - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_TEXTURE_RGBA1010102, TRUE); -#endif - - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 2) || - (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 0) && - _cogl_check_extension ("GL_OES_texture_half_float", gl_extensions) && - _cogl_check_extension ("GL_EXT_color_buffer_half_float", gl_extensions))) - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_TEXTURE_HALF_FLOAT, TRUE); - - if (_cogl_check_extension ("GL_EXT_unpack_subimage", gl_extensions)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE, TRUE); - - /* A nameless vendor implemented the extension, but got the case wrong - * per the spec. */ - if (_cogl_check_extension ("GL_OES_EGL_sync", gl_extensions) || - _cogl_check_extension ("GL_OES_egl_sync", gl_extensions)) - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_OES_EGL_SYNC, TRUE); - -#ifdef GL_ARB_sync - if (context->glFenceSync) - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_FENCE, TRUE); -#endif - - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 0) || - _cogl_check_extension ("GL_EXT_texture_rg", gl_extensions)) - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_TEXTURE_RG, - TRUE); - - if (_cogl_check_extension ("GL_EXT_texture_lod_bias", gl_extensions)) - { - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_TEXTURE_LOD_BIAS, TRUE); - } - - if (context->glGenQueries && context->glQueryCounter && context->glGetInteger64v) - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_TIMESTAMP_QUERY, TRUE); - - if (!g_strcmp0 ((char *) context->glGetString (GL_RENDERER), "Mali-400 MP")) - { - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_QUIRK_GENERATE_MIPMAP_NEEDS_FLUSH, - TRUE); - } - - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 1) && - _cogl_check_extension ("GL_EXT_texture_norm16", gl_extensions)) - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_TEXTURE_NORM16, - TRUE); - - /* Cache features */ - for (i = 0; i < G_N_ELEMENTS (private_features); i++) - context->private_features[i] |= private_features[i]; - - g_strfreev (gl_extensions); - - return TRUE; -} - -static gboolean -_cogl_driver_texture_2d_is_get_data_supported (CoglTexture2D *tex_2d) -{ - return FALSE; -} - -const CoglDriverVtable -_cogl_driver_gles = - { - _cogl_driver_gl_context_init, - _cogl_driver_gl_context_deinit, - _cogl_driver_gl_is_hardware_accelerated, - _cogl_gl_get_graphics_reset_status, - _cogl_driver_pixel_format_to_gl, - _cogl_driver_get_read_pixels_format, - _cogl_driver_update_features, - _cogl_driver_gl_create_framebuffer_driver, - _cogl_driver_gl_flush_framebuffer_state, - _cogl_texture_2d_gl_free, - _cogl_texture_2d_gl_can_create, - _cogl_texture_2d_gl_init, - _cogl_texture_2d_gl_allocate, - _cogl_texture_2d_gl_copy_from_framebuffer, - _cogl_texture_2d_gl_get_gl_handle, - _cogl_texture_2d_gl_generate_mipmap, - _cogl_texture_2d_gl_copy_from_bitmap, - _cogl_driver_texture_2d_is_get_data_supported, - NULL, /* texture_2d_get_data */ - _cogl_gl_flush_attributes_state, - _cogl_clip_stack_gl_flush, - _cogl_buffer_gl_create, - _cogl_buffer_gl_destroy, - _cogl_buffer_gl_map_range, - _cogl_buffer_gl_unmap, - _cogl_buffer_gl_set_data, - _cogl_sampler_gl_init, - _cogl_sampler_gl_free, - _cogl_gl_set_uniform, - cogl_gl_create_timestamp_query, - cogl_gl_free_timestamp_query, - cogl_gl_timestamp_query_get_time_ns, - cogl_gl_get_gpu_time_ns, - }; diff --git a/mutter/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c b/mutter/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c deleted file mode 100644 index 72d8155..0000000 --- a/mutter/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c +++ /dev/null @@ -1,555 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Matthew Allum - * Neil Roberts - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-private.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-bitmap.h" -#include "cogl/cogl-bitmap-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-pipeline.h" -#include "cogl/cogl-context-private.h" -#include "cogl/driver/gl/cogl-pipeline-opengl-private.h" -#include "cogl/driver/gl/cogl-util-gl-private.h" -#include "cogl/driver/gl/cogl-texture-gl-private.h" -#include "cogl/driver/gl/cogl-bitmap-gl-private.h" - -#include -#include -#include - -#ifndef GL_TEXTURE_3D -#define GL_TEXTURE_3D 0x806F -#endif -#ifndef GL_MAX_3D_TEXTURE_SIZE_OES -#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 -#endif - -/* This extension isn't available for GLES 1.1 so these won't be - defined */ -#ifndef GL_UNPACK_ROW_LENGTH -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#endif -#ifndef GL_UNPACK_SKIP_ROWS -#define GL_UNPACK_SKIP_ROWS 0x0CF3 -#endif -#ifndef GL_UNPACK_SKIP_PIXELS -#define GL_UNPACK_SKIP_PIXELS 0x0CF4 -#endif - -static GLuint -_cogl_texture_driver_gen (CoglContext *ctx, - GLenum gl_target, - CoglPixelFormat internal_format) -{ - GLuint tex; - - GE (ctx, glGenTextures (1, &tex)); - - _cogl_bind_gl_texture_transient (gl_target, tex); - - switch (gl_target) - { - case GL_TEXTURE_2D: - case GL_TEXTURE_3D: - /* GL_TEXTURE_MAG_FILTER defaults to GL_LINEAR, no need to set it */ - GE( ctx, glTexParameteri (gl_target, - GL_TEXTURE_MIN_FILTER, - GL_LINEAR) ); - break; - - default: - g_assert_not_reached(); - } - - return tex; -} - -static void -prep_gl_for_pixels_upload_full (CoglContext *ctx, - int pixels_rowstride, - int pixels_src_x, - int pixels_src_y, - int pixels_bpp) -{ - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE)) - { - GE( ctx, glPixelStorei (GL_UNPACK_ROW_LENGTH, - pixels_rowstride / pixels_bpp) ); - - GE( ctx, glPixelStorei (GL_UNPACK_SKIP_PIXELS, pixels_src_x) ); - GE( ctx, glPixelStorei (GL_UNPACK_SKIP_ROWS, pixels_src_y) ); - } - else - { - g_assert (pixels_src_x == 0); - g_assert (pixels_src_y == 0); - } - - _cogl_texture_gl_prep_alignment_for_pixels_upload (ctx, pixels_rowstride); -} - -static void -_cogl_texture_driver_prep_gl_for_pixels_upload (CoglContext *ctx, - int pixels_rowstride, - int pixels_bpp) -{ - prep_gl_for_pixels_upload_full (ctx, - pixels_rowstride, - 0, 0, /* src_x/y */ - pixels_bpp); -} - -static void -_cogl_texture_driver_prep_gl_for_pixels_download (CoglContext *ctx, - int pixels_rowstride, - int image_width, - int pixels_bpp) -{ - _cogl_texture_gl_prep_alignment_for_pixels_download (ctx, - pixels_bpp, - image_width, - pixels_rowstride); -} - -static CoglBitmap * -prepare_bitmap_alignment_for_upload (CoglContext *ctx, - CoglBitmap *src_bmp, - GError **error) -{ - CoglPixelFormat format = cogl_bitmap_get_format (src_bmp); - int bpp; - int src_rowstride = cogl_bitmap_get_rowstride (src_bmp); - int width = cogl_bitmap_get_width (src_bmp); - int alignment = 1; - - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); - - bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); - - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE) || - src_rowstride == 0) - return g_object_ref (src_bmp); - - /* Work out the alignment of the source rowstride */ - alignment = 1 << (ffs (src_rowstride) - 1); - alignment = MIN (alignment, 8); - - /* If the aligned data equals the rowstride then we can upload from - the bitmap directly using GL_UNPACK_ALIGNMENT */ - if (((width * bpp + alignment - 1) & ~(alignment - 1)) == src_rowstride) - return g_object_ref (src_bmp); - /* Otherwise we need to copy the bitmap to pack the alignment - because GLES has no GL_ROW_LENGTH */ - else - return _cogl_bitmap_copy (src_bmp, error); -} - -static gboolean -_cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, - CoglTexture *texture, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - int level, - CoglBitmap *source_bmp, - GLuint source_gl_format, - GLuint source_gl_type, - GError **error) -{ - GLenum gl_target; - GLuint gl_handle; - uint8_t *data; - CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp; - CoglBitmap *slice_bmp; - int rowstride; - gboolean status = TRUE; - GError *internal_error = NULL; - int level_width; - int level_height; - - g_return_val_if_fail (source_format != COGL_PIXEL_FORMAT_ANY, FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (source_format) == 1, - FALSE); - - bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0); - - cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target); - - /* If we have the GL_EXT_unpack_subimage extension then we can - upload from subregions directly. Otherwise we may need to copy - the bitmap */ - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE) && - (src_x != 0 || src_y != 0 || - width != cogl_bitmap_get_width (source_bmp) || - height != cogl_bitmap_get_height (source_bmp))) - { - slice_bmp = - _cogl_bitmap_new_with_malloc_buffer (ctx, - width, height, - source_format, - error); - if (!slice_bmp) - return FALSE; - - if (!_cogl_bitmap_copy_subregion (source_bmp, - slice_bmp, - src_x, src_y, - 0, 0, /* dst_x/y */ - width, height, - error)) - { - g_object_unref (slice_bmp); - return FALSE; - } - - src_x = src_y = 0; - } - else - { - slice_bmp = prepare_bitmap_alignment_for_upload (ctx, source_bmp, error); - if (!slice_bmp) - return FALSE; - } - - rowstride = cogl_bitmap_get_rowstride (slice_bmp); - - /* Setup gl alignment to match rowstride and top-left corner */ - prep_gl_for_pixels_upload_full (ctx, rowstride, src_x, src_y, bpp); - - data = _cogl_bitmap_gl_bind (slice_bmp, COGL_BUFFER_ACCESS_READ, 0, &internal_error); - - /* NB: _cogl_bitmap_gl_bind() may return NULL when successful so we - * have to explicitly check the cogl error pointer to catch - * problems... */ - if (internal_error) - { - g_propagate_error (error, internal_error); - g_object_unref (slice_bmp); - return FALSE; - } - - _cogl_bind_gl_texture_transient (gl_target, gl_handle); - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - _cogl_texture_get_level_size (texture, - level, - &level_width, - &level_height, - NULL); - - if (level_width == width && level_height == height) - { - /* GL gets upset if you use glTexSubImage2D to define the - * contents of a mipmap level so we make sure to use - * glTexImage2D if we are uploading a full mipmap level. - */ - ctx->glTexImage2D (gl_target, - level, - _cogl_texture_gl_get_format (texture), - width, - height, - 0, - source_gl_format, - source_gl_type, - data); - } - else - { - /* GL gets upset if you use glTexSubImage2D to initialize the - * contents of a mipmap level so if this is the first time - * we've seen a request to upload to this level we call - * glTexImage2D first to assert that the storage for this - * level exists. - */ - if (cogl_texture_get_max_level_set (texture) < level) - { - ctx->glTexImage2D (gl_target, - level, - _cogl_texture_gl_get_format (texture), - level_width, - level_height, - 0, - source_gl_format, - source_gl_type, - NULL); - } - - ctx->glTexSubImage2D (gl_target, - level, - dst_x, dst_y, - width, height, - source_gl_format, - source_gl_type, - data); - } - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - status = FALSE; - - _cogl_bitmap_gl_unbind (slice_bmp); - - g_object_unref (slice_bmp); - - return status; -} - -static gboolean -_cogl_texture_driver_upload_to_gl (CoglContext *ctx, - GLenum gl_target, - GLuint gl_handle, - CoglBitmap *source_bmp, - GLint internal_gl_format, - GLuint source_gl_format, - GLuint source_gl_type, - GError **error) -{ - CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp; - int rowstride; - int bmp_width = cogl_bitmap_get_width (source_bmp); - int bmp_height = cogl_bitmap_get_height (source_bmp); - CoglBitmap *bmp; - uint8_t *data; - GError *internal_error = NULL; - gboolean status = TRUE; - - g_return_val_if_fail (source_format != COGL_PIXEL_FORMAT_ANY, FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (source_format) == 1, - FALSE); - - bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0); - - bmp = prepare_bitmap_alignment_for_upload (ctx, source_bmp, error); - if (!bmp) - return FALSE; - - rowstride = cogl_bitmap_get_rowstride (bmp); - - /* Setup gl alignment to match rowstride and top-left corner */ - _cogl_texture_driver_prep_gl_for_pixels_upload (ctx, rowstride, bpp); - - _cogl_bind_gl_texture_transient (gl_target, gl_handle); - - data = _cogl_bitmap_gl_bind (bmp, - COGL_BUFFER_ACCESS_READ, - 0, /* hints */ - &internal_error); - - /* NB: _cogl_bitmap_gl_bind() may return NULL when successful so we - * have to explicitly check the cogl error pointer to catch - * problems... */ - if (internal_error) - { - g_object_unref (bmp); - g_propagate_error (error, internal_error); - return FALSE; - } - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glTexImage2D (gl_target, 0, - internal_gl_format, - bmp_width, bmp_height, - 0, - source_gl_format, - source_gl_type, - data); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - status = FALSE; - - _cogl_bitmap_gl_unbind (bmp); - - g_object_unref (bmp); - - return status; -} - -/* NB: GLES doesn't support glGetTexImage2D, so cogl-texture will instead - * fallback to a generic render + readpixels approach to downloading - * texture data. (See _cogl_texture_draw_and_read() ) */ -static gboolean -_cogl_texture_driver_gl_get_tex_image (CoglContext *ctx, - GLenum gl_target, - GLenum dest_gl_format, - GLenum dest_gl_type, - uint8_t *dest) -{ - return FALSE; -} - -static gboolean -_cogl_texture_driver_size_supported (CoglContext *ctx, - GLenum gl_target, - GLenum gl_intformat, - GLenum gl_format, - GLenum gl_type, - int width, - int height) -{ - GLint max_size; - - /* GLES doesn't support a proxy texture target so let's at least - check whether the size is greater than GL_MAX_TEXTURE_SIZE */ - GE( ctx, glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_size) ); - - return width <= max_size && height <= max_size; -} - -static gboolean -_cogl_texture_driver_upload_supported (CoglContext *ctx, - CoglPixelFormat format) -{ - switch (format) - { - case COGL_PIXEL_FORMAT_A_8: - case COGL_PIXEL_FORMAT_R_8: - case COGL_PIXEL_FORMAT_RG_88: - return TRUE; - case COGL_PIXEL_FORMAT_BGRX_8888: - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - case COGL_PIXEL_FORMAT_RGB_888: - case COGL_PIXEL_FORMAT_BGR_888: - return TRUE; - case COGL_PIXEL_FORMAT_RGBA_1010102: - case COGL_PIXEL_FORMAT_RGBA_1010102_PRE: - case COGL_PIXEL_FORMAT_BGRA_1010102: - case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: - case COGL_PIXEL_FORMAT_XBGR_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: - case COGL_PIXEL_FORMAT_XRGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_RGBA1010102)) - return TRUE; - else - return FALSE; -#else - return FALSE; -#endif - case COGL_PIXEL_FORMAT_RGBX_8888: - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - case COGL_PIXEL_FORMAT_XRGB_8888: - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - case COGL_PIXEL_FORMAT_XBGR_8888: - case COGL_PIXEL_FORMAT_ABGR_8888: - case COGL_PIXEL_FORMAT_ABGR_8888_PRE: - case COGL_PIXEL_FORMAT_RGB_565: - case COGL_PIXEL_FORMAT_RGBA_4444: - case COGL_PIXEL_FORMAT_RGBA_4444_PRE: - case COGL_PIXEL_FORMAT_RGBA_5551: - case COGL_PIXEL_FORMAT_RGBA_5551_PRE: - return TRUE; - case COGL_PIXEL_FORMAT_BGRX_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616: - case COGL_PIXEL_FORMAT_XRGB_FP_16161616: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616: - case COGL_PIXEL_FORMAT_XBGR_FP_16161616: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: - return FALSE; - case COGL_PIXEL_FORMAT_RGBX_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_RGBA_FP_32323232: - case COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE: - if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_HALF_FLOAT)) - return TRUE; - else - return FALSE; - case COGL_PIXEL_FORMAT_R_16: - case COGL_PIXEL_FORMAT_RG_1616: - case COGL_PIXEL_FORMAT_RGBA_16161616: - case COGL_PIXEL_FORMAT_RGBA_16161616_PRE: - if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NORM16)) - return TRUE; - else - return FALSE; - case COGL_PIXEL_FORMAT_DEPTH_16: - case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: - case COGL_PIXEL_FORMAT_ANY: - case COGL_PIXEL_FORMAT_YUV: - g_assert_not_reached (); - return FALSE; - } - - g_assert_not_reached (); - return FALSE; -} - -static CoglPixelFormat -_cogl_texture_driver_find_best_gl_get_data_format - (CoglContext *context, - CoglPixelFormat format, - GLenum *closest_gl_format, - GLenum *closest_gl_type) -{ - /* Find closest format that's supported by GL - (Can't use _cogl_pixel_format_to_gl since available formats - when reading pixels on GLES are severely limited) */ - *closest_gl_format = GL_RGBA; - *closest_gl_type = GL_UNSIGNED_BYTE; - return COGL_PIXEL_FORMAT_RGBA_8888; -} - -const CoglTextureDriver -_cogl_texture_driver_gles = - { - _cogl_texture_driver_gen, - _cogl_texture_driver_upload_subregion_to_gl, - _cogl_texture_driver_upload_to_gl, - _cogl_texture_driver_prep_gl_for_pixels_download, - _cogl_texture_driver_gl_get_tex_image, - _cogl_texture_driver_size_supported, - _cogl_texture_driver_upload_supported, - _cogl_texture_driver_find_best_gl_get_data_format - }; diff --git a/mutter/cogl/cogl/driver/nop/cogl-attribute-nop-private.h b/mutter/cogl/cogl/driver/nop/cogl-attribute-nop-private.h deleted file mode 100644 index 50e04f6..0000000 --- a/mutter/cogl/cogl/driver/nop/cogl-attribute-nop-private.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-types.h" -#include "cogl/cogl-context-private.h" - -void -_cogl_nop_flush_attributes_state (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglFlushLayerState *layers_state, - CoglDrawFlags flags, - CoglAttribute **attributes, - int n_attributes); diff --git a/mutter/cogl/cogl/driver/nop/cogl-attribute-nop.c b/mutter/cogl/cogl/driver/nop/cogl-attribute-nop.c deleted file mode 100644 index 6275d2a..0000000 --- a/mutter/cogl/cogl/driver/nop/cogl-attribute-nop.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include "cogl/cogl-types.h" -#include "cogl/cogl-framebuffer.h" -#include "cogl/cogl-attribute.h" -#include "cogl/cogl-attribute-private.h" -#include "cogl/driver/nop/cogl-attribute-nop-private.h" - -void -_cogl_nop_flush_attributes_state (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglFlushLayerState *layers_state, - CoglDrawFlags flags, - CoglAttribute **attributes, - int n_attributes) -{ -} diff --git a/mutter/cogl/cogl/driver/nop/cogl-clip-stack-nop-private.h b/mutter/cogl/cogl/driver/nop/cogl-clip-stack-nop-private.h deleted file mode 100644 index d5fdfd2..0000000 --- a/mutter/cogl/cogl/driver/nop/cogl-clip-stack-nop-private.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-types.h" -#include "cogl/cogl-context-private.h" - -void -_cogl_clip_stack_nop_flush (CoglClipStack *stack, - CoglFramebuffer *framebuffer); diff --git a/mutter/cogl/cogl/driver/nop/cogl-clip-stack-nop.c b/mutter/cogl/cogl/driver/nop/cogl-clip-stack-nop.c deleted file mode 100644 index de5fcc5..0000000 --- a/mutter/cogl/cogl/driver/nop/cogl-clip-stack-nop.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include "cogl/cogl-clip-stack.h" -#include "cogl/driver/nop/cogl-clip-stack-nop-private.h" -#include "cogl/cogl-framebuffer-private.h" - -void -_cogl_clip_stack_nop_flush (CoglClipStack *stack, - CoglFramebuffer *framebuffer) -{ -} diff --git a/mutter/cogl/cogl/driver/nop/cogl-driver-nop.c b/mutter/cogl/cogl/driver/nop/cogl-driver-nop.c deleted file mode 100644 index c2eb0d6..0000000 --- a/mutter/cogl/cogl/driver/nop/cogl-driver-nop.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include - -#include "cogl/cogl-private.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-feature-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/driver/nop/cogl-texture-2d-nop-private.h" -#include "cogl/driver/nop/cogl-attribute-nop-private.h" -#include "cogl/driver/nop/cogl-clip-stack-nop-private.h" -#include "cogl/driver/nop/cogl-nop-framebuffer.h" - -static gboolean -_cogl_driver_update_features (CoglContext *ctx, - GError **error) -{ - memset (ctx->private_features, 0, sizeof (ctx->private_features)); - - return TRUE; -} - -static gboolean -_cogl_driver_nop_context_init (CoglContext *context) -{ - return TRUE; -} - -static void -_cogl_driver_nop_context_deinit (CoglContext *context) -{ -} - -static gboolean -_cogl_driver_nop_is_hardware_accelerated (CoglContext *context) -{ - return FALSE; -} - -static CoglFramebufferDriver * -_cogl_driver_nop_create_framebuffer_driver (CoglContext *context, - CoglFramebuffer *framebuffer, - const CoglFramebufferDriverConfig *driver_config, - GError **error) -{ - return g_object_new (COGL_TYPE_NOP_FRAMEBUFFER, - "framebuffer", framebuffer, - NULL); -} - -static void -_cogl_driver_nop_flush_framebuffer_state (CoglContext *ctx, - CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer, - CoglFramebufferState state) -{ -} - -const CoglDriverVtable -_cogl_driver_nop = - { - _cogl_driver_nop_context_init, - _cogl_driver_nop_context_deinit, - _cogl_driver_nop_is_hardware_accelerated, - NULL, /* get_graphics_reset_status */ - NULL, /* pixel_format_to_gl */ - NULL, /* _cogl_driver_get_read_pixels_format */ - _cogl_driver_update_features, - _cogl_driver_nop_create_framebuffer_driver, - _cogl_driver_nop_flush_framebuffer_state, - _cogl_texture_2d_nop_free, - _cogl_texture_2d_nop_can_create, - _cogl_texture_2d_nop_init, - _cogl_texture_2d_nop_allocate, - _cogl_texture_2d_nop_copy_from_framebuffer, - _cogl_texture_2d_nop_get_gl_handle, - _cogl_texture_2d_nop_generate_mipmap, - _cogl_texture_2d_nop_copy_from_bitmap, - NULL, /* texture_2d_is_get_data_supported */ - NULL, /* texture_2d_get_data */ - _cogl_nop_flush_attributes_state, - _cogl_clip_stack_nop_flush, - }; diff --git a/mutter/cogl/cogl/driver/nop/cogl-nop-framebuffer.c b/mutter/cogl/cogl/driver/nop/cogl-nop-framebuffer.c deleted file mode 100644 index 9706fa1..0000000 --- a/mutter/cogl/cogl/driver/nop/cogl-nop-framebuffer.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "config.h" - -#include "cogl/driver/nop/cogl-nop-framebuffer.h" - -#include "cogl/cogl-framebuffer-private.h" - -struct _CoglNopFramebuffer -{ - CoglFramebufferDriver parent; -}; - -G_DEFINE_TYPE (CoglNopFramebuffer, cogl_nop_framebuffer, - COGL_TYPE_FRAMEBUFFER_DRIVER) - -static void -cogl_nop_framebuffer_query_bits (CoglFramebufferDriver *driver, - CoglFramebufferBits *bits) -{ - memset (bits, 0, sizeof (CoglFramebufferBits)); -} - -static void -cogl_nop_framebuffer_clear (CoglFramebufferDriver *driver, - unsigned long buffers, - float red, - float green, - float blue, - float alpha) -{ -} - -static void -cogl_nop_framebuffer_finish (CoglFramebufferDriver *driver) -{ -} - -static void -cogl_nop_framebuffer_flush (CoglFramebufferDriver *driver) -{ -} - -static void -cogl_nop_framebuffer_discard_buffers (CoglFramebufferDriver *driver, - unsigned long buffers) -{ -} - -static void -cogl_nop_framebuffer_draw_attributes (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags) -{ -} - -static void -cogl_nop_framebuffer_draw_indexed_attributes (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags) -{ -} - -static gboolean -cogl_nop_framebuffer_read_pixels_into_bitmap (CoglFramebufferDriver *framebuffer, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap, - GError **error) -{ - return TRUE; -} - -static void -cogl_nop_framebuffer_init (CoglNopFramebuffer *nop_framebuffer) -{ -} - -static void -cogl_nop_framebuffer_class_init (CoglNopFramebufferClass *klass) -{ - CoglFramebufferDriverClass *driver_class = - COGL_FRAMEBUFFER_DRIVER_CLASS (klass); - - driver_class->query_bits = cogl_nop_framebuffer_query_bits; - driver_class->clear = cogl_nop_framebuffer_clear; - driver_class->finish = cogl_nop_framebuffer_finish; - driver_class->flush = cogl_nop_framebuffer_flush; - driver_class->discard_buffers = cogl_nop_framebuffer_discard_buffers; - driver_class->draw_attributes = cogl_nop_framebuffer_draw_attributes; - driver_class->draw_indexed_attributes = - cogl_nop_framebuffer_draw_indexed_attributes; - driver_class->read_pixels_into_bitmap = - cogl_nop_framebuffer_read_pixels_into_bitmap; -} diff --git a/mutter/cogl/cogl/driver/nop/cogl-nop-framebuffer.h b/mutter/cogl/cogl/driver/nop/cogl-nop-framebuffer.h deleted file mode 100644 index db9f353..0000000 --- a/mutter/cogl/cogl/driver/nop/cogl-nop-framebuffer.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#pragma once - -#include "cogl/cogl-framebuffer-driver.h" - -#define COGL_TYPE_NOP_FRAMEBUFFER (cogl_nop_framebuffer_get_type ()) -G_DECLARE_FINAL_TYPE (CoglNopFramebuffer, cogl_nop_framebuffer, - COGL, NOP_FRAMEBUFFER_DRIVER, - CoglFramebufferDriver) diff --git a/mutter/cogl/cogl/driver/nop/cogl-texture-2d-nop-private.h b/mutter/cogl/cogl/driver/nop/cogl-texture-2d-nop-private.h deleted file mode 100644 index 47ba365..0000000 --- a/mutter/cogl/cogl/driver/nop/cogl-texture-2d-nop-private.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#pragma once - -#include "cogl/cogl-types.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-texture.h" - -void -_cogl_texture_2d_nop_free (CoglTexture2D *tex_2d); - -gboolean -_cogl_texture_2d_nop_can_create (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format); - -void -_cogl_texture_2d_nop_init (CoglTexture2D *tex_2d); - -gboolean -_cogl_texture_2d_nop_allocate (CoglTexture *tex, - GError **error); - -void -_cogl_texture_2d_nop_copy_from_framebuffer (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglFramebuffer *src_fb, - int dst_x, - int dst_y, - int level); - -unsigned int -_cogl_texture_2d_nop_get_gl_handle (CoglTexture2D *tex_2d); - -void -_cogl_texture_2d_nop_generate_mipmap (CoglTexture2D *tex_2d); - -gboolean -_cogl_texture_2d_nop_copy_from_bitmap (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglBitmap *bitmap, - int dst_x, - int dst_y, - int level, - GError **error); diff --git a/mutter/cogl/cogl/driver/nop/cogl-texture-2d-nop.c b/mutter/cogl/cogl/driver/nop/cogl-texture-2d-nop.c deleted file mode 100644 index cb0f2bd..0000000 --- a/mutter/cogl/cogl/driver/nop/cogl-texture-2d-nop.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009,2010,2011,2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - * Robert Bragg - */ - -#include "config.h" - -#include - -#include "cogl/cogl-private.h" -#include "cogl/driver/nop/cogl-texture-2d-nop-private.h" -#include "cogl/cogl-texture-2d-private.h" - -void -_cogl_texture_2d_nop_free (CoglTexture2D *tex_2d) -{ -} - -gboolean -_cogl_texture_2d_nop_can_create (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format) -{ - return TRUE; -} - -void -_cogl_texture_2d_nop_init (CoglTexture2D *tex_2d) -{ -} - -gboolean -_cogl_texture_2d_nop_allocate (CoglTexture *tex, - GError **error) -{ - return TRUE; -} - -void -_cogl_texture_2d_nop_copy_from_framebuffer (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglFramebuffer *src_fb, - int dst_x, - int dst_y, - int level) -{ -} - -unsigned int -_cogl_texture_2d_nop_get_gl_handle (CoglTexture2D *tex_2d) -{ - return 0; -} - -void -_cogl_texture_2d_nop_generate_mipmap (CoglTexture2D *tex_2d) -{ -} - -gboolean -_cogl_texture_2d_nop_copy_from_bitmap (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglBitmap *bitmap, - int dst_x, - int dst_y, - int level, - GError **error) -{ - return TRUE; -} diff --git a/mutter/cogl/cogl/gl-prototypes/cogl-all-functions.h b/mutter/cogl/cogl/gl-prototypes/cogl-all-functions.h deleted file mode 100644 index 2471572..0000000 --- a/mutter/cogl/cogl/gl-prototypes/cogl-all-functions.h +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009, 2011 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This is included multiple times with different definitions for - * these macros. The macros are given the following arguments: - * - * COGL_EXT_BEGIN: - * - * @name: a unique symbol name for this feature - * - * @min_gl_major: the major part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * @min_gl_minor: the minor part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * - * @gles_availability: flags to specify which versions of GLES the - * functions are available in. Should be a combination of - * COGL_EXT_IN_GLES and COGL_EXT_IN_GLES2. - * - * @extension_suffixes: A zero-separated list of suffixes in a - * string. These are appended to the extension name to get a complete - * extension name to try. The suffix is also appended to all of the - * function names. The suffix can optionally include a ':' to specify - * an alternate suffix for the function names. - * - * @extension_names: A list of extension names to try. If any of these - * extensions match then it will be used. - */ - -/* The functions in this file are part of the core GL,GLES1 and GLES2 apis */ -#include "cogl/gl-prototypes/cogl-core-functions.h" - -/* The functions in this file are core to GLES2 only but - * may be extensions for GLES1 and GL */ -#include "cogl/gl-prototypes/cogl-in-gles2-core-functions.h" - -/* The functions in this file are core to GLES1 and GLES2 but not core - * to GL but they may be extensions available for GL */ -#include "cogl/gl-prototypes/cogl-in-gles-core-functions.h" - -/* These are GLSL shader APIs core to GL 2.0 and GLES2 */ -#include "cogl/gl-prototypes/cogl-glsl-functions.h" - -/* These are the core GL functions which are only available in big - GL */ -COGL_EXT_BEGIN (only_in_big_gl, - 0, 0, - 0, /* not in GLES */ - "\0", - "\0") -COGL_EXT_FUNCTION (void, glGetTexLevelParameteriv, - (GLenum target, GLint level, - GLenum pname, GLint *params)) -COGL_EXT_FUNCTION (void, glGetTexImage, - (GLenum target, GLint level, - GLenum format, GLenum type, - GLvoid *pixels)) -COGL_EXT_FUNCTION (void, glDepthRange, - (double near_val, double far_val)) -COGL_EXT_FUNCTION (void, glDrawBuffer, - (GLenum mode)) -COGL_EXT_END () - - -/* GLES doesn't support mapping buffers in core so this has to be a - separate check */ -COGL_EXT_BEGIN (map_vbos, 1, 5, - 0, /* not in GLES core */ - "ARB\0OES\0", - "vertex_buffer_object\0mapbuffer\0") -COGL_EXT_FUNCTION (void *, glMapBuffer, - (GLenum target, - GLenum access)) -COGL_EXT_FUNCTION (GLboolean, glUnmapBuffer, - (GLenum target)) -COGL_EXT_END () - - -COGL_EXT_BEGIN (offscreen_blit, 3, 0, - COGL_EXT_IN_GLES3, - "EXT\0NV\0", - "framebuffer_blit\0") -COGL_EXT_FUNCTION (void, glBlitFramebuffer, - (GLint srcX0, - GLint srcY0, - GLint srcX1, - GLint srcY1, - GLint dstX0, - GLint dstY0, - GLint dstX1, - GLint dstY1, - GLbitfield mask, - GLenum filter)) -COGL_EXT_END () - -COGL_EXT_BEGIN (EGL_image, 255, 255, - 0, /* not in either GLES */ - "OES\0", - "EGL_image\0") -COGL_EXT_FUNCTION (void, glEGLImageTargetTexture2D, - (GLenum target, - GLeglImageOES image)) -COGL_EXT_END () - -COGL_EXT_BEGIN (discard_framebuffer, 255, 255, - 0, /* not in either GLES */ - "EXT\0", - "discard_framebuffer\0") -COGL_EXT_FUNCTION (void, glDiscardFramebuffer, - (GLenum target, - GLsizei numAttachments, - const GLenum *attachments)) -COGL_EXT_END () - -COGL_EXT_BEGIN (IMG_multisampled_render_to_texture, 255, 255, - 0, /* not in either GLES */ - "\0", - "IMG_multisampled_render_to_texture\0") -COGL_EXT_FUNCTION (void, glRenderbufferStorageMultisampleIMG, - (GLenum target, - GLsizei samples, - GLenum internal_format, - GLsizei width, - GLsizei height)) -COGL_EXT_FUNCTION (void, glFramebufferTexture2DMultisampleIMG, - (GLenum target, - GLenum attachment, - GLenum textarget, - GLuint texture, - GLint level, - GLsizei samples)) -COGL_EXT_END () - -COGL_EXT_BEGIN (ARB_sampler_objects, 3, 3, - COGL_EXT_IN_GLES3, - "ARB:\0", - "sampler_objects\0") -COGL_EXT_FUNCTION (void, glGenSamplers, - (GLsizei count, - GLuint *samplers)) -COGL_EXT_FUNCTION (void, glDeleteSamplers, - (GLsizei count, - const GLuint *samplers)) -COGL_EXT_FUNCTION (void, glBindSampler, - (GLuint unit, - GLuint sampler)) -COGL_EXT_FUNCTION (void, glSamplerParameteri, - (GLuint sampler, - GLenum pname, - GLint param)) -COGL_EXT_FUNCTION (void, glSamplerParameterf, - (GLuint sampler, - GLenum pname, - GLfloat param)) -COGL_EXT_END () - -COGL_EXT_BEGIN (only_gl3, 3, 0, - COGL_EXT_IN_GLES3, - "\0", - "\0") -COGL_EXT_FUNCTION (const GLubyte *, glGetStringi, - (GLenum name, GLuint index)) -COGL_EXT_END () - -COGL_EXT_BEGIN (vertex_array_object, 3, 0, - COGL_EXT_IN_GLES3, - "ARB\0OES\0", - "vertex_array_object\0") -COGL_EXT_FUNCTION (void, glBindVertexArray, - (GLuint array)) -COGL_EXT_FUNCTION (void, glGenVertexArrays, - (GLsizei n, - GLuint *arrays)) -COGL_EXT_END () - -COGL_EXT_BEGIN (map_region, 3, 0, - COGL_EXT_IN_GLES3, - "ARB:\0", - "map_buffer_range\0") -COGL_EXT_FUNCTION (GLvoid *, glMapBufferRange, - (GLenum target, - GLintptr offset, - GLsizeiptr length, - GLbitfield access)) -COGL_EXT_END () - -#ifdef GL_ARB_sync -COGL_EXT_BEGIN (sync, 3, 2, - COGL_EXT_IN_GLES3, - "ARB:\0", - "sync\0") -COGL_EXT_FUNCTION (GLsync, glFenceSync, - (GLenum condition, GLbitfield flags)) -COGL_EXT_FUNCTION (GLenum, glClientWaitSync, - (GLsync sync, GLbitfield flags, GLuint64 timeout)) -COGL_EXT_FUNCTION (void, glDeleteSync, - (GLsync sync)) -COGL_EXT_END () -#endif - -COGL_EXT_BEGIN (sync_get_int64, 3, 2, - 0, - "ARB:\0", - "sync\0") -COGL_EXT_FUNCTION (void, glGetInteger64v, - (GLenum pname, GLint64 *params)) -COGL_EXT_END () - -COGL_EXT_BEGIN (draw_buffers, 2, 0, - COGL_EXT_IN_GLES3, - "ARB\0EXT\0", - "draw_buffers\0") -COGL_EXT_FUNCTION (void, glDrawBuffers, - (GLsizei n, const GLenum *bufs)) -COGL_EXT_END () - -COGL_EXT_BEGIN (robustness, 255, 255, - 0, - "ARB\0", - "robustness\0") -COGL_EXT_FUNCTION (GLenum, glGetGraphicsResetStatus, - (void)) -COGL_EXT_END () - -COGL_EXT_BEGIN (multitexture_part1, 1, 3, - 0, - "ARB\0", - "multitexture\0") -COGL_EXT_FUNCTION (void, glClientActiveTexture, - (GLenum texture)) -COGL_EXT_END () - -COGL_EXT_BEGIN (query_counter, 3, 3, - 0, - "ARB:\0", - "timer_query\0") -COGL_EXT_FUNCTION (void, glQueryCounter, - (GLuint id, GLenum target)) -COGL_EXT_FUNCTION (void, glGetQueryObjecti64v, - (GLuint id, GLenum pname, GLint64 *params)) -COGL_EXT_END () - -COGL_EXT_BEGIN (queries, 1, 5, - 0, - "\0", - "\0") -COGL_EXT_FUNCTION (void, glGenQueries, - (GLsizei n, GLuint *ids)) -COGL_EXT_FUNCTION (void, glDeleteQueries, - (GLsizei n, const GLuint *ids)) -COGL_EXT_END () diff --git a/mutter/cogl/cogl/gl-prototypes/cogl-core-functions.h b/mutter/cogl/cogl/gl-prototypes/cogl-core-functions.h deleted file mode 100644 index e362e79..0000000 --- a/mutter/cogl/cogl/gl-prototypes/cogl-core-functions.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009, 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This is included multiple times with different definitions for - * these macros. The macros are given the following arguments: - * - * COGL_EXT_BEGIN: - * - * @name: a unique symbol name for this feature - * - * @min_gl_major: the major part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * @min_gl_minor: the minor part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * - * @gles_availability: flags to specify which versions of GLES the - * functions are available in. Should be a combination of - * COGL_EXT_IN_GLES and COGL_EXT_IN_GLES2. - * - * @extension_suffixes: A zero-separated list of suffixes in a - * string. These are appended to the extension name to get a complete - * extension name to try. The suffix is also appended to all of the - * function names. The suffix can optionally include a ':' to specify - * an alternate suffix for the function names. - * - * @extension_names: A list of extension names to try. If any of these - * extensions match then it will be used. - */ - -/* These are the core GL functions which we assume will always be - available */ -COGL_EXT_BEGIN (core, - 0, 0, - COGL_EXT_IN_GLES2, - "\0", - "\0") -COGL_EXT_FUNCTION (void, glActiveTexture, - (GLenum texture)) -COGL_EXT_FUNCTION (void, glBindBuffer, - (GLenum target, - GLuint buffer)) -COGL_EXT_FUNCTION (void, glBindTexture, - (GLenum target, GLuint texture)) -COGL_EXT_FUNCTION (void, glBufferData, - (GLenum target, - GLsizeiptr size, - const GLvoid *data, - GLenum usage)) -COGL_EXT_FUNCTION (void, glBufferSubData, - (GLenum target, - GLintptr offset, - GLsizeiptr size, - const GLvoid *data)) -COGL_EXT_FUNCTION (void, glClear, - (GLbitfield mask)) -COGL_EXT_FUNCTION (void, glClearColor, - (GLclampf red, - GLclampf green, - GLclampf blue, - GLclampf alpha)) -COGL_EXT_FUNCTION (void, glClearStencil, - (GLint s)) -COGL_EXT_FUNCTION (void, glColorMask, - (GLboolean red, - GLboolean green, - GLboolean blue, - GLboolean alpha)) -COGL_EXT_FUNCTION (void, glCopyTexSubImage2D, - (GLenum target, - GLint level, - GLint xoffset, - GLint yoffset, - GLint x, - GLint y, - GLsizei width, - GLsizei height)) -COGL_EXT_FUNCTION (void, glDeleteBuffers, - (GLsizei n, - const GLuint *buffers)) -COGL_EXT_FUNCTION (void, glDeleteTextures, - (GLsizei n, const GLuint* textures)) -COGL_EXT_FUNCTION (void, glDepthFunc, - (GLenum func)) -COGL_EXT_FUNCTION (void, glDepthMask, - (GLboolean flag)) -COGL_EXT_FUNCTION (void, glDisable, - (GLenum cap)) -COGL_EXT_FUNCTION (void, glDrawArrays, - (GLenum mode, GLint first, GLsizei count)) -COGL_EXT_FUNCTION (void, glDrawElements, - (GLenum mode, - GLsizei count, - GLenum type, - const GLvoid* indices)) -COGL_EXT_FUNCTION (void, glEnable, - (GLenum cap)) -COGL_EXT_FUNCTION (void, glFinish, - (void)) -COGL_EXT_FUNCTION (void, glFlush, - (void)) -COGL_EXT_FUNCTION (void, glFrontFace, - (GLenum mode)) -COGL_EXT_FUNCTION (void, glCullFace, - (GLenum mode)) -COGL_EXT_FUNCTION (void, glGenBuffers, - (GLsizei n, - GLuint *buffers)) -COGL_EXT_FUNCTION (void, glGenTextures, - (GLsizei n, GLuint* textures)) -COGL_EXT_FUNCTION (GLenum, glGetError, - (void)) -COGL_EXT_FUNCTION (void, glGetIntegerv, - (GLenum pname, GLint* params)) -COGL_EXT_FUNCTION (const GLubyte*, glGetString, - (GLenum name)) -COGL_EXT_FUNCTION (GLboolean, glIsTexture, - (GLuint texture)) -COGL_EXT_FUNCTION (void, glPixelStorei, - (GLenum pname, GLint param)) -COGL_EXT_FUNCTION (void, glReadPixels, - (GLint x, - GLint y, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - GLvoid* pixels)) -COGL_EXT_FUNCTION (void, glScissor, - (GLint x, GLint y, GLsizei width, GLsizei height)) -COGL_EXT_FUNCTION (void, glStencilFunc, - (GLenum func, GLint ref, GLuint mask)) -COGL_EXT_FUNCTION (void, glStencilMask, - (GLuint mask)) -COGL_EXT_FUNCTION (void, glStencilOp, - (GLenum fail, GLenum zfail, GLenum zpass)) -COGL_EXT_FUNCTION (void, glTexImage2D, - (GLenum target, - GLint level, - GLint internalformat, - GLsizei width, - GLsizei height, - GLint border, - GLenum format, - GLenum type, - const GLvoid* pixels)) -COGL_EXT_FUNCTION (void, glTexParameteri, - (GLenum target, GLenum pname, GLint param)) -COGL_EXT_FUNCTION (void, glTexParameterf, - (GLenum target, GLenum pname, GLfloat param)) -COGL_EXT_FUNCTION (void, glTexParameteriv, - (GLenum target, GLenum pname, const GLint* params)) -COGL_EXT_FUNCTION (void, glTexSubImage2D, - (GLenum target, - GLint level, - GLint xoffset, - GLint yoffset, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - const GLvoid* pixels)) -COGL_EXT_FUNCTION (void, glViewport, - (GLint x, GLint y, GLsizei width, GLsizei height)) -COGL_EXT_END () diff --git a/mutter/cogl/cogl/gl-prototypes/cogl-gles2-functions.h b/mutter/cogl/cogl/gl-prototypes/cogl-gles2-functions.h deleted file mode 100644 index 05b230e..0000000 --- a/mutter/cogl/cogl/gl-prototypes/cogl-gles2-functions.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009, 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* The functions in this file are part of the core GL,GLES1 and GLES2 apis */ -#include "cogl/cogl-core-functions.h" - -/* The functions in this file are core to GLES1 and GLES2 but not core - * to GL but they may be extensions available for GL */ -#include "cogl/cogl-in-gles-core-functions.h" - -/* The functions in this file are core to GLES2 only but - * may be extensions for GLES1 and GL */ -#include "cogl/cogl-in-gles2-core-functions.h" - -/* These are APIs for using GLSL used by GL and GLES2 */ -#include "cogl/cogl-glsl-functions.h" diff --git a/mutter/cogl/cogl/gl-prototypes/cogl-glsl-functions.h b/mutter/cogl/cogl/gl-prototypes/cogl-glsl-functions.h deleted file mode 100644 index a918ad8..0000000 --- a/mutter/cogl/cogl/gl-prototypes/cogl-glsl-functions.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009, 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This is included multiple times with different definitions for - * these macros. The macros are given the following arguments: - * - * COGL_EXT_BEGIN: - * - * @name: a unique symbol name for this feature - * - * @min_gl_major: the major part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * @min_gl_minor: the minor part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * - * @gles_availability: flags to specify which versions of GLES the - * functions are available in. Should be a combination of - * COGL_EXT_IN_GLES and COGL_EXT_IN_GLES2. - * - * @extension_suffixes: A zero-separated list of suffixes in a - * string. These are appended to the extension name to get a complete - * extension name to try. The suffix is also appended to all of the - * function names. The suffix can optionally include a ':' to specify - * an alternate suffix for the function names. - * - * @extension_names: A list of extension names to try. If any of these - * extensions match then it will be used. - */ - -/* This lists functions that are unique to GL 2.0 or GLES 2.0 and are - * not in the old GLSL extensions */ -COGL_EXT_BEGIN (shaders_glsl_2_only, 2, 0, - COGL_EXT_IN_GLES2, - "\0", - "\0") -COGL_EXT_FUNCTION (GLuint, glCreateProgram, - (void)) -COGL_EXT_FUNCTION (GLuint, glCreateShader, - (GLenum shaderType)) -COGL_EXT_FUNCTION (void, glDeleteShader, - (GLuint shader)) -COGL_EXT_FUNCTION (void, glAttachShader, - (GLuint program, - GLuint shader)) -COGL_EXT_FUNCTION (void, glUseProgram, - (GLuint program)) -COGL_EXT_FUNCTION (void, glDeleteProgram, - (GLuint program)) -COGL_EXT_FUNCTION (void, glGetShaderInfoLog, - (GLuint shader, - GLsizei maxLength, - GLsizei *length, - char *infoLog)) -COGL_EXT_FUNCTION (void, glGetProgramInfoLog, - (GLuint program, - GLsizei bufSize, - GLsizei *length, - char *infoLog)) -COGL_EXT_FUNCTION (void, glGetShaderiv, - (GLuint shader, - GLenum pname, - GLint *params)) -COGL_EXT_FUNCTION (void, glGetProgramiv, - (GLuint program, - GLenum pname, - GLint *params)) -COGL_EXT_END () - -/* These functions are provided by GL_ARB_shader_objects or are in GL - * 2.0 core */ -COGL_EXT_BEGIN (shader_objects_or_gl2, 2, 0, - COGL_EXT_IN_GLES2, - "ARB\0", - "shader_objects\0") -COGL_EXT_FUNCTION (void, glShaderSource, - (GLuint shader, - GLsizei count, - const char * const *string, - const GLint *length)) -COGL_EXT_FUNCTION (void, glCompileShader, - (GLuint shader)) -COGL_EXT_FUNCTION (void, glLinkProgram, - (GLuint program)) -COGL_EXT_FUNCTION (GLint, glGetUniformLocation, - (GLuint program, - const char *name)) -COGL_EXT_FUNCTION (void, glUniform1f, - (GLint location, - GLfloat v0)) -COGL_EXT_FUNCTION (void, glUniform1fv, - (GLint location, - GLsizei count, - const GLfloat * value)) -COGL_EXT_FUNCTION (void, glUniform2fv, - (GLint location, - GLsizei count, - const GLfloat * value)) -COGL_EXT_FUNCTION (void, glUniform3fv, - (GLint location, - GLsizei count, - const GLfloat * value)) -COGL_EXT_FUNCTION (void, glUniform4fv, - (GLint location, - GLsizei count, - const GLfloat * value)) -COGL_EXT_FUNCTION (void, glUniform1i, - (GLint location, - GLint v0)) -COGL_EXT_FUNCTION (void, glUniform1iv, - (GLint location, - GLsizei count, - const GLint * value)) -COGL_EXT_FUNCTION (void, glUniform2iv, - (GLint location, - GLsizei count, - const GLint * value)) -COGL_EXT_FUNCTION (void, glUniform3iv, - (GLint location, - GLsizei count, - const GLint * value)) -COGL_EXT_FUNCTION (void, glUniform4iv, - (GLint location, - GLsizei count, - const GLint * value)) -COGL_EXT_FUNCTION (void, glUniformMatrix2fv, - (GLint location, - GLsizei count, - GLboolean transpose, - const GLfloat *value)) -COGL_EXT_FUNCTION (void, glUniformMatrix3fv, - (GLint location, - GLsizei count, - GLboolean transpose, - const GLfloat *value)) -COGL_EXT_FUNCTION (void, glUniformMatrix4fv, - (GLint location, - GLsizei count, - GLboolean transpose, - const GLfloat *value)) -COGL_EXT_END () - -/* These functions are provided by GL_ARB_vertex_shader or are in GL - * 2.0 core */ -COGL_EXT_BEGIN (vertex_shaders, 2, 0, - COGL_EXT_IN_GLES2, - "ARB\0", - "vertex_shader\0") -COGL_EXT_FUNCTION (void, glVertexAttribPointer, - (GLuint index, - GLint size, - GLenum type, - GLboolean normalized, - GLsizei stride, - const GLvoid *pointer)) -COGL_EXT_FUNCTION (void, glEnableVertexAttribArray, - (GLuint index)) -COGL_EXT_FUNCTION (void, glDisableVertexAttribArray, - (GLuint index)) -COGL_EXT_FUNCTION (void, glVertexAttrib1fv, - (GLuint indx, const GLfloat* values)) -COGL_EXT_FUNCTION (void, glVertexAttrib2fv, - (GLuint indx, const GLfloat* values)) -COGL_EXT_FUNCTION (void, glVertexAttrib3fv, - (GLuint indx, const GLfloat* values)) -COGL_EXT_FUNCTION (void, glVertexAttrib4f, - (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)) -COGL_EXT_FUNCTION (void, glVertexAttrib4fv, - (GLuint indx, const GLfloat* values)) -COGL_EXT_FUNCTION (GLint, glGetAttribLocation, - (GLuint program, const char *name)) -COGL_EXT_FUNCTION (void, glBindAttribLocation, - (GLuint program, - GLuint index, - const GLchar* name)) -COGL_EXT_END () diff --git a/mutter/cogl/cogl/gl-prototypes/cogl-in-gles-core-functions.h b/mutter/cogl/cogl/gl-prototypes/cogl-in-gles-core-functions.h deleted file mode 100644 index b298bce..0000000 --- a/mutter/cogl/cogl/gl-prototypes/cogl-in-gles-core-functions.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009, 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This is included multiple times with different definitions for - * these macros. The macros are given the following arguments: - * - * COGL_EXT_BEGIN: - * - * @name: a unique symbol name for this feature - * - * @min_gl_major: the major part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * @min_gl_minor: the minor part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * - * @gles_availability: flags to specify which versions of GLES the - * functions are available in. Should be a combination of - * COGL_EXT_IN_GLES and COGL_EXT_IN_GLES2. - * - * @extension_suffixes: A zero-separated list of suffixes in a - * string. These are appended to the extension name to get a complete - * extension name to try. The suffix is also appended to all of the - * function names. The suffix can optionally include a ':' to specify - * an alternate suffix for the function names. - * - * @extension_names: A list of extension names to try. If any of these - * extensions match then it will be used. - */ - -COGL_EXT_BEGIN (only_in_both_gles, - 4, 1, - COGL_EXT_IN_GLES2, - "ARB\0", - "ES2_compatibility\0") -COGL_EXT_FUNCTION (void, glDepthRangef, - (GLfloat near_val, GLfloat far_val)) -COGL_EXT_END () diff --git a/mutter/cogl/cogl/gl-prototypes/cogl-in-gles2-core-functions.h b/mutter/cogl/cogl/gl-prototypes/cogl-in-gles2-core-functions.h deleted file mode 100644 index 113b99b..0000000 --- a/mutter/cogl/cogl/gl-prototypes/cogl-in-gles2-core-functions.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009, 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This is included multiple times with different definitions for - * these macros. The macros are given the following arguments: - * - * COGL_EXT_BEGIN: - * - * @name: a unique symbol name for this feature - * - * @min_gl_major: the major part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * @min_gl_minor: the minor part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * - * @gles_availability: flags to specify which versions of GLES the - * functions are available in. Should be a combination of - * COGL_EXT_IN_GLES and COGL_EXT_IN_GLES2. - * - * @extension_suffixes: A zero-separated list of suffixes in a - * string. These are appended to the extension name to get a complete - * extension name to try. The suffix is also appended to all of the - * function names. The suffix can optionally include a ':' to specify - * an alternate suffix for the function names. - * - * @extension_names: A list of extension names to try. If any of these - * extensions match then it will be used. - */ - -COGL_EXT_BEGIN (offscreen, - 3, 0, - COGL_EXT_IN_GLES2, - /* for some reason the ARB version of this - extension doesn't have an ARB suffix for the - functions */ - "ARB:\0EXT\0OES\0", - "framebuffer_object\0") -COGL_EXT_FUNCTION (void, glGenRenderbuffers, - (GLsizei n, - GLuint *renderbuffers)) -COGL_EXT_FUNCTION (void, glDeleteRenderbuffers, - (GLsizei n, - const GLuint *renderbuffers)) -COGL_EXT_FUNCTION (void, glBindRenderbuffer, - (GLenum target, - GLuint renderbuffer)) -COGL_EXT_FUNCTION (void, glRenderbufferStorage, - (GLenum target, - GLenum internalformat, - GLsizei width, - GLsizei height)) -COGL_EXT_FUNCTION (void, glGenFramebuffers, - (GLsizei n, - GLuint *framebuffers)) -COGL_EXT_FUNCTION (void, glBindFramebuffer, - (GLenum target, - GLuint framebuffer)) -COGL_EXT_FUNCTION (void, glFramebufferTexture2D, - (GLenum target, - GLenum attachment, - GLenum textarget, - GLuint texture, - GLint level)) -COGL_EXT_FUNCTION (void, glFramebufferRenderbuffer, - (GLenum target, - GLenum attachment, - GLenum renderbuffertarget, - GLuint renderbuffer)) -COGL_EXT_FUNCTION (GLenum, glCheckFramebufferStatus, - (GLenum target)) -COGL_EXT_FUNCTION (void, glDeleteFramebuffers, - (GLsizei n, - const GLuint *framebuffers)) -COGL_EXT_FUNCTION (void, glGenerateMipmap, - (GLenum target)) -COGL_EXT_FUNCTION (void, glGetFramebufferAttachmentParameteriv, - (GLenum target, - GLenum attachment, - GLenum pname, - GLint *params)) -COGL_EXT_END () - -COGL_EXT_BEGIN (blending, 1, 2, - COGL_EXT_IN_GLES2, - "\0", - "\0") -COGL_EXT_FUNCTION (void, glBlendColor, - (GLclampf red, - GLclampf green, - GLclampf blue, - GLclampf alpha)) -COGL_EXT_END () - -/* Optional, declared in 1.4 or GLES 1.2 */ -COGL_EXT_BEGIN (blend_func_separate, 1, 4, - COGL_EXT_IN_GLES2, - "EXT\0", - "blend_func_separate\0") -COGL_EXT_FUNCTION (void, glBlendFuncSeparate, - (GLenum srcRGB, - GLenum dstRGB, - GLenum srcAlpha, - GLenum dstAlpha)) -COGL_EXT_END () - -/* Optional, declared in 2.0 */ -COGL_EXT_BEGIN (blend_equation_separate, 2, 0, - COGL_EXT_IN_GLES2, - "EXT\0", - "blend_equation_separate\0") -COGL_EXT_FUNCTION (void, glBlendEquationSeparate, - (GLenum modeRGB, - GLenum modeAlpha)) -COGL_EXT_END () diff --git a/mutter/cogl/cogl/meson.build b/mutter/cogl/cogl/meson.build deleted file mode 100644 index 261edbd..0000000 --- a/mutter/cogl/cogl/meson.build +++ /dev/null @@ -1,462 +0,0 @@ -cogl_cogl_includesubdir = cogl_includesubdir / 'cogl' -cogl_cogl_includedir = cogl_includedir / 'cogl' - -cogl_gir_includes = [ - 'GL-1.0', - 'GObject-2.0', - 'Graphene-1.0', -] - -if have_introspection - cogl_gir_includes += [ - libmutter_mtk_gir[0], - ] -endif - -cogl_deprecated_headers = [ - 'deprecated/cogl-program.h', - 'deprecated/cogl-shader.h', - 'deprecated/cogl-clutter.h', -] - -cogl_headers = [ - 'cogl.h', - 'cogl-atlas-texture.h', - 'cogl-attribute-buffer.h', - 'cogl-attribute.h', - 'cogl-bitmap.h', - 'cogl-color.h', - 'cogl1-context.h', - 'cogl-context.h', - 'cogl-depth-state.h', - 'cogl-display.h', - 'cogl-dma-buf-handle.h', - 'cogl-fence.h', - 'cogl-framebuffer.h', - 'cogl-frame-info.h', - 'cogl-glib-source.h', - 'cogl-graphene.h', - 'cogl-index-buffer.h', - 'cogl-indices.h', - 'cogl-macros.h', - 'cogl-matrix-stack.h', - 'cogl-meta-texture.h', - 'cogl-offscreen.h', - 'cogl-onscreen.h', - 'cogl-onscreen-template.h', - 'cogl-output.h', - 'cogl-pipeline.h', - 'cogl-pipeline-layer-state.h', - 'cogl-pipeline-state.h', - 'cogl-pixel-buffer.h', - 'cogl-poll.h', - 'cogl-primitive.h', - 'cogl-primitive-texture.h', - 'cogl-renderer.h', - 'cogl-scanout.h', - 'cogl-snippet.h', - 'cogl-sub-texture.h', - 'cogl-swap-chain.h', - 'cogl-texture-2d.h', - 'cogl-texture-2d-sliced.h', - 'cogl-texture.h', - 'cogl-trace.h', - 'cogl-types.h', -] - -cogl_nonintrospected_headers = [ -] - -cogl_nodist_headers = [ -] - -cogl_noop_driver_sources = [ - 'driver/nop/cogl-attribute-nop-private.h', - 'driver/nop/cogl-attribute-nop.c', - 'driver/nop/cogl-clip-stack-nop-private.h', - 'driver/nop/cogl-clip-stack-nop.c', - 'driver/nop/cogl-driver-nop.c', - 'driver/nop/cogl-nop-framebuffer.c', - 'driver/nop/cogl-nop-framebuffer.h', - 'driver/nop/cogl-texture-2d-nop-private.h', - 'driver/nop/cogl-texture-2d-nop.c', -] - -cogl_gl_prototype_headers = [ - 'gl-prototypes/cogl-core-functions.h', - 'gl-prototypes/cogl-gles2-functions.h', - 'gl-prototypes/cogl-glsl-functions.h', - 'gl-prototypes/cogl-in-gles-core-functions.h', - 'gl-prototypes/cogl-in-gles2-core-functions.h', -] - -cogl_common_driver_sources = [ - 'driver/gl/cogl-attribute-gl-private.h', - 'driver/gl/cogl-attribute-gl.c', - 'driver/gl/cogl-bitmap-gl-private.h', - 'driver/gl/cogl-bitmap-gl.c', - 'driver/gl/cogl-buffer-gl-private.h', - 'driver/gl/cogl-buffer-gl.c', - 'driver/gl/cogl-clip-stack-gl-private.h', - 'driver/gl/cogl-clip-stack-gl.c', - 'driver/gl/cogl-framebuffer-gl-private.h', - 'driver/gl/cogl-framebuffer-gl.c', - 'driver/gl/cogl-gl-framebuffer-back.c', - 'driver/gl/cogl-gl-framebuffer-back.h', - 'driver/gl/cogl-gl-framebuffer-fbo.c', - 'driver/gl/cogl-gl-framebuffer-fbo.h', - 'driver/gl/cogl-pipeline-fragend-glsl-private.h', - 'driver/gl/cogl-pipeline-fragend-glsl.c', - 'driver/gl/cogl-pipeline-opengl-private.h', - 'driver/gl/cogl-pipeline-opengl.c', - 'driver/gl/cogl-pipeline-progend-glsl-private.h', - 'driver/gl/cogl-pipeline-progend-glsl.c', - 'driver/gl/cogl-pipeline-vertend-glsl-private.h', - 'driver/gl/cogl-pipeline-vertend-glsl.c', - 'driver/gl/cogl-texture-2d-gl-private.h', - 'driver/gl/cogl-texture-2d-gl.c', - 'driver/gl/cogl-texture-gl-private.h', - 'driver/gl/cogl-texture-gl.c', - 'driver/gl/cogl-util-gl-private.h', - 'driver/gl/cogl-util-gl.c', -] - -gl_driver_sources = [ - 'driver/gl/gl/cogl-driver-gl.c', - 'driver/gl/gl/cogl-texture-driver-gl.c', -] - -gles_driver_sources = [ - 'driver/gl/gles/cogl-driver-gles.c', - 'driver/gl/gles/cogl-texture-driver-gles.c', -] - -cogl_driver_sources = [ - cogl_noop_driver_sources, - cogl_common_driver_sources, -] - -if have_gl - cogl_driver_sources += gl_driver_sources -endif - -if have_gles2 - cogl_driver_sources += gles_driver_sources -endif - -cogl_sources = [ - cogl_driver_sources, - 'cogl-atlas-texture-private.h', - 'cogl-atlas-texture.c', - 'cogl-atlas.c', - 'cogl-atlas.h', - 'cogl-attribute-buffer-private.h', - 'cogl-attribute-buffer.c', - 'cogl-attribute-private.h', - 'cogl-attribute.c', - 'cogl-bitmap-conversion.c', - 'cogl-bitmap-packing.h', - 'cogl-bitmap-private.h', - 'cogl-bitmap.c', - 'cogl-bitmask.c', - 'cogl-bitmask.h', - 'cogl-blend-string.c', - 'cogl-blend-string.h', - 'cogl-blit.c', - 'cogl-blit.h', - 'cogl-boxed-value.c', - 'cogl-boxed-value.h', - 'cogl-buffer-private.h', - 'cogl-buffer.c', - 'cogl-clip-stack.c', - 'cogl-clip-stack.h', - 'cogl-closure-list-private.h', - 'cogl-closure-list.c', - 'cogl-color-private.h', - 'cogl-color.c', - 'cogl-context-private.h', - 'cogl-context.c', - 'cogl-cpu-caps.c', - 'cogl-cpu-caps.h', - 'cogl-debug-options.h', - 'cogl-debug.c', - 'cogl-debug.h', - 'cogl-depth-state-private.h', - 'cogl-depth-state.c', - 'cogl-display-private.h', - 'cogl-display.c', - 'cogl-display.h', - 'cogl-dma-buf-handle.c', - 'cogl-driver.h', - 'cogl-feature-private.c', - 'cogl-feature-private.h', - 'cogl-fence-private.h', - 'cogl-fence.c', - 'cogl-flags.h', - 'cogl-frame-info-private.h', - 'cogl-frame-info.c', - 'cogl-framebuffer-driver.c', - 'cogl-framebuffer-driver.h', - 'cogl-framebuffer-private.h', - 'cogl-framebuffer.c', - 'cogl-glib-source.c', - 'cogl-gl-header.h', - 'cogl-glsl-shader-boilerplate.h', - 'cogl-graphene.c', - 'cogl-half-float.c', - 'cogl-half-float.h', - 'cogl-i18n-private.h', - 'cogl-index-buffer-private.h', - 'cogl-index-buffer.c', - 'cogl-indices-private.h', - 'cogl-indices.c', - 'cogl-journal-private.h', - 'cogl-journal.c', - 'cogl-list.c', - 'cogl-list.h', - 'cogl-magazine-private.h', - 'cogl-magazine.c', - 'cogl-matrix-stack-private.h', - 'cogl-matrix-stack.c', - 'cogl-memory-stack-private.h', - 'cogl-memory-stack.c', - 'cogl-meta-texture.c', - 'cogl-mutter.h', - 'cogl-node-private.h', - 'cogl-node.c', - 'cogl-offscreen-private.h', - 'cogl-offscreen.c', - 'cogl-onscreen-private.h', - 'cogl-onscreen-template-private.h', - 'cogl-onscreen-template.c', - 'cogl-onscreen-template.h', - 'cogl-onscreen.c', - 'cogl-output-private.h', - 'cogl-output.c', - 'cogl-pipeline-cache-private.h', - 'cogl-pipeline-cache.c', - 'cogl-pipeline-cache.h', - 'cogl-pipeline-debug.c', - 'cogl-pipeline-hash-table.c', - 'cogl-pipeline-hash-table.h', - 'cogl-pipeline-layer-private.h', - 'cogl-pipeline-layer-state-private.h', - 'cogl-pipeline-layer-state.c', - 'cogl-pipeline-layer.c', - 'cogl-pipeline-private.h', - 'cogl-pipeline-snippet-private.h', - 'cogl-pipeline-snippet.c', - 'cogl-pipeline-state-private.h', - 'cogl-pipeline-state.c', - 'cogl-pipeline.c', - 'cogl-pixel-buffer-private.h', - 'cogl-pixel-buffer.c', - 'cogl-pixel-format.c', - 'cogl-point-in-poly-private.h', - 'cogl-point-in-poly.c', - 'cogl-poll-private.h', - 'cogl-poll.c', - 'cogl-primitive-private.h', - 'cogl-primitive-texture.c', - 'cogl-primitive.c', - 'cogl-primitives-private.h', - 'cogl-primitives.c', - 'cogl-private.h', - 'cogl-profile.c', - 'cogl-profile.h', - 'cogl-rectangle-map.c', - 'cogl-rectangle-map.h', - 'cogl-renderer-private.h', - 'cogl-renderer.c', - 'cogl-renderer.h', - 'cogl-sampler-cache-private.h', - 'cogl-sampler-cache.c', - 'cogl-scanout.c', - 'cogl-snippet-private.h', - 'cogl-snippet.c', - 'cogl-soft-float.c', - 'cogl-soft-float.h', - 'cogl-spans.c', - 'cogl-spans.h', - 'cogl-sub-texture-private.h', - 'cogl-sub-texture.c', - 'cogl-swap-chain-private.h', - 'cogl-swap-chain.c', - 'cogl-swap-chain.h', - 'cogl-texture-2d-private.h', - 'cogl-texture-2d-sliced-private.h', - 'cogl-texture-2d-sliced.c', - 'cogl-texture-2d.c', - 'cogl-texture-driver.h', - 'cogl-texture-private.h', - 'cogl-texture.c', - 'cogl-trace.c', - 'cogl-util.c', - 'cogl-util.h', - 'cogl.c', - 'deprecated/cogl-clutter.c', - 'deprecated/cogl-program-private.h', - 'deprecated/cogl-program.c', - 'deprecated/cogl-shader-private.h', - 'deprecated/cogl-shader.c', - 'gl-prototypes/cogl-all-functions.h', - 'winsys/cogl-winsys-private.h', - 'winsys/cogl-winsys.c', -] - -if have_x11 - cogl_gir_includes += ['xlib-2.0'] - cogl_nonintrospected_headers += [ - 'cogl-xlib.h', - 'winsys/cogl-texture-pixmap-x11.h', - ] - cogl_sources += [ - 'cogl-x11-onscreen.c', - 'cogl-x11-onscreen.h', - 'cogl-x11-renderer-private.h', - 'cogl-xlib-renderer-private.h', - 'cogl-xlib-renderer.c', - 'winsys/cogl-texture-pixmap-x11-private.h', - 'winsys/cogl-texture-pixmap-x11.c', - ] - cogl_headers += [ - 'cogl-xlib-renderer.h' - ] -endif - -if have_glx - cogl_nonintrospected_headers += [ - 'winsys/cogl-glx.h', - ] - cogl_sources += [ - 'winsys/cogl-glx-display-private.h', - 'winsys/cogl-glx-renderer-private.h', - 'winsys/cogl-onscreen-glx.c', - 'winsys/cogl-onscreen-glx.h', - 'winsys/cogl-winsys-glx-feature-functions.h', - 'winsys/cogl-winsys-glx-private.h', - 'winsys/cogl-winsys-glx.c', - ] -endif - -if have_egl - cogl_nonintrospected_headers += [ - 'cogl-egl.h', - ] - cogl_sources += [ - 'cogl-egl-private.h', - 'winsys/cogl-onscreen-egl.c', - 'winsys/cogl-onscreen-egl.h', - 'winsys/cogl-winsys-egl-feature-functions.h', - 'winsys/cogl-winsys-egl-private.h', - 'winsys/cogl-winsys-egl.c', - ] -endif - -if have_egl_xlib - cogl_sources += [ - 'winsys/cogl-onscreen-xlib.c', - 'winsys/cogl-onscreen-xlib.h', - 'winsys/cogl-winsys-egl-x11-private.h', - 'winsys/cogl-winsys-egl-x11.c', - ] -endif - -cogl_enum_headers = [ - 'cogl-buffer.h', - 'cogl-pixel-format.h', -] - -cogl_headers += [ - cogl_enum_headers, -] - -cogl_enums = gnome.mkenums('cogl-enums', - sources: cogl_enum_headers, - c_template: 'cogl-enum-types.c.in', - h_template: 'cogl-enum-types.h.in', - install_dir: cogl_cogl_includedir, - install_header: true, -) - -cogl_sources += [cogl_enums[0]] - -cogl_introspected_headers = [ - cogl_enums[1], - cogl_headers, - cogl_deprecated_headers, -] - -cogl_headers_all = [ - cogl_introspected_headers, - cogl_nonintrospected_headers, - cogl_deprecated_headers, -] - -libmutter_cogl_name = 'mutter-cogl-' + libmutter_api_version -libmutter_cogl = shared_library(libmutter_cogl_name, - sources: [cogl_sources, cogl_headers_all], - version: '0.0.0', - soversion: 0, - c_args: cogl_c_args, - include_directories: [cogl_includepath, top_includepath], - dependencies: cogl_deps, - gnu_symbol_visibility: 'hidden', - install_rpath: pkglibdir, - install_dir: pkglibdir, - install: true, -) -libmutter_cogl_dep = declare_dependency( - sources: [cogl_enums[1]], - dependencies: [cogl_deps], - link_with: libmutter_cogl, -) - -if have_introspection - libmutter_cogl_gir = gnome.generate_gir(libmutter_cogl, - sources: cogl_introspected_headers, - nsversion: libmutter_api_version, - namespace: 'Cogl', - export_packages: [libmutter_cogl_name], - includes: cogl_gir_includes, - dependencies: [cogl_deps], - extra_args: introspection_args + [ - '-UCOGL_COMPILATION', - '-D__COGL_H_INSIDE__', - '-D__COGL_XLIB_H_INSIDE__', - '-D__COGL_EGL_H_INSIDE__', - '-D__COGL_GLX_H_INSIDE__', - '-DCOGL_GIR_SCANNING', - ], - header: 'cogl/cogl.h', - kwargs: introspection_common, - ) -endif - -install_headers([ - cogl_headers, - cogl_nonintrospected_headers, - ], - subdir: cogl_cogl_includesubdir) - -install_headers([ - cogl_deprecated_headers, - ], - subdir: cogl_cogl_includesubdir / 'deprecated') - -install_headers(cogl_gl_prototype_headers, - subdir: cogl_cogl_includesubdir / 'gl-prototypes') - -pkg.generate(libmutter_cogl, - name: 'Cogl', - filebase: libmutter_cogl_name, - description: 'An object oriented GL/GLES Abstraction/Utility Layer in mutter', - libraries: [m_dep], - subdirs: pkgname / 'cogl', - requires: [cogl_pkg_deps], - version: meson.project_version(), - variables: [ - 'apiversion=' + libmutter_api_version, - ], - install_dir: pcdir, -) diff --git a/mutter/cogl/cogl/winsys/cogl-glx-display-private.h b/mutter/cogl/cogl/winsys/cogl-glx-display-private.h deleted file mode 100644 index 87767cd..0000000 --- a/mutter/cogl/cogl/winsys/cogl-glx-display-private.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - - -typedef struct _CoglGLXCachedConfig -{ - /* This will be -1 if there is no cached config in this slot */ - int depth; - gboolean found; - GLXFBConfig fb_config; - gboolean stereo; - gboolean can_mipmap; -} CoglGLXCachedConfig; - -#define COGL_GLX_N_CACHED_CONFIGS 6 - -typedef struct _CoglGLXDisplay -{ - CoglGLXCachedConfig glx_cached_configs[COGL_GLX_N_CACHED_CONFIGS]; - - gboolean found_fbconfig; - gboolean is_direct; - gboolean have_vblank_counter; - gboolean can_vblank_wait; - GLXFBConfig fbconfig; - - /* Single context for all wins */ - GLXContext glx_context; - GLXWindow dummy_glxwin; - Window dummy_xwin; -} CoglGLXDisplay; diff --git a/mutter/cogl/cogl/winsys/cogl-glx-renderer-private.h b/mutter/cogl/cogl/winsys/cogl-glx-renderer-private.h deleted file mode 100644 index 321bad8..0000000 --- a/mutter/cogl/cogl/winsys/cogl-glx-renderer-private.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include - -#include "cogl/cogl-xlib-renderer-private.h" - -typedef struct _CoglGLXRenderer -{ - int glx_major; - int glx_minor; - - int glx_error_base; - int glx_event_base; - - /* Vblank stuff */ - int dri_fd; - - /* enumeration with relatioship between OML_sync_control - * UST (unadjusted-system-time) and the system clock */ - enum -{ - COGL_GLX_UST_IS_UNKNOWN, - COGL_GLX_UST_IS_GETTIMEOFDAY, - COGL_GLX_UST_IS_MONOTONIC_TIME, - COGL_GLX_UST_IS_OTHER - } ust_type; - - /* GModule pointing to libGL which we use to get glX functions out of */ - GModule *libgl_module; - - CoglClosure *flush_notifications_idle; - - /* Copy of the winsys features that are based purely on the - * information we can get without using a GL context. We want to - * determine this before we have a context so that we can use the - * function pointers from the extensions earlier. This is necessary - * to use the glXCreateContextAttribs function. */ - unsigned long base_winsys_features - [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_WINSYS_FEATURE_N_FEATURES)]; - - /* Function pointers for core GLX functionality. We can't just link - against these directly because we need to conditionally load - libGL when we are using GLX so that it won't conflict with a GLES - library if we are using EGL + GLES. These are just the functions - that we want to use before calling glXGetProcAddress */ - Bool - (* glXQueryExtension) (Display *dpy, int *errorb, int *event); - const char * - (* glXQueryExtensionsString) (Display *dpy, int screen); - Bool - (* glXQueryVersion) (Display *dpy, int *maj, int *min); - void * - (* glXGetProcAddress) (const GLubyte *procName); - - int - (* glXQueryDrawable) (Display *dpy, GLXDrawable drawable, - int attribute, unsigned int *value); - - /* Function pointers for GLX specific extensions */ -#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f, g) - -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - ret (APIENTRY * name) args; - -#define COGL_WINSYS_FEATURE_END() - -#include "cogl/winsys/cogl-winsys-glx-feature-functions.h" - -#undef COGL_WINSYS_FEATURE_BEGIN -#undef COGL_WINSYS_FEATURE_FUNCTION -#undef COGL_WINSYS_FEATURE_END -} CoglGLXRenderer; diff --git a/mutter/cogl/cogl/winsys/cogl-glx.h b/mutter/cogl/cogl/winsys/cogl-glx.h deleted file mode 100644 index 7f6e652..0000000 --- a/mutter/cogl/cogl/winsys/cogl-glx.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Cogl - * - * A Low-Level GPU Graphics and Utilities API - * - * Copyright (C) 2014 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -/* NB: this is a top-level header that can be included directly but we - * want to be careful not to define __COGL_H_INSIDE__ when this is - * included internally while building Cogl itself since - * __COGL_H_INSIDE__ is used in headers to guard public vs private api - * definitions - */ -#ifndef COGL_COMPILATION - -/* Note: When building Cogl .gir we explicitly define - * __COGL_GLX_H_INSIDE__ */ -#ifndef __COGL_GLX_H_INSIDE__ -#define __COGL_GLX_H_INSIDE__ -#endif - -/* Note: When building Cogl .gir we explicitly define - * __COGL_H_INSIDE__ */ -#ifndef __COGL_H_INSIDE__ -#define __COGL_H_INSIDE__ -#define __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_GLX_ -#endif - -#endif /* COGL_COMPILATION */ - - -#include - -#include "cogl/cogl-types.h" - -/* The gobject introspection scanner seems to parse public headers in - * isolation which means we need to be extra careful about how we - * define and undefine __COGL_H_INSIDE__ used to detect when internal - * headers are incorrectly included by developers. In the gobject - * introspection case we have to manually define __COGL_H_INSIDE__ as - * a commandline argument for the scanner which means we must be - * careful not to undefine it in a header... - */ -#ifdef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_GLX_ -#warning -#undef __COGL_H_INSIDE__ -#undef __COGL_GLX_H_INSIDE__ -#undef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_GLX_ -#endif diff --git a/mutter/cogl/cogl/winsys/cogl-onscreen-egl.c b/mutter/cogl/cogl/winsys/cogl-onscreen-egl.c deleted file mode 100644 index 4401096..0000000 --- a/mutter/cogl/cogl/winsys/cogl-onscreen-egl.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "config.h" - -#include "cogl/winsys/cogl-onscreen-egl.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-frame-info-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-trace.h" -#include "cogl/winsys/cogl-winsys-egl-private.h" - -typedef struct _CoglOnscreenEglPrivate -{ - EGLSurface egl_surface; - - /* Can use PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC (or the EXT variant) */ - EGLBoolean (*pf_eglSwapBuffersWithDamage) (EGLDisplay, EGLSurface, const EGLint *, EGLint); -} CoglOnscreenEglPrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (CoglOnscreenEgl, cogl_onscreen_egl, - COGL_TYPE_ONSCREEN) - -gboolean -cogl_onscreen_egl_choose_config (CoglOnscreenEgl *onscreen_egl, - EGLConfig *out_egl_config, - GError **error) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen_egl); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplay *display = context->display; - CoglRenderer *renderer = display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - const CoglFramebufferConfig *config; - EGLint attributes[MAX_EGL_CONFIG_ATTRIBS]; - EGLConfig egl_config; - EGLint config_count = 0; - EGLBoolean status; - - config = cogl_framebuffer_get_config (framebuffer); - cogl_display_egl_determine_attributes (display, config, attributes); - - status = eglChooseConfig (egl_renderer->edpy, - attributes, - &egl_config, 1, - &config_count); - if (status != EGL_TRUE || config_count == 0) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "Failed to find a suitable EGL configuration"); - return FALSE; - } - - if (config->samples_per_pixel) - { - EGLint samples; - status = eglGetConfigAttrib (egl_renderer->edpy, - egl_config, - EGL_SAMPLES, &samples); - g_return_val_if_fail (status == EGL_TRUE, TRUE); - cogl_framebuffer_update_samples_per_pixel (framebuffer, samples); - } - - *out_egl_config = egl_config; - return TRUE; -} - -static void -cogl_onscreen_egl_dispose (GObject *object) -{ - CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (object); - CoglOnscreenEglPrivate *priv = - cogl_onscreen_egl_get_instance_private (onscreen_egl); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplayEGL *egl_display = context->display->winsys; - CoglRenderer *renderer = context->display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - - G_OBJECT_CLASS (cogl_onscreen_egl_parent_class)->dispose (object); - - if (priv->egl_surface != EGL_NO_SURFACE) - { - /* Cogl always needs a valid context bound to something so if we - * are destroying the onscreen that is currently bound we'll - * switch back to the dummy drawable. */ - if ((egl_display->dummy_surface != EGL_NO_SURFACE || - (egl_renderer->private_features & - COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT) != 0) && - (egl_display->current_draw_surface == priv->egl_surface || - egl_display->current_read_surface == priv->egl_surface)) - { - _cogl_winsys_egl_make_current (context->display, - egl_display->dummy_surface, - egl_display->dummy_surface, - egl_display->current_context); - } - - if (eglDestroySurface (egl_renderer->edpy, priv->egl_surface) - == EGL_FALSE) - g_warning ("Failed to destroy EGL surface"); - priv->egl_surface = EGL_NO_SURFACE; - } -} - -static void -bind_onscreen_with_context (CoglOnscreen *onscreen, - EGLContext egl_context) -{ - CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen); - CoglOnscreenEglPrivate *priv = - cogl_onscreen_egl_get_instance_private (onscreen_egl); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - - gboolean status = _cogl_winsys_egl_make_current (context->display, - priv->egl_surface, - priv->egl_surface, - egl_context); - if (status) - { - CoglRenderer *renderer = context->display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - - if (egl_renderer->pf_eglSwapBuffersWithDamageKHR) - { - priv->pf_eglSwapBuffersWithDamage = - egl_renderer->pf_eglSwapBuffersWithDamageKHR; - } - else - { - priv->pf_eglSwapBuffersWithDamage = - egl_renderer->pf_eglSwapBuffersWithDamageEXT; - } - - eglSwapInterval (egl_renderer->edpy, 1); - } -} - -static void -cogl_onscreen_egl_bind (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplayEGL *egl_display = context->display->winsys; - - bind_onscreen_with_context (onscreen, egl_display->egl_context); -} - -#ifndef EGL_BUFFER_AGE_EXT -#define EGL_BUFFER_AGE_EXT 0x313D -#endif - -static int -cogl_onscreen_egl_get_buffer_age (CoglOnscreen *onscreen) -{ - CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen); - CoglOnscreenEglPrivate *priv = - cogl_onscreen_egl_get_instance_private (onscreen_egl); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - CoglDisplayEGL *egl_display = context->display->winsys; - EGLSurface surface = priv->egl_surface; - static gboolean warned = FALSE; - int age = 0; - - if (!(egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_BUFFER_AGE)) - return 0; - - if (!_cogl_winsys_egl_make_current (context->display, - surface, surface, - egl_display->egl_context)) - return 0; - - if (!eglQuerySurface (egl_renderer->edpy, surface, EGL_BUFFER_AGE_EXT, &age)) - { - if (!warned) - g_critical ("Failed to query buffer age, got error %x", eglGetError ()); - warned = TRUE; - } - else - { - warned = FALSE; - } - - return age; -} - -static void -cogl_onscreen_egl_swap_region (CoglOnscreen *onscreen, - const int *user_rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data) -{ - CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen); - CoglOnscreenEglPrivate *priv = - cogl_onscreen_egl_get_instance_private (onscreen_egl); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - int framebuffer_height = cogl_framebuffer_get_height (framebuffer); - int *rectangles = g_alloca (sizeof (int) * n_rectangles * 4); - int i; - - /* eglSwapBuffersRegion expects rectangles relative to the - * bottom left corner but we are given rectangles relative to - * the top left so we need to flip them... */ - memcpy (rectangles, user_rectangles, sizeof (int) * n_rectangles * 4); - for (i = 0; i < n_rectangles; i++) - { - int *rect = &rectangles[4 * i]; - rect[1] = framebuffer_height - rect[1] - rect[3]; - } - - /* At least for eglSwapBuffers the EGL spec says that the surface to - swap must be bound to the current context. It looks like Mesa - also validates that this is the case for eglSwapBuffersRegion so - we must bind here too */ - cogl_context_flush_framebuffer_state (context, - COGL_FRAMEBUFFER (onscreen), - COGL_FRAMEBUFFER (onscreen), - COGL_FRAMEBUFFER_STATE_BIND); - - if (egl_renderer->pf_eglSwapBuffersRegion (egl_renderer->edpy, - priv->egl_surface, - n_rectangles, - rectangles) == EGL_FALSE) - g_warning ("Error reported by eglSwapBuffersRegion"); -} - -static void -cogl_onscreen_egl_queue_damage_region (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles) -{ - CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen); - CoglOnscreenEglPrivate *priv = - cogl_onscreen_egl_get_instance_private (onscreen_egl); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - - g_return_if_fail (n_rectangles > 0); - - if (!egl_renderer->pf_eglSetDamageRegion) - return; - - if (egl_renderer->pf_eglSetDamageRegion (egl_renderer->edpy, - priv->egl_surface, - rectangles, - n_rectangles) == EGL_FALSE) - g_warning ("Error reported by eglSetDamageRegion"); -} - -void -cogl_onscreen_egl_maybe_create_timestamp_query (CoglOnscreen *onscreen, - CoglFrameInfo *info) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - - if (!cogl_has_feature (context, COGL_FEATURE_ID_TIMESTAMP_QUERY)) - return; - - info->gpu_time_before_buffer_swap_ns = - cogl_context_get_gpu_time_ns (context); - info->cpu_time_before_buffer_swap_us = g_get_monotonic_time (); - - /* Set up a timestamp query for when all rendering will be finished. */ - info->timestamp_query = - cogl_framebuffer_create_timestamp_query (framebuffer); - - info->has_valid_gpu_rendering_duration = TRUE; -} - -static void -cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data) -{ - CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen); - CoglOnscreenEglPrivate *priv = - cogl_onscreen_egl_get_instance_private (onscreen_egl); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - - COGL_TRACE_BEGIN_SCOPED (CoglOnscreenEGLSwapBuffersWithDamage, - "Cogl::Onscreen::egl_swap_buffers_with_damage()"); - - /* The specification for EGL (at least in 1.4) says that the surface - needs to be bound to the current context for the swap to work - although it may change in future. Mesa explicitly checks for this - and just returns an error if this is not the case so we can't - just pretend this isn't in the spec. */ - cogl_context_flush_framebuffer_state (context, - COGL_FRAMEBUFFER (onscreen), - COGL_FRAMEBUFFER (onscreen), - COGL_FRAMEBUFFER_STATE_BIND); - - if (n_rectangles && priv->pf_eglSwapBuffersWithDamage) - { - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - size_t size = n_rectangles * sizeof (int) * 4; - int *flipped = alloca (size); - int i; - - memcpy (flipped, rectangles, size); - for (i = 0; i < n_rectangles; i++) - { - const int *rect = rectangles + 4 * i; - int *flip_rect = flipped + 4 * i; - - flip_rect[1] = - cogl_framebuffer_get_height (framebuffer) - rect[1] - rect[3]; - } - - if (priv->pf_eglSwapBuffersWithDamage (egl_renderer->edpy, - priv->egl_surface, - flipped, - n_rectangles) == EGL_FALSE) - g_warning ("Error reported by eglSwapBuffersWithDamage"); - } - else - eglSwapBuffers (egl_renderer->edpy, priv->egl_surface); -} - -void -cogl_onscreen_egl_set_egl_surface (CoglOnscreenEgl *onscreen_egl, - EGLSurface egl_surface) -{ - CoglOnscreenEglPrivate *priv = - cogl_onscreen_egl_get_instance_private (onscreen_egl); - - priv->egl_surface = egl_surface; -} - -EGLSurface -cogl_onscreen_egl_get_egl_surface (CoglOnscreenEgl *onscreen_egl) -{ - CoglOnscreenEglPrivate *priv = - cogl_onscreen_egl_get_instance_private (onscreen_egl); - - return priv->egl_surface; -} - -static void -cogl_onscreen_egl_init (CoglOnscreenEgl *onscreen_egl) -{ -} - -static void -cogl_onscreen_egl_class_init (CoglOnscreenEglClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - CoglOnscreenClass *onscreen_class = COGL_ONSCREEN_CLASS (klass); - - object_class->dispose = cogl_onscreen_egl_dispose; - - onscreen_class->bind = cogl_onscreen_egl_bind; - onscreen_class->queue_damage_region = - cogl_onscreen_egl_queue_damage_region; - onscreen_class->swap_buffers_with_damage = - cogl_onscreen_egl_swap_buffers_with_damage; - onscreen_class->swap_region = cogl_onscreen_egl_swap_region; - onscreen_class->get_buffer_age = cogl_onscreen_egl_get_buffer_age; -} diff --git a/mutter/cogl/cogl/winsys/cogl-onscreen-egl.h b/mutter/cogl/cogl/winsys/cogl-onscreen-egl.h deleted file mode 100644 index d4dda66..0000000 --- a/mutter/cogl/cogl/winsys/cogl-onscreen-egl.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#include "cogl/cogl-onscreen.h" -#include "cogl/winsys/cogl-winsys-egl-private.h" - -#define COGL_TYPE_ONSCREEN_EGL (cogl_onscreen_egl_get_type ()) -COGL_EXPORT -G_DECLARE_DERIVABLE_TYPE (CoglOnscreenEgl, cogl_onscreen_egl, - COGL, ONSCREEN_EGL, - CoglOnscreen) - -struct _CoglOnscreenEglClass -{ - /*< private >*/ - CoglOnscreenClass parent_class; -}; - -COGL_EXPORT void -cogl_onscreen_egl_maybe_create_timestamp_query (CoglOnscreen *onscreen, - CoglFrameInfo *info); - -COGL_EXPORT void -cogl_onscreen_egl_set_egl_surface (CoglOnscreenEgl *onscreen_egl, - EGLSurface egl_surface); - -COGL_EXPORT EGLSurface -cogl_onscreen_egl_get_egl_surface (CoglOnscreenEgl *onscreen_egl); - -gboolean -cogl_onscreen_egl_choose_config (CoglOnscreenEgl *onscreen_egl, - EGLConfig *out_egl_config, - GError **error); diff --git a/mutter/cogl/cogl/winsys/cogl-onscreen-glx.c b/mutter/cogl/cogl/winsys/cogl-onscreen-glx.c deleted file mode 100644 index e61089b..0000000 --- a/mutter/cogl/cogl/winsys/cogl-onscreen-glx.c +++ /dev/null @@ -1,1124 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "config.h" - -#include "cogl/winsys/cogl-onscreen-glx.h" - -#include -#include - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-frame-info-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-x11-onscreen.h" -#include "cogl/cogl-xlib-renderer-private.h" -#include "cogl/winsys/cogl-glx-display-private.h" -#include "cogl/winsys/cogl-glx-renderer-private.h" -#include "cogl/winsys/cogl-winsys-glx-private.h" -#include "mtk/mtk-x11.h" - -struct _CoglOnscreenGlx -{ - CoglOnscreen parent; - - Window xwin; - int x, y; - CoglOutput *output; - - GLXDrawable glxwin; - uint32_t last_swap_vsync_counter; - uint32_t pending_sync_notify; - uint32_t pending_complete_notify; -}; - -static void -x11_onscreen_init_iface (CoglX11OnscreenInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (CoglOnscreenGlx, cogl_onscreen_glx, - COGL_TYPE_ONSCREEN, - G_IMPLEMENT_INTERFACE (COGL_TYPE_X11_ONSCREEN, - x11_onscreen_init_iface)) - -#define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask) - -static gboolean -cogl_onscreen_glx_allocate (CoglFramebuffer *framebuffer, - GError **error) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (framebuffer); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplay *display = context->display; - CoglGLXDisplay *glx_display = display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - Window xwin; - const CoglFramebufferConfig *config; - GLXFBConfig fbconfig; - GError *fbconfig_error = NULL; - - g_return_val_if_fail (glx_display->glx_context, FALSE); - - config = cogl_framebuffer_get_config (framebuffer); - if (!cogl_display_glx_find_fbconfig (display, config, - &fbconfig, - &fbconfig_error)) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to find suitable fbconfig for the GLX context: %s", - fbconfig_error->message); - g_error_free (fbconfig_error); - return FALSE; - } - - /* Update the real number of samples_per_pixel now that we have - * found an fbconfig... */ - if (config->samples_per_pixel) - { - int samples; - int status = glx_renderer->glXGetFBConfigAttrib (xlib_renderer->xdpy, - fbconfig, - GLX_SAMPLES, - &samples); - g_return_val_if_fail (status == Success, TRUE); - cogl_framebuffer_update_samples_per_pixel (framebuffer, samples); - } - - /* FIXME: We need to explicitly Select for ConfigureNotify events. - * We need to document that for windows we create then toolkits - * must be careful not to clear event mask bits that we select. - */ - { - int width; - int height; - XVisualInfo *xvisinfo; - XSetWindowAttributes xattr; - unsigned long mask; - int xerror; - - width = cogl_framebuffer_get_width (framebuffer); - height = cogl_framebuffer_get_height (framebuffer); - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - xvisinfo = glx_renderer->glXGetVisualFromFBConfig (xlib_renderer->xdpy, - fbconfig); - if (xvisinfo == NULL) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "Unable to retrieve the X11 visual of context's " - "fbconfig"); - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - return FALSE; - } - - /* window attributes */ - xattr.background_pixel = WhitePixel (xlib_renderer->xdpy, - DefaultScreen (xlib_renderer->xdpy)); - xattr.border_pixel = 0; - /* XXX: is this an X resource that we are leaking‽... */ - xattr.colormap = XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - xattr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK; - - mask = CWBorderPixel | CWColormap | CWEventMask; - - xwin = XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - 0, 0, - width, height, - 0, - xvisinfo->depth, - InputOutput, - xvisinfo->visual, - mask, &xattr); - - XFree (xvisinfo); - - XSync (xlib_renderer->xdpy, False); - xerror = mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy); - if (xerror) - { - char message[1000]; - XGetErrorText (xlib_renderer->xdpy, xerror, - message, sizeof (message)); - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "X error while creating Window for CoglOnscreen: %s", - message); - return FALSE; - } - } - - onscreen_glx->xwin = xwin; - - /* Try and create a GLXWindow to use with extensions dependent on - * GLX versions >= 1.3 that don't accept regular X Windows as GLX - * drawables. */ - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 3) - { - onscreen_glx->glxwin = - glx_renderer->glXCreateWindow (xlib_renderer->xdpy, - fbconfig, - onscreen_glx->xwin, - NULL); - } - -#ifdef GLX_INTEL_swap_event - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) - { - GLXDrawable drawable = - onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - - /* similarly to above, we unconditionally select this event - * because we rely on it to advance the master clock, and - * drive redraw/relayout, animations and event handling. - */ - glx_renderer->glXSelectEvent (xlib_renderer->xdpy, - drawable, - GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK); - } -#endif /* GLX_INTEL_swap_event */ - - return TRUE; -} - -static void -cogl_onscreen_glx_dispose (GObject *object) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (object); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglGLXDisplay *glx_display = context->display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - GLXDrawable drawable; - - G_OBJECT_CLASS (cogl_onscreen_glx_parent_class)->dispose (object); - - g_clear_object (&onscreen_glx->output); - - if (onscreen_glx->glxwin != None || - onscreen_glx->xwin != None) - { - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - drawable = - onscreen_glx->glxwin == None ? onscreen_glx->xwin : onscreen_glx->glxwin; - - /* Cogl always needs a valid context bound to something so if we are - * destroying the onscreen that is currently bound we'll switch back - * to the dummy drawable. Although the documentation for - * glXDestroyWindow states that a currently bound window won't - * actually be destroyed until it is unbound, it looks like this - * doesn't work if the X window itself is destroyed */ - if (drawable == cogl_context_glx_get_current_drawable (context)) - { - GLXDrawable dummy_drawable = (glx_display->dummy_glxwin == None ? - glx_display->dummy_xwin : - glx_display->dummy_glxwin); - - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - dummy_drawable, - dummy_drawable, - glx_display->glx_context); - cogl_context_glx_set_current_drawable (context, dummy_drawable); - } - - if (onscreen_glx->glxwin != None) - { - glx_renderer->glXDestroyWindow (xlib_renderer->xdpy, - onscreen_glx->glxwin); - onscreen_glx->glxwin = None; - } - - if (onscreen_glx->xwin != None) - { - XDestroyWindow (xlib_renderer->xdpy, onscreen_glx->xwin); - onscreen_glx->xwin = None; - } - else - { - onscreen_glx->xwin = None; - } - - XSync (xlib_renderer->xdpy, False); - - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - } -} - -static void -cogl_onscreen_glx_bind (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglGLXDisplay *glx_display = context->display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - GLXDrawable drawable; - - drawable = - onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - - if (cogl_context_glx_get_current_drawable (context) == drawable) - return; - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - COGL_NOTE (WINSYS, - "MakeContextCurrent dpy: %p, window: 0x%x, context: %p", - xlib_renderer->xdpy, - (unsigned int) drawable, - glx_display->glx_context); - - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - drawable, - drawable, - glx_display->glx_context); - - /* In case we are using GLX_SGI_swap_control for vblank syncing - * we need call glXSwapIntervalSGI here to make sure that it - * affects the current drawable. - * - * Note: we explicitly set to 0 when we aren't using the swap - * interval to synchronize since some drivers have a default - * swap interval of 1. Sadly some drivers even ignore requests - * to disable the swap interval. - * - * NB: glXSwapIntervalSGI applies to the context not the - * drawable which is why we can't just do this once when the - * framebuffer is allocated. - * - * FIXME: We should check for GLX_EXT_swap_control which allows - * per framebuffer swap intervals. GLX_MESA_swap_control also - * allows per-framebuffer swap intervals but the semantics tend - * to be more muddled since Mesa drivers tend to expose both the - * MESA and SGI extensions which should technically be mutually - * exclusive. - */ - if (glx_renderer->glXSwapInterval) - glx_renderer->glXSwapInterval (1); - - XSync (xlib_renderer->xdpy, False); - - /* FIXME: We should be reporting a GError here */ - if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy)) - { - g_warning ("X Error received while making drawable 0x%08lX current", - drawable); - return; - } - - cogl_context_glx_set_current_drawable (context, drawable); -} - -static void -ensure_ust_type (CoglRenderer *renderer, - GLXDrawable drawable) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - int64_t ust; - int64_t msc; - int64_t sbc; - struct timeval tv; - int64_t current_system_time; - int64_t current_monotonic_time; - - if (glx_renderer->ust_type != COGL_GLX_UST_IS_UNKNOWN) - return; - - glx_renderer->ust_type = COGL_GLX_UST_IS_OTHER; - - if (glx_renderer->glXGetSyncValues == NULL) - goto out; - - if (!glx_renderer->glXGetSyncValues (xlib_renderer->xdpy, drawable, - &ust, &msc, &sbc)) - goto out; - - /* This is the time source that existing (buggy) linux drm drivers - * use */ - gettimeofday (&tv, NULL); - current_system_time = (tv.tv_sec * G_GINT64_CONSTANT (1000000)) + tv.tv_usec; - - if (current_system_time > ust - 1000000 && - current_system_time < ust + 1000000) - { - glx_renderer->ust_type = COGL_GLX_UST_IS_GETTIMEOFDAY; - goto out; - } - - /* This is the time source that the newer (fixed) linux drm - * drivers use (Linux >= 3.8) */ - current_monotonic_time = g_get_monotonic_time (); - - if (current_monotonic_time > ust - 1000000 && - current_monotonic_time < ust + 1000000) - { - glx_renderer->ust_type = COGL_GLX_UST_IS_MONOTONIC_TIME; - goto out; - } - - out: - COGL_NOTE (WINSYS, "Classified OML system time as: %s", - glx_renderer->ust_type == COGL_GLX_UST_IS_GETTIMEOFDAY ? "gettimeofday" : - (glx_renderer->ust_type == COGL_GLX_UST_IS_MONOTONIC_TIME ? "monotonic" : - "other")); - return; -} - -static int64_t -ust_to_microseconds (CoglRenderer *renderer, - GLXDrawable drawable, - int64_t ust) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - - ensure_ust_type (renderer, drawable); - - switch (glx_renderer->ust_type) - { - case COGL_GLX_UST_IS_UNKNOWN: - g_assert_not_reached (); - break; - case COGL_GLX_UST_IS_GETTIMEOFDAY: - case COGL_GLX_UST_IS_MONOTONIC_TIME: - return ust; - case COGL_GLX_UST_IS_OTHER: - /* In this case the scale of UST is undefined so we can't easily - * scale to microseconds. - * - * For example the driver may be reporting the rdtsc CPU counter - * as UST values and so the scale would need to be determined - * empirically. - * - * Potentially we could block for a known duration within - * ensure_ust_type() to measure the timescale of UST but for now - * we just ignore unknown time sources */ - return 0; - } - - return 0; -} - -static gboolean -is_ust_monotonic (CoglRenderer *renderer, - GLXDrawable drawable) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - - ensure_ust_type (renderer, drawable); - - return (glx_renderer->ust_type == COGL_GLX_UST_IS_MONOTONIC_TIME); -} - -static void -_cogl_winsys_wait_for_vblank (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglGLXRenderer *glx_renderer; - CoglXlibRenderer *xlib_renderer; - CoglGLXDisplay *glx_display; - - glx_renderer = ctx->display->renderer->winsys; - xlib_renderer = _cogl_xlib_renderer_get_data (ctx->display->renderer); - glx_display = ctx->display->winsys; - - if (glx_display->can_vblank_wait) - { - CoglFrameInfo *info = cogl_onscreen_peek_tail_frame_info (onscreen); - info->flags |= COGL_FRAME_INFO_FLAG_VSYNC; - - if (glx_renderer->glXWaitForMsc) - { - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - Drawable drawable = onscreen_glx->glxwin; - int64_t ust; - int64_t msc; - int64_t sbc; - - glx_renderer->glXWaitForMsc (xlib_renderer->xdpy, drawable, - 0, 1, 0, - &ust, &msc, &sbc); - - if (is_ust_monotonic (ctx->display->renderer, drawable)) - { - info->presentation_time_us = - ust_to_microseconds (ctx->display->renderer, - drawable, - ust); - info->flags |= COGL_FRAME_INFO_FLAG_HW_CLOCK; - } - else - { - info->presentation_time_us = g_get_monotonic_time (); - } - - /* Intentionally truncating to lower 32 bits, same as DRM. */ - info->sequence = msc; - } - else - { - uint32_t current_count; - - glx_renderer->glXGetVideoSync (¤t_count); - glx_renderer->glXWaitVideoSync (2, - (current_count + 1) % 2, - ¤t_count); - - info->presentation_time_us = g_get_monotonic_time (); - } - } -} - -static uint32_t -_cogl_winsys_get_vsync_counter (CoglContext *ctx) -{ - uint32_t video_sync_count; - CoglGLXRenderer *glx_renderer; - - glx_renderer = ctx->display->renderer->winsys; - - glx_renderer->glXGetVideoSync (&video_sync_count); - - return video_sync_count; -} - -#ifndef GLX_BACK_BUFFER_AGE_EXT -#define GLX_BACK_BUFFER_AGE_EXT 0x20F4 -#endif - -static int -cogl_onscreen_glx_get_buffer_age (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - GLXDrawable drawable; - unsigned int age = 0; - - if (!_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE)) - return 0; - - cogl_onscreen_bind (onscreen); - - drawable = onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - mtk_x11_error_trap_push (xlib_renderer->xdpy); - glx_renderer->glXQueryDrawable (xlib_renderer->xdpy, drawable, GLX_BACK_BUFFER_AGE_EXT, &age); - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - - return age; -} - -static void -set_frame_info_output (CoglOnscreen *onscreen, - CoglOutput *output) -{ - CoglFrameInfo *info = cogl_onscreen_peek_tail_frame_info (onscreen); - - if (output) - { - float refresh_rate = cogl_output_get_refresh_rate (output); - if (refresh_rate != 0.0) - info->refresh_rate = refresh_rate; - } -} - -static void -cogl_onscreen_glx_flush_notification (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - - while (onscreen_glx->pending_sync_notify > 0 || - onscreen_glx->pending_complete_notify > 0) - { - if (onscreen_glx->pending_sync_notify > 0) - { - CoglFrameInfo *info; - - info = cogl_onscreen_peek_head_frame_info (onscreen); - _cogl_onscreen_notify_frame_sync (onscreen, info); - onscreen_glx->pending_sync_notify--; - } - - if (onscreen_glx->pending_complete_notify > 0) - { - CoglFrameInfo *info; - - info = cogl_onscreen_pop_head_frame_info (onscreen); - _cogl_onscreen_notify_complete (onscreen, info); - g_object_unref (info); - onscreen_glx->pending_complete_notify--; - } - } -} - -static void -flush_pending_notifications_cb (void *data, - void *user_data) -{ - CoglFramebuffer *framebuffer = data; - - if (COGL_IS_ONSCREEN (framebuffer)) - { - CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); - - cogl_onscreen_glx_flush_notification (onscreen); - } -} - -static void -flush_pending_notifications_idle (void *user_data) -{ - CoglContext *context = user_data; - CoglRenderer *renderer = context->display->renderer; - CoglGLXRenderer *glx_renderer = renderer->winsys; - - /* This needs to be disconnected before invoking the callbacks in - * case the callbacks cause it to be queued again */ - _cogl_closure_disconnect (glx_renderer->flush_notifications_idle); - glx_renderer->flush_notifications_idle = NULL; - - g_list_foreach (context->framebuffers, - flush_pending_notifications_cb, - NULL); -} - -static void -set_sync_pending (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglGLXRenderer *glx_renderer = renderer->winsys; - - /* We only want to dispatch sync events when the application calls - * cogl_context_dispatch so instead of immediately notifying we - * queue an idle callback */ - if (!glx_renderer->flush_notifications_idle) - { - glx_renderer->flush_notifications_idle = - _cogl_poll_renderer_add_idle (renderer, - flush_pending_notifications_idle, - context, - NULL); - } - - onscreen_glx->pending_sync_notify++; -} - -static void -set_complete_pending (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglGLXRenderer *glx_renderer = renderer->winsys; - - /* We only want to notify swap completion when the application calls - * cogl_context_dispatch so instead of immediately notifying we - * queue an idle callback */ - if (!glx_renderer->flush_notifications_idle) - { - glx_renderer->flush_notifications_idle = - _cogl_poll_renderer_add_idle (renderer, - flush_pending_notifications_idle, - context, - NULL); - } - - onscreen_glx->pending_complete_notify++; -} - -static void -cogl_onscreen_glx_swap_region (CoglOnscreen *onscreen, - const int *user_rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - CoglGLXDisplay *glx_display = context->display->winsys; - uint32_t end_frame_vsync_counter = 0; - gboolean have_counter; - gboolean can_wait; - int x_min = 0, x_max = 0, y_min = 0, y_max = 0; - - /* - * We assume that glXCopySubBuffer is synchronized which means it won't prevent multiple - * blits per retrace if they can all be performed in the blanking period. If that's the - * case then we still want to use the vblank sync menchanism but - * we only need it to throttle redraws. - */ - gboolean blit_sub_buffer_is_synchronized = - _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION_SYNCHRONIZED); - - int framebuffer_width = cogl_framebuffer_get_width (framebuffer); - int framebuffer_height = cogl_framebuffer_get_height (framebuffer); - int *rectangles = g_alloca (sizeof (int) * n_rectangles * 4); - int i; - - /* glXCopySubBuffer expects rectangles relative to the bottom left corner but - * we are given rectangles relative to the top left so we need to flip - * them... */ - memcpy (rectangles, user_rectangles, sizeof (int) * n_rectangles * 4); - for (i = 0; i < n_rectangles; i++) - { - int *rect = &rectangles[4 * i]; - - if (i == 0) - { - x_min = rect[0]; - x_max = rect[0] + rect[2]; - y_min = rect[1]; - y_max = rect[1] + rect[3]; - } - else - { - x_min = MIN (x_min, rect[0]); - x_max = MAX (x_max, rect[0] + rect[2]); - y_min = MIN (y_min, rect[1]); - y_max = MAX (y_max, rect[1] + rect[3]); - } - - rect[1] = framebuffer_height - rect[1] - rect[3]; - - } - - cogl_context_flush_framebuffer_state (context, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - - have_counter = glx_display->have_vblank_counter; - can_wait = glx_display->can_vblank_wait; - - /* We need to ensure that all the rendering is done, otherwise - * redraw operations that are slower than the framerate can - * queue up in the pipeline during a heavy animation, causing a - * larger and larger backlog of rendering visible as lag to the - * user. - * - * For an exaggerated example consider rendering at 60fps (so 16ms - * per frame) and you have a really slow frame that takes 160ms to - * render, even though painting the scene and issuing the commands - * to the GPU takes no time at all. If all we did was use the - * video_sync extension to throttle the painting done by the CPU - * then every 16ms we would have another frame queued up even though - * the GPU has only rendered one tenth of the current frame. By the - * time the GPU would get to the 2nd frame there would be 9 frames - * waiting to be rendered. - * - * The problem is that we don't currently have a good way to throttle - * the GPU, only the CPU so we have to resort to synchronizing the - * GPU with the CPU to throttle it. - * - * Note: calling glFinish() and synchronizing the CPU with the GPU is far - * from ideal. One idea is to use sync objects to track render completion - * so we can throttle the backlog (ideally with an additional extension that - * lets us get notifications in our mainloop instead of having to busy wait - * for the completion). - */ - cogl_framebuffer_finish (framebuffer); - - if (blit_sub_buffer_is_synchronized && have_counter && can_wait) - { - end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (context); - - /* If we have the GLX_SGI_video_sync extension then we can - * be a bit smarter about how we throttle blits by avoiding - * any waits if we can see that the video sync count has - * already progressed. */ - if (onscreen_glx->last_swap_vsync_counter == end_frame_vsync_counter) - _cogl_winsys_wait_for_vblank (onscreen); - } - else if (can_wait) - _cogl_winsys_wait_for_vblank (onscreen); - - if (glx_renderer->glXCopySubBuffer) - { - Display *xdpy = xlib_renderer->xdpy; - GLXDrawable drawable; - - drawable = - onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - int i; - for (i = 0; i < n_rectangles; i++) - { - int *rect = &rectangles[4 * i]; - glx_renderer->glXCopySubBuffer (xdpy, drawable, - rect[0], rect[1], rect[2], rect[3]); - } - } - else if (context->glBlitFramebuffer) - { - int i; - /* XXX: checkout how this state interacts with the code to use - * glBlitFramebuffer in Neil's texture atlasing branch */ - - /* glBlitFramebuffer is affected by the scissor so we need to - * ensure we have flushed an empty clip stack to get rid of it. - * We also mark that the clip state is dirty so that it will be - * flushed to the correct state the next time something is - * drawn */ - _cogl_clip_stack_flush (NULL, framebuffer); - context->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP; - - context->glDrawBuffer (GL_FRONT); - for (i = 0; i < n_rectangles; i++) - { - int *rect = &rectangles[4 * i]; - int x2 = rect[0] + rect[2]; - int y2 = rect[1] + rect[3]; - context->glBlitFramebuffer (rect[0], rect[1], x2, y2, - rect[0], rect[1], x2, y2, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } - context->glDrawBuffer (context->current_gl_draw_buffer); - } - - /* NB: unlike glXSwapBuffers, glXCopySubBuffer and - * glBlitFramebuffer don't issue an implicit glFlush() so we - * have to flush ourselves if we want the request to complete in - * a finite amount of time since otherwise the driver can batch - * the command indefinitely. */ - context->glFlush (); - - /* NB: It's important we save the counter we read before acting on - * the swap request since if we are mixing and matching different - * swap methods between frames we don't want to read the timer e.g. - * after calling glFinish() some times and not for others. - * - * In other words; this way we consistently save the time at the end - * of the applications frame such that the counter isn't muddled by - * the varying costs of different swap methods. - */ - if (have_counter) - onscreen_glx->last_swap_vsync_counter = end_frame_vsync_counter; - - { - CoglOutput *output; - - x_min = CLAMP (x_min, 0, framebuffer_width); - x_max = CLAMP (x_max, 0, framebuffer_width); - y_min = CLAMP (y_min, 0, framebuffer_height); - y_max = CLAMP (y_max, 0, framebuffer_height); - - output = - _cogl_xlib_renderer_output_for_rectangle (context->display->renderer, - onscreen_glx->x + x_min, - onscreen_glx->y + y_min, - x_max - x_min, - y_max - y_min); - - set_frame_info_output (onscreen, output); - } - - /* XXX: we don't get SwapComplete events based on how we implement - * the _swap_region() API but if cogl-onscreen.c knows we are - * handling _SYNC and _COMPLETE events in the winsys then we need to - * send fake events in this case. - */ - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) - { - set_sync_pending (onscreen); - set_complete_pending (onscreen); - } -} - -static void -cogl_onscreen_glx_swap_buffers_with_damage (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - CoglGLXDisplay *glx_display = context->display->winsys; - gboolean have_counter; - GLXDrawable drawable; - - /* XXX: theoretically this shouldn't be necessary but at least with - * the Intel drivers we have see that if we don't call - * glXMakeContextCurrent for the drawable we are swapping then - * we get a BadDrawable error from the X server. */ - cogl_context_flush_framebuffer_state (context, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - - drawable = onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - - have_counter = glx_display->have_vblank_counter; - - if (!glx_renderer->glXSwapInterval) - { - gboolean can_wait = have_counter || glx_display->can_vblank_wait; - - uint32_t end_frame_vsync_counter = 0; - - /* If the swap_region API is also being used then we need to track - * the vsync counter for each swap request so we can manually - * throttle swap_region requests. */ - if (have_counter) - end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (context); - - /* If we are going to wait for VBLANK manually, we not only - * need to flush out pending drawing to the GPU before we - * sleep, we need to wait for it to finish. Otherwise, we - * may end up with the situation: - * - * - We finish drawing - GPU drawing continues - * - We go to sleep - GPU drawing continues - * VBLANK - We call glXSwapBuffers - GPU drawing continues - * - GPU drawing continues - * - Swap buffers happens - * - * Producing a tear. Calling glFinish() first will cause us - * to properly wait for the next VBLANK before we swap. This - * obviously does not happen when we use _GLX_SWAP and let - * the driver do the right thing - */ - cogl_framebuffer_finish (framebuffer); - - if (have_counter && can_wait) - { - if (onscreen_glx->last_swap_vsync_counter == - end_frame_vsync_counter) - _cogl_winsys_wait_for_vblank (onscreen); - } - else if (can_wait) - _cogl_winsys_wait_for_vblank (onscreen); - } - - glx_renderer->glXSwapBuffers (xlib_renderer->xdpy, drawable); - - if (have_counter) - onscreen_glx->last_swap_vsync_counter = - _cogl_winsys_get_vsync_counter (context); - - set_frame_info_output (onscreen, onscreen_glx->output); -} - -static Window -cogl_onscreen_glx_get_x11_window (CoglX11Onscreen *x11_onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (x11_onscreen); - - return onscreen_glx->xwin; -} - -void -cogl_onscreen_glx_notify_swap_buffers (CoglOnscreen *onscreen, - GLXBufferSwapComplete *swap_event) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - gboolean ust_is_monotonic; - CoglFrameInfo *info; - - /* We only want to notify that the swap is complete when the - application calls cogl_context_dispatch so instead of immediately - notifying we'll set a flag to remember to notify later */ - set_sync_pending (onscreen); - - info = cogl_onscreen_peek_head_frame_info (onscreen); - info->flags |= COGL_FRAME_INFO_FLAG_VSYNC; - - ust_is_monotonic = is_ust_monotonic (context->display->renderer, - onscreen_glx->glxwin); - - if (swap_event->ust != 0 && ust_is_monotonic) - { - info->presentation_time_us = - ust_to_microseconds (context->display->renderer, - onscreen_glx->glxwin, - swap_event->ust); - info->flags |= COGL_FRAME_INFO_FLAG_HW_CLOCK; - } - - /* Intentionally truncating to lower 32 bits, same as DRM. */ - info->sequence = swap_event->msc; - - set_complete_pending (onscreen); -} - -void -cogl_onscreen_glx_update_output (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplay *display = context->display; - CoglOutput *output; - int width, height; - - width = cogl_framebuffer_get_width (framebuffer); - height = cogl_framebuffer_get_height (framebuffer); - output = _cogl_xlib_renderer_output_for_rectangle (display->renderer, - onscreen_glx->x, - onscreen_glx->y, - width, height); - if (onscreen_glx->output != output) - { - if (onscreen_glx->output) - g_object_unref (onscreen_glx->output); - - onscreen_glx->output = output; - - if (output) - g_object_ref (onscreen_glx->output); - } -} - -void -cogl_onscreen_glx_resize (CoglOnscreen *onscreen, - XConfigureEvent *configure_event) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglGLXRenderer *glx_renderer = renderer->winsys; - int x, y; - - - _cogl_framebuffer_winsys_update_size (framebuffer, - configure_event->width, - configure_event->height); - - /* We only want to notify that a resize happened when the - * application calls cogl_context_dispatch so instead of immediately - * notifying we queue an idle callback */ - if (!glx_renderer->flush_notifications_idle) - { - glx_renderer->flush_notifications_idle = - _cogl_poll_renderer_add_idle (renderer, - flush_pending_notifications_idle, - context, - NULL); - } - - if (configure_event->send_event) - { - x = configure_event->x; - y = configure_event->y; - } - else - { - Window child; - XTranslateCoordinates (configure_event->display, - configure_event->window, - DefaultRootWindow (configure_event->display), - 0, 0, &x, &y, &child); - } - - onscreen_glx->x = x; - onscreen_glx->y = y; - - cogl_onscreen_glx_update_output (onscreen); -} - -gboolean -cogl_onscreen_glx_is_for_window (CoglOnscreen *onscreen, - Window window) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - - return onscreen_glx->xwin == window; -} - -CoglOnscreenGlx * -cogl_onscreen_glx_new (CoglContext *context, - int width, - int height) -{ - CoglFramebufferDriverConfig driver_config; - - driver_config = (CoglFramebufferDriverConfig) { - .type = COGL_FRAMEBUFFER_DRIVER_TYPE_BACK, - }; - return g_object_new (COGL_TYPE_ONSCREEN_GLX, - "context", context, - "driver-config", &driver_config, - "width", width, - "height", height, - NULL); -} - -static void -cogl_onscreen_glx_init (CoglOnscreenGlx *onscreen_glx) -{ -} - -static void -x11_onscreen_init_iface (CoglX11OnscreenInterface *iface) -{ - iface->get_x11_window = cogl_onscreen_glx_get_x11_window; -} - -static void -cogl_onscreen_glx_class_init (CoglOnscreenGlxClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - CoglFramebufferClass *framebuffer_class = COGL_FRAMEBUFFER_CLASS (klass); - CoglOnscreenClass *onscreen_class = COGL_ONSCREEN_CLASS (klass); - - object_class->dispose = cogl_onscreen_glx_dispose; - - framebuffer_class->allocate = cogl_onscreen_glx_allocate; - - onscreen_class->bind = cogl_onscreen_glx_bind; - onscreen_class->swap_buffers_with_damage = - cogl_onscreen_glx_swap_buffers_with_damage; - onscreen_class->swap_region = cogl_onscreen_glx_swap_region; - onscreen_class->get_buffer_age = cogl_onscreen_glx_get_buffer_age; -} diff --git a/mutter/cogl/cogl/winsys/cogl-onscreen-glx.h b/mutter/cogl/cogl/winsys/cogl-onscreen-glx.h deleted file mode 100644 index 266595a..0000000 --- a/mutter/cogl/cogl/winsys/cogl-onscreen-glx.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#include -#include - -#include "cogl/cogl-onscreen.h" - -#define COGL_TYPE_ONSCREEN_GLX (cogl_onscreen_glx_get_type ()) -G_DECLARE_FINAL_TYPE (CoglOnscreenGlx, cogl_onscreen_glx, - COGL, ONSCREEN_GLX, - CoglOnscreen) - -COGL_EXPORT CoglOnscreenGlx * -cogl_onscreen_glx_new (CoglContext *context, - int width, - int height); - -void -cogl_onscreen_glx_resize (CoglOnscreen *onscreen, - XConfigureEvent *configure_event); - -void -cogl_onscreen_glx_update_output (CoglOnscreen *onscreen); - -void -cogl_onscreen_glx_notify_swap_buffers (CoglOnscreen *onscreen, - GLXBufferSwapComplete *swap_event); - -gboolean -cogl_onscreen_glx_is_for_window (CoglOnscreen *onscreen, - Window window); diff --git a/mutter/cogl/cogl/winsys/cogl-onscreen-xlib.c b/mutter/cogl/cogl/winsys/cogl-onscreen-xlib.c deleted file mode 100644 index 96d1bf3..0000000 --- a/mutter/cogl/cogl/winsys/cogl-onscreen-xlib.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 2011,2013 Intel Corporation. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "config.h" - -#include "cogl/winsys/cogl-onscreen-xlib.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-x11-onscreen.h" -#include "cogl/cogl-xlib-renderer-private.h" -#include "cogl/winsys/cogl-onscreen-egl.h" -#include "cogl/winsys/cogl-winsys-egl-x11-private.h" -#include "mtk/mtk-x11.h" - -struct _CoglOnscreenXlib -{ - CoglOnscreenEgl parent; - - Window xwin; -}; - -static void -x11_onscreen_init_iface (CoglX11OnscreenInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (CoglOnscreenXlib, cogl_onscreen_xlib, - COGL_TYPE_ONSCREEN_EGL, - G_IMPLEMENT_INTERFACE (COGL_TYPE_X11_ONSCREEN, - x11_onscreen_init_iface)) - -#define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask) - - -static Window -create_xwindow (CoglOnscreenXlib *onscreen_xlib, - EGLConfig egl_config, - GError **error) -{ - CoglOnscreen *onscreen = COGL_ONSCREEN (onscreen_xlib); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplay *display = context->display; - CoglRenderer *renderer = display->renderer; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - Window xwin; - int width; - int height; - XVisualInfo *xvisinfo; - XSetWindowAttributes xattr; - unsigned long mask; - int xerror; - - width = cogl_framebuffer_get_width (framebuffer); - height = cogl_framebuffer_get_height (framebuffer); - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - xvisinfo = cogl_display_xlib_get_visual_info (display, egl_config); - if (xvisinfo == NULL) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "Unable to retrieve the X11 visual of context's " - "fbconfig"); - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - return None; - } - - /* window attributes */ - xattr.background_pixel = - WhitePixel (xlib_renderer->xdpy, - DefaultScreen (xlib_renderer->xdpy)); - xattr.border_pixel = 0; - /* XXX: is this an X resource that we are leaking‽... */ - xattr.colormap = - XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - xattr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK; - - mask = CWBorderPixel | CWColormap | CWEventMask; - - xwin = XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - 0, 0, - width, height, - 0, - xvisinfo->depth, - InputOutput, - xvisinfo->visual, - mask, &xattr); - - XFree (xvisinfo); - - XSync (xlib_renderer->xdpy, False); - xerror = mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy); - if (xerror) - { - char message[1000]; - XGetErrorText (xlib_renderer->xdpy, xerror, - message, sizeof (message)); - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "X error while creating Window for CoglOnscreen: %s", - message); - return None; - } - - return xwin; -} - -static gboolean -cogl_onscreen_xlib_allocate (CoglFramebuffer *framebuffer, - GError **error) -{ - CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (framebuffer); - CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (framebuffer); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplay *display = context->display; - CoglRenderer *renderer = display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - EGLConfig egl_config; - Window xwin; - EGLSurface egl_surface; - CoglFramebufferClass *parent_class; - - if (!cogl_onscreen_egl_choose_config (onscreen_egl, &egl_config, error)) - return FALSE; - - xwin = create_xwindow (onscreen_xlib, egl_config, error); - if (xwin == None) - return FALSE; - - onscreen_xlib->xwin = xwin; - - egl_surface = - eglCreateWindowSurface (egl_renderer->edpy, - egl_config, - (EGLNativeWindowType) onscreen_xlib->xwin, - NULL); - cogl_onscreen_egl_set_egl_surface (onscreen_egl, - egl_surface); - - parent_class = COGL_FRAMEBUFFER_CLASS (cogl_onscreen_xlib_parent_class); - return parent_class->allocate (framebuffer, error); -} - -static void -cogl_onscreen_xlib_dispose (GObject *object) -{ - CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (object); - - G_OBJECT_CLASS (cogl_onscreen_xlib_parent_class)->dispose (object); - - if (onscreen_xlib->xwin != None) - { - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - XDestroyWindow (xlib_renderer->xdpy, onscreen_xlib->xwin); - onscreen_xlib->xwin = None; - XSync (xlib_renderer->xdpy, False); - - if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy)) - g_warning ("X Error while destroying X window"); - - onscreen_xlib->xwin = None; - } -} - -static Window -cogl_onscreen_xlib_get_x11_window (CoglX11Onscreen *x11_onscreen) -{ - CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (x11_onscreen); - - return onscreen_xlib->xwin; -} - -gboolean -cogl_onscreen_xlib_is_for_window (CoglOnscreen *onscreen, - Window window) -{ - CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (onscreen); - - return onscreen_xlib->xwin == window; -} - -void -cogl_onscreen_xlib_resize (CoglOnscreen *onscreen, - int width, - int height) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - - _cogl_framebuffer_winsys_update_size (framebuffer, width, height); -} - -CoglOnscreenXlib * -cogl_onscreen_xlib_new (CoglContext *context, - int width, - int height) -{ - CoglFramebufferDriverConfig driver_config; - - driver_config = (CoglFramebufferDriverConfig) { - .type = COGL_FRAMEBUFFER_DRIVER_TYPE_BACK, - }; - return g_object_new (COGL_TYPE_ONSCREEN_XLIB, - "context", context, - "driver-config", &driver_config, - "width", width, - "height", height, - NULL); -} - -static void -cogl_onscreen_xlib_init (CoglOnscreenXlib *onscreen_xlib) -{ -} - -static void -x11_onscreen_init_iface (CoglX11OnscreenInterface *iface) -{ - iface->get_x11_window = cogl_onscreen_xlib_get_x11_window; -} - -static void -cogl_onscreen_xlib_class_init (CoglOnscreenXlibClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - CoglFramebufferClass *framebuffer_class = COGL_FRAMEBUFFER_CLASS (klass); - - object_class->dispose = cogl_onscreen_xlib_dispose; - - framebuffer_class->allocate = cogl_onscreen_xlib_allocate; -} diff --git a/mutter/cogl/cogl/winsys/cogl-onscreen-xlib.h b/mutter/cogl/cogl/winsys/cogl-onscreen-xlib.h deleted file mode 100644 index 913826e..0000000 --- a/mutter/cogl/cogl/winsys/cogl-onscreen-xlib.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2011,2013 Intel Corporation. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#pragma once - -#include "cogl/cogl-onscreen.h" -#include "cogl/winsys/cogl-onscreen-egl.h" -#include "cogl/winsys/cogl-winsys-egl-private.h" - -#define COGL_TYPE_ONSCREEN_XLIB (cogl_onscreen_xlib_get_type ()) -G_DECLARE_FINAL_TYPE (CoglOnscreenXlib, cogl_onscreen_xlib, - COGL, ONSCREEN_XLIB, - CoglOnscreenEgl) - -gboolean -_cogl_winsys_egl_onscreen_xlib_init (CoglOnscreen *onscreen, - EGLConfig egl_config, - GError **error); - -COGL_EXPORT CoglOnscreenXlib * -cogl_onscreen_xlib_new (CoglContext *context, - int width, - int height); - -void -_cogl_winsys_egl_onscreen_xlib_deinit (CoglOnscreen *onscreen); - -gboolean -cogl_onscreen_xlib_is_for_window (CoglOnscreen *onscreen, - Window window); - -void -cogl_onscreen_xlib_resize (CoglOnscreen *onscreen, - int width, - int height); diff --git a/mutter/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h b/mutter/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h deleted file mode 100644 index 7633c8c..0000000 --- a/mutter/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include -#include -#include - -#include - -#ifdef HAVE_GLX -#include -#endif - -#include "cogl/cogl-texture-private.h" -#include "cogl/winsys/cogl-texture-pixmap-x11.h" - -typedef struct _CoglDamageRectangle CoglDamageRectangle; - -struct _CoglDamageRectangle -{ - unsigned int x1; - unsigned int y1; - unsigned int x2; - unsigned int y2; -}; - -/* For stereo, there are a pair of textures, but we want to share most - * other state (the GLXPixmap, visual, etc.) The way we do this is that - * the left-eye texture has all the state (there is in fact, no internal - * difference between the a MONO and a LEFT texture ), and the - * right-eye texture simply points to the left eye texture, with all - * other fields ignored. - */ -typedef enum -{ - COGL_TEXTURE_PIXMAP_MONO, - COGL_TEXTURE_PIXMAP_LEFT, - COGL_TEXTURE_PIXMAP_RIGHT -} CoglTexturePixmapStereoMode; - -struct _CoglTexturePixmapX11 -{ - CoglTexture parent_instance; - - CoglTexturePixmapStereoMode stereo_mode; - CoglTexturePixmapX11 *left; /* Set only if stereo_mode=RIGHT */ - - Pixmap pixmap; - CoglTexture *tex; - - unsigned int depth; - Visual *visual; - - XImage *image; - - XShmSegmentInfo shm_info; - - Damage damage; - CoglTexturePixmapX11ReportLevel damage_report_level; - gboolean damage_owned; - CoglDamageRectangle damage_rect; - - void *winsys; - - /* During the pre_paint method, this will be set to TRUE if we - should use the winsys texture, otherwise we will use the regular - texture */ - gboolean use_winsys_texture; -}; - -struct _CoglTexturePixmapX11Class -{ - CoglTextureClass parent_class; -}; diff --git a/mutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.c b/mutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.c deleted file mode 100644 index 87598b8..0000000 --- a/mutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.c +++ /dev/null @@ -1,1097 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - * Johan Bilien - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-debug.h" -#include "cogl/cogl-util.h" -#include "cogl/winsys/cogl-texture-pixmap-x11.h" -#include "cogl/winsys/cogl-texture-pixmap-x11-private.h" -#include "cogl/cogl-bitmap-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-texture-driver.h" -#include "cogl/cogl-texture-2d-private.h" -#include "cogl/cogl-texture-2d-sliced.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-display-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-xlib.h" -#include "cogl/cogl-xlib-renderer-private.h" -#include "cogl/cogl-x11-renderer-private.h" -#include "cogl/cogl-private.h" -#include "cogl/driver/gl/cogl-texture-gl-private.h" -#include "cogl/winsys/cogl-winsys-private.h" - -#include -#include - -#include -#include -#include - -#include -#include - -G_DEFINE_FINAL_TYPE (CoglTexturePixmapX11, cogl_texture_pixmap_x11, COGL_TYPE_TEXTURE) - -static const CoglWinsysVtable * -_cogl_texture_pixmap_x11_get_winsys (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglContext *ctx; - - ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - return ctx->display->renderer->winsys_vtable; -} - -static int -_cogl_xlib_get_damage_base (CoglContext *ctx) -{ - CoglX11Renderer *x11_renderer; - - x11_renderer = - (CoglX11Renderer *) _cogl_xlib_renderer_get_data (ctx->display->renderer); - return x11_renderer->damage_base; -} - -static gboolean -cogl_damage_rectangle_is_whole (const CoglDamageRectangle *damage_rect, - unsigned int width, - unsigned int height) -{ - return (damage_rect->x1 == 0 && damage_rect->y1 == 0 - && damage_rect->x2 == width && damage_rect->y2 == height); -} - -static void -cogl_damage_rectangle_union (CoglDamageRectangle *damage_rect, - int x, - int y, - int width, - int height) -{ - /* If the damage region is empty then we'll just copy the new - rectangle directly */ - if (damage_rect->x1 == damage_rect->x2 || - damage_rect->y1 == damage_rect->y2) - { - damage_rect->x1 = x; - damage_rect->y1 = y; - damage_rect->x2 = x + width; - damage_rect->y2 = y + height; - } - else - { - if (damage_rect->x1 > x) - damage_rect->x1 = x; - if (damage_rect->y1 > y) - damage_rect->y1 = y; - if (damage_rect->x2 < x + width) - damage_rect->x2 = x + width; - if (damage_rect->y2 < y + height) - damage_rect->y2 = y + height; - } -} - -static void -process_damage_event (CoglTexturePixmapX11 *tex_pixmap, - XDamageNotifyEvent *damage_event) -{ - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - Display *display; - enum -{ DO_NOTHING, NEEDS_SUBTRACT, NEED_BOUNDING_BOX } handle_mode; - const CoglWinsysVtable *winsys; - CoglContext *ctx; - - ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - display = cogl_xlib_renderer_get_display (ctx->display->renderer); - - COGL_NOTE (TEXTURE_PIXMAP, "Damage event received for %p", tex_pixmap); - - switch (tex_pixmap->damage_report_level) - { - case COGL_TEXTURE_PIXMAP_X11_DAMAGE_RAW_RECTANGLES: - /* For raw rectangles we don't need do look at the damage region - at all because the damage area is directly given in the event - struct and the reporting of events is not affected by - clearing the damage region */ - handle_mode = DO_NOTHING; - break; - - case COGL_TEXTURE_PIXMAP_X11_DAMAGE_DELTA_RECTANGLES: - case COGL_TEXTURE_PIXMAP_X11_DAMAGE_NON_EMPTY: - /* For delta rectangles and non empty we'll query the damage - region for the bounding box */ - handle_mode = NEED_BOUNDING_BOX; - break; - - case COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX: - /* For bounding box we need to clear the damage region but we - don't actually care what it was because the damage event - itself contains the bounding box of the region */ - handle_mode = NEEDS_SUBTRACT; - break; - - default: - g_assert_not_reached (); - } - - /* If the damage already covers the whole rectangle then we don't - need to request the bounding box of the region because we're - going to update the whole texture anyway. */ - if (cogl_damage_rectangle_is_whole (&tex_pixmap->damage_rect, - cogl_texture_get_width (tex), - cogl_texture_get_height (tex))) - { - if (handle_mode != DO_NOTHING) - XDamageSubtract (display, tex_pixmap->damage, None, None); - } - else if (handle_mode == NEED_BOUNDING_BOX) - { - XserverRegion parts; - int r_count; - XRectangle r_bounds; - XRectangle *r_damage; - - /* We need to extract the damage region so we can get the - bounding box */ - - parts = XFixesCreateRegion (display, 0, 0); - XDamageSubtract (display, tex_pixmap->damage, None, parts); - r_damage = XFixesFetchRegionAndBounds (display, - parts, - &r_count, - &r_bounds); - cogl_damage_rectangle_union (&tex_pixmap->damage_rect, - r_bounds.x, - r_bounds.y, - r_bounds.width, - r_bounds.height); - if (r_damage) - XFree (r_damage); - - XFixesDestroyRegion (display, parts); - } - else - { - if (handle_mode == NEEDS_SUBTRACT) - /* We still need to subtract from the damage region but we - don't care what the region actually was */ - XDamageSubtract (display, tex_pixmap->damage, None, None); - - cogl_damage_rectangle_union (&tex_pixmap->damage_rect, - damage_event->area.x, - damage_event->area.y, - damage_event->area.width, - damage_event->area.height); - } - - if (tex_pixmap->winsys) - { - /* If we're using the texture from pixmap extension then there's no - point in getting the region and we can just mark that the texture - needs updating */ - winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - winsys->texture_pixmap_x11_damage_notify (tex_pixmap); - } -} - -static CoglFilterReturn -_cogl_texture_pixmap_x11_filter (XEvent *event, void *data) -{ - CoglTexturePixmapX11 *tex_pixmap = data; - int damage_base; - CoglContext *ctx; - - ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - damage_base = _cogl_xlib_get_damage_base (ctx); - if (event->type == damage_base + XDamageNotify) - { - XDamageNotifyEvent *damage_event = (XDamageNotifyEvent *) event; - - if (damage_event->damage == tex_pixmap->damage) - process_damage_event (tex_pixmap, damage_event); - } - - return COGL_FILTER_CONTINUE; -} - -static void -set_damage_object_internal (CoglContext *ctx, - CoglTexturePixmapX11 *tex_pixmap, - Damage damage, - CoglTexturePixmapX11ReportLevel report_level) -{ - Display *display = cogl_xlib_renderer_get_display (ctx->display->renderer); - - if (tex_pixmap->damage) - { - cogl_xlib_renderer_remove_filter (ctx->display->renderer, - _cogl_texture_pixmap_x11_filter, - tex_pixmap); - - if (tex_pixmap->damage_owned) - { - XDamageDestroy (display, tex_pixmap->damage); - tex_pixmap->damage_owned = FALSE; - } - } - - tex_pixmap->damage = damage; - tex_pixmap->damage_report_level = report_level; - - if (damage) - cogl_xlib_renderer_add_filter (ctx->display->renderer, - _cogl_texture_pixmap_x11_filter, - tex_pixmap); -} - -static void -cogl_texture_pixmap_x11_dispose (GObject *object) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (object); - CoglContext *ctx; - Display *display; - - ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - - if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - { - g_object_unref (tex_pixmap->left); - G_OBJECT_CLASS (cogl_texture_pixmap_x11_parent_class)->dispose (object); - return; - } - - display = cogl_xlib_renderer_get_display (ctx->display->renderer); - - set_damage_object_internal (ctx, tex_pixmap, 0, 0); - - if (tex_pixmap->image) - XDestroyImage (tex_pixmap->image); - - if (tex_pixmap->shm_info.shmid != -1) - { - XShmDetach (display, &tex_pixmap->shm_info); - shmdt (tex_pixmap->shm_info.shmaddr); - shmctl (tex_pixmap->shm_info.shmid, IPC_RMID, 0); - } - - if (tex_pixmap->tex) - g_object_unref (tex_pixmap->tex); - - if (tex_pixmap->winsys) - { - const CoglWinsysVtable *winsys = - _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - winsys->texture_pixmap_x11_free (tex_pixmap); - } - - G_OBJECT_CLASS (cogl_texture_pixmap_x11_parent_class)->dispose (object); -} - -static void -_cogl_texture_pixmap_x11_set_use_winsys_texture (CoglTexturePixmapX11 *tex_pixmap, - gboolean new_value) -{ - if (tex_pixmap->use_winsys_texture != new_value) - { - /* Notify cogl-pipeline.c that the texture's underlying GL texture - * storage is changing so it knows it may need to bind a new texture - * if the CoglTexture is reused with the same texture unit. */ - _cogl_pipeline_texture_storage_change_notify (COGL_TEXTURE (tex_pixmap)); - - tex_pixmap->use_winsys_texture = new_value; - } -} - -static CoglTexture * -create_fallback_texture (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format) -{ - CoglTexture *tex; - GError *skip_error = NULL; - - /* First try creating a fast-path non-sliced texture */ - tex = cogl_texture_2d_new_with_size (ctx, width, height); - - _cogl_texture_set_internal_format (tex, internal_format); - - /* TODO: instead of allocating storage here it would be better - * if we had some api that let us just check that the size is - * supported by the hardware so storage could be allocated - * lazily when uploading data. */ - if (!cogl_texture_allocate (tex, &skip_error)) - { - g_error_free (skip_error); - g_object_unref (tex); - tex = NULL; - } - - if (!tex) - { - tex = - cogl_texture_2d_sliced_new_with_size (ctx, - width, - height, - COGL_TEXTURE_MAX_WASTE); - _cogl_texture_set_internal_format (tex, internal_format); - } - - return tex; -} - - -/* Tries to allocate enough shared mem to handle a full size - * update size of the X Pixmap. */ -static void -try_alloc_shm (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - XImage *dummy_image; - CoglContext *ctx; - Display *display; - - ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - display = cogl_xlib_renderer_get_display (ctx->display->renderer); - - if (!XShmQueryExtension (display)) - return; - - /* We are creating a dummy_image so we can have Xlib calculate - * image->bytes_per_line - including any magic padding it may - * want - for the largest possible ximage we might need to use - * when handling updates to the texture. - * - * Note: we pass a NULL shminfo here, but that has no bearing - * on the setup of the XImage, except that ximage->obdata will - * == NULL. - */ - dummy_image = - XShmCreateImage (display, - tex_pixmap->visual, - tex_pixmap->depth, - ZPixmap, - NULL, - NULL, /* shminfo, */ - cogl_texture_get_width (tex), - cogl_texture_get_height (tex)); - if (!dummy_image) - goto failed_image_create; - - tex_pixmap->shm_info.shmid = shmget (IPC_PRIVATE, - dummy_image->bytes_per_line - * dummy_image->height, - IPC_CREAT | 0777); - if (tex_pixmap->shm_info.shmid == -1) - goto failed_shmget; - - tex_pixmap->shm_info.shmaddr = shmat (tex_pixmap->shm_info.shmid, 0, 0); - if (tex_pixmap->shm_info.shmaddr == (void *) -1) - goto failed_shmat; - - tex_pixmap->shm_info.readOnly = False; - - if (XShmAttach (display, &tex_pixmap->shm_info) == 0) - goto failed_xshmattach; - - XDestroyImage (dummy_image); - - return; - - failed_xshmattach: - g_warning ("XShmAttach failed"); - shmdt (tex_pixmap->shm_info.shmaddr); - - failed_shmat: - g_warning ("shmat failed"); - shmctl (tex_pixmap->shm_info.shmid, IPC_RMID, 0); - - failed_shmget: - g_warning ("shmget failed"); - XDestroyImage (dummy_image); - - failed_image_create: - tex_pixmap->shm_info.shmid = -1; -} - -static void -_cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - Display *display; - Visual *visual; - CoglContext *ctx; - CoglPixelFormat image_format; - XImage *image; - int src_x, src_y; - int x, y, width, height; - int bpp; - int offset; - GError *ignore = NULL; - - ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - display = cogl_xlib_renderer_get_display (ctx->display->renderer); - visual = tex_pixmap->visual; - - /* If the damage region is empty then there's nothing to do */ - if (tex_pixmap->damage_rect.x2 == tex_pixmap->damage_rect.x1) - return; - - x = tex_pixmap->damage_rect.x1; - y = tex_pixmap->damage_rect.y1; - width = tex_pixmap->damage_rect.x2 - x; - height = tex_pixmap->damage_rect.y2 - y; - - /* We lazily create the texture the first time it is needed in case - this texture can be entirely handled using the GLX texture - instead */ - if (tex_pixmap->tex == NULL) - { - CoglPixelFormat texture_format; - - texture_format = (tex_pixmap->depth >= 32 - ? COGL_PIXEL_FORMAT_RGBA_8888_PRE - : COGL_PIXEL_FORMAT_RGB_888); - - tex_pixmap->tex = create_fallback_texture (ctx, - cogl_texture_get_width (tex), - cogl_texture_get_height (tex), - texture_format); - } - - if (tex_pixmap->image == NULL) - { - /* If we also haven't got a shm segment then this must be the - first time we've tried to update, so lets try allocating shm - first */ - if (tex_pixmap->shm_info.shmid == -1) - try_alloc_shm (tex_pixmap); - - if (tex_pixmap->shm_info.shmid == -1) - { - COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XGetImage", tex_pixmap); - - /* We'll fallback to using a regular XImage. We'll download - the entire area instead of a sub region because presumably - if this is the first update then the entire pixmap is - needed anyway and it saves trying to manually allocate an - XImage at the right size */ - tex_pixmap->image = XGetImage (display, - tex_pixmap->pixmap, - 0, 0, - cogl_texture_get_width (tex), - cogl_texture_get_height (tex), - AllPlanes, ZPixmap); - image = tex_pixmap->image; - src_x = x; - src_y = y; - } - else - { - COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XShmGetImage", - tex_pixmap); - - /* Create a temporary image using the beginning of the - shared memory segment and the right size for the region - we want to update. We need to reallocate the XImage every - time because there is no XShmGetSubImage. */ - image = XShmCreateImage (display, - tex_pixmap->visual, - tex_pixmap->depth, - ZPixmap, - NULL, - &tex_pixmap->shm_info, - width, - height); - image->data = tex_pixmap->shm_info.shmaddr; - src_x = 0; - src_y = 0; - - XShmGetImage (display, tex_pixmap->pixmap, image, x, y, AllPlanes); - } - } - else - { - COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XGetSubImage", tex_pixmap); - - image = tex_pixmap->image; - src_x = x; - src_y = y; - - XGetSubImage (display, - tex_pixmap->pixmap, - x, y, width, height, - AllPlanes, ZPixmap, - image, - x, y); - } - - image_format = - _cogl_util_pixel_format_from_masks (visual->red_mask, - visual->green_mask, - visual->blue_mask, - image->depth, - image->bits_per_pixel, - image->byte_order == LSBFirst); - g_return_if_fail (cogl_pixel_format_get_n_planes (image_format) == 1); - - bpp = cogl_pixel_format_get_bytes_per_pixel (image_format, 0); - offset = image->bytes_per_line * src_y + bpp * src_x; - - _cogl_texture_set_region (tex_pixmap->tex, - width, - height, - image_format, - image->bytes_per_line, - ((const uint8_t *) image->data) + offset, - x, y, - 0, /* level */ - &ignore); - - /* If we have a shared memory segment then the XImage would be a - temporary one with no data allocated so we can just XFree it */ - if (tex_pixmap->shm_info.shmid != -1) - XFree (image); - - memset (&tex_pixmap->damage_rect, 0, sizeof (CoglDamageRectangle)); -} - -static void -_cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, - gboolean needs_mipmap) -{ - CoglTexturePixmapStereoMode stereo_mode = tex_pixmap->stereo_mode; - if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - tex_pixmap = tex_pixmap->left; - - if (tex_pixmap->winsys) - { - const CoglWinsysVtable *winsys = - _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - - if (winsys->texture_pixmap_x11_update (tex_pixmap, stereo_mode, needs_mipmap)) - { - _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, TRUE); - return; - } - } - - /* If it didn't work then fallback to using XGetImage. This may be - temporary */ - _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, FALSE); - - _cogl_texture_pixmap_x11_update_image_texture (tex_pixmap); -} - -static CoglTexture * -_cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapX11 *original_pixmap = tex_pixmap; - CoglTexture *tex; - int i; - CoglTexturePixmapStereoMode stereo_mode = tex_pixmap->stereo_mode; - - if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - tex_pixmap = tex_pixmap->left; - - /* We try getting the texture twice, once without flushing the - updates and once with. If pre_paint has been called already then - we should have a good idea of which texture to use so we don't - want to mess with that by ensuring the updates. However, if we - couldn't find a texture then we'll just make a best guess by - flushing without expecting mipmap support and try again. This - would happen for example if an application calls - get_gl_texture before the first paint */ - - for (i = 0; i < 2; i++) - { - if (tex_pixmap->use_winsys_texture) - { - const CoglWinsysVtable *winsys = - _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - tex = winsys->texture_pixmap_x11_get_texture (tex_pixmap, stereo_mode); - } - else - tex = tex_pixmap->tex; - - if (tex) - return tex; - - _cogl_texture_pixmap_x11_update (original_pixmap, FALSE); - } - - g_assert_not_reached (); - - return NULL; -} - -static gboolean -_cogl_texture_pixmap_x11_allocate (CoglTexture *tex, - GError **error) -{ - return TRUE; -} - -static gboolean -_cogl_texture_pixmap_x11_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int dst_width, - int dst_height, - int level, - CoglBitmap *bmp, - GError **error) -{ - /* This doesn't make much sense for texture from pixmap so it's not - supported */ - g_set_error_literal (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Explicitly setting a region of a TFP texture " - "unsupported"); - return FALSE; -} - -static gboolean -_cogl_texture_pixmap_x11_get_data (CoglTexture *tex, - CoglPixelFormat format, - int rowstride, - uint8_t *data) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return cogl_texture_get_data (child_tex, format, rowstride, data); -} - -static int -_cogl_texture_pixmap_x11_get_max_waste (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - return cogl_texture_get_max_waste (child_tex); -} - -static void -_cogl_texture_pixmap_x11_foreach_sub_texture_in_region - (CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglMetaTextureCallback callback, - void *user_data) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - cogl_meta_texture_foreach_in_region (child_tex, - virtual_tx_1, - virtual_ty_1, - virtual_tx_2, - virtual_ty_2, - COGL_PIPELINE_WRAP_MODE_REPEAT, - COGL_PIPELINE_WRAP_MODE_REPEAT, - callback, - user_data); -} - -static gboolean -_cogl_texture_pixmap_x11_is_sliced (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - return cogl_texture_is_sliced (child_tex); -} - -static gboolean -_cogl_texture_pixmap_x11_can_hardware_repeat (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - return _cogl_texture_can_hardware_repeat (child_tex); -} - -static void -_cogl_texture_pixmap_x11_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - _cogl_texture_transform_coords_to_gl (child_tex, s, t); -} - -static CoglTransformResult -_cogl_texture_pixmap_x11_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return _cogl_texture_transform_quad_coords_to_gl (child_tex, coords); -} - -static gboolean -_cogl_texture_pixmap_x11_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return cogl_texture_get_gl_texture (child_tex, - out_gl_handle, - out_gl_target); -} - -static void -_cogl_texture_pixmap_x11_gl_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - _cogl_texture_gl_flush_legacy_texobj_filters (child_tex, - min_filter, mag_filter); -} - -static void -_cogl_texture_pixmap_x11_pre_paint (CoglTexture *tex, - CoglTexturePrePaintFlags flags) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex; - - _cogl_texture_pixmap_x11_update (tex_pixmap, - !!(flags & COGL_TEXTURE_NEEDS_MIPMAP)); - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - _cogl_texture_pre_paint (child_tex, flags); -} - -static void -_cogl_texture_pixmap_x11_ensure_non_quad_rendering (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - _cogl_texture_ensure_non_quad_rendering (child_tex); -} - -static void -_cogl_texture_pixmap_x11_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - _cogl_texture_gl_flush_legacy_texobj_wrap_modes (child_tex, - wrap_mode_s, - wrap_mode_t); -} - -static CoglPixelFormat -_cogl_texture_pixmap_x11_get_format (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return _cogl_texture_get_format (child_tex); -} - -static GLenum -_cogl_texture_pixmap_x11_get_gl_format (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - return _cogl_texture_gl_get_format (child_tex); -} - -static void -cogl_texture_pixmap_x11_class_init (CoglTexturePixmapX11Class *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - CoglTextureClass *texture_class = COGL_TEXTURE_CLASS (klass); - - gobject_class->dispose = cogl_texture_pixmap_x11_dispose; - - texture_class->allocate = _cogl_texture_pixmap_x11_allocate; - texture_class->set_region = _cogl_texture_pixmap_x11_set_region; - texture_class->get_data = _cogl_texture_pixmap_x11_get_data; - texture_class->get_max_waste = _cogl_texture_pixmap_x11_get_max_waste; - texture_class->foreach_sub_texture_in_region = _cogl_texture_pixmap_x11_foreach_sub_texture_in_region; - texture_class->is_sliced = _cogl_texture_pixmap_x11_is_sliced; - texture_class->can_hardware_repeat = _cogl_texture_pixmap_x11_can_hardware_repeat; - texture_class->transform_coords_to_gl = _cogl_texture_pixmap_x11_transform_coords_to_gl; - texture_class->transform_quad_coords_to_gl = _cogl_texture_pixmap_x11_transform_quad_coords_to_gl; - texture_class->get_gl_texture = _cogl_texture_pixmap_x11_get_gl_texture; - texture_class->gl_flush_legacy_texobj_filters = _cogl_texture_pixmap_x11_gl_flush_legacy_texobj_filters; - texture_class->pre_paint = _cogl_texture_pixmap_x11_pre_paint; - texture_class->ensure_non_quad_rendering = _cogl_texture_pixmap_x11_ensure_non_quad_rendering; - texture_class->gl_flush_legacy_texobj_wrap_modes = _cogl_texture_pixmap_x11_gl_flush_legacy_texobj_wrap_modes; - texture_class->get_format = _cogl_texture_pixmap_x11_get_format; - texture_class->get_gl_format = _cogl_texture_pixmap_x11_get_gl_format; -} - -static void -cogl_texture_pixmap_x11_init (CoglTexturePixmapX11 *self) -{ - CoglTexture *texture = COGL_TEXTURE (self); - - texture->is_primitive = FALSE; -} - -uint32_t -cogl_texture_pixmap_x11_error_quark (void) -{ - return g_quark_from_static_string ("cogl-texture-pixmap-error-quark"); -} - -static CoglTexture * -_cogl_texture_pixmap_x11_new (CoglContext *ctx, - uint32_t pixmap, - gboolean automatic_updates, - CoglTexturePixmapStereoMode stereo_mode, - GError **error) -{ - CoglTexturePixmapX11 *tex_pixmap; - Display *display = cogl_xlib_renderer_get_display (ctx->display->renderer); - Window pixmap_root_window; - int pixmap_x, pixmap_y; - unsigned int pixmap_width, pixmap_height; - unsigned int pixmap_border_width; - unsigned int pixmap_depth; - CoglPixelFormat internal_format; - XWindowAttributes window_attributes; - int damage_base; - const CoglWinsysVtable *winsys; - - if (!XGetGeometry (display, pixmap, &pixmap_root_window, - &pixmap_x, &pixmap_y, - &pixmap_width, &pixmap_height, - &pixmap_border_width, &pixmap_depth)) - { - g_set_error_literal (error, - COGL_TEXTURE_PIXMAP_X11_ERROR, - COGL_TEXTURE_PIXMAP_X11_ERROR_X11, - "Unable to query pixmap size"); - return NULL; - } - - /* Note: the detailed pixel layout doesn't matter here, we are just - * interested in RGB vs RGBA... */ - internal_format = (pixmap_depth >= 32 - ? COGL_PIXEL_FORMAT_RGBA_8888_PRE - : COGL_PIXEL_FORMAT_RGB_888); - - tex_pixmap = g_object_new (COGL_TYPE_TEXTURE_PIXMAP_X11, - "context", ctx, - "width", pixmap_width, - "height", pixmap_height, - "format", internal_format, - NULL); - - tex_pixmap->depth = pixmap_depth; - tex_pixmap->pixmap = pixmap; - tex_pixmap->stereo_mode = stereo_mode; - tex_pixmap->left = NULL; - tex_pixmap->image = NULL; - tex_pixmap->shm_info.shmid = -1; - tex_pixmap->tex = NULL; - tex_pixmap->damage_owned = FALSE; - tex_pixmap->damage = 0; - - /* We need a visual to use for shared memory images so we'll query - it from the pixmap's root window */ - if (!XGetWindowAttributes (display, pixmap_root_window, &window_attributes)) - { - g_free (tex_pixmap); - g_set_error_literal (error, - COGL_TEXTURE_PIXMAP_X11_ERROR, - COGL_TEXTURE_PIXMAP_X11_ERROR_X11, - "Unable to query root window attributes"); - return NULL; - } - - tex_pixmap->visual = window_attributes.visual; - - /* If automatic updates are requested and the Xlib connection - supports damage events then we'll register a damage object on the - pixmap */ - damage_base = _cogl_xlib_get_damage_base (ctx); - if (automatic_updates && damage_base >= 0) - { - Damage damage = XDamageCreate (display, - pixmap, - XDamageReportBoundingBox); - set_damage_object_internal (ctx, - tex_pixmap, - damage, - COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX); - tex_pixmap->damage_owned = TRUE; - } - - /* Assume the entire pixmap is damaged to begin with */ - tex_pixmap->damage_rect.x1 = 0; - tex_pixmap->damage_rect.x2 = pixmap_width; - tex_pixmap->damage_rect.y1 = 0; - tex_pixmap->damage_rect.y2 = pixmap_height; - - winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - if (winsys->texture_pixmap_x11_create) - { - tex_pixmap->use_winsys_texture = - winsys->texture_pixmap_x11_create (tex_pixmap); - } - else - tex_pixmap->use_winsys_texture = FALSE; - - if (!tex_pixmap->use_winsys_texture) - tex_pixmap->winsys = NULL; - - _cogl_texture_set_allocated (COGL_TEXTURE (tex_pixmap), internal_format, - pixmap_width, pixmap_height); - - return COGL_TEXTURE (tex_pixmap); -} - -CoglTexture * -cogl_texture_pixmap_x11_new (CoglContext *ctxt, - uint32_t pixmap, - gboolean automatic_updates, - GError **error) - -{ - return _cogl_texture_pixmap_x11_new (ctxt, pixmap, - automatic_updates, COGL_TEXTURE_PIXMAP_MONO, - error); -} - -CoglTexture * -cogl_texture_pixmap_x11_new_left (CoglContext *ctxt, - uint32_t pixmap, - gboolean automatic_updates, - GError **error) -{ - return _cogl_texture_pixmap_x11_new (ctxt, pixmap, - automatic_updates, COGL_TEXTURE_PIXMAP_LEFT, - error); -} - -CoglTexture * -cogl_texture_pixmap_x11_new_right (CoglTexturePixmapX11 *tfp_left) -{ - CoglTexture *texture_left = COGL_TEXTURE (tfp_left); - CoglTexturePixmapX11 *tfp_right; - CoglPixelFormat internal_format; - - g_return_val_if_fail (tfp_left->stereo_mode == COGL_TEXTURE_PIXMAP_LEFT, NULL); - - internal_format = (tfp_left->depth >= 32 - ? COGL_PIXEL_FORMAT_RGBA_8888_PRE - : COGL_PIXEL_FORMAT_RGB_888); - - tfp_right = g_object_new (COGL_TYPE_TEXTURE_PIXMAP_X11, - "context", cogl_texture_get_context (texture_left), - "width", cogl_texture_get_width (texture_left), - "height", cogl_texture_get_height (texture_left), - "format", internal_format, - NULL); - tfp_right->stereo_mode = COGL_TEXTURE_PIXMAP_RIGHT; - tfp_right->left = g_object_ref (tfp_left); - - _cogl_texture_set_allocated (COGL_TEXTURE (tfp_right), internal_format, - cogl_texture_get_width (texture_left), - cogl_texture_get_height (texture_left)); - - return COGL_TEXTURE (tfp_right); -} - -void -cogl_texture_pixmap_x11_update_area (CoglTexturePixmapX11 *tex_pixmap, - int x, - int y, - int width, - int height) -{ - /* We'll queue the update for both the GLX texture and the regular - texture because we can't determine which will be needed until we - actually render something */ - - if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - tex_pixmap = tex_pixmap->left; - - if (tex_pixmap->winsys) - { - const CoglWinsysVtable *winsys; - winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - winsys->texture_pixmap_x11_damage_notify (tex_pixmap); - } - - cogl_damage_rectangle_union (&tex_pixmap->damage_rect, - x, y, width, height); -} - -gboolean -cogl_texture_pixmap_x11_is_using_tfp_extension (CoglTexturePixmapX11 *tex_pixmap) -{ - if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - tex_pixmap = tex_pixmap->left; - - return !!tex_pixmap->winsys; -} - diff --git a/mutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.h b/mutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.h deleted file mode 100644 index e3d2188..0000000 --- a/mutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -/* NB: this is a top-level header that can be included directly but we - * want to be careful not to define __COGL_H_INSIDE__ when this is - * included internally while building Cogl itself since - * __COGL_H_INSIDE__ is used in headers to guard public vs private api - * definitions - */ -#ifndef COGL_COMPILATION - -/* Note: When building Cogl .gir we explicitly define - * __COGL_H_INSIDE__ */ -#ifndef __COGL_H_INSIDE__ -#define __COGL_H_INSIDE__ -#define __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_TEXTURE_PIXMAP_X11_ -#endif - -#endif /* COGL_COMPILATION */ - -#include "cogl/cogl-context.h" - -#include - -G_BEGIN_DECLS - -/** - * CoglTexturePixmapX11: - * - * Functions for creating and manipulating 2D meta - * textures derived from X11 pixmaps. - * - * These functions allow high-level meta textures (See the - * #CoglMetaTexture interface) that derive their contents from an X11 - * pixmap. - */ -#define COGL_TYPE_TEXTURE_PIXMAP_X11 (cogl_texture_pixmap_x11_get_type ()) -#define COGL_TEXTURE_PIXMAP_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_TEXTURE_PIXMAP_X11, CoglTexturePixmapX11)) -#define COGL_TEXTURE_PIXMAP_X11_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_TEXTURE_PIXMAP_X11, CoglTexturePixmapX11 const)) -#define COGL_TEXTURE_PIXMAP_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_TYPE_TEXTURE_PIXMAP_X11, CoglTexturePixmapX11Class)) -#define COGL_IS_TEXTURE_PIXMAP_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_TYPE_TEXTURE_PIXMAP_X11)) -#define COGL_IS_TEXTURE_PIXMAP_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_TYPE_TEXTURE_PIXMAP_X11)) -#define COGL_TEXTURE_PIXMAP_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COGL_TYPE_TEXTURE_PIXMAP_X11, CoglTexturePixmapX11Class)) - -typedef struct _CoglTexturePixmapX11Class CoglTexturePixmapX11Class; -typedef struct _CoglTexturePixmapX11 CoglTexturePixmapX11; - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (CoglTexturePixmapX11, g_object_unref) - -COGL_EXPORT -GType cogl_texture_pixmap_x11_get_type (void) G_GNUC_CONST; - -typedef enum -{ - COGL_TEXTURE_PIXMAP_X11_DAMAGE_RAW_RECTANGLES, - COGL_TEXTURE_PIXMAP_X11_DAMAGE_DELTA_RECTANGLES, - COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX, - COGL_TEXTURE_PIXMAP_X11_DAMAGE_NON_EMPTY -} CoglTexturePixmapX11ReportLevel; - -/** - * COGL_TEXTURE_PIXMAP_X11_ERROR: - * - * #GError domain for texture-pixmap-x11 errors. - */ -#define COGL_TEXTURE_PIXMAP_X11_ERROR (cogl_texture_pixmap_x11_error_quark ()) - -/** - * CoglTexturePixmapX11Error: - * @COGL_TEXTURE_PIXMAP_X11_ERROR_X11: An X11 protocol error - * - * Error codes that can be thrown when performing texture-pixmap-x11 - * operations. - */ -typedef enum -{ - COGL_TEXTURE_PIXMAP_X11_ERROR_X11, -} CoglTexturePixmapX11Error; - -COGL_EXPORT -uint32_t cogl_texture_pixmap_x11_error_quark (void); - -/** - * cogl_texture_pixmap_x11_new: - * @context: A #CoglContext - * @pixmap: A X11 pixmap ID - * @automatic_updates: Whether to automatically copy the contents of - * the pixmap to the texture. - * @error: A #GError for exceptions - * - * Creates a texture that contains the contents of @pixmap. If - * @automatic_updates is %TRUE then Cogl will attempt to listen for - * damage events on the pixmap and automatically update the texture - * when it changes. - * - * Return value: a new #CoglTexturePixmapX11 instance - */ -COGL_EXPORT CoglTexture * -cogl_texture_pixmap_x11_new (CoglContext *context, - uint32_t pixmap, - gboolean automatic_updates, - GError **error); - -/** - * cogl_texture_pixmap_x11_new_left: - * @context: A #CoglContext - * @pixmap: A X11 pixmap ID - * @automatic_updates: Whether to automatically copy the contents of - * the pixmap to the texture. - * @error: A #GError for exceptions - * - * Creates one of a pair of textures to contain the contents of @pixmap, - * which has stereo content. (Different images for the right and left eyes.) - * The left image is drawn using this texture; the right image is drawn - * using a texture created by calling - * cogl_texture_pixmap_x11_new_right() and passing in this texture as an - * argument. - * - * In general, you should not use this function unless you have - * queried the %GLX_STEREO_TREE_EXT attribute of the corresponding - * window using glXQueryDrawable() and determined that the window is - * stereo. Note that this attribute can change over time and - * notification is also provided through events defined in the - * EXT_stereo_tree GLX extension. As long as the system has support for - * stereo content, drawing using the left and right pixmaps will not - * produce an error even if the window doesn't have stereo - * content any more, but drawing with the right pixmap will produce - * undefined output, so you need to listen for these events and - * re-render to avoid race conditions. (Recreating a non-stereo - * pixmap is not necessary, but may save resources.) - * - * Return value: a new #CoglTexturePixmapX11 instance - */ -COGL_EXPORT CoglTexture * -cogl_texture_pixmap_x11_new_left (CoglContext *context, - uint32_t pixmap, - gboolean automatic_updates, - GError **error); - -/** - * cogl_texture_pixmap_x11_new_right: - * @left_texture: A #CoglTexturePixmapX11 instance created with - * cogl_texture_pixmap_x11_new_left(). - * - * Creates a texture object that corresponds to the right-eye image - * of a pixmap with stereo content. @left_texture must have been - * created using cogl_texture_pixmap_x11_new_left(). - * - * Return value: a new #CoglTexturePixmapX11 instance - */ -COGL_EXPORT CoglTexture * -cogl_texture_pixmap_x11_new_right (CoglTexturePixmapX11 *left_texture); - -/** - * cogl_texture_pixmap_x11_update_area: - * @texture: A #CoglTexturePixmapX11 instance - * @x: x coordinate of the area to update - * @y: y coordinate of the area to update - * @width: width of the area to update - * @height: height of the area to update - * - * Forces an update of the given @texture so that it is refreshed with - * the contents of the pixmap that was given to - * cogl_texture_pixmap_x11_new(). - */ -COGL_EXPORT void -cogl_texture_pixmap_x11_update_area (CoglTexturePixmapX11 *texture, - int x, - int y, - int width, - int height); - -/** - * cogl_texture_pixmap_x11_is_using_tfp_extension: - * @texture: A #CoglTexturePixmapX11 instance - * - * Checks whether the given @texture is using the - * GLX_EXT_texture_from_pixmap or similar extension to copy the - * contents of the pixmap to the texture. This extension is usually - * implemented as zero-copy operation so it implies the updates are - * working efficiently. - * - * Return value: %TRUE if the texture is using an efficient extension - * and %FALSE otherwise - */ -COGL_EXPORT gboolean -cogl_texture_pixmap_x11_is_using_tfp_extension (CoglTexturePixmapX11 *texture); - -G_END_DECLS - -/* The gobject introspection scanner seems to parse public headers in - * isolation which means we need to be extra careful about how we - * define and undefine __COGL_H_INSIDE__ used to detect when internal - * headers are incorrectly included by developers. In the gobject - * introspection case we have to manually define __COGL_H_INSIDE__ as - * a commandline argument for the scanner which means we must be - * careful not to undefine it in a header... - */ -#ifdef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_TEXTURE_PIXMAP_X11_ -#undef __COGL_H_INSIDE__ -#undef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_TEXTURE_PIXMAP_X11_ -#endif diff --git a/mutter/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h b/mutter/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h deleted file mode 100644 index a0d03a3..0000000 --- a/mutter/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This can be included multiple times with different definitions for - * the COGL_WINSYS_FEATURE_* functions. - */ - -/* Macro prototypes: - * COGL_WINSYS_FEATURE_BEGIN (name, namespaces, extension_names, - * implied_private_egl_feature_flags) - * COGL_WINSYS_FEATURE_FUNCTION (return_type, function_name, - * (arguments)) - * ... - * COGL_WINSYS_FEATURE_END () - * - * Note: You can list multiple namespace and extension names if the - * corresponding _FEATURE_FUNCTIONS have the same semantics across - * the different extension variants. - * - * XXX: NB: Don't add a trailing semicolon when using these macros - */ - -COGL_WINSYS_FEATURE_BEGIN (swap_region, - "NOK\0", - "swap_region\0", - COGL_EGL_WINSYS_FEATURE_SWAP_REGION) -COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSwapBuffersRegion, - (EGLDisplay dpy, - EGLSurface surface, - EGLint numRects, - const EGLint *rects)) -COGL_WINSYS_FEATURE_END () -/* XXX: These macros can't handle falling back to looking for - * EGL_KHR_image if EGL_KHR_image_base and EGL_KHR_image_pixmap aren't - * found... */ -#ifdef EGL_KHR_image_base -COGL_WINSYS_FEATURE_BEGIN (image_base, - "KHR\0", - "image_base\0", - 0) -COGL_WINSYS_FEATURE_FUNCTION (EGLImageKHR, eglCreateImage, - (EGLDisplay dpy, - EGLContext ctx, - EGLenum target, - EGLClientBuffer buffer, - const EGLint *attrib_list)) -COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglDestroyImage, - (EGLDisplay dpy, - EGLImageKHR image)) -COGL_WINSYS_FEATURE_END () -#endif -COGL_WINSYS_FEATURE_BEGIN (image_pixmap, - "KHR\0", - "image_pixmap\0", - COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP) -COGL_WINSYS_FEATURE_END () -#ifdef EGL_WL_bind_wayland_display -COGL_WINSYS_FEATURE_BEGIN (bind_wayland_display, - "WL\0", - "bind_wayland_display\0", - COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_WAYLAND_BUFFER) -COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglQueryWaylandBuffer, - (EGLDisplay dpy, - struct wl_resource *buffer, - EGLint attribute, EGLint *value)) -COGL_WINSYS_FEATURE_END () -#endif /* EGL_WL_bind_wayland_display */ - -COGL_WINSYS_FEATURE_BEGIN (create_context, - "KHR\0", - "create_context\0", - COGL_EGL_WINSYS_FEATURE_CREATE_CONTEXT) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (no_config_context, - "KHR\0", - "no_config_context\0", - COGL_EGL_WINSYS_FEATURE_NO_CONFIG_CONTEXT) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (buffer_age, - "EXT\0", - "buffer_age\0", - COGL_EGL_WINSYS_FEATURE_BUFFER_AGE) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (KHR_swap_buffers_with_damage, - "KHR\0", - "swap_buffers_with_damage\0", - 0) -COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSwapBuffersWithDamageKHR, - (EGLDisplay dpy, - EGLSurface surface, - const EGLint *rects, - EGLint n_rects)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (EXT_swap_buffers_with_damage, - "EXT\0", - "swap_buffers_with_damage\0", - 0) -COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSwapBuffersWithDamageEXT, - (EGLDisplay dpy, - EGLSurface surface, - const EGLint *rects, - EGLint n_rects)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (partial_update, - "KHR\0", - "partial_update\0", - COGL_EGL_WINSYS_FEATURE_BUFFER_AGE) -COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSetDamageRegion, - (EGLDisplay dpy, - EGLSurface surface, - const EGLint *rects, - EGLint n_rects)) -COGL_WINSYS_FEATURE_END () - -#if defined(EGL_KHR_fence_sync) || defined(EGL_KHR_reusable_sync) -COGL_WINSYS_FEATURE_BEGIN (fence_sync, - "KHR\0", - "fence_sync\0", - COGL_EGL_WINSYS_FEATURE_FENCE_SYNC) -COGL_WINSYS_FEATURE_FUNCTION (EGLSyncKHR, eglCreateSync, - (EGLDisplay dpy, - EGLenum type, - const EGLint *attrib_list)) -COGL_WINSYS_FEATURE_FUNCTION (EGLint, eglClientWaitSync, - (EGLDisplay dpy, - EGLSyncKHR sync, - EGLint flags, - EGLTimeKHR timeout)) -COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglDestroySync, - (EGLDisplay dpy, - EGLSyncKHR sync)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (native_fence_sync, - "ANDROID\0", - "native_fence_sync\0", - COGL_EGL_WINSYS_FEATURE_NATIVE_FENCE_SYNC) -COGL_WINSYS_FEATURE_FUNCTION (EGLint, eglDupNativeFenceFD, - (EGLDisplay dpy, - EGLSyncKHR sync)) -COGL_WINSYS_FEATURE_END () -#endif - -COGL_WINSYS_FEATURE_BEGIN (surfaceless_context, - "KHR\0", - "surfaceless_context\0", - COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (context_priority, - "IMG\0", - "context_priority\0", - COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY) -COGL_WINSYS_FEATURE_END () diff --git a/mutter/cogl/cogl/winsys/cogl-winsys-egl-private.h b/mutter/cogl/cogl/winsys/cogl-winsys-egl-private.h deleted file mode 100644 index 6a31d1a..0000000 --- a/mutter/cogl/cogl/winsys/cogl-winsys-egl-private.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-context.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/winsys/cogl-winsys-private.h" - -/* XXX: depending on what version of Mesa you have then - * eglQueryWaylandBuffer may take a wl_buffer or wl_resource argument - * and the EGL header will only forward declare the corresponding - * type. - * - * The use of wl_buffer has been deprecated and so internally we - * assume that eglQueryWaylandBuffer takes a wl_resource but for - * compatibility we forward declare wl_resource in case we are - * building with EGL headers that still use wl_buffer. - * - * Placing the forward declaration here means it comes before we - * #include cogl-winsys-egl-feature-functions.h bellow which - * declares lots of function pointers for accessing EGL extensions - * and cogl-winsys-egl.c will include this header before it also - * includes cogl-winsys-egl-feature-functions.h that may depend - * on this type. - */ -#ifdef EGL_WL_bind_wayland_display -struct wl_resource; -#endif - -typedef struct _CoglWinsysEGLVtable -{ - gboolean - (* display_setup) (CoglDisplay *display, - GError **error); - void - (* display_destroy) (CoglDisplay *display); - - gboolean - (* context_created) (CoglDisplay *display, - GError **error); - - void - (* cleanup_context) (CoglDisplay *display); - - gboolean - (* context_init) (CoglContext *context, GError **error); - - void - (* context_deinit) (CoglContext *context); - - int - (* add_config_attributes) (CoglDisplay *display, - const CoglFramebufferConfig *config, - EGLint *attributes); - gboolean - (* choose_config) (CoglDisplay *display, - EGLint *attributes, - EGLConfig *out_config, - GError **error); -} CoglWinsysEGLVtable; - -#define MAX_EGL_CONFIG_ATTRIBS 30 - -typedef enum _CoglEGLWinsysFeature -{ - COGL_EGL_WINSYS_FEATURE_SWAP_REGION = 1L << 0, - COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP = 1L << 1, - COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_WAYLAND_BUFFER = 1L << 2, - COGL_EGL_WINSYS_FEATURE_CREATE_CONTEXT = 1L << 3, - COGL_EGL_WINSYS_FEATURE_BUFFER_AGE = 1L << 4, - COGL_EGL_WINSYS_FEATURE_FENCE_SYNC = 1L << 5, - COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT = 1L << 6, - COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY = 1L << 7, - COGL_EGL_WINSYS_FEATURE_NO_CONFIG_CONTEXT = 1L << 8, - COGL_EGL_WINSYS_FEATURE_NATIVE_FENCE_SYNC = 1L << 9, -} CoglEGLWinsysFeature; - -typedef struct _CoglRendererEGL -{ - CoglEGLWinsysFeature private_features; - - EGLDisplay edpy; - - EGLint egl_version_major; - EGLint egl_version_minor; - - CoglClosure *resize_notify_idle; - - /* Data specific to the EGL platform */ - void *platform; - /* vtable for platform specific parts */ - const CoglWinsysEGLVtable *platform_vtable; - - /* Sync for latest submitted work */ - EGLSyncKHR sync; - - /* Function pointers for EGL specific extensions */ -#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d) - -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - ret (APIENTRY * pf_ ## name) args; - -#define COGL_WINSYS_FEATURE_END() - -#include "cogl/winsys/cogl-winsys-egl-feature-functions.h" - -#undef COGL_WINSYS_FEATURE_BEGIN -#undef COGL_WINSYS_FEATURE_FUNCTION -#undef COGL_WINSYS_FEATURE_END -} CoglRendererEGL; - -typedef struct _CoglDisplayEGL -{ - EGLContext egl_context; - EGLSurface dummy_surface; - EGLSurface egl_surface; - - EGLConfig egl_config; - gboolean found_egl_config; - - EGLSurface current_read_surface; - EGLSurface current_draw_surface; - EGLContext current_context; - - /* Platform specific display data */ - void *platform; -} CoglDisplayEGL; - -typedef struct _CoglContextEGL -{ - EGLSurface saved_draw_surface; - EGLSurface saved_read_surface; -} CoglContextEGL; - -COGL_EXPORT const CoglWinsysVtable * -_cogl_winsys_egl_get_vtable (void); - -COGL_EXPORT EGLBoolean -_cogl_winsys_egl_make_current (CoglDisplay *display, - EGLSurface draw, - EGLSurface read, - EGLContext context); - -COGL_EXPORT EGLBoolean -_cogl_winsys_egl_ensure_current (CoglDisplay *display); - -#ifdef EGL_KHR_image_base -EGLImageKHR -_cogl_egl_create_image (CoglContext *ctx, - EGLenum target, - EGLClientBuffer buffer, - const EGLint *attribs); - -void -_cogl_egl_destroy_image (CoglContext *ctx, - EGLImageKHR image); -#endif - -#ifdef EGL_WL_bind_wayland_display -gboolean -_cogl_egl_query_wayland_buffer (CoglContext *ctx, - struct wl_resource *buffer, - int attribute, - int *value); -#endif - -COGL_EXPORT gboolean -_cogl_winsys_egl_renderer_connect_common (CoglRenderer *renderer, - GError **error); - -COGL_EXPORT void -cogl_display_egl_determine_attributes (CoglDisplay *display, - const CoglFramebufferConfig *config, - EGLint *attributes); diff --git a/mutter/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h b/mutter/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h deleted file mode 100644 index 70b1136..0000000 --- a/mutter/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/winsys/cogl-winsys-private.h" - -COGL_EXPORT const CoglWinsysVtable * -_cogl_winsys_egl_xlib_get_vtable (void); - -XVisualInfo * -cogl_display_xlib_get_visual_info (CoglDisplay *display, - EGLConfig egl_config); diff --git a/mutter/cogl/cogl/winsys/cogl-winsys-egl-x11.c b/mutter/cogl/cogl/winsys/cogl-winsys-egl-x11.c deleted file mode 100644 index 7393f79..0000000 --- a/mutter/cogl/cogl/winsys/cogl-winsys-egl-x11.c +++ /dev/null @@ -1,641 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg - * Neil Roberts - */ - -#include "config.h" - -#include - -#include "cogl/cogl-xlib-renderer-private.h" -#include "cogl/cogl-xlib-renderer.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-onscreen-private.h" -#include "cogl/cogl-display-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/winsys/cogl-texture-pixmap-x11-private.h" -#include "cogl/cogl-texture-2d-private.h" -#include "cogl/driver/gl/cogl-texture-2d-gl-private.h" -#include "cogl/cogl-texture-2d.h" -#include "cogl/cogl-poll-private.h" -#include "cogl/winsys/cogl-onscreen-egl.h" -#include "cogl/winsys/cogl-onscreen-xlib.h" -#include "cogl/winsys/cogl-winsys-egl-x11-private.h" -#include "cogl/winsys/cogl-winsys-egl-private.h" - -static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable; - -typedef struct _CoglDisplayXlib -{ - Window dummy_xwin; -} CoglDisplayXlib; - -#ifdef EGL_KHR_image_pixmap -typedef struct _CoglTexturePixmapEGL -{ - EGLImageKHR image; - CoglTexture *texture; - gboolean bind_tex_image_queued; -} CoglTexturePixmapEGL; -#endif - -static CoglOnscreen * -find_onscreen_for_xid (CoglContext *context, uint32_t xid) -{ - GList *l; - - for (l = context->framebuffers; l; l = l->next) - { - CoglFramebuffer *framebuffer = l->data; - CoglOnscreen *onscreen; - - if (!COGL_IS_ONSCREEN (framebuffer)) - continue; - - onscreen = COGL_ONSCREEN (framebuffer); - if (cogl_onscreen_xlib_is_for_window (onscreen, (Window) xid)) - return onscreen; - } - - return NULL; -} - -static void -notify_resize (CoglContext *context, - Window drawable, - int width, - int height) -{ - CoglOnscreen *onscreen; - - onscreen = find_onscreen_for_xid (context, drawable); - if (!onscreen) - return; - - cogl_onscreen_xlib_resize (onscreen, width, height); -} - -static CoglFilterReturn -event_filter_cb (XEvent *xevent, void *data) -{ - CoglContext *context = data; - - if (xevent->type == ConfigureNotify) - { - notify_resize (context, - xevent->xconfigure.window, - xevent->xconfigure.width, - xevent->xconfigure.height); - } - else if (xevent->type == Expose) - { - CoglOnscreen *onscreen = - find_onscreen_for_xid (context, xevent->xexpose.window); - - if (onscreen) - { - CoglOnscreenDirtyInfo info; - - info.x = xevent->xexpose.x; - info.y = xevent->xexpose.y; - info.width = xevent->xexpose.width; - info.height = xevent->xexpose.height; - - _cogl_onscreen_queue_dirty (onscreen, &info); - } - } - - return COGL_FILTER_CONTINUE; -} - -XVisualInfo * -cogl_display_xlib_get_visual_info (CoglDisplay *display, - EGLConfig egl_config) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglRendererEGL *egl_renderer = display->renderer->winsys; - XVisualInfo visinfo_template; - int template_mask = 0; - XVisualInfo *visinfo = NULL; - int visinfos_count; - EGLint visualid, red_size, green_size, blue_size, alpha_size; - - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_NATIVE_VISUAL_ID, &visualid); - - if (visualid != 0) - { - visinfo_template.visualid = visualid; - template_mask |= VisualIDMask; - } - else - { - /* some EGL drivers don't implement the EGL_NATIVE_VISUAL_ID - * attribute, so attempt to find the closest match. */ - - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_RED_SIZE, &red_size); - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_GREEN_SIZE, &green_size); - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_BLUE_SIZE, &blue_size); - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_ALPHA_SIZE, &alpha_size); - - visinfo_template.depth = red_size + green_size + blue_size + alpha_size; - template_mask |= VisualDepthMask; - - visinfo_template.screen = DefaultScreen (xlib_renderer->xdpy); - template_mask |= VisualScreenMask; - } - - visinfo = XGetVisualInfo (xlib_renderer->xdpy, - template_mask, - &visinfo_template, - &visinfos_count); - - return visinfo; -} - -static void -_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) -{ - CoglRendererEGL *egl_renderer = renderer->winsys; - - _cogl_xlib_renderer_disconnect (renderer); - - eglTerminate (egl_renderer->edpy); - - g_free (egl_renderer); -} - -static EGLDisplay -_cogl_winsys_egl_get_display (void *native) -{ - EGLDisplay dpy = NULL; - const char *client_exts = eglQueryString (NULL, EGL_EXTENSIONS); - - if (g_strstr_len (client_exts, -1, "EGL_KHR_platform_base")) - { - PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = - (void *) eglGetProcAddress ("eglGetPlatformDisplay"); - - if (get_platform_display) - dpy = get_platform_display (EGL_PLATFORM_X11_KHR, native, NULL); - - if (dpy) - return dpy; - } - - if (g_strstr_len (client_exts, -1, "EGL_EXT_platform_base")) - { - PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = - (void *) eglGetProcAddress ("eglGetPlatformDisplayEXT"); - - if (get_platform_display) - dpy = get_platform_display (EGL_PLATFORM_X11_KHR, native, NULL); - - if (dpy) - return dpy; - } - - return eglGetDisplay ((EGLNativeDisplayType) native); -} - -static gboolean -_cogl_winsys_renderer_connect (CoglRenderer *renderer, - GError **error) -{ - CoglRendererEGL *egl_renderer; - CoglXlibRenderer *xlib_renderer; - - renderer->winsys = g_new0 (CoglRendererEGL, 1); - egl_renderer = renderer->winsys; - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable; - egl_renderer->sync = EGL_NO_SYNC_KHR; - - if (!_cogl_xlib_renderer_connect (renderer, error)) - goto error; - - egl_renderer->edpy = _cogl_winsys_egl_get_display (xlib_renderer->xdpy); - - if (!_cogl_winsys_egl_renderer_connect_common (renderer, error)) - goto error; - - return TRUE; - -error: - _cogl_winsys_renderer_disconnect (renderer); - return FALSE; -} - -static int -_cogl_winsys_egl_add_config_attributes (CoglDisplay *display, - const CoglFramebufferConfig *config, - EGLint *attributes) -{ - int i = 0; - - attributes[i++] = EGL_SURFACE_TYPE; - attributes[i++] = EGL_WINDOW_BIT; - - return i; -} - -static gboolean -_cogl_winsys_egl_choose_config (CoglDisplay *display, - EGLint *attributes, - EGLConfig *out_config, - GError **error) -{ - CoglRenderer *renderer = display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - EGLint config_count = 0; - EGLBoolean status; - - status = eglChooseConfig (egl_renderer->edpy, - attributes, - out_config, 1, - &config_count); - if (status != EGL_TRUE || config_count == 0) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "No compatible EGL configs found"); - return FALSE; - } - - return TRUE; -} - -static gboolean -_cogl_winsys_egl_display_setup (CoglDisplay *display, - GError **error) -{ - CoglDisplayEGL *egl_display = display->winsys; - CoglDisplayXlib *xlib_display; - - xlib_display = g_new0 (CoglDisplayXlib, 1); - egl_display->platform = xlib_display; - - return TRUE; -} - -static void -_cogl_winsys_egl_display_destroy (CoglDisplay *display) -{ - CoglDisplayEGL *egl_display = display->winsys; - - g_free (egl_display->platform); -} - -static gboolean -_cogl_winsys_egl_context_init (CoglContext *context, - GError **error) -{ - cogl_xlib_renderer_add_filter (context->display->renderer, - event_filter_cb, - context); - - /* We'll manually handle queueing dirty events in response to - * Expose events from X */ - COGL_FLAGS_SET (context->private_features, - COGL_PRIVATE_FEATURE_DIRTY_EVENTS, - TRUE); - - return TRUE; -} - -static void -_cogl_winsys_egl_context_deinit (CoglContext *context) -{ - cogl_xlib_renderer_remove_filter (context->display->renderer, - event_filter_cb, - context); -} - -static gboolean -_cogl_winsys_egl_context_created (CoglDisplay *display, - GError **error) -{ - CoglRenderer *renderer = display->renderer; - CoglDisplayEGL *egl_display = display->winsys; - CoglRendererEGL *egl_renderer = renderer->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - CoglDisplayXlib *xlib_display = egl_display->platform; - XVisualInfo *xvisinfo; - XSetWindowAttributes attrs; - const char *error_message; - - xvisinfo = cogl_display_xlib_get_visual_info (display, - egl_display->egl_config); - if (xvisinfo == NULL) - { - error_message = "Unable to find suitable X visual"; - goto fail; - } - - attrs.override_redirect = True; - attrs.colormap = XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - attrs.border_pixel = 0; - - if ((egl_renderer->private_features & - COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT) == 0) - { - xlib_display->dummy_xwin = - XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - -100, -100, 1, 1, - 0, - xvisinfo->depth, - CopyFromParent, - xvisinfo->visual, - CWOverrideRedirect | - CWColormap | - CWBorderPixel, - &attrs); - - egl_display->dummy_surface = - eglCreateWindowSurface (egl_renderer->edpy, - egl_display->egl_config, - (EGLNativeWindowType) xlib_display->dummy_xwin, - NULL); - - if (egl_display->dummy_surface == EGL_NO_SURFACE) - { - error_message = "Unable to create an EGL surface"; - XFree (xvisinfo); - goto fail; - } - } - - g_clear_pointer (&xvisinfo, XFree); - - if (!_cogl_winsys_egl_make_current (display, - egl_display->dummy_surface, - egl_display->dummy_surface, - egl_display->egl_context)) - { - if (egl_display->dummy_surface == EGL_NO_SURFACE) - error_message = "Unable to eglMakeCurrent with no surface"; - else - error_message = "Unable to eglMakeCurrent with dummy surface"; - goto fail; - } - - return TRUE; - -fail: - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "%s", error_message); - return FALSE; -} - -static void -_cogl_winsys_egl_cleanup_context (CoglDisplay *display) -{ - CoglDisplayEGL *egl_display = display->winsys; - CoglDisplayXlib *xlib_display = egl_display->platform; - CoglRenderer *renderer = display->renderer; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - CoglRendererEGL *egl_renderer = renderer->winsys; - - if (egl_display->dummy_surface != EGL_NO_SURFACE) - { - eglDestroySurface (egl_renderer->edpy, egl_display->dummy_surface); - egl_display->dummy_surface = EGL_NO_SURFACE; - } - - if (xlib_display->dummy_xwin) - { - XDestroyWindow (xlib_renderer->xdpy, xlib_display->dummy_xwin); - xlib_display->dummy_xwin = None; - } -} - -#ifdef EGL_KHR_image_pixmap - -static gboolean -_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - CoglContext *ctx = cogl_texture_get_context (tex); - CoglTexturePixmapEGL *egl_tex_pixmap; - EGLint attribs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; - CoglPixelFormat texture_format; - CoglRendererEGL *egl_renderer; - - egl_renderer = ctx->display->renderer->winsys; - - if (!(egl_renderer->private_features & - COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP) || - !_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE)) - { - tex_pixmap->winsys = NULL; - return FALSE; - } - - egl_tex_pixmap = g_new0 (CoglTexturePixmapEGL, 1); - - egl_tex_pixmap->image = - _cogl_egl_create_image (ctx, - EGL_NATIVE_PIXMAP_KHR, - (EGLClientBuffer)tex_pixmap->pixmap, - attribs); - if (egl_tex_pixmap->image == EGL_NO_IMAGE_KHR) - { - g_free (egl_tex_pixmap); - return FALSE; - } - - texture_format = (tex_pixmap->depth >= 32 ? - COGL_PIXEL_FORMAT_RGBA_8888_PRE : - COGL_PIXEL_FORMAT_RGB_888); - - egl_tex_pixmap->texture = - cogl_egl_texture_2d_new_from_image (ctx, - cogl_texture_get_width (tex), - cogl_texture_get_height (tex), - texture_format, - egl_tex_pixmap->image, - COGL_EGL_IMAGE_FLAG_NONE, - NULL); - - /* The image is initially bound as part of the creation */ - egl_tex_pixmap->bind_tex_image_queued = FALSE; - - tex_pixmap->winsys = egl_tex_pixmap; - - return TRUE; -} - -static void -_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapEGL *egl_tex_pixmap; - CoglContext *ctx; - - ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - - if (!tex_pixmap->winsys) - return; - - egl_tex_pixmap = tex_pixmap->winsys; - - if (egl_tex_pixmap->texture) - g_object_unref (egl_tex_pixmap->texture); - - if (egl_tex_pixmap->image != EGL_NO_IMAGE_KHR) - _cogl_egl_destroy_image (ctx, egl_tex_pixmap->image); - - tex_pixmap->winsys = NULL; - g_free (egl_tex_pixmap); -} - -static gboolean -_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode, - gboolean needs_mipmap) -{ - CoglTexturePixmapEGL *egl_tex_pixmap = tex_pixmap->winsys; - CoglTexture2D *tex_2d; - GError *error = NULL; - - if (needs_mipmap) - return FALSE; - - if (egl_tex_pixmap->bind_tex_image_queued) - { - COGL_NOTE (TEXTURE_PIXMAP, "Rebinding GLXPixmap for %p", tex_pixmap); - - tex_2d = COGL_TEXTURE_2D (egl_tex_pixmap->texture); - - if (cogl_texture_2d_gl_bind_egl_image (tex_2d, - egl_tex_pixmap->image, - &error)) - { - egl_tex_pixmap->bind_tex_image_queued = FALSE; - } - else - { - g_warning ("Failed to rebind EGLImage to CoglTexture2D: %s", - error->message); - g_error_free (error); - } - } - - return TRUE; -} - -static void -_cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapEGL *egl_tex_pixmap = tex_pixmap->winsys; - - egl_tex_pixmap->bind_tex_image_queued = TRUE; -} - -static CoglTexture * -_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode) -{ - CoglTexturePixmapEGL *egl_tex_pixmap = tex_pixmap->winsys; - - return egl_tex_pixmap->texture; -} - -#endif /* EGL_KHR_image_pixmap */ - -static const CoglWinsysEGLVtable -_cogl_winsys_egl_vtable = - { - .add_config_attributes = _cogl_winsys_egl_add_config_attributes, - .choose_config = _cogl_winsys_egl_choose_config, - .display_setup = _cogl_winsys_egl_display_setup, - .display_destroy = _cogl_winsys_egl_display_destroy, - .context_created = _cogl_winsys_egl_context_created, - .cleanup_context = _cogl_winsys_egl_cleanup_context, - .context_init = _cogl_winsys_egl_context_init, - .context_deinit = _cogl_winsys_egl_context_deinit, - }; - -COGL_EXPORT const CoglWinsysVtable * -_cogl_winsys_egl_xlib_get_vtable (void) -{ - static gboolean vtable_inited = FALSE; - static CoglWinsysVtable vtable; - - if (!vtable_inited) - { - /* The EGL_X11 winsys is a subclass of the EGL winsys so we - start by copying its vtable */ - - vtable = *_cogl_winsys_egl_get_vtable (); - - vtable.id = COGL_WINSYS_ID_EGL_XLIB; - vtable.name = "EGL_XLIB"; - vtable.constraints |= (COGL_RENDERER_CONSTRAINT_USES_X11 | - COGL_RENDERER_CONSTRAINT_USES_XLIB); - - vtable.renderer_connect = _cogl_winsys_renderer_connect; - vtable.renderer_disconnect = _cogl_winsys_renderer_disconnect; - -#ifdef EGL_KHR_image_pixmap - /* X11 tfp support... */ - /* XXX: instead of having a rather monolithic winsys vtable we could - * perhaps look for a way to separate these... */ - vtable.texture_pixmap_x11_create = - _cogl_winsys_texture_pixmap_x11_create; - vtable.texture_pixmap_x11_free = - _cogl_winsys_texture_pixmap_x11_free; - vtable.texture_pixmap_x11_update = - _cogl_winsys_texture_pixmap_x11_update; - vtable.texture_pixmap_x11_damage_notify = - _cogl_winsys_texture_pixmap_x11_damage_notify; - vtable.texture_pixmap_x11_get_texture = - _cogl_winsys_texture_pixmap_x11_get_texture; -#endif /* EGL_KHR_image_pixmap) */ - - vtable_inited = TRUE; - } - - return &vtable; -} diff --git a/mutter/cogl/cogl/winsys/cogl-winsys-egl.c b/mutter/cogl/cogl/winsys/cogl-winsys-egl.c deleted file mode 100644 index 66b9940..0000000 --- a/mutter/cogl/cogl/winsys/cogl-winsys-egl.c +++ /dev/null @@ -1,724 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-i18n-private.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-feature-private.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-framebuffer.h" -#include "cogl/cogl-onscreen-private.h" -#include "cogl/cogl-swap-chain-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-onscreen-template-private.h" -#include "cogl/cogl-egl.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl-trace.h" -#include "cogl/winsys/cogl-winsys-egl-private.h" -#include "cogl/winsys/cogl-winsys-private.h" -#include "cogl/winsys/cogl-onscreen-egl.h" - -#include -#include -#include -#include -#include - - -#ifndef EGL_KHR_create_context -#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 -#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB -#define EGL_CONTEXT_FLAGS_KHR 0x30FC -#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD -#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD -#define EGL_OPENGL_ES3_BIT_KHR 0x0040 -#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE -#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF -#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001 -#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 -#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 -#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 -#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 -#endif - -#ifndef EGL_IMG_context_priority -#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100 -#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101 -#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102 -#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103 -#endif - -/* Define a set of arrays containing the functions required from GL - for each winsys feature */ -#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \ - egl_private_flags) \ - static const CoglFeatureFunction \ - cogl_egl_feature_ ## name ## _funcs[] = { -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - { G_STRINGIFY (name), G_STRUCT_OFFSET (CoglRendererEGL, pf_ ## name) }, -#define COGL_WINSYS_FEATURE_END() \ - { NULL, 0 }, \ - }; -#include "cogl/winsys/cogl-winsys-egl-feature-functions.h" - -/* Define an array of features */ -#undef COGL_WINSYS_FEATURE_BEGIN -#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \ - egl_private_flags) \ - { 255, 255, 0, namespaces, extension_names, \ - egl_private_flags, \ - 0, \ - cogl_egl_feature_ ## name ## _funcs }, -#undef COGL_WINSYS_FEATURE_FUNCTION -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) -#undef COGL_WINSYS_FEATURE_END -#define COGL_WINSYS_FEATURE_END() - -static const CoglFeatureData winsys_feature_data[] = - { -#include "cogl/winsys/cogl-winsys-egl-feature-functions.h" - }; - -static GCallback -_cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer, - const char *name) -{ - return eglGetProcAddress (name); -} - -static void -_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) -{ - /* This function must be overridden by a platform winsys */ - g_assert_not_reached (); -} - -static void -_cogl_winsys_renderer_bind_api (CoglRenderer *renderer) -{ - if (renderer->driver == COGL_DRIVER_GL3) - eglBindAPI (EGL_OPENGL_API); - else if (renderer->driver == COGL_DRIVER_GLES2) - eglBindAPI (EGL_OPENGL_ES_API); -} - -/* Updates all the function pointers */ -static void -check_egl_extensions (CoglRenderer *renderer) -{ - CoglRendererEGL *egl_renderer = renderer->winsys; - const char *egl_extensions; - char **split_extensions; - int i; - - egl_extensions = eglQueryString (egl_renderer->edpy, EGL_EXTENSIONS); - split_extensions = g_strsplit (egl_extensions, " ", 0 /* max_tokens */); - - COGL_NOTE (WINSYS, " EGL Extensions: %s", egl_extensions); - - egl_renderer->private_features = 0; - for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++) - if (_cogl_feature_check (renderer, - "EGL", winsys_feature_data + i, 0, 0, - COGL_DRIVER_GL3, /* the driver isn't used */ - split_extensions, - egl_renderer)) - { - egl_renderer->private_features |= - winsys_feature_data[i].feature_flags_private; - } - - g_strfreev (split_extensions); -} - -gboolean -_cogl_winsys_egl_renderer_connect_common (CoglRenderer *renderer, - GError **error) -{ - CoglRendererEGL *egl_renderer = renderer->winsys; - - if (!eglInitialize (egl_renderer->edpy, - &egl_renderer->egl_version_major, - &egl_renderer->egl_version_minor)) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "Couldn't initialize EGL"); - return FALSE; - } - - check_egl_extensions (renderer); - - return TRUE; -} - -static gboolean -_cogl_winsys_renderer_connect (CoglRenderer *renderer, - GError **error) -{ - /* This function must be overridden by a platform winsys */ - g_assert_not_reached (); - return FALSE; -} - -void -cogl_display_egl_determine_attributes (CoglDisplay *display, - const CoglFramebufferConfig *config, - EGLint *attributes) -{ - CoglRenderer *renderer = display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - int i = 0; - - /* Let the platform add attributes first, including setting the - * EGL_SURFACE_TYPE */ - i = egl_renderer->platform_vtable->add_config_attributes (display, - config, - attributes); - - if (config->need_stencil) - { - attributes[i++] = EGL_STENCIL_SIZE; - attributes[i++] = 2; - } - - attributes[i++] = EGL_RED_SIZE; - attributes[i++] = 1; - attributes[i++] = EGL_GREEN_SIZE; - attributes[i++] = 1; - attributes[i++] = EGL_BLUE_SIZE; - attributes[i++] = 1; - - attributes[i++] = EGL_ALPHA_SIZE; - attributes[i++] = EGL_DONT_CARE; - - attributes[i++] = EGL_DEPTH_SIZE; - attributes[i++] = 1; - - attributes[i++] = EGL_BUFFER_SIZE; - attributes[i++] = EGL_DONT_CARE; - - attributes[i++] = EGL_RENDERABLE_TYPE; - attributes[i++] = (renderer->driver == COGL_DRIVER_GL3 ? - EGL_OPENGL_BIT : - EGL_OPENGL_ES2_BIT); - - if (config->samples_per_pixel) - { - attributes[i++] = EGL_SAMPLE_BUFFERS; - attributes[i++] = 1; - attributes[i++] = EGL_SAMPLES; - attributes[i++] = config->samples_per_pixel; - } - - attributes[i++] = EGL_NONE; - - g_assert (i < MAX_EGL_CONFIG_ATTRIBS); -} - -EGLBoolean -_cogl_winsys_egl_make_current (CoglDisplay *display, - EGLSurface draw, - EGLSurface read, - EGLContext context) -{ - CoglDisplayEGL *egl_display = display->winsys; - CoglRendererEGL *egl_renderer = display->renderer->winsys; - EGLBoolean ret; - - if (egl_display->current_draw_surface == draw && - egl_display->current_read_surface == read && - egl_display->current_context == context) - return EGL_TRUE; - - ret = eglMakeCurrent (egl_renderer->edpy, - draw, - read, - context); - - egl_display->current_draw_surface = draw; - egl_display->current_read_surface = read; - egl_display->current_context = context; - - return ret; -} - -EGLBoolean -_cogl_winsys_egl_ensure_current (CoglDisplay *display) -{ - CoglDisplayEGL *egl_display = display->winsys; - CoglRendererEGL *egl_renderer = display->renderer->winsys; - - return eglMakeCurrent (egl_renderer->edpy, - egl_display->current_draw_surface, - egl_display->current_read_surface, - egl_display->current_context); -} - -static void -cleanup_context (CoglDisplay *display) -{ - CoglRenderer *renderer = display->renderer; - CoglDisplayEGL *egl_display = display->winsys; - CoglRendererEGL *egl_renderer = renderer->winsys; - - if (egl_display->egl_context != EGL_NO_CONTEXT) - { - _cogl_winsys_egl_make_current (display, - EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT); - eglDestroyContext (egl_renderer->edpy, egl_display->egl_context); - egl_display->egl_context = EGL_NO_CONTEXT; - } - - if (egl_renderer->platform_vtable->cleanup_context) - egl_renderer->platform_vtable->cleanup_context (display); -} - -static gboolean -try_create_context (CoglDisplay *display, - GError **error) -{ - CoglRenderer *renderer = display->renderer; - CoglDisplayEGL *egl_display = display->winsys; - CoglRendererEGL *egl_renderer = renderer->winsys; - EGLDisplay edpy; - EGLConfig config; - EGLint attribs[11]; - EGLint cfg_attribs[MAX_EGL_CONFIG_ATTRIBS]; - GError *config_error = NULL; - const char *error_message; - int i = 0; - - g_return_val_if_fail (egl_display->egl_context == NULL, TRUE); - - cogl_renderer_bind_api (renderer); - - cogl_display_egl_determine_attributes (display, - &display->onscreen_template->config, - cfg_attribs); - - edpy = egl_renderer->edpy; - - if (!egl_renderer->platform_vtable->choose_config (display, - cfg_attribs, - &config, - &config_error)) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Couldn't choose config: %s", config_error->message); - g_error_free (config_error); - goto err; - } - - egl_display->egl_config = config; - - if (display->renderer->driver == COGL_DRIVER_GL3) - { - if (!(egl_renderer->private_features & - COGL_EGL_WINSYS_FEATURE_CREATE_CONTEXT)) - { - error_message = "Driver does not support GL 3 contexts"; - goto fail; - } - - /* Try to get a core profile 3.1 context with no deprecated features */ - attribs[i++] = EGL_CONTEXT_MAJOR_VERSION_KHR; - attribs[i++] = 3; - attribs[i++] = EGL_CONTEXT_MINOR_VERSION_KHR; - attribs[i++] = 1; - attribs[i++] = EGL_CONTEXT_FLAGS_KHR; - attribs[i++] = EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; - attribs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR; - attribs[i++] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; - } - else if (display->renderer->driver == COGL_DRIVER_GLES2) - { - attribs[i++] = EGL_CONTEXT_CLIENT_VERSION; - attribs[i++] = 2; - } - - if (egl_renderer->private_features & - COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY) - { - attribs[i++] = EGL_CONTEXT_PRIORITY_LEVEL_IMG; - attribs[i++] = EGL_CONTEXT_PRIORITY_HIGH_IMG; - } - - attribs[i++] = EGL_NONE; - - if (egl_renderer->private_features & - COGL_EGL_WINSYS_FEATURE_NO_CONFIG_CONTEXT) - { - egl_display->egl_context = eglCreateContext (edpy, - EGL_NO_CONFIG_KHR, - EGL_NO_CONTEXT, - attribs); - } - else - { - egl_display->egl_context = eglCreateContext (edpy, - config, - EGL_NO_CONTEXT, - attribs); - } - - if (egl_display->egl_context == EGL_NO_CONTEXT) - { - error_message = "Unable to create a suitable EGL context"; - goto fail; - } - - if (egl_renderer->private_features & - COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY) - { - EGLint value = EGL_CONTEXT_PRIORITY_MEDIUM_IMG; - - eglQueryContext (egl_renderer->edpy, - egl_display->egl_context, - EGL_CONTEXT_PRIORITY_LEVEL_IMG, - &value); - - if (value != EGL_CONTEXT_PRIORITY_HIGH_IMG) - g_message ("Failed to obtain high priority context"); - else - g_message ("Obtained a high priority EGL context"); - } - - if (egl_renderer->platform_vtable->context_created && - !egl_renderer->platform_vtable->context_created (display, error)) - return FALSE; - - return TRUE; - -fail: - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "%s", error_message); - -err: - cleanup_context (display); - - return FALSE; -} - -static void -_cogl_winsys_display_destroy (CoglDisplay *display) -{ - CoglRendererEGL *egl_renderer = display->renderer->winsys; - CoglDisplayEGL *egl_display = display->winsys; - - g_return_if_fail (egl_display != NULL); - - if (egl_renderer->sync != EGL_NO_SYNC_KHR) - egl_renderer->pf_eglDestroySync (egl_renderer->edpy, egl_renderer->sync); - - cleanup_context (display); - - if (egl_renderer->platform_vtable->display_destroy) - egl_renderer->platform_vtable->display_destroy (display); - - g_free (display->winsys); - display->winsys = NULL; -} - -static gboolean -_cogl_winsys_display_setup (CoglDisplay *display, - GError **error) -{ - CoglDisplayEGL *egl_display; - CoglRenderer *renderer = display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - - g_return_val_if_fail (display->winsys == NULL, FALSE); - - egl_display = g_new0 (CoglDisplayEGL, 1); - display->winsys = egl_display; - - if (egl_renderer->platform_vtable->display_setup && - !egl_renderer->platform_vtable->display_setup (display, error)) - goto error; - - if (!try_create_context (display, error)) - goto error; - - egl_display->found_egl_config = TRUE; - - return TRUE; - -error: - _cogl_winsys_display_destroy (display); - return FALSE; -} - -static gboolean -_cogl_winsys_context_init (CoglContext *context, GError **error) -{ - CoglRenderer *renderer = context->display->renderer; - CoglDisplayEGL *egl_display = context->display->winsys; - CoglRendererEGL *egl_renderer = renderer->winsys; - - context->winsys = g_new0 (CoglContextEGL, 1); - - g_return_val_if_fail (egl_display->egl_context, FALSE); - - memset (context->winsys_features, 0, sizeof (context->winsys_features)); - - check_egl_extensions (renderer); - - if (!_cogl_context_update_features (context, error)) - return FALSE; - - if (egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_SWAP_REGION) - { - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SWAP_REGION, TRUE); - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE); - } - - if ((egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_FENCE_SYNC) && - _cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_OES_EGL_SYNC)) - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_FENCE, TRUE); - - if (egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_BUFFER_AGE) - { - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_BUFFER_AGE, - TRUE); - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_BUFFER_AGE, TRUE); - } - - if (egl_renderer->platform_vtable->context_init && - !egl_renderer->platform_vtable->context_init (context, error)) - return FALSE; - - return TRUE; -} - -static void -_cogl_winsys_context_deinit (CoglContext *context) -{ - CoglRenderer *renderer = context->display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - - if (egl_renderer->platform_vtable->context_deinit) - egl_renderer->platform_vtable->context_deinit (context); - - g_free (context->winsys); -} - -#if defined(EGL_KHR_fence_sync) || defined(EGL_KHR_reusable_sync) -static void * -_cogl_winsys_fence_add (CoglContext *context) -{ - CoglRendererEGL *renderer = context->display->renderer->winsys; - void *ret; - - if (renderer->pf_eglCreateSync) - ret = renderer->pf_eglCreateSync (renderer->edpy, - EGL_SYNC_FENCE_KHR, - NULL); - else - ret = NULL; - - return ret; -} - -static gboolean -_cogl_winsys_fence_is_complete (CoglContext *context, void *fence) -{ - CoglRendererEGL *renderer = context->display->renderer->winsys; - EGLint ret; - - ret = renderer->pf_eglClientWaitSync (renderer->edpy, - fence, - EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, - 0); - return (ret == EGL_CONDITION_SATISFIED_KHR); -} - -static void -_cogl_winsys_fence_destroy (CoglContext *context, void *fence) -{ - CoglRendererEGL *renderer = context->display->renderer->winsys; - - renderer->pf_eglDestroySync (renderer->edpy, fence); -} - -static int -_cogl_winsys_get_sync_fd (CoglContext *context) -{ - CoglRendererEGL *renderer = context->display->renderer->winsys; - int fd; - - if (!renderer->pf_eglDupNativeFenceFD) - return -1; - - fd = renderer->pf_eglDupNativeFenceFD (renderer->edpy, renderer->sync); - if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) - return -1; - - return fd; -} - -static void -_cogl_winsys_update_sync (CoglContext *context) -{ - CoglRendererEGL *renderer = context->display->renderer->winsys; - - if (!renderer->pf_eglDestroySync || !renderer->pf_eglCreateSync) - return; - - if (renderer->sync != EGL_NO_SYNC_KHR) - renderer->pf_eglDestroySync (renderer->edpy, renderer->sync); - - renderer->sync = renderer->pf_eglCreateSync (renderer->edpy, - EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); -} -#endif - -static CoglWinsysVtable _cogl_winsys_vtable = - { - .constraints = COGL_RENDERER_CONSTRAINT_USES_EGL, - - /* This winsys is only used as a base for the EGL-platform - winsys's so it does not have an ID or a name */ - - .renderer_get_proc_address = _cogl_winsys_renderer_get_proc_address, - .renderer_connect = _cogl_winsys_renderer_connect, - .renderer_disconnect = _cogl_winsys_renderer_disconnect, - .renderer_bind_api = _cogl_winsys_renderer_bind_api, - .display_setup = _cogl_winsys_display_setup, - .display_destroy = _cogl_winsys_display_destroy, - .context_init = _cogl_winsys_context_init, - .context_deinit = _cogl_winsys_context_deinit, - -#if defined(EGL_KHR_fence_sync) || defined(EGL_KHR_reusable_sync) - .fence_add = _cogl_winsys_fence_add, - .fence_is_complete = _cogl_winsys_fence_is_complete, - .fence_destroy = _cogl_winsys_fence_destroy, - .get_sync_fd = _cogl_winsys_get_sync_fd, - .update_sync = _cogl_winsys_update_sync, -#endif - }; - -/* XXX: we use a function because no doubt someone will complain - * about using c99 member initializers because they aren't portable - * to windows. We want to avoid having to rigidly follow the real - * order of members since some members are #ifdefd and we'd have - * to mirror the #ifdefing to add padding etc. For any winsys that - * can assume the platform has a sane compiler then we can just use - * c99 initializers for insane platforms they can initialize - * the members by name in a function. - */ -const CoglWinsysVtable * -_cogl_winsys_egl_get_vtable (void) -{ - return &_cogl_winsys_vtable; -} - -#ifdef EGL_KHR_image_base -EGLImageKHR -_cogl_egl_create_image (CoglContext *ctx, - EGLenum target, - EGLClientBuffer buffer, - const EGLint *attribs) -{ - CoglDisplayEGL *egl_display = ctx->display->winsys; - CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys; - EGLContext egl_ctx; - - g_return_val_if_fail (egl_renderer->pf_eglCreateImage, EGL_NO_IMAGE_KHR); - - /* The EGL_KHR_image_pixmap spec explicitly states that EGL_NO_CONTEXT must - * always be used in conjunction with the EGL_NATIVE_PIXMAP_KHR target */ -#ifdef EGL_KHR_image_pixmap - if (target == EGL_NATIVE_PIXMAP_KHR) - egl_ctx = EGL_NO_CONTEXT; - else -#endif -#ifdef EGL_WL_bind_wayland_display - /* The WL_bind_wayland_display spec states that EGL_NO_CONTEXT is to be used - * in conjunction with the EGL_WAYLAND_BUFFER_WL target */ - if (target == EGL_WAYLAND_BUFFER_WL) - egl_ctx = EGL_NO_CONTEXT; - else -#endif - egl_ctx = egl_display->egl_context; - - return egl_renderer->pf_eglCreateImage (egl_renderer->edpy, - egl_ctx, - target, - buffer, - attribs); -} - -void -_cogl_egl_destroy_image (CoglContext *ctx, - EGLImageKHR image) -{ - CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys; - - g_return_if_fail (egl_renderer->pf_eglDestroyImage); - - egl_renderer->pf_eglDestroyImage (egl_renderer->edpy, image); -} -#endif - -#ifdef EGL_WL_bind_wayland_display -gboolean -_cogl_egl_query_wayland_buffer (CoglContext *ctx, - struct wl_resource *buffer, - int attribute, - int *value) -{ - CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys; - - g_return_val_if_fail (egl_renderer->pf_eglQueryWaylandBuffer, FALSE); - - return egl_renderer->pf_eglQueryWaylandBuffer (egl_renderer->edpy, - buffer, - attribute, - value); -} -#endif - -EGLDisplay -cogl_egl_context_get_egl_display (CoglContext *context) -{ - CoglRendererEGL *egl_renderer = context->display->renderer->winsys; - - return egl_renderer->edpy; -} diff --git a/mutter/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h b/mutter/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h deleted file mode 100644 index 31e73db..0000000 --- a/mutter/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This can be included multiple times with different definitions for - * the COGL_WINSYS_FEATURE_* functions. - */ - -/* Macro prototypes: - * COGL_WINSYS_FEATURE_BEGIN (major_glx_version, minor_glx_version, - * name, namespaces, extension_names, - * implied_legacy_feature_flags, - * implied_winsys_feature) - * COGL_WINSYS_FEATURE_FUNCTION (return_type, function_name, - * (arguments)) - * ... - * COGL_WINSYS_FEATURE_END () - * - * Note: You can list multiple namespace and extension names if the - * corresponding _FEATURE_FUNCTIONS have the same semantics across - * the different extension variants. - * - * XXX: NB: Don't add a trailing semicolon when using these macros - */ - -/* Base functions that we assume are always available */ -COGL_WINSYS_FEATURE_BEGIN (0, 0, /* always available */ - base_glx_functions, - "\0", - "\0", - 0, /* no implied public feature */ - 0 /* no winsys feature */) -COGL_WINSYS_FEATURE_FUNCTION (void, glXDestroyContext, - (Display *dpy, GLXContext ctx)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXSwapBuffers, - (Display *dpy, GLXDrawable drawable)) -COGL_WINSYS_FEATURE_FUNCTION (Bool, glXIsDirect, - (Display *dpy, GLXContext ctx)) -COGL_WINSYS_FEATURE_FUNCTION (int, glXGetFBConfigAttrib, - (Display *dpy, GLXFBConfig config, - int attribute, int *value)) -COGL_WINSYS_FEATURE_FUNCTION (GLXWindow, glXCreateWindow, - (Display *dpy, GLXFBConfig config, - Window win, const int *attribList)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXDestroyWindow, - (Display *dpy, GLXWindow window)) -COGL_WINSYS_FEATURE_FUNCTION (GLXPixmap, glXCreatePixmap, - (Display *dpy, GLXFBConfig config, - Pixmap pixmap, const int *attribList)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXDestroyPixmap, - (Display *dpy, GLXPixmap pixmap)) -COGL_WINSYS_FEATURE_FUNCTION (GLXContext, glXCreateNewContext, - (Display *dpy, GLXFBConfig config, - int renderType, GLXContext shareList, - Bool direct)) -COGL_WINSYS_FEATURE_FUNCTION (Bool, glXMakeContextCurrent, - (Display *dpy, GLXDrawable draw, - GLXDrawable read, GLXContext ctx)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXSelectEvent, - (Display *dpy, GLXDrawable drawable, - unsigned long mask)) -COGL_WINSYS_FEATURE_FUNCTION (GLXFBConfig *, glXGetFBConfigs, - (Display *dpy, int screen, int *nelements)) -COGL_WINSYS_FEATURE_FUNCTION (GLXFBConfig *, glXChooseFBConfig, - (Display *dpy, int screen, - const int *attrib_list, int *nelements)) -COGL_WINSYS_FEATURE_FUNCTION (XVisualInfo *, glXGetVisualFromFBConfig, - (Display *dpy, GLXFBConfig config)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - texture_from_pixmap, - "EXT\0", - "texture_from_pixmap\0", - 0, - COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP) -COGL_WINSYS_FEATURE_FUNCTION (void, glXBindTexImage, - (Display *display, - GLXDrawable drawable, - int buffer, - int *attribList)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXReleaseTexImage, - (Display *display, - GLXDrawable drawable, - int buffer)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - video_sync, - "SGI\0", - "video_sync\0", - 0, - COGL_WINSYS_FEATURE_VBLANK_COUNTER) -COGL_WINSYS_FEATURE_FUNCTION (int, glXGetVideoSync, - (unsigned int *count)) -COGL_WINSYS_FEATURE_FUNCTION (int, glXWaitVideoSync, - (int divisor, - int remainder, - unsigned int *count)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - swap_control, - "SGI\0", - "swap_control\0", - 0, - 0) -COGL_WINSYS_FEATURE_FUNCTION (int, glXSwapInterval, - (int interval)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - sync_control, - "OML\0", - "sync_control\0", - 0, - 0) -COGL_WINSYS_FEATURE_FUNCTION (Bool, glXGetSyncValues, - (Display* dpy, - GLXDrawable drawable, - int64_t* ust, - int64_t* msc, - int64_t* sbc)) -COGL_WINSYS_FEATURE_FUNCTION (Bool, glXWaitForMsc, - (Display* dpy, - GLXDrawable drawable, - int64_t target_msc, - int64_t divisor, - int64_t remainder, - int64_t* ust, - int64_t* msc, - int64_t* sbc)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - copy_sub_buffer, - "MESA\0", - "copy_sub_buffer\0", - 0, -/* We initially assumed that copy_sub_buffer is synchronized on - * which is only the case for a subset of GPUs for example it is not - * synchronized on INTEL gen6 and gen7, so we remove this assumption - * for now - */ -#if 0 - COGL_WINSYS_FEATURE_SWAP_REGION_SYNCHRONIZED) -#endif - 0) -COGL_WINSYS_FEATURE_FUNCTION (void, glXCopySubBuffer, - (Display *dpy, - GLXDrawable drawable, - int x, int y, int width, int height)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - swap_event, - "INTEL\0", - "swap_event\0", - 0, - COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT) - -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - create_context, - "ARB\0", - "create_context", - 0, - 0) -COGL_WINSYS_FEATURE_FUNCTION (GLXContext, glXCreateContextAttribs, - (Display *dpy, - GLXFBConfig config, - GLXContext share_context, - Bool direct, - const int *attrib_list)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - buffer_age, - "EXT\0", - "buffer_age\0", - 0, - COGL_WINSYS_FEATURE_BUFFER_AGE) -COGL_WINSYS_FEATURE_END () diff --git a/mutter/cogl/cogl/winsys/cogl-winsys-glx-private.h b/mutter/cogl/cogl/winsys/cogl-winsys-glx-private.h deleted file mode 100644 index a6732d9..0000000 --- a/mutter/cogl/cogl/winsys/cogl-winsys-glx-private.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -COGL_EXPORT const CoglWinsysVtable * -_cogl_winsys_glx_get_vtable (void); - -gboolean -cogl_display_glx_find_fbconfig (CoglDisplay *display, - const CoglFramebufferConfig *config, - GLXFBConfig *config_ret, - GError **error); - -void -cogl_context_glx_set_current_drawable (CoglContext *context, - GLXDrawable drawable); - -GLXDrawable -cogl_context_glx_get_current_drawable (CoglContext *context); diff --git a/mutter/cogl/cogl/winsys/cogl-winsys-glx.c b/mutter/cogl/cogl/winsys/cogl-winsys-glx.c deleted file mode 100644 index b57d962..0000000 --- a/mutter/cogl/cogl/winsys/cogl-winsys-glx.c +++ /dev/null @@ -1,1449 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-i18n-private.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-feature-private.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-framebuffer.h" -#include "cogl/cogl-swap-chain-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-onscreen-template-private.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl-texture-2d-private.h" -#include "cogl/cogl-frame-info-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-onscreen-private.h" -#include "cogl/cogl-swap-chain-private.h" -#include "cogl/cogl-xlib-renderer.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-poll-private.h" -#include "cogl/driver/gl/cogl-pipeline-opengl-private.h" -#include "cogl/winsys/cogl-glx.h" -#include "cogl/winsys/cogl-glx-renderer-private.h" -#include "cogl/winsys/cogl-glx-display-private.h" -#include "cogl/winsys/cogl-onscreen-glx.h" -#include "cogl/winsys/cogl-winsys-private.h" -#include "cogl/winsys/cogl-winsys-glx-private.h" -#include "mtk/mtk-x11.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -/* This is a relatively new extension */ -#ifndef GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV -#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7 -#endif - -#define MAX_GLX_CONFIG_ATTRIBS 30 - -typedef struct _CoglOnscreenGlx CoglOnscreenGlx; - -typedef struct _CoglContextGLX -{ - GLXDrawable current_drawable; -} CoglContextGLX; - -typedef struct _CoglPixmapTextureEyeGLX -{ - CoglTexture *glx_tex; - gboolean bind_tex_image_queued; - gboolean pixmap_bound; -} CoglPixmapTextureEyeGLX; - -typedef struct _CoglTexturePixmapGLX -{ - GLXPixmap glx_pixmap; - gboolean has_mipmap_space; - gboolean can_mipmap; - - CoglPixmapTextureEyeGLX left; - CoglPixmapTextureEyeGLX right; -} CoglTexturePixmapGLX; - -/* Define a set of arrays containing the functions required from GL - for each winsys feature */ -#define COGL_WINSYS_FEATURE_BEGIN(major_version, minor_version, \ - name, namespaces, extension_names, \ - feature_flags, \ - winsys_feature) \ - static const CoglFeatureFunction \ - cogl_glx_feature_ ## name ## _funcs[] = { -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - { G_STRINGIFY (name), G_STRUCT_OFFSET (CoglGLXRenderer, name) }, -#define COGL_WINSYS_FEATURE_END() \ - { NULL, 0 }, \ - }; -#include "cogl/winsys/cogl-winsys-glx-feature-functions.h" - -/* Define an array of features */ -#undef COGL_WINSYS_FEATURE_BEGIN -#define COGL_WINSYS_FEATURE_BEGIN(major_version, minor_version, \ - name, namespaces, extension_names, \ - feature_flags, \ - winsys_feature) \ - { major_version, minor_version, \ - 0, namespaces, extension_names, \ - 0, \ - winsys_feature, \ - cogl_glx_feature_ ## name ## _funcs }, -#undef COGL_WINSYS_FEATURE_FUNCTION -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) -#undef COGL_WINSYS_FEATURE_END -#define COGL_WINSYS_FEATURE_END() - -static const CoglFeatureData winsys_feature_data[] = - { -#include "cogl/winsys/cogl-winsys-glx-feature-functions.h" - }; - -static GCallback -_cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer, - const char *name) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - - return glx_renderer->glXGetProcAddress ((const GLubyte *) name); -} - -static CoglOnscreen * -find_onscreen_for_xid (CoglContext *context, uint32_t xid) -{ - GList *l; - - for (l = context->framebuffers; l; l = l->next) - { - CoglFramebuffer *framebuffer = l->data; - CoglOnscreen *onscreen; - - if (!COGL_IS_ONSCREEN (framebuffer)) - continue; - - onscreen = COGL_ONSCREEN (framebuffer); - if (cogl_onscreen_glx_is_for_window (onscreen, (Window) xid)) - return onscreen; - } - - return NULL; -} - -static void -notify_swap_buffers (CoglContext *context, GLXBufferSwapComplete *swap_event) -{ - CoglOnscreen *onscreen = find_onscreen_for_xid (context, (uint32_t)swap_event->drawable); - - if (!onscreen) - return; - - cogl_onscreen_glx_notify_swap_buffers (onscreen, swap_event); -} - -static void -notify_resize (CoglContext *context, - XConfigureEvent *configure_event) -{ - CoglOnscreen *onscreen; - - onscreen = find_onscreen_for_xid (context, configure_event->window); - if (!onscreen) - return; - - cogl_onscreen_glx_resize (onscreen, configure_event); -} - -static CoglFilterReturn -glx_event_filter_cb (XEvent *xevent, void *data) -{ - CoglContext *context = data; -#ifdef GLX_INTEL_swap_event - CoglGLXRenderer *glx_renderer; -#endif - - if (xevent->type == ConfigureNotify) - { - notify_resize (context, - &xevent->xconfigure); - - /* we let ConfigureNotify pass through */ - return COGL_FILTER_CONTINUE; - } - -#ifdef GLX_INTEL_swap_event - glx_renderer = context->display->renderer->winsys; - - if (xevent->type == (glx_renderer->glx_event_base + GLX_BufferSwapComplete)) - { - GLXBufferSwapComplete *swap_event = (GLXBufferSwapComplete *) xevent; - - notify_swap_buffers (context, swap_event); - - /* remove SwapComplete events from the queue */ - return COGL_FILTER_REMOVE; - } -#endif /* GLX_INTEL_swap_event */ - - if (xevent->type == Expose) - { - CoglOnscreen *onscreen = - find_onscreen_for_xid (context, xevent->xexpose.window); - - if (onscreen) - { - CoglOnscreenDirtyInfo info; - - info.x = xevent->xexpose.x; - info.y = xevent->xexpose.y; - info.width = xevent->xexpose.width; - info.height = xevent->xexpose.height; - - _cogl_onscreen_queue_dirty (onscreen, &info); - } - - return COGL_FILTER_CONTINUE; - } - - return COGL_FILTER_CONTINUE; -} - -static void -_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - - _cogl_xlib_renderer_disconnect (renderer); - - if (glx_renderer->libgl_module) - g_module_close (glx_renderer->libgl_module); - - g_free (renderer->winsys); -} - -static gboolean -update_all_outputs (CoglRenderer *renderer) -{ - GList *l; - - _COGL_GET_CONTEXT (context, FALSE); - - if (context->display == NULL) /* during connection */ - return FALSE; - - if (context->display->renderer != renderer) - return FALSE; - - for (l = context->framebuffers; l; l = l->next) - { - CoglFramebuffer *framebuffer = l->data; - - if (!COGL_IS_ONSCREEN (framebuffer)) - continue; - - cogl_onscreen_glx_update_output (COGL_ONSCREEN (framebuffer)); - } - - return TRUE; -} - -static void -_cogl_winsys_renderer_outputs_changed (CoglRenderer *renderer) -{ - update_all_outputs (renderer); -} - -static void -_cogl_winsys_renderer_bind_api (CoglRenderer *renderer) -{ -} - -static gboolean -resolve_core_glx_functions (CoglRenderer *renderer, - GError **error) -{ - CoglGLXRenderer *glx_renderer; - - glx_renderer = renderer->winsys; - - if (!g_module_symbol (glx_renderer->libgl_module, "glXQueryExtension", - (void **) &glx_renderer->glXQueryExtension) || - !g_module_symbol (glx_renderer->libgl_module, "glXQueryVersion", - (void **) &glx_renderer->glXQueryVersion) || - !g_module_symbol (glx_renderer->libgl_module, "glXQueryExtensionsString", - (void **) &glx_renderer->glXQueryExtensionsString) || - (!g_module_symbol (glx_renderer->libgl_module, "glXGetProcAddress", - (void **) &glx_renderer->glXGetProcAddress) && - !g_module_symbol (glx_renderer->libgl_module, "glXGetProcAddressARB", - (void **) &glx_renderer->glXGetProcAddress)) || - !g_module_symbol (glx_renderer->libgl_module, "glXQueryDrawable", - (void **) &glx_renderer->glXQueryDrawable)) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "Failed to resolve required GLX symbol"); - return FALSE; - } - - return TRUE; -} - -static void -update_base_winsys_features (CoglRenderer *renderer) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - const char *glx_extensions; - int default_screen; - char **split_extensions; - int i; - - default_screen = DefaultScreen (xlib_renderer->xdpy); - glx_extensions = - glx_renderer->glXQueryExtensionsString (xlib_renderer->xdpy, - default_screen); - - COGL_NOTE (WINSYS, " GLX Extensions: %s", glx_extensions); - - split_extensions = g_strsplit (glx_extensions, " ", 0 /* max_tokens */); - - for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++) - if (_cogl_feature_check (renderer, - "GLX", winsys_feature_data + i, - glx_renderer->glx_major, - glx_renderer->glx_minor, - COGL_DRIVER_GL3, /* the driver isn't used */ - split_extensions, - glx_renderer)) - { - if (winsys_feature_data[i].winsys_feature) - COGL_FLAGS_SET (glx_renderer->base_winsys_features, - winsys_feature_data[i].winsys_feature, - TRUE); - } - - g_strfreev (split_extensions); - - /* The GLX_SGI_video_sync spec explicitly states this extension - * only works for direct contexts; we don't know per-renderer - * if the context is direct or not, so we turn off the feature - * flag; we still use the extension within this file looking - * instead at glx_display->have_vblank_counter. - */ - COGL_FLAGS_SET (glx_renderer->base_winsys_features, - COGL_WINSYS_FEATURE_VBLANK_COUNTER, - FALSE); - - /* Because of the direct-context dependency, the VBLANK_WAIT feature - * doesn't reflect the presence of GLX_SGI_video_sync. - */ - if (glx_renderer->glXWaitForMsc) - COGL_FLAGS_SET (glx_renderer->base_winsys_features, - COGL_WINSYS_FEATURE_VBLANK_WAIT, - TRUE); -} - -static gboolean -_cogl_winsys_renderer_connect (CoglRenderer *renderer, - GError **error) -{ - CoglGLXRenderer *glx_renderer; - CoglXlibRenderer *xlib_renderer; - - renderer->winsys = g_new0 (CoglGLXRenderer, 1); - - glx_renderer = renderer->winsys; - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - if (!_cogl_xlib_renderer_connect (renderer, error)) - goto error; - - if (renderer->driver != COGL_DRIVER_GL3) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "GLX Backend can only be used in conjunction with OpenGL"); - goto error; - } - - glx_renderer->libgl_module = g_module_open (COGL_GL_LIBNAME, - G_MODULE_BIND_LAZY); - - if (glx_renderer->libgl_module == NULL) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "Failed to dynamically open the OpenGL library"); - goto error; - } - - if (!resolve_core_glx_functions (renderer, error)) - goto error; - - if (!glx_renderer->glXQueryExtension (xlib_renderer->xdpy, - &glx_renderer->glx_error_base, - &glx_renderer->glx_event_base)) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "XServer appears to lack required GLX support"); - goto error; - } - - /* XXX: Note: For a long time Mesa exported a hybrid GLX, exporting - * extensions specified to require GLX 1.3, but still reporting 1.2 - * via glXQueryVersion. */ - if (!glx_renderer->glXQueryVersion (xlib_renderer->xdpy, - &glx_renderer->glx_major, - &glx_renderer->glx_minor) - || !(glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 2)) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "XServer appears to lack required GLX 1.2 support"); - goto error; - } - - update_base_winsys_features (renderer); - - glx_renderer->dri_fd = -1; - - return TRUE; - -error: - _cogl_winsys_renderer_disconnect (renderer); - return FALSE; -} - -static gboolean -update_winsys_features (CoglContext *context, GError **error) -{ - CoglGLXDisplay *glx_display = context->display->winsys; - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - - g_return_val_if_fail (glx_display->glx_context, FALSE); - - if (!_cogl_context_update_features (context, error)) - return FALSE; - - memcpy (context->winsys_features, - glx_renderer->base_winsys_features, - sizeof (context->winsys_features)); - - if (glx_renderer->glXCopySubBuffer || context->glBlitFramebuffer) - COGL_FLAGS_SET (context->winsys_features, COGL_WINSYS_FEATURE_SWAP_REGION, TRUE); - - /* Note: glXCopySubBuffer and glBlitFramebuffer won't be throttled - * by the SwapInterval so we have to throttle swap_region requests - * manually... */ - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION) && - (glx_display->have_vblank_counter || glx_display->can_vblank_wait)) - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE); - - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) - { - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT, TRUE); - } - - /* We'll manually handle queueing dirty events in response to - * Expose events from X */ - COGL_FLAGS_SET (context->private_features, - COGL_PRIVATE_FEATURE_DIRTY_EVENTS, - TRUE); - - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE)) - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_BUFFER_AGE, TRUE); - - return TRUE; -} - -static void -glx_attributes_from_framebuffer_config (CoglDisplay *display, - const CoglFramebufferConfig *config, - int *attributes) -{ - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - int i = 0; - - attributes[i++] = GLX_DRAWABLE_TYPE; - attributes[i++] = GLX_WINDOW_BIT; - - attributes[i++] = GLX_RENDER_TYPE; - attributes[i++] = GLX_RGBA_BIT; - - attributes[i++] = GLX_DOUBLEBUFFER; - attributes[i++] = GL_TRUE; - - attributes[i++] = GLX_RED_SIZE; - attributes[i++] = 1; - attributes[i++] = GLX_GREEN_SIZE; - attributes[i++] = 1; - attributes[i++] = GLX_BLUE_SIZE; - attributes[i++] = 1; - attributes[i++] = GLX_ALPHA_SIZE; - attributes[i++] = GLX_DONT_CARE; - attributes[i++] = GLX_DEPTH_SIZE; - attributes[i++] = 1; - attributes[i++] = GLX_STENCIL_SIZE; - attributes[i++] = config->need_stencil ? 2 : 0; - if (config->stereo_enabled) - { - attributes[i++] = GLX_STEREO; - attributes[i++] = TRUE; - } - - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 4 && - config->samples_per_pixel) - { - attributes[i++] = GLX_SAMPLE_BUFFERS; - attributes[i++] = 1; - attributes[i++] = GLX_SAMPLES; - attributes[i++] = config->samples_per_pixel; - } - - attributes[i++] = None; - - g_assert (i < MAX_GLX_CONFIG_ATTRIBS); -} - -/* It seems the GLX spec never defined an invalid GLXFBConfig that - * we could overload as an indication of error, so we have to return - * an explicit boolean status. */ -gboolean -cogl_display_glx_find_fbconfig (CoglDisplay *display, - const CoglFramebufferConfig *config, - GLXFBConfig *config_ret, - GError **error) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - GLXFBConfig *configs = NULL; - int n_configs; - static int attributes[MAX_GLX_CONFIG_ATTRIBS]; - gboolean ret = TRUE; - int xscreen_num = DefaultScreen (xlib_renderer->xdpy); - - glx_attributes_from_framebuffer_config (display, config, attributes); - - configs = glx_renderer->glXChooseFBConfig (xlib_renderer->xdpy, - xscreen_num, - attributes, - &n_configs); - - if (!configs || n_configs == 0) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Failed to find any compatible fbconfigs"); - ret = FALSE; - goto done; - } - - COGL_NOTE (WINSYS, "Using the first available FBConfig"); - *config_ret = configs[0]; - -done: - XFree (configs); - return ret; -} - -static GLXContext -create_gl3_context (CoglDisplay *display, - GLXFBConfig fb_config) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - - /* We want a core profile 3.1 context with no deprecated features */ - static const int attrib_list[] = - { - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 1, - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, - None - }; - /* NV_robustness_video_memory_purge relies on GLX_ARB_create_context - and in part on ARB_robustness. Namely, it needs the notification - strategy to be set to GLX_LOSE_CONTEXT_ON_RESET_ARB and that the - driver exposes the GetGraphicsResetStatusARB function. This means - we don't actually enable robust buffer access. */ - static const int attrib_list_reset_on_purge[] = - { - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 1, - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, - GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV, - GL_TRUE, - GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, - GLX_LOSE_CONTEXT_ON_RESET_ARB, - None - }; - - /* Make sure that the display supports the GLX_ARB_create_context - extension */ - if (glx_renderer->glXCreateContextAttribs == NULL) - return NULL; - - /* We can't check the presence of this extension with the usual - COGL_WINSYS_FEATURE machinery because that only gets initialized - later when the CoglContext is created. */ - if (display->renderer->xlib_want_reset_on_video_memory_purge && - strstr (glx_renderer->glXQueryExtensionsString (xlib_renderer->xdpy, - DefaultScreen (xlib_renderer->xdpy)), - "GLX_NV_robustness_video_memory_purge")) - { - GLXContext ctx; - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - ctx = glx_renderer->glXCreateContextAttribs (xlib_renderer->xdpy, - fb_config, - NULL /* share_context */, - True, /* direct */ - attrib_list_reset_on_purge); - if (!mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy) && ctx) - return ctx; - } - - return glx_renderer->glXCreateContextAttribs (xlib_renderer->xdpy, - fb_config, - NULL /* share_context */, - True, /* direct */ - attrib_list); -} - -static gboolean -create_context (CoglDisplay *display, GError **error) -{ - CoglGLXDisplay *glx_display = display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - GLXFBConfig config; - GError *fbconfig_error = NULL; - XSetWindowAttributes attrs; - XVisualInfo *xvisinfo; - GLXDrawable dummy_drawable; - - g_return_val_if_fail (glx_display->glx_context == NULL, TRUE); - - glx_display->found_fbconfig = - cogl_display_glx_find_fbconfig (display, - &display->onscreen_template->config, - &config, - &fbconfig_error); - if (!glx_display->found_fbconfig) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to find suitable fbconfig for the GLX context: %s", - fbconfig_error->message); - g_error_free (fbconfig_error); - return FALSE; - } - - glx_display->fbconfig = config; - - COGL_NOTE (WINSYS, "Creating GLX Context (display: %p)", - xlib_renderer->xdpy); - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - if (display->renderer->driver == COGL_DRIVER_GL3) - glx_display->glx_context = create_gl3_context (display, config); - else - glx_display->glx_context = - glx_renderer->glXCreateNewContext (xlib_renderer->xdpy, - config, - GLX_RGBA_TYPE, - NULL, - True); - - if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy) || - glx_display->glx_context == NULL) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to create suitable GL context"); - return FALSE; - } - - glx_display->is_direct = - glx_renderer->glXIsDirect (xlib_renderer->xdpy, glx_display->glx_context); - glx_display->have_vblank_counter = glx_display->is_direct && glx_renderer->glXWaitVideoSync; - glx_display->can_vblank_wait = glx_renderer->glXWaitForMsc || glx_display->have_vblank_counter; - - COGL_NOTE (WINSYS, "Setting %s context", - glx_display->is_direct ? "direct" : "indirect"); - - /* XXX: GLX doesn't let us make a context current without a window - * so we create a dummy window that we can use while no CoglOnscreen - * framebuffer is in use. - */ - - xvisinfo = glx_renderer->glXGetVisualFromFBConfig (xlib_renderer->xdpy, - config); - if (xvisinfo == NULL) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to retrieve the X11 visual"); - return FALSE; - } - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - attrs.override_redirect = True; - attrs.colormap = XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - attrs.border_pixel = 0; - - glx_display->dummy_xwin = - XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - -100, -100, 1, 1, - 0, - xvisinfo->depth, - CopyFromParent, - xvisinfo->visual, - CWOverrideRedirect | CWColormap | CWBorderPixel, - &attrs); - - /* Try and create a GLXWindow to use with extensions dependent on - * GLX versions >= 1.3 that don't accept regular X Windows as GLX - * drawables. */ - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 3) - { - glx_display->dummy_glxwin = - glx_renderer->glXCreateWindow (xlib_renderer->xdpy, - config, - glx_display->dummy_xwin, - NULL); - } - - if (glx_display->dummy_glxwin) - dummy_drawable = glx_display->dummy_glxwin; - else - dummy_drawable = glx_display->dummy_xwin; - - COGL_NOTE (WINSYS, "Selecting dummy 0x%x for the GLX context", - (unsigned int) dummy_drawable); - - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - dummy_drawable, - dummy_drawable, - glx_display->glx_context); - - g_clear_pointer (&xvisinfo, XFree); - - if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy)) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to select the newly created GLX context"); - return FALSE; - } - - return TRUE; -} - -static void -_cogl_winsys_display_destroy (CoglDisplay *display) -{ - CoglGLXDisplay *glx_display = display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - - g_return_if_fail (glx_display != NULL); - - if (glx_display->glx_context) - { - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - None, None, NULL); - glx_renderer->glXDestroyContext (xlib_renderer->xdpy, - glx_display->glx_context); - glx_display->glx_context = NULL; - } - - if (glx_display->dummy_glxwin) - { - glx_renderer->glXDestroyWindow (xlib_renderer->xdpy, - glx_display->dummy_glxwin); - glx_display->dummy_glxwin = None; - } - - if (glx_display->dummy_xwin) - { - XDestroyWindow (xlib_renderer->xdpy, glx_display->dummy_xwin); - glx_display->dummy_xwin = None; - } - - g_free (display->winsys); - display->winsys = NULL; -} - -static gboolean -_cogl_winsys_display_setup (CoglDisplay *display, - GError **error) -{ - CoglGLXDisplay *glx_display; - int i; - - g_return_val_if_fail (display->winsys == NULL, FALSE); - - glx_display = g_new0 (CoglGLXDisplay, 1); - display->winsys = glx_display; - - if (!create_context (display, error)) - goto error; - - for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++) - glx_display->glx_cached_configs[i].depth = -1; - - return TRUE; - -error: - _cogl_winsys_display_destroy (display); - return FALSE; -} - -static gboolean -_cogl_winsys_context_init (CoglContext *context, GError **error) -{ - context->winsys = g_new0 (CoglContextGLX, 1); - - cogl_xlib_renderer_add_filter (context->display->renderer, - glx_event_filter_cb, - context); - return update_winsys_features (context, error); -} - -static void -_cogl_winsys_context_deinit (CoglContext *context) -{ - cogl_xlib_renderer_remove_filter (context->display->renderer, - glx_event_filter_cb, - context); - g_free (context->winsys); -} - -static gboolean -get_fbconfig_for_depth (CoglContext *context, - unsigned int depth, - gboolean stereo, - GLXFBConfig *fbconfig_ret, - gboolean *can_mipmap_ret) -{ - CoglXlibRenderer *xlib_renderer; - CoglGLXRenderer *glx_renderer; - CoglGLXDisplay *glx_display; - Display *dpy; - GLXFBConfig *fbconfigs; - int n_elements, i; - int db, stencil, alpha, mipmap, rgba, value; - int spare_cache_slot = 0; - gboolean found = FALSE; - - xlib_renderer = _cogl_xlib_renderer_get_data (context->display->renderer); - glx_renderer = context->display->renderer->winsys; - glx_display = context->display->winsys; - - /* Check if we've already got a cached config for this depth and stereo */ - for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++) - if (glx_display->glx_cached_configs[i].depth == -1) - spare_cache_slot = i; - else if (glx_display->glx_cached_configs[i].depth == depth && - glx_display->glx_cached_configs[i].stereo == stereo) - { - *fbconfig_ret = glx_display->glx_cached_configs[i].fb_config; - *can_mipmap_ret = glx_display->glx_cached_configs[i].can_mipmap; - return glx_display->glx_cached_configs[i].found; - } - - dpy = xlib_renderer->xdpy; - - fbconfigs = glx_renderer->glXGetFBConfigs (dpy, DefaultScreen (dpy), - &n_elements); - - db = G_MAXSHORT; - stencil = G_MAXSHORT; - mipmap = 0; - rgba = 0; - - for (i = 0; i < n_elements; i++) - { - XVisualInfo *vi; - int visual_depth; - - vi = glx_renderer->glXGetVisualFromFBConfig (dpy, fbconfigs[i]); - if (vi == NULL) - continue; - - visual_depth = vi->depth; - - XFree (vi); - - if (visual_depth != depth) - continue; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_ALPHA_SIZE, - &alpha); - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BUFFER_SIZE, - &value); - if (value != depth && (value - alpha) != depth) - continue; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_STEREO, - &value); - if (!!value != !!stereo) - continue; - - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 4) - { - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_SAMPLES, - &value); - if (value > 1) - continue; - } - - value = 0; - if (depth == 32) - { - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BIND_TO_TEXTURE_RGBA_EXT, - &value); - if (value) - rgba = 1; - } - - if (!value) - { - if (rgba) - continue; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BIND_TO_TEXTURE_RGB_EXT, - &value); - if (!value) - continue; - } - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_DOUBLEBUFFER, - &value); - if (value > db) - continue; - - db = value; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_STENCIL_SIZE, - &value); - if (value > stencil) - continue; - - stencil = value; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BIND_TO_MIPMAP_TEXTURE_EXT, - &value); - - if (value < mipmap) - continue; - - mipmap = value; - - *fbconfig_ret = fbconfigs[i]; - *can_mipmap_ret = mipmap; - found = TRUE; - } - - if (n_elements) - XFree (fbconfigs); - - glx_display->glx_cached_configs[spare_cache_slot].depth = depth; - glx_display->glx_cached_configs[spare_cache_slot].found = found; - glx_display->glx_cached_configs[spare_cache_slot].fb_config = *fbconfig_ret; - glx_display->glx_cached_configs[spare_cache_slot].can_mipmap = mipmap; - - return found; -} - -static gboolean -try_create_glx_pixmap (CoglContext *context, - CoglTexturePixmapX11 *tex_pixmap, - gboolean mipmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - CoglRenderer *renderer; - CoglXlibRenderer *xlib_renderer; - CoglGLXRenderer *glx_renderer; - Display *dpy; - /* We have to initialize this *opaque* variable because gcc tries to - * be too smart for its own good and warns that the variable may be - * used uninitialized otherwise. */ - GLXFBConfig fb_config = (GLXFBConfig)0; - int attribs[7]; - int i = 0; - - unsigned int depth = tex_pixmap->depth; - Visual* visual = tex_pixmap->visual; - - renderer = context->display->renderer; - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - glx_renderer = renderer->winsys; - dpy = xlib_renderer->xdpy; - - if (!get_fbconfig_for_depth (context, depth, - tex_pixmap->stereo_mode != COGL_TEXTURE_PIXMAP_MONO, - &fb_config, - &glx_tex_pixmap->can_mipmap)) - { - COGL_NOTE (TEXTURE_PIXMAP, "No suitable FBConfig found for depth %i", - depth); - return FALSE; - } - - if (!glx_tex_pixmap->can_mipmap) - mipmap = FALSE; - - attribs[i++] = GLX_TEXTURE_FORMAT_EXT; - - /* Check whether an alpha channel is used by comparing the total - * number of 1-bits in color masks against the color depth requested - * by the client. - */ - if (_cogl_util_popcountl (visual->red_mask | - visual->green_mask | - visual->blue_mask) == depth) - attribs[i++] = GLX_TEXTURE_FORMAT_RGB_EXT; - else - attribs[i++] = GLX_TEXTURE_FORMAT_RGBA_EXT; - - attribs[i++] = GLX_MIPMAP_TEXTURE_EXT; - attribs[i++] = mipmap; - - attribs[i++] = GLX_TEXTURE_TARGET_EXT; - attribs[i++] = GLX_TEXTURE_2D_EXT; - - attribs[i++] = None; - - /* We need to trap errors from glXCreatePixmap because it can - * sometimes fail during normal usage. For example on NVidia it gets - * upset if you try to create two GLXPixmaps for the same drawable. - */ - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - glx_tex_pixmap->glx_pixmap = - glx_renderer->glXCreatePixmap (dpy, - fb_config, - tex_pixmap->pixmap, - attribs); - glx_tex_pixmap->has_mipmap_space = mipmap; - - XSync (dpy, False); - - if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy)) - { - COGL_NOTE (TEXTURE_PIXMAP, "Failed to create pixmap for %p", tex_pixmap); - mtk_x11_error_trap_push (xlib_renderer->xdpy); - glx_renderer->glXDestroyPixmap (dpy, glx_tex_pixmap->glx_pixmap); - XSync (dpy, False); - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - - glx_tex_pixmap->glx_pixmap = None; - return FALSE; - } - - return TRUE; -} - -static gboolean -_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap; - CoglContext *ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - - if (!_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP)) - { - tex_pixmap->winsys = NULL; - return FALSE; - } - - glx_tex_pixmap = g_new0 (CoglTexturePixmapGLX, 1); - - glx_tex_pixmap->glx_pixmap = None; - glx_tex_pixmap->can_mipmap = FALSE; - glx_tex_pixmap->has_mipmap_space = FALSE; - - glx_tex_pixmap->left.glx_tex = NULL; - glx_tex_pixmap->right.glx_tex = NULL; - - glx_tex_pixmap->left.bind_tex_image_queued = TRUE; - glx_tex_pixmap->right.bind_tex_image_queued = TRUE; - glx_tex_pixmap->left.pixmap_bound = FALSE; - glx_tex_pixmap->right.pixmap_bound = FALSE; - - tex_pixmap->winsys = glx_tex_pixmap; - - if (!try_create_glx_pixmap (ctx, tex_pixmap, FALSE)) - { - tex_pixmap->winsys = NULL; - g_free (glx_tex_pixmap); - return FALSE; - } - - return TRUE; -} - -static void -free_glx_pixmap (CoglContext *context, - CoglTexturePixmapGLX *glx_tex_pixmap) -{ - CoglRenderer *renderer; - CoglXlibRenderer *xlib_renderer; - CoglGLXRenderer *glx_renderer; - - renderer = context->display->renderer; - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - glx_renderer = renderer->winsys; - - if (glx_tex_pixmap->left.pixmap_bound) - glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - GLX_FRONT_LEFT_EXT); - if (glx_tex_pixmap->right.pixmap_bound) - glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - GLX_FRONT_RIGHT_EXT); - - /* FIXME - we need to trap errors and synchronize here because - * of ordering issues between the XPixmap destruction and the - * GLXPixmap destruction. - * - * If the X pixmap is destroyed, the GLX pixmap is destroyed as - * well immediately, and thus, when Cogl calls glXDestroyPixmap() - * it'll cause a BadDrawable error. - * - * this is technically a bug in the X server, which should not - * destroy either pixmaps until the call to glXDestroyPixmap(); so - * at some point we should revisit this code and remove the - * trap+sync after verifying that the destruction is indeed safe. - * - * for reference, see: - * http://bugzilla.clutter-project.org/show_bug.cgi?id=2324 - */ - mtk_x11_error_trap_push (xlib_renderer->xdpy); - glx_renderer->glXDestroyPixmap (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap); - XSync (xlib_renderer->xdpy, False); - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - - glx_tex_pixmap->glx_pixmap = None; - glx_tex_pixmap->left.pixmap_bound = FALSE; - glx_tex_pixmap->right.pixmap_bound = FALSE; -} - -static void -_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap; - - if (!tex_pixmap->winsys) - return; - - glx_tex_pixmap = tex_pixmap->winsys; - - free_glx_pixmap (cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)), - glx_tex_pixmap); - - if (glx_tex_pixmap->left.glx_tex) - g_object_unref (glx_tex_pixmap->left.glx_tex); - - if (glx_tex_pixmap->right.glx_tex) - g_object_unref (glx_tex_pixmap->right.glx_tex); - - tex_pixmap->winsys = NULL; - g_free (glx_tex_pixmap); -} - -static gboolean -_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode, - gboolean needs_mipmap) -{ - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - CoglContext *ctx = cogl_texture_get_context (tex); - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - CoglPixmapTextureEyeGLX *texture_info; - int buffer; - CoglGLXRenderer *glx_renderer; - - if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - { - texture_info = &glx_tex_pixmap->right; - buffer = GLX_FRONT_RIGHT_EXT; - } - else - { - texture_info = &glx_tex_pixmap->left; - buffer = GLX_FRONT_LEFT_EXT; - } - - /* If we don't have a GLX pixmap then fallback */ - if (glx_tex_pixmap->glx_pixmap == None) - return FALSE; - - glx_renderer = ctx->display->renderer->winsys; - - /* Lazily create a texture to hold the pixmap */ - if (texture_info->glx_tex == NULL) - { - CoglPixelFormat texture_format; - GError *error = NULL; - - texture_format = (tex_pixmap->depth >= 32 ? - COGL_PIXEL_FORMAT_RGBA_8888_PRE : - COGL_PIXEL_FORMAT_RGB_888); - - texture_info->glx_tex = - cogl_texture_2d_new_with_size (ctx, - cogl_texture_get_width (tex), - cogl_texture_get_height (tex)); - - _cogl_texture_set_internal_format (tex, texture_format); - - if (cogl_texture_allocate (texture_info->glx_tex, &error)) - COGL_NOTE (TEXTURE_PIXMAP, "Created a texture 2d for %p", tex_pixmap); - else - { - COGL_NOTE (TEXTURE_PIXMAP, "Falling back for %p because a " - "texture 2d could not be created: %s", - tex_pixmap, error->message); - g_error_free (error); - free_glx_pixmap (ctx, glx_tex_pixmap); - return FALSE; - } - } - - if (needs_mipmap) - { - /* If we can't support mipmapping then temporarily fallback */ - if (!glx_tex_pixmap->can_mipmap) - return FALSE; - - /* Recreate the GLXPixmap if it wasn't previously created with a - * mipmap tree */ - if (!glx_tex_pixmap->has_mipmap_space) - { - free_glx_pixmap (ctx, glx_tex_pixmap); - - COGL_NOTE (TEXTURE_PIXMAP, "Recreating GLXPixmap with mipmap " - "support for %p", tex_pixmap); - if (!try_create_glx_pixmap (ctx, tex_pixmap, TRUE)) - - { - /* If the pixmap failed then we'll permanently fallback - * to using XImage. This shouldn't happen. */ - COGL_NOTE (TEXTURE_PIXMAP, "Falling back to XGetImage " - "updates for %p because creating the GLXPixmap " - "with mipmap support failed", tex_pixmap); - - if (texture_info->glx_tex) - g_object_unref (texture_info->glx_tex); - return FALSE; - } - - glx_tex_pixmap->left.bind_tex_image_queued = TRUE; - glx_tex_pixmap->right.bind_tex_image_queued = TRUE; - } - } - - if (texture_info->bind_tex_image_queued) - { - GLuint gl_handle, gl_target; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (ctx->display->renderer); - - cogl_texture_get_gl_texture (texture_info->glx_tex, - &gl_handle, &gl_target); - - COGL_NOTE (TEXTURE_PIXMAP, "Rebinding GLXPixmap for %p", tex_pixmap); - - _cogl_bind_gl_texture_transient (gl_target, gl_handle); - - if (texture_info->pixmap_bound) - glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - buffer); - - glx_renderer->glXBindTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - buffer, - NULL); - - /* According to the recommended usage in the spec for - * GLX_EXT_texture_pixmap we should release the texture after - * we've finished drawing with it and it is undefined what - * happens if you render to a pixmap that is bound to a texture. - * However that would require the texture backend to know when - * Cogl has finished painting and it may be more expensive to - * keep unbinding the texture. Leaving it bound appears to work - * on Mesa and NVidia drivers and it is also what Compiz does so - * it is probably ok */ - - texture_info->bind_tex_image_queued = FALSE; - texture_info->pixmap_bound = TRUE; - - _cogl_texture_2d_externally_modified (texture_info->glx_tex); - } - - return TRUE; -} - -static void -_cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - - glx_tex_pixmap->left.bind_tex_image_queued = TRUE; - glx_tex_pixmap->right.bind_tex_image_queued = TRUE; -} - -static CoglTexture * -_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode) -{ - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - - if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - return glx_tex_pixmap->right.glx_tex; - else - return glx_tex_pixmap->left.glx_tex; -} - -void -cogl_context_glx_set_current_drawable (CoglContext *context, - GLXDrawable drawable) -{ - CoglContextGLX *glx_context = context->winsys; - - glx_context->current_drawable = drawable; -} - -GLXDrawable -cogl_context_glx_get_current_drawable (CoglContext *context) -{ - CoglContextGLX *glx_context = context->winsys; - - return glx_context->current_drawable; -} - -static CoglWinsysVtable _cogl_winsys_vtable = - { - .id = COGL_WINSYS_ID_GLX, - .name = "GLX", - .constraints = (COGL_RENDERER_CONSTRAINT_USES_X11 | - COGL_RENDERER_CONSTRAINT_USES_XLIB), - - .renderer_get_proc_address = _cogl_winsys_renderer_get_proc_address, - .renderer_connect = _cogl_winsys_renderer_connect, - .renderer_disconnect = _cogl_winsys_renderer_disconnect, - .renderer_outputs_changed = _cogl_winsys_renderer_outputs_changed, - .renderer_bind_api = _cogl_winsys_renderer_bind_api, - .display_setup = _cogl_winsys_display_setup, - .display_destroy = _cogl_winsys_display_destroy, - .context_init = _cogl_winsys_context_init, - .context_deinit = _cogl_winsys_context_deinit, - - /* X11 tfp support... */ - /* XXX: instead of having a rather monolithic winsys vtable we could - * perhaps look for a way to separate these... */ - .texture_pixmap_x11_create = - _cogl_winsys_texture_pixmap_x11_create, - .texture_pixmap_x11_free = - _cogl_winsys_texture_pixmap_x11_free, - .texture_pixmap_x11_update = - _cogl_winsys_texture_pixmap_x11_update, - .texture_pixmap_x11_damage_notify = - _cogl_winsys_texture_pixmap_x11_damage_notify, - .texture_pixmap_x11_get_texture = - _cogl_winsys_texture_pixmap_x11_get_texture, - }; - -/* XXX: we use a function because no doubt someone will complain - * about using c99 member initializers because they aren't portable - * to windows. We want to avoid having to rigidly follow the real - * order of members since some members are #ifdefd and we'd have - * to mirror the #ifdefing to add padding etc. For any winsys that - * can assume the platform has a sane compiler then we can just use - * c99 initializers for insane platforms they can initialize - * the members by name in a function. - */ -COGL_EXPORT const CoglWinsysVtable * -_cogl_winsys_glx_get_vtable (void) -{ - return &_cogl_winsys_vtable; -} diff --git a/mutter/cogl/cogl/winsys/cogl-winsys-private.h b/mutter/cogl/cogl/winsys/cogl-winsys-private.h deleted file mode 100644 index d627617..0000000 --- a/mutter/cogl/cogl/winsys/cogl-winsys-private.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/cogl-renderer.h" -#include "cogl/cogl-scanout.h" - -#ifdef HAVE_X11 -#include -#include "cogl/winsys/cogl-texture-pixmap-x11-private.h" -#endif - -#ifdef HAVE_EGL -#include "cogl/cogl-egl-private.h" -#endif - -#include "cogl/cogl-poll.h" - -COGL_EXPORT uint32_t -_cogl_winsys_error_quark (void); - -#define COGL_WINSYS_ERROR (_cogl_winsys_error_quark ()) - -typedef enum /*< prefix=COGL_WINSYS_ERROR >*/ -{ - COGL_WINSYS_ERROR_INIT, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - COGL_WINSYS_ERROR_MAKE_CURRENT, -} CoglWinsysError; - -typedef struct _CoglWinsysVtable -{ - CoglWinsysID id; - CoglRendererConstraint constraints; - - const char *name; - - /* Required functions */ - - GCallback - (*renderer_get_proc_address) (CoglRenderer *renderer, - const char *name); - - gboolean - (*renderer_connect) (CoglRenderer *renderer, - GError **error); - - void - (*renderer_disconnect) (CoglRenderer *renderer); - - void - (*renderer_outputs_changed) (CoglRenderer *renderer); - - gboolean - (*display_setup) (CoglDisplay *display, - GError **error); - - void - (*display_destroy) (CoglDisplay *display); - - CoglDmaBufHandle * - (*renderer_create_dma_buf) (CoglRenderer *renderer, - CoglPixelFormat format, - uint64_t *modifiers, - int n_modifiers, - int width, - int height, - GError **error); - - gboolean - (*renderer_is_dma_buf_supported) (CoglRenderer *renderer); - - void - (*renderer_bind_api) (CoglRenderer *renderer); - - gboolean - (*context_init) (CoglContext *context, - GError **error); - - void - (*context_deinit) (CoglContext *context); - - /* Optional functions */ - -#ifdef HAVE_X11 - gboolean - (*texture_pixmap_x11_create) (CoglTexturePixmapX11 *tex_pixmap); - void - (*texture_pixmap_x11_free) (CoglTexturePixmapX11 *tex_pixmap); - - gboolean - (*texture_pixmap_x11_update) (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode, - gboolean needs_mipmap); - - void - (*texture_pixmap_x11_damage_notify) (CoglTexturePixmapX11 *tex_pixmap); - - CoglTexture * - (*texture_pixmap_x11_get_texture) (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode); -#endif - - void * - (*fence_add) (CoglContext *ctx); - - gboolean - (*fence_is_complete) (CoglContext *ctx, - void *fence); - - void - (*fence_destroy) (CoglContext *ctx, - void *fence); - - void - (*update_sync) (CoglContext *ctx); - - int - (*get_sync_fd) (CoglContext *ctx); - -} CoglWinsysVtable; - -typedef const CoglWinsysVtable *(*CoglWinsysVtableGetter) (void); - -gboolean -_cogl_winsys_has_feature (CoglWinsysFeature feature); diff --git a/mutter/cogl/cogl/winsys/cogl-winsys.c b/mutter/cogl/cogl/winsys/cogl-winsys.c deleted file mode 100644 index 687dbd0..0000000 --- a/mutter/cogl/cogl/winsys/cogl-winsys.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "config.h" - -#include "cogl/cogl-context-private.h" - -#include - -uint32_t -_cogl_winsys_error_quark (void) -{ - return g_quark_from_static_string ("cogl-winsys-error-quark"); -} - -/* FIXME: we should distinguish renderer and context features */ -gboolean -_cogl_winsys_has_feature (CoglWinsysFeature feature) -{ - _COGL_GET_CONTEXT (ctx, FALSE); - - return COGL_FLAGS_GET (ctx->winsys_features, feature); -} diff --git a/mutter/cogl/meson.build b/mutter/cogl/meson.build deleted file mode 100644 index 25120f9..0000000 --- a/mutter/cogl/meson.build +++ /dev/null @@ -1,103 +0,0 @@ -cogl_includesubdir = pkgname / 'cogl' -cogl_includedir = includedir / cogl_includesubdir -cogl_srcdir = meson.current_source_dir() - -cogl_includepath = [mtk_includepath, include_directories('.', 'cogl')] - -cogl_pkg_deps = [ - glib_dep, - gio_dep, - gobject_dep, - graphene_dep, -] - -cogl_pkg_private_deps = [ - gmodule_no_export_dep, - libmutter_mtk_dep, -] - -if have_profiler - cogl_pkg_private_deps += [ - libsysprof_capture_dep, - ] -endif - -if have_wayland - cogl_pkg_deps += [ - wayland_server_dep, - ] -endif - -if have_egl - cogl_pkg_deps += [ - egl_dep, - ] -endif - -if have_x11_client - cogl_pkg_deps += [ - x11_dep, - ] - cogl_pkg_private_deps += [ - xext_dep, - xfixes_dep, - xdamage_dep, - xcomposite_dep, - xrandr_dep, - ] -endif - -if have_gl - cogl_pkg_deps += [ - gl_dep, - ] -endif - -if have_gles2 - cogl_pkg_deps += [ - gles2_dep, - ] -endif - -cogl_deps = [ - cogl_pkg_deps, - cogl_pkg_private_deps, - m_dep, -] - -cogl_c_args = [ - '-DCOGL_LOCALEDIR="@0@"'.format(localedir), - '-DCOGL_COMPILATION', -] - -if have_gl - cogl_c_args += [ - '-DCOGL_GL_LIBNAME="@0@"'.format(gl_libname) - ] -endif - -if have_gles2 - cogl_c_args += [ - '-DCOGL_GLES2_LIBNAME="@0@"'.format(gles2_libname) - ] -endif - -cogl_debug_c_args = [] -if buildtype != 'plain' - if get_option('debug') - cogl_debug_c_args += [ - '-DCOGL_GL_DEBUG', - '-DCOGL_OBJECT_DEBUG', - '-DCOGL_ENABLE_DEBUG', - ] - else - cogl_debug_c_args += [ - '-DG_DISABLE_CAST_CHECKS', - ] - endif -endif -cogl_debug_c_args = cc.get_supported_arguments(cogl_debug_c_args) -cogl_c_args += cogl_debug_c_args - -subdir('cogl') -subdir('cogl-pango') diff --git a/mutter/config.h.meson b/mutter/config.h.meson deleted file mode 100644 index 9919bd4..0000000 --- a/mutter/config.h.meson +++ /dev/null @@ -1,140 +0,0 @@ -/* The prefix for our gettext translation domains. */ -#mesondefine GETTEXT_PACKAGE - -/* Version number of package */ -#mesondefine VERSION - -/* Name of package */ -#mesondefine PACKAGE_NAME - -/* Version number of package */ -#mesondefine PACKAGE_VERSION - -/* Search path for plugins */ -#mesondefine MUTTER_PLUGIN_DIR - -/* */ -#mesondefine MUTTER_LOCALEDIR - -/* */ -#mesondefine MUTTER_LIBEXECDIR - -/* */ -#mesondefine MUTTER_PKGDATADIR - -/* Defined if EGL support is enabled */ -#mesondefine HAVE_EGL - -/* Defined if EGLDevice support is enabled */ -#mesondefine HAVE_EGL_DEVICE - -/* Have GLX for rendering */ -#mesondefine HAVE_GLX - -#mesondefine HAVE_EGL_PLATFORM_XLIB - -/* Have GL for rendering */ -#mesondefine HAVE_GL - -/* Have GLES 2.0 for rendering */ -#mesondefine HAVE_GLES2 - -/* Defined if EGLStream support is enabled */ -#mesondefine HAVE_WAYLAND_EGLSTREAM - -/* Building with gudev for device type detection */ -#mesondefine HAVE_LIBGUDEV - -/* Building with libwacom for advanced tablet management */ -#mesondefine HAVE_LIBWACOM - -/* Building with libsystemd */ -#mesondefine HAVE_LIBSYSTEMD - -/* Define if you want to enable the native (KMS) backend based on systemd */ -#mesondefine HAVE_NATIVE_BACKEND - -/* Define if you want to enable Wayland support */ -#mesondefine HAVE_WAYLAND - -/* Define if you want to enable XWayland support */ -#mesondefine HAVE_XWAYLAND - -/* Define if you want to enable X11 backend support */ -#mesondefine HAVE_X11 - -/* Define if either XWayland or X11 backend are enabled */ -#mesondefine HAVE_X11_CLIENT - -/* Defined if screen cast and remote desktop support is enabled */ -#mesondefine HAVE_REMOTE_DESKTOP - -/* Defined if gnome-desktop is enabled */ -#mesondefine HAVE_GNOME_DESKTOP - -/* Defined if sound player is enabled */ -#mesondefine HAVE_SOUND_PLAYER - -/* Building with SM support */ -#mesondefine HAVE_SM - -/* Building with startup notification support */ -#mesondefine HAVE_STARTUP_NOTIFICATION - -/* Building with Sysprof profiling support */ -#mesondefine HAVE_PROFILER - -/* Path to Xwayland executable */ -#mesondefine XWAYLAND_PATH - -/* Xwayland applications allowed to issue keyboard grabs */ -#mesondefine XWAYLAND_GRAB_DEFAULT_ACCESS_RULES - -/* XKB base prefix */ -#mesondefine XKB_BASE - -/* Whether exists and it defines prctl() */ -#mesondefine HAVE_SYS_PRCTL - -/* Either or */ -#mesondefine HAVE_SYS_RANDOM -#mesondefine HAVE_LINUX_RANDOM - -/* Whether Xwayland has -initfd option */ -#mesondefine HAVE_XWAYLAND_INITFD - -/* Whether Xwayland has -listenfd option */ -#mesondefine HAVE_XWAYLAND_LISTENFD - -/* Whether the mkostemp function exists */ -#mesondefine HAVE_MKOSTEMP - -/* Whether the posix_fallocate function exists */ -#mesondefine HAVE_POSIX_FALLOCATE - -/* Whether the memfd_create function exists */ -#mesondefine HAVE_MEMFD_CREATE - -/* Whether the Xwayland -terminate supports a delay */ -#mesondefine HAVE_XWAYLAND_TERMINATE_DELAY - -/* Whether the Xwayland supports +/-byteswappedclients */ -#mesondefine HAVE_XWAYLAND_BYTE_SWAPPED_CLIENTS - -/* Defined if libdisplay-info is enabled */ -#mesondefine HAVE_LIBDISPLAY_INFO - -/* Whether the Xwayland has -enable-ei-portal option */ -#mesondefine HAVE_XWAYLAND_ENABLE_EI_PORTAL - -/* Supports PangoFt2 */ -#mesondefine HAVE_PANGO_FT2 - -/* Supports timerfd_create/timerfd_settime */ -#mesondefine HAVE_TIMERFD - -/* Supports malloc_trim */ -#mesondefine HAVE_MALLOC_TRIM - -/* Supports eventfd */ -#mesondefine HAVE_EVENTFD diff --git a/mutter/data/50-mutter-navigation.xml b/mutter/data/50-mutter-navigation.xml deleted file mode 100644 index 6867c58..0000000 --- a/mutter/data/50-mutter-navigation.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/mutter/data/50-mutter-system.xml b/mutter/data/50-mutter-system.xml deleted file mode 100644 index 9745234..0000000 --- a/mutter/data/50-mutter-system.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - diff --git a/mutter/data/50-mutter-wayland.xml b/mutter/data/50-mutter-wayland.xml deleted file mode 100644 index 6724d89..0000000 --- a/mutter/data/50-mutter-wayland.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/mutter/data/50-mutter-windows.xml b/mutter/data/50-mutter-windows.xml deleted file mode 100644 index 6096abe..0000000 --- a/mutter/data/50-mutter-windows.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mutter/data/61-mutter.rules b/mutter/data/61-mutter.rules deleted file mode 100644 index 9262b15..0000000 --- a/mutter/data/61-mutter.rules +++ /dev/null @@ -1,116 +0,0 @@ -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1602", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1606", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x160a", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x160b", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x160d", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x160e", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1612", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1616", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x161a", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x161b", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x161d", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x161e", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1622", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1626", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x162a", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x162b", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x162d", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x162e", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1902", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1906", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x190a", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x190b", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x190e", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1912", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1913", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1915", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1916", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1917", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x191a", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x191b", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x191d", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x191e", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1921", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1923", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1926", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1927", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x192a", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x192b", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x192d", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1932", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x193a", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x193b", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x193d", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x0a84", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1a84", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1a85", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x5a84", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x5a85", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3184", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3185", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x5902", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x5906", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x590a", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x5908", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x590b", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x590e", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x5913", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x5915", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x5917", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x5912", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x5916", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x591a", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x591b", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x591d", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x591e", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x5921", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x5923", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x5926", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x5927", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x593b", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x591c", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x87c0", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x87ca", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3e90", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3e93", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3e99", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3e9c", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3e91", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3e92", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3e96", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3e98", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3e9a", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3e9b", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3e94", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3ea9", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3ea5", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3ea6", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3ea7", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3ea8", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3ea1", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3ea4", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3ea0", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3ea3", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x3ea2", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9b21", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9ba0", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9ba2", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9ba4", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9ba5", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9ba8", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9baa", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9bab", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9bac", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9b41", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9bc0", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9bc2", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9bc4", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9bc5", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9bc6", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9bc8", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9bca", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9bcb", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9bcc", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9be6", TAG+="mutter-device-disable-kms-modifiers" -DRIVERS=="i915", SUBSYSTEM=="drm", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x9bf6", TAG+="mutter-device-disable-kms-modifiers" -ENV{ID_PATH}=="platform-vkms", TAG+="mutter-device-ignore" diff --git a/mutter/data/dbus-interfaces/meson.build b/mutter/data/dbus-interfaces/meson.build deleted file mode 100644 index 0cdb844..0000000 --- a/mutter/data/dbus-interfaces/meson.build +++ /dev/null @@ -1 +0,0 @@ -dbus_interfaces_dir = meson.current_source_dir() diff --git a/mutter/data/dbus-interfaces/org.freedesktop.RealtimeKit1.xml b/mutter/data/dbus-interfaces/org.freedesktop.RealtimeKit1.xml deleted file mode 100644 index 305e767..0000000 --- a/mutter/data/dbus-interfaces/org.freedesktop.RealtimeKit1.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mutter/data/dbus-interfaces/org.freedesktop.login1.xml b/mutter/data/dbus-interfaces/org.freedesktop.login1.xml deleted file mode 100644 index 7654751..0000000 --- a/mutter/data/dbus-interfaces/org.freedesktop.login1.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mutter/data/dbus-interfaces/org.gnome.Mutter.DebugControl.xml b/mutter/data/dbus-interfaces/org.gnome.Mutter.DebugControl.xml deleted file mode 100644 index f9b88e9..0000000 --- a/mutter/data/dbus-interfaces/org.gnome.Mutter.DebugControl.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - diff --git a/mutter/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml b/mutter/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml deleted file mode 100644 index b05337d..0000000 --- a/mutter/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml +++ /dev/null @@ -1,499 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mutter/data/dbus-interfaces/org.gnome.Mutter.IdleMonitor.xml b/mutter/data/dbus-interfaces/org.gnome.Mutter.IdleMonitor.xml deleted file mode 100644 index 374af4d..0000000 --- a/mutter/data/dbus-interfaces/org.gnome.Mutter.IdleMonitor.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mutter/data/dbus-interfaces/org.gnome.Mutter.InputCapture.xml b/mutter/data/dbus-interfaces/org.gnome.Mutter.InputCapture.xml deleted file mode 100644 index fcf25bd..0000000 --- a/mutter/data/dbus-interfaces/org.gnome.Mutter.InputCapture.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mutter/data/dbus-interfaces/org.gnome.Mutter.InputMapping.xml b/mutter/data/dbus-interfaces/org.gnome.Mutter.InputMapping.xml deleted file mode 100644 index c7a8aad..0000000 --- a/mutter/data/dbus-interfaces/org.gnome.Mutter.InputMapping.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - diff --git a/mutter/data/dbus-interfaces/org.gnome.Mutter.RemoteDesktop.xml b/mutter/data/dbus-interfaces/org.gnome.Mutter.RemoteDesktop.xml deleted file mode 100644 index c309beb..0000000 --- a/mutter/data/dbus-interfaces/org.gnome.Mutter.RemoteDesktop.xml +++ /dev/null @@ -1,368 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mutter/data/dbus-interfaces/org.gnome.Mutter.ScreenCast.xml b/mutter/data/dbus-interfaces/org.gnome.Mutter.ScreenCast.xml deleted file mode 100644 index 4d8936c..0000000 --- a/mutter/data/dbus-interfaces/org.gnome.Mutter.ScreenCast.xml +++ /dev/null @@ -1,240 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mutter/data/dbus-interfaces/org.gnome.Mutter.ServiceChannel.xml b/mutter/data/dbus-interfaces/org.gnome.Mutter.ServiceChannel.xml deleted file mode 100644 index 3717827..0000000 --- a/mutter/data/dbus-interfaces/org.gnome.Mutter.ServiceChannel.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/mutter/data/dbus-interfaces/org.gnome.SettingsDaemon.Color.xml b/mutter/data/dbus-interfaces/org.gnome.SettingsDaemon.Color.xml deleted file mode 100644 index ead0096..0000000 --- a/mutter/data/dbus-interfaces/org.gnome.SettingsDaemon.Color.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/mutter/data/dbus-interfaces/org.gnome.SettingsDaemon.Power.Screen.xml b/mutter/data/dbus-interfaces/org.gnome.SettingsDaemon.Power.Screen.xml deleted file mode 100644 index 05e4b8d..0000000 --- a/mutter/data/dbus-interfaces/org.gnome.SettingsDaemon.Power.Screen.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/mutter/data/meson.build b/mutter/data/meson.build deleted file mode 100644 index 12c4428..0000000 --- a/mutter/data/meson.build +++ /dev/null @@ -1,67 +0,0 @@ -msgfmt = find_program('msgfmt') - -# Unconditionally use this dir to avoid a circular dep with gnomecc -gnome_keybindings_keysdir = datadir / 'gnome-control-center' / 'keybindings' - -keybinding_xml_files = [ - '50-mutter-navigation.xml', - '50-mutter-system.xml', - '50-mutter-windows.xml', -] - -if have_wayland - keybinding_xml_files += [ - '50-mutter-wayland.xml', - ] -endif - -install_data(keybinding_xml_files, - install_dir: gnome_keybindings_keysdir, -) - -xwayland_grab_default_access_rules = get_option('xwayland_grab_default_access_rules') - -gschema_config = configuration_data() -gschema_config.set('GETTEXT_DOMAIN', meson.project_name()) -gschema_config.set('XWAYLAND_GRAB_DEFAULT_ACCESS_RULES', - xwayland_grab_default_access_rules) - -schemadir = datadir / 'glib-2.0' / 'schemas' -schema_xmls = [] -schema_xmls += configure_file( - input: 'org.gnome.mutter.gschema.xml.in', - output: 'org.gnome.mutter.gschema.xml', - configuration: gschema_config, - install_dir: schemadir -) - -schema_xmls += configure_file( - input: 'org.gnome.mutter.wayland.gschema.xml.in', - output: 'org.gnome.mutter.wayland.gschema.xml', - configuration: gschema_config, - install_dir: schemadir -) - -locally_compiled_schemas_dir = meson.current_build_dir() - -locally_compiled_schemas = custom_target( - output: 'gschemas.compiled', - depend_files: schema_xmls, - command: ['glib-compile-schemas', locally_compiled_schemas_dir], -) - -locally_compiled_schemas_dep = declare_dependency( - sources: locally_compiled_schemas -) - -install_data(['mutter-schemas.convert'], - install_dir: datadir / 'GConf/gsettings', -) - -if have_libgudev - install_data(['61-mutter.rules'], - install_dir: udev_dir / 'rules.d', - ) -endif - -subdir('dbus-interfaces') diff --git a/mutter/data/mutter-schemas.convert b/mutter/data/mutter-schemas.convert deleted file mode 100644 index 2551c59..0000000 --- a/mutter/data/mutter-schemas.convert +++ /dev/null @@ -1,5 +0,0 @@ -[org.gnome.mutter] -overlay-key = /apps/mutter/general/overlay_key -attach-modal-dialogs = /apps/mutter/general/attach_modal_dialogs -workspaces-only-on-primary = /apps/mutter/general/workspaces_only_on_primary -draggable-border-width = /apps/mutter/general/draggable_border_width diff --git a/mutter/data/org.gnome.mutter.gschema.xml.in b/mutter/data/org.gnome.mutter.gschema.xml.in deleted file mode 100644 index 92c97b1..0000000 --- a/mutter/data/org.gnome.mutter.gschema.xml.in +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - - - - - - - - 'Super_L' - Modifier to use for extended window management operations - - This key will initiate the “overlay”, which is a combination window - overview and application launching system. The default is intended - to be the “Windows key” on PC hardware. - - It’s expected that this binding either the default or set to - the empty string. - - - - - false - Attach modal dialogs - - When true, instead of having independent titlebars, modal dialogs - appear attached to the titlebar of the parent window and are moved - together with the parent window. - - - - - false - Enable edge tiling when dropping windows on screen edges - - If enabled, dropping windows on vertical screen edges maximizes them - vertically and resizes them horizontally to cover half of the available - area. Dropping windows on the top screen edge maximizes them completely. - - - - - false - Workspaces are managed dynamically - - Determines whether workspaces are managed dynamically or - whether there’s a static number of workspaces (determined - by the num-workspaces key in org.gnome.desktop.wm.preferences). - - - - - false - Workspaces only on primary - - Determines whether workspace switching should happen for windows - on all monitors or only for windows on the primary monitor. - - - - - false - Delay focus changes until the pointer stops moving - - If set to true, and the focus mode is either “sloppy” or “mouse” - then the focus will not be changed immediately when entering a - window, but only after the pointer stops moving. - - - - - 10 - - Draggable border width - - The amount of total draggable borders. If the theme’s visible - borders are not enough, invisible borders will be added to meet - this value. - - - - - true - Auto maximize nearly monitor sized windows - - If enabled, new windows that are initially the size of the monitor - automatically get maximized. - - - - - false - Place new windows in the center - - When true, the new windows will always be put in the center of the - active screen of the monitor. - - - - - [] - Enable experimental features - - To enable experimental features, add the feature keyword to the list. - Whether the feature requires restarting the compositor depends on the - given feature. Any experimental feature is not required to still be - available, or configurable. Don’t expect adding anything in this - setting to be future proof. - - Currently possible keywords: - - • “scale-monitor-framebuffer” — makes mutter default to layout logical - monitors in a logical pixel coordinate - space, while scaling monitor - framebuffers instead of window content, - to manage HiDPI monitors. Does not - require a restart. - - • “kms-modifiers” — makes mutter always allocate scanout - buffers with explicit modifiers, if - supported by the driver. Requires a - restart. - - • “autoclose-xwayland” — automatically terminates Xwayland if all - relevant X11 clients are gone. - Requires a restart. - - • “variable-refresh-rate” — makes mutter dynamically adjust the - refresh rate of the monitor when - applicable if supported by the monitor, - GPU and DRM driver. Configurable in - Settings. Requires a restart. - - - - - - 'Control_L' - Modifier to use to locate the pointer - - This key will initiate the “locate pointer” action. - - - - - 5000 - Timeout for check-alive ping - - Number of milliseconds a client has to respond to a ping request in - order to not be detected as frozen. Using 0 will disable the alive check - completely. - - - - - - - - - - Left']]]> - View split on left - - - - Right']]]> - View split on right - - - - p','XF86Display']]]> - Switch monitor configurations - - - - - Rotates the built-in monitor configuration - - - - Escape']]]> - Cancel any active input capture session - - - - diff --git a/mutter/data/org.gnome.mutter.wayland.gschema.xml.in b/mutter/data/org.gnome.mutter.wayland.gschema.xml.in deleted file mode 100644 index 27a688e..0000000 --- a/mutter/data/org.gnome.mutter.wayland.gschema.xml.in +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - - - - - F1']]]> - Switch to VT 1 - - - F2']]]> - Switch to VT 2 - - - F3']]]> - Switch to VT 3 - - - F4']]]> - Switch to VT 4 - - - F5']]]> - Switch to VT 5 - - - F6']]]> - Switch to VT 6 - - - F7']]]> - Switch to VT 7 - - - F8']]]> - Switch to VT 8 - - - F9']]]> - Switch to VT 9 - - - F10']]]> - Switch to VT 10 - - - F11']]]> - Switch to VT 11 - - - F12']]]> - Switch to VT 12 - - - Escape']]]> - Re-enable shortcuts - - - - - - - - false - Allow X11 grabs to lock keyboard focus with Xwayland - - Allow all keyboard events to be routed to X11 “override redirect” - windows with a grab when running in Xwayland. - - This option is to support X11 clients which map an “override redirect” - window (which do not receive keyboard focus) and issue a keyboard - grab to force all keyboard events to that window. - - This option is seldom used and has no effect on regular X11 windows - which can receive keyboard focus under normal circumstances. - - For a X11 grab to be taken into account under Wayland, the client must - also either send a specific X11 ClientMessage to the root window or be - among the applications allowed in key “xwayland-grab-access-rules”. - - - - - [] - Xwayland applications allowed to issue keyboard grabs - - List the resource names or resource class of X11 windows either - allowed or not allowed to issue X11 keyboard grabs under Xwayland. - - The resource name or resource class of a given X11 window can be - obtained using the command “xprop WM_CLASS”. - - Wildcards “*” and jokers “?” in the values are supported. - - Values starting with “!” are denied, which has precedence over - the list of values allowed, to revoke applications from the default - system list. - - The default system list includes the following applications: - - “@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” - - Users can break an existing grab by using the specific keyboard - shortcut defined by the keybinding key “restore-shortcuts”. - - - - - [] - Disable selected X extensions in Xwayland - - This option disables the selected X extensions in Xwayland if - Xwayland was built with support for those X extensions. - - This option has no effect if Xwayland was built without support - for the selected extensions. - - Xwayland needs to be restarted for this setting to take effect. - - - - - false - Allow X11 clients with a different endianness to connect to Xwayland - - Allow connections from clients with an endianness different to that - of Xwayland. - - The X server byte-swapping code is a huge attack surface, much of - that code in Xwayland is prone to security issues. - - The use-case of byte-swapped clients is very niche, and disabled by - default in Xwayland. - - Enable this option to instruct Xwayland to accept connections from - X11 clients with a different endianness. - - This option has no effect if Xwayland does not support the command - line option +byteswappedclients/-byteswappedclients to control that - setting. - - Xwayland needs to be restarted for this setting to take effect. - - - - - - - diff --git a/mutter/doc/building-and-running.md b/mutter/doc/building-and-running.md deleted file mode 100644 index 1d79a5d..0000000 --- a/mutter/doc/building-and-running.md +++ /dev/null @@ -1,187 +0,0 @@ -# Building and Running - -## Building mutter - -Mutter is a meson project and can be build the usual way: -```sh -meson setup builddir && meson compile -C builddir -``` - -There are quite a few dependencies which have to be satisfied. The easiest and risk-free way to obtain the dependencies is through the distribution repository in a [Toolbx](https://containertoolbx.org/) pet-container. -```sh -$ # on the host system: -$ toolbox create --distro fedora mutter -$ toolbox enter mutter -⬢ # inside the mutter Toolbx container: -⬢ sudo dnf builddep -y gnome-shell mutter -``` - -Most dependencies from the `main` branch will be satisfied like this but sometimes the `main` branch requires new or more up-to-date dependencies which must be installed manually. Those dependencies are usually also `meson` projects and can be installed into the `/usr` prefix of the `mutter` Toolbx container: -```sh -⬢ # for example, if we the need the latest gnome-desktop: -⬢ git clone https://gitlab.gnome.org/GNOME/gnome-desktop.git -⬢ cd gnome-desktop -⬢ meson setup builddir --prefix=/usr -⬢ meson compile -C builddir -⬢ sudo meson install -C -``` - -Note: the above should not be run outside the Toolbx container, it may make your system unusable. - -## Configuring the build - -When build in a Toolbx container, we can safely install Mutter into the `/usr` prefix as well: -```sh -⬢ meson configure builddir --prefix=/usr -⬢ meson compile -C builddir && sudo meson install -C -``` - -Like any meson project, the available build options are in the `meson_options.txt` file. The defaults are usually fine but when developing for the `native backend`, it's a good idea to turn on additional tests: -```sh -⬢ meson configure builddir -Dtty_tests=true -``` - -## KVM tests - -The KVM tests are usually not necessary to run on your own machine and are meant mainly for CI where it's not possible to run the `tty` tests due to VKMS not being available. - -To run them, a specific version of [virtme-ng](https://github.com/arighi/virtme-ng) is required -```sh -⬢ sudo dnf install python3-pip qemu -⬢ sudo pip3 install --prefix=/usr --verbose -r requirements.txt . -``` - -## Running the tests - -Most of the test suit can be run via the usual `meson test` command: -```sh -⬢ meson test -C builddir --print-errorlogs -``` - -To run the `tty` tests, the `VKMS` kernel module must be loaded, and the session from which the test are invoked must be a session master. This usually means switching to another tty using `ctrl+alt+f3`, logging in, possibly entering the Toolbx container, and then invoking meson test with the `mutter/tty` suite to only run the relevant tests: -```sh -$ sudo modprobe vkms -$ toolbox enter mutter -⬢ meson test -C builddir --print-errorlogs --suite mutter/tty -``` - -## Updating Ref-Tests - -Ref-tests compare image captures of Mutter against a reference image. Sometimes a change of the rendering result is expected with some code changes. In those cases it's required to update the reference images. This can be done by running the tests with: -```sh -MESA_LOADER_DRIVER_OVERRIDE=swrast MUTTER_REF_TEST_UPDATE='/path/to/test/case' -``` - -This makes sure a software renderer is being used and the reference image of the test case `/path/to/test/case` is updated. More information is available in `src/tests/meta-ref-test.c`. - -## Running a nested instance - -While the test suite helps to catch mistakes, there are a lot of cases where we actually need to run and interact with Mutter. The least invasive method is running a "nested" instance. -```sh -⬢ dbus-run-session mutter --wayland --nested -``` - -This starts a nested Mutter instance in a new dbus session with the default plugin. Often we want to run Mutter with a real plugin, such as `gnome-shell`: -```sh -⬢ dbus-run-session gnome-shell --wayland --nested -``` - -But sometimes running Mutter with the default plugin is preferred but there is nothing to interact with by default. We can either start something, like a terminal directly when invoking Mutter -```sh -⬢ dbus-run-session mutter --wayland --nested vte-2.91 -``` - -or open apps on the nested compositor by setting `WAYLAND_DISPLAY` to the display of the nested session. This is usually just `wayland-1` but Mutter should print this to the terminal: -``` -libmutter-Message: 21:01:37.323: Using Wayland display name 'wayland-1' -``` - -```sh -$ WAYLAND_DISPLAY=wayland-1 vte-2.91 -``` - -Getting some apps to open on the desired nested compositor can sometimes be an issue. A lot of GNOME apps for example use d-bus to avoid starting multiple instances of the same app. - -Changing the size of the nested session can be done with the `MUTTER_DEBUG_DUMMY_MODE_SPECS` environment variable. -```sh -⬢ MUTTER_DEBUG_DUMMY_MODE_SPECS=1920x1080 dbus-run-session mutter --wayland --nested -``` - -## D-Bus session - -In the examples above we use `dbus-run-session` to create a nested D-Bus user session to avoid messing up the system's running D-Bus user session. - -It's sometimes required to run two applications in the same nested D-Bus session. In that case, the `dbus-session.sh` script helps: -```sh -#!/bin/bash - -set -euo pipefail - -LIGHT_GRAY="\[\033[1m\]" -NO_COLOR="\[\033[0m\]" -export PS1="[$LIGHT_GRAY D-Bus \$(echo \$DBUS_SESSION_BUS_ADDRESS | sed -e 's/.*guid=\([a-z0-9]\{4\}\).*$/\1/') $NO_COLOR][\u@\h \W]$ " - -ENV_FILE="$XDG_RUNTIME_DIR/nested-dbus-session.txt" - -ACTION=${1:-} -if [[ "$ACTION" = "attach" ]]; then - export DBUS_SESSION_BUS_ADDRESS=$(cat $ENV_FILE) - bash -i -elif [[ "$ACTION" = "new" ]]; then - cat > /tmp/dbussessionbashrc << __EOF__ -. ~/.bashrc -echo \$DBUS_SESSION_BUS_ADDRESS > $ENV_FILE -__EOF__ - dbus-run-session -- bash --init-file /tmp/dbussessionbashrc -i -else - echo "Usage: $0 [attach|new]" - echo " new .. start a new dbus session" - echo " attach .. to attach to a previously started dbus session" - exit 1 -fi -``` - -We can create a nested D-Bus user session by running -```sh -⬢ dbus-session.sh new -``` - -This will create a D-Bus session, and attach to it. To attach to the same session from another terminal, run -```sh -⬢ dbus-session.sh attach -``` - -## Remote desktop - -There are limitations to the nested instance, such as keyboard shortcuts usually not getting to the nested compositor. The remote-desktop feature can help working around this. - -First create a [nested D-Bus session](#d-bus-session). In this, run gnome-shell in headless mode with a virtual monitor. E.g. -```sh -⬢ dbus-session.sh new -⬢ gnome-shell --headless --virtual-monitor 1280x720 -``` - -```sh -⬢ dbus-session.sh attach -⬢ ./build/src/gnome-remote-desktop-daemon -``` - -## Native - -Sometimes it's necessary to run the "native backend", on real display hardware. The easiest way is to switch to a tty and run (in your Toolbx container if this is where it was installed): -```sh -⬢ dbus-run-session mutter --wayland -``` - -One can also run `gnome-shell` this way, and use the `dbus-session.sh` script. - -## Exit - -When running gnome-shell on the native backend, it's possible to exit gnome-shell by opening the "Run a Command" prompt and executing `debugexit`. - -## Full session - -Unfortunately sometimes none of that is enough and we need to run an entire session with our own Mutter. Some developers found success with some of the following techniques: -- Using an immutable operating system such as Fedora Silverblue and installing to `/usr`. It is possible to [temporarily make the system mutable](https://blog.sebastianwick.net/posts/silverblue-development-utils/) and then rollback when something goes wrong. -- Installing to `/usr/local` -- Adding a GNOME session in GDM that uses the built project through [environment variables](https://gitlab.gnome.org/GNOME/jhbuild/-/blob/master/examples/jhbuild-session?ref_type=heads). diff --git a/mutter/doc/clutter-frame-scheduling.md b/mutter/doc/clutter-frame-scheduling.md deleted file mode 100644 index f6ac3cb..0000000 --- a/mutter/doc/clutter-frame-scheduling.md +++ /dev/null @@ -1,14 +0,0 @@ -# Clutter Frame scheduling - -`ClutterFrameClock` state diagram. - -```mermaid -stateDiagram - Init --> Scheduled/ScheduledNow : schedule update() -> now - Idle --> Scheduled/ScheduledNow : schedule update() -> given presentation time - Scheduled/ScheduledNow --> Dispatching : target time hit - Dispatching --> PendingPresented : queued page flip - Dispatching --> Idle : no queued page flip - PendingPresented --> Scheduled/ScheduledNow : page flipped, if recent schedule update - PendingPresented --> Idle : page flipped -``` diff --git a/mutter/doc/clutter-rendering-model.md b/mutter/doc/clutter-rendering-model.md deleted file mode 100644 index 7369d2f..0000000 --- a/mutter/doc/clutter-rendering-model.md +++ /dev/null @@ -1,45 +0,0 @@ -# Clutter Rendering Model - -Clutter renders the stage and actors in a 3D space. Most of the time, all the scene is composed of only 2D actors. Remember that common operations, like rotating on the Z axis, and scaling and translating on the X or Y axis, do not make actors 3D, which allows Clutter to optimize rendering for 2D. - -## Camera - -ClutterStage builds the view matrix (i.e. the matrix that transforms world coordinates into camera coordinates) assuming that the camera is placed at (0, 0, 0) with a normal (0, 0, -1). That means the camera is pointing *down*: - -![camera](data/clutter_camera.png) - -The camera is implicit, and as of now, hardcoded. - -## Perspective - -When setting up the projection, ClutterStage uses a traditional perspective projection, with the addition of a "2D plane". The 2D plane (`z-2d`) is a plane in the Z axis that all the stage will be rendered into. The perspective projection is build with the following parameters: - - * **field of view Y**: 60º (hardcoded) - * **aspect**: width / height (depends on monitor configuration) - * **z-near**: 1.0 (hardcoded) - * **z-2d**: `z-near + z-near * 49,36` ( = 50,36) - * **z-far**: `z-2d + z-2d * tan(30°) * 20` ( = 631,97) - -![view cone](data/clutter_view_cone.png) - -## Culling - -Figuring out what **not** to draw is an important optimization of the rendering process. Clutter relies on clip frusta to detect which actors it can skip drawing. - -### Depth Culling - -The z-near and z-far values above are used to build the clip frusta, which culls out actors based on their position. If they're below than z-far, or above z-near, they are not rendered: - -![view cone with z-culling](data/clutter_view_cone_with_z_culling.png) - -### Clip Regions - -Clutter supports defining which regions of the 2D screen changed. Suppose you hover a button; only the rectangle that that button cover is redrawn, instead of the entire screen. For example: - -![clip region](data/clutter_clip_region.png) -*GNOME Shell with 3 clip regions (green)* - - This is translated to the 3D scene by using multiple clip frusta. Each frustum is a slice of the view cone, and only those actors and geometry and intersects it is rendered. If an actor doesn't touch any of the frusta, it is skipped when drawing. - -![clip frusta](data/clutter_clip_frusta.png) -*View cone with 3 clip frusta (green)* diff --git a/mutter/doc/code-overview.md b/mutter/doc/code-overview.md deleted file mode 100644 index 53ffb52..0000000 --- a/mutter/doc/code-overview.md +++ /dev/null @@ -1,27 +0,0 @@ -# Code Overview - -Mutter consists of four relatively distinguished and isolated parts. - -## Cogl - -Hardware acceleration pipeline abstraction layer. Handles things like allocating framebuffer, allocating, importing and drawing textures, internally using OpenGL. Originally a fork of [the Cogl project](https://gitlab.gnome.org/GNOME/cogl). - -## Clutter - -Compositing toolkit, containing an actor and render node based scene graph, and has features such as input event routing, transformation and animation. Handles compositing, both Wayland surfaces, X11 windows, and is the basis of the UI toolkit implemented by [GNOME Shell](https://gitlab.gnome.org/GNOME/gnome-shell). Originally a fork of [the Clutter project](https://gitlab.gnome.org/GNOME/clutter). - -* [Frame Scheduling](clutter-frame-scheduling.md) -* [Rendering Model](clutter-rendering-model.md) - -## Mtk - -The Meta Toolkit containing utilities shared by other parts of mutter. - -## Mutter - -The display server and window manager library. Contains a X11 window manager and compositing manager implementation, as well as a Wayland display server implementation. - -* [Compositor stage and hardware relationships](mutter-relationships.md) -* [KMS abstraction](mutter-kms-abstractions.md) -* [Window constraints](mutter-constraints.txt) -* [How to get focus right](mutter-focus.txt) diff --git a/mutter/doc/coding-style.md b/mutter/doc/coding-style.md deleted file mode 100644 index 7a2e67e..0000000 --- a/mutter/doc/coding-style.md +++ /dev/null @@ -1,394 +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`. - -## Naming conventions - - * For object instance pointers, use a descriptive name instead of `self`, e.g. - -```c -G_DEFINE_TYPE (MetaPlaceholder, meta_placeholder, G_TYPE_OBJECT) - -... - -void -meta_placeholder_hold_place (MetaPlaceholder *placeholder) -{ - ... -} -``` - - * When object instance pointers are pointers to non-generic implementations of - a generalized type, the convention is to suffix the variable name with the - sub-type name. E.g. - -```c -G_DEFINE_TYPE (MetaPlaceholderWayland, meta_placeholder_wayland, - META_TYPE_PLACEHOLDER) - -... - -void -meta_placeholder_wayland_get_waylandy (MetaPlaceholderWayland *placeholder_wayland) -{ - ... -} -``` - -## 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. Include header files - 3. Enums - 4. Structures - 5. Function prototypes - 6. `G_DEFINE_TYPE()` - 7. Static variables - 8. Auxiliary functions - 9. Callbacks - 10. Interface implementations - 11. Parent vfunc overrides - 12. class_init and init - 13. Public API - -### Include header files - -Source files should use the header include order of the following example: - -* `meta-example.c`: -```c -#include "config.h" - -#include "meta-example-private.h" - -#include -#include - -#ifdef HAVE_WAYLAND -#include -#endif - -#include "clutter/clutter.h" -#include "backends/meta-backend-private.h" -#include "mtk/mtk.h" - -#ifdef HAVE_WAYLAND -#include "wayland/meta-wayland-surface-private.h" -#endif - -#include "meta-dbus-file-generated-by-gdbus-codegen.h" -``` - -Include paths for non-system includes should be relative to the corresponding -modules source root; i.e. `"backends/meta-backend-private.h"` for -`src/backends/` and `"clutter/clutter.h"` for `clutter/clutter/clutter.h`. - -### 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) -{ - /* ... */ -} -``` - -## Trace Span Naming - -Trace spans should be named in C++ style, i.e. -`Namespace::Class::method(args)`. For example: - -```c -static void -meta_wayland_surface_commit (MetaWaylandSurface *surface) -{ - /* ... */ - - COGL_TRACE_BEGIN_SCOPED (MetaWaylandSurfaceCommit, - "Meta::WaylandSurface::commit()"); - - /* ... */ -} -``` - -This is to facilitate automatic name shrinking in profilers that will cut out -the least important parts of the name (args, then namespaces in order, then -class) to fit the name on screen when zoomed-out. - -If you need to annotate multiple spans within a function, you can append their -name to the function name, delimited by a `#` sign. For example: - -```c -void -meta_thing_do_stuff (MetaThing *thing) -{ - COGL_TRACE_BEGIN_SCOPED (OneThing, "Meta::Thing::do_stuff#one_thing()"); - /* Code that does one thing that takes time */ - COGL_TRACE_END (OneThing); - - COGL_TRACE_BEGIN_SCOPED (OtherThing, "Meta::Thing::do_stuff#other_thing()"); - /* Code that does other thing that takes time */ - COGL_TRACE_END (OtherThing); -} -``` - -Keeping in the entire method name helps in profiler views that don't show -parent-child relationships, i.e. a global span statistics view. - -[gnome-coding-style]: https://developer.gnome.org/documentation/guidelines/programming/coding-style.html diff --git a/mutter/doc/data/clutter_camera.png b/mutter/doc/data/clutter_camera.png deleted file mode 100644 index f73453c..0000000 Binary files a/mutter/doc/data/clutter_camera.png and /dev/null differ diff --git a/mutter/doc/data/clutter_clip_frusta.png b/mutter/doc/data/clutter_clip_frusta.png deleted file mode 100644 index 002fbd3..0000000 Binary files a/mutter/doc/data/clutter_clip_frusta.png and /dev/null differ diff --git a/mutter/doc/data/clutter_clip_region.png b/mutter/doc/data/clutter_clip_region.png deleted file mode 100644 index 58a58b2..0000000 Binary files a/mutter/doc/data/clutter_clip_region.png and /dev/null differ diff --git a/mutter/doc/data/clutter_view_cone.png b/mutter/doc/data/clutter_view_cone.png deleted file mode 100644 index 83d484b..0000000 Binary files a/mutter/doc/data/clutter_view_cone.png and /dev/null differ diff --git a/mutter/doc/data/clutter_view_cone_with_z_culling.png b/mutter/doc/data/clutter_view_cone_with_z_culling.png deleted file mode 100644 index 89c7baf..0000000 Binary files a/mutter/doc/data/clutter_view_cone_with_z_culling.png and /dev/null differ diff --git a/mutter/doc/debugging.md b/mutter/doc/debugging.md deleted file mode 100644 index fb67523..0000000 --- a/mutter/doc/debugging.md +++ /dev/null @@ -1,109 +0,0 @@ -# Debugging - -## Native mutter - -When running Mutter on the native backend, it takes over the input and output of the system. This poses a problem when we have to debug it: when a debugger stops Mutter, the input and output will not be released and the debugger cannot be controlled. - -A second system is required in that case to continue controlling the debugger. Usually we login to a tty on the target system, create a "screen" session, and then detach from it. On the other system, we log in to the target system with ssh, resume the screen session (`screen -rd`), and then start Mutter the usual way. This even works in toolbox. - -## gdb - -gdb usually works like with any other application. There are situations, especially when debugging the native backend, where breaking the execution can screw up the timing of the thing that's being debugged. The gdb scripting feature and conditional breakpoints can be a great help. - -## glib - -When our code creates a warning or a critical message, we can make glib send a signal when this code is hit, to make gdb stop there. This can be done with setting `G_DEBUG` to either `fatal-warnings`, `fatal-criticals`, or both `fatal-warnings,fatal-criticals`. - -## Mutter debug topics - -It's possible to make Mutter much more verbose by turning on some debugging topics with the `MUTTER_DEBUG` environment variable. - -The different topics are defined in `src/core/util.c` as `meta_debug_keys`. It's possible to enable multiple topics: -```sh -MUTTER_DEBUG="focus,stack" dbus-run-session mutter --wayland --nested -``` - -## Looking Glass - -Gnome Shell has a build-in debugger called [Looking Glass](https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/docs/looking-glass.md). It's possible to enable Mutter debug topics at runtime, show damage, run arbitrary JS code in the shell, and much more. It can be opened with the "Run a Command" prompt (Alt+F2) by executing `lg`. - -## Tests - -When a test fails when running `meson test`, it makes sense to re-run this specific test with `--print-errorlogs`. Meson's `--wrapper` argument is not useful here because the test cases run in their own special environment (`meta-dbus-runner.py`). Use the `META_DBUS_RUNNER_WRAPPER` environment variable instead to specify a custom wrapper binary. Meson takes over input and output which means it might be required to run the test outside of meson. A failing test prints out the command line that was invoked: -```sh - 11/243 mutter:cogl+cogl/conform / cogl-test-backface-culling-gl3 OK 1.49s - 12/243 mutter:cogl+cogl/conform / cogl-test-backface-culling-gles2 OK 1.46s -^CWARNING: CTRL-C detected, interrupting mutter:cogl+cogl/conform / cogl-test-just-vertex-shader-gl3 - 13/243 mutter:cogl+cogl/conform / cogl-test-just-vertex-shader-gl3 INTERRUPT 0.75s killed by signal 15 SIGTERM ->>> COGL_DRIVER=gl3 G_TEST_BUILDDIR=/var/home/swick/Projects/mutter/build/src/tests/cogl/conform MALLOC_PERTURB_=83 G_TEST_SRCDIR=/var/home/swick/Projects/mutter/src/tests/cogl/conform G_ENABLE_DIAGNOSTIC=0 LD_LIBRARY_PATH=/var/home/swick/Projects/mutter/build/cogl/cogl:/var/home/swick/Projects/mutter/build/src/tests:/var/home/swick/Projects/mutter/build/mtk/mtk:/var/home/swick/Projects/mutter/build/clutter/clutter:/var/home/swick/Projects/mutter/build/cogl/cogl-pango:/var/home/swick/Projects/mutter/build/src /var/home/swick/Projects/mutter/src/tests/meta-dbus-runner.py -- /var/home/swick/Projects/mutter/build/src/tests/cogl/conform/cogl-test-just-vertex-shader - -``` - -Adding gdb: -```sh -[...] /var/home/swick/Projects/mutter/src/tests/meta-dbus-runner.py -- gdb --args /var/home/swick/Projects/mutter/build/src/tests/cogl/conform/cogl-test-just-vertex-shader -``` - -Some tests spawn a test client to exercise some functionality of the compositor. If the test client has a bug we have to help gdb out a bit. Usually we just break on the function spawning a test client (for example `subsurface_corner_cases`) and then set `follow-fork-mode child`. This can be quite annoying to do every time we re-run the test, so making use of gdb's scripting abilities can help out a lot: -``` -set breakpoint pending on -break buffer_ycbcr_basic -commands 1 - set follow-fork-mode child - break wayland_buffer_shm_allocate - continue -end -run -``` - -## Graphics Debugging - -Debugging GL based applications can be hard without insights into the GL state that's actually in effect. Cogl has its own set of debug options in `cogl/cogl/cogl-debug.c`, including one to show the shader sources (`COGL_DEBUG=show-source`). - -For more detailed state dumps, it's possible to use graphics debuggers such as apitrace and renderdoc. - -Renderdoc is usually the better tool to debug something with, but it's also harder to capture a trace. In those cases apitrace can help by capturing trace by wrapping the Mutter invocation with `apitrace trace --api=egl` and then capturing with renderdoc the replay of the apitrace (`eglretrace mutter.trace`). - -## Reproducing CI test failures locally - -1. Create a podman that can run gdb locally using the same image used in CI. The example below uses the tag `x86_64-2022-01-20` but this will depend on the image used by the failed CI job. The Fedora version may also differ. - - ```sh - podman run -t -i --cap-add=SYS_PTRACE registry.gitlab.gnome.org/gnome/mutter/fedora/35:x86_64-2022-01-20 bash -l - ``` - -2. Clone, build and install Mutter inside the container - - ```sh - git clone https://gitlab.gnome.org/[your-user]/mutter.git -b [merge-request-branch] - cd mutter - meson build - ninja -C build install - ``` - -3. Install debug utilities - - ```sh - dnf install -y gdb - ``` - -4. Replicate a environment and run the test inside gdb. What you need here depends on the test that needs investigation. In the simplest case, the following is enough: - - ```sh - export XDG_RUNTIME_DIR=$PWD/runtime-dir - mkdir -p $XDG_RUNTIME_DIR - ./src/tests/meta-dbus-runner.py xvfb-run meson test -C build --setup plain --gdb failing-test-case - ``` - - The need for `xvfb-run` depends on whether the test case uses the nested backend or the headless backend. - - If it involves screen casting, it becomes a bit more complicated: - - ```sh - export XDG_RUNTIME_DIR=$PWD/runtime-dir - mkdir -p $XDG_RUNTIME_DIR - ./src/tests/meta-dbus-runner.py bash -l - pipewire& - wireplumber& - meson test -C build --setup plain --gdb failing-test-case - ``` diff --git a/mutter/doc/git-conventions.md b/mutter/doc/git-conventions.md deleted file mode 100644 index 136d9b0..0000000 --- a/mutter/doc/git-conventions.md +++ /dev/null @@ -1,49 +0,0 @@ -# Git conventions - -## Commit Messages - -Commit messages should follow the guidelines in the [GNOME -handbook](https://handbook.gnome.org/development/commit-messages.html). 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. - -If a commit fixes an issue and that issue should be closed, add URL to it in -the bottom of the commit message and prefix with `Closes:`. - -Do not add any `Part-of:` line, as that will be handled automatically when -merging. - -### The Fixes tag - -If a commit fixes a regression caused by a particular commit, it can be marked -with the `Fixes:` tag. To produce such a tag, use - -``` -git show -s --pretty='format:Fixes: %h ("%s")' -``` - -or create an alias - -``` -git config --global alias.fixes "show -s --pretty='format:Fixes: %h (\"%s\")'" -``` - -and then use - -``` -git fixes -``` - -### Example - -``` -compositor: Also consider dark matter when calculating paint volume - -Ignoring dark matter when calculating the paint volume missed the case where -compositing happens in complete vacuum. - -Fixes: 123abc123ab ("compositor: Calculate paint volume ourselves") -Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1234 -``` diff --git a/mutter/doc/man/meson.build b/mutter/doc/man/meson.build deleted file mode 100644 index dd54326..0000000 --- a/mutter/doc/man/meson.build +++ /dev/null @@ -1 +0,0 @@ -install_man('mutter.1') diff --git a/mutter/doc/man/mutter.1 b/mutter/doc/man/mutter.1 deleted file mode 100644 index 6d9122c..0000000 --- a/mutter/doc/man/mutter.1 +++ /dev/null @@ -1,60 +0,0 @@ -.\" Hey, EMACS: -*- nroff -*- -.\" First parameter, NAME, should be all caps -.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection -.\" other parameters are allowed: see man(7), man(1) -.TH MUTTER 1 "11 February 2006" -.\" Please adjust this date whenever revising the manpage. -.\" -.\" Some roff macros, for reference: -.\" .nh disable hyphenation -.\" .hy enable hyphenation -.\" .ad l left justify -.\" .ad b justify to both left and right margins -.\" .nf disable filling -.\" .fi enable filling -.\" .br insert line break -.\" .sp insert n+1 empty lines -.\" for manpage-specific macros, see man(7) -.SH NAME -MUTTER \- Clutter based compositing GTK2 Window Manager -.SH SYNOPSIS -.B mutter -[\-\-display=\fIDISPLAY\fP] [\-\-replace] [\-\-sm\-client\-id=\fIID\fP] [\-\-sm\-disable] [\-\-sm\-save\-file=\fIFILENAME\fP] [\-\-version] [\-\-help] [[\-\-] command [argument...]] -.SH DESCRIPTION -This manual page documents briefly -.B mutter\fP. -.PP -.\" TeX users may be more comfortable with the \fB\fP and -.\" \fI\fP escape sequences to invode bold face and italics, -.\" respectively. -\fBmutter\fP is a minimal X window manager aimed at nontechnical users and is designed to integrate well with the GNOME desktop. \fBmutter\fP lacks some features that may be expected by traditional UNIX or other technical users; these users may want to investigate other available window managers for use with GNOME or standalone. -.SH OPTIONS -.TP -.B \-\-display=DISPLAY -Connect to X display \fIDISPLAY\fP. -.TP -.B \-\-replace -a window manager which is running is replaced by \fBmutter\fP. Users are encouraged to change the GNOME window manager by running the new WM with the --replace or -replace option, and subsequently saving the session. -.TP -.B \-\-sm\-client\-id=ID -Specify a session management \fIID\fP. -.TP -.B \-\-sm\-disable -Disable the session management. -.TP -.B \-\-sm\-save\-file=FILENAME -Load a session from \fIFILENAME\fP. -.TP -.B \-\-version -Print the version number. -.TP -.B \-?, \-\-help -Show summary of options. -.SH CONFIGURATION -\fBmutter\fP configuration can be found under \fIPreferences\fP->\fIWindows\fP and \fIPreferences\fP->\fIKeyboard Shortcuts\fP on the menu-panel. Advanced configuration can be achieved directly through gsettings. -.SH SEE ALSO -.BR mutter-message (1) -.SH AUTHOR -The original manual page was written by Thom May . It was updated by Akira TAGOH -for the Debian GNU/Linux system (with permission to use by others), and then updated by Luke Morton and Philip O'Brien -for inclusion in mutter. diff --git a/mutter/doc/monitor-configuration.md b/mutter/doc/monitor-configuration.md deleted file mode 100644 index a061ee5..0000000 --- a/mutter/doc/monitor-configuration.md +++ /dev/null @@ -1,100 +0,0 @@ -# Monitor configuration - -## File locations - -Monitor configurations are stored as XML files called `monitors.xml` on the file -system. There are two types of locations for the XML file: the system level and -the user level. - -The directories for system level configuration is defined in accordance to the -$XDG_CONFIG_DIRS environment variable defined in the XDG Base Directory -Specification. The default is `/etc/xdg/monitors.xml`. - -The directory for the user level configuration is defined in accordance to the -$XDG_CONFIG_HOME environment variable defined in the XDG Base Directory -Specification. The default is `~/.config/monitors.xml` - -## File contents - -A configuration file consists of an XML document with the root element -``. In this document multiple configurations are stored as -individual `` elements containing all the details of the monitor -setup. The `version` attribute must be set to `"2"`. - -Each configuration corresponds to a specific hardware setup, where a given set -of monitors are connected to the computer. There can only be one configuration -per hardware setup. - -## Writing configuration - -Monitor configurations are managed by Mutter via the Display panel in Settings, -which uses a D-Bus API to communicate with Mutter. Each time a new configuration -is applied and accepted, the user level configuration file is replaced with -updated content. - -Previously defined monitor configurations for hardware state other than the -current are left intact. - -## Configuration policy - -The monitor configuration policy determines how Mutter configures monitors. This -can mean for example in what order configuration files should be preferred, or -whether configuration via Settings (i.e. D-Bus) should be allowed. - -The default policy is to prioritize configurations defined in the user level -configuration file, and to allow configuring via D-Bus. - -Changing the policy is possible by manually adding a `` element inside -the `` element in the `monitors.xml` file. Note that -there may only be one `` element in each configuration file. - -### Changing configuration file priority policy - -To change the order of configuration file priority, or to disable configuration -files completely, add a `` element inside the `` element -described above. - -In this element, the file policy is defined by a `` element, which -lists stores with the order according to prioritization. Each store is specified -using a `` element with either `system` or `user` as the content. - -#### Example of only reading monitor configuration from the system level file: - -```xml - - - - system - - - -``` - -#### Example of reversing the priority of monitor configuration: - -```xml - - - - user - system - - - -``` - -### Changing D-Bus configuration policy - -D-Bus configureability can be configured using a `` element in the -`` element. It's content should either be `yes` or `no` depending on -whether monitor configuration via D-Bus should be enabled or disable. - -#### Example of how to disable monitor configuration via D-Bus: - -```xml - - - no - - -``` diff --git a/mutter/doc/mutter-constraints.txt b/mutter/doc/mutter-constraints.txt deleted file mode 100644 index a6e02f3..0000000 --- a/mutter/doc/mutter-constraints.txt +++ /dev/null @@ -1,283 +0,0 @@ -File contents: - Basic Ideas - Important points to remember - Explanation of fields in the ConstraintInfo struct - Gory details of resize_gravity vs. fixed_directions - -IMPORTANT NOTE: There's a big comment at the top of constraints.c -explaining how to add extra constraints or tweak others. Read it. I put -that information there because it may be enough information by itself for -people to hack on constraints.c. I won't duplicate that information in -this file; this file is for deeper details. - - ---------------------------------------------------------------------------- -Basic Ideas ---------------------------------------------------------------------------- -There are a couple basic ideas behind how this constraints.c code works and -why it works that way: - - 1) Split the low-level error-prone operations into a special file - 2) Add robustness by prioritizing constraints - 3) Make use of a minimal spanning set of rectangles for the - "onscreen region" (screen minus struts). - 4) Constraints can be user-action vs app-action oriented - 5) Avoid over-complification ;-) - -Some more details explaining these basic ideas: - - 1) Split tedious operations out - - boxes.[ch] have been added which contain many common, tedious, and - error-prone operations. I find that this separation helps a lot for - managing the complexity and ensuring that things work correctly. - Also, note that testboxes.c thoroughly tests all functionality in - boxes.[ch] and a testboxes program is automatically compiled. - - Note that functions have also been added to this file to handle some - of the tedium necessary for edge resistance as well. - - 2) Prioritize constraints - - In the old code, if each and every constraint could not be - simultaneously satisfied, then it would result in some - difficult-to-predict set of constraints being violated. This was - because constraints were applied in order, with the possibility for - each making changes that violated previous constraints, with no - checking done at the end. - - Now, all constraints have an associated priority, defined in the - ConstraintPriority enum near the top of constraints.c. The - constraints are all applied, and then are all checked; if not all are - satisfied then the least important constraints are dropped and the - process is repeated. This ensures that the most important constraints - are satisfied. - - A special note to make here is that if any one given constraint is - impossible to satisfy even individually (e.g. if minimum size hints - specify a larger window than the screen size, making the - fully-onscreen constraint impossible to satisfy) then we treat the - constraint as being satisfied. This sounds counter-intuitive, but the - idea is that we want to satisfy as many constraints as possible and if - we treat it as a violation then all constraints with a lesser priority - also get dropped along with the impossible to satisfy one. - - 3) Using maximal/spanning rectangles - - The constraints rely heavily on something I call spanning rectangles - (which Soeren referred to as maximal rectangles, a name which I think - I like better but I don't want to go change all the code now). These - spanning rectangles have the property that a window will fit on the - screen if and only if it fits within at least one of the rectangles. - Soeren had an alternative way of describing these rectangles, namely - that they were rectangles with the property that if you made any of - them larger in any direction, they would overlap with struts or be - offscreen (with the implicit assumption that there are enough of these - rectangles that combined they cover all relevant parts of the screen). - Note that, by necessity, these spanning/maximal rectangles will often - overlap each other. - - Such a list makes it relatively easy to define operations like - window-is-onscreen or clamp-window-to-region or - shove-window-into-region. Since we have a on-single-xinerama - constraint in addition to the onscreen constraint(s), we cache - number_xineramas + 1 of these lists in the workspace. These lists - then only need to be updated whenever the workarea is (e.g. when strut - list change or screen or xinerama size changes). - - 4) Constraints can be user-action vs app-action oriented - - Such differentiation requires special care for the constraints to be - consistent; e.g. if the user does something and one constraint - applies, then the app does something you have to be careful that the - constraint on the app action doesn't result in some jarring motion. - - In particular, the constraints currently allow offscreen movement or - resizing for user actions only. The way consistency is handled is - that at the end of the constraints, update_onscreen_requirements() - checks to see if the window is offscreen or split across xineramas and - updates window->require_fully_onscreen and - window->require_on_single_xinerama appropriately. - - 5) Avoid over-complification - - The previous code tried to reform the constraints into terms of a - single variable. This made the code rather difficult to - understand. ("This is a rather complicated fix for an obscure bug - that happened when resizing a window and encountering a constraint - such as the top edge of the screen.") It also failed, even on the - very example for which it used as justification for the complexity - (bug 312104 -- when keyboard resizing the top of the window, - Metacity extends the bottom once the titlebar hits the top panel), - though the reason why it failed is somewhat mysterious as it should - have worked. Further, it didn't really reform the constraints in - terms of a single variable -- there was both an x_move_delta and an - x_resize_delta, and the existence of both caused bug 109553 - (gravity with simultaneous move and resize doesn't work) - - ---------------------------------------------------------------------------- -Important points to remember ---------------------------------------------------------------------------- - - - Inner vs Outer window - - Note that because of how configure requests work and - meta_window_move_resize_internal() and friends are set up, that the - rectangles passed to meta_window_constrain() are with respect to inner - window positions instead of outer window positions (meaning that window - manager decorations are not included in the position/size). For the - constraints that need to be enforced with respect to outer window - positions, you'll need to make use of the extend_by_frame() and - unextend_by_frame() functions. - - - meta_window_move_resize_internal() accepts a really hairy set of - inputs. See the huge comment at the beginning of that function. - constraints gets screwed up if that function can't sanitize the input, - so be very careful about that. It used to be pretty busted. - - ---------------------------------------------------------------------------- -Explanation of fields in the ConstraintInfo strut ---------------------------------------------------------------------------- - -As of the time of this writing, ConstraintInfo had the following fields: - orig - current - fgeom - action_type - is_user_action - resize_gravity - fixed_directions - work_area_xinerama - entire_xinerama - usable_screen_region - usable_xinerama_region - -A brief description of each and/or pointers to more information are found -below: - orig - The previous position and size of the window, ignoring any window - decorations - current - The requested position and size of the window, ignoring any window - decorations. This rectangle gets modified by the various constraints - to specify the allowed position closest to the requested position. - fgeom - The geometry of the window frame (i.e. "decorations"), if it exists. - Otherwise, it's a dummy 0-size frame for convenience (i.e. this pointer - is guaranteed to be non-NULL so you don't have to do the stupid check). - action_type - Whether the action being constrained is a move, resize, or a combined - move and resize. Some constraints can run faster with this information - (e.g. constraining size increment hints or min size hints don't need to - do anything for pure move operations). This may also be used for - providing slightly different behavior (e.g. clip-to-region instead of - shove-into-region for resize vs. moving operations), but doesn't - currently have a lot of use for this. - is_user_action - Used to determine whether the action being constrained is a user - action. If so, certain parts of the constraint may be relaxed. Note - that this requires care to get right; see item 4 of the basic ideas - section for more details. - resize_gravity - The gravity used in the resize operation, used in order to make sure - windows are resized correctly if constraints specify that their size - must be modified. Explained further in the resize_gravity - vs. fixed_directions section. - fixed_directions - There may be multiple solutions to shoving a window back onscreen. - Typically, the shortest distance used is the solution picked, but if - e.g. an application only moved its window in a single direction, it's - more desirable that the window is shoved back in that direction than in - a different one. fixed_directions facilitates that. Explained further - in the resize_gravity vs. fixed_directions section. - work_area_xinerama - This region is defined in the workspace and just cached here for - convenience. It is basically the area obtained by taking the current - xinerama, treating all partial struts as full struts, and then - subtracting all struts from the current xinerama region. Useful - e.g. for enforcing maximization constraints. - entire_xinerama - Just a cache of the rectangle corresponding to the entire current - xinerama, including struts. Useful e.g. for enforcing fullscreen - constraints. - usable_screen_region - The set of maximal/spanning rectangles for the entire screen; this - region doesn't overlap with any struts and helps to enforce - e.g. onscreen constraints. - usable_xinerama_region - The set of maximal/spanning rectangles for the current xinerama; this - region doesn't overlap with any struts on the xinerama and helps to - enforce e.g. the on-single-xinerama constraint. - - ---------------------------------------------------------------------------- -Gory details of resize_gravity vs. fixed_directions ---------------------------------------------------------------------------- - -Note that although resize_gravity and fixed_directions look similar, they -are used for different purposes: - - - resize_gravity is only for resize operations and is used for - constraints unrelated to keeping a window within a certain region - - fixed_directions is for both move and resize operations and is - specifically for keeping a window within a specified region. - -Examples of where each are used: - - - If a window is simultaneously moved and resized to the southeast corner - with META_GRAVITY_SOUTH_EAST, but it turns out that the window was sized to - something smaller than the minimum size hint, then the size_hints - constraint should resize the window using the resize_gravity to ensure - that the southeast corner doesn't move. - - If an application resizes itself so that it grows downward only (which - I note could be using any of three different gravities, most likely - NorthWest), and happens to put the southeast part of the window under a - partial strut, then the window needs to be forced back on screen. - (Yes, shoved onscreen and not clipped; see bug 136307). It may be the - case that moving the window to the left results in less movement of the - window than moving the window up, which, in the absence of fixed - directions would cause us to chose moving to the left. But since the - user knows that only the height of the window is changing, they would - find moving to the left weird (especially if this were a dialog that - had been centered on its parent). It'd be better to shove the window - upwards so we make sure to keep the left and right sides fixed in this - case. Note that moving the window upwards (or leftwards) is probably - totally against the gravity in this case; but that's okay because - gravity typically assumes there's more than enough onscreen space for - the resize and we only override the gravity when that assumption is - wrong. - -For the paranoid, a fixed directions might give an impossible to fulfill -constraint (I don't think that's true currently in the code, but I haven't -thought it through in a while). If this ever becomes a problem, it should -be relatively simple to throw out the fixed directions when this happens -and rerun the constraint. Of course, it might be better to rethink things -to just avoid such a problem. - -The nitty gritty of what gets fixed: - User move: - in x direction - y direction fixed - in y direction - x direction fixed - in both dirs. - neither direction fixed - User resize: (note that for clipping, only 1 side ever changed) - in x direction - y direction fixed (technically opposite x side fixed too) - in y direction - x direction fixed (technically opposite y side fixed too) - in both dirs. - neither direction fixed - App move: - in x direction - y direction fixed - in y direction - x direction fixed - in both dirs. - neither direction fixed - App resize - in x direction - y direction fixed - in y direction - x direction fixed - in 2 parallel directions (center side gravity) - other dir. fixed - in 2 orthogonal directions (corner gravity) - neither dir. fixed - in 3 or 4 directions (a center-like gravity) - neither dir. fixed - Move & resize - Treat like resize case though this will usually mean all four sides - change and result in neither direction being fixed - Note that in all cases, if neither direction moves it is likely do to a - change in struts and thus neither direction should be fixed despite the - lack of movement. diff --git a/mutter/doc/mutter-focus.txt b/mutter/doc/mutter-focus.txt deleted file mode 100644 index 574a3a5..0000000 --- a/mutter/doc/mutter-focus.txt +++ /dev/null @@ -1,252 +0,0 @@ -To make choice of focus window consistent for each focus method, a -number of guidelines should be followed. (For purposes of discussion -here, I'm excluding things like the panel and the desktop from -"windows". It is technically incorrect to do this, but I'm lazy and -"windows" is shorter than something like "normal windows". See the -end of the discussion for how these special cases are handled.) The -basics are easy: - -Focus method Behavior - click When a user clicks on a window, focus it - sloppy When an EnterNotify is received, focus the window - mouse Same as sloppy, but also defocus when mouse enters DESKTOP - window - -Note that these choices (along with the choice that clicking on a -window raises it for the click focus method) introduces the following -invariants for focus from mouse activity: - -Focus method Invariant - click The window on top is focused - sloppy If the mouse is in a window, then it is focused; if the - mouse is not in a window, then the most recently used - window is focused. - mouse If the mouse is in a non-DESKTOP window, then it is focused; - otherwise, the designated "no_focus_window" is focused - -However, there are a number of cases where the current focus window -becomes invalid and another should be chosen. Some examples are when -a focused window is closed or minimized, or when the user changes -workspaces. In these cases, there needs to be a rule consistent with -the above about the new window to choose. - -Focus method Behavior - click Focus the window on top - sloppy Focus the window containing the pointer if there is such - a window, otherwise focus the most recently used window. - mouse Focus the non-DESKTOP window containing the pointer if - there is one, otherwise focus the designated - "no_focus_window". - -Note that "most recently used window", as used here, has a slightly -different connotation than "most recent to have keyboard focus". This -is because when a user activates a window that is a transient, its -ancestor(s) should be considered to be more recently used than other -windows that have had the keyboard focus more recently. (See bug -157360; this may mean that the alt-tab order should also change -simultaneously, although the current implementation does not do that.) - -Also, sometimes a new window will be mapped (e.g. unminimizing a -window or launching a new application). Most users want to interact -with new windows right away, so these should typically be focused. -This does conflict with the invariants for sloppy and mouse focus -modes, so this wouldn't be true for a strict-pointer-focus mode. For -all other modes (non-strict-pointer-focus modes), there are only two -cases in which a new window shouldn't be focused: - - 1) If the window takes a while to launch and the user starts - interacting with a different application, the new window should - not take focus. - 2) If the window that will appear was not launched by the user - (error dialogs, instant messaging windows, etc.), then the window - should not take focus when it appears. - -To handle these cases, Metacity compares timestamps of the event that -caused the launch and the timestamp of the last interaction with the -focused window. (Case 2 is handled by the application providing a -special timestamp of 0 for the launch time, which ensures that the -window that appears doesn't get focus) - -If the newly launched window isn't focused, some things should be done -to alert the user that there is a window to work with: - 1) The _NET_WM_DEMANDS_ATTENTION hint should be set - 2) If the new window isn't modal for the focused window, it should - appear below the focused window so that it doesn't obscure the - focused window that the user is interacting with. - 3) If the new window is modal to the focused window, the currently - focused window should lose focus but the modal window should - appear on top. - -Additionally, the user may decide to use the keyboard instead of the mouse -to navigate between windows (referred to as "keynav"). This poses no -problems for click-to-focus (because the same invariant can be -maintained), but for sloppy and mouse focus it requires extra work to -attempt to handle the INHERENTLY CONFLICTING CONSTRAINTS. Metacity does -this by having a mouse_mode boolean used to determine which of the two -sets of invariants holds. This mode is set according to which method was -most recently used to choose a focus window: - 1) When receiving EnterNotify events from mouse movement, set - mouse_mode to TRUE. - 2) When using keynav to choose a focus window (e.g. alt-tab, alt-esc, - alt-f2, move-window-to-workspace keybindings), set mouse_mode to FALSE. - 3) When handling events that don't choose a focus window but rather need - a focus_window chosen for them (e.g. switch-to-workspace keybindings), - don't change the mouse_mode and just use the current value. -Note that grabs present a special case since they can generate EnterNotify -and LeaveNotify events without using the mouse, thus these events should be -ignored when the crossing mode is NotifyGrab or NotifyUngrab. THIS -MOUSENAV/KEYNAV MODERATION METHOD IS NOT PERFECT--there are corner cases -when trying to mix-and-match between mousenav and keynav simultaneously -that cause problems; but it appears to be the most reasonable tradeoff and -works well in most cases, especially if the user sticks to just mousenav -for a long time or just keynav for a long time. - -Finally, windows of type WM_DOCK or WM_DESKTOP (e.g. the desktop and -the panel) present a special case, at least partially due to the lack -of decorations. For WM_DESKTOP windows, we only focus them if the -user explicitly requests it (e.g. clicks on the window, uses -Ctrl-Alt-Tab to navigate to it, uses a keybinding to show the desktop, -etc.). For WM_DOCK windows, we do not focus unless we receive a very -explicit request (e.g. Ctrl-Alt-Tab or a _NET_ACTIVE_WINDOW message; -not normal clicks). - - - - -To read more about the bugs that inspired these choices: - - When a focused window becomes invalid and another should be chosen - http://bugzilla.gnome.org/show_bug.cgi?id=135810 - - When a new window is mapped - http://bugzilla.gnome.org/show_bug.cgi?id=118372 - Also, the EWMH spec, especially the parts relating to _NET_WM_USER_TIME - - Modal vs. non-modal dialogs that get denied focus when mapped - http://bugzilla.gnome.org/show_bug.cgi?id=151996 - - Mousenav vs. Keynav in mouse and sloppy focus modes - http://bugzilla.gnome.org/show_bug.cgi?id=167545 - http://bugzilla.gnome.org/show_bug.cgi?id=101190 - http://bugzilla.gnome.org/show_bug.cgi?id=357695 - - Not focusing panels - http://bugzilla.gnome.org/show_bug.cgi?id=160470 - http://bugzilla.gnome.org/show_bug.cgi?id=120100 - -There were many bugs which had to be fixed to get all the above -working; they helped form these policies and/or show the difficulties -in implementing this policy (my apologies in advance for producing a -list heavily lopsided to what I've done; it's just that these bugs are -the ones I'm the most familiar with): - bug 72314 ignore LeaveNotify events from grabs - bug 82921 focus windows on map - bug 87531 only show focus for sticky windows on active workspace (pager) - bug 94545 focus window on workspace switch is non-deterministic - bug 95747 should ignore EnterNotify events with NotifyInferior detail set - bug 97635 sticky windows always keep focus when switching workspaces - bug 102665 a window unminimized from the tasklist should be focused - bug 107347 focus windows that manually position themselves too - bug 108643 focus in MRU order instead of stack order - bug 110970 moving a window to another workspace loses focus - bug 112031 closing a dialog can result in a strange focus window - bug 115650 add _NET_WM_USER_TIME support to gtk+ (see also 150502) - bug 120100 panel shouldn't be focused after workspace applet usage - bug 123803 need final EnterNotify after workspace switch (see also 124798) - bug 124981 focus clicked window in pager only if on current workspace - bug 125492 catch the xserver unfocusing everything and fix its braindeadedness - bug 128200 focus correct window on libwnck window minimize (see 107681 too) - bug 131582 fix race condition on window minimize/close - bug 133120 wrong window focused when changing workspaces - bug 135024 _NET_ACTIVE_WINDOW messages need timestamps - bug 135786 middle-clicking on focused window to lower it should defocus too - bug 136581 window minimization vs. activation for mouse focus - bug 144900 fix focus choice on "un-showing" the desktop - bug 147475 don't lock keyboard on workspace change - bug 148364 DEMANDS_ATTENTION support for metacity & libwnck (and other stuff) - bug 149028 focus-stealing-prevention for metacity-dialog (and other stuff) - bug 149366 windows denied focus on map occur in wrong order in alt-tab list - bug 149543 consistent focus window when unshowing desktop - bug 149589 race in focus choice from libwnck messages - bug 150271 make sure "run application" dialog gets focused - bug 150668 update gtk+ _NET_ACTIVE_WINDOW support - bug 151245 application startup notification forwarding (partially rejected) - bug 151984 Soeren's idea--backup timestamp when startup notification not used - bug 151990 prevent focus inconsistencies by only providing one focus method - bug 151996 modal dialogs denied focus should not be lowered - bug 152000 fix race on window close followed by rapid mouse movement - bug 152004 ways to handle new window versus mouse invariants - bug 153220 catch the root window getting focus and reset to default window - bug 157360 focus parents of dismissed transient windows in preference to - the window that most recently had focus - bug 159257 focus the desktop when showing it - bug 160470 don't focus panels on click - bug 163450 correct highlighting in workspace switcher popup - bug 164716 refuse to focus a window with a modal transient, and focus - the transient instead - bug 166524 avoid new windows being obscured by the focus window - bug 167545 mousenav vs. keynav in mouse and sloppy focus modes - - - -Addendum on sloppy and mouse focus - You may occasionally hear people refer to sloppy or mouse focus - modes as inherently buggy. This is what they mean by that: - - 1) Keynav doesn't maintain the same invariants as mouse navigation - for these focus modes; switching back and forth between - navigation methods, therefore, may have or appear to have - inconsistencies. Examples: - a) If the user uses Alt-Tab to change the window with focus, then - starts to move the mouse, at that moment the window where the - mouse is does not have focus. - b) Users expect that a workspace they previously used will not - change when the return to it. This means things like window - position and stacking order, but also the focus window. - Unfortunately, using the original focus window (which would be - the most recently used window on that workspace) will - sometimes conflict with the invariants for mouse and sloppy - focus modes. Users are much more surprised by the invariant - being broken than by having the focus window changed (see bug - 94545 and probably others), so we maintain the invariant. - This only matters when using Ctrl-Alt-Arrow to switch - workspaces instead of clicking in the workspace switcher, so - this really is a keynav vs mouse issue. Either that, or a - windows-are-being-mapped exception. ;-) - c) Opening a menu, then moving the mouse to a different window, - and then pressing escape to dismiss the menu will result in - the window containing the mouse not being focused. This is - actually correct behavior (because pressing escape shows that - the user is using key navigation to interact with the window - containing the menu) but is one of those hard-to-get-right - keynav and mouse focus mixture cases. (See bug 101190 for - more details) - d) Similar to (c), moving the mouse off the menu doesn't immediately - focus the window that the mouse goes over, due to an application - grab (we couldn't change this and wouldn't want to, but - technically it does break the invariant). - e) If mouse_mode is off and the user does something to cause focus to - change (e.g. switch workspaces, close or minimize a window, etc.) - and simultaneously tries to move the mouse, the choice of which - window to focus is inherently race-y. (You probably can't satisfy - both keynav and mousenav invariants simultaneously...) - 2) The sloppy/mouse invariants are often not strictly maintained; - for example, we provide an exception to the invariant for newly - mapped windows. (Most find that not allowing this exception is - confusing) - 3) There are an awful lot of little cases to handle to get any focus - mode right, even for click-to-focus. Since mouse and sloppy - focus have sometimes been hard to even determine what correct - behavior is, it is much harder to get them completely right. - Plus mouse and sloppy focus users are a minority, decreasing the - motivation of window manager implementors to get those focus - modes right. - 4) Because of -1-, -2-, and -3-, implementations are often buggy or - inconsistent and people form their opinions from usage of these - implementations. - 5) Sloppy focus suffers from a bit of a discoverability problem (for - example, I have seen a scientist sit down to a computer for which - sloppy focus was in use and take a few minutes before figuring - out how window activation worked; granted the layout of the - windows in that situation was a bit unusual but it still - illustrates that sloppy focus is harder than it should be to - figure out). Mouse focus solves this problem; however, people - that have experience with other computing environments are - accustomed to being able to move their mouse outside the window - they are working with and still continue interacting with that - window, which conflicts with mouse focus. diff --git a/mutter/doc/mutter-kms-abstractions.md b/mutter/doc/mutter-kms-abstractions.md deleted file mode 100644 index 49d83b0..0000000 --- a/mutter/doc/mutter-kms-abstractions.md +++ /dev/null @@ -1,85 +0,0 @@ -# KMS abstraction - -The KMS abstraction consists of various building blocks for helping out with -interacting with the various drm API's, enabling users to use a -transactional API, aiming to hide all interaction with the underlying APIs. - -The subsystem defines two separate contexts, the "main" context, and the -"impl" context. The main context is the context of which mutter as a whole -runs in. It uses the main GLib main loop and main context and always runs in -the main thread. - -The impl context is where all underlying API is being executed. While in the -current state, it always runs in the main thread, the aim is to be able to -execute the impl context in a dedicated thread. - -The public facing MetaKms API is always assumed to be executed from the main -context. - -The KMS abstraction consists of the following public components: - -### `MetaKms` - -Main entry point; used by the native backend to create devices, post updates -etc. - -### `MetaKmsDevice` - -A device (usually /dev/dri/cardN, where N being a number). Used to get KMS -objects, such as connectors, CRTCs, planes, as well as basic meta data such -as device path etc. - -### `MetaKmsCrtc` - -Represents a CRTC. It manages a representation of the current CRTC state, -including current mode, coordinates, possible clones. - -### `MetaKmsConnector` - -Represents a connector, e.g. a display port connection. It also manages a -representation of the current state, including meta data such as physical -dimension of the connected, available modes, EDID, tile info etc. It also -contains helper functions for configuration, as well as methods for adding -configuration to a transaction (See `MetaKmsUpdate`). - -### `MetaKmsPlane` - -Represents a hardware plane. A plane is used to define the content of what -should be presented on a CRTC. Planes can either be primary planes, used as -a backdrop for CRTCs, overlay planes, and cursor planes. - -### `MetaKmsMode` - -Represents a mode a CRTC and connector can be configured with. -Represents both modes directly derived from the devices, as well as -fall back modes when the CRTC supports scaling. - -### `MetaKmsUpdate` - -A KMS transaction object, meant to be processed potentially atomically when -posted. An update consists of plane assignments, mode sets and KMS object -property entries. The user adds updates to the object, and then posts it via -MetaKms. It will then be processed by the MetaKms backend (See -`MetaKmsImpl`), potentially atomically. Each `MetaKmsUpdate` deals with -updating a single device. - -There are also these private objects, without public facing API: - -### `MetaKmsImpl` - -The KMS impl context object, managing things in the impl context. - -### `MetaKmsImplDevice` - -An object linked to a `MetaKmsDevice`, but where it is executed in the impl -context. It takes care of the updating of the various KMS object (CRTC, -connector, ..) states. - -This is an abstract type, with currently `MetaKmsImplDeviceSimple` -implementing mode setting and page flipping using legacy DRM API. - -### `MetaKmsPageFlip` - -A object representing a page flip. It's created when a page flip is queued, -and contains information necessary to provide feedback to the one requesting -the page flip. diff --git a/mutter/doc/mutter-relationships.md b/mutter/doc/mutter-relationships.md deleted file mode 100644 index 7d6dcc7..0000000 --- a/mutter/doc/mutter-relationships.md +++ /dev/null @@ -1,135 +0,0 @@ -# Compositor stage and hardware relationships - -## Brief description of components - - - `MetaLogicalMonitor` is one monitor or more monitor occupying the same region of the compositor space. E.g. when mirroring two monitors, both belong to the same logical monitor. - - `MetaMonitor` is a single physical monitor, but it can sometimes consist of more than one separate panel (for instance, 5K tiled monitors which literally require 2 cables due to lack of bandwidth) - - `MetaOuptut` is a connector e.g. a DisplayPort connector or HDMI connector. - - `MetaCrtc` represents a component on the display hardware that channels video memory to connectors. - -## Entity relationship diagram - -```mermaid -erDiagram - MetaBackend ||--|| MetaMonitorManager : owns - MetaBackend ||--|{ MetaGpu : owns - MetaBackend ||--|| ClutterStage : owns - MetaGpu ||--|{ MetaCrtc : owns - MetaGpu ||--|{ MetaOutput : owns - MetaCrtc |o..o{ MetaOutput : assigned - MetaBackend ||--|{ MetaVirtualMonitor : owns - MetaVirtualMonitor ||--|| MetaCrtc : owns - MetaVirtualMonitor ||--|| MetaOutput : owns - MetaMonitorManager ||--|{ MetaMonitor : owns - MetaMonitorManager ||--|{ MetaLogicalMonitor : owns - MetaLogicalMonitor ||..|{ MetaMonitor : has - MetaMonitor ||..|{ MetaOutput : has - ClutterStage ||--|{ ClutterStageView : has - ClutterStageView ||..|| MetaCrtc : corresponds - ClutterStageView ||--|| ClutterFrameClock : owns - ClutterStageView ||..|| MetaLogicalMonitor : derive-scale -``` - -## Class diagrams - -`MetaBackend`, `MetaGpu` and `MetaMonitorManager` class diagrams. - -```mermaid -classDiagram - MetaBackend <-- MetaBackendNative - MetaBackend <-- MetaBackendX11 - class MetaBackend{ - MetaMonitorManager monitor_manager - List~MetaGpu~ gpus - } - MetaGpu <-- MetaGpuKms - MetaGpu <-- MetaGpuXrandr - class MetaGpu{ - List~MetaOutput~ - List~MetaCrtc~ - } - MetaMonitorManager <-- MetaMonitorManagerNative - MetaMonitorManager <-- MetaMonitorManagerXrandr - class MetaMonitorManager{ - List~MetaMonitor~ monitors - List~MetaLogicalMonitor~ logical_monitors - } -``` - -`MetaLogicalMonitor`, `MetaMonitor`, `MetaOutput` and `MetaCrtc` class diagrams. - -```mermaid -classDiagram - MetaLogicalMonitor - class MetaLogicalMonitor{ - List~MetaMonitor~ - } - MetaMonitor <-- MetaMonitorNormal - MetaMonitor <-- MetaMonitorTiled - class MetaMonitorNormal{ - MetaOutput output - } - class MetaMonitorTiled{ - List~MetaOutput~ output - } - MetaOutput <-- MetaOutputNative - MetaOutputNative <-- MetaOutputKms - MetaOutputNative <-- MetaOutputVirtual - MetaOutput <-- MetaOutputXrandr - MetaCrtc <-- MetaCrtcNative - MetaCrtcNative <-- MetaCrtcKms - MetaCrtcNative <-- MetaCrtcVirtual - MetaCrtc <-- MetarCrtcXrandr -``` - -`ClutterStage` and `ClutterStageView` class diagram when using the Wayland session. - -```mermaid -classDiagram - class ClutterStage{ - List~ClutterStageView~ - } - class ClutterStageView{ - MetaCrtc crtc - } -``` - -`MetaKms` class diagram. - -```mermaid -classDiagram - class MetaKms{ - List~MetaKmsDevice~ devices - } - class MetaKmsDevice{ - List~MetaKmsConnector~ - List~MetaKmsCrtc~ - List~MetaKmsPlane~ - MetaKmsImplDevice impl_device - } - MetaKms "many" --> MetaKmsDevice : Owns - MetaKmsDevice --> MetaKmsImplDevice : Owns - MetaKmsImplDevice <-- MetaKmsImplDeviceAtomic - MetaKmsImplDevice <-- MetaKmsImplDeviceSimple -``` - -## Native backend and mode setting - - * `MetaGpuKms`, `MetaCrtcKms` and `MetaOutputKms` are used for configuration. - * `MetaKmsDevice`, `MetaKmsCrtc`, `MetaKmsConnector` and `MetaKmsPlane` are abstractions on top of kernel mode setting concepts. - -```mermaid -erDiagram - MetaBackendNative ||--|{ MetaGpuKms : owns - MetaBackendNative ||--|| MetaKms : owns - MetaKms ||--|{ MetaKmsDevice : owns - MetaKmsDevice ||--|{ MetaKmsCrtc : owns - MetaKmsDevice ||--|{ MetaKmsConnector : owns - MetaKmsDevice ||--|{ MetaKmsPlane : owns - MetaGpuKms ||--|{ MetaCrtcKms : owns - MetaGpuKms ||--|{ MetaOutputKms : owns - MetaCrtcKms |o..o{ MetaOutputKms : assigned - MetaGpuKms |o..o| MetaKmsDevice : associated - MetaCrtcKms |o..o| MetaKmsCrtc : associated - MetaOutputKms |o..o| MetaKmsConnector : associated -``` diff --git a/mutter/doc/reference/cally/cally.toml.in b/mutter/doc/reference/cally/cally.toml.in deleted file mode 100644 index 2b1a111..0000000 --- a/mutter/doc/reference/cally/cally.toml.in +++ /dev/null @@ -1,41 +0,0 @@ -[library] -version = "@version@" -browse_url = "https://gitlab.gnome.org/GNOME/mutter/" -repository_url = "https://gitlab.gnome.org/GNOME/mutter.git" -website_url = "https://blogs.gnome.org/shell-dev/" -docs_url = "https://mutter.gnome.org/" -logo_url = "logo.svg" -authors = "Mutter Development Team" -license = "GPL-2.0-or-later" -description = "The Clutter Accessibility Implementation Library" -dependencies = [ "GObject-2.0", "Atk-1.0" ] -devhelp = true -search_index = true - - [dependencies."GObject-2.0"] - name = "GObject" - description = "The base type system library" - docs_url = "https://docs.gtk.org/gobject/" - - [dependencies."Atk-1.0"] - name = "Atk" - description = "The Accessibility toolkit" - docs_url = "https://docs.gtk.org/atk/" - -[theme] -name = "basic" -show_index_summary = true -show_class_hierarchy = true - -[source-location] -base_url = "https://gitlab.gnome.org/GNOME/mutter/-/blob/@vcs_tag@/" - -[extra] -# The same order will be used when generating the index -content_files = [ -] -content_images = [ - "logo.svg", -] -urlmap_file = "urlmap.js" - diff --git a/mutter/doc/reference/cally/logo.svg b/mutter/doc/reference/cally/logo.svg deleted file mode 120000 index ffdbeb4..0000000 --- a/mutter/doc/reference/cally/logo.svg +++ /dev/null @@ -1 +0,0 @@ -../../../logo.svg \ No newline at end of file diff --git a/mutter/doc/reference/cally/meson.build b/mutter/doc/reference/cally/meson.build deleted file mode 100644 index 63a420e..0000000 --- a/mutter/doc/reference/cally/meson.build +++ /dev/null @@ -1,35 +0,0 @@ - -cally_toml = configure_file( - input: 'cally.toml.in', - output: 'cally.toml', - configuration: toml_conf, - install: true, - install_dir: docs_dir / 'cally', -) - -custom_target('cally-doc', - input: [ cally_toml, libmutter_cally_gir[0] ], - output: 'cally', - command: [ - gidocgen, - 'generate', - gidocgen_common_args, - '--add-include-path=@0@'.format(meson.current_build_dir() / '../../../mtk/mtk'), - '--add-include-path=@0@'.format(meson.current_build_dir() / '../../../cogl/cogl'), - '--add-include-path=@0@'.format(meson.current_build_dir() / '../../../cogl/cogl-pango'), - '--add-include-path=@0@'.format(meson.current_build_dir() / '../../../clutter/clutter'), - '--config=@INPUT0@', - '--output-dir=@OUTPUT@', - '--content-dir=@0@'.format(meson.current_source_dir()), - '@INPUT1@', - ], - depends: [ - libmutter_mtk_gir[0], - libmutter_cogl_gir[0], - libmutter_cogl_pango_gir[0], - libmutter_clutter_gir[0], - ], - build_by_default: true, - install: true, - install_dir: docs_dir, -) diff --git a/mutter/doc/reference/cally/urlmap.js b/mutter/doc/reference/cally/urlmap.js deleted file mode 100644 index 51a8da1..0000000 --- a/mutter/doc/reference/cally/urlmap.js +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-FileCopyrightText: 2021 GNOME Foundation -// SPDX-License-Identifier: LGPL-2.1-or-later - -// A map between namespaces and base URLs for their online documentation -baseURLs = [ - [ 'GLib', 'https://docs.gtk.org/glib/' ], - [ 'GObject', 'https://docs.gtk.org/gobject/' ], - [ 'Gio', 'https://docs.gtk.org/gio/' ], - [ 'Atk', 'https://docs.gtk.org/atk/' ], - [ 'Clutter', 'https://mutter.gnome.org/clutter/' ], -] diff --git a/mutter/doc/reference/clutter/clutter.toml.in b/mutter/doc/reference/clutter/clutter.toml.in deleted file mode 100644 index 5878bcc..0000000 --- a/mutter/doc/reference/clutter/clutter.toml.in +++ /dev/null @@ -1,46 +0,0 @@ -[library] -version = "@version@" -browse_url = "https://gitlab.gnome.org/GNOME/mutter/" -repository_url = "https://gitlab.gnome.org/GNOME/mutter.git" -website_url = "https://blogs.gnome.org/shell-dev/" -docs_url = "https://mutter.gnome.org/" -logo_url = "logo.svg" -authors = "Mutter Development Team" -license = "GPL-2.0-or-later" -description = "An OpenGL based 'interactive canvas' library" -dependencies = [ "GObject-2.0", "cairo-1.0", "Atk-1.0" ] -devhelp = true -search_index = true - - [dependencies."GObject-2.0"] - name = "GObject" - description = "The base type system library" - docs_url = "https://docs.gtk.org/gobject/" - - [dependencies."cairo-1.0"] - name = "cairo" - description = "A 2D graphics library with support for multiple output devices" - docs_url = "https://www.cairographics.org/manual/" - - [dependencies."Atk-1.0"] - name = "Atk" - description = "The Accessibility toolkit" - docs_url = "https://docs.gtk.org/atk/" - -[theme] -name = "basic" -show_index_summary = true -show_class_hierarchy = true - -[source-location] -base_url = "https://gitlab.gnome.org/GNOME/mutter/-/blob/@vcs_tag@/" - -[extra] -# The same order will be used when generating the index -content_files = [ -] -content_images = [ - "logo.svg", -] -urlmap_file = "urlmap.js" - diff --git a/mutter/doc/reference/clutter/logo.svg b/mutter/doc/reference/clutter/logo.svg deleted file mode 120000 index ffdbeb4..0000000 --- a/mutter/doc/reference/clutter/logo.svg +++ /dev/null @@ -1 +0,0 @@ -../../../logo.svg \ No newline at end of file diff --git a/mutter/doc/reference/clutter/meson.build b/mutter/doc/reference/clutter/meson.build deleted file mode 100644 index d93906a..0000000 --- a/mutter/doc/reference/clutter/meson.build +++ /dev/null @@ -1,33 +0,0 @@ - -clutter_toml = configure_file( - input: 'clutter.toml.in', - output: 'clutter.toml', - configuration: toml_conf, - install: true, - install_dir: docs_dir / 'clutter', -) - -custom_target('clutter-doc', - input: [ clutter_toml, libmutter_clutter_gir[0] ], - output: 'clutter', - command: [ - gidocgen, - 'generate', - gidocgen_common_args, - '--add-include-path=@0@'.format(meson.current_build_dir() / '../../../mtk/mtk'), - '--add-include-path=@0@'.format(meson.current_build_dir() / '../../../cogl/cogl'), - '--add-include-path=@0@'.format(meson.current_build_dir() / '../../../cogl/cogl-pango'), - '--config=@INPUT0@', - '--output-dir=@OUTPUT@', - '--content-dir=@0@'.format(meson.current_source_dir()), - '@INPUT1@', - ], - depends: [ - libmutter_mtk_gir[0], - libmutter_cogl_pango_gir[0], - libmutter_cogl_gir[0], - ], - build_by_default: true, - install: true, - install_dir: docs_dir, -) diff --git a/mutter/doc/reference/clutter/urlmap.js b/mutter/doc/reference/clutter/urlmap.js deleted file mode 100644 index 8cf206c..0000000 --- a/mutter/doc/reference/clutter/urlmap.js +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2021 GNOME Foundation -// SPDX-License-Identifier: LGPL-2.1-or-later - -// A map between namespaces and base URLs for their online documentation -baseURLs = [ - [ 'GLib', 'https://docs.gtk.org/glib/' ], - [ 'GObject', 'https://docs.gtk.org/gobject/' ], - [ 'Gio', 'https://docs.gtk.org/gio/' ], - [ 'Atk', 'https://docs.gtk.org/atk/' ], - [ 'Mtk', 'https://mutter.gnome.org/mtk/' ], - [ 'Cogl', 'https://mutter.gnome.org/cogl/' ], -] diff --git a/mutter/doc/reference/cogl-pango/cogl-pango.toml.in b/mutter/doc/reference/cogl-pango/cogl-pango.toml.in deleted file mode 100644 index a994e71..0000000 --- a/mutter/doc/reference/cogl-pango/cogl-pango.toml.in +++ /dev/null @@ -1,46 +0,0 @@ -[library] -version = "@version@" -browse_url = "https://gitlab.gnome.org/GNOME/mutter/" -repository_url = "https://gitlab.gnome.org/GNOME/mutter.git" -website_url = "https://blogs.gnome.org/shell-dev/" -docs_url = "https://mutter.gnome.org/" -logo_url = "logo.svg" -authors = "Mutter Development Team" -license = "GPL-2.0-or-later" -description = "A Low Level GPU Graphics and Utilities API" -dependencies = [ "GObject-2.0", "Pango-1.0", "PangoCairo-1.0" ] -devhelp = true -search_index = true - - [dependencies."GObject-2.0"] - name = "GObject" - description = "The base type system library" - docs_url = "https://docs.gtk.org/gobject/" - - [dependencies."Pango-1.0"] - name = "Pango" - description = "Text shaping and rendering" - docs_url = "https://docs.gtk.org/Pango/" - - [dependencies."PangoCairo-1.0"] - name = "PangoCairo" - description = "Cairo support for Pango" - docs_url = "https://docs.gtk.org/PangoCairo/" - -[theme] -name = "basic" -show_index_summary = true -show_class_hierarchy = true - -[source-location] -base_url = "https://gitlab.gnome.org/GNOME/mutter/-/blob/@vcs_tag@/" - -[extra] -# The same order will be used when generating the index -content_files = [ -] -content_images = [ - "logo.svg", -] -urlmap_file = "urlmap.js" - diff --git a/mutter/doc/reference/cogl-pango/logo.svg b/mutter/doc/reference/cogl-pango/logo.svg deleted file mode 120000 index ffdbeb4..0000000 --- a/mutter/doc/reference/cogl-pango/logo.svg +++ /dev/null @@ -1 +0,0 @@ -../../../logo.svg \ No newline at end of file diff --git a/mutter/doc/reference/cogl-pango/meson.build b/mutter/doc/reference/cogl-pango/meson.build deleted file mode 100644 index 49f1ddd..0000000 --- a/mutter/doc/reference/cogl-pango/meson.build +++ /dev/null @@ -1,30 +0,0 @@ - -cogl_pango_toml = configure_file( - input: 'cogl-pango.toml.in', - output: 'cogl-pango.toml', - configuration: toml_conf, - install: true, - install_dir: docs_dir / 'cogl-pango', -) - -custom_target('cogl-pango-doc', - input: [ cogl_pango_toml, libmutter_cogl_pango_gir[0] ], - output: 'cogl-pango', - command: [ - gidocgen, - 'generate', - gidocgen_common_args, - '--add-include-path=@0@'.format(meson.current_build_dir() / '../../../mtk/mtk'), - '--add-include-path=@0@'.format(meson.current_build_dir() / '../../../cogl/cogl'), - '--config=@INPUT0@', - '--output-dir=@OUTPUT@', - '--content-dir=@0@'.format(meson.current_source_dir()), - '@INPUT1@', - ], - depends: [ - libmutter_cogl_gir[0], - ], - build_by_default: true, - install: true, - install_dir: docs_dir, -) diff --git a/mutter/doc/reference/cogl-pango/urlmap.js b/mutter/doc/reference/cogl-pango/urlmap.js deleted file mode 100644 index e0f4194..0000000 --- a/mutter/doc/reference/cogl-pango/urlmap.js +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-FileCopyrightText: 2021 GNOME Foundation -// SPDX-License-Identifier: LGPL-2.1-or-later - -// A map between namespaces and base URLs for their online documentation -baseURLs = [ - [ 'GObject', 'https://docs.gtk.org/gobject/' ], - [ 'Pango', 'https://docs.gtk.org/Pango/' ], - [ 'PangoCairo', 'https://docs.gtk.org/PangoCairo/' ], - [ 'Cogl', 'https://mutter.gnome.org/cogl/' ], -] diff --git a/mutter/doc/reference/cogl/cogl.toml.in b/mutter/doc/reference/cogl/cogl.toml.in deleted file mode 100644 index b3f271b..0000000 --- a/mutter/doc/reference/cogl/cogl.toml.in +++ /dev/null @@ -1,46 +0,0 @@ -[library] -version = "@version@" -browse_url = "https://gitlab.gnome.org/GNOME/mutter/" -repository_url = "https://gitlab.gnome.org/GNOME/mutter.git" -website_url = "https://blogs.gnome.org/shell-dev/" -docs_url = "https://mutter.gnome.org/" -logo_url = "logo.svg" -authors = "Mutter Development Team" -license = "GPL-2.0-or-later" -description = "A Low Level GPU Graphics and Utilities API" -dependencies = [ "GObject-2.0", "Graphene-1.0", "cairo-1.0" ] -devhelp = true -search_index = true - - [dependencies."GObject-2.0"] - name = "GObject" - description = "The base type system library" - docs_url = "https://docs.gtk.org/gobject/" - - [dependencies."Graphene-1.0"] - name = "Graphene" - description = "A thin layer of mathematical types for 3D libraries" - docs_url = "https://ebassi.github.io/graphene/docs" - - [dependencies."cairo-1.0"] - name = "cairo" - description = "A 2D graphics library with support for multiple output devices" - docs_url = "https://www.cairographics.org/manual/" - -[theme] -name = "basic" -show_index_summary = true -show_class_hierarchy = true - -[source-location] -base_url = "https://gitlab.gnome.org/GNOME/mutter/-/blob/@vcs_tag@/" - -[extra] -# The same order will be used when generating the index -content_files = [ -] -content_images = [ - "logo.svg", -] -urlmap_file = "urlmap.js" - diff --git a/mutter/doc/reference/cogl/logo.svg b/mutter/doc/reference/cogl/logo.svg deleted file mode 120000 index ffdbeb4..0000000 --- a/mutter/doc/reference/cogl/logo.svg +++ /dev/null @@ -1 +0,0 @@ -../../../logo.svg \ No newline at end of file diff --git a/mutter/doc/reference/cogl/meson.build b/mutter/doc/reference/cogl/meson.build deleted file mode 100644 index 1b378a3..0000000 --- a/mutter/doc/reference/cogl/meson.build +++ /dev/null @@ -1,26 +0,0 @@ - -cogl_toml = configure_file( - input: 'cogl.toml.in', - output: 'cogl.toml', - configuration: toml_conf, - install: true, - install_dir: docs_dir / 'cogl', -) - -custom_target('cogl-doc', - input: [ cogl_toml, libmutter_cogl_gir[0] ], - output: 'cogl', - command: [ - gidocgen, - 'generate', - gidocgen_common_args, - '--add-include-path=@0@'.format(meson.current_build_dir() / '../../../mtk/mtk'), - '--config=@INPUT0@', - '--output-dir=@OUTPUT@', - '--content-dir=@0@'.format(meson.current_source_dir()), - '@INPUT1@', - ], - build_by_default: true, - install: true, - install_dir: docs_dir, -) diff --git a/mutter/doc/reference/cogl/urlmap.js b/mutter/doc/reference/cogl/urlmap.js deleted file mode 100644 index 3f8bc3a..0000000 --- a/mutter/doc/reference/cogl/urlmap.js +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-FileCopyrightText: 2021 GNOME Foundation -// SPDX-License-Identifier: LGPL-2.1-or-later - -// A map between namespaces and base URLs for their online documentation -baseURLs = [ - [ 'GLib', 'https://docs.gtk.org/glib/' ], - [ 'GObject', 'https://docs.gtk.org/gobject/' ], - [ 'Gio', 'https://docs.gtk.org/gio/' ], - [ 'GdkPixbuf', 'https://docs.gtk.org/gdk-pixbuf/' ], - [ 'Mtk', 'https://mutter.gnome.org/mtk/' ], -] diff --git a/mutter/doc/reference/meson.build b/mutter/doc/reference/meson.build deleted file mode 100644 index 4b54d9f..0000000 --- a/mutter/doc/reference/meson.build +++ /dev/null @@ -1,28 +0,0 @@ -if not have_introspection - error('API reference requires introspection.') -endif - - -toml_conf = configuration_data() -toml_conf.set('version', libmutter_api_version) -toml_conf.set('vcs_tag', 'main') - -gidocgen = find_program('gi-docgen') - -gidocgen_common_args = [ - '--quiet', - '--no-namespace-dir', -] - -if get_option('werror') - gidocgen_common_args += ['--fatal-warnings'] -endif - -docs_dir = pkgdatadir / 'doc' - -subdir('cally') -subdir('clutter') -subdir('cogl') -subdir('cogl-pango') -subdir('meta') -subdir('mtk') \ No newline at end of file diff --git a/mutter/doc/reference/meta/logo.svg b/mutter/doc/reference/meta/logo.svg deleted file mode 120000 index ffdbeb4..0000000 --- a/mutter/doc/reference/meta/logo.svg +++ /dev/null @@ -1 +0,0 @@ -../../../logo.svg \ No newline at end of file diff --git a/mutter/doc/reference/meta/meson.build b/mutter/doc/reference/meta/meson.build deleted file mode 100644 index bff21c1..0000000 --- a/mutter/doc/reference/meta/meson.build +++ /dev/null @@ -1,36 +0,0 @@ - -meta_toml = configure_file( - input: 'meta.toml.in', - output: 'meta.toml', - configuration: toml_conf, - install: true, - install_dir: docs_dir / 'meta', -) - -custom_target('meta-doc', - input: [ meta_toml, libmutter_gir[0] ], - output: 'meta', - command: [ - gidocgen, - 'generate', - gidocgen_common_args, - '--add-include-path=@0@'.format(meson.current_build_dir() / '../../../mtk/mtk'), - '--add-include-path=@0@'.format(meson.current_build_dir() / '../../../clutter/clutter'), - '--add-include-path=@0@'.format(meson.current_build_dir() / '../../../cogl/cogl'), - '--add-include-path=@0@'.format(meson.current_build_dir() / '../../../cogl/cogl-pango'), - '--config=@INPUT0@', - '--output-dir=@OUTPUT@', - '--content-dir=@0@'.format(meson.current_source_dir()), - '@INPUT1@', - ], - depends: [ - libmutter_mtk_gir[0], - libmutter_clutter_gir[0], - libmutter_cally_gir[0], - libmutter_cogl_pango_gir[0], - libmutter_cogl_gir[0], - ], - build_by_default: true, - install: true, - install_dir: docs_dir, -) diff --git a/mutter/doc/reference/meta/meta.toml.in b/mutter/doc/reference/meta/meta.toml.in deleted file mode 100644 index 10eca48..0000000 --- a/mutter/doc/reference/meta/meta.toml.in +++ /dev/null @@ -1,47 +0,0 @@ -[library] -version = "@version@" -browse_url = "https://gitlab.gnome.org/GNOME/mutter/" -repository_url = "https://gitlab.gnome.org/GNOME/mutter.git" -website_url = "https://blogs.gnome.org/shell-dev/" -docs_url = "https://mutter.gnome.org/" -logo_url = "logo.svg" -authors = "Mutter Development Team" -license = "GPL-2.0-or-later" -description = "The Mutter display server, window manager and compositor library" -dependencies = [ "GObject-2.0" ] -related = [ "Gdk-3.0", "Gtk-3.0" ] -devhelp = true -search_index = true - - [dependencies."GObject-2.0"] - name = "GObject" - description = "The base type system library" - docs_url = "https://docs.gtk.org/gobject/" - - [related."Gdk-3.0"] - name = "Gdk" - description = "The GTK windowing system abstraction" - docs_url = "https://docs.gtk.org/gdk3/" - - [related."Gtk-3.0"] - name = "Gtk" - description = "The GTK toolkit" - docs_url = "https://docs.gtk.org/gtk3/" - -[theme] -name = "basic" -show_index_summary = true -show_class_hierarchy = true - -[source-location] -base_url = "https://gitlab.gnome.org/GNOME/mutter/-/blob/@vcs_tag@/" - -[extra] -# The same order will be used when generating the index -content_files = [ -] -content_images = [ - "logo.svg", -] -urlmap_file = "urlmap.js" - diff --git a/mutter/doc/reference/meta/urlmap.js b/mutter/doc/reference/meta/urlmap.js deleted file mode 100644 index 5866ed2..0000000 --- a/mutter/doc/reference/meta/urlmap.js +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2021 GNOME Foundation -// SPDX-License-Identifier: LGPL-2.1-or-later - -// A map between namespaces and base URLs for their online documentation -baseURLs = [ - [ 'GLib', 'https://docs.gtk.org/glib/' ], - [ 'GObject', 'https://docs.gtk.org/gobject/' ], - [ 'Gio', 'https://docs.gtk.org/gio/' ], - [ 'Mtk', 'https://mutter.gnome.org/mtk/' ], - [ 'Cogl', 'https://mutter.gnome.org/cogl/' ], - [ 'Clutter', 'https://mutter.gnome.org/clutter/' ], -] diff --git a/mutter/doc/reference/mtk/logo.svg b/mutter/doc/reference/mtk/logo.svg deleted file mode 120000 index ffdbeb4..0000000 --- a/mutter/doc/reference/mtk/logo.svg +++ /dev/null @@ -1 +0,0 @@ -../../../logo.svg \ No newline at end of file diff --git a/mutter/doc/reference/mtk/meson.build b/mutter/doc/reference/mtk/meson.build deleted file mode 100644 index 77c2518..0000000 --- a/mutter/doc/reference/mtk/meson.build +++ /dev/null @@ -1,24 +0,0 @@ -mtk_toml = configure_file( - input: 'mtk.toml.in', - output: 'mtk.toml', - configuration: toml_conf, - install: true, - install_dir: docs_dir / 'mtk', -) - -custom_target('mtk-doc', - input: [ mtk_toml, libmutter_mtk_gir[0] ], - output: 'mtk', - command: [ - gidocgen, - 'generate', - gidocgen_common_args, - '--config=@INPUT0@', - '--output-dir=@OUTPUT@', - '--content-dir=@0@'.format(meson.current_source_dir()), - '@INPUT1@', - ], - build_by_default: true, - install: true, - install_dir: docs_dir, -) diff --git a/mutter/doc/reference/mtk/mtk.toml.in b/mutter/doc/reference/mtk/mtk.toml.in deleted file mode 100644 index dfff81b..0000000 --- a/mutter/doc/reference/mtk/mtk.toml.in +++ /dev/null @@ -1,36 +0,0 @@ -[library] -version = "@version@" -browse_url = "https://gitlab.gnome.org/GNOME/mutter/" -repository_url = "https://gitlab.gnome.org/GNOME/mutter.git" -website_url = "https://blogs.gnome.org/shell-dev/" -docs_url = "https://mutter.gnome.org/" -logo_url = "logo.svg" -authors = "Mutter Development Team" -license = "GPL-2.0-or-later" -description = "Mutter Toolkit Private Library" -dependencies = [ "GObject-2.0" ] -devhelp = true -search_index = true - - [dependencies."GObject-2.0"] - name = "GObject" - description = "The base type system library" - docs_url = "https://docs.gtk.org/gobject/" - -[theme] -name = "basic" -show_index_summary = true -show_class_hierarchy = true - -[source-location] -base_url = "https://gitlab.gnome.org/GNOME/mutter/-/blob/@vcs_tag@/" - -[extra] -# The same order will be used when generating the index -content_files = [ -] -content_images = [ - "logo.svg", -] -urlmap_file = "urlmap.js" - diff --git a/mutter/doc/reference/mtk/urlmap.js b/mutter/doc/reference/mtk/urlmap.js deleted file mode 100644 index 82261e3..0000000 --- a/mutter/doc/reference/mtk/urlmap.js +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-FileCopyrightText: 2021 GNOME Foundation -// SPDX-License-Identifier: LGPL-2.1-or-later - -// A map between namespaces and base URLs for their online documentation -baseURLs = [ - [ 'GObject', 'https://docs.gtk.org/gobject/' ], -] diff --git a/mutter/doc/website/404.html b/mutter/doc/website/404.html deleted file mode 100644 index 0f3d52e..0000000 --- a/mutter/doc/website/404.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - Mutter - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

404

- -

Document Not Found

- -

The requested page could not be found. If you feel this is not normal, then you create an issue on the Gitlab.

- -

Go Back File an issue

- -
- - - - - - - diff --git a/mutter/doc/website/LICENSE b/mutter/doc/website/LICENSE deleted file mode 100644 index 0e259d4..0000000 --- a/mutter/doc/website/LICENSE +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. diff --git a/mutter/doc/website/README.md b/mutter/doc/website/README.md deleted file mode 100644 index 21d44e3..0000000 --- a/mutter/doc/website/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Mutter Website - -This is the website for the mutter window manager. Feel free to fix typos and -suggest changes by opening MRs against the appropriate [gitlab -module](https://gitlab.gnome.org/GNOME/mutter/-/tree/main/doc/website). diff --git a/mutter/doc/website/assets/404.png b/mutter/doc/website/assets/404.png deleted file mode 100644 index 3f59a49..0000000 Binary files a/mutter/doc/website/assets/404.png and /dev/null differ diff --git a/mutter/doc/website/assets/apple-touch-icon.png b/mutter/doc/website/assets/apple-touch-icon.png deleted file mode 100644 index e075aa8..0000000 Binary files a/mutter/doc/website/assets/apple-touch-icon.png and /dev/null differ diff --git a/mutter/doc/website/assets/apple-touch-icon.svg b/mutter/doc/website/assets/apple-touch-icon.svg deleted file mode 100644 index e97665d..0000000 --- a/mutter/doc/website/assets/apple-touch-icon.svg +++ /dev/null @@ -1,104 +0,0 @@ - -image/svg+xml diff --git a/mutter/doc/website/assets/card.png b/mutter/doc/website/assets/card.png deleted file mode 100644 index 6aace21..0000000 Binary files a/mutter/doc/website/assets/card.png and /dev/null differ diff --git a/mutter/doc/website/assets/card.svg b/mutter/doc/website/assets/card.svg deleted file mode 100644 index 4bd76d6..0000000 --- a/mutter/doc/website/assets/card.svg +++ /dev/null @@ -1,197 +0,0 @@ - -image/svg+xml diff --git a/mutter/doc/website/assets/favicon.png b/mutter/doc/website/assets/favicon.png deleted file mode 100644 index b36a071..0000000 Binary files a/mutter/doc/website/assets/favicon.png and /dev/null differ diff --git a/mutter/doc/website/assets/favicon.svg b/mutter/doc/website/assets/favicon.svg deleted file mode 100644 index 9c35a04..0000000 --- a/mutter/doc/website/assets/favicon.svg +++ /dev/null @@ -1,92 +0,0 @@ - - diff --git a/mutter/doc/website/assets/page-logo-i.svg b/mutter/doc/website/assets/page-logo-i.svg deleted file mode 100644 index 0fc2740..0000000 --- a/mutter/doc/website/assets/page-logo-i.svg +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/mutter/doc/website/assets/page-logo.svg b/mutter/doc/website/assets/page-logo.svg deleted file mode 100644 index 3832ec1..0000000 --- a/mutter/doc/website/assets/page-logo.svg +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/mutter/doc/website/assets/splash-dark.png b/mutter/doc/website/assets/splash-dark.png deleted file mode 100644 index 7fbcd44..0000000 Binary files a/mutter/doc/website/assets/splash-dark.png and /dev/null differ diff --git a/mutter/doc/website/assets/splash.png b/mutter/doc/website/assets/splash.png deleted file mode 100644 index 2dda86a..0000000 Binary files a/mutter/doc/website/assets/splash.png and /dev/null differ diff --git a/mutter/doc/website/fonts/Inter.var.woff2 b/mutter/doc/website/fonts/Inter.var.woff2 deleted file mode 100644 index 365eedc..0000000 Binary files a/mutter/doc/website/fonts/Inter.var.woff2 and /dev/null differ diff --git a/mutter/doc/website/index.html b/mutter/doc/website/index.html deleted file mode 100644 index fcced8e..0000000 --- a/mutter/doc/website/index.html +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - - - - - Mutter - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - -

Mutter is a Wayland display server and X11 window manager and compositor library.

- -

When used as a Wayland display server, it runs on top of KMS and libinput. It implements the compositor side of - the Wayland core protocol as well as various protocol extensions. It also has functionality related to running X11 - applications using Xwayland. - When used on top of Xorg it acts as a X11 window manager and compositing manager. It contains functionality - related to, among other things, window management, window compositing, focus tracking, workspace management, - keybindings and monitor configuration.

- -

Mutter is used by, for example, GNOME Shell, the GNOME - core user interface, and by Gala, elementary OS’s window - manager. It can also be run standalone, using the command “mutter”, but just running plain mutter is only intended - for debugging purposes.

- -

Contributing

- -

Mutter is Free Software and is developed in the open. -

- -

To contribute, open merge requests at https://gitlab.gnome.org/GNOME/mutter.

- -

It can be useful to first look at the GNOME Handbook - and the documentation and API references below first. - -

Documentation

- - - -

API Reference

- - - - - - - -
- - - - - - - diff --git a/mutter/doc/website/style.css b/mutter/doc/website/style.css deleted file mode 100644 index 3cbdd43..0000000 --- a/mutter/doc/website/style.css +++ /dev/null @@ -1,527 +0,0 @@ -/* - - Mutter Website - ==================== - - shamelessly stolen CSS from systemd - https://github.com/systemd/systemd/tree/main/docs - -*/ - -/* GNOME Color Palette */ -:root { - --rounded-corner: 12px; - --blue1: rgb(153,193,241); - --blue2: rgb(98,160,234); - --blue3: rgb(53,132,228); - --blue4: rgb(28,113,216); - --blue5: rgb(26,95,180); - --green1: rgb(143,240,164); - --green2: rgb(87,227,137); - --green3: rgb(51,209,122); - --green4: rgb(46,194,126); - --green5: rgb(38,162,105); - --yellow1: rgb(249,240,107); - --yellow2: rgb(248,228,92); - --yellow3: rgb(246,211,45); - --yellow4: rgb(245,194,17); - --yellow5: rgb(229,165,10); - --orange1: rgb(255,190,111); - --orange2: rgb(255,163,72); - --orange3: rgb(255,120,0); - --orange4: rgb(230,97,0); - --orange5: rgb(198,70,0); - --red1: rgb(246,97,81); - --red2: rgb(237,51,59); - --red3: rgb(224,27,36); - --red4: rgb(192,28,40); - --red5: rgb(165,29,45); - --purple1: rgb(220,138,221); - --purple2: rgb(192,97,203); - --purple3: rgb(145,65,172); - --purple4: rgb(129,61,156); - --purple5: rgb(97,53,131); - --brown1: rgb(205,171,143); - --brown2: rgb(181,131,90); - --brown3: rgb(152,106,68); - --brown4: rgb(134,94,60); - --brown5: rgb(99,69,44); - --light1: rgb(255,255,255); - --light2: rgb(246,245,244); - --light3: rgb(222,221,218); - --light4: rgb(192,191,188); - --light5: rgb(154,153,150); - --dark1: rgb(119,118,123); - --dark2: rgb(94,92,100); - --dark3: rgb(61,56,70); - --dark4: rgb(36,31,49); - --dark5: rgb(0,0,0); - --primary-color: #ff7800; /* Set your project color */ - --borders: var(--light3); - --br: 9px; - --fg-color: #241f31; - --bg-color: #f6f5f4; - --term-fg: var(--dark3); - --term-bg: var(--light1); - --term-br: 9px; - --hovertile: #fff; -} - -@media (prefers-color-scheme: dark) { - :root { - color-scheme: dark; - --primary-color: #dc8add; - --fg-color: #eee; - --bg-color: #29384c; - --term-fg: var(--light1); - --term-bg: var(--dark4); - --hovertile: rgba(0,0,0,0.2); - } -} - -/* Typography */ - -@font-face { - font-family: 'Inter Var'; - font-weight: 100 900; - font-display: swap; - font-style: oblique italic 0deg 10deg; - src: url("fonts/Inter.var.woff2?v=3.19") format("woff2"); -} - -* { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} -html, body { - margin: 0; - padding: 0; - font-size: 16px; - font-family: "Inter Var", sans-serif; - font-weight: 400; - line-height: 1.6; - scroll-behavior: smooth; -} -body { - color: var(--fg-color); - background-color: var(--bg-color); - /* ⇩⇩ put footer at the bottom for short pages, such as the 404 ⇩⇩ */ - display: grid; - min-height: 100vh; - grid-template-rows: auto minmax(auto,1fr) auto; /* header, stuff, footer */ -} -h1, h2, h3, h4, h5, h6 { - margin: 3rem 0 1rem; - font-weight: 600; - line-height: 1.25; - font-variation-settings: "wght" 600; /* needed for webkit */ -} - -h1 { - font-size: 1.5rem; - font-weight: 100; - font-style: normal; - margin: 3rem 0 1rem; -} - -@media screen and (min-width: 650px) { - h1 { - font-size: 1.6rem; - } -} -h2 { - font-size: 1.2rem; -} - - - -a { - font-weight: 600; - text-decoration: none; - color: var(--primary-color); - cursor: pointer; - font-variation-settings: "wght" 600; /* needed for webkit */ -} -a:hover { - text-decoration: underline; -} -b { - font-weight: 600; -} -small { - color: #777; -} -hr { - margin: 3rem auto 4rem; - width: 40%; - opacity: 40%; -} - -img { - display: block; - margin: 2rem auto; - max-width: 100%; - } - img.full, picture.full img { width: 100%; } - img.pixels, picture.pixels img { - image-rendering: crisp-edges; /* older firefox browsers */ - image-rendering: pixelated; - } - - -/* Layout */ -.container { - width: 80%; - margin-left: auto; - margin-right: auto; - max-width: 720px; -} - -/* Singletons */ -#logo { - display: block; - width: 251px; height: 26px; - background: url('assets/page-logo.svg') no-repeat center; - padding: 5rem 0 3rem; - margin: 0 auto; - position: relative; -} - #logo a { - display: block; - position: absolute; - top: 0; left: 0; right: 0; bottom: 0; - color: rgba(0,0,0,0); /* make text transparent */ - cursor: pointer; - } -.page-logo > img { - margin: 0 auto; -} - - @media (prefers-color-scheme: dark) { - #logo { - background-image: url('assets/page-logo-i.svg'); - } - } - -.brand-white { - background-color: #fff; -} - -.brand-green { - background-color: #30D475; -} - -.brand-black { - background-color: #201A26; - color: white; -} - -.page-link::after { - content: " ➜"; -} - - -/* Footer */ -footer { - text-align: center; - padding: 3em 0 3em; - font-size: 1em; - margin-top: 4rem; -} - -/* Make tables vertically aligned to the top */ -tbody td { - vertical-align: top; -} - -/* Github Code Highlighting */ -.highlight table td { padding: 5px; } -.highlight table pre { margin: 0; } -.highlight .cm { - color: #999988; - font-style: italic; -} -.highlight .cp { - color: #999999; - font-weight: bold; -} -.highlight .c1 { - color: #999988; - font-style: italic; -} -.highlight .cs { - color: #999999; - font-weight: bold; - font-style: italic; -} -.highlight .c, .highlight .ch, .highlight .cd, .highlight .cpf { - color: #999988; - font-style: italic; -} -.highlight .err { - color: #a61717; - background-color: #e3d2d2; -} -.highlight .gd { - color: #000000; - background-color: #ffdddd; -} -.highlight .ge { - color: #000000; - font-style: italic; -} -.highlight .gr { - color: #aa0000; -} -.highlight .gh { - color: #999999; -} -.highlight .gi { - color: #000000; - background-color: #ddffdd; -} -.highlight .go { - color: #888888; -} -.highlight .gp { - color: #555555; -} -.highlight .gs { - font-weight: bold; -} -.highlight .gu { - color: #aaaaaa; -} -.highlight .gt { - color: #aa0000; -} -.highlight .kc { - color: #000000; - font-weight: bold; -} -.highlight .kd { - color: #000000; - font-weight: bold; -} -.highlight .kn { - color: #000000; - font-weight: bold; -} -.highlight .kp { - color: #000000; - font-weight: bold; -} -.highlight .kr { - color: #000000; - font-weight: bold; -} -.highlight .kt { - color: #445588; - font-weight: bold; -} -.highlight .k, .highlight .kv { - color: #000000; - font-weight: bold; -} -.highlight .mf { - color: #009999; -} -.highlight .mh { - color: #009999; -} -.highlight .il { - color: #009999; -} -.highlight .mi { - color: #009999; -} -.highlight .mo { - color: #009999; -} -.highlight .m, .highlight .mb, .highlight .mx { - color: #009999; -} -.highlight .sb { - color: #d14; -} -.highlight .sc { - color: #d14; -} -.highlight .sd { - color: #d14; -} -.highlight .s2 { - color: #d14; -} -.highlight .se { - color: #d14; -} -.highlight .sh { - color: #d14; -} -.highlight .si { - color: #d14; -} -.highlight .sx { - color: #d14; -} -.highlight .sr { - color: #009926; -} -.highlight .s1 { - color: #d14; -} -.highlight .ss { - color: #990073; -} -.highlight .s, .highlight .sa, .highlight .dl { - color: #d14; -} -.highlight .na { - color: #008080; -} -.highlight .bp { - color: #999999; -} -.highlight .nb { - color: #0086B3; -} -.highlight .nc { - color: #445588; - font-weight: bold; -} -.highlight .no { - color: #008080; -} -.highlight .nd { - color: #3c5d5d; - font-weight: bold; -} -.highlight .ni { - color: #800080; -} -.highlight .ne { - color: #990000; - font-weight: bold; -} -.highlight .nf, .highlight .fm { - color: #990000; - font-weight: bold; -} -.highlight .nl { - color: #990000; - font-weight: bold; -} -.highlight .nn { - color: #555555; -} -.highlight .nt { - color: #000080; -} -.highlight .vc { - color: #008080; -} -.highlight .vg { - color: #008080; -} -.highlight .vi { - color: #008080; -} -.highlight .nv, .highlight .vm { - color: #008080; -} -.highlight .ow { - color: #000000; - font-weight: bold; -} -.highlight .o { - color: #000000; - font-weight: bold; -} -.highlight .w { - color: #bbbbbb; -} -.highlight { -} - - -/* Code Blocks */ -.highlighter-rouge { - font-size: 80%; - line-height: normal; - padding: 2px 1rem; - border-radius: var(--term-br); - background-color: var(--term-bg); - max-width: 100vw; - overflow-x: auto; - margin: 1rem 0; -} - @media only screen and (max-device-width : 480px) { - /*mobile*/ - .highlighter-rouge { max-width: 80vw; } - } - -.highlighter-rouge * { -} - -/* Inline Code */ -code.highlighter-rouge { - padding: 2px 6px; - background-color: var(--term-bg); -} - -/* Buttons */ - -.dialog-buttons { - display: flex; - flex-direction: row; - align-items: baseline; - justify-content: space-between; - margin-top: 6rem; -} - -.inline-button { - display: inline-block; - font-weight: 900; - font-size: 90%; - padding: .4rem 1rem; - border-radius: var(--rounded-corner); - background-color: var(--term-bg); - color: var(--fg-color); -} - -/* Tiles */ - -ul.tiles { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); - list-style: none; - margin: 0; - padding: 0; - gap: 1rem; - grid-template-rows: masonry; -} - ul.tiles li { - padding: 1rem; - border-radius: var(--br); - transition: all 0.35s cubic-bezier(0.17, 0.89, 0.32, 1.28); - } - ul.tiles li:hover { - background: var(--hovertile); - box-shadow: 0 0 0 8px var(--hovertile); - } - ul.tiles h3 { - margin: 0; - color: var(--primary-color); - text-decoration: underline; - } - - ul.tiles a { - font-weight: 400; - font-variation-settings: "wght" 400; - display: block; - height: 100%; - text-decoration: none; - color: var(--fg-color); - } diff --git a/mutter/logo.svg b/mutter/logo.svg deleted file mode 100644 index bf4bfb6..0000000 --- a/mutter/logo.svg +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mutter/meson.build b/mutter/meson.build deleted file mode 100644 index 3bd61f5..0000000 --- a/mutter/meson.build +++ /dev/null @@ -1,767 +0,0 @@ -project('mutter', 'c', - version: '46.4', - meson_version: '>= 0.60.0', - license: 'GPLv2+' -) - -split_version = meson.project_version().split('.') - -# API version, bump each development cycle -libmutter_api_version = '14' - -mutter_srcdir = meson.current_source_dir() -mutter_builddir = meson.current_build_dir() - -# generic version requirements -lcms2_req = '>= 2.6' -colord_req = '>= 1.4.5' -fribidi_req = '>= 1.0.0' -glib_req = '>= 2.75.1' -gi_req = '>= 0.9.5' -graphene_req = '>= 1.10.2' -gtk3_req = '>= 3.19.8' -gtk4_req = '>= 4.0.0' -gdk_pixbuf_req = '>= 2.0' -pango_req = '>= 1.46.0' -cairo_req = '>= 1.10.0' -pangocairo_req = '>= 1.20' -pixman_req = '>= 0.42' -gsettings_desktop_schemas_req = '>= 40.alpha' -x11_req = '>= 1.7.0' -xcomposite_req = '>= 0.4' -xkbcommon_req = '>= 0.4.3' -xfixes_req = '>= 6' -xi_req = '>= 1.7.4' -xrandr_req = '>= 1.5.0' -libstartup_notification_req = '>= 0.7' -libcanberra_req = '>= 0.26' -libwacom_req = '>= 0.13' -atk_req = '>= 2.5.3' -harfbuzz_req = '>= 2.6' -libei_req = '>= 1.0.901' - -# optional version requirements -udev_req = '>= 228' -gudev_req = '>= 232' - -# wayland version requirements -wayland_server_req = '>= 1.22' -wayland_protocols_req = '>= 1.33' - -# native backend version requirements -libinput_req = '>= 1.19.0' -gbm_req = '>= 21.3' -libdrm_req = '>= 2.4.118' - -# screen cast version requirements -libpipewire_req = '>= 0.3.33' - -# profiler requirements -sysprof_req = '>= 3.37.2' - -gnome = import('gnome') -pkg = import('pkgconfig') -i18n = import('i18n') -fs = import('fs') -python = import('python') -cc = meson.get_compiler('c') - -add_project_link_arguments( - cc.get_supported_link_arguments( - # meson automatically adds -rpath to targets and strips them when they - # are installed. ld adds a RUNPATH tag for -rpath arguments by default. - # This makes ld add a RPATH tag instead (as it did some time ago). - # The reason why we want RPATH and not RUNPATH is that LD_LIBRARY_PATH - # takes precedence over RUNPATH but not over RPATH. Since we usually run - # development builds in jhbuild which sets up LD_LIBRARY_PATH this can - # result in wrong dependencies being picked up by the linker. - '-Wl,--disable-new-dtags', - ), - language : 'c', -) - -prefix = get_option('prefix') - -bindir = prefix / get_option('bindir') -datadir = prefix / get_option('datadir') -libdir = prefix / get_option('libdir') -libexecdir = prefix / get_option('libexecdir') -includedir = prefix / get_option('includedir') -sysconfdir = get_option('sysconfdir') - -pkgname = '@0@-@1@'.format(meson.project_name(), libmutter_api_version) - -pkgdatadir = datadir / pkgname -pkglibdir = libdir / pkgname -pkgincludedir = includedir / pkgname - -pcdir = libdir / 'pkgconfig' - -gettext_package = meson.project_name() -localedir = datadir / 'locale' - -libmutter_name = 'mutter-' + libmutter_api_version - -mutter_installed_tests_datadir = datadir / 'installed-tests' / libmutter_name -mutter_installed_tests_libexecdir = libexecdir / 'installed-tests' / libmutter_name - -m_dep = cc.find_library('m', required: true) -graphene_dep = dependency('graphene-gobject-1.0', version: graphene_req) -gdk_pixbuf_dep = dependency('gdk-pixbuf-2.0', version: gdk_pixbuf_req) -pango_dep = dependency('pango', version: pango_req) -cairo_dep = dependency('cairo', version: cairo_req) -pangocairo_dep = dependency('pangocairo', version: pangocairo_req) -pixman_dep = dependency('pixman-1', version: pixman_req) -fribidi_dep = dependency('fribidi', version: fribidi_req) -gsettings_desktop_schemas_dep = dependency('gsettings-desktop-schemas', - version: gsettings_desktop_schemas_req) -glib_dep = dependency('glib-2.0', version: glib_req) -gio_dep = dependency('gio-unix-2.0', version: glib_req) -gio_unix_dep = dependency('gio-unix-2.0', version: glib_req) -gobject_dep = dependency('gobject-2.0', version: glib_req) -gthread_dep = dependency('gobject-2.0', version: glib_req) -gmodule_no_export_dep = dependency('gmodule-no-export-2.0', version: glib_req) -gnome_settings_daemon_dep = dependency('gnome-settings-daemon', required: false) -xkbcommon_dep = dependency('xkbcommon', version: xkbcommon_req) -ice_dep = dependency('ice') -atk_dep = dependency('atk', version: atk_req) -dbus_dep = dependency('dbus-1') -colord_dep = dependency('colord', version: colord_req) -lcms2_dep = dependency('lcms2', version: lcms2_req) -harfbuzz_dep = dependency('harfbuzz', version: harfbuzz_req) -libeis_dep = dependency('libeis-1.0', version: libei_req) -libei_dep = dependency('libei-1.0', version: libei_req) - -have_wayland = get_option('wayland') -# For now always require X11 support -have_x11 = true -have_xwayland = get_option('xwayland') -have_x11_client = have_x11 or have_xwayland - -if have_xwayland and not have_wayland - error('XWayland support requires Wayland support enabled') -endif - -if not have_wayland and not have_x11 - error('A Wayland/X11 backend must be enabled') -endif - -if have_x11_client - gtk4_dep = dependency('gtk4', version: gtk4_req) - - x11_dep = dependency('x11', version: x11_req) - xcomposite_dep = dependency('xcomposite', version: xcomposite_req) - xcursor_dep = dependency('xcursor') - xdamage_dep = dependency('xdamage') - xext_dep = dependency('xext') - xfixes_dep = dependency('xfixes', version: xfixes_req) - xi_dep = dependency('xi', version: xi_req) - xtst_dep = dependency('xtst') - xkbfile_dep = dependency('xkbfile') - xkeyboard_config_dep = dependency('xkeyboard-config') - xkbcommon_x11_dep = dependency('xkbcommon-x11') - xrender_dep = dependency('xrender') - x11_xcb_dep = dependency('x11-xcb') - xrandr_dep = dependency('xrandr', version: xrandr_req) - xcb_randr_dep = dependency('xcb-randr') - xcb_res_dep = dependency('xcb-res') - xinerama_dep = dependency('xinerama') - xau_dep = dependency('xau') -endif - -use_libdisplay_info = get_option('libdisplay_info') -libdisplay_info_dep = dependency('libdisplay-info', required: use_libdisplay_info) -have_libdisplay_info = libdisplay_info_dep.found() - -have_gnome_desktop = get_option('libgnome_desktop') -if have_gnome_desktop - gnome_desktop_dep = dependency('gnome-desktop-4') -endif - -have_sound_player = get_option('sound_player') -if have_sound_player - libcanberra_dep = dependency('libcanberra', version: libcanberra_req) -endif - -have_gl = get_option('opengl') -if have_gl - gl_dep = dependency('gl') - gl_libname = get_option('opengl_libname') -endif - -have_egl = get_option('egl') -if have_egl - egl_dep = dependency('egl') -endif - -have_glx = get_option('glx') and have_x11_client -if have_glx - if not have_gl - error('GLX support requires OpenGL to be enabled') - endif -endif - -have_egl_xlib = have_egl and have_x11_client - -have_gles2 = get_option('gles2') -if have_gles2 - gles2_dep = dependency('glesv2') - gles2_libname = get_option('gles2_libname') - - if not have_egl - error('GLESv2 support requires EGL to be enabled') - endif -endif - -if not have_gl and not have_gles2 - error('Neither GLES2 or OpenGL was enabled') -endif - -if have_wayland - wayland_server_dep = dependency('wayland-server', version: wayland_server_req) - wayland_client_dep = dependency('wayland-client', version: wayland_server_req) - wayland_cursor_dep = dependency('wayland-cursor') - wayland_protocols_dep = dependency('wayland-protocols', - version: wayland_protocols_req) - wayland_egl_dep = dependency('wayland-egl') - - if not have_egl - error('Wayland support requires EGL to be enabled') - endif -endif - -have_libgudev = get_option('udev') -if have_libgudev - libudev_dep = dependency('libudev', version: udev_req) - gudev_dep = dependency('gudev-1.0', version: gudev_req) - udev_dep = dependency('udev') - - udev_dir = get_option('udev_dir') - if udev_dir == '' - udev_dir = udev_dep.get_variable('udevdir') - endif -endif - -have_libsystemd = get_option('systemd') -libsystemd_dep = dependency('libsystemd', required: have_libsystemd) - -have_native_backend = get_option('native_backend') -if have_native_backend - libgbm_dep = dependency('gbm', version: gbm_req) - libinput_dep = dependency('libinput', version: libinput_req) - - if libsystemd_dep.found() - logind_provider_dep = libsystemd_dep - else - logind_provider_dep = dependency('libelogind') - endif - - if not have_egl - error('The native backend requires EGL to be enabled') - endif - - if not have_gles2 - error('The native backend requires GLESv2 to be enabled') - endif - - if not have_libgudev - error('The native backend requires udev to be enabled') - endif -endif - -if have_wayland or have_native_backend - libdrm_dep = dependency('libdrm', version: libdrm_req) -endif - -have_egl_device = get_option('egl_device') - -have_wayland_eglstream = get_option('wayland_eglstream') -if have_wayland_eglstream - wayland_eglstream_protocols_dep = dependency('wayland-eglstream-protocols') - dl_dep = cc.find_library('dl', required: true) - - if not have_wayland - error('Wayland EGLStream support requires Wayland to be enabled') - endif -endif - -have_sm = get_option('sm') -if have_sm - sm_dep = dependency('sm') -endif - -have_libwacom = get_option('libwacom') -if have_libwacom - libwacom_dep = dependency('libwacom', version: libwacom_req) -endif - -have_pango_ft2 = get_option('pango_ft2') -if have_pango_ft2 - pangoft2_dep = dependency('pangoft2') -endif - -have_startup_notification = get_option('startup_notification') -if have_startup_notification - if have_x11_client - libstartup_notification_dep = dependency('libstartup-notification-1.0', - version: libstartup_notification_req) - else - error('startup_notification requires X11 or Xwayland to be enabled') - endif -endif - -have_remote_desktop = get_option('remote_desktop') -if have_remote_desktop - libpipewire_dep = dependency('libpipewire-0.3', version: libpipewire_req) -endif - -have_introspection = get_option('introspection') -if have_introspection - gobject_introspection_dep = dependency('gobject-introspection-1.0', version: gi_req) - - introspection_args = [ - '--quiet', - '-U_GNU_SOURCE', - ] - - introspection_common = { - 'install_dir_gir': pkglibdir, - 'install_dir_typelib': pkglibdir, - 'install': true, - 'fatal_warnings': get_option('werror'), - } -endif - -# Check for timerfd_create(2) -have_timerfd = cc.links(''' -#include -#include -#include -int main (int argc, char ** argv) { - struct itimerspec ts = {{0}}; - int fd = timerfd_create (CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); - timerfd_settime (fd, TFD_TIMER_ABSTIME, &ts, NULL); - return 0; -} -''', name : 'timerfd_create(2) system call') - -have_malloc_trim = meson.get_compiler('c').has_function('malloc_trim') - -have_documentation = get_option('docs') -have_tests = get_option('tests') -have_core_tests = false -have_cogl_tests = false -have_clutter_tests = false -have_native_tests = false -have_kvm_tests = false -have_tty_tests = false -have_installed_tests = false - -if have_tests - gtk3_dep = dependency('gtk+-3.0', version: gtk3_req) - dbusmock_dep = python.find_installation('python3', modules: ['dbusmock'], required: false) - - have_core_tests = get_option('core_tests') - if have_core_tests - if not have_wayland - error('Tests require Wayland to be enabled') - endif - if not have_x11_client - error('Tests requires an X11 client') - endif - if not dbusmock_dep.found() - error('Tests require python-dbusmock') - endif - endif - have_native_tests = get_option('native_tests') - if have_native_tests - if not have_native_backend - error('Native tests require the native backend') - endif - if not have_remote_desktop - error('Native tests require remote desktop') - endif - endif - have_kvm_tests = get_option('kvm_tests') - if have_kvm_tests - if not have_native_backend - error('KVM tests need the native backend tests') - endif - if host_machine.cpu_family() != 'x86_64' - error('KVM tests are only supported on x86_64') - endif - endif - have_tty_tests = get_option('tty_tests') - if have_tty_tests - if not have_native_backend - error('TTY tests need the native backend tests') - endif - endif - - have_cogl_tests = get_option('cogl_tests') - have_clutter_tests = get_option('clutter_tests') - have_installed_tests = get_option('installed_tests') - - meta_dbus_runner = find_program('src/tests/meta-dbus-runner.py') - default_test_wrappers = [ - meta_dbus_runner, - '--', - ] - - if get_option('catch') - catch = find_program('catch') - default_test_wrappers += [ - catch, - ] - endif - - add_test_setup('default', - is_default: true, - exe_wrapper: default_test_wrappers, - ) - - add_test_setup('plain') - - xvfb = find_program('xvfb-run') - xvfb_args = [ - '-a', - '-s', - '+iglx -noreset', - ] - xvfb_command = [xvfb] + xvfb_args - - add_test_setup('CI', - env: [ - 'MUTTER_DEBUG_DUMMY_MODE_SPECS=800x600@10.0', - ], - exe_wrapper: [ - default_test_wrappers, - xvfb_command, - ], - timeout_multiplier: 10, - ) -endif - -have_profiler = get_option('profiler') -if have_profiler - # libsysprof-capture support - libsysprof_capture_dep = dependency('sysprof-capture-4', - required: true, - default_options: [ - 'examples=false', - 'gtk=false', - 'tests=false', - 'tools=false', - 'libsysprof=false', - 'sysprofd=none', - 'help=false', - ], - fallback: ['sysprof', 'libsysprof_capture_dep'], - version: sysprof_req, - ) - - if libsysprof_capture_dep.type_name() == 'pkgconfig' - sysprof_dep = dependency('sysprof-6', 'sysprof-4') - sysprof_dbus_interfaces_dir = sysprof_dep.get_variable('datadir') / 'dbus-1' / 'interfaces' - else - sysprof_dbus_interfaces_dir = mutter_srcdir / 'subprojects' / 'sysprof' / 'src' - endif -endif - -required_functions = [ - 'ffs', - 'clz', - 'memmem', -] -foreach function : required_functions - if not cc.has_function(function) - error('Required function ' + function + ' missing') - endif -endforeach - -if host_machine.cpu_family() == 'x86' - add_project_arguments('-ffloat-store', language: 'c') -endif -add_project_arguments('-D_GNU_SOURCE', language: 'c') - -buildtype = get_option('buildtype') -if buildtype != 'plain' - mutter_c_args = [ - '-fno-omit-frame-pointer', - '-mno-omit-leaf-frame-pointer', - '-fno-strict-aliasing', - '-Wpointer-arith', - '-Wmissing-declarations', - '-Wformat=2', - '-Wstrict-prototypes', - '-Wmissing-prototypes', - '-Wnested-externs', - '-Wold-style-definition', - '-Wundef', - '-Wunused', - '-Wcast-align', - '-Wmissing-noreturn', - '-Wmissing-format-attribute', - '-Wmissing-include-dirs', - '-Wlogical-op', - '-Wignored-qualifiers', - '-Werror=redundant-decls', - '-Werror=implicit', - '-Werror=nonnull', - '-Werror=init-self', - '-Werror=main', - '-Werror=missing-braces', - '-Werror=sequence-point', - '-Werror=return-type', - '-Werror=trigraphs', - '-Werror=array-bounds', - '-Werror=write-strings', - '-Werror=address', - '-Werror=int-to-pointer-cast', - '-Werror=pointer-to-int-cast', - '-Werror=empty-body', - '-Werror=write-strings', - '-Werror=strict-aliasing', - '-Wno-sign-compare', - '-Wno-cast-function-type', - '-Wno-unused-parameter', - '-Wno-missing-field-initializers', - '-Wno-type-limits', - ] - - if get_option('debug') - mutter_c_args += [ - '-DG_ENABLE_DEBUG', - ] - endif - - supported_mutter_c_args = cc.get_supported_arguments(mutter_c_args) - add_project_arguments(supported_mutter_c_args, language: 'c') -endif - -cc.compiles('void main (void) { __builtin_ffsl (0); __builtin_popcountl (0); }') - -have_eventfd = cc.has_header('sys/eventfd.h') - -cdata = configuration_data() -cdata.set_quoted('GETTEXT_PACKAGE', gettext_package) -cdata.set_quoted('VERSION', meson.project_version()) -cdata.set_quoted('PACKAGE_NAME', meson.project_name()) -cdata.set_quoted('PACKAGE_VERSION', meson.project_version()) - -cdata.set('HAVE_EGL', have_egl) -cdata.set('HAVE_GLX', have_glx) -cdata.set('HAVE_EGL_PLATFORM_XLIB', have_egl_xlib) -cdata.set('HAVE_GL', have_gl) -cdata.set('HAVE_GLES2', have_gles2) -cdata.set('HAVE_WAYLAND', have_wayland) -cdata.set('HAVE_XWAYLAND', have_xwayland) -cdata.set('HAVE_X11', have_x11) -cdata.set('HAVE_X11_CLIENT', have_x11_client) -cdata.set('HAVE_LIBSYSTEMD', have_libsystemd) -cdata.set('HAVE_NATIVE_BACKEND', have_native_backend) -cdata.set('HAVE_REMOTE_DESKTOP', have_remote_desktop) -cdata.set('HAVE_GNOME_DESKTOP', have_gnome_desktop) -cdata.set('HAVE_SOUND_PLAYER', have_sound_player) -cdata.set('HAVE_EGL_DEVICE', have_egl_device) -cdata.set('HAVE_WAYLAND_EGLSTREAM', have_wayland_eglstream) -cdata.set('HAVE_LIBGUDEV', have_libgudev) -cdata.set('HAVE_LIBWACOM', have_libwacom) -cdata.set('HAVE_SM', have_sm) -cdata.set('HAVE_STARTUP_NOTIFICATION', have_startup_notification) -cdata.set('HAVE_INTROSPECTION', have_introspection) -cdata.set('HAVE_PROFILER', have_profiler) -cdata.set('HAVE_LIBDISPLAY_INFO', have_libdisplay_info) -cdata.set('HAVE_PANGO_FT2', have_pango_ft2) -cdata.set('HAVE_TIMERFD', have_timerfd) -cdata.set('HAVE_MALLOC_TRIM', have_malloc_trim) -cdata.set('HAVE_EVENTFD', have_eventfd) - -if have_x11_client - xkb_base = xkeyboard_config_dep.get_variable('xkb_base') - cdata.set_quoted('XKB_BASE', xkb_base) -endif - -if cc.has_header_symbol('sys/prctl.h', 'prctl') - cdata.set('HAVE_SYS_PRCTL', 1) -endif - -have_xwayland_initfd = false -have_xwayland_listenfd = false -have_xwayland_terminate_delay = false -have_xwayland_byte_swapped_clients = false -have_xwayland_enable_ei_portal = false -if have_xwayland - xwayland_dep = dependency('xwayland', required: false) - - xwayland_path = get_option('xwayland_path') - if xwayland_path == '' - if xwayland_dep.found() - xwayland_path = xwayland_dep.get_variable('xwayland') - else - xwayland_path = find_program('Xwayland').full_path() - endif - endif - cdata.set_quoted('XWAYLAND_PATH', xwayland_path) - - # For Xwayland authority file generation. - if cc.has_header_symbol('sys/random.h', 'getrandom') - cdata.set('HAVE_SYS_RANDOM', 1) - elif cc.has_header_symbol('linux/random.h', 'getrandom') - cdata.set('HAVE_LINUX_RANDOM', 1) - else - error('Required function getrandom not found') - endif - - # For Xwayland -initfd usage - use_initfd = get_option('xwayland_initfd') - if xwayland_dep.found() - xwayland_supports_initfd = xwayland_dep.get_variable('have_initfd') == 'true' - else - xwayland_options = run_command(xwayland_path, '-help', check: false) - xwayland_supports_initfd = xwayland_options.stderr().contains('-initfd') - endif - - if use_initfd.auto() - have_xwayland_initfd = xwayland_supports_initfd - else - have_xwayland_initfd = use_initfd.enabled() - if have_xwayland_initfd and not xwayland_supports_initfd - error('XWayland -initfd support requested but not available') - endif - endif - - if (have_xwayland_initfd) - cdata.set('HAVE_XWAYLAND_INITFD', 1) - endif - - # For Xwayland -listenfd usage - if xwayland_dep.found() - have_xwayland_listenfd = xwayland_dep.get_variable('have_listenfd') == 'true' - endif - - if (have_xwayland_listenfd) - cdata.set('HAVE_XWAYLAND_LISTENFD', 1) - endif - - # For Xwayland -listenfd usage - if xwayland_dep.found() - have_xwayland_terminate_delay = xwayland_dep.get_variable('have_terminate_delay') == 'true' - endif - - if (have_xwayland_terminate_delay) - cdata.set('HAVE_XWAYLAND_TERMINATE_DELAY', 1) - endif - - # For Xwayland +/-byteswappedclients usage - if xwayland_dep.found() - have_xwayland_byte_swapped_clients = xwayland_dep.get_variable('have_byteswappedclients', - default_value: 'false') == 'true' - endif - - if (have_xwayland_byte_swapped_clients) - cdata.set('HAVE_XWAYLAND_BYTE_SWAPPED_CLIENTS', 1) - endif - - # For Xwayland -enable-portal usage - if xwayland_dep.found() - have_xwayland_enable_ei_portal = xwayland_dep.get_variable('have_enable_ei_portal', - default_value: 'false') == 'true' - endif - - if (have_xwayland_enable_ei_portal) - cdata.set('HAVE_XWAYLAND_ENABLE_EI_PORTAL', 1) - endif -endif - -optional_functions = [ - 'mkostemp', - 'posix_fallocate', - 'memfd_create', -] - -foreach function : optional_functions - if cc.has_function(function) - cdata.set('HAVE_' + function.to_upper(), 1) - else - message('Optional function ' + function + ' missing') - endif -endforeach - -xwayland_grab_default_access_rules = get_option('xwayland_grab_default_access_rules') -cdata.set_quoted('XWAYLAND_GRAB_DEFAULT_ACCESS_RULES', - xwayland_grab_default_access_rules) - -cdata.set_quoted('MUTTER_PLUGIN_DIR', pkglibdir / 'plugins') -cdata.set_quoted('MUTTER_LOCALEDIR', localedir) -cdata.set_quoted('MUTTER_LIBEXECDIR', libexecdir) -cdata.set_quoted('MUTTER_PKGDATADIR', pkgdatadir) - -config_h = configure_file( - input: 'config.h.meson', - output: 'config.h', - configuration: cdata -) - -top_includepath = include_directories('.') - -subdir('mtk') -subdir('cogl') -subdir('clutter') -subdir('data') -subdir('tools') -subdir('src') -subdir('po') -subdir('doc/man') -if have_documentation - subdir('doc/reference') -endif - -gnome.post_install( - glib_compile_schemas: true, -) - -meson.add_dist_script('meson/check-version.py', meson.project_version(), 'NEWS') - -summary('prefix', prefix, section: 'Directories') -summary('libexecdir', libexecdir, section: 'Directories') -summary('pkgdatadir', pkgdatadir, section: 'Directories') - -summary('buildtype', get_option('buildtype'), section: 'Build Configuration') -summary('debug', get_option('debug'), section: 'Build Configuration') - -summary('OpenGL', have_gl, section: 'Rendering APIs') -summary('GLES2', have_gles2, section: 'Rendering APIs') -summary('EGL', have_egl, section: 'Rendering APIs') -summary('GLX', have_glx, section: 'Rendering APIs') - -summary('Wayland', have_wayland, section: 'Options') -summary('Wayland EGLStream', have_wayland_eglstream, section: 'Options') -summary('X11', have_x11, section: 'Options') -summary('XWayland', have_xwayland, section: 'Options') -summary('Native Backend', have_native_backend, section: 'Options') -summary('EGL Device', have_egl_device, section: 'Options') -summary('Remote desktop', have_remote_desktop, section: 'Options') -summary('libgnome-desktop', have_gnome_desktop, section: 'Options') -summary('libdisplay-info', have_libdisplay_info, section: 'Options') -summary('Sound player', have_sound_player, section: 'Options') -summary('gudev', have_libgudev, section: 'Options') -summary('Wacom', have_libwacom, section: 'Options') -summary('SM', have_sm, section: 'Options') -summary('Startup notification', have_startup_notification, section: 'Options') -summary('Introspection', have_introspection, section: 'Options') -summary('Documentation', have_documentation, section: 'Options') -summary('Profiler', have_profiler, section: 'Options') -summary('Xwayland initfd', have_xwayland_initfd, section: 'Options') -summary('Xwayland listenfd', have_xwayland_listenfd, section: 'Options') -summary('Xwayland terminate delay', have_xwayland_terminate_delay, section: 'Options') -summary('Xwayland byte-swapped clients', have_xwayland_byte_swapped_clients, section: 'Options') -summary('Xwayland enable EI portal', have_xwayland_enable_ei_portal, section: 'Options') - -summary('Enabled', have_tests, section: 'Tests') -summary('Core tests', have_core_tests, section: 'Tests') -summary('Cogl tests', have_cogl_tests, section: 'Tests') -summary('Clutter tests', have_clutter_tests, section: 'Tests') -summary('KVM tests', get_option('kvm_tests'), section: 'Tests') -summary('Installed tests', have_installed_tests, section: 'Tests') -summary('Coverage', get_option('b_coverage'), section: 'Tests') diff --git a/mutter/meson/check-version.py b/mutter/meson/check-version.py deleted file mode 100755 index 81750c9..0000000 --- a/mutter/meson/check-version.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python3 - -import os, sys -from pathlib import Path -import argparse, subprocess - -def check_version(version, file, type='news'): - if type == 'news': - line = file.open().readline() - ok = line.startswith(version) - print("{}: {}".format(file, "OK" if ok else "FAILED")) - if not ok: - raise Exception("{} does not start with {}".format(file, version)) - elif type == 'metainfo': - subprocess.run(['appstream-util', 'validate-version', file, version], - check=True) - else: - raise Exception('Not implemented') - -parser = argparse.ArgumentParser(description='Check release version information.') -parser.add_argument('--type', choices=['metainfo','news'], default='news') -parser.add_argument('version', help='the version to check for') -parser.add_argument('files', nargs='+', help='files to check') -args = parser.parse_args() - -distroot = os.environ.get('MESON_DIST_ROOT', './') - -try: - for file in args.files: - check_version(args.version, Path(distroot, file), args.type) -except: - sys.exit(1) diff --git a/mutter/meson_options.txt b/mutter/meson_options.txt deleted file mode 100644 index 158a3c1..0000000 --- a/mutter/meson_options.txt +++ /dev/null @@ -1,233 +0,0 @@ -option('opengl', - type: 'boolean', - value: true, - description: 'Enable OpenGL' -) - -option('opengl_libname', - type: 'string', - value: 'libGL.so.1', - description: 'OpenGL library file name' -) - -option('gles2_libname', - type: 'string', - value: 'libGLESv2.so.2', - description: 'GLESv2 library file name' -) - -option('gles2', - type: 'boolean', - value: true, - description: 'Enable GLES2 support' -) - -option('egl', - type: 'boolean', - value: true, - description: 'Enable EGL support' -) -option('glx', - type: 'boolean', - value: true, - description: 'Enable GLX support' -) - -option('wayland', - type: 'boolean', - value: true, - description: 'Enable Wayland support' -) - -option('xwayland', - type: 'boolean', - value: true, - description: 'Enable Xwayland support' -) - -option('systemd', - type: 'boolean', - value: true, - description: 'Enable systemd support' -) - -option('native_backend', - type: 'boolean', - value: true, - description: 'Enable the native backend' -) - -option('remote_desktop', - type: 'boolean', - value: true, - description: 'Enable remote desktop and screen cast support' -) - -option('libgnome_desktop', - type: 'boolean', - value: true, - description: 'Build with or without gnome-desktop' -) - -option('egl_device', - type: 'boolean', - value: false, - description: 'Enable EGLDevice and EGLStream renderer support' -) - -option('wayland_eglstream', - type: 'boolean', - value: false, - description: 'Enable Wayland EGLStream support client support' -) - -option('udev', - type: 'boolean', - value: true, - description: 'Enable udev support when using the X11 backend' -) - -option('udev_dir', - type: 'string', - value: '', - description: 'Absolute path of the udev base directory' -) - -option('libwacom', - type: 'boolean', - value: true, - description: 'Enable libwacom support' -) - -option('sound_player', - type: 'boolean', - value: true, - description: 'Enable sound player support using libcanberra', -) - -option('pango_ft2', - type: 'boolean', - value: true, - description: 'Enable PangoFt2 support' -) - -option('startup_notification', - type: 'boolean', - value: true, - description: 'Enable startup notification support' -) - -option('sm', - type: 'boolean', - value: true, - description: 'Enable X11 session management support' -) - -option('introspection', - type: 'boolean', - value: true, - description: 'Enable GObject introspection' -) - -option('docs', - type: 'boolean', - value: false, - description: 'Enable gi-docgen documentation' -) - -option('cogl_tests', - type: 'boolean', - value: true, - description: 'Enable cogl tests' -) - -option('clutter_tests', - type: 'boolean', - value: true, - description: 'Enable clutter tests' -) - -option('core_tests', - type: 'boolean', - value: true, - description: 'Enable mutter core tests' -) - -option('native_tests', - type: 'boolean', - value: true, - description: 'Enable mutter native backend tests' -) - -option('tests', - type: 'boolean', - value: true, - description: 'Enable tests globally. Specific test suites can be controlled with core_tests, clutter_tests, and cogl_tests' -) - -option('kvm_tests', - type: 'boolean', - value: false, - description: 'Enable running certain tests in a virtual machine with a custom built kernel' -) - -option('kvm_kernel_image', - type: 'string', - value: '', - description: 'Path to a Linux kernel image to be used for KVM testing' -) - -option('tty_tests', - type: 'boolean', - value: false, - description: 'Enable tests that must be run on a TTY (KMS tests without KVM)' -) - -option('profiler', - type: 'boolean', - value: true, - description: 'Enable Sysprof tracing' -) - -option('installed_tests', - type: 'boolean', - value: true, - description: 'Enable mutter installed tests' -) - -option('verbose', - type: 'boolean', - value: true, - description: 'Enable verbose logging ability' -) - -option('xwayland_path', - type: 'string', - value: '', - description: 'Path to Xwayland executable' -) - -option('xwayland_grab_default_access_rules', - type: 'string', - value: 'gnome-boxes,remote-viewer,virt-viewer,virt-manager,vinagre,vncviewer,Xephyr', - description: 'Comma delimited list of applications resources or class allowed to issue X11 grabs in Xwayland' -) - -option('xwayland_initfd', - type: 'feature', - value: 'auto', - description: 'Whether -initfd argument is passed to Xwayland to guarantee services (e.g. gsd-xsettings) startup before applications' -) - -option('catch', - type: 'boolean', - value: false, - description: 'Use catch to catch backtraces' -) - -option('libdisplay_info', - type: 'feature', - value: 'auto', - deprecated: {'true': 'enabled', 'false': 'disabled'}, - description: 'Build with or without libdisplay-info' -) diff --git a/mutter/mtk/meson.build b/mutter/mtk/meson.build deleted file mode 100644 index 894ae51..0000000 --- a/mutter/mtk/meson.build +++ /dev/null @@ -1,45 +0,0 @@ -mtk_includesubdir = pkgname / 'mtk' -mtk_includedir = includedir / mtk_includesubdir - -mtk_includepath = include_directories('.', 'mtk') -mtk_includes = [ - mtk_includepath, - top_includepath, -] - -mtk_c_args = [ - '-DMTK_SYSCONFDIR="@0@"'.format(prefix / sysconfdir), - '-DMTK_COMPILATION=1', - '-DG_LOG_DOMAIN="Mtk"', -] - -mtk_debug_c_args = [] -if buildtype != 'plain' - if not get_option('debug') - mtk_debug_c_args += [ - '-DG_DISABLE_ASSERT', - '-DG_DISABLE_CAST_CHECKS', - ] - endif -endif -mtk_debug_c_args = cc.get_supported_arguments(mtk_debug_c_args) -mtk_c_args += mtk_debug_c_args - -mtk_pkg_deps = [ - glib_dep, - gobject_dep, - gio_dep, - graphene_dep, - pixman_dep, -] - -if have_x11 - mtk_pkg_deps += x11_dep -endif - -mtk_deps = [ - mtk_pkg_deps, - m_dep -] - -subdir('mtk') diff --git a/mutter/mtk/mtk/meson.build b/mutter/mtk/mtk/meson.build deleted file mode 100644 index d63d7c1..0000000 --- a/mutter/mtk/mtk/meson.build +++ /dev/null @@ -1,90 +0,0 @@ -mtk_mtk_includesubdir = mtk_includesubdir / 'mtk' - -mtk_headers = [ - 'mtk.h', - 'mtk-macros.h', - 'mtk-rectangle.h', - 'mtk-region.h', -] - -mtk_sources = [ - 'mtk-rectangle.c', - 'mtk-region.c', -] - -if have_x11 - mtk_sources += 'mtk-x11-errors.c' - mtk_headers += [ - 'mtk-x11-errors.h', - 'mtk-x11.h', - ] -endif - -mtk_private_headers = [ -] - - -libmutter_mtk_name = 'mutter-mtk-' + libmutter_api_version -libmutter_mtk = shared_library(libmutter_mtk_name, - sources: [ - mtk_sources, - mtk_headers, - mtk_private_headers, - ], - version: '0.0.0', - soversion: 0, - c_args: mtk_c_args, - include_directories: mtk_includes, - dependencies: [mtk_deps], - gnu_symbol_visibility: 'hidden', - install_rpath: pkglibdir, - install_dir: pkglibdir, - install: true, -) -libmutter_mtk_dep = declare_dependency( - link_with: libmutter_mtk, - dependencies: mtk_deps, -) - -if have_introspection - mtk_introspection_args = introspection_args + [ - '-DMTK_SYSCONFDIR="@0@"'.format(prefix / sysconfdir), - '-DMTK_COMPILATION=1', - '-DG_LOG_DOMAIN="Mtk"' - ] - - libmutter_mtk_gir = gnome.generate_gir(libmutter_mtk, - sources: [ - mtk_sources, - mtk_headers, - ], - nsversion: libmutter_api_version, - namespace: 'Mtk', - export_packages: [libmutter_mtk_name], - includes: [ - 'GObject-2.0', - 'Graphene-1.0', - ], - extra_args: mtk_introspection_args + ['--c-include=mtk/mtk.h'], - kwargs: introspection_common, - ) - -endif - -install_headers(mtk_headers, - subdir: mtk_mtk_includesubdir) - - -pkg.generate(libmutter_mtk, - name: 'Mutter Toolkit', - filebase: libmutter_mtk_name, - description: 'Mutter Toolkit Private Library', - libraries: [m_dep], - subdirs: pkgname / 'mtk', - requires: [mtk_pkg_deps], - version: meson.project_version(), - variables: [ - 'apiversion=' + libmutter_api_version, - ], - install_dir: pcdir, -) diff --git a/mutter/mtk/mtk/mtk-macros.h b/mutter/mtk/mtk/mtk-macros.h deleted file mode 100644 index d147fde..0000000 --- a/mutter/mtk/mtk/mtk-macros.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Mtk - * - * A low-level base library. - * - * Copyright (C) 2023 Red Hat - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#if !defined(__MTK_H_INSIDE__) && !defined(MTK_COMPILATION) -#error "Only can be included directly." -#endif - -#define MTK_EXPORT __attribute__((visibility ("default"))) extern - -/* MTK_EXPORT_TEST should be used to export symbols that are exported only - * for testability purposes - */ -#define MTK_EXPORT_TEST MTK_EXPORT diff --git a/mutter/mtk/mtk/mtk-rectangle.c b/mutter/mtk/mtk/mtk-rectangle.c deleted file mode 100644 index 4f5927c..0000000 --- a/mutter/mtk/mtk/mtk-rectangle.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Mtk - * - * A low-level base library. - * - * Copyright (C) 2023 Red Hat - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include "config.h" - -#include "mtk/mtk-rectangle.h" - - -MtkRectangle * -mtk_rectangle_copy (const MtkRectangle *rect) -{ - return g_memdup2 (rect, sizeof (MtkRectangle)); -} - -void -mtk_rectangle_free (MtkRectangle *rect) -{ - g_free (rect); -} - -G_DEFINE_BOXED_TYPE (MtkRectangle, mtk_rectangle, - mtk_rectangle_copy, mtk_rectangle_free); - -/** - * mtk_rectangle_new: - * @x: X coordinate of the top left corner - * @y: Y coordinate of the top left corner - * @width: Width of the rectangle - * @height: Height of the rectangle - * - * Creates a new rectangle - */ -MtkRectangle * -mtk_rectangle_new (int x, - int y, - int width, - int height) -{ - MtkRectangle *rect; - - rect = g_new0 (MtkRectangle, 1); - rect->x = x; - rect->y = y; - rect->width = width; - rect->height = height; - - return rect; -} - -MtkRectangle * -mtk_rectangle_new_empty (void) -{ - return g_new0 (MtkRectangle, 1); -} - -/** - * mtk_rectangle_area: - * @rect: A rectangle - * - * Returns: The area of the rectangle - */ -int -mtk_rectangle_area (const MtkRectangle *rect) -{ - g_return_val_if_fail (rect != NULL, 0); - return rect->width * rect->height; -} - -/** - * mtk_rectangle_equal: - * @src1: The first rectangle - * @src2: The second rectangle - * - * Compares the two rectangles - * - * Returns: Whether the two rectangles are equal - */ -gboolean -mtk_rectangle_equal (const MtkRectangle *src1, - const MtkRectangle *src2) -{ - return ((src1->x == src2->x) && - (src1->y == src2->y) && - (src1->width == src2->width) && - (src1->height == src2->height)); -} - -/** - * mtk_rectangle_union: - * @rect1: a #MtkRectangle - * @rect2: another #MtkRectangle - * @dest: (out caller-allocates): an empty #MtkRectangle, to be filled - * with the coordinates of the bounding box. - * - * Computes the union of the two rectangles - */ -void -mtk_rectangle_union (const MtkRectangle *rect1, - const MtkRectangle *rect2, - MtkRectangle *dest) -{ - int dest_x, dest_y; - int dest_w, dest_h; - - dest_x = rect1->x; - dest_y = rect1->y; - dest_w = rect1->width; - dest_h = rect1->height; - - if (rect2->x < dest_x) - { - dest_w += dest_x - rect2->x; - dest_x = rect2->x; - } - if (rect2->y < dest_y) - { - dest_h += dest_y - rect2->y; - dest_y = rect2->y; - } - if (rect2->x + rect2->width > dest_x + dest_w) - dest_w = rect2->x + rect2->width - dest_x; - if (rect2->y + rect2->height > dest_y + dest_h) - dest_h = rect2->y + rect2->height - dest_y; - - dest->x = dest_x; - dest->y = dest_y; - dest->width = dest_w; - dest->height = dest_h; -} - -/** - * mtk_rectangle_intersect: - * @src1: a #MtkRectangle - * @src2: another #MtkRectangle - * @dest: (out caller-allocates): an empty #MtkRectangle, to be filled - * with the coordinates of the intersection. - * - * Find the intersection between the two rectangles - * - * Returns: TRUE is some intersection exists and is not degenerate, FALSE - * otherwise. - */ -gboolean -mtk_rectangle_intersect (const MtkRectangle *src1, - const MtkRectangle *src2, - MtkRectangle *dest) -{ - int dest_x, dest_y; - int dest_w, dest_h; - int return_val; - - g_return_val_if_fail (src1 != NULL, FALSE); - g_return_val_if_fail (src2 != NULL, FALSE); - g_return_val_if_fail (dest != NULL, FALSE); - - return_val = FALSE; - - dest_x = MAX (src1->x, src2->x); - dest_y = MAX (src1->y, src2->y); - dest_w = MIN (src1->x + src1->width, src2->x + src2->width) - dest_x; - dest_h = MIN (src1->y + src1->height, src2->y + src2->height) - dest_y; - - if (dest_w > 0 && dest_h > 0) - { - dest->x = dest_x; - dest->y = dest_y; - dest->width = dest_w; - dest->height = dest_h; - return_val = TRUE; - } - else - { - dest->width = 0; - dest->height = 0; - } - - return return_val; -} - -/** - * mtk_rectangle_overlap: - * @rect1: The first rectangle - * @rect2: The second rectangle - * - * Similar to [method@Rectangle.intersect] but doesn't provide - * the location of the intersection. - * - * Returns: Whether the two rectangles overlap - */ -gboolean -mtk_rectangle_overlap (const MtkRectangle *rect1, - const MtkRectangle *rect2) -{ - g_return_val_if_fail (rect1 != NULL, FALSE); - g_return_val_if_fail (rect2 != NULL, FALSE); - - return !((rect1->x + rect1->width <= rect2->x) || - (rect2->x + rect2->width <= rect1->x) || - (rect1->y + rect1->height <= rect2->y) || - (rect2->y + rect2->height <= rect1->y)); -} - -/** - * mtk_rectangle_vert_overlap: - * @rect1: The first rectangle - * @rect2: The second rectangle - * - * Similar to [method@Rectangle.overlap] but ignores the horizontal location. - * - * Returns: Whether the two rectangles overlap vertically - */ -gboolean -mtk_rectangle_vert_overlap (const MtkRectangle *rect1, - const MtkRectangle *rect2) -{ - return (rect1->y < rect2->y + rect2->height && - rect2->y < rect1->y + rect1->height); -} - -/** - * mtk_rectangle_horiz_overlap: - * @rect1: The first rectangle - * @rect2: The second rectangle - * - * Similar to [method@Rectangle.overlap] but ignores the vertical location. - * - * Returns: Whether the two rectangles overlap horizontally - */ -gboolean -mtk_rectangle_horiz_overlap (const MtkRectangle *rect1, - const MtkRectangle *rect2) -{ - return (rect1->x < rect2->x + rect2->width && - rect2->x < rect1->x + rect1->width); -} - -/** - * mtk_rectangle_could_fit_rect: - * @outer_rect: The outer rectangle - * @inner_rect: The inner rectangle - * - * Returns: Whether the inner rectangle could fit inside the outer one - */ -gboolean -mtk_rectangle_could_fit_rect (const MtkRectangle *outer_rect, - const MtkRectangle *inner_rect) -{ - return (outer_rect->width >= inner_rect->width && - outer_rect->height >= inner_rect->height); -} - -/** - * mtk_rectangle_contains_rect: - * @outer_rect: The outer rectangle - * @inner_rect: The inner rectangle - * - * Returns: Whether the outer rectangle contains the inner one - */ -gboolean -mtk_rectangle_contains_rect (const MtkRectangle *outer_rect, - const MtkRectangle *inner_rect) -{ - return - inner_rect->x >= outer_rect->x && - inner_rect->y >= outer_rect->y && - inner_rect->x + inner_rect->width <= outer_rect->x + outer_rect->width && - inner_rect->y + inner_rect->height <= outer_rect->y + outer_rect->height; -} - -/** - * mtk_rectangle_to_graphene_rect: - * @rect: A rectangle - * - * Returns: Return a graphene_rect_t created from `rect` - */ -graphene_rect_t -mtk_rectangle_to_graphene_rect (const MtkRectangle *rect) -{ - return (graphene_rect_t) { - .origin = { - .x = rect->x, - .y = rect->y - }, - .size = { - .width = rect->width, - .height = rect->height - } - }; -} - -/** - * mtk_rectangle_from_graphene_rect: - * @rect: A rectangle - * @rounding_strategy: The rounding strategy - * @dest: (out caller-allocates): an empty #MtkRectangle, to be filled - * with the coordinates of `rect`. - */ -void -mtk_rectangle_from_graphene_rect (const graphene_rect_t *rect, - MtkRoundingStrategy rounding_strategy, - MtkRectangle *dest) -{ - switch (rounding_strategy) - { - case MTK_ROUNDING_STRATEGY_SHRINK: - { - *dest = (MtkRectangle) { - .x = ceilf (rect->origin.x), - .y = ceilf (rect->origin.y), - .width = floorf (rect->size.width), - .height = floorf (rect->size.height), - }; - } - break; - case MTK_ROUNDING_STRATEGY_GROW: - { - graphene_rect_t clamped = *rect; - - graphene_rect_round_extents (&clamped, &clamped); - - *dest = (MtkRectangle) { - .x = clamped.origin.x, - .y = clamped.origin.y, - .width = clamped.size.width, - .height = clamped.size.height, - }; - } - break; - case MTK_ROUNDING_STRATEGY_ROUND: - { - *dest = (MtkRectangle) { - .x = roundf (rect->origin.x), - .y = roundf (rect->origin.y), - .width = roundf (rect->size.width), - .height = roundf (rect->size.height), - }; - } - } -} - -void -mtk_rectangle_crop_and_scale (const MtkRectangle *rect, - const graphene_rect_t *src_rect, - int dst_width, - int dst_height, - MtkRectangle *dest) -{ - graphene_rect_t tmp = GRAPHENE_RECT_INIT (rect->x, rect->y, - rect->width, rect->height); - - graphene_rect_scale (&tmp, - src_rect->size.width / dst_width, - src_rect->size.height / dst_height, - &tmp); - graphene_rect_offset (&tmp, src_rect->origin.x, src_rect->origin.y); - - mtk_rectangle_from_graphene_rect (&tmp, MTK_ROUNDING_STRATEGY_GROW, dest); -} - -void -mtk_rectangle_scale_double (const MtkRectangle *rect, - double scale, - MtkRoundingStrategy rounding_strategy, - MtkRectangle *dest) -{ - graphene_rect_t tmp = GRAPHENE_RECT_INIT (rect->x, rect->y, - rect->width, rect->height); - - graphene_rect_scale (&tmp, scale, scale, &tmp); - mtk_rectangle_from_graphene_rect (&tmp, rounding_strategy, dest); -} - -gboolean -mtk_rectangle_is_adjacent_to (const MtkRectangle *rect, - const MtkRectangle *other) -{ - int rect_x1 = rect->x; - int rect_y1 = rect->y; - int rect_x2 = rect->x + rect->width; - int rect_y2 = rect->y + rect->height; - int other_x1 = other->x; - int other_y1 = other->y; - int other_x2 = other->x + other->width; - int other_y2 = other->y + other->height; - - if ((rect_x1 == other_x2 || rect_x2 == other_x1) && - !(rect_y2 <= other_y1 || rect_y1 >= other_y2)) - return TRUE; - else if ((rect_y1 == other_y2 || rect_y2 == other_y1) && - !(rect_x2 <= other_x1 || rect_x1 >= other_x2)) - return TRUE; - else - return FALSE; -} diff --git a/mutter/mtk/mtk/mtk-rectangle.h b/mutter/mtk/mtk/mtk-rectangle.h deleted file mode 100644 index 1cb598f..0000000 --- a/mutter/mtk/mtk/mtk-rectangle.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Mtk - * - * A low-level base library. - * - * Copyright (C) 2023 Red Hat - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#include -#include - -#include "mtk/mtk-macros.h" - -#define MTK_TYPE_RECTANGLE (mtk_rectangle_get_type ()) - -typedef enum _MtkRoundingStrategy -{ - MTK_ROUNDING_STRATEGY_SHRINK, - MTK_ROUNDING_STRATEGY_GROW, - MTK_ROUNDING_STRATEGY_ROUND, -} MtkRoundingStrategy; - - -#define MTK_RECTANGLE_MAX_STACK_RECTS 256 - -#define MTK_RECTANGLE_CREATE_ARRAY_SCOPED(n_rects, rects) \ - g_autofree MtkRectangle *G_PASTE(__n, __LINE__) = NULL; \ - if (n_rects < MTK_RECTANGLE_MAX_STACK_RECTS) \ - rects = g_newa (MtkRectangle, n_rects); \ - else \ - rects = G_PASTE(__n, __LINE__) = g_new (MtkRectangle, n_rects); - -/** - * MtkRectangle: - * @x: X coordinate of the top-left corner - * @y: Y coordinate of the top-left corner - * @width: Width of the rectangle - * @height: Height of the rectangle - */ -struct _MtkRectangle -{ - int x; - int y; - int width; - int height; -}; - -typedef struct _MtkRectangle MtkRectangle; - -#define MTK_RECTANGLE_INIT(_x, _y, _width, _height) \ - (MtkRectangle) { \ - .x = (_x), \ - .y = (_y), \ - .width = (_width), \ - .height = (_height) \ - } - -MTK_EXPORT -GType mtk_rectangle_get_type (void); - -MTK_EXPORT -MtkRectangle * mtk_rectangle_copy (const MtkRectangle *rect); - -MTK_EXPORT -void mtk_rectangle_free (MtkRectangle *rect); - -/* Function to make initializing a rect with a single line of code easy */ -MTK_EXPORT -MtkRectangle * mtk_rectangle_new (int x, - int y, - int width, - int height); - -MTK_EXPORT -MtkRectangle * mtk_rectangle_new_empty (void); - -/* Basic comparison functions */ -MTK_EXPORT -int mtk_rectangle_area (const MtkRectangle *rect); - -MTK_EXPORT -gboolean mtk_rectangle_equal (const MtkRectangle *src1, - const MtkRectangle *src2); - -/* Find the bounding box of the union of two rectangles */ -MTK_EXPORT -void mtk_rectangle_union (const MtkRectangle *rect1, - const MtkRectangle *rect2, - MtkRectangle *dest); - -MTK_EXPORT -gboolean mtk_rectangle_intersect (const MtkRectangle *src1, - const MtkRectangle *src2, - MtkRectangle *dest); - -MTK_EXPORT -gboolean mtk_rectangle_overlap (const MtkRectangle *rect1, - const MtkRectangle *rect2); - -MTK_EXPORT -gboolean mtk_rectangle_vert_overlap (const MtkRectangle *rect1, - const MtkRectangle *rect2); - -MTK_EXPORT -gboolean mtk_rectangle_horiz_overlap (const MtkRectangle *rect1, - const MtkRectangle *rect2); - -MTK_EXPORT -gboolean mtk_rectangle_could_fit_rect (const MtkRectangle *outer_rect, - const MtkRectangle *inner_rect); - -MTK_EXPORT -gboolean mtk_rectangle_contains_rect (const MtkRectangle *outer_rect, - const MtkRectangle *inner_rect); - -MTK_EXPORT -graphene_rect_t mtk_rectangle_to_graphene_rect (const MtkRectangle *rect); - -MTK_EXPORT -void mtk_rectangle_from_graphene_rect (const graphene_rect_t *rect, - MtkRoundingStrategy rounding_strategy, - MtkRectangle *dest); - -MTK_EXPORT -void mtk_rectangle_crop_and_scale (const MtkRectangle *rect, - const graphene_rect_t *src_rect, - int dst_width, - int dst_height, - MtkRectangle *dest); - -MTK_EXPORT -void mtk_rectangle_scale_double (const MtkRectangle *rect, - double scale, - MtkRoundingStrategy rounding_strategy, - MtkRectangle *dest); - -MTK_EXPORT -gboolean mtk_rectangle_is_adjacent_to (const MtkRectangle *rect, - const MtkRectangle *other); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (MtkRectangle, mtk_rectangle_free) diff --git a/mutter/mtk/mtk/mtk-region.c b/mutter/mtk/mtk/mtk-region.c deleted file mode 100644 index 28905df..0000000 --- a/mutter/mtk/mtk/mtk-region.c +++ /dev/null @@ -1,618 +0,0 @@ -/* - * Mtk - * - * A low-level base library. - * - * Copyright (C) 2023 Red Hat - * - * The implementation is heavily inspired by cairo_region_t. - * - * 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 . - */ - -#include "config.h" - -#include - -#include "mtk/mtk-region.h" - -struct _MtkRegion -{ - pixman_region32_t inner_region; -}; - -/** - * mtk_region_ref: - * @region: A region - * - * Increases the reference count - * - * Returns: (transfer none): The region - */ -MtkRegion * -mtk_region_ref (MtkRegion *region) -{ - g_return_val_if_fail (region != NULL, NULL); - - return g_atomic_rc_box_acquire (region); -} - -static void -clear_region (gpointer data) -{ - MtkRegion *region = data; - - pixman_region32_fini (®ion->inner_region); -} - -void -mtk_region_unref (MtkRegion *region) -{ - g_return_if_fail (region != NULL); - - g_atomic_rc_box_release_full (region, clear_region); -} - -G_DEFINE_BOXED_TYPE (MtkRegion, mtk_region, - mtk_region_ref, mtk_region_unref); - -MtkRegion * -mtk_region_create (void) -{ - MtkRegion *region; - - region = g_atomic_rc_box_new0 (MtkRegion); - - pixman_region32_init (®ion->inner_region); - - return region; -} - - -/** - * mtk_region_copy: - * @region: The region to copy - * - * Returns: (transfer full): A copy of the passed region - */ -MtkRegion * -mtk_region_copy (const MtkRegion *region) -{ - g_autoptr (MtkRegion) copy = NULL; - - g_return_val_if_fail (region != NULL, NULL); - - copy = mtk_region_create (); - - if (!pixman_region32_copy (©->inner_region, - ®ion->inner_region)) - return NULL; - - return g_steal_pointer (©); -} - -gboolean -mtk_region_equal (const MtkRegion *region, - const MtkRegion *other) -{ - if (region == other) - return TRUE; - - if (region == NULL || other == NULL) - return FALSE; - - return pixman_region32_equal (®ion->inner_region, - &other->inner_region); -} - -gboolean -mtk_region_is_empty (const MtkRegion *region) -{ - g_return_val_if_fail (region != NULL, TRUE); - - return !pixman_region32_not_empty (®ion->inner_region); -} - -MtkRectangle -mtk_region_get_extents (const MtkRegion *region) -{ - pixman_box32_t *extents; - - g_return_val_if_fail (region != NULL, MTK_RECTANGLE_INIT (0, 0, 0, 0)); - - extents = pixman_region32_extents (®ion->inner_region); - return MTK_RECTANGLE_INIT (extents->x1, - extents->y1, - extents->x2 - extents->x1, - extents->y2 - extents->y1); -} - -int -mtk_region_num_rectangles (const MtkRegion *region) -{ - g_return_val_if_fail (region != NULL, 0); - - return pixman_region32_n_rects (®ion->inner_region); -} - -void -mtk_region_translate (MtkRegion *region, - int dx, - int dy) -{ - g_return_if_fail (region != NULL); - - pixman_region32_translate (®ion->inner_region, dx, dy); -} - -gboolean -mtk_region_contains_point (MtkRegion *region, - int x, - int y) -{ - g_return_val_if_fail (region != NULL, FALSE); - - return pixman_region32_contains_point (®ion->inner_region, x, y, NULL); -} - -void -mtk_region_union (MtkRegion *region, - const MtkRegion *other) -{ - g_return_if_fail (region != NULL); - g_return_if_fail (other != NULL); - - pixman_region32_union (®ion->inner_region, - ®ion->inner_region, - &other->inner_region); -} - -void -mtk_region_union_rectangle (MtkRegion *region, - const MtkRectangle *rect) -{ - pixman_region32_t pixman_region; - - g_return_if_fail (region != NULL); - g_return_if_fail (rect != NULL); - - pixman_region32_init_rect (&pixman_region, - rect->x, rect->y, - rect->width, rect->height); - pixman_region32_union (®ion->inner_region, - ®ion->inner_region, - &pixman_region); - pixman_region32_fini (&pixman_region); -} - -void -mtk_region_subtract (MtkRegion *region, - const MtkRegion *other) -{ - g_return_if_fail (region != NULL); - g_return_if_fail (other != NULL); - - pixman_region32_subtract (®ion->inner_region, - ®ion->inner_region, - &other->inner_region); -} - -void -mtk_region_subtract_rectangle (MtkRegion *region, - const MtkRectangle *rect) -{ - g_return_if_fail (region != NULL); - g_return_if_fail (rect != NULL); - - pixman_region32_t pixman_region; - pixman_region32_init_rect (&pixman_region, - rect->x, rect->y, - rect->width, rect->height); - - pixman_region32_subtract (®ion->inner_region, - ®ion->inner_region, - &pixman_region); - pixman_region32_fini (&pixman_region); -} - -void -mtk_region_intersect (MtkRegion *region, - const MtkRegion *other) -{ - g_return_if_fail (region != NULL); - g_return_if_fail (other != NULL); - - pixman_region32_intersect (®ion->inner_region, - ®ion->inner_region, - &other->inner_region); -} - -void -mtk_region_intersect_rectangle (MtkRegion *region, - const MtkRectangle *rect) -{ - pixman_region32_t pixman_region; - - g_return_if_fail (region != NULL); - - pixman_region32_init_rect (&pixman_region, - rect->x, rect->y, - rect->width, rect->height); - - pixman_region32_intersect (®ion->inner_region, - ®ion->inner_region, - &pixman_region); - pixman_region32_fini (&pixman_region); -} - -MtkRectangle -mtk_region_get_rectangle (const MtkRegion *region, - int nth) -{ - pixman_box32_t *box; - - g_return_val_if_fail (region != NULL, MTK_RECTANGLE_INIT (0, 0, 0, 0)); - - box = pixman_region32_rectangles (®ion->inner_region, NULL) + nth; - return MTK_RECTANGLE_INIT (box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); -} - -MtkRegion * -mtk_region_create_rectangle (const MtkRectangle *rect) -{ - MtkRegion *region; - g_return_val_if_fail (rect != NULL, NULL); - - region = g_atomic_rc_box_new0 (MtkRegion); - - pixman_region32_init_rect (®ion->inner_region, - rect->x, rect->y, - rect->width, rect->height); - return region; -} - -MtkRegion * -mtk_region_create_rectangles (const MtkRectangle *rects, - int n_rects) -{ - pixman_box32_t stack_boxes[512 * sizeof (int) / sizeof (pixman_box32_t)]; - pixman_box32_t *boxes = stack_boxes; - int i; - g_autoptr (MtkRegion) region = NULL; - - g_return_val_if_fail (rects != NULL, NULL); - g_return_val_if_fail (n_rects != 0, NULL); - - region = g_atomic_rc_box_new0 (MtkRegion); - - if (n_rects == 1) - { - pixman_region32_init_rect (®ion->inner_region, - rects->x, rects->y, - rects->width, rects->height); - - return g_steal_pointer (®ion); - } - - if (n_rects > sizeof (stack_boxes) / sizeof (stack_boxes[0])) - { - boxes = g_new0 (pixman_box32_t, n_rects); - if (G_UNLIKELY (boxes == NULL)) - return NULL; - } - - for (i = 0; i < n_rects; i++) - { - boxes[i].x1 = rects[i].x; - boxes[i].y1 = rects[i].y; - boxes[i].x2 = rects[i].x + rects[i].width; - boxes[i].y2 = rects[i].y + rects[i].height; - } - - i = pixman_region32_init_rects (®ion->inner_region, - boxes, n_rects); - - if (boxes != stack_boxes) - free (boxes); - - if (G_UNLIKELY (i == 0)) - return NULL; - - return g_steal_pointer (®ion); -} - -MtkRegionOverlap -mtk_region_contains_rectangle (const MtkRegion *region, - const MtkRectangle *rect) -{ - pixman_box32_t box; - pixman_region_overlap_t overlap; - - g_return_val_if_fail (region != NULL, MTK_REGION_OVERLAP_OUT); - g_return_val_if_fail (rect != NULL, MTK_REGION_OVERLAP_OUT); - - box.x1 = rect->x; - box.y1 = rect->y; - box.x2 = rect->x + rect->width; - box.y2 = rect->y + rect->height; - - overlap = pixman_region32_contains_rectangle (®ion->inner_region, - &box); - switch (overlap) - { - default: - case PIXMAN_REGION_OUT: - return MTK_REGION_OVERLAP_OUT; - case PIXMAN_REGION_IN: - return MTK_REGION_OVERLAP_IN; - case PIXMAN_REGION_PART: - return MTK_REGION_OVERLAP_PART; - } -} - -MtkRegion * -mtk_region_scale (MtkRegion *region, - int scale) -{ - int n_rects, i; - MtkRectangle *rects; - MtkRegion *scaled_region; - - if (scale == 1) - return mtk_region_copy (region); - - n_rects = mtk_region_num_rectangles (region); - MTK_RECTANGLE_CREATE_ARRAY_SCOPED (n_rects, rects); - for (i = 0; i < n_rects; i++) - { - rects[i] = mtk_region_get_rectangle (region, i); - rects[i].x *= scale; - rects[i].y *= scale; - rects[i].width *= scale; - rects[i].height *= scale; - } - - scaled_region = mtk_region_create_rectangles (rects, n_rects); - - return scaled_region; -} - -MtkRegion * -mtk_region_crop_and_scale (MtkRegion *region, - graphene_rect_t *src_rect, - int dst_width, - int dst_height) -{ - int n_rects, i; - MtkRectangle *rects; - MtkRegion *viewport_region; - - if (G_APPROX_VALUE (src_rect->size.width, dst_width, FLT_EPSILON) && - G_APPROX_VALUE (src_rect->size.height, dst_height, FLT_EPSILON) && - G_APPROX_VALUE (roundf (src_rect->origin.x), - src_rect->origin.x, FLT_EPSILON) && - G_APPROX_VALUE (roundf (src_rect->origin.y), - src_rect->origin.y, FLT_EPSILON)) - { - viewport_region = mtk_region_copy (region); - - if (!G_APPROX_VALUE (src_rect->origin.x, 0, FLT_EPSILON) || - !G_APPROX_VALUE (src_rect->origin.y, 0, FLT_EPSILON)) - { - mtk_region_translate (viewport_region, - (int) src_rect->origin.x, - (int) src_rect->origin.y); - } - - return viewport_region; - } - - n_rects = mtk_region_num_rectangles (region); - MTK_RECTANGLE_CREATE_ARRAY_SCOPED (n_rects, rects); - for (i = 0; i < n_rects; i++) - { - rects[i] = mtk_region_get_rectangle (region, i); - - mtk_rectangle_crop_and_scale (&rects[i], - src_rect, - dst_width, - dst_height, - &rects[i]); - } - - viewport_region = mtk_region_create_rectangles (rects, n_rects); - - return viewport_region; -} - -MtkRegion * -mtk_region_apply_matrix_transform_expand (const MtkRegion *region, - graphene_matrix_t *transform) -{ - MtkRegion *transformed_region; - MtkRectangle *rects; - int n_rects, i; - - if (graphene_matrix_is_identity (transform)) - return mtk_region_copy (region); - - n_rects = mtk_region_num_rectangles (region); - MTK_RECTANGLE_CREATE_ARRAY_SCOPED (n_rects, rects); - for (i = 0; i < n_rects; i++) - { - graphene_rect_t transformed_rect, rect; - MtkRectangle int_rect; - - int_rect = mtk_region_get_rectangle (region, i); - rect = mtk_rectangle_to_graphene_rect (&int_rect); - - graphene_matrix_transform_bounds (transform, &rect, &transformed_rect); - - mtk_rectangle_from_graphene_rect (&transformed_rect, - MTK_ROUNDING_STRATEGY_GROW, - &rects[i]); - } - - transformed_region = mtk_region_create_rectangles (rects, n_rects); - - return transformed_region; -} - -void -mtk_region_iterator_init (MtkRegionIterator *iter, - MtkRegion *region) -{ - iter->region = region; - iter->i = 0; - iter->n_rectangles = mtk_region_num_rectangles (region); - iter->line_start = TRUE; - - if (iter->n_rectangles > 1) - { - iter->rectangle = mtk_region_get_rectangle (region, 0); - iter->next_rectangle = mtk_region_get_rectangle (region, 1); - - iter->line_end = iter->next_rectangle.y != iter->rectangle.y; - } - else if (iter->n_rectangles > 0) - { - iter->rectangle = mtk_region_get_rectangle (region, 0); - iter->line_end = TRUE; - } -} - -gboolean -mtk_region_iterator_at_end (MtkRegionIterator *iter) -{ - return iter->i >= iter->n_rectangles; -} - -void -mtk_region_iterator_next (MtkRegionIterator *iter) -{ - iter->i++; - iter->rectangle = iter->next_rectangle; - iter->line_start = iter->line_end; - - if (iter->i + 1 < iter->n_rectangles) - { - iter->next_rectangle = mtk_region_get_rectangle (iter->region, iter->i + 1); - iter->line_end = iter->next_rectangle.y != iter->rectangle.y; - } - else - { - iter->line_end = TRUE; - } -} - -/* Various algorithms in this file require unioning together a set of rectangles - * that are unsorted or overlap; unioning such a set of rectangles 1-by-1 - * using mtk_region_union_rectangle() produces O(N^2) behavior (if the union - * adds or removes rectangles in the middle of the region, then it has to - * move all the rectangles after that.) To avoid this behavior, MtkRegionBuilder - * creates regions for small groups of rectangles and merges them together in - * a binary tree. - * - * Possible improvement: From a glance at the code, accumulating all the rectangles - * into a flat array and then calling the (not usefully documented) - * mtk_region_create_rectangles() would have the same behavior and would be - * simpler and a bit more efficient. - */ - -/* Optimium performance seems to be with MAX_CHUNK_RECTANGLES=4; 8 is about 10% slower. - * But using 8 may be more robust to systems with slow malloc(). */ -#define MAX_CHUNK_RECTANGLES 8 - -void -mtk_region_builder_init (MtkRegionBuilder *builder) -{ - int i; - - for (i = 0; i < MTK_REGION_BUILDER_MAX_LEVELS; i++) - builder->levels[i] = NULL; - builder->n_levels = 1; -} - -void -mtk_region_builder_add_rectangle (MtkRegionBuilder *builder, - int x, - int y, - int width, - int height) -{ - MtkRectangle rect; - int i; - - if (builder->levels[0] == NULL) - builder->levels[0] = mtk_region_create (); - - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - - mtk_region_union_rectangle (builder->levels[0], &rect); - if (mtk_region_num_rectangles (builder->levels[0]) >= MAX_CHUNK_RECTANGLES) - { - for (i = 1; i < builder->n_levels + 1; i++) - { - if (builder->levels[i] == NULL) - { - if (i < MTK_REGION_BUILDER_MAX_LEVELS) - { - builder->levels[i] = builder->levels[i - 1]; - builder->levels[i - 1] = NULL; - if (i == builder->n_levels) - builder->n_levels++; - } - - break; - } - else - { - mtk_region_union (builder->levels[i], builder->levels[i - 1]); - mtk_region_unref (builder->levels[i - 1]); - builder->levels[i - 1] = NULL; - } - } - } -} - -MtkRegion * -mtk_region_builder_finish (MtkRegionBuilder *builder) -{ - MtkRegion *result = NULL; - int i; - - for (i = 0; i < builder->n_levels; i++) - { - if (builder->levels[i]) - { - if (result == NULL) - { - result = builder->levels[i]; - } - else - { - mtk_region_union (result, builder->levels[i]); - mtk_region_unref (builder->levels[i]); - } - } - } - - if (result == NULL) - result = mtk_region_create (); - - return result; -} diff --git a/mutter/mtk/mtk/mtk-region.h b/mutter/mtk/mtk/mtk-region.h deleted file mode 100644 index 95da0c4..0000000 --- a/mutter/mtk/mtk/mtk-region.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Mtk - * - * A low-level base library. - * - * Copyright (C) 2023 Red Hat - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#include - -#include "mtk/mtk-rectangle.h" -#include "mtk/mtk-macros.h" - -#define MTK_TYPE_REGION (mtk_region_get_type ()) - -typedef enum _MtkRegionOverlap -{ - MTK_REGION_OVERLAP_OUT, - MTK_REGION_OVERLAP_IN, - MTK_REGION_OVERLAP_PART, -} MtkRegionOverlap; - -typedef struct _MtkRegion MtkRegion; - -MTK_EXPORT -GType mtk_region_get_type (void); - -MTK_EXPORT -MtkRegion * mtk_region_copy (const MtkRegion *region); - -MTK_EXPORT -MtkRegion * mtk_region_ref (MtkRegion *region); - -MTK_EXPORT -void mtk_region_unref (MtkRegion *region); - -MTK_EXPORT -MtkRegion * mtk_region_create (void); - -MTK_EXPORT -gboolean mtk_region_equal (const MtkRegion *region, - const MtkRegion *other); - -MTK_EXPORT -gboolean mtk_region_is_empty (const MtkRegion *region); - -MTK_EXPORT -MtkRectangle mtk_region_get_extents (const MtkRegion *region); - -MTK_EXPORT -int mtk_region_num_rectangles (const MtkRegion *region); - -MTK_EXPORT -void mtk_region_translate (MtkRegion *region, - int dx, - int dy); - -MTK_EXPORT -gboolean mtk_region_contains_point (MtkRegion *region, - int x, - int y); - -MTK_EXPORT -void mtk_region_union (MtkRegion *region, - const MtkRegion *other); - -MTK_EXPORT -void mtk_region_union_rectangle (MtkRegion *region, - const MtkRectangle *rect); - -MTK_EXPORT -void mtk_region_subtract_rectangle (MtkRegion *region, - const MtkRectangle *rect); - -MTK_EXPORT -void mtk_region_subtract (MtkRegion *region, - const MtkRegion *other); - -MTK_EXPORT -void mtk_region_intersect (MtkRegion *region, - const MtkRegion *other); - -MTK_EXPORT -void mtk_region_intersect_rectangle (MtkRegion *region, - const MtkRectangle *rect); - -MTK_EXPORT -MtkRectangle mtk_region_get_rectangle (const MtkRegion *region, - int nth); - -MTK_EXPORT -MtkRegion * mtk_region_create_rectangle (const MtkRectangle *rect); - -MTK_EXPORT -MtkRegion * mtk_region_create_rectangles (const MtkRectangle *rects, - int n_rects); - -MTK_EXPORT -MtkRegionOverlap mtk_region_contains_rectangle (const MtkRegion *region, - const MtkRectangle *rect); - -MTK_EXPORT -MtkRegion * mtk_region_scale (MtkRegion *region, - int scale); - -MTK_EXPORT -MtkRegion * mtk_region_crop_and_scale (MtkRegion *region, - graphene_rect_t *src_rect, - int dst_width, - int dst_height); - -MTK_EXPORT -MtkRegion * mtk_region_apply_matrix_transform_expand (const MtkRegion *region, - graphene_matrix_t *transform); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (MtkRegion, mtk_region_unref) - -/** - * MtkRegionIterator: - * @region: region being iterated - * @rectangle: current rectangle - * @line_start: whether the current rectangle starts a horizontal band - * @line_end: whether the current rectangle ends a horizontal band - * - * MtkRegion is a yx banded region; sometimes its useful to iterate through - * such a region treating the start and end of each horizontal band in a distinct - * fashion. - * - * Usage: - * - * ```c - * MtkRegionIterator iter; - * for (mtk_region_iterator_init (&iter, region); - * !mtk_region_iterator_at_end (&iter); - * mtk_region_iterator_next (&iter)) - * { - * [ Use iter.rectangle, iter.line_start, iter.line_end ] - * } - *``` - */ -typedef struct MtkaRegionIterator MtkRegionIterator; - -struct MtkaRegionIterator { - MtkRegion *region; - MtkRectangle rectangle; - gboolean line_start; - gboolean line_end; - int i; - - /*< private >*/ - int n_rectangles; - MtkRectangle next_rectangle; -}; - -MTK_EXPORT -void mtk_region_iterator_init (MtkRegionIterator *iter, - MtkRegion *region); - -MTK_EXPORT -gboolean mtk_region_iterator_at_end (MtkRegionIterator *iter); - -MTK_EXPORT -void mtk_region_iterator_next (MtkRegionIterator *iter); - -typedef struct _MtkRegionBuilder MtkRegionBuilder; - -#define MTK_REGION_BUILDER_MAX_LEVELS 16 - -struct _MtkRegionBuilder { - /* To merge regions in binary tree order, we need to keep track of - * the regions that we've already merged together at different - * levels of the tree. We fill in an array in the pattern: - * - * |a | - * |b |a | - * |c | |ab | - * |d |c |ab | - * |e | | |abcd| - */ - MtkRegion *levels[MTK_REGION_BUILDER_MAX_LEVELS]; - int n_levels; -}; - -MTK_EXPORT -void mtk_region_builder_init (MtkRegionBuilder *builder); - -MTK_EXPORT -void mtk_region_builder_add_rectangle (MtkRegionBuilder *builder, - int x, - int y, - int width, - int height); - -MTK_EXPORT -MtkRegion * mtk_region_builder_finish (MtkRegionBuilder *builder); diff --git a/mutter/mtk/mtk/mtk-x11-errors.c b/mutter/mtk/mtk/mtk-x11-errors.c deleted file mode 100644 index b6e9555..0000000 --- a/mutter/mtk/mtk/mtk-x11-errors.c +++ /dev/null @@ -1,352 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * Copyright (C) 2001 Havoc Pennington, error trapping inspired by GDK - * code copyrighted by the GTK team. - * - * 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, see . - */ - -/** - * Errors: - * - * Mutter X error handling - */ - -#include "config.h" - -#include "mtk/mtk-x11-errors.h" - -#include -#include -#include -#include - -/* compare X sequence numbers handling wraparound */ -#define SEQUENCE_COMPARE(a,op,b) (((long) (a) - (long) (b)) op 0) - -typedef struct _MtkErrorTrap -{ - /* Next sequence when trap was pushed, i.e. first sequence to - * ignore - */ - unsigned long start_sequence; - - /* Next sequence when trap was popped, i.e. first sequence - * to not ignore. 0 if trap is still active. - */ - unsigned long end_sequence; - - /* Most recent error code within the sequence */ - int error_code; -} MtkErrorTrap; - -/* Previously existing error handler */ -typedef int (* MtkXErrorHandler) (Display *, XErrorEvent *); -static MtkXErrorHandler old_error_handler = NULL; -/* number of times we've pushed the error handler */ -static int error_handler_push_count = 0; -static GHashTable *display_error_traps = NULL; -static int init_count = 0; - -/* look up the extension name for a given major opcode. grubs around in - * xlib to do it since a) it’s already cached there b) XQueryExtension - * emits protocol so we can’t use it in an error handler. - */ -static const char * -decode_request_code (Display *xdisplay, - int code) -{ - _XExtension *ext; - - if (code < 128) - return "core protocol"; - - for (ext = xdisplay->ext_procs; ext; ext = ext->next) - { - if (ext->codes.major_opcode == code) - return ext->name; - } - - return "unknown"; -} - -static void -display_error_event (Display *xdisplay, - XErrorEvent *error) -{ - GList *l; - gboolean ignore = FALSE; - GList *error_traps; - - error_traps = g_hash_table_lookup (display_error_traps, xdisplay); - - for (l = error_traps; l; l = l->next) - { - MtkErrorTrap *trap; - - trap = l->data; - - if (SEQUENCE_COMPARE (trap->start_sequence, <=, error->serial) && - (trap->end_sequence == 0 || - SEQUENCE_COMPARE (trap->end_sequence, >, error->serial))) - { - ignore = TRUE; - trap->error_code = error->error_code; - break; /* only innermost trap gets the error code */ - } - } - - if (!ignore) - { - char buf[64]; - - XGetErrorText (xdisplay, error->error_code, buf, 63); - - g_error ("Received an X Window System error.\n" - "This probably reflects a bug in the program.\n" - "The error was '%s'.\n" - " (Details: serial %ld error_code %d request_code %d (%s) minor_code %d)\n" - " (Note to programmers: normally, X errors are reported asynchronously;\n" - " that is, you will receive the error a while after causing it.\n" - " To debug your program, run it with the MUTTER_SYNC environment\n" - " variable to change this behavior. You can then get a meaningful\n" - " backtrace from your debugger if you break on the mtk_x_error() function.)", - buf, - error->serial, - error->error_code, - error->request_code, - decode_request_code (xdisplay, error->request_code), - error->minor_code); - } -} - -static int -mtk_x_error (Display *xdisplay, - XErrorEvent *error) -{ - if (error->error_code) - display_error_event (xdisplay, error); - - return 0; -} - -static void -error_handler_push (void) -{ - MtkXErrorHandler previous_handler; - - previous_handler = XSetErrorHandler (mtk_x_error); - - if (error_handler_push_count > 0) - { - if (previous_handler != mtk_x_error) - g_warning ("XSetErrorHandler() called with a Mutter X11 error trap pushed. Don't do that."); - } - else - { - old_error_handler = previous_handler; - } - - error_handler_push_count += 1; -} - -static void -error_handler_pop (void) -{ - g_return_if_fail (error_handler_push_count > 0); - - error_handler_push_count -= 1; - - if (error_handler_push_count == 0) - { - XSetErrorHandler (old_error_handler); - old_error_handler = NULL; - } -} - -static void -delete_outdated_error_traps (Display *xdisplay) -{ - GList *l, *error_traps; - unsigned long processed_sequence; - - processed_sequence = XLastKnownRequestProcessed (xdisplay); - l = error_traps = g_hash_table_lookup (display_error_traps, xdisplay); - g_hash_table_steal (display_error_traps, xdisplay); - - while (l != NULL) - { - MtkErrorTrap *trap = l->data; - - if (trap->end_sequence != 0 && - SEQUENCE_COMPARE (trap->end_sequence, <=, processed_sequence)) - { - GList *link = l; - - l = l->next; - error_traps = g_list_delete_link (error_traps, link); - g_free (trap); - } - else - { - l = l->next; - } - } - - g_hash_table_insert (display_error_traps, xdisplay, error_traps); -} - -static void -free_trap_list (gpointer data) -{ - g_list_free_full (data, g_free); -} - -/** - * mtk_x11_errors_init: (skip): - */ -void -mtk_x11_errors_init (void) -{ - if (init_count == 0) - { - XSetErrorHandler (mtk_x_error); - display_error_traps = - g_hash_table_new_full (NULL, NULL, NULL, free_trap_list); - } - - init_count++; -} - -/** - * mtk_x11_errors_destroy: (skip): - */ -void -mtk_x11_errors_deinit (void) -{ - init_count--; - g_assert (init_count >= 0); - - if (init_count == 0) - { - g_clear_pointer (&display_error_traps, g_hash_table_unref); - XSetErrorHandler (NULL); - } -} - -/** - * mtk_x11_error_trap_push: (skip): - */ -void -mtk_x11_error_trap_push (Display *xdisplay) -{ - MtkErrorTrap *trap; - GList *error_traps; - - delete_outdated_error_traps (xdisplay); - - /* set up the Xlib callback to tell us about errors */ - error_handler_push (); - - trap = g_new0 (MtkErrorTrap, 1); - trap->start_sequence = XNextRequest (xdisplay); - trap->error_code = Success; - - error_traps = g_hash_table_lookup (display_error_traps, xdisplay); - g_hash_table_steal (display_error_traps, xdisplay); - error_traps = g_list_prepend (error_traps, trap); - g_hash_table_insert (display_error_traps, xdisplay, error_traps); -} - -static int -mtk_x11_error_trap_pop_internal (Display *xdisplay, - gboolean need_code) -{ - MtkErrorTrap *trap = NULL; - GList *l, *error_traps; - int result; - - error_traps = g_hash_table_lookup (display_error_traps, xdisplay); - - g_return_val_if_fail (error_traps != NULL, Success); - - /* Find the first trap that hasn't been popped already */ - for (l = error_traps; l; l = l->next) - { - trap = l->data; - - if (trap->end_sequence == 0) - break; - } - - g_return_val_if_fail (trap != NULL, Success); - g_assert (trap->end_sequence == 0); - - /* May need to sync to fill in trap->error_code if we care about - * getting an error code. - */ - if (need_code) - { - unsigned long processed_sequence, next_sequence; - - next_sequence = XNextRequest (xdisplay); - processed_sequence = XLastKnownRequestProcessed (xdisplay); - - /* If our last request was already processed, there is no point - * in syncing. i.e. if last request was a round trip (or even if - * we got an event with the serial of a non-round-trip) - */ - if ((next_sequence - 1) != processed_sequence) - { - XSync (xdisplay, False); - } - - result = trap->error_code; - } - else - { - result = Success; - } - - /* record end of trap, giving us a range of - * error sequences we'll ignore. - */ - trap->end_sequence = XNextRequest (xdisplay); - - /* remove the Xlib callback */ - error_handler_pop (); - - /* we may already be outdated */ - delete_outdated_error_traps (xdisplay); - - return result; -} - -/** - * mtk_x11_error_trap_pop: (skip): - */ -void -mtk_x11_error_trap_pop (Display *xdisplay) -{ - mtk_x11_error_trap_pop_internal (xdisplay, FALSE); -} - -/** - * mtk_x11_error_trap_pop_with_return: (skip): - */ -int -mtk_x11_error_trap_pop_with_return (Display *xdisplay) -{ - return mtk_x11_error_trap_pop_internal (xdisplay, TRUE); -} diff --git a/mutter/mtk/mtk/mtk-x11-errors.h b/mutter/mtk/mtk/mtk-x11-errors.h deleted file mode 100644 index 0d742be..0000000 --- a/mutter/mtk/mtk/mtk-x11-errors.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Mutter X error handling */ - -/* - * Copyright (C) 2001 Havoc Pennington - * - * 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, see . - */ - -#pragma once - -#include "mtk/mtk-macros.h" - -#include - -MTK_EXPORT -void mtk_x11_errors_init (void); - -MTK_EXPORT -void mtk_x11_errors_deinit (void); - -MTK_EXPORT -void mtk_x11_error_trap_push (Display *xdisplay); - -MTK_EXPORT -void mtk_x11_error_trap_pop (Display *xdisplay); - -MTK_EXPORT -int mtk_x11_error_trap_pop_with_return (Display *xdisplay); diff --git a/mutter/mtk/mtk/mtk-x11.h b/mutter/mtk/mtk/mtk-x11.h deleted file mode 100644 index beec31d..0000000 --- a/mutter/mtk/mtk/mtk-x11.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Mtk - * - * A low-level base library. - * - * Copyright (C) 2023 Red Hat - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#define __MTK_H_INSIDE__ - -#include "mtk/mtk-macros.h" -#include "mtk/mtk-x11-errors.h" - -#undef __MTK_H_INSIDE__ diff --git a/mutter/mtk/mtk/mtk.h b/mutter/mtk/mtk/mtk.h deleted file mode 100644 index 7bc7e0e..0000000 --- a/mutter/mtk/mtk/mtk.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Mtk - * - * A low-level base library. - * - * Copyright (C) 2023 Red Hat - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#pragma once - -#define __MTK_H_INSIDE__ - -#include "mtk/mtk-rectangle.h" -#include "mtk/mtk-region.h" -#include "mtk/mtk-macros.h" - -#undef __MTK_H_INSIDE__ diff --git a/mutter/mutter.doap b/mutter/mutter.doap deleted file mode 100644 index ee110f7..0000000 --- a/mutter/mutter.doap +++ /dev/null @@ -1,77 +0,0 @@ - - - mutter - Window and compositing manager based on Clutter - Mutter is a window and compositing manager that displays and -manages your desktop via OpenGL. Mutter combines a sophisticated display engine -using the Clutter toolkit with solid window-management logic inherited from the -Metacity window manager. - -While Mutter can be used stand-alone, it is primarily intended to be used as -the display core of a larger system such as GNOME Shell. For this reason, -Mutter is very extensible via plugins, which are used both to add fancy visual -effects and to rework the window management behaviors to meet the needs of the -environment. - - - - - - - C - - - - Tomas Frydrych - - tomasf - - - - - Owen Taylor - - otaylor - - - - - Jonas Ådahl - - jadahl - - - - - Carlos Garnacho - - carlosg - - - - - Georges Basile Stavracas Neto - - gbsneto - - - - - Florian Müllner - - fmuellner - - - - - Marge Bot - marge-bot - - - diff --git a/mutter/po/LINGUAS b/mutter/po/LINGUAS deleted file mode 100644 index b89761c..0000000 --- a/mutter/po/LINGUAS +++ /dev/null @@ -1,100 +0,0 @@ -# please keep this list sorted alphabetically -# -ab -am -ar -as -ast -az -be -be@latin -bg -bn -bn_IN -br -bs -ca -ca@valencia -cs -cy -da -de -dz -el -en_CA -en_GB -eo -es -et -eu -fa -fi -fr -fur -ga -gd -gl -gu -ha -he -hi -hr -hu -hy -id -ig -is -it -ja -ka -kab -kk -kn -ko -ku -la -lt -lv -mai -mg -mk -ml -mn -mr -ms -nb -nds -ne -nl -nn -oc -or -pa -pl -pt -pt_BR -ro -ru -rw -si -sk -sl -sq -sr -sr@latin -sv -ta -te -tg -th -tk -tr -ug -uk -vi -wa -xh -yo -zh_CN -zh_HK -zh_TW diff --git a/mutter/po/POTFILES.in b/mutter/po/POTFILES.in deleted file mode 100644 index 520dfdd..0000000 --- a/mutter/po/POTFILES.in +++ /dev/null @@ -1,22 +0,0 @@ -# List of source files containing translatable strings. -# Please keep this file sorted alphabetically. -data/50-mutter-navigation.xml -data/50-mutter-system.xml -data/50-mutter-wayland.xml -data/50-mutter-windows.xml -data/org.gnome.mutter.gschema.xml.in -data/org.gnome.mutter.wayland.gschema.xml.in -src/backends/meta-monitor.c -src/core/bell.c -src/core/display.c -src/core/meta-context-main.c -src/core/meta-pad-action-mapper.c -src/core/meta-profiler.c -src/core/mutter.c -src/core/prefs.c -src/core/util.c -src/core/workspace.c -src/wayland/meta-wayland-tablet-pad.c -src/x11/meta-x11-display.c -src/x11/meta-x11-selection-input-stream.c -src/x11/window-props.c diff --git a/mutter/po/POTFILES.skip b/mutter/po/POTFILES.skip deleted file mode 100644 index 8191245..0000000 --- a/mutter/po/POTFILES.skip +++ /dev/null @@ -1,4 +0,0 @@ -# List of source files that should NOT be translated. -# Please keep this file sorted alphabetically. -clutter -cogl diff --git a/mutter/po/ab.po b/mutter/po/ab.po deleted file mode 100644 index 888fb14..0000000 --- a/mutter/po/ab.po +++ /dev/null @@ -1,4608 +0,0 @@ -msgid "" -msgstr "" -"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" -"POT-Creation-Date: 2022-09-20 14:08+0000\n" -"Last-Translator: Нанба Наала \n" -"Language-Team: Abkhazian \n" -"Language: ab\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: data/50-mutter-navigation.xml:6 -msgid "Navigation" -msgstr "" - -#: data/50-mutter-navigation.xml:9 -msgid "Move window to workspace 1" -msgstr "" - -#: data/50-mutter-navigation.xml:12 -msgid "Move window to workspace 2" -msgstr "" - -#: data/50-mutter-navigation.xml:15 -msgid "Move window to workspace 3" -msgstr "" - -#: data/50-mutter-navigation.xml:18 -msgid "Move window to workspace 4" -msgstr "" - -#: data/50-mutter-navigation.xml:21 -msgid "Move window to last workspace" -msgstr "" - -#: data/50-mutter-navigation.xml:24 -msgid "Move window one workspace to the left" -msgstr "" - -#: data/50-mutter-navigation.xml:27 -msgid "Move window one workspace to the right" -msgstr "" - -#: data/50-mutter-navigation.xml:31 -msgid "Move window one workspace up" -msgstr "" - -#: data/50-mutter-navigation.xml:35 -msgid "Move window one workspace down" -msgstr "" - -#: data/50-mutter-navigation.xml:38 -msgid "Move window one monitor to the left" -msgstr "" - -#: data/50-mutter-navigation.xml:41 -msgid "Move window one monitor to the right" -msgstr "" - -#: data/50-mutter-navigation.xml:44 -msgid "Move window one monitor up" -msgstr "" - -#: data/50-mutter-navigation.xml:47 -msgid "Move window one monitor down" -msgstr "" - -#: data/50-mutter-navigation.xml:51 -msgid "Switch applications" -msgstr "" - -#: data/50-mutter-navigation.xml:56 -msgid "Switch to previous application" -msgstr "" - -#: data/50-mutter-navigation.xml:60 -msgid "Switch windows" -msgstr "" - -#: data/50-mutter-navigation.xml:65 -msgid "Switch to previous window" -msgstr "" - -#: data/50-mutter-navigation.xml:69 -msgid "Switch windows of an application" -msgstr "" - -#: data/50-mutter-navigation.xml:74 -msgid "Switch to previous window of an application" -msgstr "" - -#: data/50-mutter-navigation.xml:78 -msgid "Switch system controls" -msgstr "" - -#: data/50-mutter-navigation.xml:83 -msgid "Switch to previous system control" -msgstr "" - -#: data/50-mutter-navigation.xml:87 -msgid "Switch windows directly" -msgstr "" - -#: data/50-mutter-navigation.xml:92 -msgid "Switch directly to previous window" -msgstr "" - -#: data/50-mutter-navigation.xml:96 -msgid "Switch windows of an app directly" -msgstr "" - -#: data/50-mutter-navigation.xml:101 -msgid "Switch directly to previous window of an app" -msgstr "" - -#: data/50-mutter-navigation.xml:105 -msgid "Switch system controls directly" -msgstr "" - -#: data/50-mutter-navigation.xml:110 -msgid "Switch directly to previous system control" -msgstr "" - -#: data/50-mutter-navigation.xml:113 -msgid "Hide all normal windows" -msgstr "" - -#: data/50-mutter-navigation.xml:116 -msgid "Switch to workspace 1" -msgstr "" - -#: data/50-mutter-navigation.xml:119 -msgid "Switch to workspace 2" -msgstr "" - -#: data/50-mutter-navigation.xml:122 -msgid "Switch to workspace 3" -msgstr "" - -#: data/50-mutter-navigation.xml:125 -msgid "Switch to workspace 4" -msgstr "" - -#: data/50-mutter-navigation.xml:128 -msgid "Switch to last workspace" -msgstr "" - -#: data/50-mutter-navigation.xml:131 -msgid "Move to workspace on the left" -msgstr "" - -#: data/50-mutter-navigation.xml:134 -msgid "Move to workspace on the right" -msgstr "" - -#: data/50-mutter-navigation.xml:138 -msgid "Move to workspace above" -msgstr "" - -#: data/50-mutter-navigation.xml:142 -msgid "Move to workspace below" -msgstr "" - -#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 -msgid "System" -msgstr "" - -#: data/50-mutter-system.xml:8 -msgid "Show the run command prompt" -msgstr "" - -#: data/50-mutter-wayland.xml:8 -msgid "Restore the keyboard shortcuts" -msgstr "" - -#: data/50-mutter-windows.xml:6 -msgid "Windows" -msgstr "Windows" - -#: data/50-mutter-windows.xml:8 -msgid "Activate the window menu" -msgstr "Активациа азура аԥенџьыр амениу" - -#: data/50-mutter-windows.xml:10 -msgid "Toggle fullscreen mode" -msgstr "" - -#: data/50-mutter-windows.xml:12 -msgid "Toggle maximization state" -msgstr "" - -#: data/50-mutter-windows.xml:14 -msgid "Maximize window" -msgstr "" - -#: data/50-mutter-windows.xml:16 -msgid "Restore window" -msgstr "" - -#: data/50-mutter-windows.xml:18 -msgid "Close window" -msgstr "Аҧенџьыр аркра" - -#: data/50-mutter-windows.xml:20 -msgid "Hide window" -msgstr "" - -#: data/50-mutter-windows.xml:22 -msgid "Move window" -msgstr "" - -#: data/50-mutter-windows.xml:24 -msgid "Resize window" -msgstr "" - -#: data/50-mutter-windows.xml:27 -msgid "Toggle window on all workspaces or one" -msgstr "" - -#: data/50-mutter-windows.xml:29 -msgid "Raise window if covered, otherwise lower it" -msgstr "" - -#: data/50-mutter-windows.xml:31 -msgid "Raise window above other windows" -msgstr "" - -#: data/50-mutter-windows.xml:33 -msgid "Lower window below other windows" -msgstr "" - -#: data/50-mutter-windows.xml:35 -msgid "Maximize window vertically" -msgstr "" - -#: data/50-mutter-windows.xml:37 -msgid "Maximize window horizontally" -msgstr "" - -#: data/50-mutter-windows.xml:41 data/org.gnome.mutter.gschema.xml.in:173 -msgid "View split on left" -msgstr "" - -#: data/50-mutter-windows.xml:45 data/org.gnome.mutter.gschema.xml.in:178 -msgid "View split on right" -msgstr "" - -#: data/mutter.desktop.in:4 -msgid "Mutter" -msgstr "Mutter" - -#: data/org.gnome.mutter.gschema.xml.in:15 -msgid "Modifier to use for extended window management operations" -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:16 -msgid "" -"This key will initiate the “overlay”, which is a combination window overview " -"and application launching system. The default is intended to be the “Windows " -"key” on PC hardware. It’s expected that this binding either the default or " -"set to the empty string." -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:28 -msgid "Attach modal dialogs" -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:29 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:38 -msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "" -"Аԥенџьырқәа аекран акьыԥшь ахь реиҭагараан автоматикла аԥенџьыр ашәагаа " -"аҽаԥсахра аҿакра." - -#: data/org.gnome.mutter.gschema.xml.in:39 -msgid "" -"If enabled, dropping windows on vertical screen edges maximizes them " -"vertically and resizes them horizontally to cover half of the available " -"area. Dropping windows on the top screen edge maximizes them completely." -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:48 -msgid "Workspaces are managed dynamically" -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:49 -msgid "" -"Determines whether workspaces are managed dynamically or whether there’s a " -"static number of workspaces (determined by the num-workspaces key in org." -"gnome.desktop.wm.preferences)." -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:58 -msgid "Workspaces only on primary" -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:59 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:67 -msgid "No tab popup" -msgstr "Ицәырҵуа аҭаӡҩырартәрада" - -#: data/org.gnome.mutter.gschema.xml.in:68 -msgid "" -"Determines whether the use of popup and highlight frame should be disabled " -"for window cycling." -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:76 -msgid "Delay focus changes until the pointer stops moving" -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:77 -msgid "" -"If set to true, and the focus mode is either “sloppy” or “mouse” then the " -"focus will not be changed immediately when entering a window, but only after " -"the pointer stops moving." -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:87 -msgid "Draggable border width" -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:88 -msgid "" -"The amount of total draggable borders. If the theme’s visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:97 -msgid "Auto maximize nearly monitor sized windows" -msgstr "Автоматикла аԥенџьыр ашәага амонитор ашәага аҟынӡа ардура." - -#: data/org.gnome.mutter.gschema.xml.in:98 -msgid "" -"If enabled, new windows that are initially the size of the monitor " -"automatically get maximized." -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:106 -msgid "Place new windows in the center" -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:107 -msgid "" -"When true, the new windows will always be put in the center of the active " -"screen of the monitor." -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:116 -msgid "Enable experimental features" -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:117 -msgid "" -"To enable experimental features, add the feature keyword to the list. " -"Whether the feature requires restarting the compositor depends on the given " -"feature. Any experimental feature is not required to still be available, or " -"configurable. Don’t expect adding anything in this setting to be future " -"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " -"mutter default to layout logical monitors in a logical pixel coordinate " -"space, while scaling monitor framebuffers instead of window content, to " -"manage HiDPI monitors. Does not require a restart. • “kms-modifiers” — makes " -"mutter always allocate scanout buffers with explicit modifiers, if supported " -"by the driver. Requires a restart. • “rt-scheduler” — makes mutter request a " -"low priority real-time scheduling. Requires a restart. • “autoclose-" -"xwayland” — automatically terminates Xwayland if all relevant X11 clients " -"are gone. Requires a restart." -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:150 -msgid "Modifier to use to locate the pointer" -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:151 -msgid "This key will initiate the “locate pointer” action." -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:158 -msgid "Timeout for check-alive ping" -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:159 -msgid "" -"Number of milliseconds a client has to respond to a ping request in order to " -"not be detected as frozen. Using 0 will disable the alive check completely." -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:183 -msgid "Select window from tab popup" -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:188 -msgid "Cancel tab popup" -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:193 -msgid "Switch monitor configurations" -msgstr "" - -#: data/org.gnome.mutter.gschema.xml.in:198 -msgid "Rotates the built-in monitor configuration" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:12 -msgid "Switch to VT 1" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:16 -msgid "Switch to VT 2" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:20 -msgid "Switch to VT 3" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:24 -msgid "Switch to VT 4" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:28 -msgid "Switch to VT 5" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:32 -msgid "Switch to VT 6" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:36 -msgid "Switch to VT 7" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:40 -msgid "Switch to VT 8" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:44 -msgid "Switch to VT 9" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:48 -msgid "Switch to VT 10" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:52 -msgid "Switch to VT 11" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:56 -msgid "Switch to VT 12" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:60 -msgid "Re-enable shortcuts" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:70 -msgid "Allow X11 grabs to lock keyboard focus with Xwayland" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:71 -msgid "" -"Allow all keyboard events to be routed to X11 “override redirect” windows " -"with a grab when running in Xwayland. This option is to support X11 clients " -"which map an “override redirect” window (which do not receive keyboard " -"focus) and issue a keyboard grab to force all keyboard events to that " -"window. This option is seldom used and has no effect on regular X11 windows " -"which can receive keyboard focus under normal circumstances. For a X11 grab " -"to be taken into account under Wayland, the client must also either send a " -"specific X11 ClientMessage to the root window or be among the applications " -"allowed in key “xwayland-grab-access-rules”." -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:90 -msgid "Xwayland applications allowed to issue keyboard grabs" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:91 -msgid "" -"List the resource names or resource class of X11 windows either allowed or " -"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " -"resource class of a given X11 window can be obtained using the command " -"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " -"Values starting with “!” are denied, which has precedence over the list of " -"values allowed, to revoke applications from the default system list. The " -"default system list includes the following applications: " -"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " -"using the specific keyboard shortcut defined by the keybinding key “restore-" -"shortcuts”." -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:116 -msgid "Disable selected X extensions in Xwayland" -msgstr "" - -#: data/org.gnome.mutter.wayland.gschema.xml.in:117 -msgid "" -"This option disables the selected X extensions in Xwayland if Xwayland was " -"built with support for those X extensions. This option has no effect if " -"Xwayland was built without support for the selected extensions. Xwayland " -"needs to be restarted for this setting to take effect." -msgstr "" - -#: src/backends/meta-monitor.c:253 -msgid "Built-in display" -msgstr "" - -#: src/backends/meta-monitor.c:280 -msgid "Unknown" -msgstr "Еилкаам" - -#: src/backends/meta-monitor.c:282 -msgid "Unknown Display" -msgstr "" -"This is a monitor vendor name, followed by a size in inches, like 'Dell " -"15quta1'" - -#: src/backends/meta-monitor.c:290 -#, c-format -msgctxt "" -"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" -msgid "%s %s" -msgstr "" - -#: src/backends/meta-monitor.c:298 -#, c-format -msgctxt "" -"This is a monitor vendor name followed by product/model name where size in " -"inches could not be calculated, e.g. Dell U2414H" -msgid "%s %s" -msgstr "" - -#. Translators: this string will appear in Sysprof -#: src/backends/meta-profiler.c:79 -msgid "Compositor" -msgstr "" - -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: src/compositor/compositor.c:400 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display “%s”." -msgstr "" - -#: src/core/bell.c:192 -msgid "Bell event" -msgstr "" - -#: src/core/display.c:693 -msgid "Privacy Screen Enabled" -msgstr "" - -#: src/core/display.c:694 -msgid "Privacy Screen Disabled" -msgstr "" - -#: src/core/meta-context-main.c:567 -msgid "Replace the running window manager" -msgstr "" - -#: src/core/meta-context-main.c:573 -msgid "X Display to use" -msgstr "" - -#: src/core/meta-context-main.c:579 -msgid "Disable connection to session manager" -msgstr "" - -#: src/core/meta-context-main.c:585 -msgid "Specify session management ID" -msgstr "" - -#: src/core/meta-context-main.c:591 -msgid "Initialize session from savefile" -msgstr "" - -#: src/core/meta-context-main.c:597 -msgid "Make X calls synchronous" -msgstr "" - -#: src/core/meta-context-main.c:605 -msgid "Run as a wayland compositor" -msgstr "" - -#: src/core/meta-context-main.c:611 -msgid "Run as a nested compositor" -msgstr "" - -#: src/core/meta-context-main.c:617 -msgid "Run wayland compositor without starting Xwayland" -msgstr "" - -#: src/core/meta-context-main.c:623 -msgid "Specify Wayland display name to use" -msgstr "" - -#: src/core/meta-context-main.c:631 -msgid "Run as a full display server, rather than nested" -msgstr "" - -#: src/core/meta-context-main.c:636 -msgid "Run as a headless display server" -msgstr "" - -#: src/core/meta-context-main.c:641 -msgid "Add persistent virtual monitor (WxH or WxH@R)" -msgstr "" - -#: src/core/meta-context-main.c:653 -msgid "Run with X11 backend" -msgstr "" - -#. TRANSLATORS: This string refers to a button that switches between -#. * different modes. -#. -#: src/core/meta-pad-action-mapper.c:848 -#, c-format -msgid "Mode Switch (Group %d)" -msgstr "" - -#. TRANSLATORS: This string refers to an action, cycles drawing tablets' -#. * mapping through the available outputs. -#. -#: src/core/meta-pad-action-mapper.c:871 -msgid "Switch monitor" -msgstr "" - -#: src/core/meta-pad-action-mapper.c:873 -msgid "Show on-screen help" -msgstr "" - -#: src/core/mutter.c:74 -msgid "Print version" -msgstr "" - -#: src/core/mutter.c:80 -msgid "Mutter plugin to use" -msgstr "" - -#: src/core/prefs.c:1913 -#, c-format -msgid "Workspace %d" -msgstr "Аусуратә ҵакыра %d" - -#: src/core/util.c:143 -msgid "Mutter was compiled without support for verbose mode" -msgstr "Mutter акомпилиациа азун арежим verbose ацхыраарада" - -#: src/core/workspace.c:533 -msgid "Workspace switched" -msgstr "" - -#: src/wayland/meta-wayland-tablet-pad.c:520 -#, c-format -msgid "Mode Switch: Mode %d" -msgstr "" - -#: src/x11/meta-x11-display.c:657 -#, c-format -msgid "" -"Display “%s” already has a window manager; try using the --replace option to " -"replace the current window manager." -msgstr "" - -#: src/x11/meta-x11-display.c:1048 -msgid "Failed to initialize GDK" -msgstr "" - -#: src/x11/meta-x11-display.c:1074 -#, c-format -msgid "Failed to open X Window System display “%s”" -msgstr "" - -#: src/x11/meta-x11-display.c:1187 -#, c-format -msgid "Screen %d on display “%s” is invalid" -msgstr "" - -#: src/x11/meta-x11-selection-input-stream.c:474 -#, c-format -msgid "Format %s not supported" -msgstr "" - -#: src/x11/window-props.c:548 -#, c-format -msgid "%s (on %s)" -msgstr "" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#, fuzzy - - - - - - - - - - - - - - - - - - - - - - - -#, fuzzy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#, fuzzy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#, fuzzy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#, fuzzy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#, fuzzy - - - -#, fuzzy - -#, fuzzy - - - - - - -#, fuzzy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#, fuzzy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#, fuzzy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#, fuzzy - - - - - - - - - - - - - - - - - - - - - - - - - -#, fuzzy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#, fuzzy diff --git a/mutter/po/am.po b/mutter/po/am.po deleted file mode 100644 index 0e70973..0000000 --- a/mutter/po/am.po +++ /dev/null @@ -1,2696 +0,0 @@ -# Translations into the Amharic Language. -# Copyright (C) 2002 Free Software Foundation, Inc. -# This file is distributed under the same license as the metacity package. -# Ge'ez Frontier Foundation , 2002. -# -# -msgid "" -msgstr "" -"Project-Id-Version: metacity\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-09-19 12:30+0200\n" -"PO-Revision-Date: 2003-02-03 10:16+EDT\n" -"Last-Translator: Ge'ez Frontier Foundation \n" -"Language-Team: Amharic \n" -"Language: am\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../src/tools/metacity-message.c:150 -#, c-format -msgid "Usage: %s\n" -msgstr "አጠቃቀም፦ %s\n" - -#: ../src/tools/metacity-message.c:176 ../src/util.c:128 -msgid "Metacity was compiled without support for verbose mode\n" -msgstr "" - -#: ../src/delete.c:63 ../src/delete.c:90 ../src/metacity-dialog.c:70 -#: ../src/theme-parser.c:467 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "" - -#: ../src/delete.c:70 ../src/delete.c:97 ../src/metacity-dialog.c:77 -#: ../src/theme-parser.c:476 ../src/theme-parser.c:530 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "" - -#: ../src/delete.c:128 -#, c-format -msgid "Failed to parse message \"%s\" from dialog process\n" -msgstr "" - -#: ../src/delete.c:263 -#, c-format -msgid "Error reading from dialog display process: %s\n" -msgstr "" - -#: ../src/delete.c:344 -#, c-format -msgid "" -"Error launching metacity-dialog to ask about killing an application: %s\n" -msgstr "" - -#: ../src/delete.c:452 -#, c-format -msgid "Failed to get hostname: %s\n" -msgstr "" - -#: ../src/display.c:319 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "" - -#: ../src/errors.c:231 -#, c-format -msgid "" -"Lost connection to the display '%s';\n" -"most likely the X server was shut down or you killed/destroyed\n" -"the window manager.\n" -msgstr "" - -#: ../src/errors.c:238 -#, c-format -msgid "Fatal IO error %d (%s) on display '%s'.\n" -msgstr "" - -#: ../src/frames.c:1125 -msgid "Close Window" -msgstr "መስኮቱን ዝጋ" - -#: ../src/frames.c:1128 -msgid "Window Menu" -msgstr "የመስኮት ሜኑ" - -#: ../src/frames.c:1131 -msgid "Minimize Window" -msgstr "መስኮቱን አሳንስ" - -#: ../src/frames.c:1134 -msgid "Maximize Window" -msgstr "መስኮቱን አስተልቅ" - -#: ../src/frames.c:1137 -msgid "Unmaximize Window" -msgstr "መስኮቱን አታስተልቅ" - -#: ../src/keybindings.c:994 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" - -#: ../src/keybindings.c:2620 -#, c-format -msgid "Error launching metacity-dialog to print an error about a command: %s\n" -msgstr "" - -#: ../src/keybindings.c:2725 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "" - -#: ../src/keybindings.c:3570 -msgid "No terminal command has been defined.\n" -msgstr "" - -#: ../src/main.c:69 -#, c-format -msgid "" -"metacity %s\n" -"Copyright (C) 2001-2002 Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" - -#: ../src/main.c:257 -msgid "Disable connection to session manager" -msgstr "" - -#: ../src/main.c:263 -msgid "Replace the running window manager with Metacity" -msgstr "" - -#: ../src/main.c:269 -msgid "Specify session management ID" -msgstr "" - -#: ../src/main.c:274 -msgid "X Display to use" -msgstr "" - -#: ../src/main.c:280 -msgid "Initialize session from savefile" -msgstr "" - -#: ../src/main.c:286 -msgid "Print version" -msgstr "" - -#: ../src/main.c:440 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "" - -#: ../src/main.c:456 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes." -msgstr "" - -#: ../src/main.c:518 -#, c-format -msgid "Failed to restart: %s\n" -msgstr "" - -#: ../src/menu.c:54 -msgid "Mi_nimize" -msgstr "መሳንስ (_N)" - -#: ../src/menu.c:55 -msgid "Ma_ximize" -msgstr "መተልቅ (_X)" - -#: ../src/menu.c:56 -msgid "Unma_ximize" -msgstr "መታስተልቅ (_X)" - -#: ../src/menu.c:57 -msgid "Roll _Up" -msgstr "ማውጣት (_U)" - -#: ../src/menu.c:58 -msgid "_Unroll" -msgstr "ማውረድ (_U)" - -#: ../src/menu.c:59 ../src/menu.c:60 -msgid "On _Top" -msgstr "" - -#: ../src/menu.c:61 -msgid "_Move" -msgstr "መንቀሳቅስ (_M)" - -#: ../src/menu.c:62 -msgid "_Resize" -msgstr "እንደገና መጧን ማስተሥከል (_R)" - -#. separator -#: ../src/menu.c:64 -msgid "_Close" -msgstr "ዝጋ (_C)" - -#. separator -#: ../src/menu.c:66 -#, fuzzy -msgid "_Always on Visible Workspace" -msgstr "በዚህ መሥሪያ ቦታ ላይ ብቻ (_U)" - -#: ../src/menu.c:67 -#, fuzzy -msgid "_Only on This Workspace" -msgstr "በዚህ መሥሪያ ቦታ ላይ ብቻ (_U)" - -#: ../src/menu.c:68 -#, fuzzy -msgid "Move to Workspace _Left" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 9 አንቀሳቅስ" - -#: ../src/menu.c:69 -#, fuzzy -msgid "Move to Workspace R_ight" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 1 አንቀሳቅስ" - -#: ../src/menu.c:70 -#, fuzzy -msgid "Move to Workspace _Up" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 1 አንቀሳቅስ" - -#: ../src/menu.c:71 -#, fuzzy -msgid "Move to Workspace _Down" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 9 አንቀሳቅስ" - -#: ../src/menu.c:162 ../src/prefs.c:2106 -#, c-format -msgid "Workspace %d" -msgstr "መሥሪያ ቦታ %d" - -#: ../src/menu.c:171 -#, fuzzy -msgid "Workspace 1_0" -msgstr "መሥሪያ ቦታ %d" - -#: ../src/menu.c:173 -#, c-format -msgid "Workspace %s%d" -msgstr "መሥሪያ ቦታ %s%d" - -#: ../src/menu.c:368 -#, fuzzy -msgid "Move to Another _Workspace" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 1 አንቀሳቅስ" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:105 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:111 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:117 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:123 -msgid "Meta" -msgstr "" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:129 -msgid "Super" -msgstr "" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:135 -msgid "Hyper" -msgstr "" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:141 -msgid "Mod2" -msgstr "" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:147 -msgid "Mod3" -msgstr "" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:153 -msgid "Mod4" -msgstr "" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:159 -msgid "Mod5" -msgstr "Mod5" - -#: ../src/metacity-dialog.c:110 -#, c-format -msgid "The window \"%s\" is not responding." -msgstr "" - -#: ../src/metacity-dialog.c:118 -msgid "" -"Forcing this application to quit will cause you to lose any unsaved changes." -msgstr "" - -#: ../src/metacity-dialog.c:129 -msgid "_Force Quit" -msgstr "" - -#: ../src/metacity-dialog.c:226 -msgid "Title" -msgstr "አርእስት" - -#: ../src/metacity-dialog.c:238 -msgid "Class" -msgstr "መደብ" - -#: ../src/metacity-dialog.c:264 -msgid "" -"These windows do not support \"save current setup\" and will have to be " -"restarted manually next time you log in." -msgstr "" - -#: ../src/metacity-dialog.c:330 -#, c-format -msgid "" -"There was an error running \"%s\":\n" -"%s." -msgstr "" - -#: ../src/metacity.desktop.in.h:1 -msgid "Metacity" -msgstr "" - -#: ../src/metacity.schemas.in.h:1 -msgid "(Not implemented) Navigation works in terms of applications not windows" -msgstr "" - -#: ../src/metacity.schemas.in.h:2 -msgid "" -"A font description string describing a font for window titlebars. The size " -"from the description will only be used if the titlebar_font_size option is " -"set to 0, however. Also, this option is disabled if the " -"titlebar_uses_desktop_font option is set to true. By default, titlebar_font " -"is unset, causing Metacity to fall back to the desktop font even if " -"titlebar_uses_desktop_font is false." -msgstr "" - -#: ../src/metacity.schemas.in.h:3 -msgid "Action on title bar double-click" -msgstr "" - -#: ../src/metacity.schemas.in.h:4 -msgid "Activate window menu" -msgstr "" - -#: ../src/metacity.schemas.in.h:5 -msgid "Arrangement of buttons on the titlebar" -msgstr "" - -#: ../src/metacity.schemas.in.h:6 -msgid "" -"Arrangement of buttons on the titlebar. The value should be a string, such " -"as \"menu:minimize,maximize,close\"; the colon separates the left corner of " -"the window from the right corner, and the button names are comma-separated. " -"Duplicate buttons are not allowed. Unknown button names are silently ignored " -"so that buttons can be added in future metacity versions without breaking " -"older versions." -msgstr "" - -#: ../src/metacity.schemas.in.h:7 -msgid "Automatically raises the focused window" -msgstr "" - -#: ../src/metacity.schemas.in.h:8 -msgid "" -"Clicking a window while holding down this modifier key will move the window " -"(left click), resize the window (middle click), or show the window menu " -"(right click). Modifier is expressed as \"<Alt>\" or \"<Super>\" " -"for example." -msgstr "" - -#: ../src/metacity.schemas.in.h:9 -#, fuzzy -msgid "Close window" -msgstr "መስኮትን ዝጋ" - -#: ../src/metacity.schemas.in.h:10 -msgid "Commands to run in response to keybindings" -msgstr "" - -#: ../src/metacity.schemas.in.h:11 -msgid "Current theme" -msgstr "የአሁኑን ጭብጥ" - -#: ../src/metacity.schemas.in.h:12 -msgid "Delay in milliseconds for the auto raise option" -msgstr "" - -#: ../src/metacity.schemas.in.h:13 -msgid "" -"Determines whether applications or the system can generate audible 'beeps'; " -"may be used in conjunction with 'visual bell' to allow silent 'beeps'." -msgstr "" - -#: ../src/metacity.schemas.in.h:14 -msgid "Disable misfeatures that are required by old or broken applications" -msgstr "" - -#: ../src/metacity.schemas.in.h:15 -msgid "Enable Visual Bell" -msgstr "" - -#: ../src/metacity.schemas.in.h:16 -msgid "Hide all windows and focus desktop" -msgstr "" - -#: ../src/metacity.schemas.in.h:17 -msgid "" -"If true, and the focus mode is either \"sloppy\" or \"mouse\" then the " -"focused window will be automatically raised after a delay (the delay is " -"specified by the auto_raise_delay key)." -msgstr "" - -#: ../src/metacity.schemas.in.h:18 -msgid "" -"If true, ignore the titlebar_font option, and use the standard application " -"font for window titles." -msgstr "" - -#: ../src/metacity.schemas.in.h:19 -msgid "" -"If true, metacity will give the user less feedback and less sense of " -"\"direct manipulation\", by using wireframes, avoiding animations, or other " -"means. This is a significant reduction in usability for many users, but may " -"allow legacy applications and terminal servers to function when they would " -"otherwise be impractical. However, the wireframe feature is disabled when " -"accessibility is on to avoid weird desktop breakages." -msgstr "" - -#: ../src/metacity.schemas.in.h:20 -msgid "" -"If true, then Metacity works in terms of applications rather than windows. " -"The concept is a bit abstract, but in general an application-based setup is " -"more like the Mac and less like Windows. When you focus a window in " -"application-based mode, all the windows in the application will be raised. " -"Also, in application-based mode, focus clicks are not passed through to " -"windows in other applications. The existence of this setting is somewhat " -"questionable. But it's better than having settings for all the specific " -"details of application-based vs. window-based, e.g. whether to pass through " -"clicks. Also, application-based mode is largely unimplemented at the moment." -msgstr "" - -#: ../src/metacity.schemas.in.h:21 -msgid "If true, trade off usability for less resource usage" -msgstr "" - -#: ../src/metacity.schemas.in.h:22 -msgid "Lower window below other windows" -msgstr "" - -#: ../src/metacity.schemas.in.h:23 -#, fuzzy -msgid "Maximize window" -msgstr "መስኮትን አስተልቅ" - -#: ../src/metacity.schemas.in.h:24 -msgid "Maximize window horizontally" -msgstr "" - -#: ../src/metacity.schemas.in.h:25 -msgid "Maximize window vertically" -msgstr "" - -#: ../src/metacity.schemas.in.h:26 -#, fuzzy -msgid "Minimize window" -msgstr "መስኮትን አሳንስ" - -#: ../src/metacity.schemas.in.h:27 -msgid "Modifier to use for modified window click actions" -msgstr "" - -#: ../src/metacity.schemas.in.h:28 -msgid "Move backward between panels and the desktop immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:29 -msgid "Move backwards between panels and the desktop with popup" -msgstr "" - -#: ../src/metacity.schemas.in.h:30 -msgid "Move backwards between windows immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:31 -msgid "Move between panels and the desktop immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:32 -msgid "Move between panels and the desktop with popup" -msgstr "" - -#: ../src/metacity.schemas.in.h:33 -msgid "Move between windows immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:34 -msgid "Move between windows with popup" -msgstr "" - -#: ../src/metacity.schemas.in.h:35 -msgid "Move focus backwards between windows using popup display" -msgstr "" - -#: ../src/metacity.schemas.in.h:36 -#, fuzzy -msgid "Move window" -msgstr "መስኮትን አንቀሳቅስ" - -#: ../src/metacity.schemas.in.h:37 -msgid "Move window one workspace down" -msgstr "" - -#: ../src/metacity.schemas.in.h:38 -msgid "Move window one workspace to the left" -msgstr "" - -#: ../src/metacity.schemas.in.h:39 -msgid "Move window one workspace to the right" -msgstr "" - -#: ../src/metacity.schemas.in.h:40 -msgid "Move window one workspace up" -msgstr "" - -#: ../src/metacity.schemas.in.h:41 -msgid "Move window to workspace 1" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 1 አንቀሳቅስ" - -#: ../src/metacity.schemas.in.h:42 -msgid "Move window to workspace 10" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 10 አንቀሳቅስ" - -#: ../src/metacity.schemas.in.h:43 -msgid "Move window to workspace 11" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 11 አንቀሳቅስ" - -#: ../src/metacity.schemas.in.h:44 -msgid "Move window to workspace 12" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 12 አንቀሳቅስ" - -#: ../src/metacity.schemas.in.h:45 -msgid "Move window to workspace 2" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 2 አንቀሳቅስ" - -#: ../src/metacity.schemas.in.h:46 -msgid "Move window to workspace 3" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 3 አንቀሳቅስ" - -#: ../src/metacity.schemas.in.h:47 -msgid "Move window to workspace 4" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 4 አንቀሳቅስ" - -#: ../src/metacity.schemas.in.h:48 -msgid "Move window to workspace 5" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 5 አንቀሳቅስ" - -#: ../src/metacity.schemas.in.h:49 -msgid "Move window to workspace 6" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 6 አንቀሳቅስ" - -#: ../src/metacity.schemas.in.h:50 -msgid "Move window to workspace 7" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 7 አንቀሳቅስ" - -#: ../src/metacity.schemas.in.h:51 -msgid "Move window to workspace 8" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 8 አንቀሳቅስ" - -#: ../src/metacity.schemas.in.h:52 -msgid "Move window to workspace 9" -msgstr "መስኮትን ወደ መሥሪያ ቦታ 9 አንቀሳቅስ" - -#: ../src/metacity.schemas.in.h:53 -msgid "Name of workspace" -msgstr "የመሥሪያ ቦታ ስም" - -#: ../src/metacity.schemas.in.h:54 -msgid "Number of workspaces" -msgstr "የመሥሪያ ቦታዎች ብዛት" - -#: ../src/metacity.schemas.in.h:55 -msgid "" -"Number of workspaces. Must be more than zero, and has a fixed maximum (to " -"prevent accidentally destroying your desktop by asking for 34 million " -"workspaces)." -msgstr "" - -#: ../src/metacity.schemas.in.h:56 -msgid "Raise obscured window, otherwise lower" -msgstr "" - -#: ../src/metacity.schemas.in.h:57 -msgid "Raise window above other windows" -msgstr "" - -#: ../src/metacity.schemas.in.h:58 -#, fuzzy -msgid "Resize window" -msgstr "መስኮትን አሳንስ" - -#: ../src/metacity.schemas.in.h:59 -msgid "Run a defined command" -msgstr "" - -#: ../src/metacity.schemas.in.h:60 -msgid "Run a terminal" -msgstr "" - -#: ../src/metacity.schemas.in.h:61 -msgid "Show the panel menu" -msgstr "" - -#: ../src/metacity.schemas.in.h:62 -msgid "Show the panel run application dialog" -msgstr "" - -#: ../src/metacity.schemas.in.h:63 -msgid "" -"Some applications break specifications in ways that result in window manager " -"misfeatures. For example, ideally Metacity would place all dialogs in a " -"consistent position with respect to their parent window. This requires " -"ignoring application-specified positions for dialogs. But some versions of " -"Java/Swing mark their popup menus as dialogs, so Metacity has to disable " -"dialog positioning to allow menus to work in broken Java applications. There " -"are several other examples like this. This option puts Metacity in full-on " -"Correct mode, which perhaps gives a moderately nicer UI if you don't need to " -"run any broken apps. Sadly, workarounds must be enabled by default; the real " -"world is an ugly place. Some of the workarounds are workarounds for " -"limitations in the specifications themselves, so sometimes a bug in no-" -"workarounds mode won't be fixable without amending a spec." -msgstr "" - -#: ../src/metacity.schemas.in.h:64 -msgid "Switch to workspace 1" -msgstr "ወደ መሥሪያ ቦታ 1 ቀይር" - -#: ../src/metacity.schemas.in.h:65 -msgid "Switch to workspace 10" -msgstr "ወደ መሥሪያ ቦታ 10 ቀይር" - -#: ../src/metacity.schemas.in.h:66 -msgid "Switch to workspace 11" -msgstr "ወደ መሥሪያ ቦታ 11 ቀይር" - -#: ../src/metacity.schemas.in.h:67 -msgid "Switch to workspace 12" -msgstr "ወደ መሥሪያ ቦታ 12 ቀይር" - -#: ../src/metacity.schemas.in.h:68 -msgid "Switch to workspace 2" -msgstr "ወደ መሥሪያ ቦታ 2 ቀይር" - -#: ../src/metacity.schemas.in.h:69 -msgid "Switch to workspace 3" -msgstr "ወደ መሥሪያ ቦታ 3 ቀይር" - -#: ../src/metacity.schemas.in.h:70 -msgid "Switch to workspace 4" -msgstr "ወደ መሥሪያ ቦታ 4 ቀይር" - -#: ../src/metacity.schemas.in.h:71 -msgid "Switch to workspace 5" -msgstr "ወደ መሥሪያ ቦታ 5 ቀይር" - -#: ../src/metacity.schemas.in.h:72 -msgid "Switch to workspace 6" -msgstr "ወደ መሥሪያ ቦታ 6 ቀይር" - -#: ../src/metacity.schemas.in.h:73 -msgid "Switch to workspace 7" -msgstr "ወደ መሥሪያ ቦታ 7 ቀይር" - -#: ../src/metacity.schemas.in.h:74 -msgid "Switch to workspace 8" -msgstr "ወደ መሥሪያ ቦታ 8 ቀይር" - -#: ../src/metacity.schemas.in.h:75 -msgid "Switch to workspace 9" -msgstr "ወደ መሥሪያ ቦታ 9 ቀይር" - -#: ../src/metacity.schemas.in.h:76 -msgid "Switch to workspace above this one" -msgstr "" - -#: ../src/metacity.schemas.in.h:77 -msgid "Switch to workspace below this one" -msgstr "" - -#: ../src/metacity.schemas.in.h:78 -msgid "Switch to workspace on the left" -msgstr "" - -#: ../src/metacity.schemas.in.h:79 -msgid "Switch to workspace on the right" -msgstr "" - -#: ../src/metacity.schemas.in.h:80 -msgid "System Bell is Audible" -msgstr "" - -#: ../src/metacity.schemas.in.h:81 -msgid "Take a screenshot" -msgstr "" - -#: ../src/metacity.schemas.in.h:82 -msgid "Take a screenshot of a window" -msgstr "" - -#: ../src/metacity.schemas.in.h:83 -msgid "" -"Tells Metacity how to implement the visual indication that the system bell " -"or another application 'bell' indicator has been rung. Currently there are " -"two valid values, \"fullscreen\", which causes a fullscreen white-black " -"flash, and \"frame_flash\" which causes the titlebar of the application " -"which sent the bell signal to flash. If the application which sent the bell " -"is unknown (as is usually the case for the default \"system beep\"), the " -"currently focused window's titlebar is flashed." -msgstr "" - -#: ../src/metacity.schemas.in.h:84 -msgid "" -"The /apps/metacity/global_keybindings/run_command_N keys define keybindings " -"that correspond to these commands. Pressing the keybinding for run_command_N " -"will execute command_N." -msgstr "" - -#: ../src/metacity.schemas.in.h:85 -msgid "" -"The /apps/metacity/global_keybindings/run_command_screenshot key defines a " -"keybinding which causes the command specified by this setting to be invoked." -msgstr "" - -#: ../src/metacity.schemas.in.h:86 -msgid "" -"The /apps/metacity/global_keybindings/run_command_window_screenshot key " -"defines a keybinding which causes the command specified by this setting to " -"be invoked." -msgstr "" - -#: ../src/metacity.schemas.in.h:87 -msgid "" -"The keybinding that runs the correspondingly-numbered command in /apps/" -"metacity/keybinding_commands The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:88 -msgid "" -"The keybinding that switches to the workspace above the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:89 -msgid "" -"The keybinding that switches to the workspace below the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:90 -msgid "" -"The keybinding that switches to the workspace on the left of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:91 -msgid "" -"The keybinding that switches to the workspace on the right of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:92 -msgid "" -"The keybinding that switches to workspace 1. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:93 -msgid "" -"The keybinding that switches to workspace 10. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:94 -msgid "" -"The keybinding that switches to workspace 11. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:95 -msgid "" -"The keybinding that switches to workspace 12. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:96 -msgid "" -"The keybinding that switches to workspace 2. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:97 -msgid "" -"The keybinding that switches to workspace 3. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:98 -msgid "" -"The keybinding that switches to workspace 4. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:99 -msgid "" -"The keybinding that switches to workspace 5. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:100 -msgid "" -"The keybinding that switches to workspace 6. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:101 -msgid "" -"The keybinding that switches to workspace 7. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:102 -msgid "" -"The keybinding that switches to workspace 8. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:103 -msgid "" -"The keybinding that switches to workspace 9. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:104 -msgid "" -"The keybinding used to activate the window menu. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:105 -msgid "" -"The keybinding used to close a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:106 -msgid "" -"The keybinding used to enter \"move mode\" and begin moving a window using " -"the keyboard. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:107 -msgid "" -"The keybinding used to enter \"resize mode\" and begin resizing a window " -"using the keyboard. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:108 -msgid "" -"The keybinding used to hide all normal windows and set the focus to the " -"desktop background. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:109 -msgid "" -"The keybinding used to maximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:110 -msgid "" -"The keybinding used to minimize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:111 -msgid "" -"The keybinding used to move a window one workspace down. The format looks " -"like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -"fairly liberal and allows lower or upper case, and also abbreviations such " -"as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action." -msgstr "" - -#: ../src/metacity.schemas.in.h:112 -msgid "" -"The keybinding used to move a window one workspace to the left. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:113 -msgid "" -"The keybinding used to move a window one workspace to the right. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:114 -msgid "" -"The keybinding used to move a window one workspace up. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:115 -msgid "" -"The keybinding used to move a window to workspace 1. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:116 -msgid "" -"The keybinding used to move a window to workspace 10. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:117 -msgid "" -"The keybinding used to move a window to workspace 11. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:118 -msgid "" -"The keybinding used to move a window to workspace 12. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:119 -msgid "" -"The keybinding used to move a window to workspace 2. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:120 -msgid "" -"The keybinding used to move a window to workspace 3. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:121 -msgid "" -"The keybinding used to move a window to workspace 4. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:122 -msgid "" -"The keybinding used to move a window to workspace 5. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:123 -msgid "" -"The keybinding used to move a window to workspace 6. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:124 -msgid "" -"The keybinding used to move a window to workspace 7. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:125 -msgid "" -"The keybinding used to move a window to workspace 8. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:126 -msgid "" -"The keybinding used to move a window to workspace 9. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:127 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"using a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:128 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"without a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:129 -msgid "" -"The keybinding used to move focus backwards between windows without a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:130 -msgid "" -"The keybinding used to move focus backwards between windows, using a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:131 -msgid "" -"The keybinding used to move focus between panels and the desktop, using a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:132 -msgid "" -"The keybinding used to move focus between panels and the desktop, without a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:133 -msgid "" -"The keybinding used to move focus between windows without a popup window. " -"(Traditionally <Alt>Escape) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:134 -msgid "" -"The keybinding used to move focus between windows, using a popup window. " -"(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:135 -msgid "" -"The keybinding used to toggle always on top. A window that is always on top " -"will always be visible over other overlapping windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:136 -msgid "" -"The keybinding used to toggle fullscreen mode. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:137 -msgid "" -"The keybinding used to toggle maximization. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:138 -msgid "" -"The keybinding used to toggle shaded/unshaded state. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:139 -msgid "" -"The keybinding used to toggle whether the window is on all workspaces or " -"just one. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:140 -msgid "" -"The keybinding used to unmaximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:141 -msgid "" -"The keybinding which display's the panel's \"Run Application\" dialog box. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:142 -msgid "" -"The keybinding which invokes a terminal. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:143 -msgid "" -"The keybinding which invokes the panel's screenshot utility to take a " -"screenshot of a window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:144 -msgid "" -"The keybinding which invokes the panel's screenshot utility. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:145 -msgid "" -"The keybinding which shows the panel's main menu. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:146 -msgid "The name of a workspace." -msgstr "" - -#: ../src/metacity.schemas.in.h:147 -msgid "The screenshot command" -msgstr "" - -#: ../src/metacity.schemas.in.h:148 -msgid "" -"The theme determines the appearance of window borders, titlebar, and so " -"forth." -msgstr "" - -#: ../src/metacity.schemas.in.h:149 -msgid "" -"The time delay before raising a window if auto_raise is set to true. The " -"delay is given in thousandths of a second." -msgstr "" - -#: ../src/metacity.schemas.in.h:150 -msgid "" -"The window focus mode indicates how windows are activated. It has three " -"possible values; \"click\" means windows must be clicked in order to focus " -"them, \"sloppy\" means windows are focused when the mouse enters the window, " -"and \"mouse\" means windows are focused when the mouse enters the window and " -"unfocused when the mouse leaves the window." -msgstr "" - -#: ../src/metacity.schemas.in.h:151 -msgid "The window screenshot command" -msgstr "" - -#: ../src/metacity.schemas.in.h:152 -msgid "" -"This keybinding changes whether a window is above or below other windows. If " -"the window is covered by another window, it raises the window above other " -"windows. If the window is already fully visible, it lowers the window below " -"other windows. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:153 -msgid "" -"This keybinding lowers a window below other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:154 -msgid "" -"This keybinding raises the window above other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:155 -msgid "" -"This keybinding resizes a window to fill available horizontal space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:156 -msgid "" -"This keybinding resizes a window to fill available vertical space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:157 -msgid "" -"This option determines the effects of double-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, and 'toggle_maximize' which will maximize/unmaximize the window." -msgstr "" - -#: ../src/metacity.schemas.in.h:158 -msgid "Toggle always on top state" -msgstr "" - -#: ../src/metacity.schemas.in.h:159 -msgid "Toggle fullscreen mode" -msgstr "የሙሉ እስክሪን ዘዴን ቀያይሩ" - -#: ../src/metacity.schemas.in.h:160 -msgid "Toggle maximization state" -msgstr "" - -#: ../src/metacity.schemas.in.h:161 -msgid "Toggle shaded state" -msgstr "" - -#: ../src/metacity.schemas.in.h:162 -msgid "Toggle window on all workspaces" -msgstr "" - -#: ../src/metacity.schemas.in.h:163 -msgid "" -"Turns on a visual indication when an application or the system issues a " -"'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -"environments, or when 'audible bell' is off." -msgstr "" - -#: ../src/metacity.schemas.in.h:164 -#, fuzzy -msgid "Unmaximize window" -msgstr "መስኮቱን አታስተልቅ" - -#: ../src/metacity.schemas.in.h:165 -msgid "Use standard system font in window titles" -msgstr "" - -#: ../src/metacity.schemas.in.h:166 -msgid "Visual Bell Type" -msgstr "" - -#: ../src/metacity.schemas.in.h:167 -msgid "Window focus mode" -msgstr "" - -#: ../src/metacity.schemas.in.h:168 -msgid "Window title font" -msgstr "የመስኮት አርእስት የፊደል ቅርጽ" - -#: ../src/prefs.c:528 ../src/prefs.c:544 ../src/prefs.c:560 ../src/prefs.c:576 -#: ../src/prefs.c:592 ../src/prefs.c:612 ../src/prefs.c:628 ../src/prefs.c:644 -#: ../src/prefs.c:660 ../src/prefs.c:676 ../src/prefs.c:692 ../src/prefs.c:708 -#: ../src/prefs.c:724 ../src/prefs.c:741 ../src/prefs.c:757 ../src/prefs.c:773 -#: ../src/prefs.c:789 ../src/prefs.c:805 ../src/prefs.c:820 ../src/prefs.c:835 -#: ../src/prefs.c:850 ../src/prefs.c:866 ../src/prefs.c:882 ../src/prefs.c:898 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "" - -#: ../src/prefs.c:943 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" - -#: ../src/prefs.c:967 ../src/prefs.c:1428 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "" - -#: ../src/prefs.c:1145 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "" - -#: ../src/prefs.c:1330 -#, c-format -msgid "" -"%d stored in GConf key %s is not a reasonable number of workspaces, current " -"maximum is %d\n" -msgstr "" - -#: ../src/prefs.c:1390 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" - -#: ../src/prefs.c:1455 -#, c-format -msgid "%d stored in GConf key %s is out of range 0 to %d\n" -msgstr "" - -#: ../src/prefs.c:1589 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "" - -#: ../src/prefs.c:1833 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" - -#: ../src/prefs.c:2187 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "" - -#: ../src/resizepopup.c:126 -#, c-format -msgid "%d x %d" -msgstr "%d በ %d" - -#: ../src/screen.c:408 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "" - -#: ../src/screen.c:424 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" - -#: ../src/screen.c:448 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" - -#: ../src/screen.c:506 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "" - -#: ../src/screen.c:716 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "" - -#: ../src/session.c:884 ../src/session.c:891 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "" - -#: ../src/session.c:901 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "" - -#: ../src/session.c:1053 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "" - -#: ../src/session.c:1058 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "" - -#: ../src/session.c:1133 -#, c-format -msgid "Failed to read saved session file %s: %s\n" -msgstr "" - -#: ../src/session.c:1168 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "" - -#: ../src/session.c:1217 -msgid " attribute seen but we already have the session ID" -msgstr "" - -#: ../src/session.c:1230 -#, c-format -msgid "Unknown attribute %s on element" -msgstr "" - -#: ../src/session.c:1247 -msgid "nested tag" -msgstr "" - -#: ../src/session.c:1305 ../src/session.c:1337 -#, c-format -msgid "Unknown attribute %s on element" -msgstr "" - -#: ../src/session.c:1409 -#, c-format -msgid "Unknown attribute %s on element" -msgstr "" - -#: ../src/session.c:1469 -#, c-format -msgid "Unknown attribute %s on element" -msgstr "" - -#: ../src/session.c:1489 -#, c-format -msgid "Unknown element %s" -msgstr "" - -#: ../src/session.c:1961 -#, c-format -msgid "" -"Error launching metacity-dialog to warn about apps that don't support " -"session management: %s\n" -msgstr "" - -#: ../src/theme-parser.c:224 ../src/theme-parser.c:242 -#, c-format -msgid "Line %d character %d: %s" -msgstr "" - -#: ../src/theme-parser.c:396 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "" - -#: ../src/theme-parser.c:414 ../src/theme-parser.c:439 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "" - -#: ../src/theme-parser.c:485 -#, c-format -msgid "Integer %ld must be positive" -msgstr "" - -#: ../src/theme-parser.c:493 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "" - -#: ../src/theme-parser.c:521 ../src/theme-parser.c:602 -#: ../src/theme-parser.c:626 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "" - -#: ../src/theme-parser.c:552 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "" - -#: ../src/theme-parser.c:572 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "" - -#: ../src/theme-parser.c:638 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" - -#: ../src/theme-parser.c:684 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" - -#: ../src/theme-parser.c:729 ../src/theme-parser.c:737 -#: ../src/theme-parser.c:807 ../src/theme-parser.c:897 -#: ../src/theme-parser.c:935 ../src/theme-parser.c:1012 -#: ../src/theme-parser.c:1062 ../src/theme-parser.c:1070 -#: ../src/theme-parser.c:1126 ../src/theme-parser.c:1134 -#: ../src/theme-parser.c:2936 ../src/theme-parser.c:3025 -#: ../src/theme-parser.c:3032 ../src/theme-parser.c:3039 -#, c-format -msgid "No \"%s\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:837 ../src/theme-parser.c:905 -#: ../src/theme-parser.c:943 ../src/theme-parser.c:1020 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "" - -#: ../src/theme-parser.c:849 ../src/theme-parser.c:955 -#: ../src/theme-parser.c:1032 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "" - -#: ../src/theme-parser.c:968 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "" - -#: ../src/theme-parser.c:981 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" - -#: ../src/theme-parser.c:1080 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:1091 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:1099 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "" - -#: ../src/theme-parser.c:1143 -#, c-format -msgid "Unknown function \"%s\" for menu icon" -msgstr "" - -#: ../src/theme-parser.c:1152 -#, c-format -msgid "Unknown state \"%s\" for menu icon" -msgstr "" - -#: ../src/theme-parser.c:1160 -#, c-format -msgid "Theme already has a menu icon for function %s state %s" -msgstr "" - -#: ../src/theme-parser.c:1177 ../src/theme-parser.c:3244 -#: ../src/theme-parser.c:3323 -#, c-format -msgid "No with the name \"%s\" has been defined" -msgstr "" - -#: ../src/theme-parser.c:1192 ../src/theme-parser.c:1256 -#: ../src/theme-parser.c:1545 ../src/theme-parser.c:3124 -#: ../src/theme-parser.c:3178 ../src/theme-parser.c:3338 -#: ../src/theme-parser.c:3515 ../src/theme-parser.c:3553 -#: ../src/theme-parser.c:3591 ../src/theme-parser.c:3629 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "" - -#: ../src/theme-parser.c:1282 ../src/theme-parser.c:1369 -#: ../src/theme-parser.c:1439 -#, c-format -msgid "No \"name\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1289 ../src/theme-parser.c:1376 -#, c-format -msgid "No \"value\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1320 ../src/theme-parser.c:1334 -#: ../src/theme-parser.c:1393 -msgid "" -"Cannot specify both button_width/button_height and aspect ratio for buttons" -msgstr "" - -#: ../src/theme-parser.c:1343 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "" - -#: ../src/theme-parser.c:1402 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "" - -#: ../src/theme-parser.c:1446 -#, c-format -msgid "No \"top\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1453 -#, c-format -msgid "No \"bottom\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1460 -#, c-format -msgid "No \"left\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1467 -#, c-format -msgid "No \"right\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1499 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "" - -#: ../src/theme-parser.c:1655 ../src/theme-parser.c:1765 -#: ../src/theme-parser.c:1868 ../src/theme-parser.c:2055 -#: ../src/theme-parser.c:2869 -#, c-format -msgid "No \"color\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1662 -#, c-format -msgid "No \"x1\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1669 ../src/theme-parser.c:2714 -#, c-format -msgid "No \"y1\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1676 -#, c-format -msgid "No \"x2\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1683 ../src/theme-parser.c:2721 -#, c-format -msgid "No \"y2\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1772 ../src/theme-parser.c:1875 -#: ../src/theme-parser.c:1981 ../src/theme-parser.c:2062 -#: ../src/theme-parser.c:2168 ../src/theme-parser.c:2266 -#: ../src/theme-parser.c:2483 ../src/theme-parser.c:2609 -#: ../src/theme-parser.c:2707 ../src/theme-parser.c:2781 -#: ../src/theme-parser.c:2876 -#, c-format -msgid "No \"x\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1779 ../src/theme-parser.c:1882 -#: ../src/theme-parser.c:1988 ../src/theme-parser.c:2069 -#: ../src/theme-parser.c:2175 ../src/theme-parser.c:2273 -#: ../src/theme-parser.c:2490 ../src/theme-parser.c:2616 -#: ../src/theme-parser.c:2788 ../src/theme-parser.c:2883 -#, c-format -msgid "No \"y\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1786 ../src/theme-parser.c:1889 -#: ../src/theme-parser.c:1995 ../src/theme-parser.c:2076 -#: ../src/theme-parser.c:2182 ../src/theme-parser.c:2280 -#: ../src/theme-parser.c:2497 ../src/theme-parser.c:2623 -#: ../src/theme-parser.c:2795 -#, c-format -msgid "No \"width\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1793 ../src/theme-parser.c:1896 -#: ../src/theme-parser.c:2002 ../src/theme-parser.c:2083 -#: ../src/theme-parser.c:2189 ../src/theme-parser.c:2287 -#: ../src/theme-parser.c:2504 ../src/theme-parser.c:2630 -#: ../src/theme-parser.c:2802 -#, c-format -msgid "No \"height\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1903 -#, c-format -msgid "No \"start_angle\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1910 -#, c-format -msgid "No \"extent_angle\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:2090 -#, c-format -msgid "No \"alpha\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:2161 -#, c-format -msgid "No \"type\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:2209 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "" - -#: ../src/theme-parser.c:2294 -#, c-format -msgid "No \"filename\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:2319 ../src/theme-parser.c:2827 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "" - -#: ../src/theme-parser.c:2462 ../src/theme-parser.c:2595 -#: ../src/theme-parser.c:2700 -#, c-format -msgid "No \"state\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:2469 ../src/theme-parser.c:2602 -#, c-format -msgid "No \"shadow\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:2476 -#, c-format -msgid "No \"arrow\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:2529 ../src/theme-parser.c:2651 -#: ../src/theme-parser.c:2739 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "" - -#: ../src/theme-parser.c:2539 ../src/theme-parser.c:2661 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "" - -#: ../src/theme-parser.c:2549 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "" - -#: ../src/theme-parser.c:2962 ../src/theme-parser.c:3078 -#, c-format -msgid "No called \"%s\" has been defined" -msgstr "" - -#: ../src/theme-parser.c:2974 ../src/theme-parser.c:3090 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "" - -#: ../src/theme-parser.c:3153 -#, c-format -msgid "No \"value\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:3210 -#, c-format -msgid "No \"position\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:3219 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "" - -#: ../src/theme-parser.c:3227 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "" - -#: ../src/theme-parser.c:3272 -#, c-format -msgid "No \"function\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:3280 ../src/theme-parser.c:3384 -#, c-format -msgid "No \"state\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:3289 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "" - -#: ../src/theme-parser.c:3298 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "" - -#: ../src/theme-parser.c:3306 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "" - -#: ../src/theme-parser.c:3376 -#, c-format -msgid "No \"focus\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:3392 -#, c-format -msgid "No \"style\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:3401 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "" - -#: ../src/theme-parser.c:3410 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "" - -#: ../src/theme-parser.c:3420 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "" - -#: ../src/theme-parser.c:3430 -#, c-format -msgid "No \"resize\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:3440 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "" - -#: ../src/theme-parser.c:3450 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" - -#: ../src/theme-parser.c:3464 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" - -#: ../src/theme-parser.c:3475 ../src/theme-parser.c:3486 -#: ../src/theme-parser.c:3497 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "" - -#: ../src/theme-parser.c:3536 -msgid "" -"Can't have a two draw_ops for a element (theme specified a draw_ops " -"attribute and also a element, or specified two elements)" -msgstr "" - -#: ../src/theme-parser.c:3574 -msgid "" -"Can't have a two draw_ops for a