Merge clutter's master branch into mutter

https://bugzilla.gnome.org/show_bug.cgi?id=760439
This commit is contained in:
Rui Matos 2016-04-27 18:34:03 +02:00
commit a7b5d790ac
511 changed files with 207879 additions and 0 deletions

96
clutter/.gitignore vendored Normal file
View File

@ -0,0 +1,96 @@
ABOUT-NLS
INSTALL
Makefile
Makefile.in
aclocal.m4
autom4te.cache
compile
*.pc
.deps
.libs
*.o
*.lo
*.la
*.gcov
.dirstamp
README
stamp-enum-types
stamp-marshal
tags
/ChangeLog*
/clutter/clutter-config.h
/clutter/clutter-enum-types.[ch]
/clutter/clutter-marshal.[ch]
/clutter/clutter-version.h
/clutter/gcov-report.txt
/clutter/clutter-json.h
/clutter/*.log
/clutter/*.trs
/clutter-lcov.info
/clutter-lcov
!/build/autotools/introspection.m4
!/build/autotools/as-linguas.m4
!/build/autotools/as-compiler-flag.m4
!/build/autotools/glibtests.m4
/build/autotools/*.m4
/build/test-driver
*.gir
*.typelib
*.gcda
*.gcno
config.*
configure
depcomp
/doc/cookbook/*.pdf
/doc/cookbook/html
/doc/cookbook/*.stamp
/doc/cookbook/clutter-cookbook.xml
/doc/cookbook/clutter-cookbook.html
doc/reference/clutter-*.txt
!/doc/reference/clutter-sections.txt
doc/reference/html
doc/reference/tmpl
doc/reference/xml
doc/reference/clutter.args
doc/reference/clutter.hierarchy
doc/reference/clutter.interfaces
doc/reference/clutter.prerequisites
doc/reference/clutter.signals
doc/reference/clutter-docs.xml
doc/reference/*.stamp
doc/reference/*.bak
doc/reference/*.log
doc/reference/gtkdoc-check.*
gtk-doc.make
install-sh
libtool
ltmain.sh
missing
mkinstalldirs
stamp-h1
TAGS
/tests/tools/disable-npots.sh
/tests/conform/test-launcher.sh
/tests/interactive/wrapper.sh
/po/POTFILES
/po/clutter-1.0.pot
/po/*.gmo
/po/Makefile.in.in
/po/Makevars.template
/po/Rules-quot
/po/boldquot.sed
/po/en@boldquot.header
/po/en@quot.header
/po/insert-header.sin
/po/quot.sed
/po/remove-potcdate.sin
/po/remove-potcdate.sed
/po/stamp-po
*.swn
*.swo
*.swp
*~
*.orig
*.rej
.DS_Store
.testlogs-*

53
clutter/Makefile.am Normal file
View File

@ -0,0 +1,53 @@
NULL =
SUBDIRS = build clutter tests
if BUILD_EXAMPLES
SUBDIRS += examples
endif
DIST_SUBDIRS = clutter tests examples build
# XXX - this is a massive hack to make autoreconf honour the ACLOCAL_FLAGS
# that jhbuild sets while still retaining build/autotools as the authoritative
# source for m4 macros
ACLOCAL_AMFLAGS = -I build/autotools ${ACLOCAL_FLAGS}
CLEANFILES = $(pcfiles)
DISTCLEANFILES =
DISTCHECK_CONFIGURE_FLAGS = --enable-maintainer-flags
# proxy rules for tests
test-report full-report:
$(MAKE) -C tests/conform $(@)
perf-report:
$(MAKE) -C tests/performance $(@)
if ENABLE_GCOV
# use recursive makes in order to ignore errors during check/perf
lcov:
-$(MAKE) $(AM_MAKEFLAGS) -C clutter check
-$(MAKE) $(AM_MAKEFLAGS) -C tests/conform test
$(MAKE) $(AM_MAKEFLAGS) genlcov
# we have to massage the lcov.info file slightly to hide the effect of libtool
# placing the objects files in the .libs/ directory separate from the *.c
genlcov:
$(LTP) --directory $(top_builddir) --capture --output-file clutter-lcov.info --test-name CLUTTER_TEST --no-checksum
$(SED) -e 's#.libs/##' < clutter-lcov.info > clutter-lcov.info.tmp
LANG=C $(LTP_GENHTML) --prefix $(top_builddir) --output-directory clutter-lcov --title "Clutter Code Coverage" --show-details clutter-lcov.info.tmp
rm -f clutter-lcov.info.tmp
lcov-clean:
-$(LTP) --directory $(top_builddir) -z
-$(RM) -rf clutter-lcov.info clutter-lcov
else
lcov genlcov lcov-clean:
@echo You need to configure Clutter with support for gcov enabled.
@echo e.g., ./configure --enable-gcov
endif
.PHONY: test-report full-report perf-report lcov genlcov lcov-clean

View File

@ -0,0 +1 @@
SUBDIRS = autotools

8
clutter/build/autotools/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
gtk-doc.m4
libtool.m4
ltoptions.m4
ltsugar.m4
ltversion.m4
lt~obsolete.m4
shave
shave-libtool

View File

@ -0,0 +1,10 @@
NULL =
EXTRA_DIST = \
introspection.m4 \
as-compiler-flag.m4 \
glibtests.m4 \
glib-tap.mk \
tap-driver.sh \
tap-test \
$(NULL)

View File

@ -0,0 +1,62 @@
dnl as-compiler-flag.m4 0.1.0
dnl autostars m4 macro for detection of compiler flags
dnl David Schleef <ds@schleef.org>
dnl $Id: as-compiler-flag.m4,v 1.1 2005/12/15 23:35:19 ds Exp $
dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED])
dnl Tries to compile with the given CFLAGS.
dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags,
dnl and ACTION-IF-NOT-ACCEPTED otherwise.
AC_DEFUN([AS_COMPILER_FLAG],
[
AC_MSG_CHECKING([to see if compiler understands $1])
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $1"
AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no])
CFLAGS="$save_CFLAGS"
if test "X$flag_ok" = Xyes ; then
m4_ifvaln([$2],[$2])
true
else
m4_ifvaln([$3],[$3])
true
fi
AC_MSG_RESULT([$flag_ok])
])
dnl AS_COMPILER_FLAGS(VAR, FLAGS)
dnl Tries to compile with the given CFLAGS.
AC_DEFUN([AS_COMPILER_FLAGS],
[
list=$2
flags_supported=""
flags_unsupported=""
AC_MSG_CHECKING([for supported compiler flags])
for each in $list
do
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $each"
AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no])
CFLAGS="$save_CFLAGS"
if test "X$flag_ok" = Xyes ; then
flags_supported="$flags_supported $each"
else
flags_unsupported="$flags_unsupported $each"
fi
done
AC_MSG_RESULT([$flags_supported])
if test "X$flags_unsupported" != X ; then
AC_MSG_WARN([unsupported compiler flags: $flags_unsupported])
fi
$1="$$1 $flags_supported"
])

View File

@ -0,0 +1,134 @@
# GLIB - Library of useful C routines
TESTS_ENVIRONMENT= \
G_TEST_SRCDIR="$(abs_srcdir)" \
G_TEST_BUILDDIR="$(abs_builddir)" \
G_DEBUG=gc-friendly \
MALLOC_CHECK_=2 \
MALLOC_PERTURB_=$$(($${RANDOM:-256} % 256))
LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/build/autotools/tap-driver.sh
LOG_COMPILER = $(top_srcdir)/build/autotools/tap-test
NULL =
# initialize variables for unconditional += appending
BUILT_SOURCES =
BUILT_EXTRA_DIST =
CLEANFILES = *.log *.trs
DISTCLEANFILES =
MAINTAINERCLEANFILES =
EXTRA_DIST =
TESTS =
installed_test_LTLIBRARIES =
installed_test_PROGRAMS =
installed_test_SCRIPTS =
nobase_installed_test_DATA =
noinst_LTLIBRARIES =
noinst_PROGRAMS =
noinst_SCRIPTS =
noinst_DATA =
check_LTLIBRARIES =
check_PROGRAMS =
check_SCRIPTS =
check_DATA =
# We support a fairly large range of possible variables. It is expected that all types of files in a test suite
# will belong in exactly one of the following variables.
#
# First, we support the usual automake suffixes, but in lowercase, with the customary meaning:
#
# test_programs, test_scripts, test_data, test_ltlibraries
#
# The above are used to list files that are involved in both uninstalled and installed testing. The
# test_programs and test_scripts are taken to be actual testcases and will be run as part of the test suite.
# Note that _data is always used with the nobase_ automake variable name to ensure that installed test data is
# installed in the same way as it appears in the package layout.
#
# In order to mark a particular file as being only for one type of testing, use 'installed' or 'uninstalled',
# like so:
#
# installed_test_programs, uninstalled_test_programs
# installed_test_scripts, uninstalled_test_scripts
# installed_test_data, uninstalled_test_data
# installed_test_ltlibraries, uninstalled_test_ltlibraries
#
# Additionally, we support 'extra' infixes for programs and scripts. This is used for support programs/scripts
# that should not themselves be run as testcases (but exist to be used from other testcases):
#
# test_extra_programs, installed_test_extra_programs, uninstalled_test_extra_programs
# test_extra_scripts, installed_test_extra_scripts, uninstalled_test_extra_scripts
#
# Additionally, for _scripts and _data, we support the customary dist_ prefix so that the named script or data
# file automatically end up in the tarball.
#
# dist_test_scripts, dist_test_data, dist_test_extra_scripts
# dist_installed_test_scripts, dist_installed_test_data, dist_installed_test_extra_scripts
# dist_uninstalled_test_scripts, dist_uninstalled_test_data, dist_uninstalled_test_extra_scripts
#
# Note that no file is automatically disted unless it appears in one of the dist_ variables. This follows the
# standard automake convention of not disting programs scripts or data by default.
#
# test_programs, test_scripts, uninstalled_test_programs and uninstalled_test_scripts (as well as their disted
# variants) will be run as part of the in-tree 'make check'. These are all assumed to be runnable under
# gtester. That's a bit strange for scripts, but it's possible.
TESTS += $(test_programs) $(test_scripts) $(uninstalled_test_programs) $(uninstalled_test_scripts) \
$(dist_test_scripts) $(dist_uninstalled_test_scripts)
# Note: build even the installed-only targets during 'make check' to ensure that they still work.
# We need to do a bit of trickery here and manage disting via EXTRA_DIST instead of using dist_ prefixes to
# prevent automake from mistreating gmake functions like $(wildcard ...) and $(addprefix ...) as if they were
# filenames, including removing duplicate instances of the opening part before the space, eg. '$(addprefix'.
all_test_programs = $(test_programs) $(uninstalled_test_programs) $(installed_test_programs) \
$(test_extra_programs) $(uninstalled_test_extra_programs) $(installed_test_extra_programs)
all_test_scripts = $(test_scripts) $(uninstalled_test_scripts) $(installed_test_scripts) \
$(test_extra_scripts) $(uninstalled_test_extra_scripts) $(installed_test_extra_scripts)
all_dist_test_scripts = $(dist_test_scripts) $(dist_uninstalled_test_scripts) $(dist_installed_test_scripts) \
$(dist_test_extra_scripts) $(dist_uninstalled_test_extra_scripts) $(dist_installed_test_extra_scripts)
all_test_scripts += $(all_dist_test_scripts)
EXTRA_DIST += $(all_dist_test_scripts)
all_test_data = $(test_data) $(uninstalled_test_data) $(installed_test_data)
all_dist_test_data = $(dist_test_data) $(dist_uninstalled_test_data) $(dist_installed_test_data)
all_test_data += $(all_dist_test_data)
EXTRA_DIST += $(all_dist_test_data)
all_test_ltlibs = $(test_ltlibraries) $(uninstalled_test_ltlibraries) $(installed_test_ltlibraries)
if ENABLE_ALWAYS_BUILD_TESTS
noinst_LTLIBRARIES += $(all_test_ltlibs)
noinst_PROGRAMS += $(all_test_programs)
noinst_SCRIPTS += $(all_test_scripts)
noinst_DATA += $(all_test_data)
else
check_LTLIBRARIES += $(all_test_ltlibs)
check_PROGRAMS += $(all_test_programs)
check_SCRIPTS += $(all_test_scripts)
check_DATA += $(all_test_data)
endif
if ENABLE_INSTALLED_TESTS
installed_test_PROGRAMS += $(test_programs) $(installed_test_programs) \
$(test_extra_programs) $(installed_test_extra_programs)
installed_test_SCRIPTS += $(test_scripts) $(installed_test_scripts) \
$(test_extra_scripts) $(test_installed_extra_scripts)
installed_test_SCRIPTS += $(dist_test_scripts) $(dist_test_extra_scripts) \
$(dist_installed_test_scripts) $(dist_installed_test_extra_scripts)
nobase_installed_test_DATA += $(test_data) $(installed_test_data)
nobase_installed_test_DATA += $(dist_test_data) $(dist_installed_test_data)
installed_test_LTLIBRARIES += $(test_ltlibraries) $(installed_test_ltlibraries)
installed_testcases = $(test_programs) $(installed_test_programs) \
$(test_scripts) $(installed_test_scripts) \
$(dist_test_scripts) $(dist_installed_test_scripts)
installed_test_meta_DATA = $(installed_testcases:=.test)
%.test: %$(EXEEXT) Makefile
$(AM_V_GEN) (echo '[Test]' > $@.tmp; \
echo 'Type=session' >> $@.tmp; \
echo 'Exec=env G_ENABLE_DIAGNOSTIC=0 CLUTTER_ENABLE_DIAGNOSTIC=0 $(installed_testdir)/$<' >> $@.tmp; \
mv $@.tmp $@)
CLEANFILES += $(installed_test_meta_DATA)
endif

View File

@ -0,0 +1,28 @@
dnl GLIB_TESTS
dnl
AC_DEFUN([GLIB_TESTS],
[
AC_ARG_ENABLE(installed-tests,
AS_HELP_STRING([--enable-installed-tests],
[Enable installation of some test cases]),
[case ${enableval} in
yes) ENABLE_INSTALLED_TESTS="1" ;;
no) ENABLE_INSTALLED_TESTS="" ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-installed-tests]) ;;
esac])
AM_CONDITIONAL([ENABLE_INSTALLED_TESTS], test "$ENABLE_INSTALLED_TESTS" = "1")
AC_ARG_ENABLE(always-build-tests,
AS_HELP_STRING([--enable-always-build-tests],
[Enable always building tests during 'make all']),
[case ${enableval} in
yes) ENABLE_ALWAYS_BUILD_TESTS="1" ;;
no) ENABLE_ALWAYS_BUILD_TESTS="" ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-always-build-tests]) ;;
esac])
AM_CONDITIONAL([ENABLE_ALWAYS_BUILD_TESTS], test "$ENABLE_ALWAYS_BUILD_TESTS" = "1")
if test "$ENABLE_INSTALLED_TESTS" = "1"; then
AC_SUBST(installed_test_metadir, [${datadir}/installed-tests/]AC_PACKAGE_NAME)
AC_SUBST(installed_testdir, [${libexecdir}/installed-tests/]AC_PACKAGE_NAME)
fi
])

View File

@ -0,0 +1,96 @@
dnl -*- mode: autoconf -*-
dnl Copyright 2009 Johan Dahlin
dnl
dnl This file is free software; the author(s) gives unlimited
dnl permission to copy and/or distribute it, with or without
dnl modifications, as long as this notice is preserved.
dnl
# serial 1
m4_define([_GOBJECT_INTROSPECTION_CHECK_INTERNAL],
[
AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first
AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first
AC_BEFORE([LT_INIT],[$0])dnl setup libtool first
dnl enable/disable introspection
m4_if([$2], [require],
[dnl
enable_introspection=yes
],[dnl
AC_ARG_ENABLE(introspection,
AS_HELP_STRING([--enable-introspection[=@<:@no/auto/yes@:>@]],
[Enable introspection for this build]),,
[enable_introspection=auto])
])dnl
AC_MSG_CHECKING([for gobject-introspection])
dnl presence/version checking
AS_CASE([$enable_introspection],
[no], [dnl
found_introspection="no (disabled, use --enable-introspection to enable)"
],dnl
[yes],[dnl
PKG_CHECK_EXISTS([gobject-introspection-1.0],,
AC_MSG_ERROR([gobject-introspection-1.0 is not installed]))
PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1],
found_introspection=yes,
AC_MSG_ERROR([You need to have gobject-introspection >= $1 installed to build AC_PACKAGE_NAME]))
],dnl
[auto],[dnl
PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], found_introspection=yes, found_introspection=no)
dnl Canonicalize enable_introspection
enable_introspection=$found_introspection
],dnl
[dnl
AC_MSG_ERROR([invalid argument passed to --enable-introspection, should be one of @<:@no/auto/yes@:>@])
])dnl
AC_MSG_RESULT([$found_introspection])
INTROSPECTION_SCANNER=
INTROSPECTION_COMPILER=
INTROSPECTION_GENERATE=
INTROSPECTION_GIRDIR=
INTROSPECTION_TYPELIBDIR=
if test "x$found_introspection" = "xyes"; then
INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0`
INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0`
INTROSPECTION_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0`
INTROSPECTION_GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0`
INTROSPECTION_TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)"
INTROSPECTION_CFLAGS=`$PKG_CONFIG --cflags gobject-introspection-1.0`
INTROSPECTION_LIBS=`$PKG_CONFIG --libs gobject-introspection-1.0`
INTROSPECTION_MAKEFILE=`$PKG_CONFIG --variable=datadir gobject-introspection-1.0`/gobject-introspection-1.0/Makefile.introspection
fi
AC_SUBST(INTROSPECTION_SCANNER)
AC_SUBST(INTROSPECTION_COMPILER)
AC_SUBST(INTROSPECTION_GENERATE)
AC_SUBST(INTROSPECTION_GIRDIR)
AC_SUBST(INTROSPECTION_TYPELIBDIR)
AC_SUBST(INTROSPECTION_CFLAGS)
AC_SUBST(INTROSPECTION_LIBS)
AC_SUBST(INTROSPECTION_MAKEFILE)
AM_CONDITIONAL(HAVE_INTROSPECTION, test "x$found_introspection" = "xyes")
])
dnl Usage:
dnl GOBJECT_INTROSPECTION_CHECK([minimum-g-i-version])
AC_DEFUN([GOBJECT_INTROSPECTION_CHECK],
[
_GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1])
])
dnl Usage:
dnl GOBJECT_INTROSPECTION_REQUIRE([minimum-g-i-version])
AC_DEFUN([GOBJECT_INTROSPECTION_REQUIRE],
[
_GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1], [require])
])

View File

@ -0,0 +1,652 @@
#! /bin/sh
# Copyright (C) 2011-2013 Free Software Foundation, 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, 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 <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
scriptversion=2011-12-27.17; # UTC
# Make unconditional expansion of undefined variables an error. This
# helps a lot in preventing typo-related bugs.
set -u
me=tap-driver.sh
fatal ()
{
echo "$me: fatal: $*" >&2
exit 1
}
usage_error ()
{
echo "$me: $*" >&2
print_usage >&2
exit 2
}
print_usage ()
{
cat <<END
Usage:
tap-driver.sh --test-name=NAME --log-file=PATH --trs-file=PATH
[--expect-failure={yes|no}] [--color-tests={yes|no}]
[--enable-hard-errors={yes|no}] [--ignore-exit]
[--diagnostic-string=STRING] [--merge|--no-merge]
[--comments|--no-comments] [--] TEST-COMMAND
The \`--test-name', \`--log-file' and \`--trs-file' options are mandatory.
END
}
# TODO: better error handling in option parsing (in particular, ensure
# TODO: $log_file, $trs_file and $test_name are defined).
test_name= # Used for reporting.
log_file= # Where to save the result and output of the test script.
trs_file= # Where to save the metadata of the test run.
expect_failure=0
color_tests=0
merge=0
ignore_exit=0
comments=0
diag_string='#'
while test $# -gt 0; do
case $1 in
--help) print_usage; exit $?;;
--version) echo "$me $scriptversion"; exit $?;;
--test-name) test_name=$2; shift;;
--log-file) log_file=$2; shift;;
--trs-file) trs_file=$2; shift;;
--color-tests) color_tests=$2; shift;;
--expect-failure) expect_failure=$2; shift;;
--enable-hard-errors) shift;; # No-op.
--merge) merge=1;;
--no-merge) merge=0;;
--ignore-exit) ignore_exit=1;;
--comments) comments=1;;
--no-comments) comments=0;;
--diagnostic-string) diag_string=$2; shift;;
--) shift; break;;
-*) usage_error "invalid option: '$1'";;
esac
shift
done
test $# -gt 0 || usage_error "missing test command"
case $expect_failure in
yes) expect_failure=1;;
*) expect_failure=0;;
esac
if test $color_tests = yes; then
init_colors='
color_map["red"]="" # Red.
color_map["grn"]="" # Green.
color_map["lgn"]="" # Light green.
color_map["blu"]="" # Blue.
color_map["mgn"]="" # Magenta.
color_map["std"]="" # No color.
color_for_result["ERROR"] = "mgn"
color_for_result["PASS"] = "grn"
color_for_result["XPASS"] = "red"
color_for_result["FAIL"] = "red"
color_for_result["XFAIL"] = "lgn"
color_for_result["SKIP"] = "blu"'
else
init_colors=''
fi
# :; is there to work around a bug in bash 3.2 (and earlier) which
# does not always set '$?' properly on redirection failure.
# See the Autoconf manual for more details.
:;{
(
# Ignore common signals (in this subshell only!), to avoid potential
# problems with Korn shells. Some Korn shells are known to propagate
# to themselves signals that have killed a child process they were
# waiting for; this is done at least for SIGINT (and usually only for
# it, in truth). Without the `trap' below, such a behaviour could
# cause a premature exit in the current subshell, e.g., in case the
# test command it runs gets terminated by a SIGINT. Thus, the awk
# script we are piping into would never seen the exit status it
# expects on its last input line (which is displayed below by the
# last `echo $?' statement), and would thus die reporting an internal
# error.
# For more information, see the Autoconf manual and the threads:
# <http://lists.gnu.org/archive/html/bug-autoconf/2011-09/msg00004.html>
# <http://mail.opensolaris.org/pipermail/ksh93-integration-discuss/2009-February/004121.html>
trap : 1 3 2 13 15
if test $merge -gt 0; then
exec 2>&1
else
exec 2>&3
fi
"$@"
echo $?
) | LC_ALL=C ${AM_TAP_AWK-awk} \
-v me="$me" \
-v test_script_name="$test_name" \
-v log_file="$log_file" \
-v trs_file="$trs_file" \
-v expect_failure="$expect_failure" \
-v merge="$merge" \
-v ignore_exit="$ignore_exit" \
-v comments="$comments" \
-v diag_string="$diag_string" \
'
# FIXME: the usages of "cat >&3" below could be optimized when using
# FIXME: GNU awk, and/on on systems that supports /dev/fd/.
# Implementation note: in what follows, `result_obj` will be an
# associative array that (partly) simulates a TAP result object
# from the `TAP::Parser` perl module.
## ----------- ##
## FUNCTIONS ##
## ----------- ##
function fatal(msg)
{
print me ": " msg | "cat >&2"
exit 1
}
function abort(where)
{
fatal("internal error " where)
}
# Convert a boolean to a "yes"/"no" string.
function yn(bool)
{
return bool ? "yes" : "no";
}
function add_test_result(result)
{
if (!test_results_index)
test_results_index = 0
test_results_list[test_results_index] = result
test_results_index += 1
test_results_seen[result] = 1;
}
# Whether the test script should be re-run by "make recheck".
function must_recheck()
{
for (k in test_results_seen)
if (k != "XFAIL" && k != "PASS" && k != "SKIP")
return 1
return 0
}
# Whether the content of the log file associated to this test should
# be copied into the "global" test-suite.log.
function copy_in_global_log()
{
for (k in test_results_seen)
if (k != "PASS")
return 1
return 0
}
# FIXME: this can certainly be improved ...
function get_global_test_result()
{
if ("ERROR" in test_results_seen)
return "ERROR"
if ("FAIL" in test_results_seen || "XPASS" in test_results_seen)
return "FAIL"
all_skipped = 1
for (k in test_results_seen)
if (k != "SKIP")
all_skipped = 0
if (all_skipped)
return "SKIP"
return "PASS";
}
function stringify_result_obj(result_obj)
{
if (result_obj["is_unplanned"] || result_obj["number"] != testno)
return "ERROR"
if (plan_seen == LATE_PLAN)
return "ERROR"
if (result_obj["directive"] == "TODO")
return result_obj["is_ok"] ? "XPASS" : "XFAIL"
if (result_obj["directive"] == "SKIP")
return result_obj["is_ok"] ? "SKIP" : COOKED_FAIL;
if (length(result_obj["directive"]))
abort("in function stringify_result_obj()")
return result_obj["is_ok"] ? COOKED_PASS : COOKED_FAIL
}
function decorate_result(result)
{
color_name = color_for_result[result]
if (color_name)
return color_map[color_name] "" result "" color_map["std"]
# If we are not using colorized output, or if we do not know how
# to colorize the given result, we should return it unchanged.
return result
}
function report(result, details)
{
if (result ~ /^(X?(PASS|FAIL)|SKIP|ERROR)/)
{
msg = ": " test_script_name
add_test_result(result)
}
else if (result == "#")
{
msg = " " test_script_name ":"
}
else
{
abort("in function report()")
}
if (length(details))
msg = msg " " details
# Output on console might be colorized.
print decorate_result(result) msg
# Log the result in the log file too, to help debugging (this is
# especially true when said result is a TAP error or "Bail out!").
print result msg | "cat >&3";
}
function testsuite_error(error_message)
{
report("ERROR", "- " error_message)
}
function handle_tap_result()
{
details = result_obj["number"];
if (length(result_obj["description"]))
details = details " " result_obj["description"]
if (plan_seen == LATE_PLAN)
{
details = details " # AFTER LATE PLAN";
}
else if (result_obj["is_unplanned"])
{
details = details " # UNPLANNED";
}
else if (result_obj["number"] != testno)
{
details = sprintf("%s # OUT-OF-ORDER (expecting %d)",
details, testno);
}
else if (result_obj["directive"])
{
details = details " # " result_obj["directive"];
if (length(result_obj["explanation"]))
details = details " " result_obj["explanation"]
}
report(stringify_result_obj(result_obj), details)
}
# `skip_reason` should be empty whenever planned > 0.
function handle_tap_plan(planned, skip_reason)
{
planned += 0 # Avoid getting confused if, say, `planned` is "00"
if (length(skip_reason) && planned > 0)
abort("in function handle_tap_plan()")
if (plan_seen)
{
# Error, only one plan per stream is acceptable.
testsuite_error("multiple test plans")
return;
}
planned_tests = planned
# The TAP plan can come before or after *all* the TAP results; we speak
# respectively of an "early" or a "late" plan. If we see the plan line
# after at least one TAP result has been seen, assume we have a late
# plan; in this case, any further test result seen after the plan will
# be flagged as an error.
plan_seen = (testno >= 1 ? LATE_PLAN : EARLY_PLAN)
# If testno > 0, we have an error ("too many tests run") that will be
# automatically dealt with later, so do not worry about it here. If
# $plan_seen is true, we have an error due to a repeated plan, and that
# has already been dealt with above. Otherwise, we have a valid "plan
# with SKIP" specification, and should report it as a particular kind
# of SKIP result.
if (planned == 0 && testno == 0)
{
if (length(skip_reason))
skip_reason = "- " skip_reason;
report("SKIP", skip_reason);
}
}
function extract_tap_comment(line)
{
if (index(line, diag_string) == 1)
{
# Strip leading `diag_string` from `line`.
line = substr(line, length(diag_string) + 1)
# And strip any leading and trailing whitespace left.
sub("^[ \t]*", "", line)
sub("[ \t]*$", "", line)
# Return what is left (if any).
return line;
}
return "";
}
# When this function is called, we know that line is a TAP result line,
# so that it matches the (perl) RE "^(not )?ok\b".
function setup_result_obj(line)
{
# Get the result, and remove it from the line.
result_obj["is_ok"] = (substr(line, 1, 2) == "ok" ? 1 : 0)
sub("^(not )?ok[ \t]*", "", line)
# If the result has an explicit number, get it and strip it; otherwise,
# automatically assing the next progresive number to it.
if (line ~ /^[0-9]+$/ || line ~ /^[0-9]+[^a-zA-Z0-9_]/)
{
match(line, "^[0-9]+")
# The final `+ 0` is to normalize numbers with leading zeros.
result_obj["number"] = substr(line, 1, RLENGTH) + 0
line = substr(line, RLENGTH + 1)
}
else
{
result_obj["number"] = testno
}
if (plan_seen == LATE_PLAN)
# No further test results are acceptable after a "late" TAP plan
# has been seen.
result_obj["is_unplanned"] = 1
else if (plan_seen && testno > planned_tests)
result_obj["is_unplanned"] = 1
else
result_obj["is_unplanned"] = 0
# Strip trailing and leading whitespace.
sub("^[ \t]*", "", line)
sub("[ \t]*$", "", line)
# This will have to be corrected if we have a "TODO"/"SKIP" directive.
result_obj["description"] = line
result_obj["directive"] = ""
result_obj["explanation"] = ""
if (index(line, "#") == 0)
return # No possible directive, nothing more to do.
# Directives are case-insensitive.
rx = "[ \t]*#[ \t]*([tT][oO][dD][oO]|[sS][kK][iI][pP])[ \t]*"
# See whether we have the directive, and if yes, where.
pos = match(line, rx "$")
if (!pos)
pos = match(line, rx "[^a-zA-Z0-9_]")
# If there was no TAP directive, we have nothing more to do.
if (!pos)
return
# Let`s now see if the TAP directive has been escaped. For example:
# escaped: ok \# SKIP
# not escaped: ok \\# SKIP
# escaped: ok \\\\\# SKIP
# not escaped: ok \ # SKIP
if (substr(line, pos, 1) == "#")
{
bslash_count = 0
for (i = pos; i > 1 && substr(line, i - 1, 1) == "\\"; i--)
bslash_count += 1
if (bslash_count % 2)
return # Directive was escaped.
}
# Strip the directive and its explanation (if any) from the test
# description.
result_obj["description"] = substr(line, 1, pos - 1)
# Now remove the test description from the line, that has been dealt
# with already.
line = substr(line, pos)
# Strip the directive, and save its value (normalized to upper case).
sub("^[ \t]*#[ \t]*", "", line)
result_obj["directive"] = toupper(substr(line, 1, 4))
line = substr(line, 5)
# Now get the explanation for the directive (if any), with leading
# and trailing whitespace removed.
sub("^[ \t]*", "", line)
sub("[ \t]*$", "", line)
result_obj["explanation"] = line
}
function get_test_exit_message(status)
{
if (status == 0)
return ""
if (status !~ /^[1-9][0-9]*$/)
abort("getting exit status")
if (status < 127)
exit_details = ""
else if (status == 127)
exit_details = " (command not found?)"
else if (status >= 128 && status <= 255)
exit_details = sprintf(" (terminated by signal %d?)", status - 128)
else if (status > 256 && status <= 384)
# We used to report an "abnormal termination" here, but some Korn
# shells, when a child process die due to signal number n, can leave
# in $? an exit status of 256+n instead of the more standard 128+n.
# Apparently, both behaviours are allowed by POSIX (2008), so be
# prepared to handle them both. See also Austing Group report ID
# 0000051 <http://www.austingroupbugs.net/view.php?id=51>
exit_details = sprintf(" (terminated by signal %d?)", status - 256)
else
# Never seen in practice.
exit_details = " (abnormal termination)"
return sprintf("exited with status %d%s", status, exit_details)
}
function write_test_results()
{
print ":global-test-result: " get_global_test_result() > trs_file
print ":recheck: " yn(must_recheck()) > trs_file
print ":copy-in-global-log: " yn(copy_in_global_log()) > trs_file
for (i = 0; i < test_results_index; i += 1)
print ":test-result: " test_results_list[i] > trs_file
close(trs_file);
}
BEGIN {
## ------- ##
## SETUP ##
## ------- ##
'"$init_colors"'
# Properly initialized once the TAP plan is seen.
planned_tests = 0
COOKED_PASS = expect_failure ? "XPASS": "PASS";
COOKED_FAIL = expect_failure ? "XFAIL": "FAIL";
# Enumeration-like constants to remember which kind of plan (if any)
# has been seen. It is important that NO_PLAN evaluates "false" as
# a boolean.
NO_PLAN = 0
EARLY_PLAN = 1
LATE_PLAN = 2
testno = 0 # Number of test results seen so far.
bailed_out = 0 # Whether a "Bail out!" directive has been seen.
# Whether the TAP plan has been seen or not, and if yes, which kind
# it is ("early" is seen before any test result, "late" otherwise).
plan_seen = NO_PLAN
## --------- ##
## PARSING ##
## --------- ##
is_first_read = 1
while (1)
{
# Involutions required so that we are able to read the exit status
# from the last input line.
st = getline
if (st < 0) # I/O error.
fatal("I/O error while reading from input stream")
else if (st == 0) # End-of-input
{
if (is_first_read)
abort("in input loop: only one input line")
break
}
if (is_first_read)
{
is_first_read = 0
nextline = $0
continue
}
else
{
curline = nextline
nextline = $0
$0 = curline
}
# Copy any input line verbatim into the log file.
print | "cat >&3"
# Parsing of TAP input should stop after a "Bail out!" directive.
if (bailed_out)
continue
# TAP test result.
if ($0 ~ /^(not )?ok$/ || $0 ~ /^(not )?ok[^a-zA-Z0-9_]/)
{
testno += 1
setup_result_obj($0)
handle_tap_result()
}
# TAP plan (normal or "SKIP" without explanation).
else if ($0 ~ /^1\.\.[0-9]+[ \t]*$/)
{
# The next two lines will put the number of planned tests in $0.
sub("^1\\.\\.", "")
sub("[^0-9]*$", "")
handle_tap_plan($0, "")
continue
}
# TAP "SKIP" plan, with an explanation.
else if ($0 ~ /^1\.\.0+[ \t]*#/)
{
# The next lines will put the skip explanation in $0, stripping
# any leading and trailing whitespace. This is a little more
# tricky in truth, since we want to also strip a potential leading
# "SKIP" string from the message.
sub("^[^#]*#[ \t]*(SKIP[: \t][ \t]*)?", "")
sub("[ \t]*$", "");
handle_tap_plan(0, $0)
}
# "Bail out!" magic.
# Older versions of prove and TAP::Harness (e.g., 3.17) did not
# recognize a "Bail out!" directive when preceded by leading
# whitespace, but more modern versions (e.g., 3.23) do. So we
# emulate the latter, "more modern" behaviour.
else if ($0 ~ /^[ \t]*Bail out!/)
{
bailed_out = 1
# Get the bailout message (if any), with leading and trailing
# whitespace stripped. The message remains stored in `$0`.
sub("^[ \t]*Bail out![ \t]*", "");
sub("[ \t]*$", "");
# Format the error message for the
bailout_message = "Bail out!"
if (length($0))
bailout_message = bailout_message " " $0
testsuite_error(bailout_message)
}
# Maybe we have too look for dianogtic comments too.
else if (comments != 0)
{
comment = extract_tap_comment($0);
if (length(comment))
report("#", comment);
}
}
## -------- ##
## FINISH ##
## -------- ##
# A "Bail out!" directive should cause us to ignore any following TAP
# error, as well as a non-zero exit status from the TAP producer.
if (!bailed_out)
{
if (!plan_seen)
{
testsuite_error("missing test plan")
}
else if (planned_tests != testno)
{
bad_amount = testno > planned_tests ? "many" : "few"
testsuite_error(sprintf("too %s tests run (expected %d, got %d)",
bad_amount, planned_tests, testno))
}
if (!ignore_exit)
{
# Fetch exit status from the last line.
exit_message = get_test_exit_message(nextline)
if (exit_message)
testsuite_error(exit_message)
}
}
write_test_results()
exit 0
} # End of "BEGIN" block.
'
# TODO: document that we consume the file descriptor 3 :-(
} 3>"$log_file"
test $? -eq 0 || fatal "I/O or internal error"
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View File

@ -0,0 +1,5 @@
#! /bin/sh
# run a GTest in tap mode. The test binary is passed as $1
$1 -k --tap

681
clutter/clutter/Makefile.am Normal file
View File

@ -0,0 +1,681 @@
AUTOMAKE_OPTIONS = subdir-objects
# preamble
NULL =
# common definitions
CLEANFILES =
DISTCLEANFILES =
EXTRA_DIST =
BUILT_SOURCES =
AM_CPPFLAGS = \
-DCLUTTER_PREFIX=\""$(prefix)"\" \
-DCLUTTER_LIBDIR=\""$(libdir)"\" \
-DCLUTTER_DATADIR=\""$(datadir)"\" \
-DCLUTTER_LOCALEDIR=\""$(localedir)"\" \
-DCLUTTER_SYSCONFDIR=\""$(sysconfdir)"\" \
-DCLUTTER_COMPILATION=1 \
-DCOGL_ENABLE_EXPERIMENTAL_API \
-DCOGL_DISABLE_DEPRECATION_WARNINGS \
-DG_LOG_DOMAIN=\"Clutter\" \
-I$(top_srcdir) \
-I$(top_srcdir)/clutter \
-I$(top_srcdir)/clutter/cally \
-I$(top_builddir) \
-I$(top_builddir)/clutter \
$(CLUTTER_DEPRECATED_CFLAGS) \
$(CLUTTER_DEBUG_CFLAGS) \
$(CLUTTER_HIDDEN_VISIBILITY_CFLAGS) \
$(NULL)
AM_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS)
# these are the gir files we generate using g-ir-scanner
INTROSPECTION_GIRS =
# the base include path for headers
clutter_base_includedir = $(includedir)/mutter/clutter-$(CLUTTER_API_VERSION)
clutter_includedir = $(clutter_base_includedir)/clutter
clutter_deprecateddir = $(clutter_base_includedir)/clutter/deprecated
# pkg-config files
pc_files =
# common sources - please, keep these sorted alphabetically
source_h = \
clutter-action.h \
clutter-actor-meta.h \
clutter-actor.h \
clutter-align-constraint.h \
clutter-animatable.h \
clutter-backend.h \
clutter-bind-constraint.h \
clutter-binding-pool.h \
clutter-bin-layout.h \
clutter-blur-effect.h \
clutter-box-layout.h \
clutter-brightness-contrast-effect.h \
clutter-cairo.h \
clutter-canvas.h \
clutter-child-meta.h \
clutter-click-action.h \
clutter-cogl-compat.h \
clutter-clone.h \
clutter-color-static.h \
clutter-color.h \
clutter-colorize-effect.h \
clutter-constraint.h \
clutter-container.h \
clutter-content.h \
clutter-deform-effect.h \
clutter-deprecated.h \
clutter-desaturate-effect.h \
clutter-device-manager.h \
clutter-drag-action.h \
clutter-drop-action.h \
clutter-effect.h \
clutter-enums.h \
clutter-event.h \
clutter-feature.h \
clutter-fixed-layout.h \
clutter-flow-layout.h \
clutter-gesture-action.h \
clutter-grid-layout.h \
clutter-group.h \
clutter-image.h \
clutter-input-device.h \
clutter-interval.h \
clutter-keyframe-transition.h \
clutter-keysyms.h \
clutter-layout-manager.h \
clutter-layout-meta.h \
clutter-macros.h \
clutter-main.h \
clutter-offscreen-effect.h \
clutter-page-turn-effect.h \
clutter-paint-nodes.h \
clutter-paint-node.h \
clutter-pan-action.h \
clutter-path-constraint.h \
clutter-path.h \
clutter-property-transition.h \
clutter-rotate-action.h \
clutter-script.h \
clutter-scriptable.h \
clutter-scroll-actor.h \
clutter-settings.h \
clutter-shader-effect.h \
clutter-shader-types.h \
clutter-swipe-action.h \
clutter-snap-constraint.h \
clutter-stage.h \
clutter-stage-manager.h \
clutter-tap-action.h \
clutter-test-utils.h \
clutter-texture.h \
clutter-text.h \
clutter-text-buffer.h \
clutter-timeline.h \
clutter-transition-group.h \
clutter-transition.h \
clutter-types.h \
clutter-units.h \
clutter-zoom-action.h \
$(NULL)
source_c = \
clutter-action.c \
clutter-actor-box.c \
clutter-actor-meta.c \
clutter-actor.c \
clutter-align-constraint.c \
clutter-animatable.c \
clutter-backend.c \
clutter-base-types.c \
clutter-bezier.c \
clutter-bind-constraint.c \
clutter-binding-pool.c \
clutter-bin-layout.c \
clutter-blur-effect.c \
clutter-box-layout.c \
clutter-brightness-contrast-effect.c \
clutter-cairo.c \
clutter-canvas.c \
clutter-child-meta.c \
clutter-click-action.c \
clutter-clone.c \
clutter-color.c \
clutter-colorize-effect.c \
clutter-constraint.c \
clutter-container.c \
clutter-content.c \
clutter-deform-effect.c \
clutter-desaturate-effect.c \
clutter-device-manager.c \
clutter-drag-action.c \
clutter-drop-action.c \
clutter-effect.c \
clutter-event.c \
clutter-feature.c \
clutter-fixed-layout.c \
clutter-flatten-effect.c \
clutter-flow-layout.c \
clutter-gesture-action.c \
clutter-grid-layout.c \
clutter-image.c \
clutter-input-device.c \
clutter-interval.c \
clutter-keyframe-transition.c \
clutter-keysyms-table.c \
clutter-layout-manager.c \
clutter-layout-meta.c \
clutter-main.c \
clutter-master-clock.c \
clutter-master-clock-default.c \
clutter-offscreen-effect.c \
clutter-page-turn-effect.c \
clutter-paint-nodes.c \
clutter-paint-node.c \
clutter-pan-action.c \
clutter-path-constraint.c \
clutter-path.c \
clutter-property-transition.c \
clutter-rotate-action.c \
clutter-script.c \
clutter-script-parser.c \
clutter-scriptable.c \
clutter-scroll-actor.c \
clutter-settings.c \
clutter-shader-effect.c \
clutter-shader-types.c \
clutter-swipe-action.c \
clutter-snap-constraint.c \
clutter-stage.c \
clutter-stage-manager.c \
clutter-stage-window.c \
clutter-tap-action.c \
clutter-test-utils.c \
clutter-text.c \
clutter-text-buffer.c \
clutter-transition-group.c \
clutter-transition.c \
clutter-timeline.c \
clutter-units.c \
clutter-util.c \
clutter-paint-volume.c \
clutter-zoom-action.c \
$(NULL)
# private headers; these should not be distributed or introspected
source_h_priv = \
clutter-actor-meta-private.h \
clutter-actor-private.h \
clutter-backend-private.h \
clutter-bezier.h \
clutter-constraint-private.h \
clutter-content-private.h \
clutter-debug.h \
clutter-device-manager-private.h \
clutter-easing.h \
clutter-effect-private.h \
clutter-event-translator.h \
clutter-event-private.h \
clutter-flatten-effect.h \
clutter-gesture-action-private.h \
clutter-id-pool.h \
clutter-master-clock.h \
clutter-master-clock-default.h \
clutter-offscreen-effect-private.h \
clutter-paint-node-private.h \
clutter-paint-volume-private.h \
clutter-private.h \
clutter-script-private.h \
clutter-settings-private.h \
clutter-stage-manager-private.h \
clutter-stage-private.h \
clutter-stage-window.h \
$(NULL)
# private source code; these should not be introspected
source_c_priv = \
clutter-easing.c \
clutter-event-translator.c \
clutter-id-pool.c \
$(NULL)
# deprecated installed headers
deprecated_h = \
deprecated/clutter-actor.h \
deprecated/clutter-alpha.h \
deprecated/clutter-animatable.h \
deprecated/clutter-animation.h \
deprecated/clutter-animator.h \
deprecated/clutter-backend.h \
deprecated/clutter-behaviour.h \
deprecated/clutter-behaviour-depth.h \
deprecated/clutter-behaviour-ellipse.h \
deprecated/clutter-behaviour-opacity.h \
deprecated/clutter-behaviour-path.h \
deprecated/clutter-behaviour-rotate.h \
deprecated/clutter-behaviour-scale.h \
deprecated/clutter-bin-layout.h \
deprecated/clutter-box.h \
deprecated/clutter-cairo-texture.h \
deprecated/clutter-container.h \
deprecated/clutter-fixed.h \
deprecated/clutter-frame-source.h \
deprecated/clutter-group.h \
deprecated/clutter-input-device.h \
deprecated/clutter-keysyms.h \
deprecated/clutter-list-model.h \
deprecated/clutter-main.h \
deprecated/clutter-media.h \
deprecated/clutter-model.h \
deprecated/clutter-rectangle.h \
deprecated/clutter-score.h \
deprecated/clutter-shader.h \
deprecated/clutter-stage-manager.h \
deprecated/clutter-stage.h \
deprecated/clutter-state.h \
deprecated/clutter-table-layout.h \
deprecated/clutter-texture.h \
deprecated/clutter-timeline.h \
deprecated/clutter-timeout-pool.h \
deprecated/clutter-util.h \
$(NULL)
# deprecated source code
deprecated_c = \
deprecated/clutter-actor-deprecated.c \
deprecated/clutter-alpha.c \
deprecated/clutter-animation.c \
deprecated/clutter-animator.c \
deprecated/clutter-behaviour.c \
deprecated/clutter-behaviour-depth.c \
deprecated/clutter-behaviour-ellipse.c \
deprecated/clutter-behaviour-opacity.c \
deprecated/clutter-behaviour-path.c \
deprecated/clutter-behaviour-rotate.c \
deprecated/clutter-behaviour-scale.c \
deprecated/clutter-box.c \
deprecated/clutter-cairo-texture.c \
deprecated/clutter-fixed.c \
deprecated/clutter-frame-source.c \
deprecated/clutter-group.c \
deprecated/clutter-input-device-deprecated.c \
deprecated/clutter-layout-manager-deprecated.c \
deprecated/clutter-list-model.c \
deprecated/clutter-media.c \
deprecated/clutter-model.c \
deprecated/clutter-rectangle.c \
deprecated/clutter-score.c \
deprecated/clutter-shader.c \
deprecated/clutter-state.c \
deprecated/clutter-table-layout.c \
deprecated/clutter-texture.c \
deprecated/clutter-timeout-pool.c \
$(NULL)
# deprecated private headers; these should not be installed
deprecated_h_priv = \
deprecated/clutter-model-private.h \
deprecated/clutter-timeout-interval.h \
$(NULL)
# deprecated private source code; these should not be introspected
deprecated_c_priv = \
deprecated/clutter-timeout-interval.c \
$(NULL)
# built sources
built_source_c = \
clutter-enum-types.c \
clutter-marshal.c \
$(NULL)
# built headers
built_source_h = \
clutter-enum-types.h \
clutter-marshal.h \
$(NULL)
# config header
DISTCLEANFILES += clutter-config.h
EXTRA_DIST += clutter-config.h.in
# version header
DISTCLEANFILES += clutter-version.h
EXTRA_DIST += clutter-version.h.in clutter-version.h
# key symbol update script
EXTRA_DIST += clutter-keysyms-update.pl
pc_files += mutter-clutter-$(CLUTTER_API_VERSION).pc
# in order to be compatible with Clutter < 1.10, when we shipped a single
# shared library whose name was determined by the single backend it
# supported, we need to install symbolic links so that existing applications
# using Clutter won't break in the Brave New World of multi-backend support
# in the same shared object.
compat_libs =
# backends source listings
#
# backend_source_c := source code
# backend_source_h := installed public headers
# backend_source_c_priv := source that should not be scanned by g-i
# backend_source_h_priv := private headers
# backend_source_built := built sources
#
backend_source_c =
backend_source_h =
backend_source_c_priv =
backend_source_h_priv =
backend_source_built =
# X11 backend rules
x11_source_c = \
x11/clutter-backend-x11.c \
x11/clutter-device-manager-core-x11.c \
x11/clutter-event-x11.c \
x11/clutter-input-device-core-x11.c \
x11/clutter-keymap-x11.c \
x11/clutter-stage-x11.c \
x11/clutter-x11-texture-pixmap.c \
$(NULL)
x11_source_h = \
x11/clutter-x11.h \
x11/clutter-x11-texture-pixmap.h \
$(NULL)
x11_source_h_priv = \
x11/clutter-backend-x11.h \
x11/clutter-device-manager-core-x11.h \
x11/clutter-input-device-core-x11.h \
x11/clutter-keymap-x11.h \
x11/clutter-settings-x11.h \
x11/clutter-stage-x11.h \
$(NULL)
x11_source_c_priv = \
x11/xsettings/xsettings-client.c \
x11/xsettings/xsettings-client.h \
x11/xsettings/xsettings-common.c \
x11/xsettings/xsettings-common.h \
$(NULL)
x11_source_c += \
x11/clutter-device-manager-xi2.c \
x11/clutter-input-device-xi2.c \
$(NULL)
x11_source_h_priv += \
x11/clutter-device-manager-xi2.h \
x11/clutter-input-device-xi2.h \
$(NULL)
backend_source_h += $(x11_source_h)
backend_source_c += $(x11_source_c)
backend_source_h_priv += $(x11_source_h_priv)
backend_source_c_priv += $(x11_source_c_priv)
# the list of files we want to introspect on X11
x11_introspection = $(x11_source_c) $(x11_source_h)
clutterx11_includedir = $(clutter_includedir)/x11
clutterx11_include_HEADERS = $(x11_source_h)
mutter-clutter-x11-$(CLUTTER_API_VERSION).pc: mutter-clutter-$(CLUTTER_API_VERSION).pc
$(QUIET_GEN)cp -f $< $(@F)
pc_files += mutter-clutter-x11-$(CLUTTER_API_VERSION).pc
# Shared cogl backend files
cogl_source_h =
cogl_source_c = \
cogl/clutter-stage-cogl.c \
$(NULL)
cogl_source_h_priv = \
cogl/clutter-stage-cogl.h \
$(NULL)
cogl_source_c_priv =
backend_source_h += $(cogl_source_h)
backend_source_c += $(cogl_source_c)
backend_source_h_priv += $(cogl_source_h_priv)
backend_source_c_priv += $(cogl_source_c_priv)
backend_source_h += $(glx_source_h)
backend_source_c += $(glx_source_c)
evdev_c_priv = \
evdev/clutter-device-manager-evdev.c \
evdev/clutter-input-device-evdev.c \
evdev/clutter-event-evdev.c \
$(NULL)
evdev_h_priv = \
evdev/clutter-device-manager-evdev.h \
evdev/clutter-input-device-evdev.h \
$(NULL)
evdev_h = evdev/clutter-evdev.h
backend_source_c_priv += $(evdev_c_priv)
backend_source_h_priv += $(evdev_h_priv)
backend_source_h += $(evdev_h)
clutterevdev_includedir = $(clutter_includedir)/evdev
clutterevdev_include_HEADERS = $(evdev_h)
backend_source_c += evdev/clutter-xkb-utils.c
backend_source_h_priv += evdev/clutter-xkb-utils.h
# EGL backend rules
egl_source_h = \
egl/clutter-egl-headers.h \
egl/clutter-egl.h \
$(NULL)
egl_source_h_priv = egl/clutter-backend-eglnative.h egl/clutter-stage-eglnative.h
egl_source_c = egl/clutter-backend-eglnative.c egl/clutter-stage-eglnative.c
wayland_compositor_source_h = \
wayland/clutter-wayland-compositor.h \
wayland/clutter-wayland-surface.h
backend_source_h += $(wayland_compositor_source_h)
backend_source_c += \
wayland/clutter-wayland-surface.c
wayland_compositor_includedir = $(clutter_includedir)/wayland
wayland_compositor_include_HEADERS = $(wayland_compositor_source_h)
backend_source_h += $(egl_source_h)
backend_source_c += $(egl_source_c)
backend_source_h_priv += $(egl_source_h_priv)
clutteregl_includedir = $(clutter_includedir)/egl
clutteregl_include_HEADERS = $(egl_source_h)
# cally
cally_sources_h = \
cally/cally-actor.h \
cally/cally-clone.h \
cally/cally-factory.h \
cally/cally-group.h \
cally/cally.h \
cally/cally-main.h \
cally/cally-rectangle.h \
cally/cally-root.h \
cally/cally-stage.h \
cally/cally-text.h \
cally/cally-texture.h \
cally/cally-util.h \
$(NULL)
cally_sources_c = \
cally/cally-actor.c \
cally/cally.c \
cally/cally-clone.c \
cally/cally-group.c \
cally/cally-rectangle.c \
cally/cally-root.c \
cally/cally-stage.c \
cally/cally-text.c \
cally/cally-texture.c \
cally/cally-util.c \
$(NULL)
cally_sources_private = \
cally/cally-actor-private.h \
$(NULL)
cally_includedir = $(clutter_base_includedir)/cally
cally_include_HEADERS = $(cally_sources_h)
# general build rules:
# you should not need to modify anything below this point
# glib-genmarshal rules
glib_marshal_list = clutter-marshal.list
glib_marshal_prefix = _clutter_marshal
include $(srcdir)/Makefile.am.marshal
# glib-mkenums rules
glib_enum_h = clutter-enum-types.h
glib_enum_c = clutter-enum-types.c
glib_enum_headers = $(source_h) $(deprecated_h)
include $(srcdir)/Makefile.am.enums
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = $(pc_files)
DISTCLEANFILES += $(pc_files)
clutter_include_HEADERS = $(source_h) clutter.h clutter-version.h clutter-autocleanups.h
nodist_clutter_include_HEADERS = clutter-config.h $(built_source_h)
clutter_deprecated_HEADERS = $(deprecated_h)
mutterlibdir = $(libdir)/mutter
mutterlib_LTLIBRARIES = libmutter-clutter-@CLUTTER_API_VERSION@.la
libmutter_clutter_@CLUTTER_API_VERSION@_la_LIBADD = $(LIBM) $(CLUTTER_LIBS)
libmutter_clutter_@CLUTTER_API_VERSION@_la_SOURCES = \
$(backend_source_c) \
$(backend_source_h) \
$(backend_source_c_priv) \
$(backend_source_h_priv) \
$(source_c) \
$(source_h) \
$(source_c_priv) \
$(source_h_priv) \
$(deprecated_c) \
$(deprecated_h) \
$(deprecated_c_priv) \
$(deprecated_h_priv) \
$(cally_sources_c) \
$(cally_sources_h) \
$(cally_sources_private) \
$(NULL)
nodist_libmutter_clutter_@CLUTTER_API_VERSION@_la_SOURCES = \
$(backend_source_built) \
$(built_source_c) \
$(built_source_h)
libmutter_clutter_@CLUTTER_API_VERSION@_la_LDFLAGS = \
$(CLUTTER_LINK_FLAGS) \
$(CLUTTER_LT_LDFLAGS) \
-export-dynamic \
-rpath $(mutterlibdir) \
$(NULL)
install-exec-local:
test -z "$(mutterlibdir)" || $(MKDIR_P) "$(DESTDIR)$(mutterlibdir)"
for lib in `echo $(compat_libs)`; do \
(cd $(DESTDIR)$(mutterlibdir) && \
rm -f $$lib.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION); \
) ; \
(cd $(DESTDIR)$(mutterlibdir) && \
{ ln -s -f libmutter-clutter-$(CLUTTER_API_VERSION).so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib.0 || \
{ rm -f $$lib.0 && ln -s libmutter-clutter-1.0.so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib.0; }; \
} \
) ; \
(cd $(DESTDIR)$(mutterlibdir) && \
{ ln -s -f libmutter-clutter-$(CLUTTER_API_VERSION).so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib || \
{ rm -f $$lib && ln -s libmutter-clutter-1.0.so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib; }; \
} \
) ; \
done
# gobject-introspection rules
-include $(INTROSPECTION_MAKEFILE)
Clutter-@CLUTTER_API_VERSION@.gir: libmutter-clutter-@CLUTTER_API_VERSION@.la Makefile
Clutter_@CLUTTER_API_VERSION_AM@_gir_NAMESPACE = Clutter
Clutter_@CLUTTER_API_VERSION_AM@_gir_VERSION = @CLUTTER_API_VERSION@
Clutter_@CLUTTER_API_VERSION_AM@_gir_LIBS = libmutter-clutter-@CLUTTER_API_VERSION@.la
Clutter_@CLUTTER_API_VERSION_AM@_gir_FILES = \
$(clutter_include_HEADERS) \
$(clutter_deprecated_HEADERS) \
$(nodist_clutter_include_HEADERS) \
$(source_c) \
$(deprecated_c) \
$(built_source_c)
Clutter_@CLUTTER_API_VERSION_AM@_gir_CFLAGS = $(AM_CPPFLAGS) $(CLUTTER_CFLAGS)
Clutter_@CLUTTER_API_VERSION_AM@_gir_INCLUDES = GL-1.0 GObject-2.0 cairo-1.0 Cogl-1.0 CoglPango-1.0 Atk-1.0 Json-1.0
Clutter_@CLUTTER_API_VERSION_AM@_gir_SCANNERFLAGS = \
--warn-all \
--c-include='clutter/clutter.h' \
--pkg-export=clutter-@CLUTTER_API_VERSION@
INTROSPECTION_GIRS += Clutter-@CLUTTER_API_VERSION@.gir
Cally-@CLUTTER_API_VERSION@.gir: Makefile Clutter-@CLUTTER_API_VERSION@.gir
Cally_@CLUTTER_API_VERSION_AM@_gir_NAMESPACE = Cally
Cally_@CLUTTER_API_VERSION_AM@_gir_VERSION = @CLUTTER_API_VERSION@
Cally_@CLUTTER_API_VERSION_AM@_gir_LIBS = libmutter-clutter-@CLUTTER_API_VERSION@.la
Cally_@CLUTTER_API_VERSION_AM@_gir_FILES = $(cally_sources_h) $(cally_sources_c)
Cally_@CLUTTER_API_VERSION_AM@_gir_CFLAGS = $(AM_CPPFLAGS) $(CLUTTER_CFLAGS)
Cally_@CLUTTER_API_VERSION_AM@_gir_SCANNERFLAGS = \
--warn-all \
--c-include='cally/cally.h' \
--pkg-export=cally-@CLUTTER_API_VERSION@ \
--include-uninstalled=$(top_builddir)/clutter/Clutter-@CLUTTER_API_VERSION@.gir
INTROSPECTION_GIRS += Cally-@CLUTTER_API_VERSION@.gir
ClutterX11-@CLUTTER_API_VERSION@.gir: Makefile Clutter-@CLUTTER_API_VERSION@.gir
ClutterX11_@CLUTTER_API_VERSION_AM@_gir_NAMESPACE = ClutterX11
ClutterX11_@CLUTTER_API_VERSION_AM@_gir_INCLUDES = xlib-2.0
ClutterX11_@CLUTTER_API_VERSION_AM@_gir_LIBS = libmutter-clutter-@CLUTTER_API_VERSION@.la
ClutterX11_@CLUTTER_API_VERSION_AM@_gir_FILES = $(x11_introspection)
ClutterX11_@CLUTTER_API_VERSION_AM@_gir_CFLAGS = $(AM_CPPFLAGS) $(CLUTTER_CFLAGS)
ClutterX11_@CLUTTER_API_VERSION_AM@_gir_SCANNERFLAGS = \
--warn-all \
--c-include='clutter/x11/clutter-x11.h' \
--pkg-export=clutter-x11-@CLUTTER_API_VERSION@ \
--include-uninstalled=$(top_builddir)/clutter/Clutter-@CLUTTER_API_VERSION@.gir
INTROSPECTION_GIRS += ClutterX11-@CLUTTER_API_VERSION@.gir
# INTROSPECTION_GIRDIR/INTROSPECTION_TYPELIBDIR aren't the right place to
# install anything - we need to install inside our prefix.
girdir = $(mutterlibdir)
gir_DATA = $(INTROSPECTION_GIRS)
typelibdir = $(mutterlibdir)
typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
EXTRA_DIST += \
Makefile.am.marshal \
Makefile.am.enums
CLEANFILES += $(gir_DATA) $(typelib_DATA)

View File

@ -0,0 +1,52 @@
# Rules for generating enumeration types using glib-mkenums
#
# Define:
# glib_enum_h = header template file
# glib_enum_c = source template file
# glib_enum_headers = list of headers to parse
#
# before including Makefile.am.enums. You will also need to have
# the following targets already defined:
#
# CLEANFILES
# DISTCLEANFILES
# BUILT_SOURCES
# EXTRA_DIST
#
# Author: Emmanuele Bassi <ebassi@linux.intel.com>
# Basic sanity checks
$(if $(GLIB_MKENUMS),,$(error Need to define GLIB_MKENUMS))
$(if $(or $(glib_enum_h), \
$(glib_enum_c)),, \
$(error Need to define glib_enum_h and glib_enum_c))
$(if $(glib_enum_headers),,$(error Need to define glib_enum_headers))
enum_tmpl_h=$(addprefix $(srcdir)/, $(glib_enum_h:.h=.h.in))
enum_tmpl_c=$(addprefix $(srcdir)/, $(glib_enum_c:.c=.c.in))
enum_headers=$(addprefix $(srcdir)/, $(glib_enum_headers))
CLEANFILES += stamp-enum-types
DISTCLEANFILES += $(glib_enum_h) $(glib_enum_c)
BUILT_SOURCES += $(glib_enum_h) $(glib_enum_c)
EXTRA_DIST += $(enum_tmpl_h) $(enum_tmpl_c)
stamp-enum-types: $(enum_headers) $(enum_tmpl_h)
$(AM_V_GEN)$(GLIB_MKENUMS) \
--template $(enum_tmpl_h) \
$(enum_headers) > xgen-eh \
&& (cmp -s xgen-eh $(glib_enum_h) || cp -f xgen-eh $(glib_enum_h)) \
&& rm -f xgen-eh \
&& echo timestamp > $(@F)
$(glib_enum_h): stamp-enum-types
@true
$(glib_enum_c): $(enum_headers) $(enum_tmpl_h) $(enum_tmpl_c)
$(AM_V_GEN)$(GLIB_MKENUMS) \
--template $(enum_tmpl_c) \
$(enum_headers) > xgen-ec \
&& cp -f xgen-ec $(glib_enum_c) \
&& rm -f xgen-ec

View File

@ -0,0 +1,52 @@
# Rules for generating marshal files using glib-genmarshal
#
# Define:
# glib_marshal_list = marshal list file
# glib_marshal_prefix = prefix for marshal functions
#
# before including Makefile.am.marshal. You will also need to have
# the following targets already defined:
#
# CLEANFILES
# DISTCLEANFILES
# BUILT_SOURCES
# EXTRA_DIST
#
# Author: Emmanuele Bassi <ebassi@linux.intel.com>
# Basic sanity checks
$(if $(GLIB_GENMARSHAL),,$(error Need to define GLIB_GENMARSHAL))
$(if $(or $(glib_marshal_list), \
$(glib_marshal_prefix)),, \
$(error Need to define glib_marshal_list and glib_marshal_prefix))
marshal_h = $(glib_marshal_list:.list=.h)
marshal_c = $(glib_marshal_list:.list=.c)
marshal_list = $(addprefix $(srcdir)/, $(glib_marshal_list))
CLEANFILES += stamp-marshal
DISTCLEANFILES += $(marshal_h) $(marshal_c)
BUILT_SOURCES += $(marshal_h) $(marshal_c)
EXTRA_DIST += $(marshal_list)
stamp-marshal: $(marshal_list)
$(AM_V_GEN)$(GLIB_GENMARSHAL) \
--prefix=$(glib_marshal_prefix) \
--header \
$(marshal_list) > xgen-mh \
&& (cmp -s xgen-mh $(marshal_h) || cp -f xgen-mh $(marshal_h)) \
&& rm -f xgen-mh \
&& echo timestamp > $(@F)
$(marshal_h): stamp-marshal
@true
$(marshal_c): $(marshal_h)
$(AM_V_GEN)(echo "#include \"$(marshal_h)\"" ; \
$(GLIB_GENMARSHAL) \
--prefix=$(glib_marshal_prefix) \
--body \
$(marshal_list)) > xgen-mc \
&& cp xgen-mc $(marshal_c) \
&& rm -f xgen-mc

View File

@ -0,0 +1,986 @@
# DO NOT MODIFY THIS FILE
#
# Clutter uses the Git commit log to generate the ChangeLog files when
# creating the tarball for releases and snapshots. This file is maintained
# only for historical reasons.
2010-07-05 Alejandro Piñeiro <apinheiro@igalia.com>
Cleaning ClutterText
* Removing superfluous g_return_if_fail
* Removing unused ClutterText::text-changed callback
2010-07-05 Alejandro Piñeiro <apinheiro@igalia.com>
Refactoring "window:create" and "window:destroy" emission code
Previously "window:create" and "window:destroy" were emitted on
CallyUtil. Although it works, and CallyUtil already have callbacks to
stage_added/removed signals, I think that it is more tidy/clear to do
that on CallyRoot:
* CallyRoot already has code to manage ClutterStage addition/removal
* In fact, we can see CallyRoot as the object exposing the a11y
information from ClutterStageManager, so it fits better here.
* CallyUtil callbacks these signals are related to key event
listeners (key snooper simulation). One of the main CallyUtil
responsabilities is managing event (connecting, emitting), so I
would prefer to not start to add/mix more functionalities here.
Ideally it would be better to emit all CallyStage methods from
CallyStage, but it is clear that "create" and "destroy" are more easy
to emit from a external object.
2010-06-25 Alejandro Piñeiro <apinheiro@igalia.com>
Cleaning clutter-actor
Some cleaning changes:
* Using CallyActionFunc instead of ACTION_FUNC
* Removing a extra * on cally-actor-private macro documentation, to
avoid gtk-doc warnings
* Using g_strcmp0 instead of strcmp
Changes to be applied on clutter (see CB#2097 and CB#2098), applied
also here to maintain the sync. My intention is keep this developing line
until the real integration, in order to make a final independent cally
release.
2010-06-14 Alejandro Piñeiro <apinheiro@igalia.com>
Adding -Wshadow option and solving warnings related
2010-06-14 Alejandro Piñeiro <apinheiro@igalia.com>
Added dummy padding for future vt expasion
Added dummy padding on the different classes structures, to allow
future expansion of virtual methods.
I decided to add this on all the classes, although it would be
really unlikely in some cases (ie, CallyGroup)
2010-06-10 Alejandro Piñeiro <apinheiro@igalia.com>
Adding and emitting "window:xxx" methods on CallyStage
Added some window related signals on CallyStage:
* window:activate and window:deactivate emitted from CallyStage
* window:create and window:destroy emitted from CallyUtil
ClutterStage doesn't fulfill 100% the window concept, but some of
these signals are important in order to identify the object which
could emit global/key events.
The current implementation is equivalent to GailWindow one, supposing
CallyStage as the only window related window. This likely would change
in any clutter-based toolkit implement a real Window object, so a more
flexible procedure would be required. But we would solve problems step
by step.
BTW: as I explain here [1] I really think that the current way to
implement "window:xxx" signals (not defined in ATK but expected from
the a11y implementation toolkit) somewhat hacky and undocumented (you
need to check at-spi2 idls to know that you require to emit this
events)
Related to bug CB#2147 (Orca doesn't speech out properly non
printable chars on some environments), as solves this problem
in a specific case.
[1] https://bugzilla.gnome.org/show_bug.cgi?id=620977#c1
2010-06-04 Alejandro Piñeiro <apinheiro@igalia.com>
Avoiding clutter_stage_get_key_focus warning
For any reason, in some cases, a clutter actor doesn't have a stage
associated. We use the default one as fallback.
2010-06-02 Alejandro Piñeiro <apinheiro@igalia.com>
Added a defunct check on cally_group_get_n_children
Some warnings appeared when we tried to get the number
of children of a defunct object.
2010-06-02 Alejandro Piñeiro <apinheiro@igalia.com>
Update TODO file
Use Bugzilla to setting missing features.
2010-06-01 Alejandro Piñeiro <apinheiro@igalia.com>
Removing heuristics to decide CallyRectable/CallyTexture role
Previously CallyRectangle and CallyTexture used some heuristics in
order to decide the default role: ATK_ROLE_IMAGE or
ATK_PUSH_BUTTON, as in practice most applications using these
objects as buttons were not applying the proper role.
As this is a hack, and a application responsibility, finally we
have decided to remove this, so the default role is ATK_ROLE_IMAGE.
Fixes CB#1732 (CallyTexture and CallyRectangle uses some heuristics to
decide the role)
2010-05-28 Alejandro Piñeiro <apinheiro@igalia.com>
Post-release version bump, after release 1.2.0
I wrongly added the last commit on the 1.1 branch, when in fact it
requires clutter 1.3.3, and on the README it is explained that
cally versioning is tied to clutter versioning. In order to solve
that a clutter-1.2 release branch is created, and bumped the version.
This versioning tyding will be obsolete when the integration with
clutter become a reality, but in the same way, this is the way to
tidy this thinking in this integration.
2010-04-13 Alejandro Piñeiro <apinheiro@igalia.com>
Use clutter_actor_get_accessible
The method clutter_actor_get_accessible was added due work on
bug 2070, and should be used to get the accessibility object,
instead of atk_gobject_accessible_for_object
This would allow to implement a11y support directly on
any clutter based toolkit object (ie StLabel).
2010-05-13 Alejandro Piñeiro <apinheiro@igalia.com>
Added CallyClone example
2010-05-13 Alejandro Piñeiro <apinheiro@igalia.com>
Added a11y support for ClutterClone
Resolved in the most simplified way, just as a image and a
default description to identify cloned objects.
More information:
http://lists.o-hand.com/clutter/3797.html
2010-04-14 Alejandro Piñeiro <apinheiro@igalia.com>
Remove gail dependency
Removed to avoid gdk/gtk dependency on cally.
Part of bug CB#2072 solution
2010-04-14 Alejandro Piñeiro <apinheiro@igalia.com>
Avoid gdk functions filling AtkKeyEventStruct
Now when AtkKeyEventStruct is filled in order to emit any key event
signal, it is not used any gdk function on the keyval or the
string fields.
event_string is filled with the printable character if possible, if
not (Ctrl, Alt, etc) it is set as NULL.
Now the AT should take care of that, at least until we define atk key
event struct in a more agnostic way (not tied to gdk/gtk). See orca
bug bgo#616206 as a example.
Part of bug CB#2072 solution.
2010-04-15 Alejandro Piñeiro <apinheiro@igalia.com>
Added gail_misc_layout_get_run_attributes implementation
Part of bug CB#2072 solution
2010-04-14 Alejandro Piñeiro <apinheiro@igalia.com>
Remove gailutil/gailmisc functions calls
This is because gailutil/gailmisc added a gdk/gtk dependency, and
this dependency is being removed. New cally-specific implementation
are required.
Related to bug CB#1733
Part of bug CB#2072 solution
2010-04-13 Alejandro Piñeiro <apinheiro@igalia.com>
Fixing the libdir directory in some examples
2010-03-26 Alejandro Piñeiro <apinheiro@igalia.com>
Previous cally.pc.in update was incomplete
The previous commit was not tested properly, and it was missing one
detail. Sorry for the noise.
2010-03-26 Alejandro Piñeiro <apinheiro@igalia.com>
Update cally.pc.in after module relocation
Previous commit places cally module in a different directory.
It also corrects where the include directory is placed.
2010-03-15 Alejandro Piñeiro <apinheiro@igalia.com>
Use a proper clutter module directory
Use a proper clutter module directory, instead of keep being
installed on a gtk directory.
Improve the cally-examples-util, in order to keep using
hardcoded values.
Fixes CB#1737 (Wrong cally module directory)
2010-03-15 Alejandro Piñeiro <apinheiro@igalia.com>
Proper UTF-8 headers
2010-02-25 Alejandro Piñeiro <apinheiro@igalia.com>
Change "--with-dbus" option for "atk-bridge-dir" on examples
The atk-adaptor in the dbus at-spi was renamed to atk-bridge due
some apps hardcoding the name. So right now the only difference
is the final directory.
So the option was removed, and atk-bridge-dir added. This also allows
to use the system atk-bridge or the compiled in any developing environment,
so it is really more flexible.
See the README (updated with this commit) for more information.
2010-02-19 Alejandro Piñeiro <apinheiro@igalia.com>
Added .gitignore file
2010-02-19 Alejandro Piñeiro <apinheiro@igalia.com>
Release 1.1.1
2010-02-19 Alejandro Piñeiro <apinheiro@igalia.com>
Using clutter_threads_idle_add instead of the gdk one
The idea is being as less gdk dependent as possible. Right now
it is inviable to remove the dependency (gailutil and so on) but
hypothetically, the ideal is remove this dependency in the future,
and being "clutter pure".
2010-02-15 Alejandro Piñeiro <apinheiro@igalia.com>
Check if the state is defunct on cally_text_get_name
Check if the state is defunct on cally_text_get_name, in order
to avoid warnings cally clutter_text_get_text when the clutter
object is NULL
2010-01-26 Alejandro Piñeiro <apinheiro@igalia.com>
Update on configure.ac after autoupdate call
2010-02-02 Alejandro Piñeiro <apinheiro@igalia.com>
Try to apply the key modifiers to event->keyval like GDK does
ClutterKeyEvent defines the keyval without taking into account the
modifiers. GDK defines this keyval taking into account the modifiers.
AtkKeyEventStruct expects the keyval in a GDK fashion, so a
translation is required.
This patch tries to do that using using
gdk_keymap_translate_keyboard_state.
This functions only works correctly if gtk has been initialized, so
the fallback is create the AtkKeyEventStruct with the keyval
provided by Clutter.
More information:
http://library.gnome.org/devel/atk/stable/AtkUtil.html#AtkKeyEventStruct
http://bugzilla.openedhand.com/show_bug.cgi?id=1961
2010-02-02 Alejandro Piñeiro <apinheiro@igalia.com>
Filling AtkKeyEventStruct->string used on the atk key event listeners
Finally we use directly gdk_keyval_name. Not the ideal solution, but works,
and more important, it avoids to reimplement this issue on clutter or cally.
More information on Bug 1952
Fixes http://bugzilla.openedhand.com/show_bug.cgi?id=1952
2010-01-22 Alejandro Piñeiro <apinheiro@igalia.com>
Added AM_PROG_CC_C_O option to avoid a warning running configure
2010-01-22 Alejandro Piñeiro <apinheiro@igalia.com>
Fix clutter version required on the pc files
2010-01-22 Alejandro Piñeiro <apinheiro@igalia.com>
Check on configure time if any x11 clutter backend is in use
It uses AC_CHECK_LIB in order to check if x11 backend is in use.
It also modifies cally-actor in order to use the information
retrieved.
So now cally has a minimum multi-backend support. It only manages
a x11 (glx or eglx) backend, but at least, it checks it, so you
can compile cally without this backend. It probably will not work
properly, but at least you can compile and execute it.
Solves http://bugzilla.openedhand.com/show_bug.cgi?id=1736
2010-01-21 Alejandro Piñeiro <apinheiro@igalia.com>
Fix the perspective problems computing the on-screen extensions
Use clutter_actor_get_abs_allocation_vertices and
clutter_actor_get_transformed_size to get the real on-screen
position and size, instead of compute that using the geometry
and the anchor point.
It also update cally-atkcomponent-example, adding a actor inside
a nested ClutterGroup hierarchy.
Fixes: http://bugzilla.openedhand.com/show_bug.cgi?id=1731
2010-01-13 Alejandro Piñeiro <apinheiro@igalia.com>
Added extra button on cally-atkeditabletext-example
Added a button to print the current cursor position, and also
extend the size of the buttons
2010-01-12 Alejandro Piñeiro <apinheiro@igalia.com>
Remove superfluous g_print on CallyStage
2009-12-03 Alejandro Piñeiro <apinheiro@igalia.com>
Use clutter_stage_manager_peek_stages to avoid a leak
2009-12-03 Alejandro Piñeiro <apinheiro@igalia.com>
Added ATK_STATE_SELECTABLE_TEXT management
2009-11-26 Alejandro Piñeiro <apinheiro@igalia.com>
Manage properly ATK_STATE_ACTIVE on CallyStage
* cally/cally-stage.c
Added private struct
(cally_stage_class_init),(cally_stage_init),(cally_stage_real_initalize):
Initialization stuff
(cally_stage_activate_cb)
(cally_stage_deactivate_cb): new ClutterStage signal callbacks, change
the internal value of active, and notify the atk state change
(cally_stage_ref_state_set): manage ATK_STATE_ACTIVATE
* examples/cally-atktext-example2.c
If possible, creates two stage, in order to test ATK_STATE_ACTIVATE
2009-11-24 Alejandro Piñeiro <apinheiro@igalia.com>
Focused state change and focused object notification
* cally/cally-actor.h
(focus_clutter): added virtual method for the focus management
* cally/cally-actor.c
(cally_actor_component_interface_init)
(cally_actor_add_focus_handler)
(cally_actor_remove_focus_handler):
Implementation of the AtkComponent methods add_focus_handler and
remove_focus_handler
(cally_actor_focus_event): CallyActor specific focus handler, notify
the state focused change
(cally_actor_focus_clutter)
(cally_actor_real_focus_clutter):
Handlers for the ClutterActor "key-focus-in" and "key-focus-out"
signals. Emit the signal AtkObject "focus_event" and set the focus
object with atk_focus_tracker_notify.
(cally_actor_initialize):
Connect to the signals "key-focus-in" and "key-focus-out", use
atk_component_add_focus_handler to add cally_actor_focus_event
Note: The focus management is more simplified that the gail one. The
main reason is that the focus management in GTK is really more complex
that the Clutter one.
2009-11-24 Alejandro Piñeiro <apinheiro@igalia.com>
Modify cally-atkeditabletext-example.c to manage "activatable" status
2009-11-24 Alejandro Piñeiro <apinheiro@igalia.com>
Added "activate" action in ClutterText
* cally/cally-actor.h
* cally/cally-actor.c
cally_actor_add_action now returns the action id added. Documentation
added in order to explain the return values and others.
* cally/cally-text.c
Added action "activate". This action is only available if the ClutterText is
activatable, so the "activatable" property is tracked in the notify
2009-11-20 Alejandro Piñeiro <apinheiro@igalia.com>
Signal event emission
Emits the signals "text_selection_changed", "text_caret_moved",
"text_changed::insert", "text_changed::delete", and notify the
ATK_STATE_EDITABLE state change.
It also adds the ATK_STATE_EDITABLE in the ref_state_set, includes a
finalize to clean the new private data used, and move part of the
initialization from the _init to the _real_initialization.
2009-12-03 Alejandro Piñeiro <apinheiro@igalia.com>
Remove the ATK_STATE_DEFUNCT emission
Remove the ATK_STATE_DEFUNCT emission, as this is already made by
AtkGObjectAccessible.
It also removes the clutter actor from the private structure, as we
can use the AtkGObjectAccessible API to obtain it. This makes the code
more coherent, with respect of the rest of the Cally classes
implementation.
2009-11-26 Alejandro Piñeiro <apinheiro@igalia.com>
Remove ; from the CALLY_GET_CLUTTER_ACTOR macro
2009-11-25 Alejandro Piñeiro <apinheiro@igalia.com>
TODO cleanup and more implementation notes
* TODO: removed the data that we have in the bugzilla or in the implementation
notes on the cally source
* cally/cally-actor.c: complete implementations notes
* cally/Makefile.am: add a comment related to the public headers, and include
Makefile.in in the MAINTAINERCLEANFILES
2009-11-13 Alejandro Piñeiro <apinheiro@igalia.com>
Adding new tips on CODING_STYLE
2009-11-09 Alejandro Piñeiro <apinheiro@igalia.com>
AtkEditableText implementation on CallyText
* examples/Makefile.am
* examples/cally-atkeditabletext-example.c: New example added
* cally/cally-text.c
Interface AtkEditableText implemented, except some methods:
* Missing ClipBoard feature on Clutter:
paste_text
copy_text
cut_text
* Missing a equivalent GtkTextTag on Clutter (so the possibility to
set run attributes in a range):
set_run_attributes
Fixes bug CB#1734
2009-11-03 Alejandro Piñeiro <apinheiro@igalia.com>
Removed DG_DISABLE_CHECKS and DG_DISABLE_CAST_CHECKS from CFLAGS
* configure.ac: Removed DG_DISABLE_CHECKS and DG_DISABLE_CAST_CHECKS
from the common CFLAGS options
* cally/cally-actor.c: fixed cast errors on some return values, not
detected previously because of the use of relaxed compilation
options
Problem detected by Mario Sánchez Prada <msanchez@igalia.com>
2009-10-28 Alejandro Piñeiro <apinheiro@igalia.com>
Support for multiple stages
* cally-root.c
* cally-stage.c
* cally-util.c
Implemented the support for multiple stages, by tracking the signals
stage-added and stage-removed of the ClutterStageManager.
In the same way CallyRoot has implement properly the atk_object_initialize,
and in general now is more tied to ClutterStageManager (CallyRoot is now
the a11y object of ClutterStageManager), but factory not required anyway,
as it is instanced on the CallyUtil atk_get_root
Fixes: CB#1754 (Missing multi-stage support)
2009-10-27 Alejandro Piñeiro <apinheiro@igalia.com>
Implemented atk_[add/remove]_key_event_listener on CallyUtil
* cally/cally-util.c:
Implemented atk_[add/remove]_key_event_listener
* examples/cally-atktext-example2.c:
Modified in order to install and remove key event listeners,
for testing purposes
Fixes CB#1852 (AtkUtil implementation misses
atk_[add/remove]_key_event_listener)
2009-10-21 Alejandro Piñeiro <apinheiro@igalia.com>
Implemented atk-[add/remove]-global-event-listener on CallyUtil
* cally/cally-util.c:
Implemented atk-[add/remove]-global-event-listener on CallyUtil
* examples/Makefile.am
* examples/cally-atktext-example2.c
New example in order to test easier the event emission on focus
change (not working right now)
2009-10-12 Alejandro Piñeiro <apinheiro@igalia.com>
Add --with-dbus option executing the examples
The replacement for atk-bridge on at-spi-dbus has a different name
(atk-adaptor), and it has not defined the method gnome_accessibility_init.
The --with-dbus option allow to load the correct library and use the
correct hook method if you are using at-spi-dbus.
Anyway, take into account that this is just an example, and in a final
environment, this should be made in a more general way.
More information: CB#1738, CB#1737
2009-09-25 Alejandro Piñeiro <apinheiro@igalia.com>
Symplifying shave support.
2009-09-25 Alejandro Piñeiro <apinheiro@igalia.com>
Cleanup on the compilation and installation process
* cally/Makefile.am:
Added libcallydir and libcally_HEADERS in order to publish all cally
headers, as the current policy is use the cally headers as public.
* configure.ac:
Change API_VERSION_MAJOR for CALLY_API_VERSION, as was the real
meaning, and define CALLY_VERSION.
Change CALLY_OBJ_CFLAGS and CALLY_OBJ_LIBS, used to compile the
tests, as was not required to compile against the cally module (the
example only required to compile against Clutter, as the cally
module was just a module loaded by GModule).
Support for Shave.
2009-07-31 Alejandro Piñeiro <apinheiro@igalia.com>
Be able to run the examples without installing Cally
Before that, the examples searched the cally module from the final installed
directory. This means that you should install the library to use the examples.
On development this is not desirable. Now it is loaded from ../cally/.libs
This is a little hackish, but more useful, and in the end, it is just a example.
Probably a best option could be configure that on the command line.
$ ./example --cally-dir="mydir"
But just a nitpick.
2009-07-29 Alejandro Piñeiro <apinheiro@igalia.com>
Upgrade to cally-1.0, using clutter-1.0
* NEWS
* TODO: removed several items, waiting to be moved to the bugzilla
* configure.ac
* examples/cally-examples-util.c
2009-07-27 Alejandro Piñeiro <apinheiro@igalia.com>
Fixed return value of cally_actor_get_index_in_parent
Bug and solutiond pointed by Gerd Kohlberger
2009-06-30 Alejandro Piñeiro <apinheiro@igalia.com>
Added the implementation of most AtkText methods for CluttetText (CallyText)
It remains some methods:
get_default_attributes
get_character_extents
get_offset_at_point
The current gail implementation delegate on gailmisc, but this is tied to
GtkWidget so an equivalent functionality would be implemented (something like
callymisc), and in the case of get_character_extents, not sure about the layout
position (see gtk_entry_get_layout_offsets).
I think that worth manage this in a different commit.
In the same way is still missing AtkEditableText support.
2009-07-07 Alejandro Piñeiro <apinheiro@igalia.com>
Added CALLY_GET_CLUTTER_ACTOR macro
This macro was created to simplify how do you get the clutter actor object
related to the cally object. On CallyActor a private attributte maintains it
(for convenience, as it is heavily used) but outside, atkgobject methods can
be used. Note that there is a possibility on the future to change it. Two
options:
* Add a public method to get the clutter object
* Use this method on CallyActor too
This macro simplifies this:
CLUTTER_ACTOR (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (cally_object)))
2009-06-24 Alejandro Piñeiro <apinheiro@igalia.com>
Renamed examples/cally-util.[ch] to examples/cally-examples-util.[ch]
Renamed examples/cally-util.[ch] to examples/cally-examples-util.[ch] to avoid
confusion with cally/cally-util.[ch], implementation of the AtkUtil interface
2009-06-23 Alejandro Piñeiro <apinheiro@igalia.com>
Adding examples directory
* NEWS: Updates
* configure.ac
* Makefile.am
* cally/Makefile.am
* examples/Makefile.am: New
* examples/cally-util.[ch]: New
* examples/example1.c: New
Added a directory in order to put examples. In this way we don't require any
external clutter app to make the basic a11y functionality checks. At this
moment only an example was added, but all the compiling structure is working.
By default the examples are not compiled, use "--enable-examples" on configure
time in order to enable their compilation.
This basic example basically shows several objects, with different depth, in
order to check that AtkComponent returns the correct screen position.
Other minor changes done on the building infrastructure.
2009-06-23 Alejandro Piñeiro <apinheiro@igalia.com>
Fix clutter version required
2009-06-23 Alejandro Piñeiro <apinheiro@igalia.com>
Solve a problem calling clutter_actor_get_anchor_point
* cally/cally-actor.c:
(_get_actor_extents): use gfloat instead of gint, as now this clutter_actor_get_anchor_point
use floats
2009-06-11 Alejandro Piñeiro <apinheiro@igalia.com>
Minor fixes
* Update TODO
* Fix .pc files, to use clutter-0.9 version
2009-05-20 Alejandro Piñeiro <apinheiro@igalia.com>
Library renamed from cail to cally
2009-05-08 Alejandro Piñeiro <apinheiro@igalia.com>
Removed cail-clone-texture.h from cail.h
* cail/cail.h: Removed reference to cail-clone-texture.h
2009-05-08 Alejandro Piñeiro <apinheiro@igalia.com>
Upgrade to cail-0.9, using clutter-0.9, first compilable version
* NEWS: new file with the information of the releases
* TODO: updated
* configure.ac: updated clutter version to compile against
* cail/cail-clone-texture.[ch]: Removed as ClutterCloneTexture was removed on Clutter 0.9.0
* cail/cail-label.[ch]: Removed as ClutterLabel was removed on Clutter 0.9.0
* cail/Makefile.am: updated due the source files removed
* cail/cail-actor.c: removed include to <clutter/clutter-actor.h>
* cail/cail.c: removed the factories for CailLabel and CailCloneTexture
2009-05-07 Alejandro Piñeiro <apinheiro@igalia.com>
Reflect change on the version number policy
* README: correct some typos and explain that the cail version number
is tied to the clutter version number and how
* configure.ac
Set the version number to 0.8.0
2009-05-07 Alejandro Piñeiro <apinheiro@igalia.com>
Edit the ChangeLog file, to show that now we are using git
* ChangeLog.SVN: new file, with the ChangeLog used while cail was
using a Subversion repository
* ChangeLog: now is empty, and only maintains a reference to use git log
2009-04-29 Alejandro Piñeiro <apinheiro@igalia.com>
Coding style review
* CODING_STYLE
* cail/Makefile.am
* cail/cail-actor-private.[ch]
* cail/cail-actor.h
* cail/cail-clone-texture.[ch]
* cail/cail-group.[ch]
* cail/cail-label.[ch]
* cail/cail-rectangle.[ch]
* cail/cail-root.[ch]
* cail/cail-stage.[ch]
* cail/cail-texture.[ch]
* cail/cail-util.[ch]
* cail/cail.c
2009-04-28 Alejandro Piñeiro <apinheiro@igalia.com>
Coding style review: cail-actor.c
2009-04-21 Alejandro Piñeiro <apinheiro@igalia.com>
2009-04-21 Alejandro Pinheiro <apinheiro@igalia.com>
* TODO: updated TODO file
2009-04-21 Alejandro Piñeiro <apinheiro@igalia.com>
2009-03-06 Alejandro Pinheiro <apinheiro@igalia.com>
* AUTHORS: update authors file to public release
2009-03-06 Alejandro Piñeiro <apinheiro@igalia.com>
2009-03-06 Alejandro Pinheiro <apinheiro@igalia.com>
* debian/control
Added cdbs dependency, renamed debugging package
* debian/libcail-common-dbg.dirs: new file
* debian/libcail-common.dirs
* debian/libcail-common.install
Minor changes
2009-03-05 Alejandro Piñeiro <apinheiro@igalia.com>
2009-03-05 Alejandro Pinheiro <apinheiro@igalia.com>
* TODO
Added TODO file, in order to list the remaining tasks.
2009-03-05 Alejandro Piñeiro <apinheiro@igalia.com>
2009-03-05 Alejandro Pinheiro <apinheiro@igalia.com>
* configure.ac
* cail/cail.c
* cail/cail-util.c
* Makefile.am
Removed all the missing gtk related stuff
2009-03-05 Alejandro Piñeiro <apinheiro@igalia.com>
2009-03-05 Alejandro Pinheiro <apinheiro@igalia.com>
* cail/cail-actor.c
(_get_actor_extents): managing too the anchor point to compute the position
(_get_top_level_origin): reimplemented using x11 functions, removed
gtk/gdk related functions, and taking into account the relative position
inside the parent (previous position calculation was wrong if a child
was not a direct stage child)
* cail/clutter-gtk/cail-clutter-embed.[ch]
* cail/clutter-gtk/cail-gtk-factory.h
Removed, in order to remove any gtk dependency
* cail/debian/control: removed gtk dependency
2009-03-03 Alejandro Piñeiro <apinheiro@igalia.com>
2009-03-03 Alejandro Pinheiro <apinheiro@igalia.com>
* cail/cail-actor-private.[ch]: new files to private utility functions
(_cail_actor_pushable): new function, that checks if a cail actor is
pushable by checking if the clutter actor related has a handler for
a release event
* cail/cail-texture.c
* cail/cail-clone-texture.c
* cail/cail-rectangle.c
Use of new function _cail_actor_pushable
* cail-actor.c: Added some documentation related to current implementation
* cail-util.c: Code style review
2009-03-02 Alejandro Piñeiro <apinheiro@igalia.com>
2009-03-02 Alejandro Pinheiro <apinheiro@igalia.com>
* cail/cail-label.[ch]: new
* cail/cail.[ch]
(cail_accessibility_module_init)
* cail/Makefile.am
Added CailLabel, a11y object for ClutterLabel
2009-02-27 Alejandro Piñeiro <apinheiro@igalia.com>
2009-02-27 Alejandro Pinheiro <apinheiro@igalia.com>
* cail/cail-actor.c
(cail_actor_real_remove_actor)
Fixed a typo that causes a crash while removing the actor from a
container
2009-02-26 Alejandro Piñeiro <apinheiro@igalia.com>
2009-02-26 Alejandro Pinheiro <apinheiro@igalia.com>
* cail/cail-actor.c
(cail_actor_remove_actor)
(cail_actor_add_actor)
Fixed a typo calling klass->add_actor and klass->remove_actor that causes
a crash in some (container,actor) combinations
(cail_actor_real_add_actor)
Additional parameter check
2009-02-25 Alejandro Piñeiro <apinheiro@igalia.com>
Missing cail-rectangle.[ch] files, according 2009-02-23 entry at Changelog
2009-02-23 Alejandro Piñeiro <apinheiro@igalia.com>
2009-02-23 Alejandro Pinheiro <apinheiro@igalia.com>
* cail/cail-rectangle.[ch]
* cail/cail.[ch]
* cail/Makefile.am
Added CailRectangle, a11y object for ClutterRectangle
* cail/cail-group.c
* cail/cail-texture.c
* cail/cail-stage.c
Avoid to add a empty private structure, to avoid the glib warning. Anyway
the pointer to the private structure is still on the .h, to allow future
add-on.
2009-02-20 Alejandro Piñeiro <apinheiro@igalia.com>
2009-02-20 Alejandro Pinheiro <apinheiro@igalia.com>
* cail-actor.[ch]
* cail-group.[ch]
Moved most of the ClutterContainer a11y support from cail-group to
cail-actor, in order to generalize this support.
* cail-stage.[ch]
* cail-util.[ch]
Normalize the private structure to avoid future problems with missing
gaps
2009-02-20 Alejandro Piñeiro <apinheiro@igalia.com>
2009-02-20 Alejandro Pinheiro <apinheiro@igalia.com>
* cail/cail-actor.c
(cail_actor_connect_actor_destroyed): connects to the clutter actor
destroy signal
(cail_actor_clutter_actor_destroyed): handler to the clutter actor
destroy signal, update the priv->actor pointer and notify a state change
This change allows to be sure about the priv->actor correct value, so we
can use directly priv->actor instead of atk_gobject_accessible_get_object
in the next functions:
(cail_actor_get_parent)
(cail_actor_get_index_in_parent)
(cail_actor_ref_state_set)
(cail_actor_get_extents)
2009-02-19 Alejandro Piñeiro <apinheiro@igalia.com>
2009-02-19 Alejandro Pinheiro <apinheiro@igalia.com>
* cail/cail-texture.[ch]
* cail/cail-clone-texture.[ch]
* cail/cail.[ch]
* cail/Makefile.am
Added CailTexture and CailCloneTexture a11y objects for ClutterTexture
and ClutterCloneTexture
* cail/cail-util.c
Added private structure
2009-02-18 Alejandro Piñeiro <apinheiro@igalia.com>
2009-02-18 Alejandro Pinheiro <apinheiro@igalia.com>
* cail/cail-actor.c:
(cail_actor_get_parent)
Return the accessible object of the clutter actor if accessible_parent
is not available. Previously it only took into account the these object
as a possible parent to return (you can set it with atk_object_set_parent)
2009-02-18 Alejandro Piñeiro <apinheiro@igalia.com>
2009-02-18 Alejandro Pinheiro <apinheiro@igalia.com>
* cail/cail-group.[ch]: code style review
* cail/cail-actor.[ch]: implemented basic support for ClutterContainer
2009-02-18 Alejandro Piñeiro <apinheiro@igalia.com>
2009-02-18 Alejandro Pinheiro <apinheiro@igalia.com>
* debian/control: updating dependencies
2009-02-18 Alejandro Piñeiro <apinheiro@igalia.com>
2009-02-18 Alejandro Pinheiro <apinheiro@igalia.com>
* configure.ac: added aditional compile flags
* cail/cail-actor.[ch]: Reimplemented support for AtkAction interface
* cail/cail-root.[ch]: code style review
2009-02-16 Alejandro Piñeiro <apinheiro@igalia.com>
2009-02-16 Alejandro Pinheiro <apinheiro@igalia.com>
* First release.

View File

@ -0,0 +1,42 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2008 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* Some parts are based on GailWidget from GAIL
* GAIL - The GNOME Accessibility Implementation Library
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CALLY_ACTOR_PRIVATE_H__
#define __CALLY_ACTOR_PRIVATE_H__
#include "cally-actor.h"
/*
* Auxiliar define, in order to get the clutter actor from the AtkObject using
* AtkGObject methods
*
*/
#define CALLY_GET_CLUTTER_ACTOR(cally_object) \
(CLUTTER_ACTOR (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (cally_object))))
void _cally_actor_get_top_level_origin (ClutterActor *actor,
gint *x,
gint *y);
#endif /* __CALLY_ACTOR_PRIVATE_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,160 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2008 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* Some parts are based on GailWidget from GAIL
* GAIL - The GNOME Accessibility Implementation Library
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CALLY_ACTOR_H__
#define __CALLY_ACTOR_H__
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <cally/cally.h> can be included directly."
#endif
#include <atk/atk.h>
#include <clutter/clutter.h>
G_BEGIN_DECLS
#define CALLY_TYPE_ACTOR (cally_actor_get_type ())
#define CALLY_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_ACTOR, CallyActor))
#define CALLY_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_ACTOR, CallyActorClass))
#define CALLY_IS_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_ACTOR))
#define CALLY_IS_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_ACTOR))
#define CALLY_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_ACTOR, CallyActorClass))
typedef struct _CallyActor CallyActor;
typedef struct _CallyActorClass CallyActorClass;
typedef struct _CallyActorPrivate CallyActorPrivate;
/**
* CallyActionFunc:
* @cally_actor: a #CallyActor
*
* Action function, to be used on #AtkAction implementations as a individual
* action
*
* Since: 1.4
*/
typedef void (* CallyActionFunc) (CallyActor *cally_actor);
/**
* CallyActionCallback:
* @cally_actor: a #CallyActor
* @user_data: user data passed to the function
*
* Action function, to be used on #AtkAction implementations as
* an individual action. Unlike #CallyActionFunc, this function
* uses the @user_data argument passed to cally_actor_add_action_full().
*
* Since: 1.6
*/
typedef void (* CallyActionCallback) (CallyActor *cally_actor,
gpointer user_data);
/**
* CallyActor:
*
* The <structname>CallyActor</structname> structure contains only private
* data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _CallyActor
{
/*< private >*/
AtkGObjectAccessible parent;
CallyActorPrivate *priv;
};
/**
* CallyActorClass:
* @notify_clutter: Signal handler for notify signal on Clutter actor
* @focus_clutter: Signal handler for key-focus-in and key-focus-out
* signal on Clutter actor. This virtual functions is deprecated.
* @add_actor: Signal handler for actor-added signal on
* ClutterContainer interface
* @remove_actor: Signal handler for actor-added signal on
* ClutterContainer interface
*
* The <structname>CallyActorClass</structname> structure contains
* only private data
*
* Since: 1.4
*/
struct _CallyActorClass
{
/*< private >*/
AtkGObjectAccessibleClass parent_class;
/*< public >*/
void (*notify_clutter) (GObject *object,
GParamSpec *pspec);
gboolean (*focus_clutter) (ClutterActor *actor,
gpointer data);
gint (*add_actor) (ClutterActor *container,
ClutterActor *actor,
gpointer data);
gint (*remove_actor) (ClutterActor *container,
ClutterActor *actor,
gpointer data);
/*< private >*/
/* padding for future expansion */
gpointer _padding_dummy[32];
};
CLUTTER_AVAILABLE_IN_1_4
GType cally_actor_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_4
AtkObject* cally_actor_new (ClutterActor *actor);
CLUTTER_AVAILABLE_IN_1_4
guint cally_actor_add_action (CallyActor *cally_actor,
const gchar *action_name,
const gchar *action_description,
const gchar *action_keybinding,
CallyActionFunc action_func);
CLUTTER_AVAILABLE_IN_1_6
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_AVAILABLE_IN_1_4
gboolean cally_actor_remove_action (CallyActor *cally_actor,
gint action_id);
CLUTTER_AVAILABLE_IN_1_4
gboolean cally_actor_remove_action_by_name (CallyActor *cally_actor,
const gchar *action_name);
G_END_DECLS
#endif /* __CALLY_ACTOR_H__ */

View File

@ -0,0 +1,132 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2010 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:cally-clone
* @Title: CallyClone
* @short_description: Implementation of the ATK interfaces for a #ClutterClone
* @see_also: #ClutterClone
*
* #CallyClone implements the required ATK interfaces of #ClutterClone
*
* In particular it sets a proper role for the clone, as just a image,
* as it is the sanest and simplest approach.
*/
/* Design rationale for CallyClone:
*
* In the old times, it was just ClutterCloneTexture. So, from a a11y POV
* CallyCloneTexture was just another image, like ClutterTexture, and if
* it was a clone was irrevelant. So on cally-0.8, CallyCloneTexture
* expose a object with role ATK_ROLE_IMAGE. But now, ClutterClone is more
* general. You can clone any object, including groups, and made things
* like have one text entry, and a clone with different properties in the
* same window, updated both at once.
*
* The question is if the idea is have a ClutterClone as a "first-class"
* citizen inside the stage hierarchy (full clone), or it is just supposed
* to be a mirror image of the original object.
*
* In the case of the a11y POV this would mean that if the text changes on
* the source, the clone should emit as well the text-changing signals.
*
* As ClutterClone smartly just paint the same object with different
* parameters, this would mean that it should be the cally object the one
* that should replicate the source clutter hierarchy to do that,
* something that just sound crazy.
*
* Taking into account that:
*
* - ClutterClone doesn't re-emit mirrored signals from the source
* I think that likely the answer would be "yes, it is just a
* mirrored image, not a real full clone".
*
* - You can't interact directly with the clone (ie: focus, and so on).
* Its basic usage (right now) is clone textures.
*
* Any other solution could be overwhelming.
*
* I think that the final solution would be that ClutterClone from the
* a11y POV should still be managed as a image (with the proper properties,
* position, size, etc.).
*/
#include "config.h"
#include "cally-clone.h"
#include "cally-actor-private.h"
/* AtkObject */
static void cally_clone_real_initialize (AtkObject *obj,
gpointer data);
G_DEFINE_TYPE (CallyClone, cally_clone, CALLY_TYPE_ACTOR)
static void
cally_clone_class_init (CallyCloneClass *klass)
{
/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
class->initialize = cally_clone_real_initialize;
}
static void
cally_clone_init (CallyClone *clone)
{
/* nothing to do yet */
}
/**
* cally_clone_new:
* @actor: a #ClutterActor
*
* Creates a new #CallyClone for the given @actor. @actor must be a
* #ClutterClone.
*
* Return value: the newly created #AtkObject
*
* Since: 1.4
*/
AtkObject*
cally_clone_new (ClutterActor *actor)
{
GObject *object = NULL;
AtkObject *accessible = NULL;
g_return_val_if_fail (CLUTTER_IS_CLONE (actor), NULL);
object = g_object_new (CALLY_TYPE_CLONE, NULL);
accessible = ATK_OBJECT (object);
atk_object_initialize (accessible, actor);
return accessible;
}
static void
cally_clone_real_initialize (AtkObject *obj,
gpointer data)
{
ATK_OBJECT_CLASS (cally_clone_parent_class)->initialize (obj, data);
obj->role = ATK_ROLE_IMAGE;
}

View File

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

View File

@ -0,0 +1,117 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2008 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* Based on gailfactory.h from GAIL
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef _CALLY_FACTORY_H__
#define _CALLY_FACTORY_H__
#include <glib-object.h>
#include <atk/atkobject.h>
/**
* CALLY_ACCESSIBLE_FACTORY:
* @type: GType of the accessible which is created by the factory
* @type_as_function: prefix of the accessible object methods
* @opt_create_accessible: method to instantiate the accessibility object
*
* Defines a new #AtkObjectFactory factory to create accessible
* objects of a specific GType. It defines the factory GType and also
* overrides the proper #AtkObjectFactory methods.
*
* It assumes that the accessibility object provides a
* @opt_create_accessible method in order to create the accessibility
* object. It returns a @type GType object.
*
* Since: 1.4
*/
#define CALLY_ACCESSIBLE_FACTORY(type, type_as_function, opt_create_accessible) \
\
static GType \
type_as_function ## _factory_get_accessible_type (void) \
{ \
return type; \
} \
\
static AtkObject* \
type_as_function ## _factory_create_accessible (GObject *obj) \
{ \
ClutterActor *actor; \
AtkObject *accessible; \
\
g_return_val_if_fail (CLUTTER_ACTOR (obj), NULL); \
\
actor = CLUTTER_ACTOR (obj); \
\
accessible = opt_create_accessible (actor); \
\
return accessible; \
} \
\
static void \
type_as_function ## _factory_class_init (AtkObjectFactoryClass *klass) \
{ \
klass->create_accessible = type_as_function ## _factory_create_accessible; \
klass->get_accessible_type = type_as_function ## _factory_get_accessible_type;\
} \
\
static GType \
type_as_function ## _factory_get_type (void) \
{ \
static GType t = 0; \
\
if (!t) \
{ \
char *name; \
static const GTypeInfo tinfo = \
{ \
sizeof (AtkObjectFactoryClass), \
NULL, NULL, (GClassInitFunc) type_as_function ## _factory_class_init, \
NULL, NULL, sizeof (AtkObjectFactory), 0, NULL, NULL \
}; \
\
name = g_strconcat (g_type_name (type), "Factory", NULL); \
t = g_type_register_static ( \
ATK_TYPE_OBJECT_FACTORY, name, &tinfo, 0); \
g_free (name); \
} \
\
return t; \
}
/**
* CALLY_ACTOR_SET_FACTORY:
* @widget_type: GType of the clutter actor
* @type_as_function: prefix of the accessible object methods
*
* Sets the #AtkObjectFactory to be used in order to instantiate
* accessibility objects for the actor which GType is @widget_type.
*
* Since: 1.4
*/
#define CALLY_ACTOR_SET_FACTORY(widget_type, type_as_function) \
atk_registry_set_factory_type (atk_get_default_registry (), \
widget_type, \
type_as_function ## _factory_get_type ())
#endif /* _CALLY_FACTORY_H__ */

View File

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

View File

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

View File

@ -0,0 +1,44 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2008 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* Some parts are based on GailWidget from GAIL
* GAIL - The GNOME Accessibility Implementation Library
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CALLY_MAIN_H__
#define __CALLY_MAIN_H__
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <cally/cally.h> can be included directly."
#endif
#include <glib.h>
#include <atk/atk.h>
G_BEGIN_DECLS
CLUTTER_AVAILABLE_IN_1_4
gboolean cally_get_cally_initialized (void);
CLUTTER_AVAILABLE_IN_1_4
gboolean cally_accessibility_init (void);
G_END_DECLS
#endif /* __CALLY_MAIN_H__ */

View File

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

View File

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

View File

@ -0,0 +1,294 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2008 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:cally-root
* @short_description: Root object for the Cally toolkit
* @see_also: #ClutterStage
*
* #CallyRoot is the root object of the accessibility tree-like
* hierarchy, exposing the application level.
*
* Somewhat equivalent to #GailTopLevel. We consider that this class
* expose the a11y information of the #ClutterStageManager, as the
* children of this object are the different ClutterStage managed (so
* the #GObject used in the atk_object_initialize() is the
* #ClutterStageManager).
*/
#include "config.h"
#include "cally-root.h"
#include "clutter-actor.h"
#include "clutter-stage-private.h"
#include "clutter-stage-manager.h"
/* GObject */
static void cally_root_finalize (GObject *object);
/* AtkObject.h */
static void cally_root_initialize (AtkObject *accessible,
gpointer data);
static gint cally_root_get_n_children (AtkObject *obj);
static AtkObject * cally_root_ref_child (AtkObject *obj,
gint i);
static AtkObject * cally_root_get_parent (AtkObject *obj);
static const char * cally_root_get_name (AtkObject *obj);
/* Private */
static void cally_util_stage_added_cb (ClutterStageManager *stage_manager,
ClutterStage *stage,
gpointer data);
static void cally_util_stage_removed_cb (ClutterStageManager *stage_manager,
ClutterStage *stage,
gpointer data);
struct _CallyRootPrivate
{
/* We save the CallyStage objects. Other option could save the stage
* list, and then just get the a11y object on the ref_child, etc. But
* the ref_child is more common that the init and the stage-add,
* stage-remove, so we avoid getting the accessible object
* constantly
*/
GSList *stage_list;
/* signals id */
guint stage_added_id;
guint stage_removed_id;
};
G_DEFINE_TYPE_WITH_PRIVATE (CallyRoot, cally_root, ATK_TYPE_GOBJECT_ACCESSIBLE)
static void
cally_root_class_init (CallyRootClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
gobject_class->finalize = cally_root_finalize;
/* AtkObject */
class->get_n_children = cally_root_get_n_children;
class->ref_child = cally_root_ref_child;
class->get_parent = cally_root_get_parent;
class->initialize = cally_root_initialize;
class->get_name = cally_root_get_name;
}
static void
cally_root_init (CallyRoot *root)
{
root->priv = cally_root_get_instance_private (root);
root->priv->stage_list = NULL;
root->priv->stage_added_id = 0;
root->priv->stage_removed_id = 0;
}
/**
* cally_root_new:
*
* Creates a new #CallyRoot object.
*
* Return value: the newly created #AtkObject
*
* Since: 1.4
*/
AtkObject*
cally_root_new (void)
{
GObject *object = NULL;
AtkObject *accessible = NULL;
ClutterStageManager *stage_manager = NULL;
object = g_object_new (CALLY_TYPE_ROOT, NULL);
accessible = ATK_OBJECT (object);
stage_manager = clutter_stage_manager_get_default ();
atk_object_initialize (accessible, stage_manager);
return accessible;
}
static void
cally_root_finalize (GObject *object)
{
CallyRoot *root = CALLY_ROOT (object);
GObject *stage_manager = NULL;
g_return_if_fail (CALLY_IS_ROOT (object));
if (root->priv->stage_list)
{
g_slist_free (root->priv->stage_list);
root->priv->stage_list = NULL;
}
stage_manager = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (root));
g_signal_handler_disconnect (stage_manager,
root->priv->stage_added_id);
g_signal_handler_disconnect (stage_manager,
root->priv->stage_added_id);
G_OBJECT_CLASS (cally_root_parent_class)->finalize (object);
}
/* AtkObject.h */
static void
cally_root_initialize (AtkObject *accessible,
gpointer data)
{
ClutterStageManager *stage_manager = NULL;
const GSList *iter = NULL;
const GSList *stage_list = NULL;
ClutterStage *clutter_stage = NULL;
AtkObject *cally_stage = NULL;
CallyRoot *root = NULL;
accessible->role = ATK_ROLE_APPLICATION;
accessible->accessible_parent = NULL;
/* children initialization */
root = CALLY_ROOT (accessible);
stage_manager = CLUTTER_STAGE_MANAGER (data);
stage_list = clutter_stage_manager_peek_stages (stage_manager);
for (iter = stage_list; iter != NULL; iter = g_slist_next (iter))
{
clutter_stage = CLUTTER_STAGE (iter->data);
cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (clutter_stage));
atk_object_set_parent (cally_stage, ATK_OBJECT (root));
root->priv->stage_list = g_slist_append (root->priv->stage_list,
cally_stage);
}
root->priv->stage_added_id =
g_signal_connect (G_OBJECT (stage_manager), "stage-added",
G_CALLBACK (cally_util_stage_added_cb), root);
root->priv->stage_removed_id =
g_signal_connect (G_OBJECT (stage_manager), "stage-removed",
G_CALLBACK (cally_util_stage_removed_cb), root);
ATK_OBJECT_CLASS (cally_root_parent_class)->initialize (accessible, data);
}
static gint
cally_root_get_n_children (AtkObject *obj)
{
CallyRoot *root = CALLY_ROOT (obj);
return g_slist_length (root->priv->stage_list);
}
static AtkObject*
cally_root_ref_child (AtkObject *obj,
gint i)
{
CallyRoot *cally_root = NULL;
GSList *stage_list = NULL;
gint num = 0;
AtkObject *item = NULL;
cally_root = CALLY_ROOT (obj);
stage_list = cally_root->priv->stage_list;
num = g_slist_length (stage_list);
g_return_val_if_fail ((i < num)&&(i >= 0), NULL);
item = g_slist_nth_data (stage_list, i);
if (!item)
{
return NULL;
}
g_object_ref (item);
return item;
}
static AtkObject*
cally_root_get_parent (AtkObject *obj)
{
return NULL;
}
static const char *
cally_root_get_name (AtkObject *obj)
{
return g_get_prgname ();
}
/* -------------------------------- PRIVATE --------------------------------- */
static void
cally_util_stage_added_cb (ClutterStageManager *stage_manager,
ClutterStage *stage,
gpointer data)
{
CallyRoot *root = CALLY_ROOT (data);
AtkObject *cally_stage = NULL;
gint index = -1;
cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage));
atk_object_set_parent (cally_stage, ATK_OBJECT (root));
root->priv->stage_list = g_slist_append (root->priv->stage_list,
cally_stage);
index = g_slist_index (root->priv->stage_list, cally_stage);
g_signal_emit_by_name (root, "children_changed::add",
index, cally_stage, NULL);
g_signal_emit_by_name (cally_stage, "create", 0);
}
static void
cally_util_stage_removed_cb (ClutterStageManager *stage_manager,
ClutterStage *stage,
gpointer data)
{
CallyRoot *root = CALLY_ROOT (data);
AtkObject *cally_stage = NULL;
gint index = -1;
cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage));
index = g_slist_index (root->priv->stage_list, cally_stage);
root->priv->stage_list = g_slist_remove (root->priv->stage_list,
cally_stage);
index = g_slist_index (root->priv->stage_list, cally_stage);
g_signal_emit_by_name (root, "children_changed::remove",
index, cally_stage, NULL);
g_signal_emit_by_name (cally_stage, "destroy", 0);
}

View File

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

View File

@ -0,0 +1,260 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2008 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:cally-stage
* @Title: CallyStage
* @short_description: Implementation of the ATK interfaces for a #ClutterStage
* @see_also: #ClutterStage
*
* #CallyStage implements the required ATK interfaces for #ClutterStage
*
* Some implementation details: at this moment #CallyStage is used as
* the most similar Window object in this toolkit (ie: emitting window
* related signals), although the real purpose of #ClutterStage is
* being a canvas. Anyway, this is required for applications using
* just clutter, or directly #ClutterStage
*/
#include "config.h"
#include "cally-stage.h"
#include "cally-actor-private.h"
/* AtkObject.h */
static void cally_stage_real_initialize (AtkObject *obj,
gpointer data);
static AtkStateSet* cally_stage_ref_state_set (AtkObject *obj);
/* AtkWindow */
static void cally_stage_window_interface_init (AtkWindowIface *iface);
/* Auxiliar */
static void cally_stage_activate_cb (ClutterStage *stage,
gpointer data);
static void cally_stage_deactivate_cb (ClutterStage *stage,
gpointer data);
struct _CallyStagePrivate
{
/* NULL means that the stage will receive the focus */
ClutterActor *key_focus;
gboolean active;
};
G_DEFINE_TYPE_WITH_CODE (CallyStage,
cally_stage,
CALLY_TYPE_GROUP,
G_ADD_PRIVATE (CallyStage)
G_IMPLEMENT_INTERFACE (ATK_TYPE_WINDOW,
cally_stage_window_interface_init));
static void
cally_stage_class_init (CallyStageClass *klass)
{
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
/* AtkObject */
class->initialize = cally_stage_real_initialize;
class->ref_state_set = cally_stage_ref_state_set;
}
static void
cally_stage_init (CallyStage *cally_stage)
{
CallyStagePrivate *priv = cally_stage_get_instance_private (cally_stage);
cally_stage->priv = priv;
priv->active = FALSE;
}
/**
* cally_stage_new:
* @actor: a #ClutterActor
*
* Creates a new #CallyStage for the given @actor. @actor should be a
* #ClutterStage.
*
* Return value: the newly created #AtkObject
*
* Since: 1.4
*/
AtkObject*
cally_stage_new (ClutterActor *actor)
{
GObject *object = NULL;
AtkObject *accessible = NULL;
g_return_val_if_fail (CLUTTER_IS_STAGE (actor), NULL);
object = g_object_new (CALLY_TYPE_STAGE, NULL);
accessible = ATK_OBJECT (object);
atk_object_initialize (accessible, actor);
return accessible;
}
static void
cally_stage_notify_key_focus_cb (ClutterStage *stage,
GParamSpec *pspec,
CallyStage *self)
{
ClutterActor *key_focus = NULL;
AtkObject *new = NULL;
if (self->priv->active == FALSE)
return;
key_focus = clutter_stage_get_key_focus (stage);
if (key_focus != self->priv->key_focus)
{
AtkObject *old = NULL;
if (self->priv->key_focus != NULL)
{
g_object_remove_weak_pointer (G_OBJECT (self->priv->key_focus),
(gpointer *) &self->priv->key_focus);
old = clutter_actor_get_accessible (self->priv->key_focus);
}
else
old = clutter_actor_get_accessible (CLUTTER_ACTOR (stage));
atk_object_notify_state_change (old,
ATK_STATE_FOCUSED,
FALSE);
}
/* we keep notifying the focus gain without checking previous
* key-focus to avoid some missing events due timing
*/
self->priv->key_focus = key_focus;
if (key_focus != NULL)
{
/* ensure that if the key focus goes away, the field inside
* CallyStage is reset. see bug:
*
* https://bugzilla.gnome.org/show_bug.cgi?id=692706
*
* we remove the weak pointer above.
*/
g_object_add_weak_pointer (G_OBJECT (self->priv->key_focus),
(gpointer *) &self->priv->key_focus);
new = clutter_actor_get_accessible (key_focus);
}
else
new = clutter_actor_get_accessible (CLUTTER_ACTOR (stage));
atk_object_notify_state_change (new,
ATK_STATE_FOCUSED,
TRUE);
}
static void
cally_stage_real_initialize (AtkObject *obj,
gpointer data)
{
ClutterStage *stage = NULL;
g_return_if_fail (CALLY_IS_STAGE (obj));
ATK_OBJECT_CLASS (cally_stage_parent_class)->initialize (obj, data);
stage = CLUTTER_STAGE (CALLY_GET_CLUTTER_ACTOR (obj));
g_signal_connect (stage, "activate", G_CALLBACK (cally_stage_activate_cb), obj);
g_signal_connect (stage, "deactivate", G_CALLBACK (cally_stage_deactivate_cb), obj);
g_signal_connect (stage, "notify::key-focus",
G_CALLBACK (cally_stage_notify_key_focus_cb), obj);
atk_object_set_role (obj, ATK_ROLE_WINDOW);
}
static AtkStateSet*
cally_stage_ref_state_set (AtkObject *obj)
{
CallyStage *cally_stage = NULL;
AtkStateSet *state_set = NULL;
ClutterStage *stage = NULL;
g_return_val_if_fail (CALLY_IS_STAGE (obj), NULL);
cally_stage = CALLY_STAGE (obj);
state_set = ATK_OBJECT_CLASS (cally_stage_parent_class)->ref_state_set (obj);
stage = CLUTTER_STAGE (CALLY_GET_CLUTTER_ACTOR (cally_stage));
if (stage == NULL)
return state_set;
if (cally_stage->priv->active)
atk_state_set_add_state (state_set, ATK_STATE_ACTIVE);
return state_set;
}
/* AtkWindow */
static void
cally_stage_window_interface_init (AtkWindowIface *iface)
{
/* At this moment AtkWindow is just about signals */
}
/* Auxiliar */
static void
cally_stage_activate_cb (ClutterStage *stage,
gpointer data)
{
CallyStage *cally_stage = NULL;
g_return_if_fail (CALLY_IS_STAGE (data));
cally_stage = CALLY_STAGE (data);
cally_stage->priv->active = TRUE;
atk_object_notify_state_change (ATK_OBJECT (cally_stage),
ATK_STATE_ACTIVE, TRUE);
g_signal_emit_by_name (cally_stage, "activate", 0);
}
static void
cally_stage_deactivate_cb (ClutterStage *stage,
gpointer data)
{
CallyStage *cally_stage = NULL;
g_return_if_fail (CALLY_IS_STAGE (data));
cally_stage = CALLY_STAGE (data);
cally_stage->priv->active = FALSE;
atk_object_notify_state_change (ATK_OBJECT (cally_stage),
ATK_STATE_ACTIVE, FALSE);
g_signal_emit_by_name (cally_stage, "deactivate", 0);
}

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

@ -0,0 +1,452 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2008 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* Based on GailUtil from GAIL
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:cally-util
* @Title: CallyUtil
* @short_description: #AtkUtil implementation
* @see_also: #ClutterActor
*
* #CallyUtil implements #AtkUtil abstract methods. Although it
* includes the name "Util" it is in fact one of the most important
* interfaces to be implemented in any ATK toolkit implementation.
* For instance, it defines atk_get_root(), the method that returns
* the root object in the hierarchy. Without it, you don't have
* available any accessible object.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include <clutter/clutter.h>
#include "cally-util.h"
#include "cally-root.h"
#include "cally-stage.h"
#define DEFAULT_PASSWORD_CHAR '*'
/* atkutil.h */
static guint cally_util_add_key_event_listener (AtkKeySnoopFunc listener,
gpointer data);
static void cally_util_remove_key_event_listener (guint remove_listener);
static AtkObject* cally_util_get_root (void);
static const gchar * cally_util_get_toolkit_name (void);
static const gchar * cally_util_get_toolkit_version (void);
/* private */
static void cally_util_simulate_snooper_install (void);
static void cally_util_simulate_snooper_remove (void);
static gboolean cally_key_snooper (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data);
static void cally_util_stage_added_cb (ClutterStageManager *stage_manager,
ClutterStage *stage,
gpointer data);
static void cally_util_stage_removed_cb (ClutterStageManager *stage_manager,
ClutterStage *stage,
gpointer data);
static gboolean notify_hf (gpointer key,
gpointer value,
gpointer data);
static void insert_hf (gpointer key,
gpointer value,
gpointer data);
/* This is just a copy of the Gail one, a shared library or place to
define it could be a good idea. */
typedef struct _CallyKeyEventInfo CallyKeyEventInfo;
struct _CallyKeyEventInfo
{
AtkKeySnoopFunc listener;
gpointer func_data;
};
static AtkObject* root = NULL;
static GHashTable *key_listener_list = NULL;
G_DEFINE_TYPE (CallyUtil, cally_util, ATK_TYPE_UTIL);
static void
cally_util_class_init (CallyUtilClass *klass)
{
AtkUtilClass *atk_class;
gpointer data;
data = g_type_class_peek (ATK_TYPE_UTIL);
atk_class = ATK_UTIL_CLASS (data);
atk_class->add_key_event_listener = cally_util_add_key_event_listener;
atk_class->remove_key_event_listener = cally_util_remove_key_event_listener;
atk_class->get_root = cally_util_get_root;
atk_class->get_toolkit_name = cally_util_get_toolkit_name;
atk_class->get_toolkit_version = cally_util_get_toolkit_version;
/* FIXME: Instead of create this on the class, I think that would
worth to implement CallyUtil as a singleton instance, so the
class methods will access this instance. This will be a good
future enhancement, meanwhile, just using the same *working*
implementation used on GailUtil */
}
static void
cally_util_init (CallyUtil *cally_util)
{
/* instance init: usually not required */
}
/* ------------------------------ ATK UTIL METHODS -------------------------- */
static AtkObject*
cally_util_get_root (void)
{
if (!root)
root = cally_root_new ();
return root;
}
static const gchar *
cally_util_get_toolkit_name (void)
{
return "clutter";
}
static const gchar *
cally_util_get_toolkit_version (void)
{
return CLUTTER_VERSION_S;
}
static guint
cally_util_add_key_event_listener (AtkKeySnoopFunc listener,
gpointer data)
{
static guint key = 1;
CallyKeyEventInfo *event_info = NULL;
if (!key_listener_list)
{
key_listener_list = g_hash_table_new_full (NULL, NULL, NULL, g_free);
cally_util_simulate_snooper_install ();
}
event_info = g_new (CallyKeyEventInfo, 1);
event_info->listener = listener;
event_info->func_data = data;
g_hash_table_insert (key_listener_list, GUINT_TO_POINTER (key++), event_info);
/* XXX: we don't check to see if n_listeners > MAXUINT */
return key - 1;
}
static void
cally_util_remove_key_event_listener (guint remove_listener)
{
if (!g_hash_table_remove (key_listener_list, GUINT_TO_POINTER (remove_listener))) {
g_warning ("Not able to remove listener with id %i", remove_listener);
}
if (g_hash_table_size (key_listener_list) == 0)
{
g_hash_table_destroy (key_listener_list);
key_listener_list = NULL;
cally_util_simulate_snooper_remove ();
}
}
/* ------------------------------ PRIVATE FUNCTIONS ------------------------- */
/* Trying to emulate gtk_key_snooper install (a kind of wrapper). This
could be implemented without it, but I will maintain it in this
way, so if in the future clutter implements it natively it would be
easier the transition */
static void
cally_util_simulate_snooper_install (void)
{
ClutterStageManager *stage_manager = NULL;
ClutterStage *stage = NULL;
GSList *stage_list = NULL;
GSList *iter = NULL;
stage_manager = clutter_stage_manager_get_default ();
stage_list = clutter_stage_manager_list_stages (stage_manager);
for (iter = stage_list; iter != NULL; iter = g_slist_next (iter))
{
stage = CLUTTER_STAGE (iter->data);
g_signal_connect (G_OBJECT (stage), "captured-event",
G_CALLBACK (cally_key_snooper), NULL);
}
g_signal_connect (G_OBJECT (stage_manager), "stage-added",
G_CALLBACK (cally_util_stage_added_cb), cally_key_snooper);
g_signal_connect (G_OBJECT (stage_manager), "stage-removed",
G_CALLBACK (cally_util_stage_removed_cb), cally_key_snooper);
}
static void
cally_util_simulate_snooper_remove (void)
{
ClutterStageManager *stage_manager = NULL;
ClutterStage *stage = NULL;
GSList *stage_list = NULL;
GSList *iter = NULL;
gint num = 0;
stage_manager = clutter_stage_manager_get_default ();
stage_list = clutter_stage_manager_list_stages (stage_manager);
for (iter = stage_list; iter != NULL; iter = g_slist_next (iter))
{
stage = CLUTTER_STAGE (iter->data);
num += g_signal_handlers_disconnect_by_func (stage, cally_key_snooper, NULL);
}
g_signal_handlers_disconnect_by_func (G_OBJECT (stage_manager),
G_CALLBACK (cally_util_stage_added_cb),
cally_key_snooper);
g_signal_handlers_disconnect_by_func (G_OBJECT (stage_manager),
G_CALLBACK (cally_util_stage_removed_cb),
cally_key_snooper);
#ifdef CALLY_DEBUG
g_print ("Number of snooper callbacks disconnected: %i\n", num);
#endif
}
static AtkKeyEventStruct *
atk_key_event_from_clutter_event_key (ClutterKeyEvent *clutter_event,
gunichar password_char)
{
AtkKeyEventStruct *atk_event = g_new0 (AtkKeyEventStruct, 1);
gunichar key_unichar;
switch (clutter_event->type)
{
case CLUTTER_KEY_PRESS:
atk_event->type = ATK_KEY_EVENT_PRESS;
break;
case CLUTTER_KEY_RELEASE:
atk_event->type = ATK_KEY_EVENT_RELEASE;
break;
default:
g_assert_not_reached ();
return NULL;
}
if (password_char)
atk_event->state = 0;
else
atk_event->state = clutter_event->modifier_state;
/* We emit the clutter keyval. This is not exactly the one expected
by AtkKeyEventStruct, as it expects a Gdk-like event, with the
modifiers applied. But to avoid a dependency to gdk, we delegate
that on the AT application.
More information: Bug 1952 and bug 2072
*/
if (password_char)
atk_event->keyval = clutter_unicode_to_keysym (password_char);
else
atk_event->keyval = clutter_event->keyval;
/* It is expected to store a key defining string here (ie "Space" in
case you press a space). Anyway, there are no function on clutter
to obtain that, and we want to avoid a gdk dependency here, so we
delegate on the AT application to obtain that string using the
rest of the data on the ATK event struct.
More information: Bug 1952 and 2072
*/
if (password_char)
key_unichar = password_char;
else
key_unichar = clutter_event_get_key_unicode ((ClutterEvent *) clutter_event);
if (g_unichar_validate (key_unichar) && !g_unichar_iscntrl (key_unichar))
{
GString *new = NULL;
new = g_string_new ("");
new = g_string_insert_unichar (new, 0, key_unichar);
atk_event->string = new->str;
g_string_free (new, FALSE);
}
else
atk_event->string = NULL;
atk_event->length = 0;
/* Computing the hardware keycode from the password-char is
difficult. But we are in a password situation. We are already a
unichar that it is not the original one. Providing a "almost
real" keycode is irrelevant */
if (password_char)
atk_event->keycode = 0;
else
atk_event->keycode = clutter_event->hardware_keycode;
atk_event->timestamp = clutter_event->time;
#ifdef CALLY_DEBUG
g_debug ("CallyKeyEvent:\tsym 0x%x\n\t\tmods %x\n\t\tcode %u\n\t\ttime %lx \n\t\tstring %s\n",
(unsigned int) atk_event->keyval,
(unsigned int) atk_event->state,
(unsigned int) atk_event->keycode,
(unsigned long int) atk_event->timestamp,
atk_event->string);
#endif
return atk_event;
}
static gboolean
notify_hf (gpointer key, gpointer value, gpointer data)
{
CallyKeyEventInfo *info = (CallyKeyEventInfo *) value;
AtkKeyEventStruct *key_event = (AtkKeyEventStruct *)data;
return (*(AtkKeySnoopFunc) info->listener) (key_event, info->func_data) ? TRUE : FALSE;
}
static void
insert_hf (gpointer key, gpointer value, gpointer data)
{
GHashTable *new_table = (GHashTable *) data;
g_hash_table_insert (new_table, key, value);
}
/*
* 0 if the key of that event is visible, in other case the password
* char
*/
static gunichar
check_key_visibility (ClutterEvent *event)
{
ClutterKeyEvent *key_event = (ClutterKeyEvent *)event;
AtkObject *accessible = clutter_actor_get_accessible (key_event->source);
g_return_val_if_fail (accessible != NULL, 0);
if (atk_object_get_role (accessible) != ATK_ROLE_PASSWORD_TEXT)
return 0;
/* If it is a clutter text, we use his password char. Note that
although at Clutter toolkit itself, only ClutterText exposes a
password role, nothing prevents on any derived toolkit (like st)
to create a new actor that can behave like a password entry. And
the key event will still be emitted here. Although in that case
we would lose any password char from the derived toolkit, it is
still better fill this with a default unichar that the original
one */
if (CLUTTER_IS_TEXT (key_event->source))
return clutter_text_get_password_char (CLUTTER_TEXT (key_event->source));
else
return DEFAULT_PASSWORD_CHAR;
}
static gboolean
cally_key_snooper (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
AtkKeyEventStruct *key_event = NULL;
gint consumed = 0;
gunichar password_char = 0;
/* filter key events */
if ((event->type != CLUTTER_KEY_PRESS) && (event->type != CLUTTER_KEY_RELEASE))
{
return FALSE;
}
password_char = check_key_visibility (event);
if (key_listener_list)
{
GHashTable *new_hash = g_hash_table_new (NULL, NULL);
g_hash_table_foreach (key_listener_list, insert_hf, new_hash);
key_event = atk_key_event_from_clutter_event_key ((ClutterKeyEvent *)event,
password_char);
/* func data is inside the hash table */
consumed = g_hash_table_foreach_steal (new_hash, notify_hf, key_event);
g_hash_table_destroy (new_hash);
g_free (key_event->string);
g_free (key_event);
}
return (consumed ? 1 : 0);
}
static void
cally_util_stage_added_cb (ClutterStageManager *stage_manager,
ClutterStage *stage,
gpointer data)
{
GCallback cally_key_snooper_cb = G_CALLBACK (data);
g_signal_connect (G_OBJECT (stage), "captured-event", cally_key_snooper_cb, NULL);
}
static void
cally_util_stage_removed_cb (ClutterStageManager *stage_manager,
ClutterStage *stage,
gpointer data)
{
GCallback cally_key_snooper_cb = G_CALLBACK (data);
g_signal_handlers_disconnect_by_func (stage, cally_key_snooper_cb, NULL);
}
void
_cally_util_override_atk_util (void)
{
AtkUtilClass *atk_class = ATK_UTIL_CLASS (g_type_class_ref (ATK_TYPE_UTIL));
atk_class->add_key_event_listener = cally_util_add_key_event_listener;
atk_class->remove_key_event_listener = cally_util_remove_key_event_listener;
atk_class->get_root = cally_util_get_root;
atk_class->get_toolkit_name = cally_util_get_toolkit_name;
atk_class->get_toolkit_version = cally_util_get_toolkit_version;
}

View File

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

View File

@ -0,0 +1,108 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2008 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:cally
* @Title: Cally
* @short_description: Cally initialization methods.
*
* Cally initialization methods.
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
#include "cally.h"
#include "cally-actor.h"
#include "cally-group.h"
#include "cally-stage.h"
#include "cally-text.h"
#include "cally-texture.h"
#include "cally-rectangle.h"
#include "cally-clone.h"
#include "cally-factory.h"
#include "cally-util.h"
#include "clutter.h"
#include "clutter-debug.h"
#include "clutter-private.h"
/* factories initialization*/
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_ACTOR, cally_actor, cally_actor_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_GROUP, cally_group, cally_group_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_STAGE, cally_stage, cally_stage_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXT, cally_text, cally_text_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXTURE, cally_texture, cally_texture_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_RECTANGLE, cally_rectangle, cally_rectangle_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_CLONE, cally_clone, cally_clone_new)
/**
* cally_accessibility_init:
*
* Initializes the accessibility support.
*
* Return value: %TRUE if accessibility support has been correctly
* initialized.
*
* Since: 1.4
*/
gboolean
cally_accessibility_init (void)
{
/* setting the factories */
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_ACTOR, cally_actor);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_GROUP, cally_group);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_STAGE, cally_stage);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXT, cally_text);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXTURE, cally_texture);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_RECTANGLE, cally_rectangle);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_CLONE, cally_clone);
/* Initialize the CallyUtility class */
_cally_util_override_atk_util ();
CLUTTER_NOTE (MISC, "Clutter Accessibility initialized");
return TRUE;
}
/**
* cally_get_cally_initialized:
*
* Returns if the accessibility support using cally is enabled.
*
* Return value: %TRUE if accessibility support has been correctly
* initialized.
*
* Since: 1.4
*/
gboolean cally_get_cally_initialized (void)
{
return !g_strcmp0 (atk_get_toolkit_name (), "clutter");
}

View File

@ -0,0 +1,40 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2008 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CALLY_H__
#define __CALLY_H__
#define __CALLY_H_INSIDE__
#include "cally-actor.h"
#include "cally-clone.h"
#include "cally-factory.h"
#include "cally-group.h"
#include "cally-main.h"
#include "cally-rectangle.h"
#include "cally-root.h"
#include "cally-stage.h"
#include "cally-text.h"
#include "cally-texture.h"
#include "cally-util.h"
#undef __CALLY_H_INSIDE__
#endif /* __CALLY_H__ */

View File

@ -0,0 +1,63 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-action
* @Title: ClutterAction
* @Short_Description: Abstract class for event-related logic
* @See_Also: #ClutterConstraint
*
* #ClutterAction is an abstract base class for event-related actions that
* modify the user interaction of a #ClutterActor, just like
* #ClutterConstraint is an abstract class for modifiers of an actor's
* position or size.
*
* Implementations of #ClutterAction are associated to an actor and can
* provide behavioral changes when dealing with user input - for instance
* drag and drop capabilities, or scrolling, or panning - by using the
* various event-related signals provided by #ClutterActor itself.
*
* #ClutterAction is available since Clutter 1.4
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-action.h"
#include "clutter-debug.h"
#include "clutter-private.h"
G_DEFINE_ABSTRACT_TYPE (ClutterAction, clutter_action, CLUTTER_TYPE_ACTOR_META);
static void
clutter_action_class_init (ClutterActionClass *klass)
{
}
static void
clutter_action_init (ClutterAction *self)
{
}

View File

@ -0,0 +1,111 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_ACTION_H__
#define __CLUTTER_ACTION_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-actor-meta.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_ACTION (clutter_action_get_type ())
#define CLUTTER_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTION, ClutterAction))
#define CLUTTER_IS_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTION))
#define CLUTTER_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTION, ClutterActionClass))
#define CLUTTER_IS_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTION))
#define CLUTTER_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTION, ClutterActionClass))
typedef struct _ClutterActionClass ClutterActionClass;
/**
* ClutterAction:
*
* The #ClutterAction structure contains only private data and
* should be accessed using the provided API.
*
* Since: 1.4
*/
struct _ClutterAction
{
/*< private >*/
ClutterActorMeta parent_instance;
};
/**
* ClutterActionClass:
*
* The ClutterActionClass structure contains only private data
*
* Since: 1.4
*/
struct _ClutterActionClass
{
/*< private >*/
ClutterActorMetaClass parent_class;
void (* _clutter_action1) (void);
void (* _clutter_action2) (void);
void (* _clutter_action3) (void);
void (* _clutter_action4) (void);
void (* _clutter_action5) (void);
void (* _clutter_action6) (void);
void (* _clutter_action7) (void);
void (* _clutter_action8) (void);
};
CLUTTER_AVAILABLE_IN_1_4
GType clutter_action_get_type (void) G_GNUC_CONST;
/* ClutterActor API */
CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_add_action (ClutterActor *self,
ClutterAction *action);
CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_add_action_with_name (ClutterActor *self,
const gchar *name,
ClutterAction *action);
CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_remove_action (ClutterActor *self,
ClutterAction *action);
CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_remove_action_by_name (ClutterActor *self,
const gchar *name);
CLUTTER_AVAILABLE_IN_1_4
ClutterAction *clutter_actor_get_action (ClutterActor *self,
const gchar *name);
CLUTTER_AVAILABLE_IN_1_4
GList * clutter_actor_get_actions (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_clear_actions (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
gboolean clutter_actor_has_actions (ClutterActor *self);
G_END_DECLS
#endif /* __CLUTTER_ACTION_H__ */

View File

@ -0,0 +1,550 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include "clutter-types.h"
#include "clutter-interval.h"
#include "clutter-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 #ClutterActorBox using the passed coordinates
* for the top left and bottom right points.
*
* This function is the logical equivalent of:
*
* |[
* 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 clutter_actor_box_free() to free the resources
*
* Since: 1.0
*/
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 #ClutterActorBox.
*
* Return value: (transfer full): the newly allocated #ClutterActorBox.
* Use clutter_actor_box_free() to free its resources
*
* Since: 1.12
*/
ClutterActorBox *
clutter_actor_box_alloc (void)
{
return g_slice_new0 (ClutterActorBox);
}
/**
* 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
*
* Since: 1.10
*/
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.
*
* Since: 1.10
*/
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
* clutter_actor_box_free() to free the allocated resources
*
* Since: 1.0
*/
ClutterActorBox *
clutter_actor_box_copy (const ClutterActorBox *box)
{
if (G_LIKELY (box != NULL))
return g_slice_dup (ClutterActorBox, box);
return NULL;
}
/**
* clutter_actor_box_free:
* @box: a #ClutterActorBox
*
* Frees a #ClutterActorBox allocated using clutter_actor_box_new()
* or clutter_actor_box_copy()
*
* Since: 1.0
*/
void
clutter_actor_box_free (ClutterActorBox *box)
{
if (G_LIKELY (box != NULL))
g_slice_free (ClutterActorBox, 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
*
* Since: 1.0
*/
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
*
* Since: 1.0
*/
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
*
* Since: 1.0
*/
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
*
* Since: 1.0
*/
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
*
* Since: 1.0
*/
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
*
* Since: 1.0
*/
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
*
* Since: 1.0
*/
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
*
* Since: 1.0
*/
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
* withing @box
*
* Return value: %TRUE if the point is contained by the #ClutterActorBox
*
* Since: 1.0
*/
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 #ClutterVertex
*
* Calculates the bounding box represented by the four vertices; for details
* of the vertex array see clutter_actor_get_abs_allocation_vertices().
*
* Since: 1.0
*/
void
clutter_actor_box_from_vertices (ClutterActorBox *box,
const ClutterVertex 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
*
* Since: 1.2
*/
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
*
* Since: 1.2
*/
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.
*
* Since: 1.4
*/
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.
*
* Since: 1.6
*/
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.
*
* Since: 1.6
*/
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;
}
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));

View File

@ -0,0 +1,97 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_ACTOR_META_PRIVATE_H__
#define __CLUTTER_ACTOR_META_PRIVATE_H__
#include <clutter/clutter-actor-meta.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_META_GROUP (_clutter_meta_group_get_type ())
#define CLUTTER_META_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_META_GROUP, ClutterMetaGroup))
#define CLUTTER_IS_META_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_META_GROUP))
typedef struct _ClutterMetaGroup ClutterMetaGroup;
typedef struct _ClutterMetaGroupClass ClutterMetaGroupClass;
struct _ClutterMetaGroup
{
GObject parent_instance;
ClutterActor *actor;
GList *meta;
};
struct _ClutterMetaGroupClass
{
GObjectClass parent_class;
};
/* Each actor meta has a priority with zero as a default. A higher
number means higher priority. Higher priority metas stay at the
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)
GType _clutter_meta_group_get_type (void) G_GNUC_CONST;
void _clutter_meta_group_add_meta (ClutterMetaGroup *group,
ClutterActorMeta *meta);
void _clutter_meta_group_remove_meta (ClutterMetaGroup *group,
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 */
void _clutter_actor_meta_set_actor (ClutterActorMeta *meta,
ClutterActor *actor);
const gchar * _clutter_actor_meta_get_debug_name (ClutterActorMeta *meta);
void _clutter_actor_meta_set_priority (ClutterActorMeta *meta,
gint priority);
int _clutter_actor_meta_get_priority (ClutterActorMeta *meta);
gboolean _clutter_actor_meta_is_internal (ClutterActorMeta *meta);
G_END_DECLS
#endif /* __CLUTTER_ACTOR_META_PRIVATE_H__ */

View File

@ -0,0 +1,664 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-actor-meta
* @Title: ClutterActorMeta
* @Short_Description: Base class of actor modifiers
* @See_Also: #ClutterAction, #ClutterConstraint
*
* #ClutterActorMeta is an abstract class providing a common API for
* modifiers of #ClutterActor behaviour, appearance or layout.
*
* A #ClutterActorMeta can only be owned by a single #ClutterActor at
* any time.
*
* Every sub-class of #ClutterActorMeta should check if the
* #ClutterActorMeta:enabled property is set to %TRUE before applying
* any kind of modification.
*
* #ClutterActorMeta is available since Clutter 1.4
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-actor-meta-private.h"
#include "clutter-debug.h"
#include "clutter-private.h"
struct _ClutterActorMetaPrivate
{
ClutterActor *actor;
guint 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)
{
meta->priv->actor = NULL;
}
static void
clutter_actor_meta_real_set_actor (ClutterActorMeta *meta,
ClutterActor *actor)
{
if (meta->priv->actor == actor)
return;
if (meta->priv->destroy_id != 0)
{
g_signal_handler_disconnect (meta->priv->actor, meta->priv->destroy_id);
meta->priv->destroy_id = 0;
}
meta->priv->actor = actor;
if (meta->priv->actor != NULL)
meta->priv->destroy_id = g_signal_connect (meta->priv->actor, "destroy",
G_CALLBACK (on_actor_destroy),
meta);
}
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)
{
ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject);
switch (prop_id)
{
case PROP_ACTOR:
g_value_set_object (value, meta->priv->actor);
break;
case PROP_NAME:
g_value_set_string (value, meta->priv->name);
break;
case PROP_ENABLED:
g_value_set_boolean (value, meta->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 (gobject)->priv;
if (priv->destroy_id != 0 && priv->actor != NULL)
g_signal_handler_disconnect (priv->actor, priv->destroy_id);
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;
/**
* ClutterActorMeta:actor:
*
* The #ClutterActor attached to the #ClutterActorMeta instance
*
* Since: 1.4
*/
obj_props[PROP_ACTOR] =
g_param_spec_object ("actor",
P_("Actor"),
P_("The actor attached to the meta"),
CLUTTER_TYPE_ACTOR,
CLUTTER_PARAM_READABLE);
/**
* ClutterActorMeta:name:
*
* The unique name to access the #ClutterActorMeta
*
* Since: 1.4
*/
obj_props[PROP_NAME] =
g_param_spec_string ("name",
P_("Name"),
P_("The name of the meta"),
NULL,
CLUTTER_PARAM_READWRITE);
/**
* ClutterActorMeta:enabled:
*
* Whether or not the #ClutterActorMeta is enabled
*
* Since: 1.4
*/
obj_props[PROP_ENABLED] =
g_param_spec_boolean ("enabled",
P_("Enabled"),
P_("Whether the meta is enabled"),
TRUE,
CLUTTER_PARAM_READWRITE);
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)
{
self->priv = clutter_actor_meta_get_instance_private (self);
self->priv->is_enabled = TRUE;
self->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
*
* Since: 1.4
*/
void
clutter_actor_meta_set_name (ClutterActorMeta *meta,
const gchar *name)
{
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
if (g_strcmp0 (meta->priv->name, name) == 0)
return;
g_free (meta->priv->name);
meta->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 clutter_actor_meta_set_name()
*
* Return value: (transfer none): the name of the #ClutterActorMeta
* instance, or %NULL if none was set. The returned string is owned
* by the #ClutterActorMeta instance and it should not be modified
* or freed
*
* Since: 1.4
*/
const gchar *
clutter_actor_meta_get_name (ClutterActorMeta *meta)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
return meta->priv->name;
}
/**
* clutter_actor_meta_set_enabled:
* @meta: a #ClutterActorMeta
* @is_enabled: whether @meta is enabled
*
* Sets whether @meta should be enabled or not
*
* Since: 1.4
*/
void
clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
gboolean is_enabled)
{
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
is_enabled = !!is_enabled;
if (meta->priv->is_enabled == is_enabled)
return;
meta->priv->is_enabled = is_enabled;
g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ENABLED]);
}
/**
* clutter_actor_meta_get_enabled:
* @meta: a #ClutterActorMeta
*
* Retrieves whether @meta is enabled
*
* Return value: %TRUE if the #ClutterActorMeta instance is enabled
*
* Since: 1.4
*/
gboolean
clutter_actor_meta_get_enabled (ClutterActorMeta *meta)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), FALSE);
return meta->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
*
* Since: 1.4
*/
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 #ClutterActor that owns @meta
*
* Return value: (transfer none): a pointer to a #ClutterActor or %NULL
*
* Since: 1.4
*/
ClutterActor *
clutter_actor_meta_get_actor (ClutterActorMeta *meta)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
return meta->priv->actor;
}
void
_clutter_actor_meta_set_priority (ClutterActorMeta *meta,
gint priority)
{
g_return_if_fail (CLUTTER_IS_ACTOR_META (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 (meta->priv->actor == NULL);
meta->priv->priority = priority;
}
gint
_clutter_actor_meta_get_priority (ClutterActorMeta *meta)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), 0);
return meta->priv->priority;
}
gboolean
_clutter_actor_meta_is_internal (ClutterActorMeta *meta)
{
gint priority = meta->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_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)
{
GList *prev = NULL, *l;
if (meta->priv->actor != NULL)
{
g_warning ("The meta of type '%s' with name '%s' is "
"already attached to actor '%s'",
G_OBJECT_TYPE_NAME (meta),
meta->priv->name != NULL
? meta->priv->name
: "<unknown>",
clutter_actor_get_name (meta->priv->actor) != NULL
? clutter_actor_get_name (meta->priv->actor)
: G_OBJECT_TYPE_NAME (meta->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)
{
if (meta->priv->actor != group->actor)
{
g_warning ("The meta of type '%s' with name '%s' is not "
"attached to the actor '%s'",
G_OBJECT_TYPE_NAME (meta),
meta->priv->name != NULL
? meta->priv->name
: "<unknown>",
clutter_actor_get_name (group->actor) != NULL
? clutter_actor_get_name (group->actor)
: G_OBJECT_TYPE_NAME (group->actor));
return;
}
_clutter_actor_meta_set_actor (meta, NULL);
group->meta = g_list_remove (group->meta, meta);
g_object_unref (meta);
}
/*
* _clutter_meta_group_peek_metas:
* @group: a #ClutterMetaGroup
*
* Returns a pointer to the #ClutterActorMeta list
*
* Return value: a const pointer to the #GList of #ClutterActorMeta
*/
const GList *
_clutter_meta_group_peek_metas (ClutterMetaGroup *group)
{
return group->meta;
}
/*
* _clutter_meta_group_get_metas_no_internal:
* @group: a #ClutterMetaGroup
*
* Returns a new allocated list containing all of the metas that don't
* have an internal priority.
*
* Return value: A GList containing non-internal metas. Free with
* g_list_free.
*/
GList *
_clutter_meta_group_get_metas_no_internal (ClutterMetaGroup *group)
{
GList *ret = NULL;
GList *l;
/* Build a new list filtering out the internal metas */
for (l = group->meta; l; l = l->next)
if (!_clutter_actor_meta_is_internal (l->data))
ret = g_list_prepend (ret, l->data);
return g_list_reverse (ret);
}
/*
* _clutter_meta_group_has_metas_no_internal:
* @group: a #ClutterMetaGroup
*
* Returns whether the group has any metas that don't have an internal priority.
*
* Return value: %TRUE if metas without internal priority exist
* %FALSE otherwise
*/
gboolean
_clutter_meta_group_has_metas_no_internal (ClutterMetaGroup *group)
{
GList *l;
for (l = group->meta; l; l = l->next)
if (!_clutter_actor_meta_is_internal (l->data))
return TRUE;
return FALSE;
}
/*
* _clutter_meta_group_clear_metas:
* @group: a #ClutterMetaGroup
*
* Clears @group of all #ClutterActorMeta instances and releases
* the reference on them
*/
void
_clutter_meta_group_clear_metas (ClutterMetaGroup *group)
{
g_list_foreach (group->meta, (GFunc) _clutter_actor_meta_set_actor, NULL);
g_list_foreach (group->meta, (GFunc) g_object_unref, NULL);
g_list_free (group->meta);
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;
if (g_strcmp0 (meta->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)
{
return meta->priv->name != NULL ? meta->priv->name
: G_OBJECT_TYPE_NAME (meta);
}

View File

@ -0,0 +1,119 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_ACTOR_META_H__
#define __CLUTTER_ACTOR_META_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-types.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_ACTOR_META (clutter_actor_meta_get_type ())
#define CLUTTER_ACTOR_META(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMeta))
#define CLUTTER_IS_ACTOR_META(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTOR_META))
#define CLUTTER_ACTOR_META_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass))
#define CLUTTER_IS_ACTOR_META_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTOR_META))
#define CLUTTER_ACTOR_META_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass))
typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate;
typedef struct _ClutterActorMetaClass ClutterActorMetaClass;
/**
* ClutterActorMeta:
*
* The #ClutterActorMeta structure contains only
* private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _ClutterActorMeta
{
/*< private >*/
GInitiallyUnowned parent_instance;
ClutterActorMetaPrivate *priv;
};
/**
* ClutterActorMetaClass:
* @set_actor: virtual function, invoked when attaching and detaching
* a #ClutterActorMeta instance to a #ClutterActor
*
* The #ClutterActorMetaClass structure contains
* only private data
*
* Since: 1.4
*/
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);
/*< private >*/
void (* _clutter_meta1) (void);
void (* _clutter_meta2) (void);
void (* _clutter_meta3) (void);
void (* _clutter_meta4) (void);
void (* _clutter_meta5) (void);
void (* _clutter_meta6) (void);
void (* _clutter_meta7) (void);
};
CLUTTER_AVAILABLE_IN_1_4
GType clutter_actor_meta_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_meta_set_name (ClutterActorMeta *meta,
const gchar *name);
CLUTTER_AVAILABLE_IN_1_4
const gchar * clutter_actor_meta_get_name (ClutterActorMeta *meta);
CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
gboolean is_enabled);
CLUTTER_AVAILABLE_IN_1_4
gboolean clutter_actor_meta_get_enabled (ClutterActorMeta *meta);
CLUTTER_AVAILABLE_IN_1_4
ClutterActor * clutter_actor_meta_get_actor (ClutterActorMeta *meta);
G_END_DECLS
#endif /* __CLUTTER_ACTOR_META_H__ */

View File

@ -0,0 +1,327 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CLUTTER_ACTOR_PRIVATE_H__
#define __CLUTTER_ACTOR_PRIVATE_H__
#include <clutter/clutter-actor.h>
G_BEGIN_DECLS
/*< private >
* ClutterRedrawFlags:
* @CLUTTER_REDRAW_CLIPPED_TO_ALLOCATION: Tells clutter the maximum
* extents of what needs to be redrawn lies within the actors
* current allocation. (Only use this for 2D actors though because
* any actor with depth may be projected outside of its allocation)
*
* Flags passed to the clutter_actor_queue_redraw_with_clip ()
* function
*
* Since: 1.6
*/
typedef enum
{
CLUTTER_REDRAW_CLIPPED_TO_ALLOCATION = 1 << 0
} ClutterRedrawFlags;
/*< private >
* ClutterActorTraverseFlags:
* CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST: Traverse the graph in
* 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. The difference when compared to
* #ClutterCallback is that it returns a boolean so it is possible to break
* out of an iteration early.
*
* Return value: %TRUE to continue iterating or %FALSE to break iteration
* early.
*/
typedef gboolean (*ClutterForeachCallback) (ClutterActor *actor,
gpointer user_data);
typedef struct _AnchorCoord AnchorCoord;
typedef struct _SizeRequest SizeRequest;
typedef struct _ClutterLayoutInfo ClutterLayoutInfo;
typedef struct _ClutterTransformInfo ClutterTransformInfo;
typedef struct _ClutterAnimationInfo ClutterAnimationInfo;
/* Internal helper struct to represent a point that can be stored in
either direct pixel coordinates or as a fraction of the actor's
size. It is used for the anchor point, scale center and rotation
centers. */
struct _AnchorCoord
{
gboolean is_fractional;
union
{
/* Used when is_fractional == TRUE */
struct
{
gdouble x;
gdouble y;
} fraction;
/* Use when is_fractional == FALSE */
ClutterVertex units;
} v;
};
struct _SizeRequest
{
guint age;
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 */
ClutterPoint fixed_pos;
ClutterMargin margin;
guint x_align : 4;
guint y_align : 4;
guint x_expand : 1;
guint y_expand : 1;
ClutterSize minimum;
ClutterSize 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 (angle and center) */
gdouble rx_angle;
AnchorCoord rx_center;
gdouble ry_angle;
AnchorCoord ry_center;
gdouble rz_angle;
AnchorCoord rz_center;
/* scaling */
gdouble scale_x;
gdouble scale_y;
gdouble scale_z;
AnchorCoord scale_center;
/* anchor point */
AnchorCoord anchor;
/* translation */
ClutterVertex translation;
/* z_position */
gfloat z_position;
/* transformation center */
ClutterPoint pivot;
gfloat pivot_z;
CoglMatrix transform;
guint transform_set : 1;
CoglMatrix 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,
...);
ClutterTransition * _clutter_actor_get_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,
CoglMatrix *matrix);
void _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self,
ClutterActor *ancestor,
CoglMatrix *matrix);
void _clutter_actor_rerealize (ClutterActor *self,
ClutterCallback callback,
gpointer data);
void _clutter_actor_set_in_clone_paint (ClutterActor *self,
gboolean is_in_clone_paint);
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_queue_redraw_with_clip (ClutterActor *self,
ClutterRedrawFlags flags,
ClutterPaintVolume *clip_volume);
void _clutter_actor_queue_redraw_full (ClutterActor *self,
ClutterRedrawFlags flags,
ClutterPaintVolume *volume,
ClutterEffect *effect);
ClutterPaintVolume * _clutter_actor_get_queue_redraw_clip (ClutterActor *self);
void _clutter_actor_set_queue_redraw_clip (ClutterActor *self,
ClutterPaintVolume *clip_volume);
void _clutter_actor_finish_queue_redraw (ClutterActor *self,
ClutterPaintVolume *clip);
gboolean _clutter_actor_set_default_paint_volume (ClutterActor *self,
GType check_gtype,
ClutterPaintVolume *volume);
const gchar * _clutter_actor_get_debug_name (ClutterActor *self);
void _clutter_actor_push_clone_paint (void);
void _clutter_actor_pop_clone_paint (void);
guint32 _clutter_actor_get_pick_id (ClutterActor *self);
void _clutter_actor_shader_pre_paint (ClutterActor *actor,
gboolean repeat);
void _clutter_actor_shader_post_paint (ClutterActor *actor);
ClutterActorAlign _clutter_actor_get_effective_x_align (ClutterActor *self);
void _clutter_actor_handle_event (ClutterActor *actor,
const ClutterEvent *event);
void _clutter_actor_attach_clone (ClutterActor *actor,
ClutterActor *clone);
void _clutter_actor_detach_clone (ClutterActor *actor,
ClutterActor *clone);
void _clutter_actor_queue_redraw_on_clones (ClutterActor *actor);
void _clutter_actor_queue_relayout_on_clones (ClutterActor *actor);
void _clutter_actor_queue_only_relayout (ClutterActor *actor);
CoglFramebuffer * _clutter_actor_get_active_framebuffer (ClutterActor *actor);
ClutterPaintNode * clutter_actor_create_texture_paint_node (ClutterActor *self,
CoglTexture *texture);
G_END_DECLS
#endif /* __CLUTTER_ACTOR_PRIVATE_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,904 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
*
* Copyright (C) 2006, 2007, 2008 OpenedHand Ltd
* Copyright (C) 2009, 2010 Intel Corp
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CLUTTER_ACTOR_H__
#define __CLUTTER_ACTOR_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
/* clutter-actor.h */
#include <gio/gio.h>
#include <pango/pango.h>
#include <atk/atk.h>
#include <cogl/cogl.h>
#include <clutter/clutter-types.h>
#include <clutter/clutter-event.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))
/**
* CLUTTER_ACTOR_SET_FLAGS:
* @a: a #ClutterActor
* @f: the #ClutterActorFlags to set
*
* Sets the given flags on a #ClutterActor
*
* Deprecated: 1.24: Changing flags directly is heavily discouraged in
* newly written code. #ClutterActor will take care of setting the
* internal state.
*/
#define CLUTTER_ACTOR_SET_FLAGS(a,f) \
CLUTTER_MACRO_DEPRECATED_IN_1_24 \
(((ClutterActor*)(a))->flags |= (f))
/**
* CLUTTER_ACTOR_UNSET_FLAGS:
* @a: a #ClutterActor
* @f: the #ClutterActorFlags to unset
*
* Unsets the given flags on a #ClutterActor
*
* Deprecated: 1.24: Changing flags directly is heavily discouraged in
* newly written code. #ClutterActor will take care of unsetting the
* internal state.
*/
#define CLUTTER_ACTOR_UNSET_FLAGS(a,f) \
CLUTTER_MACRO_DEPRECATED_IN_1_24 \
(((ClutterActor*)(a))->flags &= ~(f))
#define CLUTTER_ACTOR_IS_MAPPED(a) \
CLUTTER_MACRO_DEPRECATED_IN_1_24_FOR ("Deprecated macro. Use clutter_actor_is_mapped instead") \
((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_MAPPED) != FALSE)
#define CLUTTER_ACTOR_IS_REALIZED(a) \
CLUTTER_MACRO_DEPRECATED_IN_1_24_FOR ("Deprecated macro. Use clutter_actor_is_realized instead") \
((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_REALIZED) != FALSE)
#define CLUTTER_ACTOR_IS_VISIBLE(a) \
CLUTTER_MACRO_DEPRECATED_IN_1_24_FOR ("Deprecated macro. Use clutter_actor_is_visible instead") \
((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_VISIBLE) != FALSE)
#define CLUTTER_ACTOR_IS_REACTIVE(a) \
CLUTTER_MACRO_DEPRECATED_IN_1_24_FOR ("Deprecated macro. Use clutter_actor_get_reactive instead") \
((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_REACTIVE) != FALSE)
typedef struct _ClutterActorClass ClutterActorClass;
typedef struct _ClutterActorPrivate ClutterActorPrivate;
/**
* ClutterCallback:
* @actor: a #ClutterActor
* @data: (closure): user data
*
* Generic callback
*/
typedef void (*ClutterCallback) (ClutterActor *actor,
gpointer data);
/**
* CLUTTER_CALLBACK:
* @f: a function
*
* Convenience macro to cast a function to #ClutterCallback
*/
#define CLUTTER_CALLBACK(f) ((ClutterCallback) (f))
/**
* ClutterActor:
* @flags: #ClutterActorFlags
*
* Base class for actors.
*/
struct _ClutterActor
{
/*< private >*/
GInitiallyUnowned parent_instance;
/*< public >*/
guint32 flags;
/*< private >*/
guint32 private_flags;
ClutterActorPrivate *priv;
};
/**
* ClutterActorClass:
* @show: signal class handler for #ClutterActor::show; it must chain
* up to the parent's implementation
* @show_all: virtual function for containers and composite actors, to
* determine which children should be shown when calling
* clutter_actor_show_all() on the actor. Defaults to calling
* clutter_actor_show(). This virtual function is deprecated and it
* should not be overridden.
* @hide: signal class handler for #ClutterActor::hide; it must chain
* up to the parent's implementation
* @hide_all: virtual function for containers and composite actors, to
* 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 settings the coordinates of an
* actor; it is used by clutter_actor_allocate(); it must chain up to
* the parent's implementation, or call clutter_actor_set_allocation()
* @apply_transform: virtual function, used when applying the transformations
* to an actor before painting it or when transforming coordinates or
* the allocation; it must chain up to the parent's implementation
* @parent_set: signal class handler for the #ClutterActor::parent-set
* @destroy: signal class handler for #ClutterActor::destroy. It must
* chain up to the parent's implementation
* @pick: virtual function, used to draw an outline of the actor with
* the given color
* @queue_redraw: class handler for #ClutterActor::queue-redraw
* @event: class handler for #ClutterActor::event
* @button_press_event: class handler for #ClutterActor::button-press-event
* @button_release_event: class handler for
* #ClutterActor::button-release-event
* @scroll_event: signal class closure for #ClutterActor::scroll-event
* @key_press_event: signal class closure for #ClutterActor::key-press-event
* @key_release_event: signal class closure for
* #ClutterActor::key-release-event
* @motion_event: signal class closure for #ClutterActor::motion-event
* @enter_event: signal class closure for #ClutterActor::enter-event
* @leave_event: signal class closure for #ClutterActor::leave-event
* @captured_event: signal class closure for #ClutterActor::captured-event
* @key_focus_in: signal class closure for #ClutterActor::key-focus-in
* @key_focus_out: signal class closure for #ClutterActor::key-focus-out
* @queue_relayout: class handler for #ClutterActor::queue-relayout
* @get_accessible: virtual function, returns the accessible object that
* describes the actor to an assistive technology.
* @get_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 #ClutterActor::touch-event
*
* Base class for actors.
*/
struct _ClutterActorClass
{
/*< private >*/
GInitiallyUnownedClass parent_class;
/*< public >*/
void (* show) (ClutterActor *self);
void (* show_all) (ClutterActor *self);
void (* hide) (ClutterActor *self);
void (* hide_all) (ClutterActor *self);
void (* realize) (ClutterActor *self);
void (* unrealize) (ClutterActor *self);
void (* map) (ClutterActor *self);
void (* unmap) (ClutterActor *self);
void (* paint) (ClutterActor *self);
void (* parent_set) (ClutterActor *actor,
ClutterActor *old_parent);
void (* destroy) (ClutterActor *self);
void (* pick) (ClutterActor *actor,
const ClutterColor *color);
void (* queue_redraw) (ClutterActor *actor,
ClutterActor *leaf_that_queued);
/* 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,
ClutterAllocationFlags flags);
/* transformations */
void (* apply_transform) (ClutterActor *actor,
ClutterMatrix *matrix);
/* event signals */
gboolean (* event) (ClutterActor *actor,
ClutterEvent *event);
gboolean (* button_press_event) (ClutterActor *actor,
ClutterButtonEvent *event);
gboolean (* button_release_event) (ClutterActor *actor,
ClutterButtonEvent *event);
gboolean (* scroll_event) (ClutterActor *actor,
ClutterScrollEvent *event);
gboolean (* key_press_event) (ClutterActor *actor,
ClutterKeyEvent *event);
gboolean (* key_release_event) (ClutterActor *actor,
ClutterKeyEvent *event);
gboolean (* motion_event) (ClutterActor *actor,
ClutterMotionEvent *event);
gboolean (* enter_event) (ClutterActor *actor,
ClutterCrossingEvent *event);
gboolean (* leave_event) (ClutterActor *actor,
ClutterCrossingEvent *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,
ClutterTouchEvent *event);
/*< private >*/
/* padding for future expansion */
gpointer _padding_dummy[26];
};
/**
* 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.
*
* Since: 1.10
*/
struct _ClutterActorIter
{
/*< private >*/
gpointer CLUTTER_PRIVATE_FIELD (dummy1);
gpointer CLUTTER_PRIVATE_FIELD (dummy2);
gpointer CLUTTER_PRIVATE_FIELD (dummy3);
gint CLUTTER_PRIVATE_FIELD (dummy4);
gpointer CLUTTER_PRIVATE_FIELD (dummy5);
};
CLUTTER_AVAILABLE_IN_ALL
GType clutter_actor_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_10
ClutterActor * clutter_actor_new (void);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_flags (ClutterActor *self,
ClutterActorFlags flags);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_unset_flags (ClutterActor *self,
ClutterActorFlags flags);
CLUTTER_AVAILABLE_IN_ALL
ClutterActorFlags clutter_actor_get_flags (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_show (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_hide (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_realize (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_unrealize (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_map (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_unmap (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_paint (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_continue_paint (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_queue_redraw (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_queue_redraw_with_clip (ClutterActor *self,
const cairo_rectangle_int_t *clip);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_queue_relayout (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_destroy (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_name (ClutterActor *self,
const gchar *name);
CLUTTER_AVAILABLE_IN_ALL
const gchar * clutter_actor_get_name (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
AtkObject * clutter_actor_get_accessible (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_24
gboolean clutter_actor_is_visible (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_24
gboolean clutter_actor_is_mapped (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_24
gboolean clutter_actor_is_realized (ClutterActor *self);
/* Size negotiation */
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_request_mode (ClutterActor *self,
ClutterRequestMode mode);
CLUTTER_AVAILABLE_IN_ALL
ClutterRequestMode clutter_actor_get_request_mode (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_preferred_width (ClutterActor *self,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_preferred_height (ClutterActor *self,
gfloat for_width,
gfloat *min_height_p,
gfloat *natural_height_p);
CLUTTER_AVAILABLE_IN_ALL
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_AVAILABLE_IN_ALL
void clutter_actor_allocate (ClutterActor *self,
const ClutterActorBox *box,
ClutterAllocationFlags flags);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_allocate_preferred_size (ClutterActor *self,
ClutterAllocationFlags flags);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_allocate_available_size (ClutterActor *self,
gfloat x,
gfloat y,
gfloat available_width,
gfloat available_height,
ClutterAllocationFlags flags);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_allocate_align_fill (ClutterActor *self,
const ClutterActorBox *box,
gdouble x_align,
gdouble y_align,
gboolean x_fill,
gboolean y_fill,
ClutterAllocationFlags flags);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_allocation (ClutterActor *self,
const ClutterActorBox *box,
ClutterAllocationFlags flags);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_allocation_box (ClutterActor *self,
ClutterActorBox *box);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_allocation_vertices (ClutterActor *self,
ClutterActor *ancestor,
ClutterVertex verts[]);
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_has_allocation (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_size (ClutterActor *self,
gfloat width,
gfloat height);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_size (ClutterActor *self,
gfloat *width,
gfloat *height);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_position (ClutterActor *self,
gfloat x,
gfloat y);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_position (ClutterActor *self,
gfloat *x,
gfloat *y);
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_get_fixed_position_set (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_fixed_position_set (ClutterActor *self,
gboolean is_set);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_move_by (ClutterActor *self,
gfloat dx,
gfloat dy);
/* Actor geometry */
CLUTTER_AVAILABLE_IN_ALL
gfloat clutter_actor_get_width (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
gfloat clutter_actor_get_height (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_width (ClutterActor *self,
gfloat width);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_height (ClutterActor *self,
gfloat height);
CLUTTER_AVAILABLE_IN_ALL
gfloat clutter_actor_get_x (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
gfloat clutter_actor_get_y (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_x (ClutterActor *self,
gfloat x);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_y (ClutterActor *self,
gfloat y);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_z_position (ClutterActor *self,
gfloat z_position);
CLUTTER_AVAILABLE_IN_1_12
gfloat clutter_actor_get_z_position (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_layout_manager (ClutterActor *self,
ClutterLayoutManager *manager);
CLUTTER_AVAILABLE_IN_1_10
ClutterLayoutManager * clutter_actor_get_layout_manager (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_x_align (ClutterActor *self,
ClutterActorAlign x_align);
CLUTTER_AVAILABLE_IN_1_10
ClutterActorAlign clutter_actor_get_x_align (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_y_align (ClutterActor *self,
ClutterActorAlign y_align);
CLUTTER_AVAILABLE_IN_1_10
ClutterActorAlign clutter_actor_get_y_align (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_margin_top (ClutterActor *self,
gfloat margin);
CLUTTER_AVAILABLE_IN_1_10
gfloat clutter_actor_get_margin_top (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_margin_bottom (ClutterActor *self,
gfloat margin);
CLUTTER_AVAILABLE_IN_1_10
gfloat clutter_actor_get_margin_bottom (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_margin_left (ClutterActor *self,
gfloat margin);
CLUTTER_AVAILABLE_IN_1_10
gfloat clutter_actor_get_margin_left (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_margin_right (ClutterActor *self,
gfloat margin);
CLUTTER_AVAILABLE_IN_1_10
gfloat clutter_actor_get_margin_right (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_margin (ClutterActor *self,
const ClutterMargin *margin);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_get_margin (ClutterActor *self,
ClutterMargin *margin);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_x_expand (ClutterActor *self,
gboolean expand);
CLUTTER_AVAILABLE_IN_1_12
gboolean clutter_actor_get_x_expand (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_y_expand (ClutterActor *self,
gboolean expand);
CLUTTER_AVAILABLE_IN_1_12
gboolean clutter_actor_get_y_expand (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_12
gboolean clutter_actor_needs_expand (ClutterActor *self,
ClutterOrientation orientation);
/* Paint */
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_clip (ClutterActor *self,
gfloat xoff,
gfloat yoff,
gfloat width,
gfloat height);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_remove_clip (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_has_clip (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_clip (ClutterActor *self,
gfloat *xoff,
gfloat *yoff,
gfloat *width,
gfloat *height);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_clip_to_allocation (ClutterActor *self,
gboolean clip_set);
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_get_clip_to_allocation (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_opacity (ClutterActor *self,
guint8 opacity);
CLUTTER_AVAILABLE_IN_ALL
guint8 clutter_actor_get_opacity (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
guint8 clutter_actor_get_paint_opacity (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_get_paint_visibility (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_8
void clutter_actor_set_offscreen_redirect (ClutterActor *self,
ClutterOffscreenRedirect redirect);
CLUTTER_AVAILABLE_IN_1_8
ClutterOffscreenRedirect clutter_actor_get_offscreen_redirect (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_should_pick_paint (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_is_in_clone_paint (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_get_paint_box (ClutterActor *self,
ClutterActorBox *box);
CLUTTER_AVAILABLE_IN_1_8
gboolean clutter_actor_has_overlaps (ClutterActor *self);
/* Content */
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_content (ClutterActor *self,
ClutterContent *content);
CLUTTER_AVAILABLE_IN_1_10
ClutterContent * clutter_actor_get_content (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_content_gravity (ClutterActor *self,
ClutterContentGravity gravity);
CLUTTER_AVAILABLE_IN_1_10
ClutterContentGravity clutter_actor_get_content_gravity (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_content_scaling_filters (ClutterActor *self,
ClutterScalingFilter min_filter,
ClutterScalingFilter mag_filter);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_get_content_scaling_filters (ClutterActor *self,
ClutterScalingFilter *min_filter,
ClutterScalingFilter *mag_filter);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_content_repeat (ClutterActor *self,
ClutterContentRepeat repeat);
CLUTTER_AVAILABLE_IN_1_12
ClutterContentRepeat clutter_actor_get_content_repeat (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_get_content_box (ClutterActor *self,
ClutterActorBox *box);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_background_color (ClutterActor *self,
const ClutterColor *color);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_get_background_color (ClutterActor *self,
ClutterColor *color);
CLUTTER_AVAILABLE_IN_1_6
const ClutterPaintVolume * clutter_actor_get_paint_volume (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_6
const ClutterPaintVolume * clutter_actor_get_transformed_paint_volume (ClutterActor *self,
ClutterActor *relative_to_ancestor);
CLUTTER_AVAILABLE_IN_1_10
const ClutterPaintVolume * clutter_actor_get_default_paint_volume (ClutterActor *self);
/* Events */
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_reactive (ClutterActor *actor,
gboolean reactive);
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_get_reactive (ClutterActor *actor);
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_has_key_focus (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_grab_key_focus (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_event (ClutterActor *actor,
const ClutterEvent *event,
gboolean capture);
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_has_pointer (ClutterActor *self);
/* Text */
CLUTTER_AVAILABLE_IN_ALL
PangoContext * clutter_actor_get_pango_context (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
PangoContext * clutter_actor_create_pango_context (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
PangoLayout * clutter_actor_create_pango_layout (ClutterActor *self,
const gchar *text);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_text_direction (ClutterActor *self,
ClutterTextDirection text_dir);
CLUTTER_AVAILABLE_IN_ALL
ClutterTextDirection clutter_actor_get_text_direction (ClutterActor *self);
/* Actor hierarchy */
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_add_child (ClutterActor *self,
ClutterActor *child);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_insert_child_at_index (ClutterActor *self,
ClutterActor *child,
gint index_);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_insert_child_above (ClutterActor *self,
ClutterActor *child,
ClutterActor *sibling);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_insert_child_below (ClutterActor *self,
ClutterActor *child,
ClutterActor *sibling);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_replace_child (ClutterActor *self,
ClutterActor *old_child,
ClutterActor *new_child);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_remove_child (ClutterActor *self,
ClutterActor *child);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_remove_all_children (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_destroy_all_children (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
GList * clutter_actor_get_children (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
gint clutter_actor_get_n_children (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
ClutterActor * clutter_actor_get_child_at_index (ClutterActor *self,
gint index_);
CLUTTER_AVAILABLE_IN_1_10
ClutterActor * clutter_actor_get_previous_sibling (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
ClutterActor * clutter_actor_get_next_sibling (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
ClutterActor * clutter_actor_get_first_child (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
ClutterActor * clutter_actor_get_last_child (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
ClutterActor * clutter_actor_get_parent (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_4
gboolean clutter_actor_contains (ClutterActor *self,
ClutterActor *descendant);
CLUTTER_AVAILABLE_IN_ALL
ClutterActor* clutter_actor_get_stage (ClutterActor *actor);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_child_below_sibling (ClutterActor *self,
ClutterActor *child,
ClutterActor *sibling);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_child_above_sibling (ClutterActor *self,
ClutterActor *child,
ClutterActor *sibling);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_child_at_index (ClutterActor *self,
ClutterActor *child,
gint index_);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_iter_init (ClutterActorIter *iter,
ClutterActor *root);
CLUTTER_AVAILABLE_IN_1_10
gboolean clutter_actor_iter_next (ClutterActorIter *iter,
ClutterActor **child);
CLUTTER_AVAILABLE_IN_1_10
gboolean clutter_actor_iter_prev (ClutterActorIter *iter,
ClutterActor **child);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_iter_remove (ClutterActorIter *iter);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_iter_destroy (ClutterActorIter *iter);
CLUTTER_AVAILABLE_IN_1_12
gboolean clutter_actor_iter_is_valid (const ClutterActorIter *iter);
/* Transformations */
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_is_rotated (ClutterActor *self);
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_is_scaled (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_pivot_point (ClutterActor *self,
gfloat pivot_x,
gfloat pivot_y);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_get_pivot_point (ClutterActor *self,
gfloat *pivot_x,
gfloat *pivot_y);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_pivot_point_z (ClutterActor *self,
gfloat pivot_z);
CLUTTER_AVAILABLE_IN_1_12
gfloat clutter_actor_get_pivot_point_z (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_rotation_angle (ClutterActor *self,
ClutterRotateAxis axis,
gdouble angle);
CLUTTER_AVAILABLE_IN_1_12
gdouble clutter_actor_get_rotation_angle (ClutterActor *self,
ClutterRotateAxis axis);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_set_scale (ClutterActor *self,
gdouble scale_x,
gdouble scale_y);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_scale (ClutterActor *self,
gdouble *scale_x,
gdouble *scale_y);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_scale_z (ClutterActor *self,
gdouble scale_z);
CLUTTER_AVAILABLE_IN_1_12
gdouble clutter_actor_get_scale_z (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_translation (ClutterActor *self,
gfloat translate_x,
gfloat translate_y,
gfloat translate_z);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_get_translation (ClutterActor *self,
gfloat *translate_x,
gfloat *translate_y,
gfloat *translate_z);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_transform (ClutterActor *self,
const ClutterMatrix *transform);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_get_transform (ClutterActor *self,
ClutterMatrix *transform);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_child_transform (ClutterActor *self,
const ClutterMatrix *transform);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_get_child_transform (ClutterActor *self,
ClutterMatrix *transform);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_transformed_position (ClutterActor *self,
gfloat *x,
gfloat *y);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_transformed_size (ClutterActor *self,
gfloat *width,
gfloat *height);
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_actor_transform_stage_point (ClutterActor *self,
gfloat x,
gfloat y,
gfloat *x_out,
gfloat *y_out);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_get_abs_allocation_vertices (ClutterActor *self,
ClutterVertex verts[]);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_apply_transform_to_point (ClutterActor *self,
const ClutterVertex *point,
ClutterVertex *vertex);
CLUTTER_AVAILABLE_IN_ALL
void clutter_actor_apply_relative_transform_to_point (ClutterActor *self,
ClutterActor *ancestor,
const ClutterVertex *point,
ClutterVertex *vertex);
/* Implicit animations */
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_save_easing_state (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_restore_easing_state (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_easing_mode (ClutterActor *self,
ClutterAnimationMode mode);
CLUTTER_AVAILABLE_IN_1_10
ClutterAnimationMode clutter_actor_get_easing_mode (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_easing_duration (ClutterActor *self,
guint msecs);
CLUTTER_AVAILABLE_IN_1_10
guint clutter_actor_get_easing_duration (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_set_easing_delay (ClutterActor *self,
guint msecs);
CLUTTER_AVAILABLE_IN_1_10
guint clutter_actor_get_easing_delay (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
ClutterTransition * clutter_actor_get_transition (ClutterActor *self,
const char *name);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_add_transition (ClutterActor *self,
const char *name,
ClutterTransition *transition);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_remove_transition (ClutterActor *self,
const char *name);
CLUTTER_AVAILABLE_IN_1_10
void clutter_actor_remove_all_transitions (ClutterActor *self);
/* Experimental API */
#ifdef CLUTTER_ENABLE_EXPERIMENTAL_API
CLUTTER_AVAILABLE_IN_1_16
gboolean clutter_actor_has_mapped_clones (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_22
void clutter_actor_set_opacity_override (ClutterActor *self,
gint opacity);
CLUTTER_AVAILABLE_IN_1_22
gint clutter_actor_get_opacity_override (ClutterActor *self);
#endif
/**
* 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 #ClutterActor
*
* Since: 1.24
*/
typedef ClutterActor * (* ClutterActorCreateChildFunc) (gpointer item,
gpointer user_data);
CLUTTER_AVAILABLE_IN_1_24
void clutter_actor_bind_model (ClutterActor *self,
GListModel *model,
ClutterActorCreateChildFunc create_child_func,
gpointer user_data,
GDestroyNotify notify);
CLUTTER_AVAILABLE_IN_1_24
void clutter_actor_bind_model_with_properties (ClutterActor *self,
GListModel *model,
GType child_type,
const char *first_model_property,
...);
G_END_DECLS
#endif /* __CLUTTER_ACTOR_H__ */

View File

@ -0,0 +1,542 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-align-constraint
* @Title: ClutterAlignConstraint
* @Short_Description: A constraint aligning the position of an actor
*
* #ClutterAlignConstraint is a #ClutterConstraint that aligns the position
* of the #ClutterActor to which it is applied to the size of another
* #ClutterActor using an alignment factor
*
* #ClutterAlignConstraint is available since Clutter 1.4
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-align-constraint.h"
#include "clutter-actor-meta-private.h"
#include "clutter-actor-private.h"
#include "clutter-constraint.h"
#include "clutter-debug.h"
#include "clutter-enum-types.h"
#include "clutter-private.h"
#include <math.h>
#define CLUTTER_ALIGN_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ALIGN_CONSTRAINT, ClutterAlignConstraintClass))
#define CLUTTER_IS_ALIGN_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ALIGN_CONSTRAINT))
#define CLUTTER_ALIGN_CONSTRAINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ALIGN_CONSTRAINT, ClutterAlignConstraintClass))
struct _ClutterAlignConstraint
{
ClutterConstraint parent_instance;
ClutterActor *actor;
ClutterActor *source;
ClutterAlignAxis align_axis;
gfloat factor;
};
struct _ClutterAlignConstraintClass
{
ClutterConstraintClass parent_class;
};
enum
{
PROP_0,
PROP_SOURCE,
PROP_ALIGN_AXIS,
PROP_FACTOR,
PROP_LAST
};
static GParamSpec *obj_props[PROP_LAST];
G_DEFINE_TYPE (ClutterAlignConstraint,
clutter_align_constraint,
CLUTTER_TYPE_CONSTRAINT);
static void
source_position_changed (ClutterActor *actor,
const ClutterActorBox *allocation,
ClutterAllocationFlags flags,
ClutterAlignConstraint *align)
{
if (align->actor != NULL)
clutter_actor_queue_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 source_x, source_y;
if (align->source == NULL)
return;
clutter_actor_box_get_size (allocation, &actor_width, &actor_height);
clutter_actor_get_position (align->source, &source_x, &source_y);
clutter_actor_get_size (align->source, &source_width, &source_height);
switch (align->align_axis)
{
case CLUTTER_ALIGN_X_AXIS:
allocation->x1 = ((source_width - actor_width) * align->factor)
+ source_x;
allocation->x2 = allocation->x1 + actor_width;
break;
case CLUTTER_ALIGN_Y_AXIS:
allocation->y1 = ((source_height - actor_height) * align->factor)
+ source_y;
allocation->y2 = allocation->y1 + actor_height;
break;
case CLUTTER_ALIGN_BOTH:
allocation->x1 = ((source_width - actor_width) * align->factor)
+ source_x;
allocation->y1 = ((source_height - actor_height) * align->factor)
+ source_y;
allocation->x2 = allocation->x1 + actor_width;
allocation->y2 = allocation->y1 + actor_height;
break;
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_position_changed),
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_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_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.
*
* Since: 1.4
*/
obj_props[PROP_SOURCE] =
g_param_spec_object ("source",
P_("Source"),
P_("The source of the alignment"),
CLUTTER_TYPE_ACTOR,
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT);
/**
* ClutterAlignConstraint:align-axis:
*
* The axis to be used to compute the alignment
*
* Since: 1.4
*/
obj_props[PROP_ALIGN_AXIS] =
g_param_spec_enum ("align-axis",
P_("Align Axis"),
P_("The axis to align the position to"),
CLUTTER_TYPE_ALIGN_AXIS,
CLUTTER_ALIGN_X_AXIS,
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT);
/**
* 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.
*
* Since: 1.4
*/
obj_props[PROP_FACTOR] =
g_param_spec_float ("factor",
P_("Factor"),
P_("The alignment factor, between 0.0 and 1.0"),
0.0, 1.0,
0.0,
CLUTTER_PARAM_READWRITE | 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->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
*
* Since: 1.4
*/
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
*
* Since: 1.4
*/
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_position_changed),
align);
}
align->source = source;
if (align->source != NULL)
{
g_signal_connect (align->source, "allocation-changed",
G_CALLBACK (source_position_changed),
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
*
* Since: 1.4
*/
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
*
* Since: 1.4
*/
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 clutter_align_constraint_set_align_axis()
*
* Return value: the alignment axis
*
* Since: 1.4
*/
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_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
*
* Since: 1.4
*/
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 clutter_align_constraint_set_factor()
*
* Return value: the alignment factor
*
* Since: 1.4
*/
gfloat
clutter_align_constraint_get_factor (ClutterAlignConstraint *align)
{
g_return_val_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align), 0.0);
return align->factor;
}

View File

@ -0,0 +1,77 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_ALIGN_CONSTRAINT_H__
#define __CLUTTER_ALIGN_CONSTRAINT_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-constraint.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_ALIGN_CONSTRAINT (clutter_align_constraint_get_type ())
#define CLUTTER_ALIGN_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ALIGN_CONSTRAINT, ClutterAlignConstraint))
#define CLUTTER_IS_ALIGN_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ALIGN_CONSTRAINT))
/**
* ClutterAlignConstraint:
*
* #ClutterAlignConstraint is an opaque structure
* whose members cannot be directly accesses
*
* Since: 1.4
*/
typedef struct _ClutterAlignConstraint ClutterAlignConstraint;
typedef struct _ClutterAlignConstraintClass ClutterAlignConstraintClass;
CLUTTER_AVAILABLE_IN_1_4
GType clutter_align_constraint_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_4
ClutterConstraint *clutter_align_constraint_new (ClutterActor *source,
ClutterAlignAxis axis,
gfloat factor);
CLUTTER_AVAILABLE_IN_1_4
void clutter_align_constraint_set_source (ClutterAlignConstraint *align,
ClutterActor *source);
CLUTTER_AVAILABLE_IN_1_4
ClutterActor * clutter_align_constraint_get_source (ClutterAlignConstraint *align);
CLUTTER_AVAILABLE_IN_1_4
void clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align,
ClutterAlignAxis axis);
CLUTTER_AVAILABLE_IN_1_4
ClutterAlignAxis clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align);
CLUTTER_AVAILABLE_IN_1_4
void clutter_align_constraint_set_factor (ClutterAlignConstraint *align,
gfloat factor);
CLUTTER_AVAILABLE_IN_1_4
gfloat clutter_align_constraint_get_factor (ClutterAlignConstraint *align);
G_END_DECLS
#endif /* __CLUTTER_ALIGN_CONSTRAINT_H__ */

View File

@ -0,0 +1,286 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2009 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-animatable
* @short_description: Interface for animatable classes
*
* #ClutterAnimatable is an interface that allows a #GObject class
* to control how a #ClutterAnimation will animate a property.
*
* Each #ClutterAnimatable should implement the
* #ClutterAnimatableIface.interpolate_property() virtual function of the
* interface to compute the animation state between two values of an interval
* depending on a progress factor, expressed as a floating point value.
*
* If a #ClutterAnimatable is animated by a #ClutterAnimation
* instance, the #ClutterAnimation will call
* clutter_animatable_interpolate_property() passing the name of the
* currently animated property; the values interval; and the progress factor.
* The #ClutterAnimatable implementation should return the computed value for
* the animated
* property.
*
* #ClutterAnimatable is available since Clutter 1.0
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
#include "clutter-animatable.h"
#include "clutter-interval.h"
#include "clutter-debug.h"
#include "clutter-private.h"
#include "deprecated/clutter-animatable.h"
#include "deprecated/clutter-animation.h"
typedef ClutterAnimatableIface ClutterAnimatableInterface;
G_DEFINE_INTERFACE (ClutterAnimatable, clutter_animatable, G_TYPE_OBJECT);
static void
clutter_animatable_default_init (ClutterAnimatableInterface *iface)
{
}
/**
* clutter_animatable_animate_property:
* @animatable: a #ClutterAnimatable
* @animation: a #ClutterAnimation
* @property_name: the name of the animated property
* @initial_value: the initial value of the animation interval
* @final_value: the final value of the animation interval
* @progress: the progress factor
* @value: return location for the animation value
*
* Calls the animate_property() virtual function for @animatable.
*
* The @initial_value and @final_value #GValue<!-- -->s must contain
* the same type; @value must have been initialized to the same
* type of @initial_value and @final_value.
*
* All implementation of the #ClutterAnimatable interface must
* implement this function.
*
* Return value: %TRUE if the value has been validated and can
* be applied to the #ClutterAnimatable, and %FALSE otherwise
*
* Since: 1.0
*
* Deprecated: 1.8: Use clutter_animatable_interpolate_value()
* instead
*/
gboolean
clutter_animatable_animate_property (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name,
const GValue *initial_value,
const GValue *final_value,
gdouble progress,
GValue *value)
{
ClutterAnimatableIface *iface;
gboolean res;
g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), FALSE);
g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), FALSE);
g_return_val_if_fail (property_name != NULL, FALSE);
g_return_val_if_fail (initial_value != NULL && final_value != NULL, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (initial_value) != G_TYPE_INVALID, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (final_value) != G_TYPE_INVALID, FALSE);
g_return_val_if_fail (value != NULL, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (value) == G_VALUE_TYPE (initial_value) &&
G_VALUE_TYPE (value) == G_VALUE_TYPE (final_value),
FALSE);
iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable);
if (iface->animate_property == NULL)
{
ClutterInterval *interval;
interval = clutter_animation_get_interval (animation, property_name);
if (interval == NULL)
return FALSE;
res = clutter_animatable_interpolate_value (animatable, property_name,
interval,
progress,
value);
}
else
res = iface->animate_property (animatable, animation,
property_name,
initial_value, final_value,
progress,
value);
return res;
}
/**
* clutter_animatable_find_property:
* @animatable: a #ClutterAnimatable
* @property_name: the name of the animatable property to find
*
* Finds the #GParamSpec for @property_name
*
* Return value: (transfer none): The #GParamSpec for the given property
* or %NULL
*
* Since: 1.4
*/
GParamSpec *
clutter_animatable_find_property (ClutterAnimatable *animatable,
const gchar *property_name)
{
ClutterAnimatableIface *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
*
* Since: 1.4
*/
void
clutter_animatable_get_initial_state (ClutterAnimatable *animatable,
const gchar *property_name,
GValue *value)
{
ClutterAnimatableIface *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
*
* Since: 1.4
*/
void
clutter_animatable_set_final_state (ClutterAnimatable *animatable,
const gchar *property_name,
const GValue *value)
{
ClutterAnimatableIface *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.
*
* This function replaces clutter_animatable_animate_property().
*
* Return value: %TRUE if the interpolation was successful,
* and %FALSE otherwise
*
* Since: 1.8
*/
gboolean
clutter_animatable_interpolate_value (ClutterAnimatable *animatable,
const gchar *property_name,
ClutterInterval *interval,
gdouble progress,
GValue *value)
{
ClutterAnimatableIface *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);
}

View File

@ -0,0 +1,121 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2009 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_ANIMATABLE_H__
#define __CLUTTER_ANIMATABLE_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-types.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_ANIMATABLE (clutter_animatable_get_type ())
#define CLUTTER_ANIMATABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ANIMATABLE, ClutterAnimatable))
#define CLUTTER_IS_ANIMATABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ANIMATABLE))
#define CLUTTER_ANIMATABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_ANIMATABLE, ClutterAnimatableIface))
typedef struct _ClutterAnimatableIface ClutterAnimatableIface;
/**
* ClutterAnimatable:
*
* #ClutterAnimatable is an opaque structure whose members cannot be directly
* accessed
*
* Since: 1.0
*/
/**
* ClutterAnimatableIface:
* @animate_property: virtual function for custom interpolation of a
* property. This virtual function is deprecated
* @find_property: virtual function for retrieving the #GParamSpec of
* an animatable property
* @get_initial_state: virtual function for retrieving the initial
* 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
*
* Base interface for #GObject<!-- -->s that can be animated by a
* a #ClutterAnimation.
*
* Since: 1.0
*/
struct _ClutterAnimatableIface
{
/*< private >*/
GTypeInterface parent_iface;
/*< public >*/
gboolean (* animate_property) (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name,
const GValue *initial_value,
const GValue *final_value,
gdouble progress,
GValue *value);
GParamSpec *(* find_property) (ClutterAnimatable *animatable,
const gchar *property_name);
void (* get_initial_state) (ClutterAnimatable *animatable,
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);
};
CLUTTER_AVAILABLE_IN_1_0
GType clutter_animatable_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_0
GParamSpec *clutter_animatable_find_property (ClutterAnimatable *animatable,
const gchar *property_name);
CLUTTER_AVAILABLE_IN_1_0
void clutter_animatable_get_initial_state (ClutterAnimatable *animatable,
const gchar *property_name,
GValue *value);
CLUTTER_AVAILABLE_IN_1_0
void clutter_animatable_set_final_state (ClutterAnimatable *animatable,
const gchar *property_name,
const GValue *value);
CLUTTER_AVAILABLE_IN_1_8
gboolean clutter_animatable_interpolate_value (ClutterAnimatable *animatable,
const gchar *property_name,
ClutterInterval *interval,
gdouble progress,
GValue *value);
G_END_DECLS
#endif /* __CLUTTER_ANIMATABLE_H__ */

View File

@ -0,0 +1,106 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright 2015 Emmanuele Bassi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef __CLUTTER_AUTO_CLEANUPS_H__
#define __CLUTTER_AUTO_CLEANUPS_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __GI_SCANNER__
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActor, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorMeta, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAlignConstraint, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAnimatable, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackend, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBindConstraint, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBindingPool, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBinLayout, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBlurEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBoxLayout, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBrightnessContrastEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterCanvas, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterChildMeta, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClickAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClone, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColorizeEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterConstraint, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterContainer, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterContent, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDeformEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDesaturateEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDeviceManager, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDragAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDropAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFixedLayout, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFlowLayout, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterGestureAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterGridLayout, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterImage, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterInputDevice, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterInterval, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterKeyframeTransition, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterLayoutManager, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterLayoutMeta, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterOffscreenEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPageTurnEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPanAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPathConstraint, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPath, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPropertyTransition, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterRotateAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterScriptable, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterScript, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterScrollActor, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterSettings, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterShaderEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterSnapConstraint, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterStage, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterSwipeAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterTapAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterTextBuffer, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterText, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterTimeline, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterTransitionGroup, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterTransition, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterZoomAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorBox, clutter_actor_box_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColor, clutter_color_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMargin, clutter_margin_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMatrix, clutter_matrix_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintNode, clutter_paint_node_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintVolume, clutter_paint_volume_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPathNode, clutter_path_node_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPoint, clutter_point_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterRect, clutter_rect_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterSize, clutter_size_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterVertex, clutter_vertex_free)
#endif /* __GI_SCANNER__ */
#endif /* __CLUTTER_AUTO_CLEANUPS_H__ */

View File

@ -0,0 +1,162 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CLUTTER_BACKEND_PRIVATE_H__
#define __CLUTTER_BACKEND_PRIVATE_H__
#include <clutter/clutter-backend.h>
#include <clutter/clutter-device-manager.h>
#include <clutter/clutter-stage-window.h>
#include "clutter-event-translator.h"
#define CLUTTER_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BACKEND, ClutterBackendClass))
#define CLUTTER_IS_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BACKEND))
#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;
ClutterDeviceManager *device_manager;
cairo_font_options_t *font_options;
gchar *font_name;
gfloat units_per_em;
gint32 units_serial;
GList *event_translators;
};
struct _ClutterBackendClass
{
/*< private >*/
GObjectClass parent_class;
GType stage_window_type;
/* vfuncs */
gboolean (* pre_parse) (ClutterBackend *backend,
GError **error);
gboolean (* post_parse) (ClutterBackend *backend,
GError **error);
ClutterStageWindow * (* create_stage) (ClutterBackend *backend,
ClutterStage *wrapper,
GError **error);
void (* init_events) (ClutterBackend *backend);
void (* init_features) (ClutterBackend *backend);
void (* add_options) (ClutterBackend *backend,
GOptionGroup *group);
ClutterFeatureFlags (* get_features) (ClutterBackend *backend);
CoglRenderer * (* get_renderer) (ClutterBackend *backend,
GError **error);
CoglDisplay * (* get_display) (ClutterBackend *backend,
CoglRenderer *renderer,
CoglSwapChain *swap_chain,
GError **error);
gboolean (* create_context) (ClutterBackend *backend,
GError **error);
void (* ensure_context) (ClutterBackend *backend,
ClutterStage *stage);
ClutterDeviceManager *(* get_device_manager) (ClutterBackend *backend);
void (* copy_event_data) (ClutterBackend *backend,
const ClutterEvent *src,
ClutterEvent *dest);
void (* free_event_data) (ClutterBackend *backend,
ClutterEvent *event);
gboolean (* translate_event) (ClutterBackend *backend,
gpointer native,
ClutterEvent *event);
PangoDirection (* get_keymap_direction) (ClutterBackend *backend);
/* signals */
void (* resolution_changed) (ClutterBackend *backend);
void (* font_changed) (ClutterBackend *backend);
void (* settings_changed) (ClutterBackend *backend);
};
ClutterBackend * _clutter_create_backend (void);
ClutterStageWindow * _clutter_backend_create_stage (ClutterBackend *backend,
ClutterStage *wrapper,
GError **error);
void _clutter_backend_ensure_context (ClutterBackend *backend,
ClutterStage *stage);
void _clutter_backend_ensure_context_internal (ClutterBackend *backend,
ClutterStage *stage);
gboolean _clutter_backend_create_context (ClutterBackend *backend,
GError **error);
void _clutter_backend_add_options (ClutterBackend *backend,
GOptionGroup *group);
gboolean _clutter_backend_pre_parse (ClutterBackend *backend,
GError **error);
gboolean _clutter_backend_post_parse (ClutterBackend *backend,
GError **error);
void _clutter_backend_init_events (ClutterBackend *backend);
void _clutter_backend_copy_event_data (ClutterBackend *backend,
const ClutterEvent *src,
ClutterEvent *dest);
void _clutter_backend_free_event_data (ClutterBackend *backend,
ClutterEvent *event);
gboolean _clutter_backend_translate_event (ClutterBackend *backend,
gpointer native,
ClutterEvent *event);
void _clutter_backend_add_event_translator (ClutterBackend *backend,
ClutterEventTranslator *translator);
void _clutter_backend_remove_event_translator (ClutterBackend *backend,
ClutterEventTranslator *translator);
ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend);
gfloat _clutter_backend_get_units_per_em (ClutterBackend *backend,
PangoFontDescription *font_desc);
gint32 _clutter_backend_get_units_serial (ClutterBackend *backend);
PangoDirection _clutter_backend_get_keymap_direction (ClutterBackend *backend);
void _clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend);
void clutter_set_allowed_drivers (const char *drivers);
void clutter_try_set_windowing_backend (const char *drivers);
G_END_DECLS
#endif /* __CLUTTER_BACKEND_PRIVATE_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,83 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
*
* Copyright (C) 2006 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CLUTTER_BACKEND_H__
#define __CLUTTER_BACKEND_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <cairo.h>
#include <pango/pango.h>
#ifdef COGL_ENABLE_EXPERIMENTAL_API
#include <cogl/cogl.h>
#endif
#include <clutter/clutter-config.h>
#include <clutter/clutter-types.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))
/**
* ClutterBackend:
*
* #ClutterBackend is an opaque structure whose
* members cannot be directly accessed.
*
* Since: 0.4
*/
typedef struct _ClutterBackend ClutterBackend;
typedef struct _ClutterBackendClass ClutterBackendClass;
CLUTTER_AVAILABLE_IN_ALL
GType clutter_backend_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_ALL
ClutterBackend * clutter_get_default_backend (void);
CLUTTER_AVAILABLE_IN_1_16
void clutter_set_windowing_backend (const char *backend_type);
CLUTTER_AVAILABLE_IN_ALL
gdouble clutter_backend_get_resolution (ClutterBackend *backend);
CLUTTER_AVAILABLE_IN_ALL
void clutter_backend_set_font_options (ClutterBackend *backend,
const cairo_font_options_t *options);
CLUTTER_AVAILABLE_IN_ALL
const cairo_font_options_t * clutter_backend_get_font_options (ClutterBackend *backend);
#if defined (COGL_ENABLE_EXPERIMENTAL_API) && defined (CLUTTER_ENABLE_EXPERIMENTAL_API)
CLUTTER_AVAILABLE_IN_1_8
CoglContext * clutter_backend_get_cogl_context (ClutterBackend *backend);
#endif
G_END_DECLS
#endif /* __CLUTTER_BACKEND_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,424 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Tomas Frydrych <tf@openedhand.com>
*
* Copyright (C) 2007 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <glib.h>
#include <string.h>
#include "clutter-bezier.h"
#include "clutter-debug.h"
/*
* We have some experimental code here to allow for constant velocity
* movement of actors along the bezier path, this macro enables it.
*/
#undef CBZ_L2T_INTERPOLATION
/****************************************************************************
* ClutterBezier -- represenation of a cubic bezier curve *
* (private; a building block for the public bspline object) *
****************************************************************************/
/*
* The t parameter of the bezier is from interval <0,1>, so we can use
* 14.18 format and special multiplication functions that preserve
* more of the least significant bits but would overflow if the value
* is > 1
*/
#define CBZ_T_Q 18
#define CBZ_T_ONE (1 << CBZ_T_Q)
#define CBZ_T_MUL(x,y) ((((x) >> 3) * ((y) >> 3)) >> 12)
#define CBZ_T_POW2(x) CBZ_T_MUL (x, x)
#define CBZ_T_POW3(x) CBZ_T_MUL (CBZ_T_POW2 (x), x)
#define CBZ_T_DIV(x,y) ((((x) << 9)/(y)) << 9)
/*
* Constants for sampling of the bezier
*/
#define CBZ_T_SAMPLES 128
#define CBZ_T_STEP (CBZ_T_ONE / CBZ_T_SAMPLES)
#define CBZ_L_STEP (CBZ_T_ONE / CBZ_T_SAMPLES)
typedef gint32 _FixedT;
/*
* This is a private type representing a single cubic bezier
*/
struct _ClutterBezier
{
/*
* bezier coefficients -- these are calculated using multiplication and
* addition from integer input, so these are also integers
*/
gint ax;
gint bx;
gint cx;
gint dx;
gint ay;
gint by;
gint cy;
gint dy;
/* length of the bezier */
guint length;
#ifdef CBZ_L2T_INTERPOLATION
/*
* coefficients for the L -> t bezier; these are calculated from fixed
* point input, and more specifically numbers that have been normalised
* to fit <0,1>, so these are also fixed point, and we can used the
* _FixedT type here.
*/
_FixedT La;
_FixedT Lb;
_FixedT Lc;
/* _FixedT Ld; == 0 */
#endif
};
ClutterBezier *
_clutter_bezier_new (void)
{
return g_slice_new0 (ClutterBezier);
}
void
_clutter_bezier_free (ClutterBezier * b)
{
if (G_LIKELY (b))
{
g_slice_free (ClutterBezier, b);
}
}
ClutterBezier *
_clutter_bezier_clone_and_move (const ClutterBezier *b, gint x, gint y)
{
ClutterBezier * b2 = _clutter_bezier_new ();
memcpy (b2, b, sizeof (ClutterBezier));
b2->dx += x;
b2->dy += y;
return b2;
}
#ifdef CBZ_L2T_INTERPOLATION
/*
* L is relative advance along the bezier curve from interval <0,1>
*/
static _FixedT
_clutter_bezier_L2t (const ClutterBezier *b, _FixedT L)
{
_FixedT t = CBZ_T_MUL (b->La, CBZ_T_POW3(L))
+ CBZ_T_MUL (b->Lb, CBZ_T_POW2(L))
+ CBZ_T_MUL (b->Lc, L);
if (t > CBZ_T_ONE)
t = CBZ_T_ONE;
else if (t < 0)
t = 0;
return t;
}
#endif
static gint
_clutter_bezier_t2x (const ClutterBezier * b, _FixedT t)
{
/*
* NB -- the int coefficients can be at most 8192 for the multiplication
* to work in this fashion due to the limits of the 14.18 fixed.
*/
return ((b->ax*CBZ_T_POW3(t) + b->bx*CBZ_T_POW2(t) + b->cx*t) >> CBZ_T_Q)
+ b->dx;
}
static gint
_clutter_bezier_t2y (const ClutterBezier * b, _FixedT t)
{
/*
* NB -- the int coefficients can be at most 8192 for the multiplication
* to work in this fashion due to the limits of the 14.18 fixed.
*/
return ((b->ay*CBZ_T_POW3(t) + b->by*CBZ_T_POW2(t) + b->cy*t) >> CBZ_T_Q)
+ b->dy;
}
/*
* Advances along the bezier to relative length L and returns the coordinances
* in knot
*/
void
_clutter_bezier_advance (const ClutterBezier *b, gint L, ClutterKnot * knot)
{
#ifdef CBZ_L2T_INTERPOLATION
_FixedT t = clutter_bezier_L2t (b, L);
#else
_FixedT t = L;
#endif
knot->x = _clutter_bezier_t2x (b, t);
knot->y = _clutter_bezier_t2y (b, t);
CLUTTER_NOTE (MISC, "advancing to relative pt %f: t %f, {%d,%d}",
(double) L / (double) CBZ_T_ONE,
(double) t / (double) CBZ_T_ONE,
knot->x, knot->y);
}
void
_clutter_bezier_init (ClutterBezier *b,
gint x_0, gint y_0,
gint x_1, gint y_1,
gint x_2, gint y_2,
gint x_3, gint y_3)
{
_FixedT t;
int i;
int xp = x_0;
int yp = y_0;
_FixedT length [CBZ_T_SAMPLES + 1];
#ifdef CBZ_L2T_INTERPOLATION
int j, k;
_FixedT L;
_FixedT t_equalized [CBZ_T_SAMPLES + 1];
#endif
#if 0
g_debug ("Initializing bezier at {{%d,%d},{%d,%d},{%d,%d},{%d,%d}}",
x0, y0, x1, y1, x2, y2, x3, y3);
#endif
b->dx = x_0;
b->dy = y_0;
b->cx = 3 * (x_1 - x_0);
b->cy = 3 * (y_1 - y_0);
b->bx = 3 * (x_2 - x_1) - b->cx;
b->by = 3 * (y_2 - y_1) - b->cy;
b->ax = x_3 - 3 * x_2 + 3 * x_1 - x_0;
b->ay = y_3 - 3 * y_2 + 3 * y_1 - y_0;
#if 0
g_debug ("Cooeficients {{%d,%d},{%d,%d},{%d,%d},{%d,%d}}",
b->ax, b->ay, b->bx, b->by, b->cx, b->cy, b->dx, b->dy);
#endif
/*
* Because of the way we do the multiplication in bezeir_t2x,y
* these coefficients need to be at most 0x1fff; this should be the case,
* I think, but have added this warning to catch any problems -- if it
* triggers, we need to change those two functions a bit.
*/
if (b->ax > 0x1fff || b->bx > 0x1fff || b->cx > 0x1fff)
g_warning ("Calculated coefficents will result in multiplication "
"overflow in clutter_bezier_t2x and clutter_bezier_t2y.");
/*
* Sample the bezier with CBZ_T_SAMPLES and calculate length at
* each point.
*
* We are working with integers here, so we use the fast sqrti function.
*/
length[0] = 0;
for (t = CBZ_T_STEP, i = 1; i <= CBZ_T_SAMPLES; ++i, t += CBZ_T_STEP)
{
int x = _clutter_bezier_t2x (b, t);
int y = _clutter_bezier_t2y (b, t);
guint l = cogl_sqrti ((y - yp)*(y - yp) + (x - xp)*(x - xp));
l += length[i-1];
length[i] = l;
xp = x;
yp = y;
}
b->length = length[CBZ_T_SAMPLES];
#if 0
g_debug ("length %d", b->length);
#endif
#ifdef CBZ_L2T_INTERPOLATION
/*
* Now normalize the length values, converting them into _FixedT
*/
for (i = 0; i <= CBZ_T_SAMPLES; ++i)
{
length[i] = (length[i] << CBZ_T_Q) / b->length;
}
/*
* Now generate a L -> t table such that the L will equidistant
* over <0,1>
*/
t_equalized[0] = 0;
for (i = 1, j = 1, L = CBZ_L_STEP; i < CBZ_T_SAMPLES; ++i, L += CBZ_L_STEP)
{
_FixedT l1, l2;
_FixedT d1, d2, d;
_FixedT t1, t2;
/* find the band for our L */
for (k = j; k < CBZ_T_SAMPLES; ++k)
{
if (L < length[k])
break;
}
/*
* Now we know that L is from (length[k-1],length[k]>
* We remember k-1 in order not to have to iterate over the
* whole length array in the next iteration of the main loop
*/
j = k - 1;
/*
* Now interpolate equlised t as a weighted average
*/
l1 = length[k-1];
l2 = length[k];
d1 = l2 - L;
d2 = L - l1;
d = l2 - l1;
t1 = (k - 1) * CBZ_T_STEP;
t2 = k * CBZ_T_STEP;
t_equalized[i] = (t1*d1 + t2*d2)/d;
if (t_equalized[i] < t_equalized[i-1])
g_debug ("wrong t: L %f, l1 %f, l2 %f, t1 %f, t2 %f",
(double) (L)/(double)CBZ_T_ONE,
(double) (l1)/(double)CBZ_T_ONE,
(double) (l2)/(double)CBZ_T_ONE,
(double) (t1)/(double)CBZ_T_ONE,
(double) (t2)/(double)CBZ_T_ONE);
}
t_equalized[CBZ_T_SAMPLES] = CBZ_T_ONE;
/* We now fit a bezier -- at this stage, do a single fit through our values
* at 0, 1/3, 2/3 and 1
*
* FIXME -- do we need to use a better fitting approach to choose the best
* beziere. The actual curve we acquire this way is not too bad shapwise,
* but (probably due to rounding errors) the resulting curve no longer
* satisfies the necessary condition that for L2 > L1, t2 > t1, which
* causes oscilation.
*/
#if 0
/*
* These are the control points we use to calculate the curve coefficients
* for bezier t(L); these are not needed directly, but are implied in the
* calculations below.
*
* (p0 is 0,0, and p3 is 1,1)
*/
p1 = (18 * t_equalized[CBZ_T_SAMPLES/3] -
9 * t_equalized[2*CBZ_T_SAMPLES/3] +
2 << CBZ_T_Q) / 6;
p2 = (18 * t_equalized[2*CBZ_T_SAMPLES/3] -
9 * t_equalized[CBZ_T_SAMPLES/3] -
(5 << CBZ_T_Q)) / 6;
#endif
b->Lc = (18 * t_equalized[CBZ_T_SAMPLES/3] -
9 * t_equalized[2*CBZ_T_SAMPLES/3] +
(2 << CBZ_T_Q)) >> 1;
b->Lb = (36 * t_equalized[2*CBZ_T_SAMPLES/3] -
45 * t_equalized[CBZ_T_SAMPLES/3] -
(9 << CBZ_T_Q)) >> 1;
b->La = ((27 * (t_equalized[CBZ_T_SAMPLES/3] -
t_equalized[2*CBZ_T_SAMPLES/3]) +
(7 << CBZ_T_Q)) >> 1) + CBZ_T_ONE;
g_debug ("t(1/3) %f, t(2/3) %f",
(double)t_equalized[CBZ_T_SAMPLES/3]/(double)CBZ_T_ONE,
(double)t_equalized[2*CBZ_T_SAMPLES/3]/(double)CBZ_T_ONE);
g_debug ("L -> t coefficients: %f, %f, %f",
(double)b->La/(double)CBZ_T_ONE,
(double)b->Lb/(double)CBZ_T_ONE,
(double)b->Lc/(double)CBZ_T_ONE);
/*
* For debugging, you can load these values into a spreadsheet and graph
* them to see how well the approximation matches the data
*/
for (i = 0; i < CBZ_T_SAMPLES; ++i)
{
g_print ("%f, %f, %f\n",
(double)(i*CBZ_T_STEP)/(double)CBZ_T_ONE,
(double)(t_equalized[i])/(double)CBZ_T_ONE,
(double)(clutter_bezier_L2t(b,i*CBZ_T_STEP))/(double)CBZ_T_ONE);
}
#endif
}
/*
* Moves a control point at indx to location represented by knot
*/
void
_clutter_bezier_adjust (ClutterBezier * b, ClutterKnot * knot, guint indx)
{
guint x[4], y[4];
g_assert (indx < 4);
x[0] = b->dx;
y[0] = b->dy;
x[1] = b->cx / 3 + x[0];
y[1] = b->cy / 3 + y[0];
x[2] = b->bx / 3 + b->cx + x[1];
y[2] = b->by / 3 + b->cy + y[1];
x[3] = b->ax + x[0] + b->cx + b->bx;
y[3] = b->ay + y[0] + b->cy + b->by;
x[indx] = knot->x;
y[indx] = knot->y;
_clutter_bezier_init (b, x[0], y[0], x[1], y[1], x[2], y[2], x[3], y[3]);
}
guint
_clutter_bezier_get_length (const ClutterBezier *b)
{
return b->length;
}

View File

@ -0,0 +1,65 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Tomas Frydrych <tf@openedhand.com>
*
* Copyright (C) 2006, 2007 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CLUTTER_BEZIER_H__
#define __CLUTTER_BEZIER_H__
#include <glib.h>
#include "clutter-types.h"
G_BEGIN_DECLS
/* This is used in _clutter_bezier_advance to represent the full
length of the bezier curve. Anything less than that represents a
fraction of the length */
#define CLUTTER_BEZIER_MAX_LENGTH (1 << 18)
typedef struct _ClutterBezier ClutterBezier;
ClutterBezier *_clutter_bezier_new ();
void _clutter_bezier_free (ClutterBezier * b);
ClutterBezier *_clutter_bezier_clone_and_move (const ClutterBezier *b,
gint x,
gint y);
void _clutter_bezier_advance (const ClutterBezier *b,
gint L,
ClutterKnot *knot);
void _clutter_bezier_init (ClutterBezier *b,
gint x_0, gint y_0,
gint x_1, gint y_1,
gint x_2, gint y_2,
gint x_3, gint y_3);
void _clutter_bezier_adjust (ClutterBezier *b,
ClutterKnot *knot,
guint indx);
guint _clutter_bezier_get_length (const ClutterBezier *b);
G_END_DECLS
#endif /* __CLUTTER_BEZIER_H__ */

View File

@ -0,0 +1,886 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2009 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-bin-layout
* @short_description: 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.
*
* The [bin-layout example](https://git.gnome.org/browse/clutter/tree/examples/bin-layout.c?h=clutter-1.18)
* shows how to pack actors inside a #ClutterBinLayout.
*
* #ClutterBinLayout is available since Clutter 1.2
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
#include "deprecated/clutter-container.h"
#include "deprecated/clutter-bin-layout.h"
#include "clutter-actor-private.h"
#include "clutter-animatable.h"
#include "clutter-child-meta.h"
#include "clutter-debug.h"
#include "clutter-enum-types.h"
#include "clutter-layout-meta.h"
#include "clutter-private.h"
#define CLUTTER_TYPE_BIN_LAYER (clutter_bin_layer_get_type ())
#define CLUTTER_BIN_LAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BIN_LAYER, ClutterBinLayer))
#define CLUTTER_IS_BIN_LAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BIN_LAYER))
typedef struct _ClutterBinLayer ClutterBinLayer;
typedef struct _ClutterLayoutMetaClass ClutterBinLayerClass;
struct _ClutterBinLayoutPrivate
{
ClutterBinAlignment x_align;
ClutterBinAlignment y_align;
ClutterContainer *container;
};
struct _ClutterBinLayer
{
ClutterLayoutMeta parent_instance;
ClutterBinAlignment x_align;
ClutterBinAlignment y_align;
};
enum
{
PROP_LAYER_0,
PROP_LAYER_X_ALIGN,
PROP_LAYER_Y_ALIGN,
PROP_LAYER_LAST
};
enum
{
PROP_0,
PROP_X_ALIGN,
PROP_Y_ALIGN,
PROP_LAST
};
static GParamSpec *layer_props[PROP_LAYER_LAST] = { NULL, };
static GParamSpec *bin_props[PROP_LAST] = { NULL, };
GType clutter_bin_layer_get_type (void);
G_DEFINE_TYPE (ClutterBinLayer,
clutter_bin_layer,
CLUTTER_TYPE_LAYOUT_META)
G_DEFINE_TYPE_WITH_PRIVATE (ClutterBinLayout,
clutter_bin_layout,
CLUTTER_TYPE_LAYOUT_MANAGER)
/*
* ClutterBinLayer
*/
static void
set_layer_x_align (ClutterBinLayer *self,
ClutterBinAlignment alignment)
{
ClutterLayoutManager *manager;
ClutterLayoutMeta *meta;
if (self->x_align == alignment)
return;
self->x_align = alignment;
meta = CLUTTER_LAYOUT_META (self);
manager = clutter_layout_meta_get_manager (meta);
clutter_layout_manager_layout_changed (manager);
g_object_notify_by_pspec (G_OBJECT (self), layer_props[PROP_LAYER_X_ALIGN]);
}
static void
set_layer_y_align (ClutterBinLayer *self,
ClutterBinAlignment alignment)
{
ClutterLayoutManager *manager;
ClutterLayoutMeta *meta;
if (self->y_align == alignment)
return;
self->y_align = alignment;
meta = CLUTTER_LAYOUT_META (self);
manager = clutter_layout_meta_get_manager (meta);
clutter_layout_manager_layout_changed (manager);
g_object_notify_by_pspec (G_OBJECT (self), layer_props[PROP_LAYER_Y_ALIGN]);
}
static void
clutter_bin_layer_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterBinLayer *layer = CLUTTER_BIN_LAYER (gobject);
switch (prop_id)
{
case PROP_LAYER_X_ALIGN:
set_layer_x_align (layer, g_value_get_enum (value));
break;
case PROP_LAYER_Y_ALIGN:
set_layer_y_align (layer, g_value_get_enum (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_bin_layer_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterBinLayer *layer = CLUTTER_BIN_LAYER (gobject);
switch (prop_id)
{
case PROP_LAYER_X_ALIGN:
g_value_set_enum (value, layer->x_align);
break;
case PROP_LAYER_Y_ALIGN:
g_value_set_enum (value, layer->y_align);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_bin_layer_class_init (ClutterBinLayerClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->set_property = clutter_bin_layer_set_property;
gobject_class->get_property = clutter_bin_layer_get_property;
layer_props[PROP_LAYER_X_ALIGN] =
g_param_spec_enum ("x-align",
P_("Horizontal Alignment"),
P_("Horizontal alignment for the actor "
"inside the layout manager"),
CLUTTER_TYPE_BIN_ALIGNMENT,
CLUTTER_BIN_ALIGNMENT_CENTER,
CLUTTER_PARAM_READWRITE);
layer_props[PROP_LAYER_Y_ALIGN] =
g_param_spec_enum ("y-align",
P_("Vertical Alignment"),
P_("Vertical alignment for the actor "
"inside the layout manager"),
CLUTTER_TYPE_BIN_ALIGNMENT,
CLUTTER_BIN_ALIGNMENT_CENTER,
CLUTTER_PARAM_READWRITE);
g_object_class_install_properties (gobject_class,
PROP_LAYER_LAST,
layer_props);
}
static void
clutter_bin_layer_init (ClutterBinLayer *layer)
{
layer->x_align = CLUTTER_BIN_ALIGNMENT_CENTER;
layer->y_align = CLUTTER_BIN_ALIGNMENT_CENTER;
}
/*
* ClutterBinLayout
*/
static void
set_x_align (ClutterBinLayout *self,
ClutterBinAlignment alignment)
{
ClutterBinLayoutPrivate *priv = self->priv;
if (priv->x_align != alignment)
{
ClutterLayoutManager *manager;
priv->x_align = alignment;
manager = CLUTTER_LAYOUT_MANAGER (self);
clutter_layout_manager_layout_changed (manager);
g_object_notify_by_pspec (G_OBJECT (self), bin_props[PROP_X_ALIGN]);
}
}
static void
set_y_align (ClutterBinLayout *self,
ClutterBinAlignment alignment)
{
ClutterBinLayoutPrivate *priv = self->priv;
if (priv->y_align != alignment)
{
ClutterLayoutManager *manager;
priv->y_align = alignment;
manager = CLUTTER_LAYOUT_MANAGER (self);
clutter_layout_manager_layout_changed (manager);
g_object_notify_by_pspec (G_OBJECT (self), bin_props[PROP_Y_ALIGN]);
}
}
static void
clutter_bin_layout_get_preferred_width (ClutterLayoutManager *manager,
ClutterContainer *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,
ClutterContainer *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_bin_alignment_factor (ClutterBinAlignment alignment,
ClutterTextDirection text_dir)
{
switch (alignment)
{
case CLUTTER_BIN_ALIGNMENT_CENTER:
return 0.5;
case CLUTTER_BIN_ALIGNMENT_START:
return text_dir == CLUTTER_TEXT_DIRECTION_LTR ? 0.0 : 1.0;
case CLUTTER_BIN_ALIGNMENT_END:
return text_dir == CLUTTER_TEXT_DIRECTION_LTR ? 1.0 : 0.0;
case CLUTTER_BIN_ALIGNMENT_FIXED:
case CLUTTER_BIN_ALIGNMENT_FILL:
return 0.0;
}
return 0.0;
}
static gdouble
get_actor_align_factor (ClutterActorAlign alignment)
{
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,
ClutterContainer *container,
const ClutterActorBox *allocation,
ClutterAllocationFlags flags)
{
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))
{
ClutterLayoutMeta *meta;
ClutterBinLayer *layer;
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;
meta = clutter_layout_manager_get_child_meta (manager,
container,
child);
layer = CLUTTER_BIN_LAYER (meta);
fixed_x = fixed_y = 0.f;
g_object_get (child,
"fixed-position-set", &is_fixed_position_set,
"fixed-x", &fixed_x,
"fixed-y", &fixed_y,
NULL);
/* XXX:2.0 - remove the FIXED alignment, and just use the fixed position
* of the actor if one is set
*/
if (is_fixed_position_set ||
layer->x_align == CLUTTER_BIN_ALIGNMENT_FIXED)
{
if (is_fixed_position_set)
child_alloc.x1 = fixed_x;
else
child_alloc.x1 = clutter_actor_get_x (child);
}
else
child_alloc.x1 = allocation_x;
if (is_fixed_position_set ||
layer->y_align == CLUTTER_BIN_ALIGNMENT_FIXED)
{
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
{
ClutterTextDirection text_dir;
x_fill = (layer->x_align == CLUTTER_BIN_ALIGNMENT_FILL);
text_dir = clutter_actor_get_text_direction (child);
if (!is_fixed_position_set)
x_align = get_bin_alignment_factor (layer->x_align, text_dir);
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 = (layer->y_align == CLUTTER_BIN_ALIGNMENT_FILL);
if (!is_fixed_position_set)
y_align = get_bin_alignment_factor (layer->y_align,
CLUTTER_TEXT_DIRECTION_LTR);
else
y_align = 0.0;
}
clutter_actor_allocate_align_fill (child, &child_alloc,
x_align, y_align,
x_fill, y_fill,
flags);
}
}
static GType
clutter_bin_layout_get_child_meta_type (ClutterLayoutManager *manager)
{
return CLUTTER_TYPE_BIN_LAYER;
}
static ClutterLayoutMeta *
clutter_bin_layout_create_child_meta (ClutterLayoutManager *manager,
ClutterContainer *container,
ClutterActor *actor)
{
ClutterBinLayoutPrivate *priv;
priv = CLUTTER_BIN_LAYOUT (manager)->priv;
return g_object_new (CLUTTER_TYPE_BIN_LAYER,
"container", container,
"actor", actor,
"manager", manager,
"x-align", priv->x_align,
"y_align", priv->y_align,
NULL);
}
static void
clutter_bin_layout_set_container (ClutterLayoutManager *manager,
ClutterContainer *container)
{
ClutterBinLayoutPrivate *priv;
ClutterLayoutManagerClass *parent_class;
priv = CLUTTER_BIN_LAYOUT (manager)->priv;
priv->container = container;
parent_class = CLUTTER_LAYOUT_MANAGER_CLASS (clutter_bin_layout_parent_class);
parent_class->set_container (manager, container);
}
static void
clutter_bin_layout_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterBinLayout *layout = CLUTTER_BIN_LAYOUT (gobject);
switch (prop_id)
{
case PROP_X_ALIGN:
set_x_align (layout, g_value_get_enum (value));
break;
case PROP_Y_ALIGN:
set_y_align (layout, g_value_get_enum (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_bin_layout_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterBinLayoutPrivate *priv;
priv = CLUTTER_BIN_LAYOUT (gobject)->priv;
switch (prop_id)
{
case PROP_X_ALIGN:
g_value_set_enum (value, priv->x_align);
break;
case PROP_Y_ALIGN:
g_value_set_enum (value, priv->y_align);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_bin_layout_class_init (ClutterBinLayoutClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterLayoutManagerClass *layout_class =
CLUTTER_LAYOUT_MANAGER_CLASS (klass);
/**
* ClutterBinLayout:x-align:
*
* The default horizontal alignment policy for actors managed
* by the #ClutterBinLayout
*
* Since: 1.2
*
* Deprecated: 1.12: Use the #ClutterActor:x-expand and the
* #ClutterActor:x-align properties on #ClutterActor instead.
*/
bin_props[PROP_X_ALIGN] =
g_param_spec_enum ("x-align",
P_("Horizontal Alignment"),
P_("Default horizontal alignment for the actors "
"inside the layout manager"),
CLUTTER_TYPE_BIN_ALIGNMENT,
CLUTTER_BIN_ALIGNMENT_CENTER,
CLUTTER_PARAM_READWRITE);
/**
* ClutterBinLayout:y-align:
*
* The default vertical alignment policy for actors managed
* by the #ClutterBinLayout
*
* Since: 1.2
*
* Deprecated: 1.12: Use the #ClutterActor:y-expand and the
* #ClutterActor:y-align properties on #ClutterActor instead.
*/
bin_props[PROP_Y_ALIGN] =
g_param_spec_enum ("y-align",
P_("Vertical Alignment"),
P_("Default vertical alignment for the actors "
"inside the layout manager"),
CLUTTER_TYPE_BIN_ALIGNMENT,
CLUTTER_BIN_ALIGNMENT_CENTER,
CLUTTER_PARAM_READWRITE);
gobject_class->set_property = clutter_bin_layout_set_property;
gobject_class->get_property = clutter_bin_layout_get_property;
g_object_class_install_properties (gobject_class, PROP_LAST, bin_props);
layout_class->get_preferred_width = clutter_bin_layout_get_preferred_width;
layout_class->get_preferred_height = clutter_bin_layout_get_preferred_height;
layout_class->allocate = clutter_bin_layout_allocate;
layout_class->create_child_meta = clutter_bin_layout_create_child_meta;
layout_class->get_child_meta_type = clutter_bin_layout_get_child_meta_type;
layout_class->set_container = clutter_bin_layout_set_container;
}
static void
clutter_bin_layout_init (ClutterBinLayout *self)
{
self->priv = clutter_bin_layout_get_instance_private (self);
self->priv->x_align = CLUTTER_BIN_ALIGNMENT_CENTER;
self->priv->y_align = CLUTTER_BIN_ALIGNMENT_CENTER;
}
/**
* clutter_bin_layout_new:
* @x_align: the default alignment policy to be used on the
* horizontal axis
* @y_align: the default alignment policy to be used on the
* vertical axis
*
* Creates a new #ClutterBinLayout layout manager
*
* Return value: the newly created layout manager
*
* Since: 1.2
*/
ClutterLayoutManager *
clutter_bin_layout_new (ClutterBinAlignment x_align,
ClutterBinAlignment y_align)
{
return g_object_new (CLUTTER_TYPE_BIN_LAYOUT,
"x-align", x_align,
"y-align", y_align,
NULL);
}
/**
* clutter_bin_layout_set_alignment:
* @self: a #ClutterBinLayout
* @child: (allow-none): a child of @container
* @x_align: the horizontal alignment policy to be used for the @child
* inside @container
* @y_align: the vertical aligment policy to be used on the @child
* inside @container
*
* Sets the horizontal and vertical alignment policies to be applied
* to a @child of @self
*
* If @child is %NULL then the @x_align and @y_align values will
* be set as the default alignment policies
*
* Since: 1.2
*
* Deprecated: 1.12: Use the #ClutterActor:x-align and
* #ClutterActor:y-align properties of #ClutterActor instead.
*/
void
clutter_bin_layout_set_alignment (ClutterBinLayout *self,
ClutterActor *child,
ClutterBinAlignment x_align,
ClutterBinAlignment y_align)
{
ClutterBinLayoutPrivate *priv;
ClutterLayoutManager *manager;
ClutterLayoutMeta *meta;
g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self));
g_return_if_fail (child == NULL || CLUTTER_IS_ACTOR (child));
priv = self->priv;
if (priv->container == NULL)
{
if (child == NULL)
{
set_x_align (self, x_align);
set_y_align (self, y_align);
}
else
g_warning ("The layout of type '%s' must be associated to "
"a ClutterContainer before setting the alignment "
"on its children",
G_OBJECT_TYPE_NAME (self));
return;
}
manager = CLUTTER_LAYOUT_MANAGER (self);
meta = clutter_layout_manager_get_child_meta (manager,
priv->container,
child);
g_assert (CLUTTER_IS_BIN_LAYER (meta));
set_layer_x_align (CLUTTER_BIN_LAYER (meta), x_align);
set_layer_y_align (CLUTTER_BIN_LAYER (meta), y_align);
}
/**
* clutter_bin_layout_get_alignment:
* @self: a #ClutterBinLayout
* @child: (allow-none): a child of @container
* @x_align: (out) (allow-none): return location for the horizontal
* alignment policy
* @y_align: (out) (allow-none): return location for the vertical
* alignment policy
*
* Retrieves the horizontal and vertical alignment policies for
* a child of @self
*
* If @child is %NULL the default alignment policies will be returned
* instead
*
* Since: 1.2
*
* Deprecated: 1.12: Use the #ClutterActor:x-align and the
* #ClutterActor:y-align properties of #ClutterActor instead.
*/
void
clutter_bin_layout_get_alignment (ClutterBinLayout *self,
ClutterActor *child,
ClutterBinAlignment *x_align,
ClutterBinAlignment *y_align)
{
ClutterBinLayoutPrivate *priv;
ClutterLayoutManager *manager;
ClutterLayoutMeta *meta;
ClutterBinLayer *layer;
g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self));
priv = self->priv;
if (priv->container == NULL)
{
if (child == NULL)
{
if (x_align)
*x_align = priv->x_align;
if (y_align)
*y_align = priv->y_align;
}
else
g_warning ("The layout of type '%s' must be associated to "
"a ClutterContainer before getting the alignment "
"of its children",
G_OBJECT_TYPE_NAME (self));
return;
}
manager = CLUTTER_LAYOUT_MANAGER (self);
meta = clutter_layout_manager_get_child_meta (manager,
priv->container,
child);
g_assert (CLUTTER_IS_BIN_LAYER (meta));
layer = CLUTTER_BIN_LAYER (meta);
if (x_align)
*x_align = layer->x_align;
if (y_align)
*y_align = layer->y_align;
}
/**
* clutter_bin_layout_add:
* @self: a #ClutterBinLayout
* @child: a #ClutterActor
* @x_align: horizontal alignment policy for @child
* @y_align: vertical alignment policy for @child
*
* Adds a #ClutterActor to the container using @self and
* sets the alignment policies for it
*
* This function is equivalent to clutter_container_add_actor()
* and clutter_layout_manager_child_set_property() but it does not
* require a pointer to the #ClutterContainer associated to the
* #ClutterBinLayout
*
* Since: 1.2
*
* Deprecated: 1.12: Use clutter_actor_add_child() instead.
*/
void
clutter_bin_layout_add (ClutterBinLayout *self,
ClutterActor *child,
ClutterBinAlignment x_align,
ClutterBinAlignment y_align)
{
ClutterBinLayoutPrivate *priv;
ClutterLayoutManager *manager;
ClutterLayoutMeta *meta;
g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self));
g_return_if_fail (CLUTTER_IS_ACTOR (child));
priv = self->priv;
if (priv->container == NULL)
{
g_warning ("The layout of type '%s' must be associated to "
"a ClutterContainer before adding children",
G_OBJECT_TYPE_NAME (self));
return;
}
clutter_container_add_actor (priv->container, child);
manager = CLUTTER_LAYOUT_MANAGER (self);
meta = clutter_layout_manager_get_child_meta (manager,
priv->container,
child);
g_assert (CLUTTER_IS_BIN_LAYER (meta));
set_layer_x_align (CLUTTER_BIN_LAYER (meta), x_align);
set_layer_y_align (CLUTTER_BIN_LAYER (meta), y_align);
}

View File

@ -0,0 +1,86 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2009 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_BIN_LAYOUT_H__
#define __CLUTTER_BIN_LAYOUT_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-layout-manager.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_BIN_LAYOUT (clutter_bin_layout_get_type ())
#define CLUTTER_BIN_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BIN_LAYOUT, ClutterBinLayout))
#define CLUTTER_IS_BIN_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BIN_LAYOUT))
#define CLUTTER_BIN_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BIN_LAYOUT, ClutterBinLayoutClass))
#define CLUTTER_IS_BIN_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BIN_LAYOUT))
#define CLUTTER_BIN_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BIN_LAYOUT, ClutterBinLayoutClass))
typedef struct _ClutterBinLayout ClutterBinLayout;
typedef struct _ClutterBinLayoutPrivate ClutterBinLayoutPrivate;
typedef struct _ClutterBinLayoutClass ClutterBinLayoutClass;
/**
* ClutterBinLayout:
*
* The #ClutterBinLayout structure contains only private data
* and should be accessed using the provided API
*
* Since: 1.2
*/
struct _ClutterBinLayout
{
/*< private >*/
ClutterLayoutManager parent_instance;
ClutterBinLayoutPrivate *priv;
};
/**
* ClutterBinLayoutClass:
*
* The #ClutterBinLayoutClass structure contains only private
* data and should be accessed using the provided API
*
* Since: 1.2
*/
struct _ClutterBinLayoutClass
{
/*< private >*/
ClutterLayoutManagerClass parent_class;
};
CLUTTER_AVAILABLE_IN_1_2
GType clutter_bin_layout_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_2
ClutterLayoutManager * clutter_bin_layout_new (ClutterBinAlignment x_align,
ClutterBinAlignment y_align);
G_END_DECLS
#endif /* __CLUTTER_BIN_LAYOUT_H__ */

View File

@ -0,0 +1,591 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-bind-constraint
* @Title: ClutterBindConstraint
* @Short_Description: A constraint binding the position or size of an actor
*
* #ClutterBindConstraint is a #ClutterConstraint that binds the
* position or the size of the #ClutterActor to which it is applied
* to the the position or the size of another #ClutterActor, or
* "source".
*
* An offset can be applied to the constraint, to avoid overlapping. The offset
* can also be animated. For instance, the following code will set up three
* actors to be bound to the same origin:
*
* |[<!-- language="C" -->
* // source
* rect[0] = clutter_rectangle_new_with_color (&red_color);
* clutter_actor_set_position (rect[0], x_pos, y_pos);
* clutter_actor_set_size (rect[0], 100, 100);
*
* // second rectangle
* rect[1] = clutter_rectangle_new_with_color (&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_rectangle_new_with_color (&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:
*
* |[<!-- language="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);
* ]|
*
* #ClutterBindConstraint is available since Clutter 1.4
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include "clutter-bind-constraint.h"
#include "clutter-actor-meta-private.h"
#include "clutter-actor-private.h"
#include "clutter-constraint.h"
#include "clutter-debug.h"
#include "clutter-enum-types.h"
#include "clutter-private.h"
#define CLUTTER_BIND_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BIND_CONSTRAINT, ClutterBindConstraintClass))
#define CLUTTER_IS_BIND_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BIND_CONSTRAINT))
#define CLUTTER_BIND_CONSTRAINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BIND_CONSTRAINT, ClutterBindConstraintClass))
struct _ClutterBindConstraint
{
ClutterConstraint parent_instance;
ClutterActor *actor;
ClutterActor *source;
ClutterBindCoordinate coordinate;
gfloat offset;
};
struct _ClutterBindConstraintClass
{
ClutterConstraintClass parent_class;
};
enum
{
PROP_0,
PROP_SOURCE,
PROP_COORDINATE,
PROP_OFFSET,
PROP_LAST
};
static GParamSpec *obj_props[PROP_LAST];
G_DEFINE_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_allocation (ClutterConstraint *constraint,
ClutterActor *actor,
ClutterActorBox *allocation)
{
ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint);
gfloat source_width, source_height;
gfloat actor_width, actor_height;
ClutterVertex source_position = { 0., };
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;
/**
* ClutterBindConstraint:source:
*
* The #ClutterActor used as the source for the binding.
*
* The #ClutterActor must not be contained inside the actor associated
* to the constraint.
*
* Since: 1.4
*/
obj_props[PROP_SOURCE] =
g_param_spec_object ("source",
P_("Source"),
P_("The source of the binding"),
CLUTTER_TYPE_ACTOR,
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT);
/**
* ClutterBindConstraint:coordinate:
*
* The coordinate to be bound
*
* Since: 1.4
*/
obj_props[PROP_COORDINATE] =
g_param_spec_enum ("coordinate",
P_("Coordinate"),
P_("The coordinate to bind"),
CLUTTER_TYPE_BIND_COORDINATE,
CLUTTER_BIND_X,
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT);
/**
* ClutterBindConstraint:offset:
*
* The offset, in pixels, to be applied to the binding
*
* Since: 1.4
*/
obj_props[PROP_OFFSET] =
g_param_spec_float ("offset",
P_("Offset"),
P_("The offset in pixels to apply to the binding"),
-G_MAXFLOAT, G_MAXFLOAT,
0.0f,
CLUTTER_PARAM_READWRITE | 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
*
* Since: 1.4
*/
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
*
* Since: 1.4
*/
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 clutter_bind_constraint_set_source()
*
* Return value: (transfer none): a pointer to the source actor
*
* Since: 1.4
*/
ClutterActor *
clutter_bind_constraint_get_source (ClutterBindConstraint *constraint)
{
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
*
* Since: 1.4
*/
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
*
* Since: 1.4
*/
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
*
* Since: 1.4
*/
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 clutter_bind_constraint_set_offset()
*
* Return value: the offset, in pixels
*
* Since: 1.4
*/
gfloat
clutter_bind_constraint_get_offset (ClutterBindConstraint *bind)
{
g_return_val_if_fail (CLUTTER_IS_BIND_CONSTRAINT (bind), 0.0);
return bind->offset;
}

View File

@ -0,0 +1,77 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_BIND_CONSTRAINT_H__
#define __CLUTTER_BIND_CONSTRAINT_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-constraint.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_BIND_CONSTRAINT (clutter_bind_constraint_get_type ())
#define CLUTTER_BIND_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BIND_CONSTRAINT, ClutterBindConstraint))
#define CLUTTER_IS_BIND_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BIND_CONSTRAINT))
/**
* ClutterBindConstraint:
*
* #ClutterBindConstraint is an opaque structure
* whose members cannot be directly accessed
*
* Since: 1.4
*/
typedef struct _ClutterBindConstraint ClutterBindConstraint;
typedef struct _ClutterBindConstraintClass ClutterBindConstraintClass;
CLUTTER_AVAILABLE_IN_1_4
GType clutter_bind_constraint_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_4
ClutterConstraint * clutter_bind_constraint_new (ClutterActor *source,
ClutterBindCoordinate coordinate,
gfloat offset);
CLUTTER_AVAILABLE_IN_1_4
void clutter_bind_constraint_set_source (ClutterBindConstraint *constraint,
ClutterActor *source);
CLUTTER_AVAILABLE_IN_1_4
ClutterActor * clutter_bind_constraint_get_source (ClutterBindConstraint *constraint);
CLUTTER_AVAILABLE_IN_1_4
void clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint,
ClutterBindCoordinate coordinate);
CLUTTER_AVAILABLE_IN_1_4
ClutterBindCoordinate clutter_bind_constraint_get_coordinate (ClutterBindConstraint *constraint);
CLUTTER_AVAILABLE_IN_1_4
void clutter_bind_constraint_set_offset (ClutterBindConstraint *constraint,
gfloat offset);
CLUTTER_AVAILABLE_IN_1_4
gfloat clutter_bind_constraint_get_offset (ClutterBindConstraint *constraint);
G_END_DECLS
#endif /* __CLUTTER_BIND_CONSTRAINT_H__ */

View File

@ -0,0 +1,938 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2008 Intel Corporation.
*
* Authored By: Emmanuele Bassi <ebassi@linux.intel.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* SECTION:clutter-binding-pool
* @short_description: Pool for key bindings
*
* #ClutterBindingPool is a data structure holding a set of key bindings.
* Each key binding associates a key symbol (eventually with modifiers)
* 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:
*
* |[<!-- language="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:
*
* |[<!-- language="C" -->
* gboolean (* callback) (GObject *instance,
* const gchar *action_name,
* guint key_val,
* ClutterModifierType modifiers,
* gpointer user_data);
* ]|
*
* The actor should then override the #ClutterActor::key-press-event and
* use clutter_binding_pool_activate() to match a #ClutterKeyEvent structure
* to one of the actions:
*
* |[<!-- language="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 clutter_binding_pool_activate() function will return %FALSE if
* no action for the given key binding was found, if the action was
* blocked (using clutter_binding_pool_block_action()) or if the
* key binding handler returned %FALSE.
*
* #ClutterBindingPool is available since Clutter 1.0
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-binding-pool.h"
#include "clutter-debug.h"
#include "clutter-enum-types.h"
#include "clutter-marshal.h"
#include "clutter-private.h"
#define CLUTTER_BINDING_POOL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), CLUTTER_TYPE_BINDING_POOL, ClutterBindingPoolClass))
#define CLUTTER_IS_BINDING_POOL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CLUTTER_TYPE_BINDING_POOL))
#define CLUTTER_BINDING_POOL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CLUTTER_TYPE_BINDING_POOL, ClutterBindingPoolClass))
#define BINDING_MOD_MASK ((CLUTTER_SHIFT_MASK | \
CLUTTER_CONTROL_MASK | \
CLUTTER_MOD1_MASK | \
CLUTTER_SUPER_MASK | \
CLUTTER_HYPER_MASK | \
CLUTTER_META_MASK) | CLUTTER_RELEASE_MASK)
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 _ClutterBindingPoolClass
{
GObjectClass parent_class;
};
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_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_slice_new (ClutterBindingEntry);
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_slice_free (ClutterBindingEntry, 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_foreach (pool->entries, (GFunc) binding_entry_free, NULL);
g_slist_free (pool->entries);
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.
*
* Since: 1.0
*/
obj_props[PROP_NAME] =
g_param_spec_string ("name",
P_("Name"),
P_("The unique name of the binding pool"),
NULL,
CLUTTER_PARAM_READWRITE |
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 clutter_binding_pool_find() will
* be able to return the correct binding pool.
*
* Return value: the newly created binding pool with the given
* name. Use g_object_unref() when done.
*
* Since: 1.0
*/
ClutterBindingPool *
clutter_binding_pool_new (const gchar *name)
{
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
* clutter_binding_pool_new() and uses the class type name as the
* unique name for the binding pool.
*
* Calling this function multiple times will return the same
* #ClutterBindingPool.
*
* A binding pool for a class can also be retrieved using
* clutter_binding_pool_find() with the class type name:
*
* |[
* pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (instance));
* ]|
*
* Return value: (transfer none): the binding pool for the given class.
* The returned #ClutterBindingPool is owned by Clutter and should not
* be freed directly
*
* Since: 1.0
*/
ClutterBindingPool *
clutter_binding_pool_get_for_class (gpointer klass)
{
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
*
* Since: 1.0
*/
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: (type Clutter.BindingActionFunc): function to be called
* when the action is activated
* @data: data to be passed to @callback
* @notify: function to be called when the action is removed
* 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 clutter_binding_pool_activate()
* the passed @callback will be invoked (with @data).
*
* Actions can be blocked with clutter_binding_pool_block_action()
* and then unblocked using clutter_binding_pool_unblock_action().
*
* Since: 1.0
*/
void
clutter_binding_pool_install_action (ClutterBindingPool *pool,
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 clutter_binding_pool_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 clutter_binding_pool_activate()
* the passed @closure will be invoked.
*
* Actions can be blocked with clutter_binding_pool_block_action()
* and then unblocked using clutter_binding_pool_unblock_action().
*
* Since: 1.0
*/
void
clutter_binding_pool_install_closure (ClutterBindingPool *pool,
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 clutter_binding_pool_install_action().
*
* When an action has been activated using clutter_binding_pool_activate()
* the passed @callback will be invoked (with @data).
*
* Actions can be blocked with clutter_binding_pool_block_action()
* and then unblocked using clutter_binding_pool_unblock_action().
*
* Since: 1.0
*/
void
clutter_binding_pool_override_action (ClutterBindingPool *pool,
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 clutter_binding_pool_override_action().
*
* Allows overriding the action for @key_val and @modifiers inside a
* #ClutterBindingPool. See clutter_binding_pool_install_closure().
*
* When an action has been activated using clutter_binding_pool_activate()
* the passed @callback will be invoked (with @data).
*
* Actions can be blocked with clutter_binding_pool_block_action()
* and then unblocked using clutter_binding_pool_unblock_action().
*
* Since: 1.0
*/
void
clutter_binding_pool_override_closure (ClutterBindingPool *pool,
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
*
* Since: 1.0
*/
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.
*
* Since: 1.0
*/
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 (&params[0], G_TYPE_OBJECT);
g_value_set_object (&params[0], gobject);
g_value_init (&params[1], G_TYPE_STRING);
g_value_set_static_string (&params[1], entry->name);
g_value_init (&params[2], G_TYPE_UINT);
g_value_set_uint (&params[2], entry->key_val);
g_value_init (&params[3], CLUTTER_TYPE_MODIFIER_TYPE);
g_value_set_flags (&params[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 (&params[0]);
g_value_unset (&params[1]);
g_value_unset (&params[2]);
g_value_unset (&params[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
* clutter_binding_pool_install_action().
*
* If the action bound to the @key_val, @modifiers pair has been
* blocked using clutter_binding_pool_block_action(), the callback
* will not be invoked, and this function will return %FALSE.
*
* Return value: %TRUE if an action was found and was activated
*
* Since: 1.0
*/
gboolean
clutter_binding_pool_activate (ClutterBindingPool *pool,
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.
*
* Since: 1.0
*/
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 clutter_binding_pool_activate() was called on
* an action previously blocked with clutter_binding_pool_block_action().
*
* Since: 1.0
*/
void
clutter_binding_pool_unblock_action (ClutterBindingPool *pool,
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;
}
}

View File

@ -0,0 +1,135 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2008 Intel Corporation.
*
* Authored By: Emmanuele Bassi <ebassi@linux.intel.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CLUTTER_BINDING_POOL_H__
#define __CLUTTER_BINDING_POOL_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <glib-object.h>
#include <clutter/clutter-event.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_BINDING_POOL (clutter_binding_pool_get_type ())
#define CLUTTER_BINDING_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BINDING_POOL, ClutterBindingPool))
#define CLUTTER_IS_BINDING_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BINDING_POOL))
/**
* ClutterBindingPool:
*
* Container of key bindings. The #ClutterBindingPool struct is
* private.
*
* Since: 1.0
*/
typedef struct _ClutterBindingPool ClutterBindingPool;
typedef struct _ClutterBindingPoolClass ClutterBindingPoolClass;
/**
* ClutterBindingActionFunc:
* @gobject: a #GObject
* @action_name: the name of the action
* @key_val: the key symbol
* @modifiers: bitmask of the modifier flags
* @user_data: data passed to the function
*
* The prototype for the callback function registered with
* clutter_binding_pool_install_action() and invoked by
* clutter_binding_pool_activate().
*
* Return value: the function should return %TRUE if the key
* binding has been handled, and return %FALSE otherwise
*
* Since: 1.0
*/
typedef gboolean (* ClutterBindingActionFunc) (GObject *gobject,
const gchar *action_name,
guint key_val,
ClutterModifierType modifiers,
gpointer user_data);
CLUTTER_AVAILABLE_IN_1_0
GType clutter_binding_pool_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_0
ClutterBindingPool * clutter_binding_pool_new (const gchar *name);
CLUTTER_AVAILABLE_IN_1_0
ClutterBindingPool * clutter_binding_pool_get_for_class (gpointer klass);
CLUTTER_AVAILABLE_IN_1_0
ClutterBindingPool * clutter_binding_pool_find (const gchar *name);
CLUTTER_AVAILABLE_IN_1_0
void clutter_binding_pool_install_action (ClutterBindingPool *pool,
const gchar *action_name,
guint key_val,
ClutterModifierType modifiers,
GCallback callback,
gpointer data,
GDestroyNotify notify);
CLUTTER_AVAILABLE_IN_1_0
void clutter_binding_pool_install_closure (ClutterBindingPool *pool,
const gchar *action_name,
guint key_val,
ClutterModifierType modifiers,
GClosure *closure);
CLUTTER_AVAILABLE_IN_1_0
void clutter_binding_pool_override_action (ClutterBindingPool *pool,
guint key_val,
ClutterModifierType modifiers,
GCallback callback,
gpointer data,
GDestroyNotify notify);
CLUTTER_AVAILABLE_IN_1_0
void clutter_binding_pool_override_closure (ClutterBindingPool *pool,
guint key_val,
ClutterModifierType modifiers,
GClosure *closure);
CLUTTER_AVAILABLE_IN_1_0
const gchar * clutter_binding_pool_find_action (ClutterBindingPool *pool,
guint key_val,
ClutterModifierType modifiers);
CLUTTER_AVAILABLE_IN_1_0
void clutter_binding_pool_remove_action (ClutterBindingPool *pool,
guint key_val,
ClutterModifierType modifiers);
CLUTTER_AVAILABLE_IN_1_0
gboolean clutter_binding_pool_activate (ClutterBindingPool *pool,
guint key_val,
ClutterModifierType modifiers,
GObject *gobject);
CLUTTER_AVAILABLE_IN_1_0
void clutter_binding_pool_block_action (ClutterBindingPool *pool,
const gchar *action_name);
CLUTTER_AVAILABLE_IN_1_0
void clutter_binding_pool_unblock_action (ClutterBindingPool *pool,
const gchar *action_name);
G_END_DECLS
#endif /* __CLUTTER_BINDING_POOL_H__ */

View File

@ -0,0 +1,278 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-blur-effect
* @short_description: A blur effect
* @see_also: #ClutterEffect, #ClutterOffscreenEffect
*
* #ClutterBlurEffect is a sub-class of #ClutterEffect that allows blurring a
* actor and its contents.
*
* #ClutterBlurEffect is available since Clutter 1.4
*/
#define CLUTTER_BLUR_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BLUR_EFFECT, ClutterBlurEffectClass))
#define CLUTTER_IS_BLUR_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BLUR_EFFECT))
#define CLUTTER_BLUR_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BLUR_EFFECT, ClutterBlurEffectClass))
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-blur-effect.h"
#include "cogl/cogl.h"
#include "clutter-debug.h"
#include "clutter-offscreen-effect.h"
#include "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
struct _ClutterBlurEffect
{
ClutterOffscreenEffect parent_instance;
/* a back pointer to our actor, so that we can query it */
ClutterActor *actor;
gint pixel_step_uniform;
gint tex_width;
gint tex_height;
CoglPipeline *pipeline;
};
struct _ClutterBlurEffectClass
{
ClutterOffscreenEffectClass parent_class;
CoglPipeline *base_pipeline;
};
G_DEFINE_TYPE (ClutterBlurEffect,
clutter_blur_effect,
CLUTTER_TYPE_OFFSCREEN_EFFECT);
static gboolean
clutter_blur_effect_pre_paint (ClutterEffect *effect)
{
ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect);
ClutterEffectClass *parent_class;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
return FALSE;
self->actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
if (self->actor == NULL)
return FALSE;
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
{
/* if we don't have support for GLSL shaders then we
* forcibly disable the ActorMeta
*/
g_warning ("Unable to use the ShaderEffect: the graphics hardware "
"or the current GL driver does not implement support "
"for the GLSL shading language.");
clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
return FALSE;
}
parent_class = CLUTTER_EFFECT_CLASS (clutter_blur_effect_parent_class);
if (parent_class->pre_paint (effect))
{
ClutterOffscreenEffect *offscreen_effect =
CLUTTER_OFFSCREEN_EFFECT (effect);
CoglHandle texture;
texture = clutter_offscreen_effect_get_texture (offscreen_effect);
self->tex_width = cogl_texture_get_width (texture);
self->tex_height = cogl_texture_get_height (texture);
if (self->pixel_step_uniform > -1)
{
gfloat pixel_step[2];
pixel_step[0] = 1.0f / self->tex_width;
pixel_step[1] = 1.0f / self->tex_height;
cogl_pipeline_set_uniform_float (self->pipeline,
self->pixel_step_uniform,
2, /* n_components */
1, /* count */
pixel_step);
}
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
return TRUE;
}
else
return FALSE;
}
static void
clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect)
{
ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect);
guint8 paint_opacity;
paint_opacity = clutter_actor_get_paint_opacity (self->actor);
cogl_pipeline_set_color4ub (self->pipeline,
paint_opacity,
paint_opacity,
paint_opacity,
paint_opacity);
cogl_push_source (self->pipeline);
cogl_rectangle (0, 0, self->tex_width, self->tex_height);
cogl_pop_source ();
}
static gboolean
clutter_blur_effect_get_paint_volume (ClutterEffect *effect,
ClutterPaintVolume *volume)
{
gfloat cur_width, cur_height;
ClutterVertex 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);
if (self->pipeline != NULL)
{
cogl_object_unref (self->pipeline);
self->pipeline = NULL;
}
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->pre_paint = clutter_blur_effect_pre_paint;
effect_class->get_paint_volume = clutter_blur_effect_get_paint_volume;
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
offscreen_class->paint_target = clutter_blur_effect_paint_target;
}
static void
clutter_blur_effect_init (ClutterBlurEffect *self)
{
ClutterBlurEffectClass *klass = CLUTTER_BLUR_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_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);
cogl_object_unref (snippet);
cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
0, /* layer number */
COGL_TEXTURE_TYPE_2D);
}
self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
self->pixel_step_uniform =
cogl_pipeline_get_uniform_location (self->pipeline, "pixel_step");
}
/**
* clutter_blur_effect_new:
*
* Creates a new #ClutterBlurEffect to be used with
* clutter_actor_add_effect()
*
* Return value: the newly created #ClutterBlurEffect or %NULL
*
* Since: 1.4
*/
ClutterEffect *
clutter_blur_effect_new (void)
{
return g_object_new (CLUTTER_TYPE_BLUR_EFFECT, NULL);
}

View File

@ -0,0 +1,59 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_BLUR_EFFECT_H__
#define __CLUTTER_BLUR_EFFECT_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-effect.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_BLUR_EFFECT (clutter_blur_effect_get_type ())
#define CLUTTER_BLUR_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BLUR_EFFECT, ClutterBlurEffect))
#define CLUTTER_IS_BLUR_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BLUR_EFFECT))
/**
* ClutterBlurEffect:
*
* #ClutterBlurEffect is an opaque structure
* whose members cannot be accessed directly
*
* Since: 1.4
*/
typedef struct _ClutterBlurEffect ClutterBlurEffect;
typedef struct _ClutterBlurEffectClass ClutterBlurEffectClass;
CLUTTER_AVAILABLE_IN_1_4
GType clutter_blur_effect_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_4
ClutterEffect *clutter_blur_effect_new (void);
G_END_DECLS
#endif /* __CLUTTER_BLUR_EFFECT_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,168 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2009 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*
* Based on the NBTK NbtkBoxLayout actor by:
* Thomas Wood <thomas.wood@intel.com>
*/
#ifndef __CLUTTER_BOX_LAYOUT_H__
#define __CLUTTER_BOX_LAYOUT_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-layout-manager.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_BOX_LAYOUT (clutter_box_layout_get_type ())
#define CLUTTER_BOX_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BOX_LAYOUT, ClutterBoxLayout))
#define CLUTTER_IS_BOX_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BOX_LAYOUT))
#define CLUTTER_BOX_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BOX_LAYOUT, ClutterBoxLayoutClass))
#define CLUTTER_IS_BOX_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BOX_LAYOUT))
#define CLUTTER_BOX_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BOX_LAYOUT, ClutterBoxLayoutClass))
typedef struct _ClutterBoxLayout ClutterBoxLayout;
typedef struct _ClutterBoxLayoutPrivate ClutterBoxLayoutPrivate;
typedef struct _ClutterBoxLayoutClass ClutterBoxLayoutClass;
/**
* ClutterBoxLayout:
*
* The #ClutterBoxLayout structure contains only private data
* and should be accessed using the provided API
*
* Since: 1.2
*/
struct _ClutterBoxLayout
{
/*< private >*/
ClutterLayoutManager parent_instance;
ClutterBoxLayoutPrivate *priv;
};
/**
* ClutterBoxLayoutClass:
*
* The #ClutterBoxLayoutClass structure contains only private
* data and should be accessed using the provided API
*
* Since: 1.2
*/
struct _ClutterBoxLayoutClass
{
/*< private >*/
ClutterLayoutManagerClass parent_class;
};
CLUTTER_AVAILABLE_IN_1_2
GType clutter_box_layout_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_2
ClutterLayoutManager * clutter_box_layout_new (void);
CLUTTER_AVAILABLE_IN_1_12
void clutter_box_layout_set_orientation (ClutterBoxLayout *layout,
ClutterOrientation orientation);
CLUTTER_AVAILABLE_IN_1_12
ClutterOrientation clutter_box_layout_get_orientation (ClutterBoxLayout *layout);
CLUTTER_AVAILABLE_IN_1_2
void clutter_box_layout_set_spacing (ClutterBoxLayout *layout,
guint spacing);
CLUTTER_AVAILABLE_IN_1_2
guint clutter_box_layout_get_spacing (ClutterBoxLayout *layout);
CLUTTER_AVAILABLE_IN_1_2
void clutter_box_layout_set_homogeneous (ClutterBoxLayout *layout,
gboolean homogeneous);
CLUTTER_AVAILABLE_IN_1_2
gboolean clutter_box_layout_get_homogeneous (ClutterBoxLayout *layout);
CLUTTER_AVAILABLE_IN_1_2
void clutter_box_layout_set_pack_start (ClutterBoxLayout *layout,
gboolean pack_start);
CLUTTER_AVAILABLE_IN_1_2
gboolean clutter_box_layout_get_pack_start (ClutterBoxLayout *layout);
CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_box_layout_set_orientation)
void clutter_box_layout_set_vertical (ClutterBoxLayout *layout,
gboolean vertical);
CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_box_layout_get_orientation)
gboolean clutter_box_layout_get_vertical (ClutterBoxLayout *layout);
CLUTTER_AVAILABLE_IN_1_2
void clutter_box_layout_pack (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean expand,
gboolean x_fill,
gboolean y_fill,
ClutterBoxAlignment x_align,
ClutterBoxAlignment y_align);
CLUTTER_DEPRECATED_IN_1_12
void clutter_box_layout_set_alignment (ClutterBoxLayout *layout,
ClutterActor *actor,
ClutterBoxAlignment x_align,
ClutterBoxAlignment y_align);
CLUTTER_DEPRECATED_IN_1_12
void clutter_box_layout_get_alignment (ClutterBoxLayout *layout,
ClutterActor *actor,
ClutterBoxAlignment *x_align,
ClutterBoxAlignment *y_align);
CLUTTER_DEPRECATED_IN_1_12
void clutter_box_layout_set_fill (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean x_fill,
gboolean y_fill);
CLUTTER_DEPRECATED_IN_1_12
void clutter_box_layout_get_fill (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean *x_fill,
gboolean *y_fill);
CLUTTER_DEPRECATED_IN_1_12
void clutter_box_layout_set_expand (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean expand);
CLUTTER_DEPRECATED_IN_1_12
gboolean clutter_box_layout_get_expand (ClutterBoxLayout *layout,
ClutterActor *actor);
CLUTTER_DEPRECATED_IN_1_12
void clutter_box_layout_set_use_animations (ClutterBoxLayout *layout,
gboolean animate);
CLUTTER_DEPRECATED_IN_1_12
gboolean clutter_box_layout_get_use_animations (ClutterBoxLayout *layout);
CLUTTER_DEPRECATED_IN_1_12
void clutter_box_layout_set_easing_mode (ClutterBoxLayout *layout,
gulong mode);
CLUTTER_DEPRECATED_IN_1_12
gulong clutter_box_layout_get_easing_mode (ClutterBoxLayout *layout);
CLUTTER_DEPRECATED_IN_1_12
void clutter_box_layout_set_easing_duration (ClutterBoxLayout *layout,
guint msecs);
CLUTTER_DEPRECATED_IN_1_12
guint clutter_box_layout_get_easing_duration (ClutterBoxLayout *layout);
G_END_DECLS
#endif /* __CLUTTER_BOX_LAYOUT_H__ */

View File

@ -0,0 +1,657 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010-2012 Inclusive Design Research Centre, OCAD University.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Joseph Scheuhammer <clown@alum.mit.edu>
*/
/**
* SECTION:clutter-brightness-contrast-effect
* @short_description: Increase/decrease brightness and/or contrast of actor.
* @see_also: #ClutterEffect, #ClutterOffscreenEffect
*
* #ClutterBrightnessContrastEffect is a sub-class of #ClutterEffect that
* changes the overall brightness of a #ClutterActor.
*
* #ClutterBrightnessContrastEffect is available since Clutter 1.10
*/
#define CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT, ClutterBrightnessContrastEffectClass))
#define CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT))
#define CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT, ClutterBrightnessContrastEffectClass))
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-brightness-contrast-effect.h"
#include <cogl/cogl.h>
#include "clutter-debug.h"
#include "clutter-enum-types.h"
#include "clutter-offscreen-effect.h"
#include "clutter-private.h"
struct _ClutterBrightnessContrastEffect
{
ClutterOffscreenEffect parent_instance;
/* Brightness and contrast changes. */
gfloat brightness_red;
gfloat brightness_green;
gfloat brightness_blue;
gfloat contrast_red;
gfloat contrast_green;
gfloat contrast_blue;
gint brightness_multiplier_uniform;
gint brightness_offset_uniform;
gint contrast_uniform;
gint tex_width;
gint tex_height;
CoglPipeline *pipeline;
};
struct _ClutterBrightnessContrastEffectClass
{
ClutterOffscreenEffectClass parent_class;
CoglPipeline *base_pipeline;
};
/* 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 (ClutterBrightnessContrastEffect,
clutter_brightness_contrast_effect,
CLUTTER_TYPE_OFFSCREEN_EFFECT);
static gboolean
will_have_no_effect (ClutterBrightnessContrastEffect *self)
{
return (self->brightness_red == no_change &&
self->brightness_green == no_change &&
self->brightness_blue == no_change &&
self->contrast_red == no_change &&
self->contrast_green == no_change &&
self->contrast_blue == no_change);
}
static gboolean
clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect)
{
ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
ClutterEffectClass *parent_class;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
return FALSE;
if (will_have_no_effect (self))
return FALSE;
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
{
/* if we don't have support for GLSL shaders then we
* forcibly disable the ActorMeta
*/
g_warning ("Unable to use the ClutterBrightnessContrastEffect: the "
"graphics hardware or the current GL driver does not "
"implement support for the GLSL shading language. The "
"effect will be disabled.");
clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
return FALSE;
}
parent_class =
CLUTTER_EFFECT_CLASS (clutter_brightness_contrast_effect_parent_class);
if (parent_class->pre_paint (effect))
{
ClutterOffscreenEffect *offscreen_effect =
CLUTTER_OFFSCREEN_EFFECT (effect);
CoglHandle texture;
texture = clutter_offscreen_effect_get_texture (offscreen_effect);
self->tex_width = cogl_texture_get_width (texture);
self->tex_height = cogl_texture_get_height (texture);
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
return TRUE;
}
else
return FALSE;
}
static void
clutter_brightness_contrast_effect_paint_target (ClutterOffscreenEffect *effect)
{
ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
ClutterActor *actor;
guint8 paint_opacity;
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
paint_opacity = clutter_actor_get_paint_opacity (actor);
cogl_pipeline_set_color4ub (self->pipeline,
paint_opacity,
paint_opacity,
paint_opacity,
paint_opacity);
cogl_push_source (self->pipeline);
cogl_rectangle (0, 0, self->tex_width, self->tex_height);
cogl_pop_source ();
}
static void
clutter_brightness_contrast_effect_dispose (GObject *gobject)
{
ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (gobject);
if (self->pipeline != NULL)
{
cogl_object_unref (self->pipeline);
self->pipeline = NULL;
}
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);
ClutterColor color;
switch (prop_id)
{
case PROP_BRIGHTNESS:
{
color.red = (effect->brightness_red + 1.0f) * 127.0f;
color.green = (effect->brightness_green + 1.0f) * 127.0f;
color.blue = (effect->brightness_blue + 1.0f) * 127.0f;
color.alpha = 0xff;
clutter_value_set_color (value, &color);
}
break;
case PROP_CONTRAST:
{
color.red = (effect->contrast_red + 1.0f) * 127.0f;
color.green = (effect->contrast_green + 1.0f) * 127.0f;
color.blue = (effect->contrast_blue + 1.0f) * 127.0f;
color.alpha = 0xff;
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->paint_target = clutter_brightness_contrast_effect_paint_target;
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.
*
* Since: 1.10
*/
obj_props[PROP_BRIGHTNESS] =
clutter_param_spec_color ("brightness",
P_("Brightness"),
P_("The brightness change to apply"),
&no_brightness_change,
CLUTTER_PARAM_READWRITE);
/**
* ClutterBrightnessContrastEffect:contrast:
*
* The contrast change to apply to the effect.
*
* This property uses a #ClutterColor to represent the changes to each
* color channel. The range is [ 0, 255 ], with 127 as the value used
* to indicate no change; values smaller than 127 indicate a decrease
* in contrast, and values larger than 127 indicate an increase in
* contrast.
*
* Since: 1.10
*/
obj_props[PROP_CONTRAST] =
clutter_param_spec_color ("contrast",
P_("Contrast"),
P_("The contrast change to apply"),
&no_contrast_change,
CLUTTER_PARAM_READWRITE);
g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
}
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)
{
if (self->brightness_multiplier_uniform > -1 &&
self->brightness_offset_uniform > -1)
{
float brightness_multiplier[3];
float brightness_offset[3];
get_brightness_values (self->brightness_red,
brightness_multiplier + 0,
brightness_offset + 0);
get_brightness_values (self->brightness_green,
brightness_multiplier + 1,
brightness_offset + 1);
get_brightness_values (self->brightness_blue,
brightness_multiplier + 2,
brightness_offset + 2);
cogl_pipeline_set_uniform_float (self->pipeline,
self->brightness_multiplier_uniform,
3, /* n_components */
1, /* count */
brightness_multiplier);
cogl_pipeline_set_uniform_float (self->pipeline,
self->brightness_offset_uniform,
3, /* n_components */
1, /* count */
brightness_offset);
}
if (self->contrast_uniform > -1)
{
float contrast[3] = {
tan ((self->contrast_red + 1) * G_PI_4),
tan ((self->contrast_green + 1) * G_PI_4),
tan ((self->contrast_blue + 1) * G_PI_4)
};
cogl_pipeline_set_uniform_float (self->pipeline,
self->contrast_uniform,
3, /* n_components */
1, /* count */
contrast);
}
}
static void
clutter_brightness_contrast_effect_init (ClutterBrightnessContrastEffect *self)
{
ClutterBrightnessContrastEffectClass *klass;
self->brightness_red = no_change;
self->brightness_green = no_change;
self->brightness_blue = no_change;
self->contrast_red = no_change;
self->contrast_green = no_change;
self->contrast_blue = no_change;
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);
cogl_object_unref (snippet);
cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
0, /* layer number */
COGL_TEXTURE_TYPE_2D);
}
self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
self->brightness_multiplier_uniform =
cogl_pipeline_get_uniform_location (self->pipeline,
"brightness_multiplier");
self->brightness_offset_uniform =
cogl_pipeline_get_uniform_location (self->pipeline,
"brightness_offset");
self->contrast_uniform =
cogl_pipeline_get_uniform_location (self->pipeline, "contrast");
update_uniforms (self);
}
/**
* clutter_brightness_contrast_effect_new:
*
* Creates a new #ClutterBrightnessContrastEffect to be used with
* clutter_actor_add_effect()
*
* Return value: (transfer full): the newly created
* #ClutterBrightnessContrastEffect or %NULL. Use g_object_unref() when
* done.
*
* Since: 1.10
*/
ClutterEffect *
clutter_brightness_contrast_effect_new (void)
{
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.
*
* Since: 1.10
*/
void
clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContrastEffect *effect,
gfloat red,
gfloat green,
gfloat blue)
{
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
if (red == effect->brightness_red &&
green == effect->brightness_green &&
blue == effect->brightness_blue)
return;
effect->brightness_red = red;
effect->brightness_green = green;
effect->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.
*
* Since: 1.10
*/
void
clutter_brightness_contrast_effect_get_brightness (ClutterBrightnessContrastEffect *effect,
gfloat *red,
gfloat *green,
gfloat *blue)
{
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
if (red != NULL)
*red = effect->brightness_red;
if (green != NULL)
*green = effect->brightness_green;
if (blue != NULL)
*blue = effect->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.
*
* Since: 1.10
*/
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.
*
* Since: 1.10
*/
void
clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastEffect *effect,
gfloat red,
gfloat green,
gfloat blue)
{
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
if (red == effect->contrast_red &&
green == effect->contrast_green &&
blue == effect->contrast_blue)
return;
effect->contrast_red = red;
effect->contrast_green = green;
effect->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.
*
* Since: 1.10
*/
void
clutter_brightness_contrast_effect_get_contrast (ClutterBrightnessContrastEffect *effect,
gfloat *red,
gfloat *green,
gfloat *blue)
{
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
if (red != NULL)
*red = effect->contrast_red;
if (green != NULL)
*green = effect->contrast_green;
if (blue != NULL)
*blue = effect->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.
*
* Since: 1.10
*/
void
clutter_brightness_contrast_effect_set_contrast (ClutterBrightnessContrastEffect *effect,
gfloat contrast)
{
clutter_brightness_contrast_effect_set_contrast_full (effect,
contrast,
contrast,
contrast);
}

View File

@ -0,0 +1,88 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010-2012 Inclusive Design Research Centre, OCAD University.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Joseph Scheuhammer <clown@alum.mit.edu>
*/
#ifndef __CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_H__
#define __CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-color.h>
#include <clutter/clutter-effect.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT (clutter_brightness_contrast_effect_get_type ())
#define CLUTTER_BRIGHTNESS_CONTRAST_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT, ClutterBrightnessContrastEffect))
#define CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT))
/**
* ClutterBrightnessContrastEffect:
*
* #ClutterBrightnessContrastEffect is an opaque structure
* whose members cannot be directly accessed
*
* Since: 1.10
*/
typedef struct _ClutterBrightnessContrastEffect ClutterBrightnessContrastEffect;
typedef struct _ClutterBrightnessContrastEffectClass ClutterBrightnessContrastEffectClass;
CLUTTER_AVAILABLE_IN_1_10
GType clutter_brightness_contrast_effect_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_10
ClutterEffect * clutter_brightness_contrast_effect_new (void);
CLUTTER_AVAILABLE_IN_1_10
void clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContrastEffect *effect,
float red,
float green,
float blue);
CLUTTER_AVAILABLE_IN_1_10
void clutter_brightness_contrast_effect_set_brightness (ClutterBrightnessContrastEffect *effect,
float brightness);
CLUTTER_AVAILABLE_IN_1_10
void clutter_brightness_contrast_effect_get_brightness (ClutterBrightnessContrastEffect *effect,
float *red,
float *green,
float *blue);
CLUTTER_AVAILABLE_IN_1_10
void clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastEffect *effect,
float red,
float green,
float blue);
CLUTTER_AVAILABLE_IN_1_10
void clutter_brightness_contrast_effect_set_contrast (ClutterBrightnessContrastEffect *effect,
float contrast);
CLUTTER_AVAILABLE_IN_1_10
void clutter_brightness_contrast_effect_get_contrast (ClutterBrightnessContrastEffect *effect,
float *red,
float *green,
float *blue);
G_END_DECLS
#endif /* __CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_H__ */

View File

@ -0,0 +1,92 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2012 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* SECTION:clutter-cairo
* @Title: Cairo integration
* @Short_Description: Functions for interoperating with Cairo
*
* Clutter provides some utility functions for using Cairo.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-cairo.h"
#include "clutter-color.h"
/**
* clutter_cairo_set_source_color:
* @cr: a Cairo context
* @color: a #ClutterColor
*
* Utility function for setting the source color of @cr using
* a #ClutterColor. This function is the equivalent of:
*
* |[
* cairo_set_source_rgba (cr,
* color->red / 255.0,
* color->green / 255.0,
* color->blue / 255.0,
* color->alpha / 255.0);
* ]|
*
* Since: 1.0
*/
void
clutter_cairo_set_source_color (cairo_t *cr,
const ClutterColor *color)
{
g_return_if_fail (cr != NULL);
g_return_if_fail (color != NULL);
if (color->alpha == 0xff)
cairo_set_source_rgb (cr,
color->red / 255.0,
color->green / 255.0,
color->blue / 255.0);
else
cairo_set_source_rgba (cr,
color->red / 255.0,
color->green / 255.0,
color->blue / 255.0,
color->alpha / 255.0);
}
/**
* clutter_cairo_clear:
* @cr: a Cairo context
*
* Utility function to clear a Cairo context.
*
* Since: 1.12
*/
void
clutter_cairo_clear (cairo_t *cr)
{
cairo_save (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
cairo_paint (cr);
cairo_restore (cr);
}

View File

@ -0,0 +1,61 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2012 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CLUTTER_CAIRO_H__
#define __CLUTTER_CAIRO_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-types.h>
G_BEGIN_DECLS
/**
* CLUTTER_CAIRO_FORMAT_ARGB32:
*
* The #CoglPixelFormat to be used when uploading image data from
* and to a Cairo image surface using %CAIRO_FORMAT_ARGB32 and
* %CAIRO_FORMAT_RGB24 as #cairo_format_t.
*
* Since: 1.8
*/
/* Cairo stores the data in native byte order as ARGB but Cogl's pixel
* formats specify the actual byte order. Therefore we need to use a
* different format depending on the architecture
*/
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
#define CLUTTER_CAIRO_FORMAT_ARGB32 (COGL_PIXEL_FORMAT_BGRA_8888_PRE)
#else
#define CLUTTER_CAIRO_FORMAT_ARGB32 (COGL_PIXEL_FORMAT_ARGB_8888_PRE)
#endif
CLUTTER_AVAILABLE_IN_1_12
void clutter_cairo_clear (cairo_t *cr);
CLUTTER_AVAILABLE_IN_1_0
void clutter_cairo_set_source_color (cairo_t *cr,
const ClutterColor *color);
G_END_DECLS
#endif /* __CLUTTER_CAIRO_H__ */

View File

@ -0,0 +1,716 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2012 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-canvas
* @Title: ClutterCanvas
* @Short_Description: Content for 2D painting
* @See_Also: #ClutterContent
*
* The #ClutterCanvas class is a #ClutterContent implementation that allows
* drawing using the Cairo API on a 2D surface.
*
* In order to draw on a #ClutterCanvas, you should connect a handler to the
* #ClutterCanvas::draw signal; the signal will receive a #cairo_t context
* that can be used to draw. #ClutterCanvas will emit the #ClutterCanvas::draw
* signal when invalidated using clutter_content_invalidate().
*
* See [canvas.c](https://git.gnome.org/browse/clutter/tree/examples/canvas.c?h=clutter-1.18)
* for an example of how to use #ClutterCanvas.
*
* #ClutterCanvas is available since Clutter 1.10.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <cogl/cogl.h>
#include <cairo-gobject.h>
#include "clutter-canvas.h"
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-actor-private.h"
#include "clutter-backend.h"
#include "clutter-cairo.h"
#include "clutter-color.h"
#include "clutter-content-private.h"
#include "clutter-debug.h"
#include "clutter-marshal.h"
#include "clutter-paint-node.h"
#include "clutter-paint-nodes.h"
#include "clutter-private.h"
#include "clutter-settings.h"
struct _ClutterCanvasPrivate
{
cairo_t *cr;
int width;
int height;
CoglTexture *texture;
gboolean dirty;
CoglBitmap *buffer;
int scale_factor;
guint scale_factor_set : 1;
};
enum
{
PROP_0,
PROP_WIDTH,
PROP_HEIGHT,
PROP_SCALE_FACTOR,
PROP_SCALE_FACTOR_SET,
LAST_PROP
};
static GParamSpec *obj_props[LAST_PROP] = { NULL, };
enum
{
DRAW,
LAST_SIGNAL
};
static guint canvas_signals[LAST_SIGNAL] = { 0, };
static void clutter_content_iface_init (ClutterContentIface *iface);
G_DEFINE_TYPE_WITH_CODE (ClutterCanvas, clutter_canvas, G_TYPE_OBJECT,
G_ADD_PRIVATE (ClutterCanvas)
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT,
clutter_content_iface_init))
static void
clutter_cairo_context_draw_marshaller (GClosure *closure,
GValue *return_value,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint,
gpointer marshal_data)
{
cairo_t *cr = g_value_get_boxed (&param_values[1]);
cairo_save (cr);
_clutter_marshal_BOOLEAN__BOXED_INT_INT (closure,
return_value,
n_param_values,
param_values,
invocation_hint,
marshal_data);
cairo_restore (cr);
}
static void
clutter_canvas_finalize (GObject *gobject)
{
ClutterCanvasPrivate *priv = CLUTTER_CANVAS (gobject)->priv;
if (priv->buffer != NULL)
{
cogl_object_unref (priv->buffer);
priv->buffer = NULL;
}
g_clear_pointer (&priv->texture, cogl_object_unref);
G_OBJECT_CLASS (clutter_canvas_parent_class)->finalize (gobject);
}
static void
clutter_canvas_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterCanvasPrivate *priv = CLUTTER_CANVAS (gobject)->priv;
switch (prop_id)
{
case PROP_WIDTH:
{
gint new_size = g_value_get_int (value);
if (priv->width != new_size)
{
priv->width = new_size;
clutter_content_invalidate (CLUTTER_CONTENT (gobject));
}
}
break;
case PROP_HEIGHT:
{
gint new_size = g_value_get_int (value);
if (priv->height != new_size)
{
priv->height = new_size;
clutter_content_invalidate (CLUTTER_CONTENT (gobject));
}
}
break;
case PROP_SCALE_FACTOR:
clutter_canvas_set_scale_factor (CLUTTER_CANVAS (gobject),
g_value_get_int (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_canvas_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterCanvasPrivate *priv = CLUTTER_CANVAS (gobject)->priv;
switch (prop_id)
{
case PROP_WIDTH:
g_value_set_int (value, priv->width);
break;
case PROP_HEIGHT:
g_value_set_int (value, priv->height);
break;
case PROP_SCALE_FACTOR:
if (priv->scale_factor_set)
g_value_set_int (value, priv->scale_factor);
else
g_value_set_int (value, -1);
break;
case PROP_SCALE_FACTOR_SET:
g_value_set_boolean (value, priv->scale_factor_set);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_canvas_class_init (ClutterCanvasClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
/**
* ClutterCanvas:width:
*
* The width of the canvas.
*
* Since: 1.10
*/
obj_props[PROP_WIDTH] =
g_param_spec_int ("width",
P_("Width"),
P_("The width of the canvas"),
-1, G_MAXINT,
-1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/**
* ClutterCanvas:height:
*
* The height of the canvas.
*
* Since: 1.10
*/
obj_props[PROP_HEIGHT] =
g_param_spec_int ("height",
P_("Height"),
P_("The height of the canvas"),
-1, G_MAXINT,
-1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/**
* ClutterCanvas:scale-factor-set:
*
* Whether the #ClutterCanvas:scale-factor property is set.
*
* If the #ClutterCanvas:scale-factor-set property is %FALSE
* then #ClutterCanvas will use the #ClutterSettings:window-scaling-factor
* property.
*
* Since: 1.18
*/
obj_props[PROP_SCALE_FACTOR_SET] =
g_param_spec_boolean ("scale-factor-set",
P_("Scale Factor Set"),
P_("Whether the scale-factor property is set"),
FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* ClutterCanvas:scale-factor:
*
* The scaling factor to be applied to the Cairo surface used for
* drawing.
*
* If #ClutterCanvas:scale-factor is set to a negative value, the
* value of the #ClutterSettings:window-scaling-factor property is
* used instead.
*
* Use #ClutterCanvas:scale-factor-set to check if the scale factor
* is set.
*
* Since: 1.18
*/
obj_props[PROP_SCALE_FACTOR] =
g_param_spec_int ("scale-factor",
P_("Scale Factor"),
P_("The scaling factor for the surface"),
-1, 1000,
-1,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
/**
* ClutterCanvas::draw:
* @canvas: the #ClutterCanvas that emitted the signal
* @cr: the Cairo context used to draw
* @width: the width of the @canvas
* @height: the height of the @canvas
*
* The #ClutterCanvas::draw signal is emitted each time a canvas is
* invalidated.
*
* It is safe to connect multiple handlers to this signal: each
* handler invocation will be automatically protected by cairo_save()
* and cairo_restore() pairs.
*
* Return value: %TRUE if the signal emission should stop, and
* %FALSE otherwise
*
* Since: 1.10
*/
canvas_signals[DRAW] =
g_signal_new (I_("draw"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
G_STRUCT_OFFSET (ClutterCanvasClass, draw),
_clutter_boolean_handled_accumulator, NULL,
clutter_cairo_context_draw_marshaller,
G_TYPE_BOOLEAN, 3,
CAIRO_GOBJECT_TYPE_CONTEXT,
G_TYPE_INT,
G_TYPE_INT);
gobject_class->set_property = clutter_canvas_set_property;
gobject_class->get_property = clutter_canvas_get_property;
gobject_class->finalize = clutter_canvas_finalize;
g_object_class_install_properties (gobject_class, LAST_PROP, obj_props);
}
static void
clutter_canvas_init (ClutterCanvas *self)
{
self->priv = clutter_canvas_get_instance_private (self);
self->priv->width = -1;
self->priv->height = -1;
self->priv->scale_factor = -1;
}
static void
clutter_canvas_paint_content (ClutterContent *content,
ClutterActor *actor,
ClutterPaintNode *root)
{
ClutterCanvas *self = CLUTTER_CANVAS (content);
ClutterCanvasPrivate *priv = self->priv;
ClutterPaintNode *node;
if (priv->buffer == NULL)
return;
if (priv->dirty)
g_clear_pointer (&priv->texture, cogl_object_unref);
if (priv->texture == NULL)
priv->texture = cogl_texture_new_from_bitmap (priv->buffer,
COGL_TEXTURE_NO_SLICING,
CLUTTER_CAIRO_FORMAT_ARGB32);
if (priv->texture == NULL)
return;
node = clutter_actor_create_texture_paint_node (actor, priv->texture);
clutter_paint_node_set_name (node, "Canvas Content");
clutter_paint_node_add_child (root, node);
clutter_paint_node_unref (node);
priv->dirty = FALSE;
}
static void
clutter_canvas_emit_draw (ClutterCanvas *self)
{
ClutterCanvasPrivate *priv = self->priv;
int real_width, real_height;
cairo_surface_t *surface;
gboolean mapped_buffer;
unsigned char *data;
CoglBuffer *buffer;
int window_scale = 1;
gboolean res;
cairo_t *cr;
g_assert (priv->width > 0 && priv->width > 0);
priv->dirty = TRUE;
if (priv->scale_factor_set)
window_scale = priv->scale_factor;
else
g_object_get (clutter_settings_get_default (),
"window-scaling-factor", &window_scale,
NULL);
real_width = priv->width * window_scale;
real_height = priv->height * window_scale;
CLUTTER_NOTE (MISC, "Creating Cairo surface with size %d x %d (real: %d x %d, scale: %d)",
priv->width, priv->height,
real_width, real_height,
window_scale);
if (priv->buffer == NULL)
{
CoglContext *ctx;
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
priv->buffer = cogl_bitmap_new_with_size (ctx,
real_width,
real_height,
CLUTTER_CAIRO_FORMAT_ARGB32);
}
buffer = COGL_BUFFER (cogl_bitmap_get_buffer (priv->buffer));
if (buffer == NULL)
return;
cogl_buffer_set_update_hint (buffer, COGL_BUFFER_UPDATE_HINT_DYNAMIC);
data = cogl_buffer_map (buffer,
COGL_BUFFER_ACCESS_READ_WRITE,
COGL_BUFFER_MAP_HINT_DISCARD);
if (data != NULL)
{
int bitmap_stride = cogl_bitmap_get_rowstride (priv->buffer);
surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
real_width,
real_height,
bitmap_stride);
mapped_buffer = TRUE;
}
else
{
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
real_width,
real_height);
mapped_buffer = FALSE;
}
cairo_surface_set_device_scale (surface, window_scale, window_scale);
self->priv->cr = cr = cairo_create (surface);
g_signal_emit (self, canvas_signals[DRAW], 0,
cr, priv->width, priv->height,
&res);
#ifdef CLUTTER_ENABLE_DEBUG
if (_clutter_diagnostic_enabled () && cairo_status (cr))
{
g_warning ("Drawing failed for <ClutterCanvas>[%p]: %s",
self,
cairo_status_to_string (cairo_status (cr)));
}
#endif
self->priv->cr = NULL;
cairo_destroy (cr);
if (mapped_buffer)
cogl_buffer_unmap (buffer);
else
{
int size = cairo_image_surface_get_stride (surface) * priv->height;
cogl_buffer_set_data (buffer,
0,
cairo_image_surface_get_data (surface),
size);
}
cairo_surface_destroy (surface);
}
static void
clutter_canvas_invalidate (ClutterContent *content)
{
ClutterCanvas *self = CLUTTER_CANVAS (content);
ClutterCanvasPrivate *priv = self->priv;
if (priv->buffer != NULL)
{
cogl_object_unref (priv->buffer);
priv->buffer = NULL;
}
if (priv->width <= 0 || priv->height <= 0)
return;
clutter_canvas_emit_draw (self);
}
static gboolean
clutter_canvas_get_preferred_size (ClutterContent *content,
gfloat *width,
gfloat *height)
{
ClutterCanvasPrivate *priv = CLUTTER_CANVAS (content)->priv;
if (priv->width < 0 || priv->height < 0)
return FALSE;
if (width != NULL)
*width = priv->width;
if (height != NULL)
*height = priv->height;
return TRUE;
}
static void
clutter_content_iface_init (ClutterContentIface *iface)
{
iface->invalidate = clutter_canvas_invalidate;
iface->paint_content = clutter_canvas_paint_content;
iface->get_preferred_size = clutter_canvas_get_preferred_size;
}
/**
* clutter_canvas_new:
*
* Creates a new instance of #ClutterCanvas.
*
* You should call clutter_canvas_set_size() to set the size of the canvas.
*
* You should call clutter_content_invalidate() every time you wish to
* draw the contents of the canvas.
*
* Return value: (transfer full): The newly allocated instance of
* #ClutterCanvas. Use g_object_unref() when done.
*
* Since: 1.10
*/
ClutterContent *
clutter_canvas_new (void)
{
return g_object_new (CLUTTER_TYPE_CANVAS, NULL);
}
static gboolean
clutter_canvas_invalidate_internal (ClutterCanvas *canvas,
int width,
int height)
{
gboolean width_changed = FALSE, height_changed = FALSE;
gboolean res = FALSE;
GObject *obj;
obj = G_OBJECT (canvas);
g_object_freeze_notify (obj);
if (canvas->priv->width != width)
{
canvas->priv->width = width;
width_changed = TRUE;
g_object_notify_by_pspec (obj, obj_props[PROP_WIDTH]);
}
if (canvas->priv->height != height)
{
canvas->priv->height = height;
height_changed = TRUE;
g_object_notify_by_pspec (obj, obj_props[PROP_HEIGHT]);
}
if (width_changed || height_changed)
{
clutter_content_invalidate (CLUTTER_CONTENT (canvas));
res = TRUE;
}
g_object_thaw_notify (obj);
return res;
}
/**
* clutter_canvas_set_size:
* @canvas: a #ClutterCanvas
* @width: the width of the canvas, in pixels
* @height: the height of the canvas, in pixels
*
* Sets the size of the @canvas, and invalidates the content.
*
* This function will cause the @canvas to be invalidated only
* if the size of the canvas surface has changed.
*
* If you want to invalidate the contents of the @canvas when setting
* the size, you can use the return value of the function to conditionally
* call clutter_content_invalidate():
*
* |[
* if (!clutter_canvas_set_size (canvas, width, height))
* clutter_content_invalidate (CLUTTER_CONTENT (canvas));
* ]|
*
* Return value: this function returns %TRUE if the size change
* caused a content invalidation, and %FALSE otherwise
*
* Since: 1.10
*/
gboolean
clutter_canvas_set_size (ClutterCanvas *canvas,
int width,
int height)
{
g_return_val_if_fail (CLUTTER_IS_CANVAS (canvas), FALSE);
g_return_val_if_fail (width >= -1 && height >= -1, FALSE);
return clutter_canvas_invalidate_internal (canvas, width, height);
}
/**
* clutter_canvas_set_scale_factor:
* @canvas: a #ClutterCanvas
* @scale: the scale factor, or -1 for the default
*
* Sets the scaling factor for the Cairo surface used by @canvas.
*
* This function should rarely be used.
*
* The default scaling factor of a #ClutterCanvas content uses the
* #ClutterSettings:window-scaling-factor property, which is set by
* the windowing system. By using this function it is possible to
* override that setting.
*
* Changing the scale factor will invalidate the @canvas.
*
* Since: 1.18
*/
void
clutter_canvas_set_scale_factor (ClutterCanvas *canvas,
int scale)
{
ClutterCanvasPrivate *priv;
GObject *obj;
g_return_if_fail (CLUTTER_IS_CANVAS (canvas));
g_return_if_fail (scale != 0);
priv = canvas->priv;
if (scale < 0)
{
if (!priv->scale_factor_set)
return;
priv->scale_factor_set = FALSE;
priv->scale_factor = -1;
}
else
{
if (priv->scale_factor_set && priv->scale_factor == scale)
return;
priv->scale_factor_set = TRUE;
priv->scale_factor = scale;
}
clutter_content_invalidate (CLUTTER_CONTENT (canvas));
obj = G_OBJECT (canvas);
g_object_notify_by_pspec (obj, obj_props[PROP_SCALE_FACTOR]);
g_object_notify_by_pspec (obj, obj_props[PROP_SCALE_FACTOR_SET]);
}
/**
* clutter_canvas_get_scale_factor:
* @canvas: a #ClutterCanvas
*
* Retrieves the scaling factor of @canvas, as set using
* clutter_canvas_set_scale_factor().
*
* Return value: the scaling factor, or -1 if the @canvas
* uses the default from #ClutterSettings
*
* Since: 1.18
*/
int
clutter_canvas_get_scale_factor (ClutterCanvas *canvas)
{
g_return_val_if_fail (CLUTTER_IS_CANVAS (canvas), -1);
if (!canvas->priv->scale_factor_set)
return -1;
return canvas->priv->scale_factor;
}

View File

@ -0,0 +1,106 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2012 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_CANVAS_H__
#define __CLUTTER_CANVAS_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-types.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_CANVAS (clutter_canvas_get_type ())
#define CLUTTER_CANVAS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CANVAS, ClutterCanvas))
#define CLUTTER_IS_CANVAS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CANVAS))
#define CLUTTER_CANVAS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CANVAS, ClutterCanvasClass))
#define CLUTTER_IS_CANVAS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CANVAS))
#define CLUTTER_CANVAS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CANVAS, ClutterCanvasClass))
typedef struct _ClutterCanvas ClutterCanvas;
typedef struct _ClutterCanvasPrivate ClutterCanvasPrivate;
typedef struct _ClutterCanvasClass ClutterCanvasClass;
/**
* ClutterCanvas:
*
* The #ClutterCanvas structure contains
* private data and should only be accessed using the provided
* API.
*
* Since: 1.10
*/
struct _ClutterCanvas
{
/*< private >*/
GObject parent_instance;
ClutterCanvasPrivate *priv;
};
/**
* ClutterCanvasClass:
* @draw: class handler for the #ClutterCanvas::draw signal
*
* The #ClutterCanvasClass structure contains
* private data.
*
* Since: 1.10
*/
struct _ClutterCanvasClass
{
/*< private >*/
GObjectClass parent_class;
/*< public >*/
gboolean (* draw) (ClutterCanvas *canvas,
cairo_t *cr,
int width,
int height);
/*< private >*/
gpointer _padding[16];
};
CLUTTER_AVAILABLE_IN_1_10
GType clutter_canvas_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_10
ClutterContent * clutter_canvas_new (void);
CLUTTER_AVAILABLE_IN_1_10
gboolean clutter_canvas_set_size (ClutterCanvas *canvas,
int width,
int height);
CLUTTER_AVAILABLE_IN_1_18
void clutter_canvas_set_scale_factor (ClutterCanvas *canvas,
int scale);
CLUTTER_AVAILABLE_IN_1_18
int clutter_canvas_get_scale_factor (ClutterCanvas *canvas);
G_END_DECLS
#endif /* __CLUTTER_CANVAS_H__ */

View File

@ -0,0 +1,192 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
* Jorn Baayen <jorn@openedhand.com>
* Emmanuele Bassi <ebassi@openedhand.com>
* Tomas Frydrych <tf@openedhand.com>
* Øyvind Kolås <ok@openedhand.com>
*
* Copyright (C) 2008 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* SECTION:clutter-child-meta
* @short_description: Wrapper for actors inside a container
*
* #ClutterChildMeta is a wrapper object created by #ClutterContainer
* implementations in order to store child-specific data and properties.
*
* A #ClutterChildMeta wraps a #ClutterActor inside a #ClutterContainer.
*
* #ClutterChildMeta is available since Clutter 0.8
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-child-meta.h"
#include "clutter-container.h"
#include "clutter-debug.h"
#include "clutter-private.h"
G_DEFINE_ABSTRACT_TYPE (ClutterChildMeta, clutter_child_meta, G_TYPE_OBJECT);
enum
{
PROP_0,
PROP_CONTAINER,
PROP_ACTOR,
PROP_LAST
};
static GParamSpec *obj_props[PROP_LAST];
static void
clutter_child_meta_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterChildMeta *child_meta = CLUTTER_CHILD_META (object);
switch (prop_id)
{
case PROP_CONTAINER:
child_meta->container = g_value_get_object (value);
break;
case PROP_ACTOR:
child_meta->actor = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
clutter_child_meta_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterChildMeta *child_meta = CLUTTER_CHILD_META (object);
switch (prop_id)
{
case PROP_CONTAINER:
g_value_set_object (value, child_meta->container);
break;
case PROP_ACTOR:
g_value_set_object (value, child_meta->actor);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
clutter_child_meta_class_init (ClutterChildMetaClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->set_property = clutter_child_meta_set_property;
gobject_class->get_property = clutter_child_meta_get_property;
/**
* ClutterChildMeta:container:
*
* The #ClutterContainer that created this #ClutterChildMeta.
*
* Since: 0.8
*/
obj_props[PROP_CONTAINER] =
g_param_spec_object ("container",
P_("Container"),
P_("The container that created this data"),
CLUTTER_TYPE_CONTAINER,
G_PARAM_CONSTRUCT_ONLY |
CLUTTER_PARAM_READWRITE);
/**
* ClutterChildMeta:actor:
*
* The #ClutterActor being wrapped by this #ClutterChildMeta
*
* Since: 0.8
*/
obj_props[PROP_ACTOR] =
g_param_spec_object ("actor",
P_("Actor"),
P_("The actor wrapped by this data"),
CLUTTER_TYPE_ACTOR,
G_PARAM_CONSTRUCT_ONLY |
CLUTTER_PARAM_READWRITE);
g_object_class_install_properties (gobject_class,
PROP_LAST,
obj_props);
}
static void
clutter_child_meta_init (ClutterChildMeta *self)
{
}
/**
* clutter_child_meta_get_container:
* @data: a #ClutterChildMeta
*
* Retrieves the container using @data
*
* Return value: (transfer none): a #ClutterContainer
*
* Since: 0.8
*/
ClutterContainer *
clutter_child_meta_get_container (ClutterChildMeta *data)
{
g_return_val_if_fail (CLUTTER_IS_CHILD_META (data), NULL);
return data->container;
}
/**
* clutter_child_meta_get_actor:
* @data: a #ClutterChildMeta
*
* Retrieves the actor wrapped by @data
*
* Return value: (transfer none): a #ClutterActor
*
* Since: 0.8
*/
ClutterActor *
clutter_child_meta_get_actor (ClutterChildMeta *data)
{
g_return_val_if_fail (CLUTTER_IS_CHILD_META (data), NULL);
return data->actor;
}

View File

@ -0,0 +1,122 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
* Jorn Baayen <jorn@openedhand.com>
* Emmanuele Bassi <ebassi@openedhand.com>
* Tomas Frydrych <tf@openedhand.com>
* Øyvind Kolås <ok@openedhand.com>
*
* Copyright (C) 2008 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CLUTTER_CHILD_META_H__
#define __CLUTTER_CHILD_META_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <glib-object.h>
#include <clutter/clutter-types.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_CHILD_META (clutter_child_meta_get_type ())
#define CLUTTER_CHILD_META(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CHILD_META, ClutterChildMeta))
#define CLUTTER_CHILD_META_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CHILD_META, ClutterChildMetaClass))
#define CLUTTER_IS_CHILD_META(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CHILD_META))
#define CLUTTER_IS_CHILD_META_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CHILD_META))
#define CLUTTER_CHILD_META_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CHILD_META, ClutterChildMetaClass))
typedef struct _ClutterChildMetaClass ClutterChildMetaClass;
/**
* ClutterChildMeta:
* @container: the container handling this data
* @actor: the actor wrapped by this data
*
* Base interface for container specific state for child actors. A child
* data is meant to be used when you need to keep track of information
* about each individual child added to a container.
*
* In order to use it you should create your own subclass of
* #ClutterChildMeta and set the #ClutterContainerIface child_meta_type
* interface member to your subclass type, like:
*
* |[
* static void
* my_container_iface_init (ClutterContainerIface *iface)
* {
* // set the rest of the #ClutterContainer vtable
*
* container_iface->child_meta_type = MY_TYPE_CHILD_META;
* }
* ]|
*
* This will automatically create a #ClutterChildMeta of type
* `MY_TYPE_CHILD_META` for every actor that is added to the container.
*
* The child data for an actor can be retrieved using the
* clutter_container_get_child_meta() function.
*
* The properties of the data and your subclass can be manipulated with
* clutter_container_child_set() and clutter_container_child_get() which
* act like g_object_set() and g_object_get().
*
* You can provide hooks for your own storage as well as control the
* instantiation by overriding the #ClutterContainerIface virtual functions
* #ClutterContainerIface.create_child_meta(), #ClutterContainerIface.destroy_child_meta(),
* and #ClutterContainerIface.get_child_meta().
*
* Since: 0.8
*/
struct _ClutterChildMeta
{
/*< private >*/
GObject parent_instance;
/*< public >*/
ClutterContainer *container;
ClutterActor *actor;
};
/**
* ClutterChildMetaClass:
*
* The #ClutterChildMetaClass contains only private data
*
* Since: 0.8
*/
struct _ClutterChildMetaClass
{
/*< private >*/
GObjectClass parent_class;
};
CLUTTER_AVAILABLE_IN_ALL
GType clutter_child_meta_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_ALL
ClutterContainer * clutter_child_meta_get_container (ClutterChildMeta *data);
CLUTTER_AVAILABLE_IN_ALL
ClutterActor * clutter_child_meta_get_actor (ClutterChildMeta *data);
G_END_DECLS
#endif /* __CLUTTER_CHILD_META_H__ */

View File

@ -0,0 +1,831 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-click-action
* @Title: ClutterClickAction
* @Short_Description: Action for clickable actors
*
* #ClutterClickAction is a sub-class of #ClutterAction that implements
* the logic for clickable actors, by using the low level events of
* #ClutterActor, such as #ClutterActor::button-press-event and
* #ClutterActor::button-release-event, to synthesize the high level
* #ClutterClickAction::clicked signal.
*
* To use #ClutterClickAction you just need to apply it to a #ClutterActor
* using clutter_actor_add_action() and connect to the
* #ClutterClickAction::clicked signal:
*
* |[
* 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 #ClutterClickAction:long-press-threshold property) for a
* minimum amount of time (as the defined by the
* #ClutterClickAction:long-press-duration property).
* The #ClutterClickAction::long-press signal is emitted multiple times,
* using different #ClutterLongPressState values; to handle long presses
* you should connect to the #ClutterClickAction::long-press signal and
* handle the different states:
*
* |[
* static gboolean
* on_long_press (ClutterClickAction *action,
* ClutterActor *actor,
* ClutterLongPressState state)
* {
* switch (state)
* {
* case CLUTTER_LONG_PRESS_QUERY:
* /&ast; return TRUE if the actor should support long press
* &ast; gestures, and FALSE otherwise; this state will be
* &ast; emitted on button presses
* &ast;/
* return TRUE;
*
* case CLUTTER_LONG_PRESS_ACTIVATE:
* /&ast; this state is emitted if the minimum duration has
* &ast; been reached without the gesture being cancelled.
* &ast; the return value is not used
* &ast;/
* return TRUE;
*
* case CLUTTER_LONG_PRESS_CANCEL:
* /&ast; this state is emitted if the long press was cancelled;
* &ast; for instance, the pointer went outside the actor or the
* &ast; allowed threshold, or the button was released before
* &ast; the minimum duration was reached. the return value is
* &ast; not used
* &ast;/
* return FALSE;
* }
* }
* ]|
*
* #ClutterClickAction is available since Clutter 1.4
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-click-action.h"
#include "clutter-debug.h"
#include "clutter-enum-types.h"
#include "clutter-marshal.h"
#include "clutter-private.h"
struct _ClutterClickActionPrivate
{
ClutterActor *stage;
guint event_id;
guint capture_id;
guint long_press_id;
gint long_press_threshold;
gint long_press_duration;
gint drag_threshold;
guint press_button;
gint press_device_id;
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)
/* forward declaration */
static gboolean on_captured_event (ClutterActor *stage,
ClutterEvent *event,
ClutterClickAction *action);
static inline void
click_action_set_pressed (ClutterClickAction *action,
gboolean is_pressed)
{
ClutterClickActionPrivate *priv = action->priv;
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 = action->priv;
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 = action->priv;
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);
if (priv->capture_id != 0)
{
g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0;
}
click_action_set_pressed (action, FALSE);
click_action_set_held (action, FALSE);
return FALSE;
}
static inline void
click_action_query_long_press (ClutterClickAction *action)
{
ClutterClickActionPrivate *priv = action->priv;
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)
{
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 = action->priv;
if (priv->long_press_id != 0)
{
ClutterActor *actor;
gboolean result;
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
g_source_remove (priv->long_press_id);
priv->long_press_id = 0;
g_signal_emit (action, click_signals[LONG_PRESS], 0,
actor,
CLUTTER_LONG_PRESS_CANCEL,
&result);
}
}
static gboolean
on_event (ClutterActor *actor,
ClutterEvent *event,
ClutterClickAction *action)
{
ClutterClickActionPrivate *priv = action->priv;
gboolean has_button = TRUE;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
return CLUTTER_EVENT_PROPAGATE;
switch (clutter_event_type (event))
{
case CLUTTER_TOUCH_BEGIN:
has_button = FALSE;
case CLUTTER_BUTTON_PRESS:
if (has_button && clutter_event_get_click_count (event) != 1)
return CLUTTER_EVENT_PROPAGATE;
if (priv->is_held)
return CLUTTER_EVENT_STOP;
if (!clutter_actor_contains (actor, clutter_event_get_source (event)))
return CLUTTER_EVENT_PROPAGATE;
priv->press_button = has_button ? clutter_event_get_button (event) : 0;
priv->press_device_id = clutter_event_get_device_id (event);
priv->press_sequence = clutter_event_get_event_sequence (event);
priv->modifier_state = clutter_event_get_state (event);
clutter_event_get_coords (event, &priv->press_x, &priv->press_y);
if (priv->long_press_threshold < 0)
{
ClutterSettings *settings = clutter_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);
priv->capture_id = g_signal_connect_after (priv->stage, "captured-event",
G_CALLBACK (on_captured_event),
action);
click_action_set_pressed (action, TRUE);
click_action_set_held (action, TRUE);
click_action_query_long_press (action);
break;
case CLUTTER_ENTER:
click_action_set_pressed (action, priv->is_held);
break;
case CLUTTER_LEAVE:
click_action_set_pressed (action, priv->is_held);
click_action_cancel_long_press (action);
break;
default:
break;
}
return CLUTTER_EVENT_PROPAGATE;
}
static gboolean
on_captured_event (ClutterActor *stage,
ClutterEvent *event,
ClutterClickAction *action)
{
ClutterClickActionPrivate *priv = action->priv;
ClutterActor *actor;
ClutterModifierType modifier_state;
gboolean has_button = TRUE;
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
switch (clutter_event_type (event))
{
case CLUTTER_TOUCH_END:
has_button = FALSE;
case CLUTTER_BUTTON_RELEASE:
if (!priv->is_held)
return CLUTTER_EVENT_STOP;
if ((has_button && clutter_event_get_button (event) != priv->press_button) ||
(has_button && clutter_event_get_click_count (event) != 1) ||
clutter_event_get_device_id (event) != priv->press_device_id ||
clutter_event_get_event_sequence (event) != priv->press_sequence)
return CLUTTER_EVENT_PROPAGATE;
click_action_set_held (action, FALSE);
click_action_cancel_long_press (action);
/* disconnect the capture */
if (priv->capture_id != 0)
{
g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0;
}
if (priv->long_press_id != 0)
{
g_source_remove (priv->long_press_id);
priv->long_press_id = 0;
}
if (!clutter_actor_contains (actor, clutter_event_get_source (event)))
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 (action, FALSE);
g_signal_emit (action, click_signals[CLICKED], 0, actor);
break;
case CLUTTER_MOTION:
case CLUTTER_TOUCH_UPDATE:
{
gfloat motion_x, motion_y;
gfloat delta_x, delta_y;
if (clutter_event_get_device_id (event) != priv->press_device_id ||
clutter_event_get_event_sequence (event) != priv->press_sequence)
return CLUTTER_EVENT_PROPAGATE;
if (!priv->is_held)
return CLUTTER_EVENT_PROPAGATE;
clutter_event_get_coords (event, &motion_x, &motion_y);
delta_x = ABS (motion_x - priv->press_x);
delta_y = ABS (motion_y - priv->press_y);
if (delta_x > priv->drag_threshold ||
delta_y > priv->drag_threshold)
click_action_cancel_long_press (action);
}
break;
default:
break;
}
return CLUTTER_EVENT_STOP;
}
static void
clutter_click_action_set_actor (ClutterActorMeta *meta,
ClutterActor *actor)
{
ClutterClickAction *action = CLUTTER_CLICK_ACTION (meta);
ClutterClickActionPrivate *priv = action->priv;
if (priv->event_id != 0)
{
ClutterActor *old_actor = clutter_actor_meta_get_actor (meta);
if (old_actor != NULL)
g_signal_handler_disconnect (old_actor, priv->event_id);
priv->event_id = 0;
}
if (priv->capture_id != 0)
{
if (priv->stage != NULL)
g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0;
priv->stage = NULL;
}
if (priv->long_press_id != 0)
{
g_source_remove (priv->long_press_id);
priv->long_press_id = 0;
}
click_action_set_pressed (action, FALSE);
click_action_set_held (action, FALSE);
if (actor != NULL)
priv->event_id = g_signal_connect (actor, "event",
G_CALLBACK (on_event),
action);
CLUTTER_ACTOR_META_CLASS (clutter_click_action_parent_class)->set_actor (meta, actor);
}
static void
clutter_click_action_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv;
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 (gobject)->priv;
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 (gobject)->priv;
if (priv->event_id)
{
g_signal_handler_disconnect (clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gobject)),
priv->event_id);
priv->event_id = 0;
}
if (priv->capture_id)
{
g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0;
}
if (priv->long_press_id)
{
g_source_remove (priv->long_press_id);
priv->long_press_id = 0;
}
G_OBJECT_CLASS (clutter_click_action_parent_class)->dispose (gobject);
}
static void
clutter_click_action_class_init (ClutterClickActionClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
meta_class->set_actor = clutter_click_action_set_actor;
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
*
* Since: 1.4
*/
obj_props[PROP_PRESSED] =
g_param_spec_boolean ("pressed",
P_("Pressed"),
P_("Whether the clickable should be in pressed state"),
FALSE,
CLUTTER_PARAM_READABLE);
/**
* ClutterClickAction:held:
*
* Whether the clickable actor has the pointer grabbed
*
* Since: 1.4
*/
obj_props[PROP_HELD] =
g_param_spec_boolean ("held",
P_("Held"),
P_("Whether the clickable has a grab"),
FALSE,
CLUTTER_PARAM_READABLE);
/**
* 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 #ClutterSettings:long-press-duration property.
*
* Since: 1.8
*/
obj_props[PROP_LONG_PRESS_DURATION] =
g_param_spec_int ("long-press-duration",
P_("Long Press Duration"),
P_("The minimum duration of a long press to recognize the gesture"),
-1, G_MAXINT,
-1,
CLUTTER_PARAM_READWRITE);
/**
* 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 #ClutterSettings:dnd-drag-threshold property.
*
* Since: 1.8
*/
obj_props[PROP_LONG_PRESS_THRESHOLD] =
g_param_spec_int ("long-press-threshold",
P_("Long Press Threshold"),
P_("The maximum threshold before a long press is cancelled"),
-1, G_MAXINT,
-1,
CLUTTER_PARAM_READWRITE);
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 ::clicked signal is emitted when the #ClutterActor to which
* a #ClutterClickAction has been applied should respond to a
* pointer button press and release events
*
* Since: 1.4
*/
click_signals[CLICKED] =
g_signal_new (I_("clicked"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterClickActionClass, clicked),
NULL, NULL,
_clutter_marshal_VOID__OBJECT,
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 ::long-press 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
* clutter_click_action_release().
*
* Return value: Only the %CLUTTER_LONG_PRESS_QUERY state uses the
* returned value of the handler; other states will ignore it
*
* Since: 1.8
*/
click_signals[LONG_PRESS] =
g_signal_new (I_("long-press"),
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)
{
self->priv = clutter_click_action_get_instance_private (self);
self->priv->long_press_threshold = -1;
self->priv->long_press_duration = -1;
}
/**
* clutter_click_action_new:
*
* Creates a new #ClutterClickAction instance
*
* Return value: the newly created #ClutterClickAction
*
* Since: 1.4
*/
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 #ClutterClickAction:pressed state.
*
* This function will also cancel the long press gesture if one was
* initiated.
*
* This function is useful to break a grab, for instance after a certain
* amount of time has passed.
*
* Since: 1.4
*/
void
clutter_click_action_release (ClutterClickAction *action)
{
ClutterClickActionPrivate *priv;
g_return_if_fail (CLUTTER_IS_CLICK_ACTION (action));
priv = action->priv;
if (!priv->is_held)
return;
/* disconnect the capture */
if (priv->capture_id != 0)
{
g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0;
}
click_action_cancel_long_press (action);
click_action_set_held (action, FALSE);
click_action_set_pressed (action, FALSE);
}
/**
* clutter_click_action_get_button:
* @action: a #ClutterClickAction
*
* Retrieves the button that was pressed.
*
* Return value: the button value
*
* Since: 1.4
*/
guint
clutter_click_action_get_button (ClutterClickAction *action)
{
g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0);
return action->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
*
* Since: 1.6
*/
ClutterModifierType
clutter_click_action_get_state (ClutterClickAction *action)
{
g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0);
return action->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.
*
* Since: 1.8
*/
void
clutter_click_action_get_coords (ClutterClickAction *action,
gfloat *press_x,
gfloat *press_y)
{
g_return_if_fail (CLUTTER_IS_ACTION (action));
if (press_x != NULL)
*press_x = action->priv->press_x;
if (press_y != NULL)
*press_y = action->priv->press_y;
}

View File

@ -0,0 +1,120 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*
* Inspired by the StClickable class in GNOME Shell, written by:
* Colin Walters <walters@verbum.org>
*/
#ifndef __CLUTTER_CLICK_ACTION_H__
#define __CLUTTER_CLICK_ACTION_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-action.h>
#include <clutter/clutter-event.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_CLICK_ACTION (clutter_click_action_get_type ())
#define CLUTTER_CLICK_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CLICK_ACTION, ClutterClickAction))
#define CLUTTER_IS_CLICK_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CLICK_ACTION))
#define CLUTTER_CLICK_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CLICK_ACTION, ClutterClickActionClass))
#define CLUTTER_IS_CLICK_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CLICK_ACTION))
#define CLUTTER_CLICK_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CLICK_ACTION, ClutterClickActionClass))
typedef struct _ClutterClickAction ClutterClickAction;
typedef struct _ClutterClickActionPrivate ClutterClickActionPrivate;
typedef struct _ClutterClickActionClass ClutterClickActionClass;
/**
* ClutterClickAction:
*
* The #ClutterClickAction structure contains
* only private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _ClutterClickAction
{
/*< private >*/
ClutterAction parent_instance;
ClutterClickActionPrivate *priv;
};
/**
* ClutterClickActionClass:
* @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
*
* Since: 1.4
*/
struct _ClutterClickActionClass
{
/*< private >*/
ClutterActionClass parent_class;
/*< public >*/
void (* clicked) (ClutterClickAction *action,
ClutterActor *actor);
gboolean (* long_press) (ClutterClickAction *action,
ClutterActor *actor,
ClutterLongPressState state);
/*< private >*/
void (* _clutter_click_action1) (void);
void (* _clutter_click_action2) (void);
void (* _clutter_click_action3) (void);
void (* _clutter_click_action4) (void);
void (* _clutter_click_action5) (void);
void (* _clutter_click_action6) (void);
void (* _clutter_click_action7) (void);
};
CLUTTER_AVAILABLE_IN_1_4
GType clutter_click_action_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_4
ClutterAction * clutter_click_action_new (void);
CLUTTER_AVAILABLE_IN_1_4
guint clutter_click_action_get_button (ClutterClickAction *action);
CLUTTER_AVAILABLE_IN_1_4
ClutterModifierType clutter_click_action_get_state (ClutterClickAction *action);
CLUTTER_AVAILABLE_IN_1_8
void clutter_click_action_get_coords (ClutterClickAction *action,
gfloat *press_x,
gfloat *press_y);
CLUTTER_AVAILABLE_IN_1_4
void clutter_click_action_release (ClutterClickAction *action);
G_END_DECLS
#endif /* __CLUTTER_CLICK_ACTION_H__ */

View File

@ -0,0 +1,442 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2008 Intel Corporation.
*
* Authored By: Robert Bragg <robert@linux.intel.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* SECTION:clutter-clone
* @short_description: An actor that displays a clone of a source actor
*
* #ClutterClone is a #ClutterActor which draws with the paint
* function of another actor, scaled to fit its own allocation.
*
* #ClutterClone can be used to efficiently clone any other actor.
*
* Unlike clutter_texture_new_from_actor(), #ClutterClone does not require
* the presence of support for FBOs in the underlying GL or GLES
* implementation.
*
* #ClutterClone is available since Clutter 1.0
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-actor-private.h"
#include "clutter-clone.h"
#include "clutter-debug.h"
#include "clutter-main.h"
#include "clutter-paint-volume-private.h"
#include "clutter-private.h"
#include "cogl/cogl.h"
struct _ClutterClonePrivate
{
ClutterActor *clone_source;
};
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 (self)->priv;
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 (self)->priv;
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_apply_transform (ClutterActor *self, CoglMatrix *matrix)
{
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
ClutterActorBox box, source_box;
gfloat x_scale, y_scale;
/* First chain up and apply all the standard ClutterActor
* transformations... */
CLUTTER_ACTOR_CLASS (clutter_clone_parent_class)->apply_transform (self,
matrix);
/* if we don't have a source, nothing else to do */
if (priv->clone_source == NULL)
return;
/* get our allocated size */
clutter_actor_get_allocation_box (self, &box);
/* and get the allocated size of the source */
clutter_actor_get_allocation_box (priv->clone_source, &source_box);
/* We need to scale what the clone-source actor paints to fill our own
* allocation...
*/
x_scale = clutter_actor_box_get_width (&box)
/ clutter_actor_box_get_width (&source_box);
y_scale = clutter_actor_box_get_height (&box)
/ clutter_actor_box_get_height (&source_box);
cogl_matrix_scale (matrix, x_scale, y_scale, x_scale);
}
static void
clutter_clone_paint (ClutterActor *actor)
{
ClutterClone *self = CLUTTER_CLONE (actor);
ClutterClonePrivate *priv = self->priv;
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))
{
_clutter_actor_push_clone_paint ();
clutter_actor_paint (priv->clone_source);
_clutter_actor_pop_clone_paint ();
}
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 (actor)->priv;
const ClutterPaintVolume *source_volume;
/* if the source is not set the paint volume is defined to be empty */
if (priv->clone_source == NULL)
return TRUE;
/* query the volume of the source actor and simply masquarade it as
* the clones volume... */
source_volume = clutter_actor_get_paint_volume (priv->clone_source);
if (source_volume == NULL)
return FALSE;
_clutter_paint_volume_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 (actor)->priv;
/* 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,
ClutterAllocationFlags flags)
{
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
ClutterActorClass *parent_class;
/* chain up */
parent_class = CLUTTER_ACTOR_CLASS (clutter_clone_parent_class);
parent_class->allocate (self, box, flags);
if (priv->clone_source == NULL)
return;
#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, flags);
#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 (gobject)->priv;
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->apply_transform = clutter_clone_apply_transform;
actor_class->paint = clutter_clone_paint;
actor_class->get_paint_volume = clutter_clone_get_paint_volume;
actor_class->get_preferred_width = clutter_clone_get_preferred_width;
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.
*
* Since: 1.0
*/
obj_props[PROP_SOURCE] =
g_param_spec_object ("source",
P_("Source"),
P_("Specifies the actor to be cloned"),
CLUTTER_TYPE_ACTOR,
G_PARAM_CONSTRUCT |
CLUTTER_PARAM_READWRITE);
g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
}
static void
clutter_clone_init (ClutterClone *self)
{
self->priv = clutter_clone_get_instance_private (self);
}
/**
* clutter_clone_new:
* @source: a #ClutterActor, or %NULL
*
* Creates a new #ClutterActor which clones @source/
*
* Return value: the newly created #ClutterClone
*
* Since: 1.0
*/
ClutterActor *
clutter_clone_new (ClutterActor *source)
{
return g_object_new (CLUTTER_TYPE_CLONE, "source", source, NULL);
}
static void
clutter_clone_set_source_internal (ClutterClone *self,
ClutterActor *source)
{
ClutterClonePrivate *priv = self->priv;
if (priv->clone_source == source)
return;
if (priv->clone_source != NULL)
{
_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));
}
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.
*
* Since: 1.0
*/
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
*
* Since: 1.0
*/
ClutterActor *
clutter_clone_get_source (ClutterClone *self)
{
g_return_val_if_fail (CLUTTER_IS_CLONE (self), NULL);
return self->priv->clone_source;
}

View File

@ -0,0 +1,94 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2008 Intel Corporation.
*
* Authored By: Robert Bragg <robert@linux.intel.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CLUTTER_CLONE_H__
#define __CLUTTER_CLONE_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-actor.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_CLONE (clutter_clone_get_type())
#define CLUTTER_CLONE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CLONE, ClutterClone))
#define CLUTTER_CLONE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CLONE, ClutterCloneClass))
#define CLUTTER_IS_CLONE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CLONE))
#define CLUTTER_IS_CLONE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CLONE))
#define CLUTTER_CLONE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CLONE, ClutterCloneClass))
typedef struct _ClutterClone ClutterClone;
typedef struct _ClutterCloneClass ClutterCloneClass;
typedef struct _ClutterClonePrivate ClutterClonePrivate;
/**
* ClutterClone:
*
* The #ClutterClone structure contains only private data
* and should be accessed using the provided API
*
* Since: 1.0
*/
struct _ClutterClone
{
/*< private >*/
ClutterActor parent_instance;
ClutterClonePrivate *priv;
};
/**
* ClutterCloneClass:
*
* The #ClutterCloneClass structure contains only private data
*
* Since: 1.0
*/
struct _ClutterCloneClass
{
/*< private >*/
ClutterActorClass parent_class;
/* padding for future expansion */
void (*_clutter_actor_clone1) (void);
void (*_clutter_actor_clone2) (void);
void (*_clutter_actor_clone3) (void);
void (*_clutter_actor_clone4) (void);
};
CLUTTER_AVAILABLE_IN_1_0
GType clutter_clone_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_0
ClutterActor * clutter_clone_new (ClutterActor *source);
CLUTTER_AVAILABLE_IN_1_0
void clutter_clone_set_source (ClutterClone *self,
ClutterActor *source);
CLUTTER_AVAILABLE_IN_1_0
ClutterActor * clutter_clone_get_source (ClutterClone *self);
G_END_DECLS
#endif /* __CLUTTER_CLONE_H__ */

View File

@ -0,0 +1,52 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2012 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __CLUTTER_COGL_COMPAT_H__
#define __CLUTTER_COGL_COMPAT_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
G_BEGIN_DECLS
/* XXX: Some public Clutter apis depend on Cogl types that have been
* removed from the Cogl 2.0 experimental api.
*
* If somone has opted to use the Cogl 2.0 experimental api by
* defining COGL_ENABLE_EXPERIMENTAL_2_0_API then we need to define
* some place holder typdefs for compatability.
*
* NB: we build all clutter internals with COGL_ENABLE_EXPERIMENTAL_2_0_API
* defined.
*/
#ifdef COGL_ENABLE_EXPERIMENTAL_2_0_API
/* CoglMaterial has been replaced with CoglPipeline in Cogl 2.0 */
typedef struct _CoglMaterial CoglMaterial;
#endif
G_END_DECLS
#endif /* __CLUTTER_COGL_COMPAT_H__ */

View File

@ -0,0 +1,79 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CLUTTER_COLOR_STATIC_H__
#define __CLUTTER_COLOR_STATIC_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#define __CLUTTER_COLOR_SYM(x) (clutter_color_get_static (CLUTTER_COLOR_##x))
#define CLUTTER_COLOR_White (__CLUTTER_COLOR_SYM (WHITE))
#define CLUTTER_COLOR_Black (__CLUTTER_COLOR_SYM (BLACK))
#define CLUTTER_COLOR_Red (__CLUTTER_COLOR_SYM (RED))
#define CLUTTER_COLOR_DarkRed (__CLUTTER_COLOR_SYM (DARK_RED))
#define CLUTTER_COLOR_Green (__CLUTTER_COLOR_SYM (GREEN))
#define CLUTTER_COLOR_DarkGreen (__CLUTTER_COLOR_SYM (DARK_GREEN))
#define CLUTTER_COLOR_Blue (__CLUTTER_COLOR_SYM (BLUE))
#define CLUTTER_COLOR_DarkBlue (__CLUTTER_COLOR_SYM (DARK_BLUE))
#define CLUTTER_COLOR_Cyan (__CLUTTER_COLOR_SYM (CYAN))
#define CLUTTER_COLOR_DarkCyan (__CLUTTER_COLOR_SYM (DARK_CYAN))
#define CLUTTER_COLOR_Magenta (__CLUTTER_COLOR_SYM (MAGENTA))
#define CLUTTER_COLOR_DarkMagenta (__CLUTTER_COLOR_SYM (DARK_MAGENTA))
#define CLUTTER_COLOR_Yellow (__CLUTTER_COLOR_SYM (YELLOW))
#define CLUTTER_COLOR_DarkYellow (__CLUTTER_COLOR_SYM (DARK_YELLOW))
#define CLUTTER_COLOR_Gray (__CLUTTER_COLOR_SYM (GRAY))
#define CLUTTER_COLOR_DarkGray (__CLUTTER_COLOR_SYM (DARK_GRAY))
#define CLUTTER_COLOR_LightGray (__CLUTTER_COLOR_SYM (LIGHT_GRAY))
#define CLUTTER_COLOR_Butter (__CLUTTER_COLOR_SYM (BUTTER))
#define CLUTTER_COLOR_LightButter (__CLUTTER_COLOR_SYM (BUTTER_LIGHT))
#define CLUTTER_COLOR_DarkButter (__CLUTTER_COLOR_SYM (BUTTER_DARK))
#define CLUTTER_COLOR_Orange (__CLUTTER_COLOR_SYM (ORANGE))
#define CLUTTER_COLOR_LightOrange (__CLUTTER_COLOR_SYM (ORANGE_LIGHT))
#define CLUTTER_COLOR_DarkOrange (__CLUTTER_COLOR_SYM (ORANGE_DARK))
#define CLUTTER_COLOR_Chocolate (__CLUTTER_COLOR_SYM (CHOCOLATE))
#define CLUTTER_COLOR_LightChocolate (__CLUTTER_COLOR_SYM (CHOCOLATE_LIGHT))
#define CLUTTER_COLOR_DarkChocolate (__CLUTTER_COLOR_SYM (CHOCOLATE_DARK))
#define CLUTTER_COLOR_Chameleon (__CLUTTER_COLOR_SYM (CHAMELEON))
#define CLUTTER_COLOR_LightChameleon (__CLUTTER_COLOR_SYM (CHAMELEON_LIGHT))
#define CLUTTER_COLOR_DarkChameleon (__CLUTTER_COLOR_SYM (CHAMELEON_DARK))
#define CLUTTER_COLOR_SkyBlue (__CLUTTER_COLOR_SYM (SKY_BLUE))
#define CLUTTER_COLOR_LightSkyBlue (__CLUTTER_COLOR_SYM (SKY_BLUE_LIGHT))
#define CLUTTER_COLOR_DarkSkyBlue (__CLUTTER_COLOR_SYM (SKY_BLUE_DARK))
#define CLUTTER_COLOR_Plum (__CLUTTER_COLOR_SYM (PLUM))
#define CLUTTER_COLOR_LightPlum (__CLUTTER_COLOR_SYM (PLUM_LIGHT))
#define CLUTTER_COLOR_DarkPlum (__CLUTTER_COLOR_SYM (PLUM_DARK))
#define CLUTTER_COLOR_ScarletRed (__CLUTTER_COLOR_SYM (SCARLET_RED))
#define CLUTTER_COLOR_LightScarletRed (__CLUTTER_COLOR_SYM (SCARLET_RED_LIGHT))
#define CLUTTER_COLOR_DarkScarletRed (__CLUTTER_COLOR_SYM (SCARLET_RED_DARK))
#define CLUTTER_COLOR_Aluminium1 (__CLUTTER_COLOR_SYM (ALUMINIUM_1))
#define CLUTTER_COLOR_Aluminium2 (__CLUTTER_COLOR_SYM (ALUMINIUM_2))
#define CLUTTER_COLOR_Aluminium3 (__CLUTTER_COLOR_SYM (ALUMINIUM_3))
#define CLUTTER_COLOR_Aluminium4 (__CLUTTER_COLOR_SYM (ALUMINIUM_4))
#define CLUTTER_COLOR_Aluminium5 (__CLUTTER_COLOR_SYM (ALUMINIUM_5))
#define CLUTTER_COLOR_Aluminium6 (__CLUTTER_COLOR_SYM (ALUMINIUM_6))
#define CLUTTER_COLOR_Transparent (__CLUTTER_COLOR_SYM (TRANSPARENT))
#endif /* __CLUTTER_COLOR_STATIC_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,200 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By: Matthew Allum <mallum@openedhand.com>
* Emmanuele Bassi <ebassi@linux.intel.com>
*
* Copyright (C) 2006, 2007, 2008 OpenedHand
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __CLUTTER_COLOR_H__
#define __CLUTTER_COLOR_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-types.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_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
*
* Color representation.
*/
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.
*
* Since: 1.12
*/
#define CLUTTER_COLOR_INIT(r,g,b,a) { (r), (g), (b), (a) }
CLUTTER_AVAILABLE_IN_ALL
GType clutter_color_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_ALL
ClutterColor *clutter_color_new (guint8 red,
guint8 green,
guint8 blue,
guint8 alpha);
CLUTTER_AVAILABLE_IN_1_12
ClutterColor *clutter_color_alloc (void);
CLUTTER_AVAILABLE_IN_1_12
ClutterColor *clutter_color_init (ClutterColor *color,
guint8 red,
guint8 green,
guint8 blue,
guint8 alpha);
CLUTTER_AVAILABLE_IN_ALL
ClutterColor *clutter_color_copy (const ClutterColor *color);
CLUTTER_AVAILABLE_IN_ALL
void clutter_color_free (ClutterColor *color);
CLUTTER_AVAILABLE_IN_ALL
void clutter_color_add (const ClutterColor *a,
const ClutterColor *b,
ClutterColor *result);
CLUTTER_AVAILABLE_IN_ALL
void clutter_color_subtract (const ClutterColor *a,
const ClutterColor *b,
ClutterColor *result);
CLUTTER_AVAILABLE_IN_ALL
void clutter_color_lighten (const ClutterColor *color,
ClutterColor *result);
CLUTTER_AVAILABLE_IN_ALL
void clutter_color_darken (const ClutterColor *color,
ClutterColor *result);
CLUTTER_AVAILABLE_IN_ALL
void clutter_color_shade (const ClutterColor *color,
gdouble factor,
ClutterColor *result);
CLUTTER_AVAILABLE_IN_ALL
gchar * clutter_color_to_string (const ClutterColor *color);
CLUTTER_AVAILABLE_IN_1_0
gboolean clutter_color_from_string (ClutterColor *color,
const gchar *str);
CLUTTER_AVAILABLE_IN_ALL
void clutter_color_to_hls (const ClutterColor *color,
gfloat *hue,
gfloat *luminance,
gfloat *saturation);
CLUTTER_AVAILABLE_IN_ALL
void clutter_color_from_hls (ClutterColor *color,
gfloat hue,
gfloat luminance,
gfloat saturation);
CLUTTER_AVAILABLE_IN_ALL
guint32 clutter_color_to_pixel (const ClutterColor *color);
CLUTTER_AVAILABLE_IN_ALL
void clutter_color_from_pixel (ClutterColor *color,
guint32 pixel);
CLUTTER_AVAILABLE_IN_1_0
guint clutter_color_hash (gconstpointer v);
CLUTTER_AVAILABLE_IN_ALL
gboolean clutter_color_equal (gconstpointer v1,
gconstpointer v2);
CLUTTER_AVAILABLE_IN_1_6
void clutter_color_interpolate (const ClutterColor *initial,
const ClutterColor *final,
gdouble progress,
ClutterColor *result);
#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<!-- -->.
*
* Since: 1.0
*/
#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.
*
* Since: 1.0
*/
struct _ClutterParamSpecColor
{
/*< private >*/
GParamSpec parent_instance;
/*< public >*/
ClutterColor *default_value;
};
CLUTTER_AVAILABLE_IN_1_0
void clutter_value_set_color (GValue *value,
const ClutterColor *color);
CLUTTER_AVAILABLE_IN_1_0
const ClutterColor * clutter_value_get_color (const GValue *value);
CLUTTER_AVAILABLE_IN_1_0
GType clutter_param_color_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_0
GParamSpec * clutter_param_spec_color (const gchar *name,
const gchar *nick,
const gchar *blurb,
const ClutterColor *default_value,
GParamFlags flags);
CLUTTER_AVAILABLE_IN_1_6
const ClutterColor *clutter_color_get_static (ClutterStaticColor color);
G_END_DECLS
#endif /* __CLUTTER_COLOR_H__ */

View File

@ -0,0 +1,372 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-colorize-effect
* @short_description: A colorization effect
* @see_also: #ClutterEffect, #ClutterOffscreenEffect
*
* #ClutterColorizeEffect is a sub-class of #ClutterEffect that
* colorizes an actor with the given tint.
*
* #ClutterColorizeEffect is available since Clutter 1.4
*/
#define CLUTTER_COLORIZE_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_COLORIZE_EFFECT, ClutterColorizeEffectClass))
#define CLUTTER_IS_COLORIZE_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_COLORIZE_EFFECT))
#define CLUTTER_COLORIZE_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_COLORIZE_EFFECT, ClutterColorizeEffectClass))
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-colorize-effect.h"
#include "cogl/cogl.h"
#include "clutter-debug.h"
#include "clutter-enum-types.h"
#include "clutter-offscreen-effect.h"
#include "clutter-private.h"
struct _ClutterColorizeEffect
{
ClutterOffscreenEffect parent_instance;
/* the tint of the colorization */
ClutterColor tint;
gint tint_uniform;
gint tex_width;
gint tex_height;
CoglPipeline *pipeline;
};
struct _ClutterColorizeEffectClass
{
ClutterOffscreenEffectClass parent_class;
CoglPipeline *base_pipeline;
};
/* 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 (ClutterColorizeEffect,
clutter_colorize_effect,
CLUTTER_TYPE_OFFSCREEN_EFFECT);
static gboolean
clutter_colorize_effect_pre_paint (ClutterEffect *effect)
{
ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect);
ClutterEffectClass *parent_class;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
return FALSE;
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
{
/* if we don't have support for GLSL shaders then we
* forcibly disable the ActorMeta
*/
g_warning ("Unable to use the ShaderEffect: the graphics hardware "
"or the current GL driver does not implement support "
"for the GLSL shading language.");
clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
return FALSE;
}
parent_class = CLUTTER_EFFECT_CLASS (clutter_colorize_effect_parent_class);
if (parent_class->pre_paint (effect))
{
ClutterOffscreenEffect *offscreen_effect =
CLUTTER_OFFSCREEN_EFFECT (effect);
CoglHandle texture;
texture = clutter_offscreen_effect_get_texture (offscreen_effect);
self->tex_width = cogl_texture_get_width (texture);
self->tex_height = cogl_texture_get_height (texture);
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
return TRUE;
}
else
return FALSE;
}
static void
clutter_colorize_effect_paint_target (ClutterOffscreenEffect *effect)
{
ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect);
ClutterActor *actor;
guint8 paint_opacity;
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
paint_opacity = clutter_actor_get_paint_opacity (actor);
cogl_pipeline_set_color4ub (self->pipeline,
paint_opacity,
paint_opacity,
paint_opacity,
paint_opacity);
cogl_push_source (self->pipeline);
cogl_rectangle (0, 0, self->tex_width, self->tex_height);
cogl_pop_source ();
}
static void
clutter_colorize_effect_dispose (GObject *gobject)
{
ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (gobject);
if (self->pipeline != NULL)
{
cogl_object_unref (self->pipeline);
self->pipeline = NULL;
}
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);
switch (prop_id)
{
case PROP_TINT:
clutter_value_set_color (value, &effect->tint);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_colorize_effect_class_init (ClutterColorizeEffectClass *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->paint_target = clutter_colorize_effect_paint_target;
effect_class->pre_paint = clutter_colorize_effect_pre_paint;
gobject_class->set_property = clutter_colorize_effect_set_property;
gobject_class->get_property = clutter_colorize_effect_get_property;
gobject_class->dispose = clutter_colorize_effect_dispose;
/**
* ClutterColorizeEffect:tint:
*
* The tint to apply to the actor
*
* Since: 1.4
*/
obj_props[PROP_TINT] =
clutter_param_spec_color ("tint",
P_("Tint"),
P_("The tint to apply"),
&default_tint,
CLUTTER_PARAM_READWRITE);
g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
}
static void
update_tint_uniform (ClutterColorizeEffect *self)
{
if (self->tint_uniform > -1)
{
float tint[3] = {
self->tint.red / 255.0,
self->tint.green / 255.0,
self->tint.blue / 255.0
};
cogl_pipeline_set_uniform_float (self->pipeline,
self->tint_uniform,
3, /* n_components */
1, /* count */
tint);
}
}
static void
clutter_colorize_effect_init (ClutterColorizeEffect *self)
{
ClutterColorizeEffectClass *klass = CLUTTER_COLORIZE_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,
colorize_glsl_declarations,
colorize_glsl_source);
cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
cogl_object_unref (snippet);
cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
0, /* layer number */
COGL_TEXTURE_TYPE_2D);
}
self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
self->tint_uniform =
cogl_pipeline_get_uniform_location (self->pipeline, "tint");
self->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
* clutter_actor_add_effect()
*
* Return value: the newly created #ClutterColorizeEffect or %NULL
*
* Since: 1.4
*/
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
*
* Since: 1.4
*/
void
clutter_colorize_effect_set_tint (ClutterColorizeEffect *effect,
const ClutterColor *tint)
{
g_return_if_fail (CLUTTER_IS_COLORIZE_EFFECT (effect));
effect->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
*
* Since: 1.4
*/
void
clutter_colorize_effect_get_tint (ClutterColorizeEffect *effect,
ClutterColor *tint)
{
g_return_if_fail (CLUTTER_IS_COLORIZE_EFFECT (effect));
g_return_if_fail (tint != NULL);
*tint = effect->tint;
}

View File

@ -0,0 +1,67 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_COLORIZE_EFFECT_H__
#define __CLUTTER_COLORIZE_EFFECT_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-color.h>
#include <clutter/clutter-effect.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_COLORIZE_EFFECT (clutter_colorize_effect_get_type ())
#define CLUTTER_COLORIZE_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_COLORIZE_EFFECT, ClutterColorizeEffect))
#define CLUTTER_IS_COLORIZE_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_COLORIZE_EFFECT))
/**
* ClutterColorizeEffect:
*
* #ClutterColorizeEffect is an opaque structure
* whose members cannot be directly accessed
*
* Since: 1.4
*/
typedef struct _ClutterColorizeEffect ClutterColorizeEffect;
typedef struct _ClutterColorizeEffectClass ClutterColorizeEffectClass;
CLUTTER_AVAILABLE_IN_1_4
GType clutter_colorize_effect_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_4
ClutterEffect *clutter_colorize_effect_new (const ClutterColor *tint);
CLUTTER_AVAILABLE_IN_1_4
void clutter_colorize_effect_set_tint (ClutterColorizeEffect *effect,
const ClutterColor *tint);
CLUTTER_AVAILABLE_IN_1_4
void clutter_colorize_effect_get_tint (ClutterColorizeEffect *effect,
ClutterColor *tint);
G_END_DECLS
#endif /* __CLUTTER_COLORIZE_EFFECT_H__ */

View File

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

View File

@ -0,0 +1,42 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CLUTTER_CONSTRAINT_PRIVATE_H__
#define __CLUTTER_CONSTRAINT_PRIVATE_H__
#include "clutter-constraint.h"
G_BEGIN_DECLS
gboolean clutter_constraint_update_allocation (ClutterConstraint *constraint,
ClutterActor *actor,
ClutterActorBox *allocation);
void clutter_constraint_update_preferred_size (ClutterConstraint *constraint,
ClutterActor *actor,
ClutterOrientation direction,
float for_size,
float *minimum_size,
float *natural_size);
G_END_DECLS
#endif /* __CLUTTER_CONSTRAINT_PRIVATE_H__ */

View File

@ -0,0 +1,243 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-constraint
* @Title: ClutterConstraint
* @Short_Description: Abstract class for constraints on position or size
* @See_Also: #ClutterAction
*
* #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
* #ClutterConstraintClass.update_allocation() virtual function.
*
* #ClutterConstraint is available since Clutter 1.4
*
* ## 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 and #ClutterTableLayout lay out their children.
*
* Constraints are attached to a #ClutterActor, and are available
* for inspection using 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.
*
* The [constraints example](https://git.gnome.org/browse/clutter/tree/examples/constraints.c?h=clutter-1.18)
* uses various types of #ClutterConstraints to lay out three actors on a
* resizable stage. Only the central actor has an explicit size, and no
* actor has an explicit position.
*
* - The #ClutterActor with #ClutterActor:name `layerA` is explicitly
* sized to 100 pixels by 25 pixels, and it's added to the #ClutterStage
* - two #ClutterAlignConstraints are used to anchor `layerA` to the
* center of the stage, by using 0.5 as the alignment #ClutterAlignConstraint:factor on
* both the X and Y axis
* - the #ClutterActor with #ClutterActor:name `layerB` is added to the
* #ClutterStage with no explicit size
* - the #ClutterActor:x and #ClutterActor:width of `layerB` are bound
* to the same properties of `layerA` using two #ClutterBindConstraint
* objects, thus keeping `layerB` aligned to `layerA`
* - the top edge of `layerB` is snapped together with the bottom edge
* of `layerA`; the bottom edge of `layerB` is also snapped together with
* the bottom edge of the #ClutterStage; an offset is given to the two
* #ClutterSnapConstraintss to allow for some padding; since `layerB` is
* snapped between two different #ClutterActors, its height is stretched
* to match the gap
* - the #ClutterActor with #ClutterActor:name `layerC` mirrors `layerB`,
* snapping the top edge of the #ClutterStage to the top edge of `layerC`
* and the top edge of `layerA` to the bottom edge of `layerC`
*
* You can try resizing interactively the #ClutterStage and verify
* that the three #ClutterActors maintain the same position and
* size relative to each other, and to the #ClutterStage.
*
* 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 #ClutterConstraintClass.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().
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include "clutter-constraint-private.h"
#include "clutter-actor.h"
#include "clutter-actor-meta-private.h"
#include "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_notify (GObject *gobject,
GParamSpec *pspec)
{
if (strcmp (pspec->name, "enabled") == 0)
{
ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject);
ClutterActor *actor = clutter_actor_meta_get_actor (meta);
if (actor != NULL)
clutter_actor_queue_relayout (actor);
}
if (G_OBJECT_CLASS (clutter_constraint_parent_class)->notify != NULL)
G_OBJECT_CLASS (clutter_constraint_parent_class)->notify (gobject, pspec);
}
static void
clutter_constraint_class_init (ClutterConstraintClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->notify = clutter_constraint_notify;
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);
}
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);
}

View File

@ -0,0 +1,129 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_CONSTRAINT_H__
#define __CLUTTER_CONSTRAINT_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-actor-meta.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_CONSTRAINT (clutter_constraint_get_type ())
#define CLUTTER_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CONSTRAINT, ClutterConstraint))
#define CLUTTER_IS_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CONSTRAINT))
#define CLUTTER_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CONSTRAINT, ClutterConstraintClass))
#define CLUTTER_IS_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CONSTRAINT))
#define CLUTTER_CONSTRAINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CONSTRAINT, ClutterConstraintClass))
typedef struct _ClutterConstraintClass ClutterConstraintClass;
/**
* ClutterConstraint:
*
* The #ClutterConstraint structure contains only
* private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _ClutterConstraint
{
/*< private >*/
ClutterActorMeta parent_instance;
};
/**
* 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
*
* Since: 1.4
*/
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);
/*< private >*/
void (* _clutter_constraint1) (void);
void (* _clutter_constraint2) (void);
void (* _clutter_constraint3) (void);
void (* _clutter_constraint4) (void);
void (* _clutter_constraint5) (void);
void (* _clutter_constraint6) (void);
void (* _clutter_constraint7) (void);
};
CLUTTER_AVAILABLE_IN_1_4
GType clutter_constraint_get_type (void) G_GNUC_CONST;
/* ClutterActor API */
CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_add_constraint (ClutterActor *self,
ClutterConstraint *constraint);
CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_add_constraint_with_name (ClutterActor *self,
const gchar *name,
ClutterConstraint *constraint);
CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_remove_constraint (ClutterActor *self,
ClutterConstraint *constraint);
CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_remove_constraint_by_name (ClutterActor *self,
const gchar *name);
CLUTTER_AVAILABLE_IN_1_4
GList * clutter_actor_get_constraints (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_4
ClutterConstraint *clutter_actor_get_constraint (ClutterActor *self,
const gchar *name);
CLUTTER_AVAILABLE_IN_1_4
void clutter_actor_clear_constraints (ClutterActor *self);
CLUTTER_AVAILABLE_IN_1_10
gboolean clutter_actor_has_constraints (ClutterActor *self);
G_END_DECLS
#endif /* __CLUTTER_CONSTRAINT_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,196 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
*
* Copyright (C) 2006 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* ClutterContainer: Generic actor container interface.
* Author: Emmanuele Bassi <ebassi@openedhand.com>
*/
#ifndef __CLUTTER_CONTAINER_H__
#define __CLUTTER_CONTAINER_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-actor.h>
#include <clutter/clutter-child-meta.h>
#include <clutter/clutter-types.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_CONTAINER (clutter_container_get_type ())
#define CLUTTER_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CONTAINER, ClutterContainer))
#define CLUTTER_IS_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CONTAINER))
#define CLUTTER_CONTAINER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_CONTAINER, ClutterContainerIface))
typedef struct _ClutterContainerIface ClutterContainerIface;
/**
* ClutterContainer:
*
* #ClutterContainer is an opaque structure whose members cannot be directly
* accessed
*
* Since: 0.4
*/
/**
* ClutterContainerIface:
* @add: virtual function for adding an actor to the container. This virtual
* function is deprecated, and it should not be overridden.
* @remove: virtual function for removing an actor from the container. This
* virtual function is deprecated, and it should not be overridden.
* @foreach: virtual function for iterating over the container's children.
* This virtual function is deprecated, and it should not be overridden.
* @foreach_with_internals: virtual functions for iterating over the
* container's children, both added using the #ClutterContainer API
* and internal children. The implementation of this virtual function
* is required only if the #ClutterContainer implementation has
* internal children. This virtual function is deprecated, and it should
* not be overridden.
* @raise: virtual function for raising a child. This virtual function is
* deprecated and it should not be overridden.
* @lower: virtual function for lowering a child. This virtual function is
* deprecated and it should not be overridden.
* @sort_depth_order: virtual function for sorting the children of a
* container depending on their depth. This virtual function is deprecated
* and it should not be overridden.
* @child_meta_type: The GType used for storing auxiliary information about
* each of the containers children.
* @create_child_meta: virtual function that gets called for each added
* child, the function should instantiate an object of type
* #ClutterContainerIface::child_meta_type, set the container and actor
* fields in the instance and add the record to a data structure for
* subsequent access for #ClutterContainerIface::get_child_meta
* @destroy_child_meta: virtual function that gets called when a child is
* removed; it shuld release all resources held by the record
* @get_child_meta: return the record for a container child
* @actor_added: class handler for #ClutterContainer::actor-added
* @actor_removed: class handler for #ClutterContainer::actor-removed
* @child_notify: class handler for #ClutterContainer::child-notify
*
* Base interface for container actors. The @add, @remove and @foreach
* virtual functions must be provided by any implementation; the other
* virtual functions are optional.
*
* Since: 0.4
*/
struct _ClutterContainerIface
{
/*< private >*/
GTypeInterface g_iface;
/*< public >*/
void (* add) (ClutterContainer *container,
ClutterActor *actor);
void (* remove) (ClutterContainer *container,
ClutterActor *actor);
void (* foreach) (ClutterContainer *container,
ClutterCallback callback,
gpointer user_data);
void (* foreach_with_internals) (ClutterContainer *container,
ClutterCallback callback,
gpointer user_data);
/* child stacking */
void (* raise) (ClutterContainer *container,
ClutterActor *actor,
ClutterActor *sibling);
void (* lower) (ClutterContainer *container,
ClutterActor *actor,
ClutterActor *sibling);
void (* sort_depth_order) (ClutterContainer *container);
/* ClutterChildMeta management */
GType child_meta_type;
void (* create_child_meta) (ClutterContainer *container,
ClutterActor *actor);
void (* destroy_child_meta) (ClutterContainer *container,
ClutterActor *actor);
ClutterChildMeta *(* get_child_meta) (ClutterContainer *container,
ClutterActor *actor);
/* signals */
void (* actor_added) (ClutterContainer *container,
ClutterActor *actor);
void (* actor_removed) (ClutterContainer *container,
ClutterActor *actor);
void (* child_notify) (ClutterContainer *container,
ClutterActor *child,
GParamSpec *pspec);
};
CLUTTER_AVAILABLE_IN_ALL
GType clutter_container_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_ALL
ClutterActor * clutter_container_find_child_by_name (ClutterContainer *container,
const gchar *child_name);
CLUTTER_AVAILABLE_IN_ALL
GParamSpec * clutter_container_class_find_child_property (GObjectClass *klass,
const gchar *property_name);
CLUTTER_AVAILABLE_IN_ALL
GParamSpec ** clutter_container_class_list_child_properties (GObjectClass *klass,
guint *n_properties);
CLUTTER_AVAILABLE_IN_ALL
void clutter_container_create_child_meta (ClutterContainer *container,
ClutterActor *actor);
CLUTTER_AVAILABLE_IN_ALL
void clutter_container_destroy_child_meta (ClutterContainer *container,
ClutterActor *actor);
CLUTTER_AVAILABLE_IN_ALL
ClutterChildMeta * clutter_container_get_child_meta (ClutterContainer *container,
ClutterActor *actor);
CLUTTER_AVAILABLE_IN_ALL
void clutter_container_child_set_property (ClutterContainer *container,
ClutterActor *child,
const gchar * property,
const GValue *value);
CLUTTER_AVAILABLE_IN_ALL
void clutter_container_child_get_property (ClutterContainer *container,
ClutterActor *child,
const gchar *property,
GValue *value);
CLUTTER_AVAILABLE_IN_ALL
void clutter_container_child_set (ClutterContainer *container,
ClutterActor *actor,
const gchar *first_prop,
...) G_GNUC_NULL_TERMINATED;
CLUTTER_AVAILABLE_IN_ALL
void clutter_container_child_get (ClutterContainer *container,
ClutterActor *actor,
const gchar *first_prop,
...) G_GNUC_NULL_TERMINATED;
CLUTTER_AVAILABLE_IN_ALL
void clutter_container_child_notify (ClutterContainer *container,
ClutterActor *child,
GParamSpec *pspec);
G_END_DECLS
#endif /* __CLUTTER_CONTAINER_H__ */

View File

@ -0,0 +1,43 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_CONTENT_PRIVATE_H__
#define __CLUTTER_CONTENT_PRIVATE_H__
#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);
G_END_DECLS
#endif /* __CLUTTER_CONTENT_PRIVATE_H__ */

View File

@ -0,0 +1,305 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-content
* @Title: ClutterContent
* @Short_Description: Delegate for painting the content of an actor
*
* #ClutterContent is an interface to implement types responsible for
* painting the content of a #ClutterActor.
*
* Multiple actors can use the same #ClutterContent instance, in order
* to share the resources associated with painting the same content.
*
* #ClutterContent is available since Clutter 1.10.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-content-private.h"
#include "clutter-debug.h"
#include "clutter-marshal.h"
#include "clutter-private.h"
typedef struct _ClutterContentIface ClutterContentInterface;
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_paint_content (ClutterContent *content,
ClutterActor *actor,
ClutterPaintNode *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;
/**
* 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.
*
* Since: 1.10
*/
content_signals[ATTACHED] =
g_signal_new (I_("attached"),
G_TYPE_FROM_INTERFACE (iface),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ClutterContentIface, attached),
NULL, NULL,
_clutter_marshal_VOID__OBJECT,
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.
*
* Since: 1.10
*/
content_signals[DETACHED] =
g_signal_new (I_("detached"),
G_TYPE_FROM_INTERFACE (iface),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ClutterContentIface, detached),
NULL, NULL,
_clutter_marshal_VOID__OBJECT,
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.
*
* Since: 1.10
*/
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);
}
}
/*< 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 #ClutterContentIface.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 #ClutterContentIface.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
* @context: a #ClutterPaintNode
*
* Creates the render tree for the @content and @actor.
*
* This function will invoke the #ClutterContentIface.paint_content()
* virtual function.
*/
void
_clutter_content_paint_content (ClutterContent *content,
ClutterActor *actor,
ClutterPaintNode *node)
{
CLUTTER_CONTENT_GET_IFACE (content)->paint_content (content, actor, node);
}
/**
* clutter_content_get_preferred_size:
* @content: a #ClutterContent
* @width: (out): return location for the natural width of the content
* @height: (out): return location for the natural height of the content
*
* Retrieves the natural size of the @content, if any.
*
* 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
*
* Since: 1.10
*/
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);
}

View File

@ -0,0 +1,103 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2012 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_CONTENT_H__
#define __CLUTTER_CONTENT_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-types.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_CONTENT (clutter_content_get_type ())
#define CLUTTER_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CONTENT, ClutterContent))
#define CLUTTER_IS_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CONTENT))
#define CLUTTER_CONTENT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_CONTENT, ClutterContentIface))
typedef struct _ClutterContentIface ClutterContentIface;
/**
* ClutterContent:
*
* The #ClutterContent structure is an opaque type
* whose members cannot be acccessed directly.
*
* Since: 1.10
*/
/**
* ClutterContentIface:
* @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 #ClutterContentIface structure contains only
* private data.
*
* Since: 1.10
*/
struct _ClutterContentIface
{
/*< private >*/
GTypeInterface g_iface;
/*< public >*/
gboolean (* get_preferred_size) (ClutterContent *content,
gfloat *width,
gfloat *height);
void (* paint_content) (ClutterContent *content,
ClutterActor *actor,
ClutterPaintNode *node);
void (* attached) (ClutterContent *content,
ClutterActor *actor);
void (* detached) (ClutterContent *content,
ClutterActor *actor);
void (* invalidate) (ClutterContent *content);
};
CLUTTER_AVAILABLE_IN_1_10
GType clutter_content_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_10
gboolean clutter_content_get_preferred_size (ClutterContent *content,
gfloat *width,
gfloat *height);
CLUTTER_AVAILABLE_IN_1_10
void clutter_content_invalidate (ClutterContent *content);
G_END_DECLS
#endif /* __CLUTTER_CONTENT_H__ */

View File

@ -0,0 +1,88 @@
#ifndef __CLUTTER_DEBUG_H__
#define __CLUTTER_DEBUG_H__
#include <glib.h>
#include "clutter-main.h"
G_BEGIN_DECLS
typedef enum {
CLUTTER_DEBUG_MISC = 1 << 0,
CLUTTER_DEBUG_ACTOR = 1 << 1,
CLUTTER_DEBUG_TEXTURE = 1 << 2,
CLUTTER_DEBUG_EVENT = 1 << 3,
CLUTTER_DEBUG_PAINT = 1 << 4,
CLUTTER_DEBUG_PANGO = 1 << 5,
CLUTTER_DEBUG_BACKEND = 1 << 6,
CLUTTER_DEBUG_SCHEDULER = 1 << 7,
CLUTTER_DEBUG_SCRIPT = 1 << 8,
CLUTTER_DEBUG_SHADER = 1 << 9,
CLUTTER_DEBUG_MULTISTAGE = 1 << 10,
CLUTTER_DEBUG_ANIMATION = 1 << 11,
CLUTTER_DEBUG_LAYOUT = 1 << 12,
CLUTTER_DEBUG_PICK = 1 << 13,
CLUTTER_DEBUG_EVENTLOOP = 1 << 14,
CLUTTER_DEBUG_CLIPPING = 1 << 15,
CLUTTER_DEBUG_OOB_TRANSFORMS = 1 << 16
} ClutterDebugFlag;
typedef enum {
CLUTTER_DEBUG_NOP_PICKING = 1 << 0,
CLUTTER_DEBUG_DUMP_PICK_BUFFERS = 1 << 1
} 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
} ClutterDrawDebugFlag;
#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 "]:" G_STRLOC ": " 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 "]:" G_STRLOC ": %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;
void _clutter_debug_messagev (const char *format,
va_list var_args);
void _clutter_debug_message (const char *format,
...);
G_END_DECLS
#endif /* __CLUTTER_DEBUG_H__ */

View File

@ -0,0 +1,813 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*
* Based on the MxDeformTexture class, written by:
* Chris Lord <chris@linux.intel.com>
*/
/**
* SECTION:clutter-deform-effect
* @Title: ClutterDeformEffect
* @Short_Description: 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.
*
* #ClutterDeformEffect is available since Clutter 1.4
*
* ## Implementing ClutterDeformEffect
*
* Sub-classes of #ClutterDeformEffect should override the
* #ClutterDeformEffectClass.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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-deform-effect.h"
#include <cogl/cogl.h>
#include "clutter-debug.h"
#include "clutter-enum-types.h"
#include "clutter-offscreen-effect-private.h"
#include "clutter-private.h"
#define DEFAULT_N_TILES 32
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;
};
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,
const ClutterActorBox *allocation,
ClutterAllocationFlags flags,
ClutterDeformEffect *effect)
{
effect->priv->is_dirty = TRUE;
}
static void
clutter_deform_effect_set_actor (ClutterActorMeta *meta,
ClutterActor *actor)
{
ClutterDeformEffectPrivate *priv = CLUTTER_DEFORM_EFFECT (meta)->priv;
if (priv->allocation_id != 0)
{
ClutterActor *old_actor = clutter_actor_meta_get_actor (meta);
if (old_actor != NULL)
g_signal_handler_disconnect (old_actor, priv->allocation_id);
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, "allocation-changed",
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)
{
ClutterDeformEffect *self= CLUTTER_DEFORM_EFFECT (effect);
ClutterDeformEffectPrivate *priv = self->priv;
CoglHandle material;
CoglPipeline *pipeline;
CoglDepthState depth_state;
CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
if (priv->is_dirty)
{
ClutterRect rect;
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_rect (effect, &rect))
{
width = clutter_rect_get_width (&rect);
height = clutter_rect_get_height (&rect);
}
else
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_4ub (&vertex.color, 255, 255, 255, opacity);
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_byte (&vertex.color);
vertex_out->g = cogl_color_get_green_byte (&vertex.color);
vertex_out->b = cogl_color_get_blue_byte (&vertex.color);
vertex_out->a = cogl_color_get_alpha_byte (&vertex.color);
}
}
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;
}
material = clutter_offscreen_effect_get_target (effect);
pipeline = COGL_PIPELINE (material);
/* enable depth testing */
cogl_depth_state_init (&depth_state);
cogl_depth_state_set_test_enabled (&depth_state, TRUE);
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 (material != NULL)
cogl_framebuffer_draw_primitive (fb, pipeline, priv->primitive);
/* draw the back */
if (priv->back_pipeline != NULL)
{
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);
cogl_framebuffer_draw_primitive (fb, back_pipeline, priv->primitive);
cogl_object_unref (back_pipeline);
}
if (G_UNLIKELY (priv->lines_primitive != NULL))
{
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
CoglPipeline *lines_pipeline = cogl_pipeline_new (ctx);
cogl_pipeline_set_color4f (lines_pipeline, 1.0, 0, 0, 1.0);
cogl_framebuffer_draw_primitive (fb, lines_pipeline,
priv->lines_primitive);
cogl_object_unref (lines_pipeline);
}
}
static inline void
clutter_deform_effect_free_arrays (ClutterDeformEffect *self)
{
ClutterDeformEffectPrivate *priv = self->priv;
if (priv->buffer)
{
cogl_object_unref (priv->buffer);
priv->buffer = NULL;
}
if (priv->primitive)
{
cogl_object_unref (priv->primitive);
priv->primitive = NULL;
}
if (priv->lines_primitive)
{
cogl_object_unref (priv->lines_primitive);
priv->lines_primitive = NULL;
}
}
static void
clutter_deform_effect_init_arrays (ClutterDeformEffect *self)
{
ClutterDeformEffectPrivate *priv = self->priv;
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);
}
cogl_object_unref (indices);
for (i = 0; i < 3; i++)
cogl_object_unref (attributes[i]);
priv->is_dirty = TRUE;
}
static inline void
clutter_deform_effect_free_back_pipeline (ClutterDeformEffect *self)
{
ClutterDeformEffectPrivate *priv = self->priv;
if (priv->back_pipeline != NULL)
{
cogl_object_unref (priv->back_pipeline);
priv->back_pipeline = NULL;
}
}
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);
switch (prop_id)
{
case PROP_X_TILES:
clutter_deform_effect_set_n_tiles (self, g_value_get_uint (value),
self->priv->y_tiles);
break;
case PROP_Y_TILES:
clutter_deform_effect_set_n_tiles (self, self->priv->x_tiles,
g_value_get_uint (value));
break;
case PROP_BACK_MATERIAL:
clutter_deform_effect_set_back_material (self, g_value_get_boxed (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)
{
ClutterDeformEffectPrivate *priv = CLUTTER_DEFORM_EFFECT (gobject)->priv;
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_boxed (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
*
* Since: 1.4
*/
obj_props[PROP_X_TILES] =
g_param_spec_uint ("x-tiles",
P_("Horizontal Tiles"),
P_("The number of horizontal tiles"),
1, G_MAXUINT,
DEFAULT_N_TILES,
CLUTTER_PARAM_READWRITE);
/**
* ClutterDeformEffect:y-tiles:
*
* The number of vertical tiles. The bigger the number, the
* smaller the tiles
*
* Since: 1.4
*/
obj_props[PROP_Y_TILES] =
g_param_spec_uint ("y-tiles",
P_("Vertical Tiles"),
P_("The number of vertical tiles"),
1, G_MAXUINT,
DEFAULT_N_TILES,
CLUTTER_PARAM_READWRITE);
/**
* 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
*
* Since: 1.4
*/
obj_props[PROP_BACK_MATERIAL] =
g_param_spec_boxed ("back-material",
P_("Back Material"),
P_("The material to be used when painting the back of the actor"),
COGL_TYPE_HANDLE,
CLUTTER_PARAM_READWRITE);
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)
{
self->priv = clutter_deform_effect_get_instance_private (self);
self->priv->x_tiles = self->priv->y_tiles = DEFAULT_N_TILES;
self->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
*
* Since: 1.4
*/
void
clutter_deform_effect_set_back_material (ClutterDeformEffect *effect,
CoglHandle material)
{
ClutterDeformEffectPrivate *priv;
CoglPipeline *pipeline = COGL_PIPELINE (material);
g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect));
g_return_if_fail (pipeline == NULL || cogl_is_pipeline (pipeline));
priv = effect->priv;
clutter_deform_effect_free_back_pipeline (effect);
priv->back_pipeline = material;
if (priv->back_pipeline != NULL)
cogl_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
*
* Since: 1.4
*/
CoglHandle
clutter_deform_effect_get_back_material (ClutterDeformEffect *effect)
{
g_return_val_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect), NULL);
return effect->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
*
* Since: 1.4
*/
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 = effect->priv;
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
*
* Since: 1.4
*/
void
clutter_deform_effect_get_n_tiles (ClutterDeformEffect *effect,
guint *x_tiles,
guint *y_tiles)
{
g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect));
if (x_tiles != NULL)
*x_tiles = effect->priv->x_tiles;
if (y_tiles != NULL)
*y_tiles = effect->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
*
* Since: 1.4
*/
void
clutter_deform_effect_invalidate (ClutterDeformEffect *effect)
{
ClutterActor *actor;
g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect));
if (effect->priv->is_dirty)
return;
effect->priv->is_dirty = TRUE;
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
if (actor != NULL)
clutter_effect_queue_repaint (CLUTTER_EFFECT (effect));
}

View File

@ -0,0 +1,117 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_DEFORM_EFFECT_H__
#define __CLUTTER_DEFORM_EFFECT_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <cogl/cogl.h>
#include <clutter/clutter-offscreen-effect.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_DEFORM_EFFECT (clutter_deform_effect_get_type ())
#define CLUTTER_DEFORM_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DEFORM_EFFECT, ClutterDeformEffect))
#define CLUTTER_IS_DEFORM_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DEFORM_EFFECT))
#define CLUTTER_DEFORM_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DEFORM_EFFECT, ClutterDeformEffectClass))
#define CLUTTER_IS_DEFORM_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DEFORM_EFFECT))
#define CLUTTER_DEFORM_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DEFORM_EFFECT, ClutterDeformEffectClass))
typedef struct _ClutterDeformEffect ClutterDeformEffect;
typedef struct _ClutterDeformEffectPrivate ClutterDeformEffectPrivate;
typedef struct _ClutterDeformEffectClass ClutterDeformEffectClass;
/**
* ClutterDeformEffect:
*
* The #ClutterDeformEffect structure contains
* only private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _ClutterDeformEffect
{
/*< private >*/
ClutterOffscreenEffect parent_instance;
ClutterDeformEffectPrivate *priv;
};
/**
* 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
*
* Since: 1.4
*/
struct _ClutterDeformEffectClass
{
/*< private >*/
ClutterOffscreenEffectClass parent_class;
/*< public >*/
void (* deform_vertex) (ClutterDeformEffect *effect,
gfloat width,
gfloat height,
CoglTextureVertex *vertex);
/*< private >*/
void (*_clutter_deform1) (void);
void (*_clutter_deform2) (void);
void (*_clutter_deform3) (void);
void (*_clutter_deform4) (void);
void (*_clutter_deform5) (void);
void (*_clutter_deform6) (void);
void (*_clutter_deform7) (void);
};
CLUTTER_AVAILABLE_IN_1_4
GType clutter_deform_effect_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_4
void clutter_deform_effect_set_back_material (ClutterDeformEffect *effect,
CoglHandle material);
CLUTTER_AVAILABLE_IN_1_4
CoglHandle clutter_deform_effect_get_back_material (ClutterDeformEffect *effect);
CLUTTER_AVAILABLE_IN_1_4
void clutter_deform_effect_set_n_tiles (ClutterDeformEffect *effect,
guint x_tiles,
guint y_tiles);
CLUTTER_AVAILABLE_IN_1_4
void clutter_deform_effect_get_n_tiles (ClutterDeformEffect *effect,
guint *x_tiles,
guint *y_tiles);
CLUTTER_AVAILABLE_IN_1_4
void clutter_deform_effect_invalidate (ClutterDeformEffect *effect);
G_END_DECLS
#endif /* __CLUTTER_DEFORM_EFFECT_H__ */

View File

@ -0,0 +1,46 @@
#ifndef __CLUTTER_DEPRECATED_H__
#define __CLUTTER_DEPRECATED_H__
#define __CLUTTER_DEPRECATED_H_INSIDE__
#include "deprecated/clutter-actor.h"
#include "deprecated/clutter-alpha.h"
#include "deprecated/clutter-animatable.h"
#include "deprecated/clutter-animation.h"
#include "deprecated/clutter-animator.h"
#include "deprecated/clutter-backend.h"
#include "deprecated/clutter-behaviour.h"
#include "deprecated/clutter-behaviour-depth.h"
#include "deprecated/clutter-behaviour-ellipse.h"
#include "deprecated/clutter-behaviour-opacity.h"
#include "deprecated/clutter-behaviour-path.h"
#include "deprecated/clutter-behaviour-rotate.h"
#include "deprecated/clutter-behaviour-scale.h"
#include "deprecated/clutter-bin-layout.h"
#include "deprecated/clutter-box.h"
#include "deprecated/clutter-cairo-texture.h"
#include "deprecated/clutter-container.h"
#include "deprecated/clutter-fixed.h"
#include "deprecated/clutter-frame-source.h"
#include "deprecated/clutter-group.h"
#include "deprecated/clutter-input-device.h"
#include "deprecated/clutter-keysyms.h"
#include "deprecated/clutter-list-model.h"
#include "deprecated/clutter-main.h"
#include "deprecated/clutter-media.h"
#include "deprecated/clutter-model.h"
#include "deprecated/clutter-rectangle.h"
#include "deprecated/clutter-score.h"
#include "deprecated/clutter-shader.h"
#include "deprecated/clutter-stage-manager.h"
#include "deprecated/clutter-stage.h"
#include "deprecated/clutter-state.h"
#include "deprecated/clutter-table-layout.h"
#include "deprecated/clutter-texture.h"
#include "deprecated/clutter-timeline.h"
#include "deprecated/clutter-timeout-pool.h"
#include "deprecated/clutter-util.h"
#undef __CLUTTER_DEPRECATED_H_INSIDE__
#endif /* __CLUTTER_DEPRECATED_H__ */

View File

@ -0,0 +1,382 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-desaturate-effect
* @short_description: A desaturation effect
* @see_also: #ClutterEffect, #ClutterOffscreenEffect
*
* #ClutterDesaturateEffect is a sub-class of #ClutterEffect that
* desaturates the color of an actor and its contents. The strenght
* of the desaturation effect is controllable and animatable through
* the #ClutterDesaturateEffect:factor property.
*
* #ClutterDesaturateEffect is available since Clutter 1.4
*/
#define CLUTTER_DESATURATE_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DESATURATE_EFFECT, ClutterDesaturateEffectClass))
#define CLUTTER_IS_DESATURATE_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DESATURATE_EFFECT))
#define CLUTTER_DESATURATE_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DESATURATE_EFFECT, ClutterDesaturateEffectClass))
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include <math.h>
#include "clutter-desaturate-effect.h"
#include "cogl/cogl.h"
#include "clutter-debug.h"
#include "clutter-enum-types.h"
#include "clutter-offscreen-effect.h"
#include "clutter-private.h"
struct _ClutterDesaturateEffect
{
ClutterOffscreenEffect parent_instance;
/* the desaturation factor, also known as "strength" */
gdouble factor;
gint factor_uniform;
gint tex_width;
gint tex_height;
CoglPipeline *pipeline;
};
struct _ClutterDesaturateEffectClass
{
ClutterOffscreenEffectClass parent_class;
CoglPipeline *base_pipeline;
};
/* 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 (ClutterDesaturateEffect,
clutter_desaturate_effect,
CLUTTER_TYPE_OFFSCREEN_EFFECT);
static gboolean
clutter_desaturate_effect_pre_paint (ClutterEffect *effect)
{
ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (effect);
ClutterEffectClass *parent_class;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
return FALSE;
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
{
/* if we don't have support for GLSL shaders then we
* forcibly disable the ActorMeta
*/
g_warning ("Unable to use the ShaderEffect: the graphics hardware "
"or the current GL driver does not implement support "
"for the GLSL shading language.");
clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
return FALSE;
}
parent_class = CLUTTER_EFFECT_CLASS (clutter_desaturate_effect_parent_class);
if (parent_class->pre_paint (effect))
{
ClutterOffscreenEffect *offscreen_effect =
CLUTTER_OFFSCREEN_EFFECT (effect);
CoglHandle texture;
texture = clutter_offscreen_effect_get_texture (offscreen_effect);
self->tex_width = cogl_texture_get_width (texture);
self->tex_height = cogl_texture_get_height (texture);
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
return TRUE;
}
else
return FALSE;
}
static void
clutter_desaturate_effect_paint_target (ClutterOffscreenEffect *effect)
{
ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (effect);
ClutterActor *actor;
CoglHandle texture;
guint8 paint_opacity;
texture = clutter_offscreen_effect_get_texture (effect);
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
paint_opacity = clutter_actor_get_paint_opacity (actor);
cogl_pipeline_set_color4ub (self->pipeline,
paint_opacity,
paint_opacity,
paint_opacity,
paint_opacity);
cogl_push_source (self->pipeline);
cogl_rectangle (0, 0,
cogl_texture_get_width (texture),
cogl_texture_get_height (texture));
cogl_pop_source ();
}
static void
clutter_desaturate_effect_dispose (GObject *gobject)
{
ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (gobject);
if (self->pipeline != NULL)
{
cogl_object_unref (self->pipeline);
self->pipeline = NULL;
}
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);
switch (prop_id)
{
case PROP_FACTOR:
g_value_set_double (value, effect->factor);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
update_factor_uniform (ClutterDesaturateEffect *self)
{
if (self->factor_uniform > -1)
cogl_pipeline_set_uniform_1f (self->pipeline,
self->factor_uniform,
self->factor);
}
static void
clutter_desaturate_effect_class_init (ClutterDesaturateEffectClass *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->paint_target = clutter_desaturate_effect_paint_target;
effect_class->pre_paint = clutter_desaturate_effect_pre_paint;
/**
* ClutterDesaturateEffect:factor:
*
* The desaturation factor, between 0.0 (no desaturation) and 1.0 (full
* desaturation).
*
* Since: 1.4
*/
obj_props[PROP_FACTOR] =
g_param_spec_double ("factor",
P_("Factor"),
P_("The desaturation factor"),
0.0, 1.0,
1.0,
CLUTTER_PARAM_READWRITE);
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);
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);
cogl_object_unref (snippet);
cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
0, /* layer number */
COGL_TEXTURE_TYPE_2D);
}
self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
self->factor_uniform =
cogl_pipeline_get_uniform_location (self->pipeline, "factor");
self->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
* clutter_actor_add_effect()
*
* Return value: the newly created #ClutterDesaturateEffect or %NULL
*
* Since: 1.4
*/
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"
*
* Since: 1.4
*/
void
clutter_desaturate_effect_set_factor (ClutterDesaturateEffect *effect,
gdouble factor)
{
g_return_if_fail (CLUTTER_IS_DESATURATE_EFFECT (effect));
g_return_if_fail (factor >= 0.0 && factor <= 1.0);
if (fabsf (effect->factor - factor) >= 0.00001)
{
effect->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
*
* Since: 1.4
*/
gdouble
clutter_desaturate_effect_get_factor (ClutterDesaturateEffect *effect)
{
g_return_val_if_fail (CLUTTER_IS_DESATURATE_EFFECT (effect), 0.0);
return effect->factor;
}

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