Merge branch 'master' into more-texture-backends

This commit is contained in:
Neil Roberts 2010-01-15 12:15:46 +00:00
commit ead4399536
82 changed files with 7941 additions and 5957 deletions

5
.gitignore vendored
View File

@ -11,11 +11,13 @@ clutter.pc
*.o
*.lo
*.la
*.gcov
ChangeLog*
clutter/clutter-enum-types.[ch]
clutter/clutter-marshal.[ch]
clutter/clutter-version.h
clutter/stamp-*
/clutter/gcov-report.txt
/clutter/clutter-json.h
/clutter/cogl/cogl/cogl-defines.h
/clutter/cogl/cogl/*.pc
@ -236,10 +238,13 @@ TAGS
/tests/conform/test-script-object-property
/tests/conform/test-script-animation
/tests/conform/test-script-named-object
/tests/conform/test-actor-destruction
/tests/conform/test-color-operators
/tests/micro-bench/test-text-perf
/tests/micro-bench/test-text
/tests/micro-bench/test-picking
/tests/tools/disable-npots.sh
/tests/conform/test-cogl-multitexture
/clutter/x11/clutter-x11-enum-types.[ch]
/clutter/x11/stamp-clutter-x11-enum-types.h
/po/Makefile.in.in

View File

@ -1,3 +1,9 @@
# 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.
2008-12-10 Neil Roberts <neil@linux.intel.com>
* clutter/cogl/gl/cogl.c:

View File

@ -48,3 +48,6 @@ MAINTAINERCLEANFILES = \
$(NULL)
include $(top_srcdir)/build/autotools/Makefile.am.changelog
gcov:
@( cd clutter && $(MAKE) $(AM_MAKEFLAGS) $@ ) || exit $$?

56
NEWS
View File

@ -1,3 +1,59 @@
Clutter 1.1.4 (03/01/2010)
===============================================================================
* List of changes since Clutter 1.1.2
o Update the ClutterScript parser to be more resilient, and support
constructor and ChildMeta properties. The parser also respects the
order of the properties in the UI definitions when applying them,
and will apply the properties of an Actor after building the scene
graph.
o Simplified the implementation of LayoutManager sub-classes, and added
support for animating a layout manager.
o Allow short-circuiting some layout operations by setting a specific
flag on ClutterActor.
o Improve caching of the preferred size of a ClutterActor.
o Allow declaring "internal children" for a ClutterContainer
implementation: the memory management of these actors will be deferred
entirely to the Container.
o Let the ClutterStage honour the :opacity property and the alpha component
of the stage color. This requires support in the Clutter backend used.
o Improve Windows and OSX backends.
o Simplify the feature detection code for OpenGL; this also reduced the
required OpenGL version to 1.2.
o Improve the matrix stack handling code. The matrices can be debugged by
using the COGL_DEBUG environment variable, assuming that Clutter was
compiled with the right configure-time switch.
o Improve COGL API for draw buffers, and for offscreen buffer support.
o Add support for text direction to ClutterActor.
o Documentation, introspection and build fixes.
Many thanks to:
Robert Bragg
Neil Roberts
Damien Lespiau
Joshua Lock
Bastian Winkler
Rob Bradford
Samuel Degrande
Christian Persch
Colin Walters
Johan Bilien
Raymond Liu
Tim Horton
Clutter 1.1.2 (23/10/2009)
===============================================================================

139
README
View File

@ -1,5 +1,5 @@
Clutter 1.2 README
==================
Clutter - README
===============================================================================
Clutter is an open source software library for creating fast, visually
rich and animated graphical user interfaces.
@ -22,6 +22,9 @@ If you are building the Introspection data you will also need:
• GObject-Introspection >= 0.6.4
If you want built in support for profiling Clutter you will also need:
• UProf 0.2 available from git://git.moblin.org/uprof.git
The official website is:
http://www.clutter-project.org
@ -42,85 +45,115 @@ Clutter is licensed under the terms of the GNU Lesser General Public
License, version 2.1 or (at your option) later.
INSTALLATION
============
===============================================================================
See the INSTALL file. Info on specific Clutter options;
--enable-debug=[no/minimum/yes]
Controls Clutter debugging level (default=yes):
yes: All glib asserts, checks and runtime clutter verbose messages.
minimum: Just glib cast checks and runtime clutter verbose messagaes.
no: No glib asserts or checks and no runtime clutter verbose messages
(Only really of use in extreme performance cases)
Controls Clutter debugging level:
yes:
All GLib asserts, checks and support for runtime Clutter
debugging notes through CLUTTER_DEBUG. This is the default
value for snapshots.
minimum:
Just GType cast checks and support for runtime Clutter
debugging notes through CLUTTER_DEBUG. This is the default
for stable releases.
no:
No GLib asserts or checks and no support for runtime Clutter
debugging notes. Only use in extreme performance and/or size
optimization cases.
--enable-cogl-debug=[no/minimum/yes]
Controls COGL debugging level (default=minimum):
yes: All runtime verbose messages and error checking for each GL
primitive
minimum: All runtime verbose messages
no: No error checking and no messages
yes:
Support for COGL debugging notes through COGL_DEBUG and
error checking for each GL primitive.
minimum:
Support for COGL debugging notes through COGL_DEBUG. This is
the default for snapshots.
no:
Disable support for COGL runtime debugging notes. This is
the default for stable releases.
--enable-maintainer-flags=[no/yes]
Use strict compiler flags (default=no)
Use strict compiler flags. This defaults to 'yes' for snapshots and
to 'no' for stable releases.
--enable-gtk-doc
use gtk-doc to build API documentation (default=no). Requires gtk-doc
present on system
present on the target system.
--enable-manual=[no/yes]
Build application developers manual. Requires jw and xmlto binaries.
Presently incomplete.
--enable-docs=[no/yes]
Build additional documentation. Requires xsltproc for DocBook
conversion, and optionally jw for PDF generation.
--with-flavour=[glx/eglx/eglnative/sdl/osx/win32/fruity]
--with-flavour=[glx/eglx/eglnative/sdl/osx/win32/fruity]
Select the Clutter backend: (default=glx)
glx: Fully featured GLX backend. Using Open GL.
glx:
Fully featured GLX backend. Using Open GL.
eglx: EGL/Open GL ES backend for EGL on X windows implementations
eglx:
EGL/Open GL ES backend for EGL on X windows implementations
eglnative:
eglnative:
EGL/Open GL ES backend on 'native windowing system' - i.e
raw framebuffer. Expects the EGL implementation to provide
a createNativeWindow() call. Also it optionally supports
tslib for touchscreen events.
sdl: Basic SDL backend, using Open GL. Should provide portability
sdl:
Basic SDL backend, using Open GL. Should provide portability
to Windows and possibly other OS's. (DEPRECATED)
osx: OS X backend. (EXPERIMENTAL)
osx:
OS X backend. (EXPERIMENTAL)
win32:
win32:
Microsoft Windows(tm) WGL backend
fruity:
fruity:
Apple iPod Touch(tm)/iPhone(tm) backend (EXPERIMENTAL)
--with-imagebackend=[gdk-pixbuf/quartz/internal]
--with-imagebackend=[gdk-pixbuf/quartz/internal]
Select the image loading backend used by COGL
gdk-pixbuf: Depend on gdk-pixbuf-2.0 (default for the glx, eglx,
eglnative, sdl, win32 flavours and recommended)
gdk-pixbuf:
Depend on gdk-pixbuf-2.0 (default for the glx, eglx,
eglnative, sdl, win32 flavours and recommended)
quartz: Depend on CoreGraphics (default for the osx flavour)
quartz:
Depend on CoreGraphics (default for the osx flavour)
internal: Internal JPEG and PNG loader. Should only be used
for testing on new platforms
internal:
Internal JPEG and PNG loader. Should only be used
for testing on new platforms
--with-gles=[1.1/2.0]
--with-gles=[1.1/2.0]
Select the GLES version (for EGL backends) (default=1.1)
--with-json=[internal/check/system]
--with-json=[internal/check/system]
Select the JSON-GLib copy to use (default=check)
internal: Use the internal copy of JSON-GLib for ClutterScript
internal:
Use the internal copy of JSON-GLib for ClutterScript
check: Check for the existence of a system copy of JSON-GLib
and if it is available, make Clutter depend on it
check:
Check for the existence of a system copy of JSON-GLib
and if it is available, make Clutter depend on it
system: Only use the system copy of JSON-GLib
system:
Only use the system copy of JSON-GLib
VERSIONING
==========
===============================================================================
Clutter uses the common "Linux kernel" versioning system, where
even-numbered minor versions are stable and odd-numbered minor
@ -137,7 +170,7 @@ numbers are only used for released archives; odd micro numbers are
only used on the SVN repository.
HACKING
=======
===============================================================================
If you want to hack on and improve Clutter, check the contained TODO
file for pending tasks, the HACKING file for general implementation guidelines,
@ -147,7 +180,7 @@ used throughout Clutter. Remember: the coding style is mandatory; patches
not conforming to it will be rejected.
BUGS
====
===============================================================================
Bugs should be reported to the OpenedHand Bugzilla at:
@ -171,8 +204,8 @@ behaviour.
If the bug exposes a crash, the exact text printed out and a stack trace
obtained using gdb are greatly appreciated.
PATCHES
=======
CONTRIBUTING
===============================================================================
Patches should be submitted using Bugzilla. Patches fixing a bug should be
attached to the bug report; patches for new features or for fixing bugs not
@ -199,13 +232,13 @@ If you do not intend to waive your copyright you should contact the Clutter
development team to arrange a suitable solution.
RELEASE NOTES
=============
===============================================================================
Relevant information for developers with existing Clutter applications
wanting to port to newer releases (See NEWS for general new feature info).
Release Notes for Clutter 1.2
-------------------------------
-------------------------------------------------------------------------------
* ClutterStageManager is now publicly available and documented API.
@ -213,7 +246,7 @@ Release Notes for Clutter 1.2
back to the internal copy only if JSON-GLib is not installed.
Cogl API changes for Clutter 1.2
--------------------------------
-------------------------------------------------------------------------------
* cogl_viewport is now deprecated in favour of cogl_set_viewport which
accepts a viewport offset.
@ -250,7 +283,7 @@ Cogl API changes for Clutter 1.2
Release Notes for Clutter 1.0
-------------------------------
-------------------------------------------------------------------------------
* The clutter_actor_set_shader_param() function now takes a
GValue, which can be set using the clutter_value_set_shader()
@ -365,8 +398,8 @@ Release Notes for Clutter 1.0
takes the duration of the timeline in milliseconds, and thus it replaces
the clutter_timeline_new_for_duration() variant.
Cogl API changes for Clutter 1.0
--------------------------------
Cogl API changes for Clutter 1.0
-------------------------------------------------------------------------------
* All drawing functions now use a source material to determine how geometry is
filled. The source material is set via cogl_set_source. Or the convenience
@ -473,7 +506,7 @@ Release Notes for Clutter 1.0
a corresponding cogl_get_depth_test_enabled function has been added.
Release Notes for Clutter 0.8
-------------------------------
-------------------------------------------------------------------------------
* The COGL GL wrapper API has been completely overhauled and now
contains many new features including new greatly improved texture
@ -639,7 +672,7 @@ Release Notes for Clutter 0.8
* ClutterContainer can have per child custom properties via ClutterChildMeta.
Release Notes for Clutter 0.6
-------------------------------
-------------------------------------------------------------------------------
* Now that every actor has events, the class signal handlers have been
removed from ClutterStageClass and moved into ClutterActorClass.
@ -728,7 +761,7 @@ Release Notes for Clutter 0.6
respectively.
Release Notes for Clutter 0.4.0
-------------------------------
-------------------------------------------------------------------------------
* clutter_actor_show_all does not recurse for groups at least (this is to
match the original group_show_all behaviour). This is like 0.3 but was
@ -747,7 +780,7 @@ Release Notes for Clutter 0.4.0
overhauled.
Release Notes for Clutter 0.3.1
-------------------------------
-------------------------------------------------------------------------------
* clutter_actor_apply_transform_to_point() parameters changed to use
ClutterVertices.
@ -758,7 +791,7 @@ Release Notes for Clutter 0.3.1
* Exisiting X11 based egl backend public API calls now prefixed eglx.
Release Notes for Clutter 0.3
-----------------------------
-------------------------------------------------------------------------------
* ClutterTexture changes:
+ clutter_texture_set_pixbuf() now takes a GError paremeter.

View File

@ -1 +1,3 @@
SUBDIRS = autotools
EXTRA_DIST = gen-gcov.pl

View File

@ -5,6 +5,7 @@ EXTRA_DIST = \
Makefile.am.marshal \
Makefile.am.enums \
Makefile.am.changelog \
Makefile.am.gcov \
dolt.m4 \
introspection.m4 \
gtk-doc.m4 \

View File

@ -0,0 +1,33 @@
if GCOV_ENABLED
gcov-report.txt: gcov-clean
$(QUIET_GEN)(rm -f $@; \
echo -e "Test coverage for Clutter:\n" >> $@; \
total_covered=0; total_actual=0; \
for file in $(filter %.c,$(gcov_sources)); do \
gcov -o .libs/$${file/.c/.gcda} $$file > /dev/null; \
if test -f $$file.gcov; then \
actual=`grep -v ' -:' $$file.gcov | wc -l`; \
uncovered=`grep '#####:' $$file.gcov | wc -l`; \
covered=$$((actual - uncovered)); \
total_covered=$$((total_covered + covered)); \
total_actual=$$((total_actual + actual)); \
perl $(top_builddir)/build/gen-gcov.pl $$file.gcov; \
fi \
done >> $@; \
cd $(abs_srcdir); \
echo -e "\nSource lines: $$total_actual\nCovered statements: $$total_covered\nTotal coverage: $$((($$total_covered * 100) / $$total_actual))%" >> $@)
gcov: gcov-report.txt
@echo ""; cat gcov-report.txt
gcov-clean:
@find . -name "*.gcda" -o -name "*.gcov" -delete
else
gcov-report.txt:
@true
gcov-clean:
@true
gcov:
@echo "Need to reconfigure with --enable-gcov"
endif # GCOV_ENABLED
.PHONY: gcov gcov-clean gcov-report.txt

44
build/gen-gcov.pl Executable file
View File

@ -0,0 +1,44 @@
#!/usr/bin/perl
use strict;
use warnings;
our $gcov_file = $ARGV[0] or undef;
open my $g, '<', $gcov_file
or die("Unable to open '$gcov_file': $!");
my ($actual, $covered, $uncovered, $percent) = (0, 0, 0, 0);
while (<$g>) {
my $report_line = $_;
chomp($report_line);
$actual += 1;
$actual -= 1 if $report_line =~ / -:/;
$uncovered += 1 if $report_line =~ /#####:/;
}
close($g);
$covered = $actual - $uncovered;
$percent = int(($covered * 100) / $actual);
$gcov_file =~ s/^\.\///g;
$gcov_file =~ s/\.gcov$//g;
my $cover_file = "$gcov_file:";
my $cover_literal = "$covered / $actual";
my $cover_percent = "$percent%";
format ReportLine =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>>>>>>>> @>>>>>
$cover_file, $cover_literal, $cover_percent
.
$~ = 'ReportLine';
write;
0;

View File

@ -41,14 +41,7 @@ AM_CPPFLAGS = \
$(CLUTTER_DEBUG_CFLAGS) \
$(NULL)
AM_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS)
LDADD = \
$(CLUTTER_LT_LDFLAGS) \
-export-dynamic \
-export-symbols-regex "^(clutter|cogl|json).*" \
-rpath $(libdir) \
$(NULL)
AM_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS) $(GCOV_CFLAGS)
# please, keep this sorted alphabetically
source_h = \
@ -152,7 +145,6 @@ source_c = \
$(srcdir)/clutter-flow-layout.c \
$(srcdir)/clutter-frame-source.c \
$(srcdir)/clutter-group.c \
$(srcdir)/clutter-id-pool.c \
$(srcdir)/clutter-interval.c \
$(srcdir)/clutter-layout-manager.c \
$(srcdir)/clutter-layout-meta.c \
@ -176,12 +168,17 @@ source_c = \
$(srcdir)/clutter-texture.c \
$(srcdir)/clutter-text.c \
$(srcdir)/clutter-timeline.c \
$(srcdir)/clutter-timeout-interval.c \
$(srcdir)/clutter-timeout-pool.c \
$(srcdir)/clutter-units.c \
$(srcdir)/clutter-util.c \
$(NULL)
source_c_priv = \
$(srcdir)/clutter-id-pool.c \
$(srcdir)/clutter-profile.c \
$(srcdir)/clutter-timeout-interval.c \
$(NULL)
source_h_priv = \
$(srcdir)/clutter-bezier.h \
$(srcdir)/clutter-debug.h \
@ -192,6 +189,7 @@ source_h_priv = \
$(srcdir)/clutter-id-pool.h \
$(srcdir)/clutter-script-private.h \
$(srcdir)/clutter-timeout-interval.h \
$(srcdir)/clutter-profile.h \
$(NULL)
libclutter_@CLUTTER_WINSYS@_@CLUTTER_API_VERSION@_la_LIBADD = \
@ -212,9 +210,16 @@ libclutter_@CLUTTER_WINSYS@_@CLUTTER_API_VERSION@_la_DEPENDENCIES = \
libclutter_@CLUTTER_WINSYS@_@CLUTTER_API_VERSION@_la_SOURCES = \
$(source_c) \
$(source_h) \
$(source_c_priv) \
$(source_h_priv)
libclutter_@CLUTTER_WINSYS@_@CLUTTER_API_VERSION@_la_LDFLAGS = $(LDADD)
libclutter_@CLUTTER_WINSYS@_@CLUTTER_API_VERSION@_la_LDFLAGS = \
$(CLUTTER_LT_LDFLAGS) \
$(GCOV_LDFLAGS) \
-export-dynamic \
-export-symbols-regex "^(clutter|cogl|json).*" \
-rpath $(libdir) \
$(NULL)
lib_LTLIBRARIES = $(CLUTTER_WINSYS_LIB)
@ -316,3 +321,6 @@ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
CLEANFILES += $(BUILT_GIRSOURCES) $(typelibs_DATA)
endif # HAVE_INTROSPECTION
gcov_sources = $(source_c)
include $(top_srcdir)/build/autotools/Makefile.am.gcov

View File

@ -74,8 +74,8 @@
* clutter_actor_set_width(); or it can have a preferred width and
* height, which then allows a layout manager to implicitly size and
* position it by "allocating" an area for an actor. This allows for
* actors to be manipulate in both a fixed or static parent container
* (i.e. children of #ClutterGroup) and a more automatic or dynamic
* actors to be manipulated in both a fixed (or static) parent container
* (i.e. children of #ClutterGroup) and a more automatic (or dynamic)
* layout based parent container.
*
* When accessing the position and size of an actor, the simple accessors
@ -204,6 +204,7 @@
#include "clutter-private.h"
#include "clutter-debug.h"
#include "clutter-units.h"
#include "clutter-profile.h"
#include "cogl/cogl.h"
typedef struct _ShaderData ShaderData;
@ -234,6 +235,18 @@ struct _AnchorCoord
} v;
};
/* 3 entries should be a good compromise, few layout managers
* will ask for 3 different preferred size in each allocation cycle */
#define N_CACHED_SIZE_REQUESTS 3
typedef struct _SizeRequest SizeRequest;
struct _SizeRequest
{
guint age;
gfloat for_size;
gfloat min_size;
gfloat natural_size;
};
/* Internal enum used to control mapped state update. This is a hint
* which indicates when to do something other than just enforce
* invariants.
@ -262,14 +275,17 @@ struct _ClutterActorPrivate
/* request mode */
ClutterRequestMode request_mode;
/* our cached request width is for this height */
gfloat request_width_for_height;
gfloat request_min_width;
gfloat request_natural_width;
/* our cached size requests for different width / height */
SizeRequest width_requests[N_CACHED_SIZE_REQUESTS];
SizeRequest height_requests[N_CACHED_SIZE_REQUESTS];
/* our cached request height is for this width */
gfloat request_height_for_width;
/* An age of 0 means the entry is not set */
guint cached_height_age;
guint cached_width_age;
gfloat request_min_width;
gfloat request_min_height;
gfloat request_natural_width;
gfloat request_natural_height;
ClutterActorBox allocation;
@ -880,6 +896,7 @@ clutter_actor_real_map (ClutterActor *self)
g_assert (!CLUTTER_ACTOR_IS_MAPPED (self));
CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_MAPPED);
/* notify on parent mapped before potentially mapping
* children, so apps see a top-down notification.
*/
@ -993,20 +1010,29 @@ clutter_actor_real_show (ClutterActor *self)
ClutterActorPrivate *priv = self->priv;
CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_VISIBLE);
/* we notify on the "visible" flag in the clutter_actor_show()
* wrapper so the entire show signal emission completes first
* (?)
*/
clutter_actor_update_map_state (self, MAP_STATE_CHECK);
/* While an actor is hidden the parent may not have allocated/requested
* so we need to start from scratch and avoid the short-circuiting
* in clutter_actor_queue_relayout().
/* we queue a relayout unless the actor is inside a
* container that explicitly told us not to
*/
priv->needs_width_request = FALSE;
priv->needs_height_request = FALSE;
priv->needs_allocation = FALSE;
clutter_actor_queue_relayout (self);
if (priv->parent_actor &&
(!(priv->parent_actor->flags & CLUTTER_ACTOR_NO_LAYOUT)))
{
/* While an actor is hidden the parent may not have
* allocated/requested so we need to start from scratch
* and avoid the short-circuiting in
* clutter_actor_queue_relayout().
*/
priv->needs_width_request = FALSE;
priv->needs_height_request = FALSE;
priv->needs_allocation = FALSE;
clutter_actor_queue_relayout (self);
}
}
}
@ -1081,6 +1107,8 @@ clutter_actor_real_hide (ClutterActor *self)
{
if (CLUTTER_ACTOR_IS_VISIBLE (self))
{
ClutterActorPrivate *priv = self->priv;
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_VISIBLE);
/* we notify on the "visible" flag in the clutter_actor_hide()
@ -1089,7 +1117,12 @@ clutter_actor_real_hide (ClutterActor *self)
*/
clutter_actor_update_map_state (self, MAP_STATE_CHECK);
clutter_actor_queue_relayout (self);
/* we queue a relayout unless the actor is inside a
* container that explicitly told us not to
*/
if (priv->parent_actor &&
(!(priv->parent_actor->flags & CLUTTER_ACTOR_NO_LAYOUT)))
clutter_actor_queue_relayout (priv->parent_actor);
}
}
@ -1663,6 +1696,12 @@ clutter_actor_real_queue_relayout (ClutterActor *self)
priv->needs_height_request = TRUE;
priv->needs_allocation = TRUE;
/* reset the cached size requests */
memset (priv->width_requests, 0,
N_CACHED_SIZE_REQUESTS * sizeof (SizeRequest));
memset (priv->height_requests, 0,
N_CACHED_SIZE_REQUESTS * sizeof (SizeRequest));
/* always repaint also (no-op if not mapped) */
clutter_actor_queue_redraw (self);
@ -2329,6 +2368,15 @@ clutter_actor_paint (ClutterActor *self)
ClutterActorPrivate *priv;
ClutterMainContext *context;
gboolean clip_set = FALSE;
CLUTTER_STATIC_COUNTER (actor_paint_counter,
"Actor real-paint counter",
"Increments each time any actor is painted",
0 /* no application private data */);
CLUTTER_STATIC_COUNTER (actor_pick_counter,
"Actor pick-paint counter",
"Increments each time any actor is painted "
"for picking",
0 /* no application private data */);
g_return_if_fail (CLUTTER_IS_ACTOR (self));
@ -2384,6 +2432,8 @@ clutter_actor_paint (ClutterActor *self)
{
ClutterColor col = { 0, };
CLUTTER_COUNTER_INC (_clutter_uprof_context, actor_pick_counter);
_clutter_id_to_color (clutter_actor_get_gid (self), &col);
/* Actor will then paint silhouette of itself in supplied
@ -2394,6 +2444,8 @@ clutter_actor_paint (ClutterActor *self)
}
else
{
CLUTTER_COUNTER_INC (_clutter_uprof_context, actor_paint_counter);
clutter_actor_shader_pre_paint (self, FALSE);
self->priv->queued_redraw = FALSE;
@ -3001,8 +3053,14 @@ clutter_actor_dispose (GObject *object)
{
ClutterActor *parent = priv->parent_actor;
if (CLUTTER_IS_CONTAINER (parent))
clutter_container_remove_actor (CLUTTER_CONTAINER (parent), self);
/* go through the Container implementation unless this
* is an internal child and has been marked as such
*/
if (CLUTTER_IS_CONTAINER (parent) &&
!(CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_INTERNAL_CHILD))
{
clutter_container_remove_actor (CLUTTER_CONTAINER (parent), self);
}
else
priv->parent_actor = NULL;
}
@ -4392,6 +4450,9 @@ clutter_actor_init (ClutterActor *self)
priv->needs_height_request = TRUE;
priv->needs_allocation = TRUE;
priv->cached_width_age = 1;
priv->cached_height_age = 1;
priv->opacity_parent = NULL;
priv->enable_model_view_transform = TRUE;
@ -4500,7 +4561,6 @@ clutter_actor_queue_relayout (ClutterActor *self)
"not allowed",
priv->name ? priv->name
: G_OBJECT_TYPE_NAME (self));
return;
}
g_signal_emit (self, actor_signals[QUEUE_RELAYOUT], 0);
@ -4586,6 +4646,43 @@ clutter_actor_get_preferred_size (ClutterActor *self,
*natural_height_p = natural_height;
}
/* looks for a cached size request for this for_size. If not
* found, returns the oldest entry so it can be overwritten */
static gboolean
_clutter_actor_get_cached_size_request (gfloat for_size,
SizeRequest *cached_size_requests,
SizeRequest **result)
{
gboolean found_free_cache;
guint i;
found_free_cache = FALSE;
*result = &cached_size_requests[0];
for (i = 0; i < N_CACHED_SIZE_REQUESTS; i++)
{
SizeRequest *sr;
sr = &cached_size_requests[i];
if (sr->age > 0 &&
sr->for_size == for_size)
{
CLUTTER_NOTE (LAYOUT, "Size cache hit for size: %.2f", for_size);
*result = sr;
return TRUE;
}
else if (sr->age < (*result)->age)
{
*result = sr;
}
}
CLUTTER_NOTE (LAYOUT, "Size cache miss for size: %.2f", for_size);
return FALSE;
}
/**
* clutter_actor_get_preferred_width:
* @self: A #ClutterActor
@ -4616,14 +4713,23 @@ clutter_actor_get_preferred_width (ClutterActor *self,
{
ClutterActorClass *klass;
ClutterActorPrivate *priv;
gboolean found_in_cache;
SizeRequest *cached_size_request;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
klass = CLUTTER_ACTOR_GET_CLASS (self);
priv = self->priv;
if (priv->needs_width_request ||
priv->request_width_for_height != for_height)
found_in_cache = FALSE;
cached_size_request = &priv->width_requests[0];
if (!priv->needs_width_request)
found_in_cache = _clutter_actor_get_cached_size_request (for_height,
priv->width_requests,
&cached_size_request);
if (!found_in_cache)
{
gfloat min_width, natural_width;
@ -4641,16 +4747,21 @@ clutter_actor_get_preferred_width (ClutterActor *self,
if (natural_width < min_width)
natural_width = min_width;
if (!priv->min_width_set)
priv->request_min_width = min_width;
cached_size_request->min_size = min_width;
cached_size_request->natural_size = natural_width;
cached_size_request->for_size = for_height;
cached_size_request->age = priv->cached_width_age;
if (!priv->natural_width_set)
priv->request_natural_width = natural_width;
priv->request_width_for_height = for_height;
priv->cached_width_age ++;
priv->needs_width_request = FALSE;
}
if (!priv->min_width_set)
priv->request_min_width = cached_size_request->min_size;
if (!priv->natural_width_set)
priv->request_natural_width = cached_size_request->natural_size;
if (min_width_p)
*min_width_p = priv->request_min_width;
@ -4687,20 +4798,29 @@ clutter_actor_get_preferred_height (ClutterActor *self,
{
ClutterActorClass *klass;
ClutterActorPrivate *priv;
gboolean found_in_cache;
SizeRequest *cached_size_request;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
klass = CLUTTER_ACTOR_GET_CLASS (self);
priv = self->priv;
if (priv->needs_height_request ||
priv->request_height_for_width != for_width)
found_in_cache = FALSE;
cached_size_request = &priv->height_requests[0];
if (!priv->needs_height_request)
found_in_cache = _clutter_actor_get_cached_size_request (for_width,
priv->height_requests,
&cached_size_request);
if (!found_in_cache)
{
gfloat min_height, natural_height;
min_height = natural_height = 0;
CLUTTER_NOTE (LAYOUT, "Width request for %.2f px", for_width);
CLUTTER_NOTE (LAYOUT, "Height request for %.2f px", for_width);
klass->get_preferred_height (self, for_width,
&min_height,
@ -4713,15 +4833,31 @@ clutter_actor_get_preferred_height (ClutterActor *self,
natural_height = min_height;
if (!priv->min_height_set)
priv->request_min_height = min_height;
{
priv->request_min_height = min_height;
}
if (!priv->natural_height_set)
priv->request_natural_height = natural_height;
{
priv->request_natural_height = natural_height;
}
cached_size_request->min_size = min_height;
cached_size_request->natural_size = natural_height;
cached_size_request->for_size = for_width;
cached_size_request->age = priv->cached_height_age;
priv->cached_height_age ++;
priv->request_height_for_width = for_width;
priv->needs_height_request = FALSE;
}
if (!priv->min_height_set)
priv->request_min_height = cached_size_request->min_size;
if (!priv->natural_height_set)
priv->request_natural_height = cached_size_request->natural_size;
if (min_height_p)
*min_height_p = priv->request_min_height;
@ -6619,6 +6755,7 @@ clutter_actor_set_parent (ClutterActor *self,
{
ClutterActorPrivate *priv;
ClutterTextDirection text_dir;
ClutterMainContext *ctx;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (CLUTTER_IS_ACTOR (parent));
@ -6648,6 +6785,14 @@ clutter_actor_set_parent (ClutterActor *self,
g_object_ref_sink (self);
priv->parent_actor = parent;
ctx = _clutter_context_get_default ();
/* if push_internal() has been called then we automatically set
* the flag on the actor
*/
if (ctx->internal_child)
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_INTERNAL_CHILD);
/* clutter_actor_reparent() will emit ::parent-set for us */
if (!(CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IN_REPARENT))
g_signal_emit (self, actor_signals[PARENT_SET], 0, NULL);
@ -6825,17 +6970,22 @@ clutter_actor_reparent (ClutterActor *self,
g_object_ref (self);
if (CLUTTER_IS_CONTAINER (priv->parent_actor))
/* go through the Container implementation if this is a regular
* child and not an internal one
*/
if (CLUTTER_IS_CONTAINER (priv->parent_actor) &&
!(CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_INTERNAL_CHILD))
{
ClutterContainer *parent = CLUTTER_CONTAINER (priv->parent_actor);
/* Note, will call unparent() */
/* this will have to call unparent() */
clutter_container_remove_actor (parent, self);
}
else
clutter_actor_unparent (self);
if (CLUTTER_IS_CONTAINER (new_parent))
/* Note, will call parent() */
if (CLUTTER_IS_CONTAINER (new_parent))
clutter_container_add_actor (CLUTTER_CONTAINER (new_parent), self);
else
clutter_actor_set_parent (self, new_parent);
@ -8317,6 +8467,53 @@ clutter_actor_box_from_vertices (ClutterActorBox *box,
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 + 0.5);
box->y1 = floorf (box->y1 + 0.5);
box->x2 = floorf (box->x2 + 0.5);
box->y2 = floorf (box->y2 + 0.5);
}
/******************************************************************************/
struct _ShaderData
@ -9448,7 +9645,8 @@ clutter_actor_set_text_direction (ClutterActor *self,
* Retrieves the value set using clutter_actor_set_text_direction()
*
* If no text direction has been previously set, the default text
* direction will be returned
* direction, as returned by clutter_get_default_text_direction(), will
* be returned instead
*
* Return value: the #ClutterTextDirection for the actor
*
@ -9470,3 +9668,83 @@ clutter_actor_get_text_direction (ClutterActor *self)
return priv->text_direction;
}
/**
* clutter_actor_push_internal:
*
* Should be used by actors implementing the #ClutterContainer and with
* internal children added through clutter_actor_set_parent(), for instance:
*
* |[
* static void
* my_actor_init (MyActor *self)
* {
* self->priv = SELF_ACTOR_GET_PRIVATE (self);
*
* clutter_actor_push_internal ();
*
* /&ast; calling clutter_actor_set_parent() now will result in
* &ast; the internal flag being set on a child of MyActor
* &ast;/
*
* /&ast; internal child: a background texture &ast;/
* self->priv->background_tex = clutter_texture_new ();
* clutter_actor_set_parent (self->priv->background_tex,
* CLUTTER_ACTOR (self));
*
* /&ast; internal child: a label &ast;/
* self->priv->label = clutter_text_new ();
* clutter_actor_set_parent (self->priv->label,
* CLUTTER_ACTOR (self));
*
* clutter_actor_pop_internal ();
*
* /&ast; calling clutter_actor_set_parent() now will not result in
* &ast; the internal flag being set on a child of MyActor
* &ast;/
* }
* ]|
*
* This function will be used by Clutter to toggle an "internal child"
* flag whenever clutter_actor_set_parent() is called; internal children
* are handled differently by Clutter, specifically when destroying their
* parent.
*
* Call clutter_actor_pop_internal() when you finished adding internal
* children.
*
* Nested calls to clutter_actor_push_internal() are allowed, but each
* one must by followed by a clutter_actor_pop_internal() call.
*
* Since: 1.2
*/
void
clutter_actor_push_internal (void)
{
ClutterMainContext *ctx = _clutter_context_get_default ();
ctx->internal_child += 1;
}
/**
* clutter_actor_pop_internal:
*
* Disables the effects of clutter_actor_pop_internal()
*
* Since: 1.2
*/
void
clutter_actor_pop_internal (void)
{
ClutterMainContext *ctx = _clutter_context_get_default ();
if (ctx->internal_child == 0)
{
g_warning ("Mismatched %s: you need to call "
"clutter_actor_push_composite() at least once before "
"calling this function", G_STRFUNC);
return;
}
ctx->internal_child -= 1;
}

View File

@ -93,21 +93,26 @@ typedef void (*ClutterCallback) (ClutterActor *actor,
/**
* ClutterActorFlags:
* @CLUTTER_ACTOR_MAPPED: the actor will be painted (is visible, and inside a toplevel, and all parents visible)
* @CLUTTER_ACTOR_MAPPED: the actor will be painted (is visible, and inside
* a toplevel, and all parents visible)
* @CLUTTER_ACTOR_REALIZED: the resources associated to the actor have been
* allocated
* @CLUTTER_ACTOR_REACTIVE: the actor 'reacts' to mouse events emmitting event
* signals
* @CLUTTER_ACTOR_VISIBLE: the actor has been shown by the application program
* @CLUTTER_ACTOR_NO_LAYOUT: the actor provides an explicit layout management
* policy for its children; this flag will prevent Clutter from automatic
* queueing of relayout and will defer all layouting to the actor itself
*
* Flags used to signal the state of an actor.
*/
typedef enum
{
CLUTTER_ACTOR_MAPPED = 1 << 1,
CLUTTER_ACTOR_REALIZED = 1 << 2,
CLUTTER_ACTOR_REACTIVE = 1 << 3,
CLUTTER_ACTOR_VISIBLE = 1 << 4
CLUTTER_ACTOR_MAPPED = 1 << 1,
CLUTTER_ACTOR_REALIZED = 1 << 2,
CLUTTER_ACTOR_REACTIVE = 1 << 3,
CLUTTER_ACTOR_VISIBLE = 1 << 4,
CLUTTER_ACTOR_NO_LAYOUT = 1 << 5
} ClutterActorFlags;
/**
@ -532,6 +537,9 @@ void clutter_actor_set_text_direction (ClutterActor *sel
ClutterTextDirection text_dir);
ClutterTextDirection clutter_actor_get_text_direction (ClutterActor *self);
void clutter_actor_push_internal (void);
void clutter_actor_pop_internal (void);
G_END_DECLS
#endif /* __CLUTTER_ACTOR_H__ */

View File

@ -46,6 +46,7 @@
#include "clutter-fixed.h"
#include "clutter-marshal.h"
#include "clutter-private.h"
#include "clutter-profile.h"
#include <cogl/cogl.h>
@ -302,10 +303,24 @@ _clutter_backend_redraw (ClutterBackend *backend,
ClutterStage *stage)
{
ClutterBackendClass *klass;
CLUTTER_STATIC_COUNTER (redraw_counter,
"_clutter_backend_redraw counter",
"Increments for each _clutter_backend_redraw call",
0 /* no application private data */);
CLUTTER_STATIC_TIMER (redraw_timer,
"Mainloop", /* parent */
"Redrawing",
"The time spent redrawing everything",
0 /* no application private data */);
CLUTTER_COUNTER_INC (_clutter_uprof_context, redraw_counter);
CLUTTER_TIMER_START (_clutter_uprof_context, redraw_timer);
klass = CLUTTER_BACKEND_GET_CLASS (backend);
if (G_LIKELY (klass->redraw))
klass->redraw (backend, stage);
CLUTTER_TIMER_STOP (_clutter_uprof_context, redraw_timer);
}
gboolean

View File

@ -94,8 +94,13 @@ struct _ClutterBoxLayoutPrivate
guint spacing;
guint is_vertical : 1;
guint is_pack_start : 1;
gulong easing_mode;
guint easing_duration;
guint is_vertical : 1;
guint is_pack_start : 1;
guint is_animating : 1;
guint use_animations : 1;
};
struct _ClutterBoxChild
@ -109,6 +114,11 @@ struct _ClutterBoxChild
guint y_fill : 1;
guint expand : 1;
/* the last stable allocation before an animation; it is
* used as the initial ActorBox when interpolating
*/
ClutterActorBox *last_allocation;
};
enum
@ -128,7 +138,10 @@ enum
PROP_SPACING,
PROP_VERTICAL,
PROP_PACK_START
PROP_PACK_START,
PROP_USE_ANIMATIONS,
PROP_EASING_MODE,
PROP_EASING_DURATION
};
G_DEFINE_TYPE (ClutterBoxChild,
@ -167,9 +180,19 @@ box_child_set_align (ClutterBoxChild *self,
if (x_changed || y_changed)
{
ClutterLayoutManager *layout;
ClutterBoxLayout *box;
layout = clutter_layout_meta_get_manager (CLUTTER_LAYOUT_META (self));
clutter_layout_manager_layout_changed (layout);
box = CLUTTER_BOX_LAYOUT (layout);
if (box->priv->use_animations)
{
clutter_layout_manager_begin_animation (layout,
box->priv->easing_duration,
box->priv->easing_mode);
}
else
clutter_layout_manager_layout_changed (layout);
if (x_changed)
g_object_notify (G_OBJECT (self), "x-align");
@ -203,9 +226,19 @@ box_child_set_fill (ClutterBoxChild *self,
if (x_changed || y_changed)
{
ClutterLayoutManager *layout;
ClutterBoxLayout *box;
layout = clutter_layout_meta_get_manager (CLUTTER_LAYOUT_META (self));
clutter_layout_manager_layout_changed (layout);
box = CLUTTER_BOX_LAYOUT (layout);
if (box->priv->use_animations)
{
clutter_layout_manager_begin_animation (layout,
box->priv->easing_duration,
box->priv->easing_mode);
}
else
clutter_layout_manager_layout_changed (layout);
if (x_changed)
g_object_notify (G_OBJECT (self), "x-fill");
@ -222,11 +255,21 @@ box_child_set_expand (ClutterBoxChild *self,
if (self->expand != expand)
{
ClutterLayoutManager *layout;
ClutterBoxLayout *box;
self->expand = expand;
layout = clutter_layout_meta_get_manager (CLUTTER_LAYOUT_META (self));
clutter_layout_manager_layout_changed (layout);
box = CLUTTER_BOX_LAYOUT (layout);
if (box->priv->use_animations)
{
clutter_layout_manager_begin_animation (layout,
box->priv->easing_duration,
box->priv->easing_mode);
}
else
clutter_layout_manager_layout_changed (layout);
g_object_notify (G_OBJECT (self), "expand");
}
@ -312,6 +355,16 @@ clutter_box_child_get_property (GObject *gobject,
}
}
static void
clutter_box_child_finalize (GObject *gobject)
{
ClutterBoxChild *self = CLUTTER_BOX_CHILD (gobject);
clutter_actor_box_free (self->last_allocation);
G_OBJECT_CLASS (clutter_box_child_parent_class)->finalize (gobject);
}
static void
clutter_box_child_class_init (ClutterBoxChildClass *klass)
{
@ -320,6 +373,7 @@ clutter_box_child_class_init (ClutterBoxChildClass *klass)
gobject_class->set_property = clutter_box_child_set_property;
gobject_class->get_property = clutter_box_child_get_property;
gobject_class->finalize = clutter_box_child_finalize;
pspec = g_param_spec_boolean ("expand",
"Expand",
@ -374,6 +428,8 @@ clutter_box_child_init (ClutterBoxChild *self)
self->x_fill = self->y_fill = FALSE;
self->expand = FALSE;
self->last_allocation = NULL;
}
static inline void
@ -698,14 +754,6 @@ allocate_box_child (ClutterBoxLayout *self,
child_box.x1 = 0;
child_box.x2 = floorf (avail_width + 0.5);
allocate_fill (child, &child_box, box_child);
clutter_actor_allocate (child, &child_box, flags);
if (box_child->expand)
*position += (child_nat + priv->spacing + extra_space);
else
*position += (child_nat + priv->spacing);
}
else
{
@ -721,15 +769,61 @@ allocate_box_child (ClutterBoxLayout *self,
child_box.y1 = 0;
child_box.y2 = floorf (avail_height + 0.5);
allocate_fill (child, &child_box, box_child);
clutter_actor_allocate (child, &child_box, flags);
if (box_child->expand)
*position += (child_nat + priv->spacing + extra_space);
else
*position += (child_nat + priv->spacing);
}
allocate_fill (child, &child_box, box_child);
if (priv->use_animations && priv->is_animating)
{
ClutterLayoutManager *manager = CLUTTER_LAYOUT_MANAGER (self);
ClutterActorBox *start = NULL;
ClutterActorBox end = { 0, };
gdouble p;
p = clutter_layout_manager_get_animation_progress (manager);
start = box_child->last_allocation;
if (start == NULL)
{
/* if there is no allocation available then the child has just
* been added to the container; we put it in the final state
* and store its allocation for later
*/
box_child->last_allocation = clutter_actor_box_copy (&child_box);
goto do_allocate;
}
end = child_box;
/* interpolate between the initial and final values */
clutter_actor_box_interpolate (start, &end, p, &child_box);
CLUTTER_NOTE (ANIMATION,
"Animate { %.1f, %.1f, %.1f, %.1f }\t"
"%.3f * { %.1f, %.1f, %.1f, %.1f }\t"
"-> { %.1f, %.1f, %.1f, %.1f }",
start->x1, start->y1,
start->x2, start->y2,
p,
child_box.x1, child_box.y1,
child_box.x2, child_box.y2,
end.x1, end.y1,
end.x2, end.y2);
}
else
{
/* store the allocation for later animations */
box_child->last_allocation = clutter_actor_box_copy (&child_box);
}
do_allocate:
clutter_actor_allocate (child, &child_box, flags);
if (box_child->expand)
*position += (child_nat + priv->spacing + extra_space);
else
*position += (child_nat + priv->spacing);
}
static void
@ -887,6 +981,35 @@ clutter_box_layout_allocate (ClutterLayoutManager *layout,
g_list_free (children);
}
static ClutterAlpha *
clutter_box_layout_begin_animation (ClutterLayoutManager *manager,
guint duration,
gulong easing)
{
ClutterBoxLayoutPrivate *priv = CLUTTER_BOX_LAYOUT (manager)->priv;
ClutterLayoutManagerClass *parent_class;
priv->is_animating = TRUE;
/* we want the default implementation */
parent_class = CLUTTER_LAYOUT_MANAGER_CLASS (clutter_box_layout_parent_class);
return parent_class->begin_animation (manager, duration, easing);
}
static void
clutter_box_layout_end_animation (ClutterLayoutManager *manager)
{
ClutterBoxLayoutPrivate *priv = CLUTTER_BOX_LAYOUT (manager)->priv;
ClutterLayoutManagerClass *parent_class;
priv->is_animating = FALSE;
/* we want the default implementation */
parent_class = CLUTTER_LAYOUT_MANAGER_CLASS (clutter_box_layout_parent_class);
parent_class->end_animation (manager);
}
static void
clutter_box_layout_set_property (GObject *gobject,
guint prop_id,
@ -909,6 +1032,18 @@ clutter_box_layout_set_property (GObject *gobject,
clutter_box_layout_set_pack_start (self, g_value_get_boolean (value));
break;
case PROP_USE_ANIMATIONS:
clutter_box_layout_set_use_animations (self, g_value_get_boolean (value));
break;
case PROP_EASING_MODE:
clutter_box_layout_set_easing_mode (self, g_value_get_ulong (value));
break;
case PROP_EASING_DURATION:
clutter_box_layout_set_easing_duration (self, g_value_get_uint (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
@ -937,6 +1072,18 @@ clutter_box_layout_get_property (GObject *gobject,
g_value_set_boolean (value, priv->is_pack_start);
break;
case PROP_USE_ANIMATIONS:
g_value_set_boolean (value, priv->use_animations);
break;
case PROP_EASING_MODE:
g_value_set_ulong (value, priv->easing_mode);
break;
case PROP_EASING_DURATION:
g_value_set_uint (value, priv->easing_duration);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
@ -963,6 +1110,8 @@ clutter_box_layout_class_init (ClutterBoxLayoutClass *klass)
layout_class->set_container = clutter_box_layout_set_container;
layout_class->get_child_meta_type =
clutter_box_layout_get_child_meta_type;
layout_class->begin_animation = clutter_box_layout_begin_animation;
layout_class->end_animation = clutter_box_layout_end_animation;
g_type_class_add_private (klass, sizeof (ClutterBoxLayoutPrivate));
@ -1010,6 +1159,62 @@ clutter_box_layout_class_init (ClutterBoxLayoutClass *klass)
0, G_MAXUINT, 0,
CLUTTER_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_SPACING, pspec);
/**
* ClutterBoxLayout:use-animations:
*
* Whether the #ClutterBoxLayout should animate changes in the
* layout properties
*
* Since: 1.2
*/
pspec = g_param_spec_boolean ("use-animations",
"Use Animations",
"Whether layout changes should be animated",
FALSE,
CLUTTER_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_USE_ANIMATIONS, pspec);
/**
* ClutterBoxLayout:easing-mode:
*
* The easing mode for the animations, in case
* #ClutterBoxLayout:use-animations is set to %TRUE
*
* The easing mode has the same semantics of #ClutterAnimation:mode: it can
* either be a value from the #ClutterAnimationMode enumeration, like
* %CLUTTER_EASE_OUT_CUBIC, or a logical id as returned by
* clutter_alpha_register_func()
*
* The default value is %CLUTTER_EASE_OUT_CUBIC
*
* Since: 1.2
*/
pspec = g_param_spec_ulong ("easing-mode",
"Easing Mode",
"The easing mode of the animations",
0, G_MAXULONG,
CLUTTER_EASE_OUT_CUBIC,
CLUTTER_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_EASING_MODE, pspec);
/**
* ClutterBoxLayout:easing-duration:
*
* The duration of the animations, in case #ClutterBoxLayout:use-animations
* is set to %TRUE
*
* The duration is expressed in milliseconds
*
* Since: 1.2
*/
pspec = g_param_spec_uint ("easing-duration",
"Easing Duration",
"The duration of the animations",
0, G_MAXUINT,
500,
CLUTTER_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_EASING_DURATION, pspec);
}
static void
@ -1022,6 +1227,10 @@ clutter_box_layout_init (ClutterBoxLayout *layout)
priv->is_vertical = FALSE;
priv->is_pack_start = FALSE;
priv->spacing = 0;
priv->use_animations = FALSE;
priv->easing_mode = CLUTTER_EASE_OUT_CUBIC;
priv->easing_duration = 500;
}
/**
@ -1065,7 +1274,15 @@ clutter_box_layout_set_spacing (ClutterBoxLayout *layout,
priv->spacing = spacing;
manager = CLUTTER_LAYOUT_MANAGER (layout);
clutter_layout_manager_layout_changed (manager);
if (priv->use_animations)
{
clutter_layout_manager_begin_animation (manager,
priv->easing_duration,
priv->easing_mode);
}
else
clutter_layout_manager_layout_changed (manager);
g_object_notify (G_OBJECT (layout), "spacing");
}
@ -1116,7 +1333,15 @@ clutter_box_layout_set_vertical (ClutterBoxLayout *layout,
priv->is_vertical = vertical ? TRUE : FALSE;
manager = CLUTTER_LAYOUT_MANAGER (layout);
clutter_layout_manager_layout_changed (manager);
if (priv->use_animations)
{
clutter_layout_manager_begin_animation (manager,
priv->easing_duration,
priv->easing_mode);
}
else
clutter_layout_manager_layout_changed (manager);
g_object_notify (G_OBJECT (layout), "vertical");
}
@ -1170,7 +1395,15 @@ clutter_box_layout_set_pack_start (ClutterBoxLayout *layout,
priv->is_pack_start = pack_start ? TRUE : FALSE;
manager = CLUTTER_LAYOUT_MANAGER (layout);
clutter_layout_manager_layout_changed (manager);
if (priv->use_animations)
{
clutter_layout_manager_begin_animation (manager,
priv->easing_duration,
priv->easing_mode);
}
else
clutter_layout_manager_layout_changed (manager);
g_object_notify (G_OBJECT (layout), "pack-start");
}
@ -1574,3 +1807,154 @@ clutter_box_layout_get_expand (ClutterBoxLayout *layout,
return CLUTTER_BOX_CHILD (meta)->expand;
}
/**
* clutter_box_layout_set_use_animations:
* @layout: a #ClutterBoxLayout
* @animate: %TRUE if the @layout should use animations
*
* Sets whether @layout should animate changes in the layout properties
*
* The duration of the animations is controlled by
* clutter_box_layout_set_easing_duration(); the easing mode to be used
* by the animations is controlled by clutter_box_layout_set_easing_mode()
*
* Since: 1.2
*/
void
clutter_box_layout_set_use_animations (ClutterBoxLayout *layout,
gboolean animate)
{
ClutterBoxLayoutPrivate *priv;
g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
priv = layout->priv;
if (priv->use_animations != animate)
{
priv->use_animations = animate;
g_object_notify (G_OBJECT (layout), "use-animations");
}
}
/**
* clutter_box_layout_get_use_animations:
* @layout: a #ClutterBoxLayout
*
* Retrieves whether @layout should animate changes in the layout properties
*
* Since clutter_box_layout_set_use_animations()
*
* Return value: %TRUE if the animations should be used, %FALSE otherwise
*
* Since: 1.2
*/
gboolean
clutter_box_layout_get_use_animations (ClutterBoxLayout *layout)
{
g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout), FALSE);
return layout->priv->use_animations;
}
/**
* clutter_box_layout_set_easing_mode:
* @layout: a #ClutterBoxLayout
* @mode: an easing mode, either from #ClutterAnimationMode or a logical id
* from clutter_alpha_register_func()
*
* Sets the easing mode to be used by @layout when animating changes in layout
* properties
*
* Use clutter_box_layout_set_use_animations() to enable and disable the
* animations
*
* Since: 1.2
*/
void
clutter_box_layout_set_easing_mode (ClutterBoxLayout *layout,
gulong mode)
{
ClutterBoxLayoutPrivate *priv;
g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
priv = layout->priv;
if (priv->easing_mode != mode)
{
priv->easing_mode = mode;
g_object_notify (G_OBJECT (layout), "easing-mode");
}
}
/**
* clutter_box_layout_get_easing_mode:
* @layout: a #ClutterBoxLayout
*
* Retrieves the easing mode set using clutter_box_layout_set_easing_mode()
*
* Return value: an easing mode
*
* Since: 1.2
*/
gulong
clutter_box_layout_get_easing_mode (ClutterBoxLayout *layout)
{
g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout),
CLUTTER_EASE_OUT_CUBIC);
return layout->priv->easing_mode;
}
/**
* clutter_box_layout_set_easing_duration:
* @layout: a #ClutterBoxLayout
* @msecs: the duration of the animations, in milliseconds
*
* Sets the duration of the animations used by @layout when animating changes
* in the layout properties
*
* Use clutter_box_layout_set_use_animations() to enable and disable the
* animations
*
* Since: 1.2
*/
void
clutter_box_layout_set_easing_duration (ClutterBoxLayout *layout,
guint msecs)
{
ClutterBoxLayoutPrivate *priv;
g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
priv = layout->priv;
if (priv->easing_duration != msecs)
{
priv->easing_duration = msecs;
g_object_notify (G_OBJECT (layout), "easing-duration");
}
}
/**
* clutter_box_layout_get_easing_duration:
* @layout: a #ClutterBoxLayout
*
* Retrieves the duration set using clutter_box_layout_set_easing_duration()
*
* Return value: the duration of the animations, in milliseconds
*
* Since: 1.2
*/
guint
clutter_box_layout_get_easing_duration (ClutterBoxLayout *layout)
{
g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout), 500);
return layout->priv->easing_duration;
}

View File

@ -97,46 +97,56 @@ struct _ClutterBoxLayoutClass
GType clutter_box_layout_get_type (void) G_GNUC_CONST;
ClutterLayoutManager *clutter_box_layout_new (void);
ClutterLayoutManager *clutter_box_layout_new (void);
void clutter_box_layout_set_spacing (ClutterBoxLayout *layout,
guint spacing);
guint clutter_box_layout_get_spacing (ClutterBoxLayout *layout);
void clutter_box_layout_set_vertical (ClutterBoxLayout *layout,
gboolean vertical);
gboolean clutter_box_layout_get_vertical (ClutterBoxLayout *layout);
void clutter_box_layout_set_pack_start (ClutterBoxLayout *layout,
gboolean pack_start);
gboolean clutter_box_layout_get_pack_start (ClutterBoxLayout *layout);
void clutter_box_layout_set_spacing (ClutterBoxLayout *layout,
guint spacing);
guint clutter_box_layout_get_spacing (ClutterBoxLayout *layout);
void clutter_box_layout_set_vertical (ClutterBoxLayout *layout,
gboolean vertical);
gboolean clutter_box_layout_get_vertical (ClutterBoxLayout *layout);
void clutter_box_layout_set_pack_start (ClutterBoxLayout *layout,
gboolean pack_start);
gboolean clutter_box_layout_get_pack_start (ClutterBoxLayout *layout);
void clutter_box_layout_pack (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean expand,
gboolean x_fill,
gboolean y_fill,
ClutterBoxAlignment x_align,
ClutterBoxAlignment y_align);
void clutter_box_layout_set_alignment (ClutterBoxLayout *layout,
ClutterActor *actor,
ClutterBoxAlignment x_align,
ClutterBoxAlignment y_align);
void clutter_box_layout_get_alignment (ClutterBoxLayout *layout,
ClutterActor *actor,
ClutterBoxAlignment *x_align,
ClutterBoxAlignment *y_align);
void clutter_box_layout_set_fill (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean x_fill,
gboolean y_fill);
void clutter_box_layout_get_fill (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean *x_fill,
gboolean *y_fill);
void clutter_box_layout_set_expand (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean expand);
gboolean clutter_box_layout_get_expand (ClutterBoxLayout *layout,
ClutterActor *actor);
void clutter_box_layout_pack (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean expand,
gboolean x_fill,
gboolean y_fill,
ClutterBoxAlignment x_align,
ClutterBoxAlignment y_align);
void clutter_box_layout_set_alignment (ClutterBoxLayout *layout,
ClutterActor *actor,
ClutterBoxAlignment x_align,
ClutterBoxAlignment y_align);
void clutter_box_layout_get_alignment (ClutterBoxLayout *layout,
ClutterActor *actor,
ClutterBoxAlignment *x_align,
ClutterBoxAlignment *y_align);
void clutter_box_layout_set_fill (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean x_fill,
gboolean y_fill);
void clutter_box_layout_get_fill (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean *x_fill,
gboolean *y_fill);
void clutter_box_layout_set_expand (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean expand);
gboolean clutter_box_layout_get_expand (ClutterBoxLayout *layout,
ClutterActor *actor);
void clutter_box_layout_set_use_animations (ClutterBoxLayout *layout,
gboolean animate);
gboolean clutter_box_layout_get_use_animations (ClutterBoxLayout *layout);
void clutter_box_layout_set_easing_mode (ClutterBoxLayout *layout,
gulong mode);
gulong clutter_box_layout_get_easing_mode (ClutterBoxLayout *layout);
void clutter_box_layout_set_easing_duration (ClutterBoxLayout *layout,
guint msecs);
guint clutter_box_layout_get_easing_duration (ClutterBoxLayout *layout);
G_END_DECLS

View File

@ -661,48 +661,21 @@ clutter_box_packv (ClutterBox *box,
}
}
/**
* clutter_box_pack:
* @box: a #ClutterBox
* @actor: a #ClutterActor
* @first_property: the name of the first property to set, or %NULL
* @Varargs: a list of property name and value pairs, terminated by %NULL
*
* Adds @actor to @box and sets layout properties at the same time,
* if the #ClutterLayoutManager used by @box has them
*
* This function is a wrapper around clutter_container_add_actor()
* and clutter_layout_manager_child_set()
*
* Language bindings should use the vector-based clutter_box_addv()
* variant instead
*
* Since: 1.2
*/
void
clutter_box_pack (ClutterBox *box,
ClutterActor *actor,
const gchar *first_property,
...)
static inline void
clutter_box_set_property_valist (ClutterBox *box,
ClutterActor *actor,
const gchar *first_property,
va_list var_args)
{
ClutterBoxPrivate *priv;
ClutterContainer *container;
ClutterContainer *container = CLUTTER_CONTAINER (box);
ClutterBoxPrivate *priv = box->priv;
ClutterLayoutMeta *meta;
GObjectClass *klass;
const gchar *pname;
va_list var_args;
g_return_if_fail (CLUTTER_IS_BOX (box));
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
container = CLUTTER_CONTAINER (box);
clutter_container_add_actor (container, actor);
if (first_property == NULL || *first_property == '\0')
if (priv->manager == NULL)
return;
priv = box->priv;
meta = clutter_layout_manager_get_child_meta (priv->manager,
container,
actor);
@ -712,8 +685,6 @@ clutter_box_pack (ClutterBox *box,
klass = G_OBJECT_GET_CLASS (meta);
va_start (var_args, first_property);
pname = first_property;
while (pname)
{
@ -761,7 +732,183 @@ clutter_box_pack (ClutterBox *box,
pname = va_arg (var_args, gchar*);
}
}
/**
* clutter_box_pack:
* @box: a #ClutterBox
* @actor: a #ClutterActor
* @first_property: the name of the first property to set, or %NULL
* @Varargs: a list of property name and value pairs, terminated by %NULL
*
* Adds @actor to @box and sets layout properties at the same time,
* if the #ClutterLayoutManager used by @box has them
*
* This function is a wrapper around clutter_container_add_actor()
* and clutter_layout_manager_child_set()
*
* Language bindings should use the vector-based clutter_box_addv()
* variant instead
*
* Since: 1.2
*/
void
clutter_box_pack (ClutterBox *box,
ClutterActor *actor,
const gchar *first_property,
...)
{
va_list var_args;
g_return_if_fail (CLUTTER_IS_BOX (box));
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
clutter_container_add_actor (CLUTTER_CONTAINER (box), actor);
if (first_property == NULL || *first_property == '\0')
return;
va_start (var_args, first_property);
clutter_box_set_property_valist (box, actor, first_property, var_args);
va_end (var_args);
}
/**
* clutter_box_pack_after:
* @box: a #ClutterBox
* @actor: a #ClutterActor
* @sibling: (allow none): a #ClutterActor or %NULL
* @first_property: the name of the first property to set, or %NULL
* @Varargs: a list of property name and value pairs, terminated by %NULL
*
* Adds @actor to @box, placing it after @sibling, and sets layout
* properties at the same time, if the #ClutterLayoutManager used by
* @box supports them
*
* If @sibling is %NULL then @actor is placed at the end of the
* list of children, to be allocated and painted after every other child
*
* This function is a wrapper around clutter_container_add_actor(),
* clutter_container_raise_child() and clutter_layout_manager_child_set()
*
* Since: 1.2
*/
void
clutter_box_pack_after (ClutterBox *box,
ClutterActor *actor,
ClutterActor *sibling,
const gchar *first_property,
...)
{
va_list var_args;
g_return_if_fail (CLUTTER_IS_BOX (box));
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling));
clutter_container_add_actor (CLUTTER_CONTAINER (box), actor);
clutter_container_raise_child (CLUTTER_CONTAINER (box), actor, sibling);
if (first_property == NULL || *first_property == '\0')
return;
va_start (var_args, first_property);
clutter_box_set_property_valist (box, actor, first_property, var_args);
va_end (var_args);
}
/**
* clutter_box_pack_before:
* @box: a #ClutterBox
* @actor: a #ClutterActor
* @sibling: (allow none): a #ClutterActor or %NULL
* @first_property: the name of the first property to set, or %NULL
* @Varargs: a list of property name and value pairs, terminated by %NULL
*
* Adds @actor to @box, placing it before @sibling, and sets layout
* properties at the same time, if the #ClutterLayoutManager used by
* @box supports them
*
* If @sibling is %NULL then @actor is placed at the beginning of the
* list of children, to be allocated and painted below every other child
*
* This function is a wrapper around clutter_container_add_actor(),
* clutter_container_lower_child() and clutter_layout_manager_child_set()
*
* Since: 1.2
*/
void
clutter_box_pack_before (ClutterBox *box,
ClutterActor *actor,
ClutterActor *sibling,
const gchar *first_property,
...)
{
va_list var_args;
g_return_if_fail (CLUTTER_IS_BOX (box));
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling));
clutter_container_add_actor (CLUTTER_CONTAINER (box), actor);
clutter_container_lower_child (CLUTTER_CONTAINER (box), actor, sibling);
if (first_property == NULL || *first_property == '\0')
return;
va_start (var_args, first_property);
clutter_box_set_property_valist (box, actor, first_property, var_args);
va_end (var_args);
}
/**
* clutter_box_pack_at:
* @box: a #ClutterBox
* @actor: a #ClutterActor
* @position: the position to insert the @actor at
* @first_property: the name of the first property to set, or %NULL
* @Varargs: a list of property name and value pairs, terminated by %NULL
*
* Adds @actor to @box, placing it at @position, and sets layout
* properties at the same time, if the #ClutterLayoutManager used by
* @box supports them
*
* If @position is a negative number, or is larger than the number of
* children of @box, the new child is added at the end of the list of
* children
*
* Since: 1.2
*/
void
clutter_box_pack_at (ClutterBox *box,
ClutterActor *actor,
gint position,
const gchar *first_property,
...)
{
ClutterBoxPrivate *priv;
va_list var_args;
g_return_if_fail (CLUTTER_IS_BOX (box));
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
priv = box->priv;
/* this is really clutter_box_add() with a different insert() */
priv->children = g_list_insert (priv->children,
actor,
position);
clutter_actor_set_parent (actor, CLUTTER_ACTOR (box));
clutter_actor_queue_relayout (actor);
g_signal_emit_by_name (box, "actor-added", actor);
if (first_property == NULL || *first_property == '\0')
return;
va_start (var_args, first_property);
clutter_box_set_property_valist (box, actor, first_property, var_args);
va_end (var_args);
}

View File

@ -57,6 +57,22 @@ void clutter_box_packv (ClutterBox *box,
const gchar * const properties[],
const GValue *values);
void clutter_box_pack_after (ClutterBox *box,
ClutterActor *actor,
ClutterActor *sibling,
const gchar *first_property,
...) G_GNUC_NULL_TERMINATED;
void clutter_box_pack_before (ClutterBox *box,
ClutterActor *actor,
ClutterActor *sibling,
const gchar *first_property,
...) G_GNUC_NULL_TERMINATED;
void clutter_box_pack_at (ClutterBox *box,
ClutterActor *actor,
gint position,
const gchar *first_property,
...) G_GNUC_NULL_TERMINATED;
G_END_DECLS
#endif /* __CLUTTER_BOX_H__ */

View File

@ -765,6 +765,29 @@ clutter_get_current_event_time (void)
return CLUTTER_CURRENT_TIME;
}
/**
* clutter_get_current_event:
*
* If an event is currently being processed, return that event.
* This function is intended to be used to access event state
* that might not be exposed by higher-level widgets. For
* example, to get the key modifier state from a Button 'clicked'
* event.
*
* Return value: (transfer none): The current ClutterEvent, or %NULL if none
*
* Since: 1.2
*/
G_CONST_RETURN ClutterEvent *
clutter_get_current_event (void)
{
ClutterMainContext *context = _clutter_context_get_default ();
g_return_val_if_fail (context != NULL, NULL);
return context->current_event;
}
/**
* clutter_input_device_get_device_type:
* @device: a #ClutterInputDevice

View File

@ -507,6 +507,7 @@ ClutterScrollDirection clutter_event_get_scroll_direction (ClutterEvent *e
guint32 clutter_keysym_to_unicode (guint keyval);
guint32 clutter_get_current_event_time (void);
G_CONST_RETURN ClutterEvent *clutter_get_current_event (void);
ClutterInputDeviceType clutter_input_device_get_device_type (ClutterInputDevice *device);
gint clutter_input_device_get_device_id (ClutterInputDevice *device);

View File

@ -554,7 +554,7 @@ clutter_flow_layout_allocate (ClutterLayoutManager *manager,
clutter_actor_get_preferred_width (child, item_height,
&child_min,
&child_natural);
item_width = MIN (item_width, child_min);
item_width = MIN (item_width, child_natural);
clutter_actor_get_preferred_height (child, item_width,
&child_min,
@ -593,7 +593,7 @@ clutter_flow_layout_allocate (ClutterLayoutManager *manager,
clutter_actor_get_preferred_width (child, item_height,
&child_min,
&child_natural);
item_width = MIN (item_width, child_min);
item_width = MIN (item_width, child_natural);
clutter_actor_get_preferred_height (child, item_width,
&child_min,

View File

@ -441,6 +441,12 @@ clutter_group_init (ClutterGroup *self)
self->priv->layout = clutter_fixed_layout_new ();
g_object_ref_sink (self->priv->layout);
/* signal Clutter that we don't impose any layout on
* our children, so we can shave off some relayout
* operations
*/
CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_NO_LAYOUT);
}
/**

View File

@ -36,10 +36,10 @@
* a generic container using #ClutterLayoutManager called #ClutterBox.
*
* Clutter provides some simple #ClutterLayoutManager sub-classes, like
* #ClutterFixedLayout and #ClutterBinLayout.
* #ClutterFlowLayout and #ClutterBinLayout.
*
* <refsect2 id="ClutterLayoutManager-use-in-Actor">
* <title>Using ClutterLayoutManager inside an Actor</title>
* <title>Using a Layout Manager inside an Actor</title>
* <para>In order to use a #ClutterLayoutManager inside a #ClutterActor
* sub-class you should invoke clutter_layout_manager_get_preferred_width()
* inside the <structname>ClutterActor</structname>::get_preferred_width()
@ -56,10 +56,10 @@
* does not need to perform specific operations whenever a layout
* manager changes:</para>
* <informalexample><programlisting>
* g_signal_connect_swapped (layout_manager,
* "layout-changed",
* G_CALLBACK (clutter_actor_queue_relayout),
* actor);
* g_signal_connect_swapped (layout_manager,
* "layout-changed",
* G_CALLBACK (clutter_actor_queue_relayout),
* actor);
* </programlisting></informalexample>
* </refsect2>
*
@ -70,18 +70,20 @@
* #ClutterActor, so you should read the relative documentation
* <link linkend="clutter-subclassing-ClutterActor">for subclassing
* ClutterActor</link>.</para>
* <para>The layout manager implementation can hold a back reference
* to the #ClutterContainer by implementing the set_container()
* virtual function. The layout manager should not hold a reference
* on the container actor, to avoid reference cycles.</para>
* <para>The layout manager implementation can hold a back pointer
* to the #ClutterContainer by implementing the
* <function>set_container()</function> virtual function. The layout manager
* should not hold a real reference (i.e. call g_object_ref()) on the
* container actor, to avoid reference cycles.</para>
* <para>If the layout manager has properties affecting the layout
* policies then it should emit the #ClutterLayoutManager::layout-changed
* signal on itself by using the clutter_layout_manager_layout_changed()
* function.</para>
* function whenever one of these properties changes.</para>
* <para>If the layout manager has layout properties, that is properties that
* should exist only as the result of the presence of a specific (layout
* manager, container actor, child actor) combination, then it should
* override the <structname>ClutterLayoutManager</structname>::get_child_meta_type()
* manager, container actor, child actor) combination, and it wishes to store
* those properties inside a #ClutterLayoutMeta then it should override the
* <structname>ClutterLayoutManager</structname>::get_child_meta_type()
* virtual function to return the #GType of the #ClutterLayoutMeta sub-class
* used to store the layout properties; optionally, the #ClutterLayoutManager
* sub-class might also override the
@ -89,17 +91,17 @@
* function to control how the #ClutterLayoutMeta instance is created,
* otherwise the default implementation will be equivalent to:</para>
* <informalexample><programlisting>
* ClutterLayoutManagerClass *klass;
* GType meta_type;
* ClutterLayoutManagerClass *klass;
* GType meta_type;
*
* klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
* meta_type = klass->get_child_meta_type (manager);
* klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
* meta_type = klass->get_child_meta_type (manager);
*
* return g_object_new (meta_type,
* "manager", manager,
* "container", container,
* "actor", actor,
* NULL);
* return g_object_new (meta_type,
* "manager", manager,
* "container", container,
* "actor", actor,
* NULL);
* </programlisting></informalexample>
* <para>Where <varname>manager</varname> is the #ClutterLayoutManager,
* <varname>container</varname> is the #ClutterContainer using the
@ -107,6 +109,176 @@
* child of the #ClutterContainer.</para>
* </refsect2>
*
* <refsect2 id="ClutterLayoutManager-animation">
* <title>Animating a ClutterLayoutManager</title>
* <para>A layout manager is used to let a #ClutterContainer take complete
* ownership over the layout (that is: the position and sizing) of its
* children; this means that using the Clutter animation API, like
* clutter_actor_animate(), to animate the position and sizing of a child of
* a layout manager it is not going to work properly, as the animation will
* automatically override any setting done by the layout manager
* itself.</para>
* <para>It is possible for a #ClutterLayoutManager sub-class to animate its
* children layout by using the base class animation support. The
* #ClutterLayoutManager animation support consists of three virtual
* functions: <function>begin_animation()</function>,
* <function>get_animation_progress()</function> and
* <function>end_animation()</function>.</para>
* <variablelist>
* <varlistentry>
* <term><function>begin_animation (duration, easing)</function></term>
* <listitem><para>This virtual function is invoked when the layout
* manager should begin an animation. The implementation should set up
* the state for the animation and create the ancillary objects for
* animating the layout. The default implementation creates a
* #ClutterTimeline for the given duration and a #ClutterAlpha binding
* the timeline to the given easing mode. This function returns a
* #ClutterAlpha which should be used to control the animation from
* the caller perspective.</para></listitem>
* </varlistentry>
* <varlistentry>
* <term><function>get_animation_progress()</function></term>
* <listitem><para>This virtual function should be invoked when animating
* a layout manager. It returns the progress of the animation, using the
* same semantics as the #ClutterAlpha:alpha value.</para></listitem>
* </varlistentry>
* <varlistentry>
* <term><function>end_animation()</function></term>
* <listitem><para>This virtual function is invoked when the animation of
* a layout manager ends, and it is meant to be used for bookkeeping the
* objects created in the <function>begin_animation()</function>
* function. The default implementation will call it implicitly when the
* timeline is complete.</para></listitem>
* </varlistentry>
* </variablelist>
* <para>The simplest way to animate a layout is to create a #ClutterTimeline
* inside the <function>begin_animation()</function> virtual function, along
* with a #ClutterAlpha, and for each #ClutterTimeline::new-frame signal
* emission call clutter_layout_manager_layout_changed(), which will cause a
* relayout. The #ClutterTimeline::completed signal emission should cause
* clutter_layout_manager_end_animation() to be called. The default
* implementation provided internally by #ClutterLayoutManager does exactly
* this, so most sub-classes should either not override any animation-related
* virtual function or simply override <function>begin_animation()</function>
* and <function>end_animation()</function> to set up ad hoc state, and then
* chain up to the parent's implementation.</para>
* <example id="example-ClutterLayoutManager-animation">
* <title>Animation of a Layout Manager</title>
* <para>The code below shows how a #ClutterLayoutManager sub-class should
* provide animating the allocation of its children from within the
* <function>allocate()</function> virtual function implementation. The
* animation is computed between the last stable allocation performed
* before the animation started and the desired final allocation.</para>
* <para>The <varname>is_animating</varname> variable is stored inside the
* #ClutterLayoutManager sub-class and it is updated by overriding the
* <function>begin_animation()</function> and
* <function>end_animation()</function> virtual functions and chaining up
* to the base class implementation.</para>
* <para>The last stable allocation is stored within a #ClutterLayoutMeta
* sub-class used by the implementation.</para>
* <programlisting>
* static void
* my_layout_manager_allocate (ClutterLayoutManager *manager,
* ClutterContainer *container,
* const ClutterActorBox *allocation,
* ClutterAllocationFlags flags)
* {
* MyLayoutManager *self = MY_LAYOUT_MANAGER (manager);
* GList *children, *l;
*
* children = clutter_container_get_children (container);
*
* for (l = children; l != NULL; l = l-&gt;next)
* {
* ClutterActor *child = l->data;
* ClutterLayoutMeta *meta;
* MyLayoutMeta *my_meta;
*
* /&ast; retrieve the layout meta-object &ast;/
* meta = clutter_layout_manager_get_child_meta (manager,
* container,
* child);
* my_meta = MY_LAYOUT_META (meta);
*
* /&ast; compute the desired allocation for the child &ast;/
* compute_allocation (self, my_meta, child,
* allocation, flags,
* &amp;child_box);
*
* /&ast; this is the additional code that deals with the animation
* &ast; of the layout manager
* &ast;/
* if (!self-&gt;is_animating)
* {
* /&ast; store the last stable allocation for later use &ast;/
* my_meta-&gt;last_alloc = clutter_actor_box_copy (&amp;child_box);
* }
* else
* {
* ClutterActorBox end = { 0, };
* gdouble p;
*
* /&ast; get the progress of the animation &ast;/
* p = clutter_layout_manager_get_animation_progress (manager);
*
* if (my_meta-&gt;last_alloc != NULL)
* {
* /&ast; copy the desired allocation as the final state &ast;/
* end = child_box;
*
* /&ast; then interpolate the initial and final state
* &ast; depending on the progress of the animation,
* &ast; and put the result inside the box we will use
* &ast; to allocate the child
* &ast;/
* clutter_actor_box_interpolate (my_meta-&gt;last_alloc,
* &amp;end,
* p,
* &amp;child_box);
* }
* else
* {
* /&ast; if there is no stable allocation then the child was
* &ast; added while animating; one possible course of action
* &ast; is to just bail out and fall through to the allocation
* &ast; to position the child directly at its final state
* &ast;/
* my_meta-&gt;last_alloc =
* clutter_actor_box_copy (&amp;child_box);
* }
* }
*
* /&ast; allocate the child &ast;/
* clutter_actor_allocate (child, &child_box, flags);
* }
*
* g_list_free (children);
* }
* </programlisting>
* </example>
* <para>Sub-classes of #ClutterLayoutManager that support animations of the
* layout changes should call clutter_layout_manager_begin_animation()
* whenever a layout property changes value, e.g.:</para>
* <informalexample>
* <programlisting>
* if (self->orientation != new_orientation)
* {
* ClutterLayoutManager *manager;
*
* self->orientation = new_orientation;
*
* manager = CLUTTER_LAYOUT_MANAGER (self);
* clutter_layout_manager_layout_changed (manager);
* clutter_layout_manager_begin_animation (manager, 500, CLUTTER_LINEAR);
*
* g_object_notify (G_OBJECT (self), "orientation");
* }
* </programlisting>
* </informalexample>
* <para>The code above will animate a change in the
* <varname>orientation</varname> layout property of a layout manager.</para>
* </refsect2>
*
* #ClutterLayoutManager is available since Clutter 1.2
*/
@ -117,11 +289,13 @@
#include <glib-object.h>
#include <gobject/gvaluecollector.h>
#include "clutter-alpha.h"
#include "clutter-debug.h"
#include "clutter-layout-manager.h"
#include "clutter-layout-meta.h"
#include "clutter-marshal.h"
#include "clutter-private.h"
#include "clutter-timeline.h"
#define LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED(m,method) G_STMT_START { \
GObject *_obj = G_OBJECT (m); \
@ -141,7 +315,9 @@ G_DEFINE_ABSTRACT_TYPE (ClutterLayoutManager,
clutter_layout_manager,
G_TYPE_INITIALLY_UNOWNED);
static GQuark quark_layout_meta = 0;
static GQuark quark_layout_meta = 0;
static GQuark quark_layout_alpha = 0;
static guint manager_signals[LAST_SIGNAL] = { 0, };
static void
@ -217,17 +393,105 @@ layout_manager_real_get_child_meta_type (ClutterLayoutManager *manager)
return G_TYPE_INVALID;
}
static ClutterAlpha *
layout_manager_real_begin_animation (ClutterLayoutManager *manager,
guint duration,
gulong mode)
{
ClutterTimeline *timeline;
ClutterAlpha *alpha;
alpha = g_object_get_qdata (G_OBJECT (manager), quark_layout_alpha);
if (alpha != NULL)
{
clutter_alpha_set_mode (alpha, mode);
timeline = clutter_alpha_get_timeline (alpha);
clutter_timeline_set_duration (timeline, duration);
clutter_timeline_rewind (timeline);
return alpha;
};
timeline = clutter_timeline_new (duration);
alpha = clutter_alpha_new_full (timeline, mode);
/* let the alpha take ownership of the timeline */
g_object_unref (timeline);
g_signal_connect_swapped (timeline, "completed",
G_CALLBACK (clutter_layout_manager_end_animation),
manager);
g_signal_connect_swapped (timeline, "new-frame",
G_CALLBACK (clutter_layout_manager_layout_changed),
manager);
g_object_set_qdata_full (G_OBJECT (manager),
quark_layout_alpha, alpha,
(GDestroyNotify) g_object_unref);
clutter_timeline_start (timeline);
return alpha;
}
static gdouble
layout_manager_real_get_animation_progress (ClutterLayoutManager *manager)
{
ClutterAlpha *alpha;
alpha = g_object_get_qdata (G_OBJECT (manager), quark_layout_alpha);
if (alpha == NULL)
return 1.0;
return clutter_alpha_get_alpha (alpha);
}
static void
layout_manager_real_end_animation (ClutterLayoutManager *manager)
{
ClutterTimeline *timeline;
ClutterAlpha *alpha;
alpha = g_object_get_qdata (G_OBJECT (manager), quark_layout_alpha);
if (alpha == NULL)
return;
timeline = clutter_alpha_get_timeline (alpha);
g_assert (timeline != NULL);
if (clutter_timeline_is_playing (timeline))
clutter_timeline_stop (timeline);
g_signal_handlers_disconnect_by_func (timeline,
G_CALLBACK (clutter_layout_manager_end_animation),
manager);
g_signal_handlers_disconnect_by_func (timeline,
G_CALLBACK (clutter_layout_manager_layout_changed),
manager);
g_object_set_qdata (G_OBJECT (manager), quark_layout_alpha, NULL);
clutter_layout_manager_layout_changed (manager);
}
static void
clutter_layout_manager_class_init (ClutterLayoutManagerClass *klass)
{
quark_layout_meta =
g_quark_from_static_string ("clutter-layout-manager-child-meta");
quark_layout_alpha =
g_quark_from_static_string ("clutter-layout-manager-alpha");
klass->get_preferred_width = layout_manager_real_get_preferred_width;
klass->get_preferred_height = layout_manager_real_get_preferred_height;
klass->allocate = layout_manager_real_allocate;
klass->create_child_meta = layout_manager_real_create_child_meta;
klass->get_child_meta_type = layout_manager_real_get_child_meta_type;
klass->begin_animation = layout_manager_real_begin_animation;
klass->get_animation_progress = layout_manager_real_get_animation_progress;
klass->end_animation = layout_manager_real_end_animation;
/**
* ClutterLayoutManager::layout-changed:
@ -905,3 +1169,81 @@ clutter_layout_manager_list_child_properties (ClutterLayoutManager *manager,
return pspecs;
}
/**
* clutter_layout_manager_begin_animation:
* @manager: a #ClutterLayoutManager
* @duration: the duration of the animation, in milliseconds
* @mode: the easing mode of the animation
*
* Begins an animation of @duration milliseconds, using the provided
* easing @mode
*
* The easing mode can be specified either as a #ClutterAnimationMode
* or as a logical id returned by clutter_alpha_register_func()
*
* The result of this function depends on the @manager implementation
*
* Return value: (transfer none): The #ClutterAlpha created by the
* layout manager; the returned instance is owned by the layout
* manager and should not be unreferenced
*
* Since: 1.2
*/
ClutterAlpha *
clutter_layout_manager_begin_animation (ClutterLayoutManager *manager,
guint duration,
gulong mode)
{
ClutterLayoutManagerClass *klass;
g_return_val_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager), NULL);
klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
return klass->begin_animation (manager, duration, mode);
}
/**
* clutter_layout_manager_end_animation:
* @manager: a #ClutterLayoutManager
*
* Ends an animation started by clutter_layout_manager_begin_animation()
*
* The result of this call depends on the @manager implementation
*
* Since: 1.2
*/
void
clutter_layout_manager_end_animation (ClutterLayoutManager *manager)
{
g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager));
CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager)->end_animation (manager);
}
/**
* clutter_layout_manager_get_animation_progress:
* @manager: a #ClutterLayoutManager
*
* Retrieves the progress of the animation, if one has been started by
* clutter_layout_manager_begin_animation()
*
* The returned value has the same semantics of the #ClutterAlpha:alpha
* value
*
* Return value: the progress of the animation
*
* Since: 1.2
*/
gdouble
clutter_layout_manager_get_animation_progress (ClutterLayoutManager *manager)
{
ClutterLayoutManagerClass *klass;
g_return_val_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager), 1.0);
klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
return klass->get_animation_progress (manager);
}

View File

@ -30,6 +30,7 @@
#define __CLUTTER_LAYOUT_MANAGER_H__
#include <clutter/clutter-actor.h>
#include <clutter/clutter-alpha.h>
#include <clutter/clutter-container.h>
#include <clutter/clutter-types.h>
@ -82,6 +83,12 @@ struct _ClutterLayoutManager
* @create_child_meta: virtual function; override to create a
* #ClutterLayoutMeta instance associated to a #ClutterContainer and a
* child #ClutterActor, used to maintain layout manager specific properties
* @begin_animation: virtual function; override to control the animation
* of a #ClutterLayoutManager with the given duration and easing mode
* @end_animation: virtual function; override to end an animation started
* by clutter_layout_manager_begin_animation()
* @get_animation_progress: virtual function; override to control the
* progress of the animation of a #ClutterLayoutManager
* @layout_changed: class handler for the #ClutterLayoutManager::layout-changed
* signal
*
@ -96,30 +103,38 @@ struct _ClutterLayoutManagerClass
GInitiallyUnownedClass parent_class;
/*< public >*/
void (* get_preferred_width) (ClutterLayoutManager *manager,
ClutterContainer *container,
gfloat for_height,
gfloat *minimum_width_p,
gfloat *natural_width_p);
void (* get_preferred_height) (ClutterLayoutManager *manager,
ClutterContainer *container,
gfloat for_width,
gfloat *minimum_height_p,
gfloat *natural_height_p);
void (* allocate) (ClutterLayoutManager *manager,
ClutterContainer *container,
const ClutterActorBox *allocation,
ClutterAllocationFlags flags);
/* vfuncs, not signals */
void (* get_preferred_width) (ClutterLayoutManager *manager,
ClutterContainer *container,
gfloat for_height,
gfloat *minimum_width_p,
gfloat *natural_width_p);
void (* get_preferred_height) (ClutterLayoutManager *manager,
ClutterContainer *container,
gfloat for_width,
gfloat *minimum_height_p,
gfloat *natural_height_p);
void (* allocate) (ClutterLayoutManager *manager,
ClutterContainer *container,
const ClutterActorBox *allocation,
ClutterAllocationFlags flags);
void (* set_container) (ClutterLayoutManager *manager,
ClutterContainer *container);
void (* set_container) (ClutterLayoutManager *manager,
ClutterContainer *container);
GType (* get_child_meta_type) (ClutterLayoutManager *manager);
ClutterLayoutMeta *(* create_child_meta) (ClutterLayoutManager *manager,
ClutterContainer *container,
ClutterActor *actor);
GType (* get_child_meta_type) (ClutterLayoutManager *manager);
ClutterLayoutMeta *(* create_child_meta) (ClutterLayoutManager *manager,
ClutterContainer *container,
ClutterActor *actor);
void (* layout_changed) (ClutterLayoutManager *manager);
ClutterAlpha * (* begin_animation) (ClutterLayoutManager *manager,
guint duration,
gulong mode);
gdouble (* get_animation_progress) (ClutterLayoutManager *manager);
void (* end_animation) (ClutterLayoutManager *manager);
/* signals */
void (* layout_changed) (ClutterLayoutManager *manager);
/*< private >*/
/* padding for future expansion */
@ -184,6 +199,12 @@ void clutter_layout_manager_child_get_property (ClutterLayoutMa
const gchar *property_name,
GValue *value);
ClutterAlpha * clutter_layout_manager_begin_animation (ClutterLayoutManager *manager,
guint duration,
gulong mode);
void clutter_layout_manager_end_animation (ClutterLayoutManager *manager);
gdouble clutter_layout_manager_get_animation_progress (ClutterLayoutManager *manager);
G_END_DECLS
#endif /* __CLUTTER_LAYOUT_MANAGER_H__ */

View File

@ -109,6 +109,7 @@
#include "clutter-debug.h"
#include "clutter-version.h" /* For flavour define */
#include "clutter-frame-source.h"
#include "clutter-profile.h"
#include "cogl/cogl.h"
#include "pango/cogl-pango.h"
@ -136,6 +137,7 @@ static guint clutter_main_loop_level = 0;
static GSList *main_loops = NULL;
guint clutter_debug_flags = 0; /* global clutter debug flag */
guint clutter_profile_flags = 0; /* global clutter profile flag */
const guint clutter_major_version = CLUTTER_MAJOR_VERSION;
const guint clutter_minor_version = CLUTTER_MINOR_VERSION;
@ -164,6 +166,13 @@ static const GDebugKey clutter_debug_keys[] = {
};
#endif /* CLUTTER_ENABLE_DEBUG */
#ifdef CLUTTER_ENABLE_PROFILE
static const GDebugKey clutter_profile_keys[] = {
{"picking-only", CLUTTER_PROFILE_PICKING_ONLY },
{"disable-report", CLUTTER_PROFILE_DISABLE_REPORT }
};
#endif /* CLUTTER_ENABLE_DEBUG */
/**
* clutter_get_show_fps:
*
@ -187,10 +196,16 @@ _clutter_stage_maybe_relayout (ClutterActor *stage)
{
gfloat natural_width, natural_height;
ClutterActorBox box = { 0, };
CLUTTER_STATIC_TIMER (relayout_timer,
"Mainloop", /* no parent */
"Layouting",
"The time spent reallocating the stage",
0 /* no application private data */);
/* avoid reentrancy */
if (!(CLUTTER_PRIVATE_FLAGS (stage) & CLUTTER_ACTOR_IN_RELAYOUT))
{
CLUTTER_TIMER_START (_clutter_uprof_context, relayout_timer);
CLUTTER_NOTE (ACTOR, "Recomputing layout");
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_IN_RELAYOUT);
@ -212,6 +227,7 @@ _clutter_stage_maybe_relayout (ClutterActor *stage)
clutter_actor_allocate (stage, &box, CLUTTER_ALLOCATION_NONE);
CLUTTER_UNSET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_IN_RELAYOUT);
CLUTTER_TIMER_STOP (_clutter_uprof_context, relayout_timer);
}
}
@ -354,19 +370,6 @@ clutter_get_motion_events_enabled (void)
guint _clutter_pix_to_id (guchar pixel[4]);
static inline void init_bits (void)
{
ClutterMainContext *ctx;
static gboolean done = FALSE;
if (G_LIKELY (done))
return;
ctx = _clutter_context_get_default ();
done = TRUE;
}
void
_clutter_id_to_color (guint id, ClutterColor *col)
{
@ -377,9 +380,11 @@ _clutter_id_to_color (guint id, ClutterColor *col)
/* compute the numbers we'll store in the components */
red = (id >> (ctx->fb_g_mask_used+ctx->fb_b_mask_used))
& (0xff >> (8-ctx->fb_r_mask_used));
green = (id >> ctx->fb_b_mask_used) & (0xff >> (8-ctx->fb_g_mask_used));
blue = (id) & (0xff >> (8-ctx->fb_b_mask_used));
& (0xff >> (8-ctx->fb_r_mask_used));
green = (id >> ctx->fb_b_mask_used)
& (0xff >> (8-ctx->fb_g_mask_used));
blue = (id)
& (0xff >> (8-ctx->fb_b_mask_used));
/* shift left bits a bit and add one, this circumvents
* at least some potential rounding errors in GL/GLES
@ -409,9 +414,9 @@ _clutter_id_to_color (guint id, ClutterColor *col)
*/
if (G_UNLIKELY (clutter_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS))
{
col->red = (col->red << 4) | (col->red >> 4);
col->red = (col->red << 4) | (col->red >> 4);
col->green = (col->green << 4) | (col->green >> 4);
col->blue = (col->blue << 4) | (col->blue >> 4);
col->blue = (col->blue << 4) | (col->blue >> 4);
}
}
@ -456,8 +461,9 @@ _clutter_pixel_to_id (guchar pixel[4])
blue = blue >> (ctx->fb_b_mask - ctx->fb_b_mask_used);
/* combine the correct per component values into the final id */
id = blue + (green << ctx->fb_b_mask_used)
+ (red << (ctx->fb_b_mask_used + ctx->fb_g_mask_used));
id = blue
+ (green << ctx->fb_b_mask_used)
+ (red << (ctx->fb_b_mask_used + ctx->fb_g_mask_used));
return id;
}
@ -498,28 +504,34 @@ read_pixels_to_file (char *filename_stem,
NULL); /* callback data */
if (pixbuf)
{
char *filename =
g_strdup_printf ("%s-%05d.png", filename_stem, read_count);
char *filename = g_strdup_printf ("%s-%05d.png",
filename_stem,
read_count);
GError *error = NULL;
if (!gdk_pixbuf_save (pixbuf, filename, "png", &error, NULL))
{
g_warning ("Failed to save pick buffer to file %s: %s",
filename, error->message);
g_error_free (error);
}
g_free (filename);
g_object_unref (pixbuf);
read_count++;
}
#else
static gboolean seen = FALSE;
if (!seen)
{
g_warning ("dumping buffers to an image isn't supported on platforms "
"without gdk pixbuf support\n");
seen = TRUE;
}
#endif
#else /* !USE_GDKPIXBUF */
{
static gboolean seen = FALSE;
if (!seen)
{
g_warning ("dumping buffers to an image isn't supported on platforms "
"without gdk pixbuf support\n");
seen = TRUE;
}
}
#endif /* USE_GDKPIXBUF */
}
ClutterActor *
@ -533,10 +545,44 @@ _clutter_do_pick (ClutterStage *stage,
CoglColor stage_pick_id;
guint32 id;
GLboolean dither_was_on;
ClutterActor *actor;
CLUTTER_STATIC_COUNTER (do_pick_counter,
"_clutter_do_pick counter",
"Increments for each full pick run",
0 /* no application private data */);
CLUTTER_STATIC_TIMER (pick_timer,
"Mainloop", /* parent */
"Picking",
"The time spent picking",
0 /* no application private data */);
CLUTTER_STATIC_TIMER (pick_clear,
"Picking", /* parent */
"Stage clear (pick)",
"The time spent clearing stage for picking",
0 /* no application private data */);
CLUTTER_STATIC_TIMER (pick_paint,
"Picking", /* parent */
"Painting actors (pick mode)",
"The time spent painting actors in pick mode",
0 /* no application private data */);
CLUTTER_STATIC_TIMER (pick_read,
"Picking", /* parent */
"Read Pixels",
"The time spent issuing a read pixels",
0 /* no application private data */);
if (clutter_debug_flags & CLUTTER_DEBUG_NOP_PICKING)
return CLUTTER_ACTOR (stage);
#ifdef CLUTTER_ENABLE_PROFILE
if (clutter_profile_flags & CLUTTER_PROFILE_PICKING_ONLY)
_clutter_profile_resume ();
#endif /* CLUTTER_ENABLE_PROFILE */
CLUTTER_COUNTER_INC (_clutter_uprof_context, do_pick_counter);
CLUTTER_TIMER_START (_clutter_uprof_context, pick_timer);
context = _clutter_context_get_default ();
_clutter_backend_ensure_context (context->backend, stage);
@ -549,9 +595,11 @@ _clutter_do_pick (ClutterStage *stage,
cogl_disable_fog ();
cogl_color_set_from_4ub (&stage_pick_id, 255, 255, 255, 255);
CLUTTER_TIMER_START (_clutter_uprof_context, pick_clear);
cogl_clear (&stage_pick_id,
COGL_BUFFER_BIT_COLOR |
COGL_BUFFER_BIT_DEPTH);
CLUTTER_TIMER_STOP (_clutter_uprof_context, pick_clear);
/* Disable dithering (if any) when doing the painting in pick mode */
dither_was_on = glIsEnabled (GL_DITHER);
@ -561,9 +609,11 @@ _clutter_do_pick (ClutterStage *stage,
/* Render the entire scence in pick mode - just single colored silhouette's
* are drawn offscreen (as we never swap buffers)
*/
CLUTTER_TIMER_START (_clutter_uprof_context, pick_paint);
context->pick_mode = mode;
clutter_actor_paint (CLUTTER_ACTOR (stage));
context->pick_mode = CLUTTER_PICK_NONE;
CLUTTER_TIMER_STOP (_clutter_uprof_context, pick_paint);
if (G_LIKELY (!(clutter_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
cogl_clip_pop ();
@ -572,10 +622,12 @@ _clutter_do_pick (ClutterStage *stage,
cogl_flush ();
/* Read the color of the screen co-ords pixel */
CLUTTER_TIMER_START (_clutter_uprof_context, pick_read);
cogl_read_pixels (x, y, 1, 1,
COGL_READ_PIXELS_COLOR_BUFFER,
COGL_PIXEL_FORMAT_RGBA_8888,
pixel);
CLUTTER_TIMER_STOP (_clutter_uprof_context, pick_read);
if (G_UNLIKELY (clutter_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS))
{
@ -589,11 +641,24 @@ _clutter_do_pick (ClutterStage *stage,
glEnable (GL_DITHER);
if (pixel[0] == 0xff && pixel[1] == 0xff && pixel[2] == 0xff)
return CLUTTER_ACTOR (stage);
{
actor = CLUTTER_ACTOR (stage);
goto result;
}
id = _clutter_pixel_to_id (pixel);
actor = clutter_get_actor_by_gid (id);
return clutter_get_actor_by_gid (id);
result:
CLUTTER_TIMER_STOP (_clutter_uprof_context, pick_timer);
#ifdef CLUTTER_ENABLE_PROFILE
if (clutter_profile_flags & CLUTTER_PROFILE_PICKING_ONLY)
_clutter_profile_suspend ();
#endif
return actor;
}
static ClutterTextDirection
@ -727,6 +792,28 @@ clutter_main_level (void)
return clutter_main_loop_level;
}
#ifdef CLUTTER_ENABLE_PROFILE
static gint (*prev_poll) (GPollFD *ufds, guint nfsd, gint timeout_) = NULL;
static gint
timed_poll (GPollFD *ufds,
guint nfsd,
gint timeout_)
{
gint ret;
CLUTTER_STATIC_TIMER (poll_timer,
"Mainloop", /* parent */
"poll (idle)",
"The time spent idle in poll()",
0 /* no application private data */);
CLUTTER_TIMER_START (_clutter_uprof_context, poll_timer);
ret = prev_poll (ufds, nfsd, timeout_);
CLUTTER_TIMER_STOP (_clutter_uprof_context, poll_timer);
return ret;
}
#endif
/**
* clutter_main:
*
@ -736,6 +823,14 @@ void
clutter_main (void)
{
GMainLoop *loop;
CLUTTER_STATIC_TIMER (mainloop_timer,
NULL, /* no parent */
"Mainloop",
"The time spent in the clutter mainloop",
0 /* no application private data */);
if (clutter_main_loop_level == 0)
CLUTTER_TIMER_START (_clutter_uprof_context, mainloop_timer);
/* Make sure there is a context */
CLUTTER_CONTEXT ();
@ -751,6 +846,14 @@ clutter_main (void)
clutter_main_loop_level++;
#ifdef CLUTTER_ENABLE_PROFILE
if (!prev_poll)
{
prev_poll = g_main_context_get_poll_func (NULL);
g_main_context_set_poll_func (NULL, timed_poll);
}
#endif
loop = g_main_loop_new (NULL, TRUE);
main_loops = g_slist_prepend (main_loops, loop);
@ -775,19 +878,22 @@ clutter_main (void)
clutter_main_loop_level--;
CLUTTER_MARK ();
if (clutter_main_loop_level == 0)
CLUTTER_TIMER_STOP (_clutter_uprof_context, mainloop_timer);
}
static void
clutter_threads_impl_lock (void)
{
if (clutter_threads_mutex)
if (G_LIKELY (clutter_threads_mutex != NULL))
g_mutex_lock (clutter_threads_mutex);
}
static void
clutter_threads_impl_unlock (void)
{
if (clutter_threads_mutex)
if (G_LIKELY (clutter_threads_mutex != NULL))
g_mutex_unlock (clutter_threads_mutex);
}
@ -802,6 +908,8 @@ clutter_threads_impl_unlock (void)
*
* This function must be called before clutter_init().
*
* It is safe to call this function multiple times.
*
* Since: 0.4
*/
void
@ -810,6 +918,9 @@ clutter_threads_init (void)
if (!g_thread_supported ())
g_error ("g_thread_init() must be called before clutter_threads_init()");
if (clutter_threads_mutex != NULL)
return;
clutter_threads_mutex = g_mutex_new ();
if (!clutter_threads_lock)
@ -1253,6 +1364,7 @@ _clutter_context_get_default (void)
ClutterCntx = ctx = g_new0 (ClutterMainContext, 1);
/* create the default backend */
ctx->backend = g_object_new (_clutter_backend_impl_get_type (), NULL);
ctx->is_initialized = FALSE;
@ -1331,6 +1443,32 @@ clutter_arg_no_debug_cb (const char *key,
}
#endif /* CLUTTER_ENABLE_DEBUG */
#ifdef CLUTTER_ENABLE_PROFILE
static gboolean
clutter_arg_profile_cb (const char *key,
const char *value,
gpointer user_data)
{
clutter_profile_flags |=
g_parse_debug_string (value,
clutter_profile_keys,
G_N_ELEMENTS (clutter_profile_keys));
return TRUE;
}
static gboolean
clutter_arg_no_profile_cb (const char *key,
const char *value,
gpointer user_data)
{
clutter_profile_flags &=
~g_parse_debug_string (value,
clutter_profile_keys,
G_N_ELEMENTS (clutter_profile_keys));
return TRUE;
}
#endif /* CLUTTER_ENABLE_PROFILE */
GQuark
clutter_init_error_quark (void)
{
@ -1403,6 +1541,18 @@ clutter_init_real (GError **error)
/* - will call to backend and cogl */
_clutter_feature_init ();
#ifdef CLUTTER_ENABLE_PROFILE
{
UProfContext *cogl_context;
cogl_context = uprof_find_context ("Cogl");
if (cogl_context)
uprof_context_link (_clutter_uprof_context, cogl_context);
}
if (clutter_profile_flags & CLUTTER_PROFILE_PICKING_ONLY)
_clutter_profile_suspend ();
#endif
/*
* Resolution requires display to be open, so can only be queried after
* the post_parse hooks run.
@ -1414,7 +1564,7 @@ clutter_init_real (GError **error)
resolution = clutter_backend_get_resolution (ctx->backend);
cogl_pango_font_map_set_resolution (ctx->font_map, resolution);
if (G_LIKELY (!clutter_disable_mipmap_text))
if (!clutter_disable_mipmap_text)
cogl_pango_font_map_set_use_mipmapping (ctx->font_map, TRUE);
clutter_text_direction = clutter_get_text_direction ();
@ -1465,6 +1615,12 @@ static GOptionEntry clutter_args[] = {
{ "clutter-no-debug", 0, 0, G_OPTION_ARG_CALLBACK, clutter_arg_no_debug_cb,
N_("Clutter debugging flags to unset"), "FLAGS" },
#endif /* CLUTTER_ENABLE_DEBUG */
#ifdef CLUTTER_ENABLE_PROFILE
{ "clutter-profile", 0, 0, G_OPTION_ARG_CALLBACK, clutter_arg_profile_cb,
N_("Clutter profiling flags to set"), "FLAGS" },
{ "clutter-no-profile", 0, 0, G_OPTION_ARG_CALLBACK, clutter_arg_no_profile_cb,
N_("Clutter profiling flags to unset"), "FLAGS" },
#endif /* CLUTTER_ENABLE_PROFILE */
{ NULL, },
};
@ -1508,6 +1664,18 @@ pre_parse_hook (GOptionContext *context,
}
#endif /* CLUTTER_ENABLE_DEBUG */
#ifdef CLUTTER_ENABLE_PROFILE
env_string = g_getenv ("CLUTTER_PROFILE");
if (env_string != NULL)
{
clutter_profile_flags =
g_parse_debug_string (env_string,
clutter_profile_keys,
G_N_ELEMENTS (clutter_profile_keys));
env_string = NULL;
}
#endif /* CLUTTER_ENABLE_PROFILE */
env_string = g_getenv ("CLUTTER_SHOW_FPS");
if (env_string)
clutter_show_fps = TRUE;
@ -1723,8 +1891,10 @@ clutter_init_with_args (int *argc,
if (!ctx->defer_display_setup)
{
#if 0
if (argc && *argc > 0 && *argv)
g_set_prgname ((*argv)[0]);
#endif
context = g_option_context_new (parameter_string);
@ -1829,8 +1999,10 @@ clutter_init (int *argc,
if (!ctx->defer_display_setup)
{
#if 0
if (argc && *argc > 0 && *argv)
g_set_prgname ((*argv)[0]);
#endif
/* parse_args will trigger backend creation and things like
* DISPLAY connection etc.
@ -2166,36 +2338,13 @@ clutter_do_event (ClutterEvent *event)
_clutter_stage_queue_event (event->any.stage, event);
}
/**
* _clutter_process_event
* @event: a #ClutterEvent.
*
* Does the actual work of processing an event that was queued earlier
* out of clutter_do_event().
*/
void
_clutter_process_event (ClutterEvent *event)
static void
_clutter_process_event_details (ClutterActor *stage,
ClutterMainContext *context,
ClutterEvent *event)
{
/* FIXME: This should probably be clutter_cook_event() - it would
* take a raw event from the backend and 'cook' it so its more tasty.
*
*/
ClutterMainContext *context;
ClutterBackend *backend;
ClutterActor *stage;
ClutterInputDevice *device = NULL;
context = _clutter_context_get_default ();
backend = context->backend;
stage = CLUTTER_ACTOR(event->any.stage);
if (!stage)
return;
CLUTTER_TIMESTAMP (EVENT, "Event received");
context->last_event_time = clutter_event_get_time (event);
switch (event->type)
{
case CLUTTER_NOTHING:
@ -2226,14 +2375,7 @@ _clutter_process_event (ClutterEvent *event)
case CLUTTER_DELETE:
event->any.source = stage;
/* the stage did not handle the event, so we just quit */
if (!clutter_stage_event (CLUTTER_STAGE (stage), event))
{
if (stage == clutter_stage_get_default())
clutter_main_quit ();
else
clutter_actor_destroy (stage);
}
clutter_stage_event (CLUTTER_STAGE (stage), event);
break;
case CLUTTER_KEY_PRESS:
@ -2393,6 +2535,37 @@ _clutter_process_event (ClutterEvent *event)
}
}
/**
* _clutter_process_event
* @event: a #ClutterEvent.
*
* Does the actual work of processing an event that was queued earlier
* out of clutter_do_event().
*/
void
_clutter_process_event (ClutterEvent *event)
{
ClutterMainContext *context;
ClutterBackend *backend;
ClutterActor *stage;
context = _clutter_context_get_default ();
backend = context->backend;
stage = CLUTTER_ACTOR(event->any.stage);
if (!stage)
return;
CLUTTER_TIMESTAMP (EVENT, "Event received");
context->last_event_time = clutter_event_get_time (event);
context->current_event = event;
_clutter_process_event_details (stage, context, event);
context->current_event = NULL;
}
/**
* clutter_get_actor_by_gid
* @id: a #ClutterActor ID.
@ -3090,18 +3263,20 @@ clutter_check_version (guint major,
clutter_micro_version >= micro));
}
void
clutter_set_default_text_direction (ClutterTextDirection text_dir)
{
if (text_dir == CLUTTER_TEXT_DIRECTION_DEFAULT)
text_dir = clutter_get_text_direction ();
if (text_dir != clutter_text_direction)
clutter_text_direction = text_dir;
/* FIXME - queue a relayout on all stages */
}
/**
* clutter_get_default_text_direction:
*
* Retrieves the default direction for the text. The text direction is
* determined by the locale and/or by the %CLUTTER_TEXT_DIRECTION environment
* variable
*
* The default text direction can be overridden on a per-actor basis by using
* clutter_actor_set_text_direction()
*
* Return value: the default text direction
*
* Since: 1.2
*/
ClutterTextDirection
clutter_get_default_text_direction (void)
{

View File

@ -164,7 +164,6 @@ void clutter_ungrab_pointer_for_device (gint id);
PangoFontMap * clutter_get_font_map (void);
void clutter_set_default_text_direction (ClutterTextDirection text_dir);
ClutterTextDirection clutter_get_default_text_direction (void);
G_END_DECLS

View File

@ -16,3 +16,4 @@ VOID:STRING,BOOLEAN,BOOLEAN
VOID:STRING,INT
VOID:UINT
VOID:VOID
VOID:STRING,INT,POINTER

View File

@ -38,6 +38,7 @@
#include "clutter-master-clock.h"
#include "clutter-debug.h"
#include "clutter-private.h"
#include "clutter-profile.h"
#define CLUTTER_MASTER_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_MASTER_CLOCK, ClutterMasterClockClass))
#define CLUTTER_IS_MASTER_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_MASTER_CLOCK))
@ -262,6 +263,19 @@ clutter_clock_dispatch (GSource *source,
ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();
GSList *stages, *l;
CLUTTER_STATIC_TIMER (master_dispatch_timer,
"Mainloop",
"Master Clock",
"Master clock dispatch",
0);
CLUTTER_STATIC_TIMER (master_event_process,
"Master Clock",
"Event Processing",
"The time spent processing events on all stages",
0);
CLUTTER_TIMER_START (_clutter_uprof_context, master_dispatch_timer);
CLUTTER_NOTE (SCHEDULER, "Master clock [tick]");
clutter_threads_enter ();
@ -276,6 +290,8 @@ clutter_clock_dispatch (GSource *source,
stages = clutter_stage_manager_list_stages (stage_manager);
g_slist_foreach (stages, (GFunc)g_object_ref, NULL);
CLUTTER_TIMER_START (_clutter_uprof_context, master_event_process);
master_clock->updated_stages = FALSE;
/* Process queued events
@ -283,7 +299,10 @@ clutter_clock_dispatch (GSource *source,
for (l = stages; l != NULL; l = l->next)
_clutter_stage_process_queued_events (l->data);
CLUTTER_TIMER_STOP (_clutter_uprof_context, master_event_process);
_clutter_master_clock_advance (master_clock);
_clutter_run_repaint_functions ();
/* Update any stage that needs redraw/relayout after the clock
@ -299,6 +318,8 @@ clutter_clock_dispatch (GSource *source,
clutter_threads_leave ();
CLUTTER_TIMER_STOP (_clutter_uprof_context, master_dispatch_timer);
return TRUE;
}
@ -427,14 +448,31 @@ _clutter_master_clock_advance (ClutterMasterClock *master_clock)
{
GSList *l, *next;
CLUTTER_STATIC_TIMER (master_timeline_advance,
"Master Clock",
"Timelines Advancement",
"The time spent advancing all timelines",
0);
g_return_if_fail (CLUTTER_IS_MASTER_CLOCK (master_clock));
/* we protect ourselves from timelines being removed during
* the advancement by other timelines
*/
g_slist_foreach (master_clock->timelines, (GFunc) g_object_ref, NULL);
CLUTTER_TIMER_START (_clutter_uprof_context, master_timeline_advance);
for (l = master_clock->timelines; l != NULL; l = next)
{
next = l->next;
clutter_timeline_do_tick (l->data, &master_clock->cur_tick);
}
CLUTTER_TIMER_STOP (_clutter_uprof_context, master_timeline_advance);
g_slist_foreach (master_clock->timelines, (GFunc) g_object_unref, NULL);
}
/**

View File

@ -109,6 +109,36 @@ clutter_media_base_init (gpointer g_iface)
CLUTTER_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec);
/**
* ClutterMedia:subtitle-uri:
*
* The location of a subtitle file, expressed as a valid URI.
*
* Since: 1.2
*/
pspec = g_param_spec_string ("subtitle-uri",
"Subtitle URI",
"URI of a subtitle file",
NULL,
CLUTTER_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec);
/**
* ClutterMedia:subtitle-font-name:
*
* The font used to display subtitles. The font description has to
* follow the same grammar as the one recognized by
* pango_font_description_from_string().
*
* Since: 1.2
*/
pspec = g_param_spec_string ("subtitle-font-name",
"Subtitle Font Name",
"The font used to display subtitles",
NULL,
CLUTTER_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec);
/**
* ClutterMedia:audio-volume:
*
@ -348,6 +378,95 @@ clutter_media_get_progress (ClutterMedia *media)
return retval;
}
/**
* clutter_media_set_subtitle_uri:
* @media: a #ClutterMedia
* @uri: the URI of a subtitle file
*
* Sets the location of a subtitle file to display while playing @media.
*
* Since: 1.2
*/
void
clutter_media_set_subtitle_uri (ClutterMedia *media,
const char *uri)
{
g_return_if_fail (CLUTTER_IS_MEDIA (media));
g_object_set (G_OBJECT (media), "subtitle-uri", uri, NULL);
}
/**
* clutter_media_get_subtitle_uri:
* @media: a #ClutterMedia
*
* Retrieves the URI of the subtitle file in use.
*
* Return value: the URI of the subtitle file. Use g_free()
* to free the returned string
*
* Since: 1.2
*/
gchar *
clutter_media_get_subtitle_uri (ClutterMedia *media)
{
gchar *retval = NULL;
g_return_val_if_fail (CLUTTER_IS_MEDIA(media), NULL);
g_object_get (G_OBJECT (media), "subtitle-uri", &retval, NULL);
return retval;
}
/**
* clutter_media_set_subtitle_font_name:
* @media: a #ClutterMedia
* @font_name: a font name, or %NULL to set the default font name
*
* Sets the font used by the subtitle renderer. The @font_name string must be
* either %NULL, which means that the default font name of the underlying
* implementation will be used; or must follow the grammar recognized by
* pango_font_description_from_string() like:
*
* |[
* clutter_media_set_subtitle_font_name (media, "Sans 24pt");
* ]|
*
* Since: 1.2
*/
void
clutter_media_set_subtitle_font_name (ClutterMedia *media,
const char *font_name)
{
g_return_if_fail (CLUTTER_IS_MEDIA (media));
g_object_set (G_OBJECT (media), "subtitle-font-name", font_name, NULL);
}
/**
* clutter_media_get_subtitle_font_name:
* @media: a #ClutterMedia
*
* Retrieves the font name currently used.
*
* Return value: a string containing the font name. Use g_free()
* to free the returned string
*
* Since: 1.2
*/
gchar *
clutter_media_get_subtitle_font_name (ClutterMedia *media)
{
gchar *retval = NULL;
g_return_val_if_fail (CLUTTER_IS_MEDIA(media), NULL);
g_object_get (G_OBJECT (media), "subtitle-font-name", &retval, NULL);
return retval;
}
/**
* clutter_media_set_audio_volume:
* @media: a #ClutterMedia

View File

@ -62,26 +62,32 @@ struct _ClutterMediaIface
const GError *error);
};
GType clutter_media_get_type (void) G_GNUC_CONST;
GType clutter_media_get_type (void) G_GNUC_CONST;
void clutter_media_set_uri (ClutterMedia *media,
const gchar *uri);
gchar * clutter_media_get_uri (ClutterMedia *media);
void clutter_media_set_filename (ClutterMedia *media,
const gchar *filename);
void clutter_media_set_uri (ClutterMedia *media,
const gchar *uri);
gchar * clutter_media_get_uri (ClutterMedia *media);
void clutter_media_set_filename (ClutterMedia *media,
const gchar *filename);
void clutter_media_set_playing (ClutterMedia *media,
gboolean playing);
gboolean clutter_media_get_playing (ClutterMedia *media);
void clutter_media_set_progress (ClutterMedia *media,
gdouble progress);
gdouble clutter_media_get_progress (ClutterMedia *media);
void clutter_media_set_audio_volume (ClutterMedia *media,
gdouble volume);
gdouble clutter_media_get_audio_volume (ClutterMedia *media);
gboolean clutter_media_get_can_seek (ClutterMedia *media);
gdouble clutter_media_get_buffer_fill (ClutterMedia *media);
gdouble clutter_media_get_duration (ClutterMedia *media);
void clutter_media_set_playing (ClutterMedia *media,
gboolean playing);
gboolean clutter_media_get_playing (ClutterMedia *media);
void clutter_media_set_progress (ClutterMedia *media,
gdouble progress);
gdouble clutter_media_get_progress (ClutterMedia *media);
void clutter_media_set_subtitle_uri (ClutterMedia *media,
const gchar *uri);
gchar * clutter_media_get_subtitle_uri (ClutterMedia *media);
void clutter_media_set_subtitle_font_name (ClutterMedia *media,
const char *font_name);
gchar * clutter_media_get_subtitle_font_name (ClutterMedia *media);
void clutter_media_set_audio_volume (ClutterMedia *media,
gdouble volume);
gdouble clutter_media_get_audio_volume (ClutterMedia *media);
gboolean clutter_media_get_can_seek (ClutterMedia *media);
gdouble clutter_media_get_buffer_fill (ClutterMedia *media);
gdouble clutter_media_get_duration (ClutterMedia *media);
G_END_DECLS

View File

@ -58,13 +58,26 @@ typedef enum {
CLUTTER_ACTOR_IN_DESTRUCTION = 1 << 0,
CLUTTER_ACTOR_IS_TOPLEVEL = 1 << 1,
CLUTTER_ACTOR_IN_REPARENT = 1 << 2,
CLUTTER_ACTOR_SYNC_MATRICES = 1 << 3, /* Used by stage to indicate GL
* viewport / perspective etc
* needs (re)setting.
*/
CLUTTER_ACTOR_IN_PAINT = 1 << 4, /* Used to avoid recursion */
CLUTTER_ACTOR_IN_RELAYOUT = 1 << 5, /* Used to avoid recursion */
CLUTTER_STAGE_IN_RESIZE = 1 << 6
/* Used by the stage to indicate GL viewport / perspective etc needs
* (re)setting.
*/
CLUTTER_ACTOR_SYNC_MATRICES = 1 << 3,
/* Used to avoid recursion */
CLUTTER_ACTOR_IN_PAINT = 1 << 4,
/* Used to avoid recursion */
CLUTTER_ACTOR_IN_RELAYOUT = 1 << 5,
/* Used by the stage if resizing is an asynchronous operation (like on
* X11) to delay queueing relayouts until we got a notification from the
* event handling
*/
CLUTTER_STAGE_IN_RESIZE = 1 << 6,
/* a flag for internal children of Containers */
CLUTTER_ACTOR_INTERNAL_CHILD = 1 << 7
} ClutterPrivateFlags;
struct _ClutterInputDevice
@ -128,11 +141,14 @@ struct _ClutterMainContext
GSList *input_devices; /* For extra input devices, i.e
MultiTouch */
ClutterEvent *current_event;
guint32 last_event_time;
gulong redraw_count;
GList *repaint_funcs;
gint internal_child;
};
#define CLUTTER_CONTEXT() (_clutter_context_get_default ())

199
clutter/clutter-profile.c Normal file
View File

@ -0,0 +1,199 @@
#ifdef CLUTTER_ENABLE_PROFILE
#include "clutter-profile.h"
#include <stdlib.h>
UProfContext *_clutter_uprof_context;
#define REPORT_COLUMN0_WIDTH 40
static gboolean searched_for_gl_uprof_context = FALSE;
static UProfContext *gl_uprof_context = NULL;
typedef struct _ClutterUProfReportState
{
gulong n_frames;
} ClutterUProfReportState;
static void
print_counter (UProfCounterResult *counter,
gpointer data)
{
ClutterUProfReportState *state = data;
gulong count = uprof_counter_result_get_count (counter);
if (count == 0)
return;
g_print (" %-*s %-5ld %-5ld\n", REPORT_COLUMN0_WIDTH - 2,
uprof_counter_result_get_name (counter),
uprof_counter_result_get_count (counter),
uprof_counter_result_get_count (counter) / state->n_frames);
}
static char *
print_timer_fields (UProfTimerResult *timer,
guint *fields_width,
gpointer data)
{
ClutterUProfReportState *state = data;
/* Print the field titles when timer == NULL */
if (!timer)
return g_strdup_printf ("Per Frame");
return g_strdup_printf ("%-10.2f",
uprof_timer_result_get_total_msecs (timer) /
(float)state->n_frames);
}
static void
print_report (UProfReport *report, UProfContext *context)
{
GList *root_timers;
GList *l;
UProfTimerResult *stage_paint_timer;
UProfTimerResult *mainloop_timer;
UProfTimerResult *do_pick_timer;
float fps;
ClutterUProfReportState state;
g_print ("\n");
/* FIXME: We need to fix the way Clutter initializes the uprof library
* (we don't currently call uprof_init()) and add a mechanism to know
* if uprof_init hasn't been called so we can simply bail out of report
* generation and not print spurious warning about missing timers.
* Probably we can just have uprof_report_print bail out if uprof wasn't
* initialized, so we don't have to care here.
*/
stage_paint_timer = uprof_context_get_timer_result (context, "Redrawing");
#if 0
if (!stage_paint_timer)
g_critical ("Failed to find \"Redrawing\" timer "
"(you need to update print_report code if you rename it)\n");
#endif
state.n_frames = uprof_timer_result_get_start_count (stage_paint_timer);
g_print ("Frame count = %lu\n", state.n_frames);
mainloop_timer = uprof_context_get_timer_result (context, "Mainloop");
fps = (float)state.n_frames / (uprof_timer_result_get_total_msecs (mainloop_timer)
/ 1000.0);
g_print ("Average fps = %5.2f\n", fps);
do_pick_timer = uprof_context_get_timer_result (context, "Do pick");
if (do_pick_timer)
{
int n_picks = uprof_timer_result_get_start_count (do_pick_timer);
g_print ("Pick Stats:\n");
g_print ("Pick count = %d\n", n_picks);
g_print ("Average picks per frame = %3.2f\n",
(float)n_picks / (float)state.n_frames);
g_print ("Average Msecs per pick = %3.2f\n",
(float)uprof_timer_result_get_total_msecs (do_pick_timer)
/ (float)n_picks);
g_print ("\n");
}
/* XXX: UProfs default reporting code now supports dynamic sizing for the Name
* column, the only thing it's missing is support for adding custom columns but
* when that's added we should switch away from manual report generation. */
g_print ("Counters:\n");
g_print (" %-*s %5s %s\n", REPORT_COLUMN0_WIDTH - 2, "Name", "Total", "Per Frame");
g_print (" %-*s %5s %s\n", REPORT_COLUMN0_WIDTH - 2, "----", "-----", "---------");
uprof_context_foreach_counter (context,
UPROF_COUNTER_SORT_COUNT_INC,
print_counter,
&state);
g_print ("\n");
g_print ("Timers:\n");
root_timers = uprof_context_get_root_timer_results (context);
for (l = root_timers; l != NULL; l = l->next)
uprof_timer_result_print_and_children ((UProfTimerResult *)l->data,
print_timer_fields,
&state);
g_print ("\n");
}
/* FIXME: we should be able to deal with creating the uprof context in
* clutter_init instead. I think the only reason I did it this way originally
* was as a quick hack.
*/
static void __attribute__ ((constructor))
clutter_uprof_constructor (void)
{
_clutter_uprof_context = uprof_context_new ("Clutter");
}
#if 0
static void
print_timers (UProfContext *context)
{
GList *root_timers;
GList *l;
root_timers = uprof_context_get_root_timer_results ();
root_timers =
g_list_sort_with_data (context->root_timers,
(GCompareDataFunc)_uprof_timer_compare_total_times,
NULL);
for (l = context->timers; l != NULL; l = l->next)
{
UProfTimerState *timer = l->data;
timer->children =
g_list_sort_with_data (timer->children,
(GCompareDataFunc)
_uprof_timer_compare_total_times,
NULL);
}
}
#endif
static void __attribute__ ((destructor))
clutter_uprof_destructor (void)
{
if (!(clutter_profile_flags & CLUTTER_PROFILE_DISABLE_REPORT))
{
UProfReport *report = uprof_report_new ("Clutter report");
uprof_report_add_context (report, _clutter_uprof_context);
uprof_report_add_context_callback (report, print_report);
uprof_report_print (report);
uprof_report_unref (report);
}
uprof_context_unref (_clutter_uprof_context);
}
void
_clutter_profile_suspend (void)
{
if (G_UNLIKELY (!searched_for_gl_uprof_context))
{
gl_uprof_context = uprof_find_context ("OpenGL");
searched_for_gl_uprof_context = TRUE;
}
if (gl_uprof_context)
uprof_context_suspend (gl_uprof_context);
/* NB: The Cogl context is linked to this so it will also be suspended... */
uprof_context_suspend (_clutter_uprof_context);
}
void
_clutter_profile_resume (void)
{
if (gl_uprof_context)
uprof_context_resume (gl_uprof_context);
/* NB: The Cogl context is linked to this so it will also be resumed... */
uprof_context_resume (_clutter_uprof_context);
}
#endif

74
clutter/clutter-profile.h Normal file
View File

@ -0,0 +1,74 @@
/*
* 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/>.
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef _CLUTTER_PROFILE_H_
#define _CLUTTER_PROFILE_H_
#include <glib.h>
G_BEGIN_DECLS
typedef enum {
CLUTTER_PROFILE_PICKING_ONLY = 1 << 0,
CLUTTER_PROFILE_DISABLE_REPORT = 1 << 1
} ClutterProfileFlag;
#ifdef CLUTTER_ENABLE_PROFILE
#include <uprof.h>
extern UProfContext *_clutter_uprof_context;
#define CLUTTER_STATIC_TIMER UPROF_STATIC_TIMER
#define CLUTTER_STATIC_COUNTER UPROF_STATIC_COUNTER
#define CLUTTER_COUNTER_INC UPROF_COUNTER_INC
#define CLUTTER_COUNTER_DEC UPROF_COUNTER_DEC
#define CLUTTER_TIMER_START UPROF_TIMER_START
#define CLUTTER_TIMER_STOP UPROF_TIMER_STOP
void
_clutter_profile_suspend (void);
void
_clutter_profile_resume (void);
#else /* CLUTTER_ENABLE_PROFILE */
#define CLUTTER_STATIC_TIMER(A,B,C,D,E) extern void _clutter_dummy_decl (void)
#define CLUTTER_STATIC_COUNTER(A,B,C,D) extern void _clutter_dummy_decl (void)
#define CLUTTER_COUNTER_INC(A,B) G_STMT_START{ (void)0; }G_STMT_END
#define CLUTTER_COUNTER_DEC(A,B) G_STMT_START{ (void)0; }G_STMT_END
#define CLUTTER_TIMER_START(A,B) G_STMT_START{ (void)0; }G_STMT_END
#define CLUTTER_TIMER_STOP(A,B) G_STMT_START{ (void)0; }G_STMT_END
#define _clutter_profile_suspend() G_STMT_START {} G_STMT_END
#define _clutter_profile_resume() G_STMT_START {} G_STMT_END
#endif /* CLUTTER_ENABLE_PROFILE */
extern guint clutter_profile_flags;
G_END_DECLS
#endif /* _CLUTTER_PROFILE_H_ */

View File

@ -707,7 +707,7 @@ construct_timeline (ClutterScript *script,
PropertyInfo *pinfo = g_slice_new0 (PropertyInfo);
pinfo->name = g_strdelimit (g_strdup (name), G_STR_DELIMITERS, '-');
pinfo->node = node;
pinfo->node = json_node_copy (node);
oinfo->properties = g_list_prepend (oinfo->properties, pinfo);
}

View File

@ -68,6 +68,7 @@
#include "clutter-version.h" /* For flavour */
#include "clutter-id-pool.h"
#include "clutter-container.h"
#include "clutter-profile.h"
#include "cogl/cogl.h"
@ -96,6 +97,7 @@ struct _ClutterStagePrivate
guint is_user_resizable : 1;
guint use_fog : 1;
guint throttle_motion_events : 1;
guint use_alpha : 1;
};
enum
@ -110,7 +112,8 @@ enum
PROP_TITLE,
PROP_USER_RESIZE,
PROP_USE_FOG,
PROP_FOG
PROP_FOG,
PROP_USE_ALPHA
};
enum
@ -119,6 +122,7 @@ enum
UNFULLSCREEN,
ACTIVATE,
DEACTIVATE,
DELETE_EVENT,
LAST_SIGNAL
};
@ -243,17 +247,36 @@ clutter_stage_paint (ClutterActor *self)
{
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
CoglColor stage_color;
guint8 real_alpha;
CLUTTER_STATIC_TIMER (stage_clear_timer,
"Painting actors", /* parent */
"Stage clear",
"The time spent clearing the stage",
0 /* no application private data */);
CLUTTER_NOTE (PAINT, "Initializing stage paint");
/* composite the opacity to the stage color */
real_alpha = clutter_actor_get_opacity (self)
* priv->color.alpha
/ 255;
/* we use the real alpha to clear the stage if :use-alpha is
* set; the effect depends entirely on how the Clutter backend
*/
cogl_color_set_from_4ub (&stage_color,
priv->color.red,
priv->color.green,
priv->color.blue,
priv->color.alpha);
priv->use_alpha ? real_alpha
: 255);
cogl_color_premultiply (&stage_color);
CLUTTER_TIMER_START (_clutter_uprof_context, stage_clear_timer);
cogl_clear (&stage_color,
COGL_BUFFER_BIT_COLOR |
COGL_BUFFER_BIT_DEPTH);
CLUTTER_TIMER_STOP (_clutter_uprof_context, stage_clear_timer);
if (priv->use_fog)
{
@ -270,11 +293,6 @@ clutter_stage_paint (ClutterActor *self)
else
cogl_disable_fog ();
#if 0
CLUTTER_NOTE (PAINT, "Proxying the paint to the stage implementation");
_clutter_stage_window_paint (priv->impl);
#endif
/* this will take care of painting every child */
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (self);
}
@ -287,9 +305,9 @@ clutter_stage_pick (ClutterActor *self,
* emitted for the stage itself. The stage's pick id is effectively handled
* by the call to cogl_clear done in clutter-main.c:_clutter_do_pick_async()
*/
clutter_container_foreach (CLUTTER_CONTAINER (self),
CLUTTER_CALLBACK (clutter_actor_paint), NULL);
CLUTTER_CALLBACK (clutter_actor_paint),
NULL);
}
static void
@ -608,6 +626,18 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
CLUTTER_CONTEXT ()->redraw_count += 1;
}
static gboolean
clutter_stage_real_delete_event (ClutterStage *stage,
ClutterEvent *event)
{
if (clutter_stage_is_default (stage))
clutter_main_quit ();
else
clutter_actor_destroy (CLUTTER_ACTOR (stage));
return TRUE;
}
static void
clutter_stage_set_property (GObject *object,
guint prop_id,
@ -660,6 +690,10 @@ clutter_stage_set_property (GObject *object,
clutter_stage_set_fog (stage, g_value_get_boxed (value));
break;
case PROP_USE_ALPHA:
clutter_stage_set_use_alpha (stage, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -712,6 +746,10 @@ clutter_stage_get_property (GObject *gobject,
g_value_set_boxed (value, &priv->fog);
break;
case PROP_USE_ALPHA:
g_value_set_boolean (value, priv->use_alpha);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
@ -772,7 +810,6 @@ clutter_stage_finalize (GObject *object)
G_OBJECT_CLASS (clutter_stage_parent_class)->finalize (object);
}
static void
clutter_stage_class_init (ClutterStageClass *klass)
{
@ -939,6 +976,24 @@ clutter_stage_class_init (ClutterStageClass *klass)
CLUTTER_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_FOG, pspec);
/**
* ClutterStage:use-alpha:
*
* Whether the #ClutterStage should honour the alpha component of the
* #ClutterStage:color property when painting. If Clutter is run under
* a compositing manager this will result in the stage being blended
* with the underlying window(s)
*
* Since: 1.2
*/
pspec = g_param_spec_boolean ("use-alpha",
"Use Alpha",
"Whether to honour the alpha component of "
"the stage color",
FALSE,
CLUTTER_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_USE_ALPHA, pspec);
/**
* ClutterStage::fullscreen
* @stage: the stage which was fullscreened
@ -1007,9 +1062,41 @@ clutter_stage_class_init (ClutterStageClass *klass)
clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* ClutterStage::delete-event:
* @stage: the stage that received the event
* @event: a #ClutterEvent of type %CLUTTER_DELETE
*
* The ::delete-event signal is emitted when the user closes a
* #ClutterStage window using the window controls.
*
* Clutter by default will call clutter_main_quit() if @stage is
* the default stage, and clutter_actor_destroy() for any other
* stage.
*
* It is possible to override the default behaviour by connecting
* a new handler and returning %TRUE there.
*
* <note>This signal is emitted only on Clutter backends that
* embed #ClutterStage in native windows. It is not emitted for
* backends that use a static frame buffer.</note>
*
* Since: 1.2
*/
stage_signals[DELETE_EVENT] =
g_signal_new (I_("delete-event"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterStageClass, delete_event),
_clutter_boolean_handled_accumulator, NULL,
clutter_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
klass->fullscreen = clutter_stage_real_fullscreen;
klass->activate = clutter_stage_real_activate;
klass->deactivate = clutter_stage_real_deactivate;
klass->delete_event = clutter_stage_real_delete_event;
g_type_class_add_private (gobject_class, sizeof (ClutterStagePrivate));
}
@ -1488,6 +1575,9 @@ clutter_stage_event (ClutterStage *stage,
g_signal_emit_by_name (stage, "event", event, &retval);
if (!retval)
g_signal_emit_by_name (stage, "delete-event", event, &retval);
return retval;
}
@ -2129,3 +2219,53 @@ clutter_stage_get_throttle_motion_events (ClutterStage *stage)
return stage->priv->throttle_motion_events;
}
/**
* clutter_stage_set_use_alpha:
* @stage: a #ClutterStage
* @use_alpha: whether the stage should honour the opacity or the
* alpha channel of the stage color
*
* Sets whether the @stage should honour the #ClutterActor:opacity and
* the alpha channel of the #ClutterStage:color
*
* Since: 1.2
*/
void
clutter_stage_set_use_alpha (ClutterStage *stage,
gboolean use_alpha)
{
ClutterStagePrivate *priv;
g_return_if_fail (CLUTTER_IS_STAGE (stage));
priv = stage->priv;
if (priv->use_alpha != use_alpha)
{
priv->use_alpha = use_alpha;
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
g_object_notify (G_OBJECT (stage), "use-alpha");
}
}
/**
* clutter_stage_get_use_alpha:
* @stage: a #ClutterStage
*
* Retrieves the value set using clutter_stage_set_use_alpha()
*
* Return value: %TRUE if the stage should honour the opacity and the
* alpha channel of the stage color
*
* Since: 1.2
*/
gboolean
clutter_stage_get_use_alpha (ClutterStage *stage)
{
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
return stage->priv->use_alpha;
}

View File

@ -39,25 +39,13 @@ G_BEGIN_DECLS
#define CLUTTER_TYPE_FOG (clutter_fog_get_type ())
#define CLUTTER_TYPE_STAGE (clutter_stage_get_type())
#define CLUTTER_STAGE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
CLUTTER_TYPE_STAGE, ClutterStage))
#define CLUTTER_STAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_STAGE, ClutterStage))
#define CLUTTER_STAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_STAGE, ClutterStageClass))
#define CLUTTER_IS_STAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_STAGE))
#define CLUTTER_IS_STAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_STAGE))
#define CLUTTER_STAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_STAGE, ClutterStageClass))
#define CLUTTER_STAGE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), \
CLUTTER_TYPE_STAGE, ClutterStageClass))
#define CLUTTER_IS_STAGE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
CLUTTER_TYPE_STAGE))
#define CLUTTER_IS_STAGE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
CLUTTER_TYPE_STAGE))
#define CLUTTER_STAGE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
CLUTTER_TYPE_STAGE, ClutterStageClass))
#ifndef CLUTTER_DISABLE_DEPRECATED
/**
* CLUTTER_STAGE_WIDTH:
@ -65,9 +53,10 @@ G_BEGIN_DECLS
* Macro that evaluates to the width of the default stage
*
* Since: 0.2
*
* Deprecated: 1.2: Use clutter_actor_get_width() instead
*/
#define CLUTTER_STAGE_WIDTH() \
(clutter_actor_get_width (clutter_stage_get_default ()))
#define CLUTTER_STAGE_WIDTH() (clutter_actor_get_width (clutter_stage_get_default ()))
/**
* CLUTTER_STAGE_HEIGHT:
@ -75,9 +64,12 @@ G_BEGIN_DECLS
* Macro that evaluates to the height of the default stage
*
* Since: 0.2
*
* Deprecated: 1.2: use clutter_actor_get_height() instead
*/
#define CLUTTER_STAGE_HEIGHT() \
(clutter_actor_get_height (clutter_stage_get_default ()))
#define CLUTTER_STAGE_HEIGHT() (clutter_actor_get_height (clutter_stage_get_default ()))
#endif /* !CLUTTER_DISABLE_DEPRECATED */
/**
* ClutterPickMode:
@ -122,6 +114,7 @@ struct _ClutterStage
* @unfullscreen: handler for the #ClutterStage::unfullscreen signal
* @activate: handler for the #ClutterStage::activate signal
* @deactivate: handler for the #ClutterStage::deactive signal
* @delete_event: handler for the #ClutterStage::delete-event signal
*
* The #ClutterStageClass structure contains only private data
*
@ -140,9 +133,12 @@ struct _ClutterStageClass
void (* activate) (ClutterStage *stage);
void (* deactivate) (ClutterStage *stage);
gboolean (* delete_event) (ClutterStage *stage,
ClutterEvent *event);
/*< private >*/
/* padding for future expansion */
gpointer _padding_dummy[32];
gpointer _padding_dummy[31];
};
@ -247,6 +243,10 @@ void clutter_stage_set_throttle_motion_events (ClutterStage *stage,
gboolean throttle);
gboolean clutter_stage_get_throttle_motion_events (ClutterStage *stage);
void clutter_stage_set_use_alpha (ClutterStage *stage,
gboolean use_alpha);
gboolean clutter_stage_get_use_alpha (ClutterStage *stage);
/* Commodity macro, for mallum only */
#define clutter_stage_add(stage,actor) G_STMT_START { \
if (CLUTTER_IS_STAGE ((stage)) && CLUTTER_IS_ACTOR ((actor))) \

View File

@ -55,6 +55,7 @@
#include "clutter-main.h"
#include "clutter-private.h" /* includes pango/cogl-pango.h */
#include "clutter-units.h"
#include "clutter-marshal.h"
/* cursor width in pixels */
#define DEFAULT_CURSOR_SIZE 2
@ -111,8 +112,18 @@ struct _ClutterTextPrivate
LayoutCache cached_layouts[N_CACHED_LAYOUTS];
guint cache_age;
/* These are the attributes set by the attributes property */
PangoAttrList *attrs;
/* These are the attributes derived from the text when the
use-markup property is set */
PangoAttrList *markup_attrs;
/* This is the combination of the above two lists. It is set to NULL
whenever either of them changes and then regenerated by merging
the two lists whenever a layout is needed */
PangoAttrList *effective_attrs;
/* These are the attributes for the preedit string. These are merged
with the effective attributes into a temporary list before
creating a layout */
PangoAttrList *preedit_attrs;
guint alignment : 2;
@ -211,6 +222,8 @@ enum
TEXT_CHANGED,
CURSOR_EVENT,
ACTIVATE,
INSERT_TEXT,
DELETE_TEXT,
LAST_SIGNAL
};
@ -284,6 +297,52 @@ clutter_text_get_display_text (ClutterText *self)
}
}
static void
clutter_text_ensure_effective_attributes (ClutterText *self)
{
ClutterTextPrivate *priv = self->priv;
/* If we already have the effective attributes then we don't need to
do anything */
if (priv->effective_attrs == NULL)
{
if (priv->attrs)
{
/* If there are no markup attributes then we can just use
these attributes directly */
if (priv->markup_attrs == NULL)
priv->effective_attrs = pango_attr_list_ref (priv->attrs);
else
{
/* Otherwise we need to merge the two lists */
PangoAttrIterator *iter;
GSList *attributes, *l;
priv->effective_attrs = pango_attr_list_copy (priv->markup_attrs);
iter = pango_attr_list_get_iterator (priv->attrs);
do
{
attributes = pango_attr_iterator_get_attrs (iter);
for (l = attributes; l != NULL; l = l->next)
{
PangoAttribute *attr = l->data;
pango_attr_list_insert (priv->effective_attrs, attr);
}
g_slist_free (attributes);
}
while (pango_attr_iterator_next (iter));
}
}
else if (priv->markup_attrs)
/* We can just use the markup attributes directly */
priv->effective_attrs = pango_attr_list_ref (priv->markup_attrs);
}
}
static PangoLayout *
clutter_text_create_layout_no_cache (ClutterText *text,
gfloat allocation_width,
@ -330,8 +389,15 @@ clutter_text_create_layout_no_cache (ClutterText *text,
else
pango_layout_set_text (layout, contents, contents_len);
if (!priv->editable && priv->effective_attrs)
pango_layout_set_attributes (layout, priv->effective_attrs);
if (!priv->editable)
{
/* This will merge the markup attributes and the attributes
property if needed */
clutter_text_ensure_effective_attributes (text);
if (priv->effective_attrs)
pango_layout_set_attributes (layout, priv->effective_attrs);
}
pango_layout_set_alignment (layout, priv->alignment);
pango_layout_set_single_paragraph_mode (layout, priv->single_line_mode);
@ -746,39 +812,6 @@ clutter_text_delete_selection (ClutterText *self)
return TRUE;
}
static void
clutter_text_merge_attributes (ClutterText *self)
{
ClutterTextPrivate *priv = self->priv;
PangoAttrIterator *iter;
GSList *attributes, *l;
if (!priv->attrs)
return;
if (!priv->effective_attrs)
{
priv->effective_attrs = pango_attr_list_ref (priv->attrs);
return;
}
iter = pango_attr_list_get_iterator (priv->attrs);
do
{
attributes = pango_attr_iterator_get_attrs (iter);
for (l = attributes; l != NULL; l = l->next)
{
PangoAttribute *attr = l->data;
pango_attr_list_insert (priv->effective_attrs, attr);
}
g_slist_free (attributes);
}
while (pango_attr_iterator_next (iter));
}
static inline void
clutter_text_set_text_internal (ClutterText *self,
const gchar *text)
@ -872,19 +905,28 @@ clutter_text_set_markup_internal (ClutterText *self,
if (text)
{
gint tmp_pos = 0;
g_signal_emit (self, text_signals[DELETE_TEXT], 0, 0, -1);
g_signal_emit (self, text_signals[INSERT_TEXT], 0, text,
strlen (text), &tmp_pos);
clutter_text_set_text_internal (self, text);
g_free (text);
}
if (attrs)
/* Store the new markup attributes */
if (priv->markup_attrs)
pango_attr_list_unref (priv->markup_attrs);
priv->markup_attrs = attrs;
/* Clear the effective attributes so they will be regenerated when a
layout is created */
if (priv->effective_attrs)
{
if (priv->effective_attrs)
pango_attr_list_unref (priv->effective_attrs);
priv->effective_attrs = attrs;
pango_attr_list_unref (priv->effective_attrs);
priv->effective_attrs = NULL;
}
clutter_text_merge_attributes (self);
}
static void
@ -1135,6 +1177,15 @@ clutter_text_finalize (GObject *gobject)
if (priv->font_desc)
pango_font_description_free (priv->font_desc);
if (priv->attrs)
pango_attr_list_unref (priv->attrs);
if (priv->markup_attrs)
pango_attr_list_unref (priv->markup_attrs);
if (priv->effective_attrs)
pango_attr_list_unref (priv->effective_attrs);
if (priv->preedit_attrs)
pango_attr_list_unref (priv->preedit_attrs);
g_free (priv->text);
g_free (priv->font_name);
@ -2566,6 +2617,56 @@ clutter_text_class_init (ClutterTextClass *klass)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* ClutterText::insert-text:
* @self: the #ClutterText that emitted the signal
* @new_text: the new text to insert
* @new_text_length: the length of the new text, in bytes, or -1 if
* new_text is nul-terminated
* @position: the position, in characters, at which to insert the
* new text. this is an in-out parameter. After the signal
* emission is finished, it should point after the newly
* inserted text.
*
* This signal is emitted when text is inserted into the actor by
* the user. It is emitted before @self text changes.
*
* Since: 1.2
*/
text_signals[INSERT_TEXT] =
g_signal_new ("insert-text",
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
0,
NULL, NULL,
clutter_marshal_VOID__STRING_INT_POINTER,
G_TYPE_NONE, 3,
G_TYPE_STRING,
G_TYPE_INT,
G_TYPE_POINTER);
/**
* ClutterText::delete-text:
* @self: the #ClutterText that emitted the signal
* @start_pos: the starting position
* @end_pos: the end position
*
* This signal is emitted when text is deleted from the actor by
* the user. It is emitted before @self text changes.
*
* Since: 1.2
*/
text_signals[DELETE_TEXT] =
g_signal_new ("delete-text",
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
0,
NULL, NULL,
clutter_marshal_VOID__INT_INT,
G_TYPE_NONE, 2,
G_TYPE_INT,
G_TYPE_INT);
/**
* ClutterText::cursor-event:
* @self: the #ClutterText that emitted the signal
@ -2734,6 +2835,7 @@ clutter_text_init (ClutterText *self)
priv->max_length = 0;
priv->cursor_size = DEFAULT_CURSOR_SIZE;
memset (&priv->cursor_pos, 0, sizeof (ClutterGeometry));
priv->font_changed_id =
g_signal_connect_swapped (clutter_get_default_backend (),
@ -3480,6 +3582,14 @@ clutter_text_set_text (ClutterText *self,
{
g_return_if_fail (CLUTTER_IS_TEXT (self));
g_signal_emit (self, text_signals[DELETE_TEXT], 0, 0, -1);
if (text)
{
gint tmp_pos = 0;
g_signal_emit (self, text_signals[INSERT_TEXT], 0, text,
strlen (text), &tmp_pos);
}
clutter_text_set_use_markup_internal (self, FALSE);
clutter_text_set_text_internal (self, text ? text : "");
}
@ -3784,18 +3894,13 @@ clutter_text_set_attributes (ClutterText *self,
priv->attrs = attrs;
if (!priv->use_markup)
/* Clear the effective attributes so they will be regenerated when a
layout is created */
if (priv->effective_attrs)
{
if (attrs)
pango_attr_list_ref (attrs);
if (priv->effective_attrs)
pango_attr_list_unref (priv->effective_attrs);
priv->effective_attrs = attrs;
pango_attr_list_unref (priv->effective_attrs);
priv->effective_attrs = NULL;
}
else
clutter_text_set_markup_internal (self, priv->text);
clutter_text_dirty_cache (self);
@ -4238,7 +4343,9 @@ clutter_text_insert_unichar (ClutterText *self,
new = g_string_insert_unichar (new, pos, wc);
clutter_text_set_text (self, new->str);
g_signal_emit (self, text_signals[INSERT_TEXT], 0, &wc, 1, &pos);
clutter_text_set_text_internal (self, new->str);
if (priv->position >= 0)
{
@ -4283,7 +4390,10 @@ clutter_text_insert_text (ClutterText *self,
new = g_string_new (priv->text);
new = g_string_insert (new, pos_bytes, text);
clutter_text_set_text (self, new->str);
g_signal_emit (self, text_signals[INSERT_TEXT], 0,
text, g_utf8_strlen (text, -1), &position);
clutter_text_set_text_internal (self, new->str);
if (position >= 0 && priv->position >= position)
{
@ -4338,7 +4448,9 @@ clutter_text_delete_text (ClutterText *self,
new = g_string_new (priv->text);
new = g_string_erase (new, start_bytes, end_bytes - start_bytes);
clutter_text_set_text (self, new->str);
g_signal_emit (self, text_signals[DELETE_TEXT], 0, start_pos, end_pos);
clutter_text_set_text_internal (self, new->str);
g_string_free (new, TRUE);
}
@ -4362,6 +4474,7 @@ clutter_text_delete_chars (ClutterText *self,
gint len;
gint pos;
gint num_pos;
gint start_pos;
g_return_if_fail (CLUTTER_IS_TEXT (self));
@ -4385,7 +4498,11 @@ clutter_text_delete_chars (ClutterText *self,
new = g_string_erase (new, pos, num_pos - pos);
}
clutter_text_set_text (self, new->str);
start_pos = clutter_text_get_cursor_position (self);
g_signal_emit (self, text_signals[DELETE_TEXT], 0,
start_pos, start_pos + n_chars);
clutter_text_set_text_internal (self, new->str);
if (priv->position > 0)
clutter_text_set_cursor_position (self, priv->position - n_chars);

View File

@ -34,12 +34,6 @@
* clutter_texture_set_from_file() functions are used to copy image
* data into texture memory and subsequently realize the texture.
*
* If texture reads are supported by underlying GL implementation,
* unrealizing frees image data from texture memory moving to main
* system memory. Re-realizing then performs the opposite operation.
* This process allows basic management of commonly limited available
* texture memory.
*
* Note: a ClutterTexture will scale its contents to fit the bounding
* box requested using clutter_actor_set_size(). To display an area of
* a texture without scaling, you should set the clip area using
@ -86,16 +80,9 @@ struct _ClutterTexturePrivate
ClutterActor *fbo_source;
CoglHandle fbo_handle;
/* Non video memory copy of image data */
guint local_data_width, local_data_height;
guint local_data_rowstride;
guint local_data_has_alpha;
guchar *local_data;
guint sync_actor_size : 1;
guint repeat_x : 1;
guint repeat_y : 1;
guint in_dispose : 1;
guint keep_aspect_ratio : 1;
guint load_size_async : 1;
guint load_data_async : 1;
@ -172,12 +159,6 @@ static GStaticMutex upload_list_mutex = G_STATIC_MUTEX_INIT;
static void
texture_fbo_free_resources (ClutterTexture *texture);
static void
clutter_texture_save_to_local_data (ClutterTexture *texture);
static void
clutter_texture_load_from_local_data (ClutterTexture *texture);
GQuark
clutter_texture_error_quark (void)
{
@ -241,14 +222,6 @@ clutter_texture_unrealize (ClutterActor *actor)
if (priv->material == COGL_INVALID_HANDLE)
return;
/* there's no need to read the pixels back when unrealizing inside
* a dispose run, and the dispose() call will release the GL
* texture data as well, so we can safely bail out now
*/
if ((CLUTTER_PRIVATE_FLAGS (actor) & CLUTTER_ACTOR_IN_DESTRUCTION) ||
priv->in_dispose)
return;
CLUTTER_MARK();
if (priv->fbo_source != NULL)
@ -260,24 +233,6 @@ clutter_texture_unrealize (ClutterActor *actor)
return;
}
if (clutter_feature_available (CLUTTER_FEATURE_TEXTURE_READ_PIXELS))
{
/* Move image data from video to main memory.
* GL/ES cant do this - it probably makes sense
* to move this kind of thing into a ClutterProxyTexture
* where this behaviour can be better controlled.
*
* Or make it controllable via a property.
*/
if (priv->local_data == NULL)
{
clutter_texture_save_to_local_data (texture);
CLUTTER_NOTE (TEXTURE, "moved pixels into system mem");
}
texture_free_gl_resources (texture);
}
CLUTTER_NOTE (TEXTURE, "Texture unrealized");
}
@ -327,25 +282,14 @@ clutter_texture_realize (ClutterActor *actor)
return;
}
if (priv->local_data != NULL)
{
/* Move any local image data we have from unrealization
* back into video memory.
*/
clutter_texture_load_from_local_data (texture);
}
else
{
/* If we have no data, then realization is a no-op but
* we still want to be in REALIZED state to maintain
* invariants. We may have already created the texture
* if someone set some data earlier, or we may create it
* later if someone sets some data later. The fact that
* we may have created it earlier is really a bug, since
* it means ClutterTexture can have GL resources without
* being realized.
*/
}
/* If the texture is not a FBO, then realization is a no-op but
* we still want to be in REALIZED state to maintain invariants.
* We may have already created the texture if someone set some
* data earlier, or we may create it later if someone sets some
* data later. The fact that we may have created it earlier is
* really a bug, since it means ClutterTexture can have GL
* resources without being realized.
*/
CLUTTER_NOTE (TEXTURE, "Texture realized");
}
@ -705,23 +649,9 @@ clutter_texture_dispose (GObject *object)
priv = texture->priv;
/* mark that we are in dispose, so when the parent class'
* dispose implementation will call unrealize on us we'll
* not try to copy back the resources from video memory
* to system memory
*/
if (!priv->in_dispose)
priv->in_dispose = TRUE;
texture_free_gl_resources (texture);
texture_fbo_free_resources (texture);
if (priv->local_data != NULL)
{
g_free (priv->local_data);
priv->local_data = NULL;
}
clutter_texture_async_load_cancel (texture);
G_OBJECT_CLASS (clutter_texture_parent_class)->dispose (object);
@ -1177,78 +1107,9 @@ clutter_texture_init (ClutterTexture *self)
priv->sync_actor_size = TRUE;
priv->material = cogl_material_new ();
priv->fbo_handle = COGL_INVALID_HANDLE;
priv->local_data = NULL;
priv->keep_aspect_ratio = FALSE;
}
static void
clutter_texture_save_to_local_data (ClutterTexture *texture)
{
ClutterTexturePrivate *priv;
int bpp;
CoglPixelFormat pixel_format;
CoglHandle cogl_texture;
priv = texture->priv;
if (priv->local_data)
{
g_free (priv->local_data);
priv->local_data = NULL;
}
if (priv->material == COGL_INVALID_HANDLE)
return;
cogl_texture = clutter_texture_get_cogl_texture (texture);
priv->local_data_width = cogl_texture_get_width (cogl_texture);
priv->local_data_height = cogl_texture_get_height (cogl_texture);
pixel_format = cogl_texture_get_format (cogl_texture);
priv->local_data_has_alpha = pixel_format & COGL_A_BIT;
bpp = priv->local_data_has_alpha ? 4 : 3;
/* Align to 4 bytes */
priv->local_data_rowstride = (priv->local_data_width * bpp + 3) & ~3;
priv->local_data = g_malloc (priv->local_data_rowstride
* priv->local_data_height);
if (cogl_texture_get_data (cogl_texture,
priv->local_data_has_alpha
? COGL_PIXEL_FORMAT_RGBA_8888_PRE
: COGL_PIXEL_FORMAT_RGB_888,
priv->local_data_rowstride,
priv->local_data) == 0)
{
g_free (priv->local_data);
priv->local_data = NULL;
}
}
static void
clutter_texture_load_from_local_data (ClutterTexture *texture)
{
ClutterTexturePrivate *priv;
priv = texture->priv;
if (priv->local_data == NULL)
return;
clutter_texture_set_from_rgb_data (texture,
priv->local_data,
priv->local_data_has_alpha,
priv->local_data_width,
priv->local_data_height,
priv->local_data_rowstride,
priv->local_data_has_alpha ? 4: 3,
CLUTTER_TEXTURE_RGB_FLAG_PREMULT, NULL);
g_free (priv->local_data);
priv->local_data = NULL;
}
/**
* clutter_texture_get_cogl_material:
* @texture: A #ClutterTexture
@ -1393,15 +1254,7 @@ clutter_texture_set_cogl_texture (ClutterTexture *texture,
/* Remove old texture */
texture_free_gl_resources (texture);
/* Free any saved data so realization doesn't resend it to GL */
if (priv->local_data)
{
g_free (priv->local_data);
priv->local_data = NULL;
}
/* Use the new texture */
cogl_material_set_layer (priv->material, 0, cogl_tex);
/* The material now holds a reference to the texture so we can

View File

@ -153,6 +153,11 @@ gboolean clutter_actor_box_contains (const ClutterActorBox *box,
gfloat y);
void clutter_actor_box_from_vertices (ClutterActorBox *box,
const ClutterVertex verts[]);
void clutter_actor_box_interpolate (const ClutterActorBox *initial,
const ClutterActorBox *final,
gdouble progress,
ClutterActorBox *result);
void clutter_actor_box_clamp_to_pixel (ClutterActorBox *box);
/**
* ClutterGeometry:

View File

@ -34,6 +34,17 @@ INCLUDES = \
-I$(top_builddir)/clutter/cogl \
$(NULL)
AM_CPPFLAGS = \
-DG_DISABLE_SINGLE_INCLUDES \
-DG_DISABLE_DEPRECATED \
-DG_LOG_DOMAIN=\"Cogl-$(COGL_WINSYS)\" \
-DCLUTTER_COMPILATION \
$(COGL_DEBUG_CFLAGS) \
$(CLUTTER_DEBUG_CFLAGS) \
$(NULL)
AM_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS)
cogl-defines.h: $(top_builddir)/clutter/cogl/cogl/driver/gl/cogl-defines.h $(top_builddir)/clutter/cogl/cogl/driver/gles/cogl-defines.h
$(QUIET_GEN)cp -f $(top_builddir)/clutter/cogl/cogl/driver/$(COGL_DRIVER)/cogl-defines.h $(@F)
@ -68,28 +79,7 @@ cogl_winsys_sources = \
$(srcdir)/winsys/cogl-win32.c \
$(NULL)
# glib-mkenums rules
glib_enum_h = cogl-enum-types.h
glib_enum_c = cogl-enum-types.c
glib_enum_headers = $(cogl_public_h)
include $(top_srcdir)/build/autotools/Makefile.am.enums
noinst_LTLIBRARIES = libclutter-cogl.la
libclutter_cogl_la_CPPFLAGS = \
$(COGL_DEBUG_CFLAGS) \
$(CLUTTER_DEBUG_CFLAGS) \
$(MAINTAINER_CFLAGS) \
-DG_DISABLE_SINGLE_INCLUDES \
-DG_LOG_DOMAIN=\"Cogl-$(COGL_WINSYS)\" \
-DCLUTTER_COMPILATION
libclutter_cogl_la_CFLAGS = $(CLUTTER_CFLAGS)
libclutter_cogl_la_LIBADD = -lm $(CLUTTER_LIBS) \
$(top_builddir)/clutter/cogl/cogl/driver/$(COGL_DRIVER)/libclutter-cogl-driver.la
libclutter_cogl_la_SOURCES = \
$(BUILT_SOURCES) \
cogl_sources_c = \
$(srcdir)/winsys/cogl-winsys.h \
$(srcdir)/winsys/cogl-@COGL_WINSYS@.c \
$(srcdir)/cogl-handle.h \
@ -143,8 +133,22 @@ libclutter_cogl_la_SOURCES = \
$(srcdir)/cogl-framebuffer.c \
$(srcdir)/cogl-matrix-mesa.h \
$(srcdir)/cogl-matrix-mesa.c \
$(srcdir)/cogl-profile.h \
$(srcdir)/cogl-profile.c \
$(NULL)
# glib-mkenums rules
glib_enum_h = cogl-enum-types.h
glib_enum_c = cogl-enum-types.c
glib_enum_headers = $(cogl_public_h)
include $(top_srcdir)/build/autotools/Makefile.am.enums
noinst_LTLIBRARIES = libclutter-cogl.la
libclutter_cogl_la_LIBADD = -lm $(CLUTTER_LIBS) $(top_builddir)/clutter/cogl/cogl/driver/$(COGL_DRIVER)/libclutter-cogl-driver.la
libclutter_cogl_la_SOURCES = $(BUILT_SOURCES) $(cogl_sources_c)
EXTRA_DIST += $(cogl_winsys_sources)
EXTRA_DIST += stb_image.c
@ -163,11 +167,8 @@ if HAVE_INTROSPECTION
Cogl-@CLUTTER_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libclutter-cogl.la
$(QUIET_GEN)$(INTROSPECTION_SCANNER) -v \
--namespace Cogl --nsversion=@CLUTTER_API_VERSION@ \
-I$(srcdir) \
-I$(srcdir)/.. \
-I$(srcdir)/winsys \
-I$(srcdir)/driver/@COGL_DRIVER@ \
-DCLUTTER_COMPILATION \
$(INCLUDES) \
$(AM_CPPFLAGS) \
--c-include='cogl/cogl.h' \
--include=GL-1.0 \
--include=GObject-2.0 \
@ -184,4 +185,3 @@ gir_DATA = $(BUILT_GIRSOURCES)
CLEANFILES += $(BUILT_GIRSOURCES)
endif

View File

@ -56,7 +56,8 @@ typedef struct _CoglOffscreen
{
CoglFramebuffer _parent;
GLuint fbo_handle;
GLuint gl_stencil_handle;
GSList *renderbuffers;
CoglHandle texture;
} CoglOffscreen;
#define COGL_OFFSCREEN(X) ((CoglOffscreen *)(X))

View File

@ -71,6 +71,21 @@
#ifndef GL_STENCIL_INDEX8
#define GL_STENCIL_INDEX8 0x8D48
#endif
#ifndef GL_DEPTH_STENCIL
#define GL_DEPTH_STENCIL 0x84F9
#endif
#ifndef GL_DEPTH_ATTACHMENT
#define GL_DEPTH_ATTACHMENT 0x8D00
#endif
#ifndef GL_DEPTH_COMPONENT16
#define GL_DEPTH_COMPONENT16 0x81A5
#endif
typedef enum {
_TRY_DEPTH_STENCIL = 1L<<0,
_TRY_DEPTH = 1L<<1,
_TRY_STENCIL = 1L<<2
} TryFBOFlags;
static void _cogl_framebuffer_free (CoglFramebuffer *framebuffer);
static void _cogl_onscreen_free (CoglOnscreen *onscreen);
@ -232,17 +247,123 @@ _cogl_framebuffer_get_projection_stack (CoglHandle handle)
return framebuffer->projection_stack;
}
static gboolean
try_creating_fbo (CoglOffscreen *offscreen,
TryFBOFlags flags,
CoglHandle texture)
{
GLuint gl_depth_stencil_handle;
GLuint gl_depth_handle;
GLuint gl_stencil_handle;
GLuint tex_gl_handle;
GLenum tex_gl_target;
GLuint fbo_gl_handle;
GLenum status;
_COGL_GET_CONTEXT (ctx, FALSE);
if (!cogl_texture_get_gl_texture (texture, &tex_gl_handle, &tex_gl_target))
return FALSE;
if (tex_gl_target != GL_TEXTURE_2D
#ifdef HAVE_COGL_GL
&& tex_gl_target != GL_TEXTURE_RECTANGLE_ARB
#endif
)
return FALSE;
/* We are about to generate and bind a new fbo, so when next flushing the
* journal, we will need to rebind the current framebuffer... */
ctx->dirty_bound_framebuffer = 1;
/* Generate framebuffer */
glGenFramebuffers (1, &fbo_gl_handle);
GE (glBindFramebuffer (GL_FRAMEBUFFER, fbo_gl_handle));
offscreen->fbo_handle = fbo_gl_handle;
GE (glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
tex_gl_target, tex_gl_handle, 0));
if (flags & _TRY_DEPTH_STENCIL)
{
/* Create a renderbuffer for depth and stenciling */
GE (glGenRenderbuffers (1, &gl_depth_stencil_handle));
GE (glBindRenderbuffer (GL_RENDERBUFFER, gl_depth_stencil_handle));
GE (glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_STENCIL,
cogl_texture_get_width (texture),
cogl_texture_get_height (texture)));
GE (glBindRenderbuffer (GL_RENDERBUFFER, 0));
GE (glFramebufferRenderbuffer (GL_FRAMEBUFFER,
GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, gl_depth_stencil_handle));
GE (glFramebufferRenderbuffer (GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, gl_depth_stencil_handle));
offscreen->renderbuffers =
g_slist_prepend (offscreen->renderbuffers,
GUINT_TO_POINTER (gl_depth_stencil_handle));
}
if (flags & _TRY_DEPTH)
{
GE (glGenRenderbuffers (1, &gl_depth_handle));
GE (glBindRenderbuffer (GL_RENDERBUFFER, gl_depth_handle));
/* For now we just ask for GL_DEPTH_COMPONENT16 since this is all that's
* available under GLES */
GE (glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
cogl_texture_get_width (texture),
cogl_texture_get_height (texture)));
GE (glBindRenderbuffer (GL_RENDERBUFFER, 0));
GE (glFramebufferRenderbuffer (GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, gl_depth_handle));
offscreen->renderbuffers =
g_slist_prepend (offscreen->renderbuffers,
GUINT_TO_POINTER (gl_depth_handle));
}
if (flags & _TRY_STENCIL)
{
GE (glGenRenderbuffers (1, &gl_stencil_handle));
GE (glBindRenderbuffer (GL_RENDERBUFFER, gl_stencil_handle));
GE (glRenderbufferStorage (GL_RENDERBUFFER, GL_STENCIL_INDEX8,
cogl_texture_get_width (texture),
cogl_texture_get_height (texture)));
GE (glBindRenderbuffer (GL_RENDERBUFFER, 0));
GE (glFramebufferRenderbuffer (GL_FRAMEBUFFER,
GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, gl_stencil_handle));
offscreen->renderbuffers =
g_slist_prepend (offscreen->renderbuffers,
GUINT_TO_POINTER (gl_stencil_handle));
}
/* Make sure it's complete */
status = glCheckFramebufferStatus (GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
GSList *l;
GE (glDeleteFramebuffers (1, &fbo_gl_handle));
for (l = offscreen->renderbuffers; l; l = l->next)
{
GLuint renderbuffer = GPOINTER_TO_UINT (l->data);
GE (glDeleteRenderbuffers (1, &renderbuffer));
}
return FALSE;
}
return TRUE;
}
CoglHandle
cogl_offscreen_new_to_texture (CoglHandle texhandle)
{
CoglOffscreen *offscreen;
int width;
int height;
GLuint tex_gl_handle;
GLenum tex_gl_target;
GLuint fbo_gl_handle;
GLuint gl_stencil_handle;
GLenum status;
CoglOffscreen *offscreen;
static TryFBOFlags flags;
static gboolean have_working_flags = FALSE;
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
@ -257,42 +378,6 @@ cogl_offscreen_new_to_texture (CoglHandle texhandle)
if (cogl_texture_is_sliced (texhandle))
return COGL_INVALID_HANDLE;
/* Pick the single texture slice width, height and GL id */
width = cogl_texture_get_width (texhandle);
height = cogl_texture_get_height (texhandle);
if (!cogl_texture_get_gl_texture (texhandle, &tex_gl_handle, &tex_gl_target))
return COGL_INVALID_HANDLE;
if (tex_gl_target != GL_TEXTURE_2D
#ifdef HAVE_COGL_GL
&& tex_gl_target != GL_TEXTURE_RECTANGLE_ARB
#endif
)
return COGL_INVALID_HANDLE;
/* Create a renderbuffer for stenciling */
GE (glGenRenderbuffers (1, &gl_stencil_handle));
GE (glBindRenderbuffer (GL_RENDERBUFFER, gl_stencil_handle));
GE (glRenderbufferStorage (GL_RENDERBUFFER, GL_STENCIL_INDEX8,
cogl_texture_get_width (texhandle),
cogl_texture_get_height (texhandle)));
GE (glBindRenderbuffer (GL_RENDERBUFFER, 0));
/* We are about to generate and bind a new fbo, so when next flushing the
* journal, we will need to rebind the current framebuffer... */
ctx->dirty_bound_framebuffer = 1;
/* Generate framebuffer */
glGenFramebuffers (1, &fbo_gl_handle);
GE (glBindFramebuffer (GL_FRAMEBUFFER, fbo_gl_handle));
GE (glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
tex_gl_target, tex_gl_handle, 0));
GE (glFramebufferRenderbuffer (GL_FRAMEBUFFER,
GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, gl_stencil_handle));
/* XXX: The framebuffer_object spec isn't clear in defining whether attaching
* a texture as a renderbuffer with mipmap filtering enabled while the
* mipmaps have not been uploaded should result in an incomplete framebuffer
@ -305,64 +390,60 @@ cogl_offscreen_new_to_texture (CoglHandle texhandle)
*/
_cogl_texture_set_filters (texhandle, GL_NEAREST, GL_NEAREST);
/* Make sure it's complete */
status = glCheckFramebufferStatus (GL_FRAMEBUFFER);
offscreen = g_new0 (CoglOffscreen, 1);
offscreen->texture = cogl_handle_ref (texhandle);
if (status != GL_FRAMEBUFFER_COMPLETE)
if ((have_working_flags &&
try_creating_fbo (offscreen, flags, texhandle)) ||
try_creating_fbo (offscreen, flags = _TRY_DEPTH_STENCIL, texhandle) ||
try_creating_fbo (offscreen, flags = _TRY_DEPTH | _TRY_STENCIL,
texhandle) ||
try_creating_fbo (offscreen, flags = _TRY_STENCIL, texhandle) ||
try_creating_fbo (offscreen, flags = _TRY_DEPTH, texhandle) ||
try_creating_fbo (offscreen, flags = 0, texhandle))
{
/* Stencil renderbuffers aren't always supported. Try again
without the stencil buffer */
GE (glFramebufferRenderbuffer (GL_FRAMEBUFFER,
GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER,
0));
GE (glDeleteRenderbuffers (1, &gl_stencil_handle));
gl_stencil_handle = 0;
/* Record that the last set of flags succeeded so that we can
try that set first next time */
have_working_flags = TRUE;
status = glCheckFramebufferStatus (GL_FRAMEBUFFER);
_cogl_framebuffer_init (COGL_FRAMEBUFFER (offscreen),
COGL_FRAMEBUFFER_TYPE_OFFSCREEN,
cogl_texture_get_width (texhandle),
cogl_texture_get_height (texhandle));
if (status != GL_FRAMEBUFFER_COMPLETE)
{
/* Still failing, so give up */
GE (glDeleteFramebuffers (1, &fbo_gl_handle));
GE (glBindFramebuffer (GL_FRAMEBUFFER, 0));
return COGL_INVALID_HANDLE;
}
return _cogl_offscreen_handle_new (offscreen);
}
else
{
g_free (offscreen);
/* XXX: This API should probably have been defined to take a GError */
g_warning ("%s: Failed to create an OpenGL framebuffer", G_STRLOC);
return COGL_INVALID_HANDLE;
}
offscreen = g_new0 (CoglOffscreen, 1);
_cogl_framebuffer_init (COGL_FRAMEBUFFER (offscreen),
COGL_FRAMEBUFFER_TYPE_OFFSCREEN,
width,
height);
offscreen->fbo_handle = fbo_gl_handle;
offscreen->gl_stencil_handle = gl_stencil_handle;
/* XXX: Can we get a away with removing this? It wasn't documented, and most
* users of the API are hopefully setting up the modelview from scratch
* anyway */
#if 0
cogl_matrix_translate (&framebuffer->modelview, -1.0f, -1.0f, 0.0f);
cogl_matrix_scale (&framebuffer->modelview,
2.0f / framebuffer->width, 2.0f / framebuffer->height, 1.0f);
#endif
return _cogl_offscreen_handle_new (offscreen);
}
static void
_cogl_offscreen_free (CoglOffscreen *offscreen)
{
GSList *l;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Chain up to parent */
_cogl_framebuffer_free (COGL_FRAMEBUFFER (offscreen));
if (offscreen->gl_stencil_handle)
GE (glDeleteRenderbuffers (1, &offscreen->gl_stencil_handle));
for (l = offscreen->renderbuffers; l; l = l->next)
{
GLuint renderbuffer = GPOINTER_TO_UINT (l->data);
GE (glDeleteRenderbuffers (1, &renderbuffer));
}
g_slist_free (offscreen->renderbuffers);
GE (glDeleteFramebuffers (1, &offscreen->fbo_handle));
if (offscreen->texture != COGL_INVALID_HANDLE)
cogl_handle_unref (offscreen->texture);
g_free (offscreen);
}

View File

@ -27,13 +27,6 @@
#include "cogl.h"
#include "cogl-matrix-stack.h"
typedef enum
{
COGL_MATRIX_MODELVIEW,
COGL_MATRIX_PROJECTION,
COGL_MATRIX_TEXTURE
} CoglMatrixMode;
typedef enum
{
COGL_FRONT_WINDING_CLOCKWISE,

View File

@ -33,6 +33,7 @@
#include "cogl-material-private.h"
#include "cogl-vertex-buffer-private.h"
#include "cogl-framebuffer-private.h"
#include "cogl-profile.h"
#include <string.h>
#include <gmodule.h>
@ -535,12 +536,19 @@ _cogl_journal_flush (void)
(cogl_get_features () & COGL_FEATURE_VBOS) ? FALSE : TRUE;
CoglHandle framebuffer;
CoglMatrixStack *modelview_stack;
COGL_STATIC_TIMER (flush_timer,
"Mainloop", /* parent */
"Journal Flush",
"The time spent flushing the Cogl journal",
0 /* no application private data */);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (ctx->journal->len == 0)
return;
COGL_TIMER_START (_cogl_uprof_context, flush_timer);
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_BATCHING))
g_print ("BATCHING: journal len = %d\n", ctx->journal->len);
@ -608,6 +616,8 @@ _cogl_journal_flush (void)
g_array_set_size (ctx->journal, 0);
g_array_set_size (ctx->logged_vertices, 0);
COGL_TIMER_STOP (_cogl_uprof_context, flush_timer);
}
static void
@ -644,9 +654,16 @@ _cogl_journal_log_quad (float x_1,
int next_entry;
guint32 disable_layers;
CoglJournalEntry *entry;
COGL_STATIC_TIMER (log_timer,
"Mainloop", /* parent */
"Journal Log",
"The time spent logging in the Cogl journal",
0 /* no application private data */);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
COGL_TIMER_START (_cogl_uprof_context, log_timer);
if (ctx->logged_vertices->len == 0)
_cogl_journal_init ();
@ -723,13 +740,13 @@ _cogl_journal_log_quad (float x_1,
next_vert + POS_STRIDE +
COLOR_STRIDE + TEX_STRIDE * i);
t[0] = tex_coords[0]; t[1] = tex_coords[1];
t[0] = tex_coords[i * 4 + 0]; t[1] = tex_coords[i * 4 + 1];
t += stride;
t[0] = tex_coords[0]; t[1] = tex_coords[3];
t[0] = tex_coords[i * 4 + 0]; t[1] = tex_coords[i * 4 + 3];
t += stride;
t[0] = tex_coords[2]; t[1] = tex_coords[3];
t[0] = tex_coords[i * 4 + 2]; t[1] = tex_coords[i * 4 + 3];
t += stride;
t[0] = tex_coords[2]; t[1] = tex_coords[1];
t[0] = tex_coords[i * 4 + 2]; t[1] = tex_coords[i * 4 + 1];
}
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_JOURNAL))
@ -765,5 +782,7 @@ _cogl_journal_log_quad (float x_1,
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DISABLE_BATCHING
|| cogl_debug_flags & COGL_DEBUG_RECTANGLES))
_cogl_journal_flush ();
COGL_TIMER_STOP (_cogl_uprof_context, log_timer);
}

View File

@ -48,6 +48,12 @@
#include "../gles/cogl-gles2-wrapper.h"
#endif
#ifdef HAVE_COGL_GLES
#define COGL_MATERIAL_MAX_TEXTURE_UNITS GL_MAX_TEXTURE_UNITS
#else
#define COGL_MATERIAL_MAX_TEXTURE_UNITS GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
#endif
#ifdef HAVE_COGL_GL
#define glActiveTexture ctx->drv.pf_glActiveTexture
#define glClientActiveTexture ctx->drv.pf_glClientActiveTexture
@ -106,7 +112,7 @@ _cogl_material_init_default_material (void)
#ifndef HAVE_COGL_GLES
material->blend_equation_rgb = GL_FUNC_ADD;
material->blend_equation_alpha = GL_FUNC_ADD;
material->blend_src_factor_alpha = GL_SRC_ALPHA;
material->blend_src_factor_alpha = GL_ONE;
material->blend_dst_factor_alpha = GL_ONE_MINUS_SRC_ALPHA;
material->blend_constant[0] = 0;
material->blend_constant[1] = 0;
@ -822,7 +828,7 @@ cogl_material_set_layer (CoglHandle material_handle,
_cogl_material_pre_change_notify (material, FALSE, NULL);
material->n_layers = g_list_length (material->layers);
if (material->n_layers >= CGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS)
if (material->n_layers >= COGL_MATERIAL_MAX_TEXTURE_UNITS)
{
if (!(material->flags & COGL_MATERIAL_FLAG_SHOWN_SAMPLER_WARNING))
{
@ -1534,7 +1540,7 @@ _cogl_material_flush_layers_gl_state (CoglMaterial *material,
layer->flags &= ~COGL_MATERIAL_LAYER_FLAG_DIRTY;
if ((i+1) >= CGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS)
if ((i+1) >= COGL_MATERIAL_MAX_TEXTURE_UNITS)
break;
}

View File

@ -28,10 +28,15 @@
#define __COGL_MATRIX_STACK_H
#include "cogl-matrix.h"
#include "cogl.h" /* needed for GLenum */
typedef struct _CoglMatrixStack CoglMatrixStack;
typedef enum {
COGL_MATRIX_MODELVIEW,
COGL_MATRIX_PROJECTION,
COGL_MATRIX_TEXTURE
} CoglMatrixMode;
CoglMatrixStack* _cogl_matrix_stack_new (void);
void _cogl_matrix_stack_destroy (CoglMatrixStack *stack);
void _cogl_matrix_stack_push (CoglMatrixStack *stack);
@ -79,7 +84,7 @@ void _cogl_matrix_stack_get (CoglMatrixStack *stack,
void _cogl_matrix_stack_set (CoglMatrixStack *stack,
const CoglMatrix *matrix);
void _cogl_matrix_stack_flush_to_gl (CoglMatrixStack *stack,
GLenum gl_mode);
CoglMatrixMode mode);
void _cogl_matrix_stack_dirty (CoglMatrixStack *stack);
#endif /* __COGL_MATRIX_STACK_H */

View File

@ -61,7 +61,7 @@ typedef struct _TextureSlicedQuadState
typedef struct _TextureSlicedPolygonState
{
CoglTextureVertex *vertices;
const CoglTextureVertex *vertices;
int n_vertices;
int stride;
} TextureSlicedPolygonState;
@ -696,7 +696,7 @@ draw_polygon_sub_texture_cb (CoglHandle tex_handle,
/* handles 2d-sliced textures with > 1 slice */
static void
_cogl_texture_polygon_multiple_primitives (CoglTextureVertex *vertices,
_cogl_texture_polygon_multiple_primitives (const CoglTextureVertex *vertices,
unsigned int n_vertices,
unsigned int stride,
gboolean use_color)
@ -749,7 +749,7 @@ _cogl_texture_polygon_multiple_primitives (CoglTextureVertex *vertices,
}
static void
_cogl_multitexture_polygon_single_primitive (CoglTextureVertex *vertices,
_cogl_multitexture_polygon_single_primitive (const CoglTextureVertex *vertices,
guint n_vertices,
guint n_layers,
guint stride,
@ -828,14 +828,13 @@ _cogl_multitexture_polygon_single_primitive (CoglTextureVertex *vertices,
}
void
cogl_polygon (CoglTextureVertex *vertices,
guint n_vertices,
gboolean use_color)
cogl_polygon (const CoglTextureVertex *vertices,
guint n_vertices,
gboolean use_color)
{
CoglHandle material;
const GList *layers;
const GList *layers, *tmp;
int n_layers;
GList *tmp;
gboolean use_sliced_polygon_fallback = FALSE;
guint32 fallback_layers = 0;
int i;
@ -858,10 +857,10 @@ cogl_polygon (CoglTextureVertex *vertices,
layers = cogl_material_get_layers (ctx->source_material);
n_layers = g_list_length ((GList *)layers);
for (tmp = (GList *)layers, i = 0; tmp != NULL; tmp = tmp->next, i++)
for (tmp = layers, i = 0; tmp != NULL; tmp = tmp->next, i++)
{
CoglHandle layer = (CoglHandle)tmp->data;
CoglHandle tex_handle = cogl_material_layer_get_texture (layer);
CoglHandle layer = tmp->data;
CoglHandle tex_handle = cogl_material_layer_get_texture (layer);
/* COGL_INVALID_HANDLE textures will be handled in
* _cogl_material_flush_layers_gl_state */
@ -891,6 +890,7 @@ cogl_polygon (CoglTextureVertex *vertices,
warning_seen = TRUE;
}
}
use_sliced_polygon_fallback = TRUE;
n_layers = 1;
@ -902,7 +902,7 @@ cogl_polygon (CoglTextureVertex *vertices,
{
g_warning ("cogl_texture_polygon does not work for sliced textures "
"when the minification and magnification filters are not "
"CGL_NEAREST");
"COGL_MATERIAL_FILTER_NEAREST");
warning_seen = TRUE;
}
return;
@ -977,9 +977,10 @@ cogl_polygon (CoglTextureVertex *vertices,
/* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */
v + 3 + 2 * i));
}
prev_n_texcoord_arrays_enabled =
ctx->n_texcoord_arrays_enabled;
prev_n_texcoord_arrays_enabled = ctx->n_texcoord_arrays_enabled;
ctx->n_texcoord_arrays_enabled = n_layers;
for (; i < prev_n_texcoord_arrays_enabled; i++)
{
GE (glClientActiveTexture (GL_TEXTURE0 + i));

View File

@ -0,0 +1,30 @@
#ifdef COGL_ENABLE_PROFILE
#include "cogl-profile.h"
#include <stdlib.h>
UProfContext *_cogl_uprof_context;
static void __attribute__ ((constructor))
cogl_uprof_constructor (void)
{
_cogl_uprof_context = uprof_context_new ("Cogl");
}
static void __attribute__ ((destructor))
cogl_uprof_destructor (void)
{
if (getenv ("COGL_PROFILE_OUTPUT_REPORT"))
{
UProfReport *report = uprof_report_new ("Cogl report");
uprof_report_add_context (report, _cogl_uprof_context);
uprof_report_print (report);
uprof_report_unref (report);
}
uprof_context_unref (_cogl_uprof_context);
}
#endif

View File

@ -0,0 +1,54 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2007,2008,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, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __COGL_PROFILE_H__
#define __COGL_PROFILE_H__
#ifdef COGL_ENABLE_PROFILE
#include <uprof.h>
extern UProfContext *_cogl_uprof_context;
#define COGL_STATIC_TIMER UPROF_STATIC_TIMER
#define COGL_STATIC_COUNTER UPROF_STATIC_COUNTER
#define COGL_COUNTER_INC UPROF_COUNTER_INC
#define COGL_COUNTER_DEC UPROF_COUNTER_DEC
#define COGL_TIMER_START UPROF_TIMER_START
#define COGL_TIMER_STOP UPROF_TIMER_STOP
#else
#define COGL_STATIC_TIMER(A,B,C,D,E) extern void _cogl_dummy_decl (void)
#define COGL_STATIC_COUNTER(A,B,C,D) extern void _cogl_dummy_decl (void)
#define COGL_COUNTER_INC(A,B) G_STMT_START{ (void)0; }G_STMT_END
#define COGL_COUNTER_DEC(A,B) G_STMT_START{ (void)0; }G_STMT_END
#define COGL_TIMER_START(A,B) G_STMT_START{ (void)0; }G_STMT_END
#define COGL_TIMER_STOP(A,B) G_STMT_START{ (void)0; }G_STMT_END
#endif
#endif /* __COGL_PROFILE_H__ */

View File

@ -29,6 +29,7 @@
#define __COGL_SHADER_H__
#include <cogl/cogl-types.h>
#include <cogl/cogl-defines.h>
G_BEGIN_DECLS
@ -58,7 +59,7 @@ typedef enum {
/**
* cogl_create_shader:
* @shader_type: CGL_VERTEX_SHADER or CGL_FRAGMENT_SHADER.
* @shader_type: COGL_SHADER_TYPE_VERTEX or COGL_SHADER_TYPE_FRAGMENT.
*
* Create a new shader handle, use #cogl_shader_source to set the source code
* to be used on it.
@ -265,22 +266,22 @@ void cogl_program_uniform_1i (int uniform_no,
* @uniform_no: the uniform to set.
* @size: Size of float vector.
* @count: Size of array of uniforms.
* @value: the new value of the uniform.
* @value: (array length=count): the new value of the uniform.
*
* Changes the value of a float vector uniform, or uniform array in the
* currently used (see #cogl_program_use) shader program.
* currently used (see cogl_program_use()) shader program.
*/
void cogl_program_uniform_float (int uniform_no,
int size,
int count,
const GLfloat *value);
void cogl_program_uniform_float (int uniform_no,
int size,
int count,
const GLfloat *value);
/**
* cogl_program_uniform_int:
* @uniform_no: the uniform to set.
* @size: Size of int vector.
* @count: Size of array of uniforms.
* @value: the new value of the uniform.
* @value: (array length=count): the new value of the uniform.
*
* Changes the value of a int vector uniform, or uniform array in the
* currently used (see cogl_program_use()) shader program.
@ -296,7 +297,7 @@ void cogl_program_uniform_int (int uniform_no,
* @size: Size of matrix.
* @count: Size of array of uniforms.
* @transpose: Whether to transpose the matrix when setting the uniform.
* @value: the new value of the uniform.
* @value: (array length=count): the new value of the uniform.
*
* Changes the value of a matrix uniform, or uniform array in the
* currently used (see cogl_program_use()) shader program. The @size

View File

@ -504,8 +504,6 @@ cogl_texture_get_max_waste (CoglHandle handle)
tex = COGL_TEXTURE (handle);
return tex->vtable->get_max_waste (tex);
g_return_val_if_reached (0);
}
gboolean
@ -572,7 +570,7 @@ _cogl_texture_transform_coords_to_gl (CoglHandle handle,
{
CoglTexture *tex = COGL_TEXTURE (handle);
return tex->vtable->transform_coords_to_gl (tex, s, t);
tex->vtable->transform_coords_to_gl (tex, s, t);
}
GLenum
@ -610,7 +608,7 @@ _cogl_texture_set_filters (CoglHandle handle,
tex = COGL_TEXTURE (handle);
return tex->vtable->set_filters (tex, min_filter, mag_filter);
tex->vtable->set_filters (tex, min_filter, mag_filter);
}
void
@ -623,7 +621,7 @@ _cogl_texture_ensure_mipmaps (CoglHandle handle)
tex = COGL_TEXTURE (handle);
return tex->vtable->ensure_mipmaps (tex);
tex->vtable->ensure_mipmaps (tex);
}
gboolean

View File

@ -29,6 +29,7 @@
#define __COGL_TEXTURE_H__
#include <cogl/cogl-types.h>
#include <cogl/cogl-defines.h>
G_BEGIN_DECLS
@ -487,15 +488,16 @@ void cogl_rectangles (const float *verts,
* All of the texture coordinates must be in the range [0,1] and repeating the
* texture is not supported.
*
* Because of the way this function is implemented it will currently only work
* if either the texture is not sliced or the backend is not OpenGL ES and the
* minifying and magnifying functions are both set to CGL_NEAREST.
* Because of the way this function is implemented it will currently
* only work if either the texture is not sliced or the backend is not
* OpenGL ES and the minifying and magnifying functions are both set
* to COGL_MATERIAL_FILTER_NEAREST.
*
* Since: 1.0
*/
void cogl_polygon (CoglTextureVertex *vertices,
guint n_vertices,
gboolean use_color);
void cogl_polygon (const CoglTextureVertex *vertices,
guint n_vertices,
gboolean use_color);
G_END_DECLS

View File

@ -29,661 +29,6 @@
G_BEGIN_DECLS
/* FIXME + DOCUMENT */
#define COPENSTEP OPENSTEP
#define CGLAPI GLAPI
#define CGLAPI GLAPI
#define CGLAPI GLAPI
#define CGLAPIENTRY GLAPIENTRY
#define CGLAPI GLAPI
#define CGLAPIENTRY GLAPIENTRY
#define CGLAPI GLAPI
#define CGLAPIENTRY GLAPIENTRY
#define CPRAGMA_EXPORT_SUPPORTED PRAGMA_EXPORT_SUPPORTED
#define CGLAPI GLAPI
#define CGLAPIENTRY GLAPIENTRY
#define CAPIENTRY APIENTRY
#define CAPIENTRYP APIENTRYP
#define CGLAPIENTRYP GLAPIENTRYP
#define CGL_FALSE GL_FALSE
#define CGL_TRUE GL_TRUE
#define CGL_BYTE GL_BYTE
#define CGL_UNSIGNED_BYTE GL_UNSIGNED_BYTE
#define CGL_SHORT GL_SHORT
#define CGL_UNSIGNED_SHORT GL_UNSIGNED_SHORT
#define CGL_INT GL_INT
#define CGL_UNSIGNED_INT GL_UNSIGNED_INT
#define CGL_FLOAT GL_FLOAT
#define CGL_DOUBLE GL_DOUBLE
#define CGL_POINTS GL_POINTS
#define CGL_LINES GL_LINES
#define CGL_LINE_LOOP GL_LINE_LOOP
#define CGL_LINE_STRIP GL_LINE_STRIP
#define CGL_TRIANGLES GL_TRIANGLES
#define CGL_TRIANGLE_STRIP GL_TRIANGLE_STRIP
#define CGL_TRIANGLE_FAN GL_TRIANGLE_FAN
#define CGL_QUADS GL_QUADS
#define CGL_QUAD_STRIP GL_QUAD_STRIP
#define CGL_POLYGON GL_POLYGON
#define CGL_VERTEX_ARRAY GL_VERTEX_ARRAY
#define CGL_NORMAL_ARRAY GL_NORMAL_ARRAY
#define CGL_COLOR_ARRAY GL_COLOR_ARRAY
#define CGL_INDEX_ARRAY GL_INDEX_ARRAY
#define CGL_TEXTURE_COORD_ARRAY GL_TEXTURE_COORD_ARRAY
#define CGL_EDGE_FLAG_ARRAY GL_EDGE_FLAG_ARRAY
#define CGL_VERTEX_ARRAY_SIZE GL_VERTEX_ARRAY_SIZE
#define CGL_VERTEX_ARRAY_TYPE GL_VERTEX_ARRAY_TYPE
#define CGL_VERTEX_ARRAY_STRIDE GL_VERTEX_ARRAY_STRIDE
#define CGL_NORMAL_ARRAY_TYPE GL_NORMAL_ARRAY_TYPE
#define CGL_NORMAL_ARRAY_STRIDE GL_NORMAL_ARRAY_STRIDE
#define CGL_COLOR_ARRAY_SIZE GL_COLOR_ARRAY_SIZE
#define CGL_COLOR_ARRAY_TYPE GL_COLOR_ARRAY_TYPE
#define CGL_COLOR_ARRAY_STRIDE GL_COLOR_ARRAY_STRIDE
#define CGL_INDEX_ARRAY_TYPE GL_INDEX_ARRAY_TYPE
#define CGL_INDEX_ARRAY_STRIDE GL_INDEX_ARRAY_STRIDE
#define CGL_TEXTURE_COORD_ARRAY_SIZE GL_TEXTURE_COORD_ARRAY_SIZE
#define CGL_TEXTURE_COORD_ARRAY_TYPE GL_TEXTURE_COORD_ARRAY_TYPE
#define CGL_TEXTURE_COORD_ARRAY_STRIDE GL_TEXTURE_COORD_ARRAY_STRIDE
#define CGL_EDGE_FLAG_ARRAY_STRIDE GL_EDGE_FLAG_ARRAY_STRIDE
#define CGL_VERTEX_ARRAY_POINTER GL_VERTEX_ARRAY_POINTER
#define CGL_NORMAL_ARRAY_POINTER GL_NORMAL_ARRAY_POINTER
#define CGL_COLOR_ARRAY_POINTER GL_COLOR_ARRAY_POINTER
#define CGL_INDEX_ARRAY_POINTER GL_INDEX_ARRAY_POINTER
#define CGL_TEXTURE_COORD_ARRAY_POINTER GL_TEXTURE_COORD_ARRAY_POINTER
#define CGL_EDGE_FLAG_ARRAY_POINTER GL_EDGE_FLAG_ARRAY_POINTER
#define CGL_MATRIX_MODE GL_MATRIX_MODE
#define CGL_MODELVIEW GL_MODELVIEW
#define CGL_PROJECTION GL_PROJECTION
#define CGL_TEXTURE GL_TEXTURE
#define CGL_POINT_SMOOTH GL_POINT_SMOOTH
#define CGL_POINT_SIZE GL_POINT_SIZE
#define CGL_POINT_SIZE_GRANULARITY GL_POINT_SIZE_GRANULARITY
#define CGL_POINT_SIZE_RANGE GL_POINT_SIZE_RANGE
#define CGL_LINE_SMOOTH GL_LINE_SMOOTH
#define CGL_LINE_STIPPLE GL_LINE_STIPPLE
#define CGL_LINE_STIPPLE_PATTERN GL_LINE_STIPPLE_PATTERN
#define CGL_LINE_STIPPLE_REPEAT GL_LINE_STIPPLE_REPEAT
#define CGL_LINE_WIDTH GL_LINE_WIDTH
#define CGL_LINE_WIDTH_GRANULARITY GL_LINE_WIDTH_GRANULARITY
#define CGL_LINE_WIDTH_RANGE GL_LINE_WIDTH_RANGE
#define CGL_POINT GL_POINT
#define CGL_LINE GL_LINE
#define CGL_FILL GL_FILL
#define CGL_CW GL_CW
#define CGL_CCW GL_CCW
#define CGL_FRONT GL_FRONT
#define CGL_BACK GL_BACK
#define CGL_POLYGON_MODE GL_POLYGON_MODE
#define CGL_POLYGON_SMOOTH GL_POLYGON_SMOOTH
#define CGL_POLYGON_STIPPLE GL_POLYGON_STIPPLE
#define CGL_EDGE_FLAG GL_EDGE_FLAG
#define CGL_CULL_FACE GL_CULL_FACE
#define CGL_CULL_FACE_MODE GL_CULL_FACE_MODE
#define CGL_FRONT_FACE GL_FRONT_FACE
#define CGL_POLYGON_OFFSET_FACTOR GL_POLYGON_OFFSET_FACTOR
#define CGL_POLYGON_OFFSET_UNITS GL_POLYGON_OFFSET_UNITS
#define CGL_POLYGON_OFFSET_POINT GL_POLYGON_OFFSET_POINT
#define CGL_POLYGON_OFFSET_LINE GL_POLYGON_OFFSET_LINE
#define CGL_POLYGON_OFFSET_FILL GL_POLYGON_OFFSET_FILL
#define CGL_COMPILE GL_COMPILE
#define CGL_COMPILE_AND_EXECUTE GL_COMPILE_AND_EXECUTE
#define CGL_LIST_BASE GL_LIST_BASE
#define CGL_LIST_INDEX GL_LIST_INDEX
#define CGL_LIST_MODE GL_LIST_MODE
#define CGL_NEVER GL_NEVER
#define CGL_LESS GL_LESS
#define CGL_EQUAL GL_EQUAL
#define CGL_LEQUAL GL_LEQUAL
#define CGL_GREATER GL_GREATER
#define CGL_NOTEQUAL GL_NOTEQUAL
#define CGL_GEQUAL GL_GEQUAL
#define CGL_ALWAYS GL_ALWAYS
#define CGL_DEPTH_TEST GL_DEPTH_TEST
#define CGL_DEPTH_BITS GL_DEPTH_BITS
#define CGL_DEPTH_CLEAR_VALUE GL_DEPTH_CLEAR_VALUE
#define CGL_DEPTH_FUNC GL_DEPTH_FUNC
#define CGL_DEPTH_RANGE GL_DEPTH_RANGE
#define CGL_DEPTH_WRITEMASK GL_DEPTH_WRITEMASK
#define CGL_DEPTH_COMPONENT GL_DEPTH_COMPONENT
#define CGL_LIGHTING GL_LIGHTING
#define CGL_SPOT_EXPONENT GL_SPOT_EXPONENT
#define CGL_SPOT_CUTOFF GL_SPOT_CUTOFF
#define CGL_CONSTANT_ATTENUATION GL_CONSTANT_ATTENUATION
#define CGL_LINEAR_ATTENUATION GL_LINEAR_ATTENUATION
#define CGL_QUADRATIC_ATTENUATION GL_QUADRATIC_ATTENUATION
#define CGL_AMBIENT GL_AMBIENT
#define CGL_DIFFUSE GL_DIFFUSE
#define CGL_SPECULAR GL_SPECULAR
#define CGL_SHININESS GL_SHININESS
#define CGL_EMISSION GL_EMISSION
#define CGL_POSITION GL_POSITION
#define CGL_SPOT_DIRECTION GL_SPOT_DIRECTION
#define CGL_AMBIENT_AND_DIFFUSE GL_AMBIENT_AND_DIFFUSE
#define CGL_COLOR_INDEXES GL_COLOR_INDEXES
#define CGL_LIGHT_MODEL_TWO_SIDE GL_LIGHT_MODEL_TWO_SIDE
#define CGL_LIGHT_MODEL_LOCAL_VIEWER GL_LIGHT_MODEL_LOCAL_VIEWER
#define CGL_LIGHT_MODEL_AMBIENT GL_LIGHT_MODEL_AMBIENT
#define CGL_FRONT_AND_BACK GL_FRONT_AND_BACK
#define CGL_SHADE_MODEL GL_SHADE_MODEL
#define CGL_FLAT GL_FLAT
#define CGL_SMOOTH GL_SMOOTH
#define CGL_COLOR_MATERIAL GL_COLOR_MATERIAL
#define CGL_COLOR_MATERIAL_FACE GL_COLOR_MATERIAL_FACE
#define CGL_COLOR_MATERIAL_PARAMETER GL_COLOR_MATERIAL_PARAMETER
#define CGL_NORMALIZE GL_NORMALIZE
#define CGL_ACCUM_RED_BITS GL_ACCUM_RED_BITS
#define CGL_ACCUM_GREEN_BITS GL_ACCUM_GREEN_BITS
#define CGL_ACCUM_BLUE_BITS GL_ACCUM_BLUE_BITS
#define CGL_ACCUM_ALPHA_BITS GL_ACCUM_ALPHA_BITS
#define CGL_ACCUM_CLEAR_VALUE GL_ACCUM_CLEAR_VALUE
#define CGL_ACCUM GL_ACCUM
#define CGL_ADD GL_ADD
#define CGL_LOAD GL_LOAD
#define CGL_MULT GL_MULT
#define CGL_RETURN GL_RETURN
#define CGL_ALPHA_TEST GL_ALPHA_TEST
#define CGL_ALPHA_TEST_REF GL_ALPHA_TEST_REF
#define CGL_ALPHA_TEST_FUNC GL_ALPHA_TEST_FUNC
#define CGL_BLEND GL_BLEND
#define CGL_BLEND_SRC GL_BLEND_SRC
#define CGL_BLEND_DST GL_BLEND_DST
#define CGL_ZERO GL_ZERO
#define CGL_ONE GL_ONE
#define CGL_SRC_COLOR GL_SRC_COLOR
#define CGL_ONE_MINUS_SRC_COLOR GL_ONE_MINUS_SRC_COLOR
#define CGL_SRC_ALPHA GL_SRC_ALPHA
#define CGL_ONE_MINUS_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA
#define CGL_DST_ALPHA GL_DST_ALPHA
#define CGL_ONE_MINUS_DST_ALPHA GL_ONE_MINUS_DST_ALPHA
#define CGL_DST_COLOR GL_DST_COLOR
#define CGL_ONE_MINUS_DST_COLOR GL_ONE_MINUS_DST_COLOR
#define CGL_SRC_ALPHA_SATURATE GL_SRC_ALPHA_SATURATE
#define CGL_FEEDBACK GL_FEEDBACK
#define CGL_RENDER GL_RENDER
#define CGL_SELECT GL_SELECT
#define CGL_POINT_TOKEN GL_POINT_TOKEN
#define CGL_LINE_TOKEN GL_LINE_TOKEN
#define CGL_LINE_RESET_TOKEN GL_LINE_RESET_TOKEN
#define CGL_POLYGON_TOKEN GL_POLYGON_TOKEN
#define CGL_BITMAP_TOKEN GL_BITMAP_TOKEN
#define CGL_DRAW_PIXEL_TOKEN GL_DRAW_PIXEL_TOKEN
#define CGL_COPY_PIXEL_TOKEN GL_COPY_PIXEL_TOKEN
#define CGL_PASS_THROUGH_TOKEN GL_PASS_THROUGH_TOKEN
#define CGL_FEEDBACK_BUFFER_POINTER GL_FEEDBACK_BUFFER_POINTER
#define CGL_FEEDBACK_BUFFER_SIZE GL_FEEDBACK_BUFFER_SIZE
#define CGL_FEEDBACK_BUFFER_TYPE GL_FEEDBACK_BUFFER_TYPE
#define CGL_SELECTION_BUFFER_POINTER GL_SELECTION_BUFFER_POINTER
#define CGL_SELECTION_BUFFER_SIZE GL_SELECTION_BUFFER_SIZE
#define CGL_FOG GL_FOG
#define CGL_FOG_MODE GL_FOG_MODE
#define CGL_FOG_DENSITY GL_FOG_DENSITY
#define CGL_FOG_COLOR GL_FOG_COLOR
#define CGL_FOG_INDEX GL_FOG_INDEX
#define CGL_FOG_START GL_FOG_START
#define CGL_FOG_END GL_FOG_END
#define CGL_EXP GL_EXP
#define CGL_LOGIC_OP GL_LOGIC_OP
#define CGL_INDEX_LOGIC_OP GL_INDEX_LOGIC_OP
#define CGL_COLOR_LOGIC_OP GL_COLOR_LOGIC_OP
#define CGL_LOGIC_OP_MODE GL_LOGIC_OP_MODE
#define CGL_CLEAR GL_CLEAR
#define CGL_SET GL_SET
#define CGL_COPY GL_COPY
#define CGL_COPY_INVERTED GL_COPY_INVERTED
#define CGL_NOOP GL_NOOP
#define CGL_INVERT GL_INVERT
#define CGL_AND GL_AND
#define CGL_NAND GL_NAND
#define CGL_OR GL_OR
#define CGL_NOR GL_NOR
#define CGL_XOR GL_XOR
#define CGL_EQUIV GL_EQUIV
#define CGL_AND_REVERSE GL_AND_REVERSE
#define CGL_AND_INVERTED GL_AND_INVERTED
#define CGL_OR_REVERSE GL_OR_REVERSE
#define CGL_OR_INVERTED GL_OR_INVERTED
#define CGL_STENCIL_BITS GL_STENCIL_BITS
#define CGL_STENCIL_TEST GL_STENCIL_TEST
#define CGL_STENCIL_CLEAR_VALUE GL_STENCIL_CLEAR_VALUE
#define CGL_STENCIL_FUNC GL_STENCIL_FUNC
#define CGL_STENCIL_VALUE_MASK GL_STENCIL_VALUE_MASK
#define CGL_STENCIL_FAIL GL_STENCIL_FAIL
#define CGL_STENCIL_PASS_DEPTH_FAIL GL_STENCIL_PASS_DEPTH_FAIL
#define CGL_STENCIL_PASS_DEPTH_PASS GL_STENCIL_PASS_DEPTH_PASS
#define CGL_STENCIL_REF GL_STENCIL_REF
#define CGL_STENCIL_WRITEMASK GL_STENCIL_WRITEMASK
#define CGL_STENCIL_INDEX GL_STENCIL_INDEX
#define CGL_KEEP GL_KEEP
#define CGL_REPLACE GL_REPLACE
#define CGL_INCR GL_INCR
#define CGL_DECR GL_DECR
#define CGL_NONE GL_NONE
#define CGL_LEFT GL_LEFT
#define CGL_RIGHT GL_RIGHT
#define CGL_FRONT_LEFT GL_FRONT_LEFT
#define CGL_FRONT_RIGHT GL_FRONT_RIGHT
#define CGL_BACK_LEFT GL_BACK_LEFT
#define CGL_BACK_RIGHT GL_BACK_RIGHT
#define CGL_COLOR_INDEX GL_COLOR_INDEX
#define CGL_RED GL_RED
#define CGL_GREEN GL_GREEN
#define CGL_BLUE GL_BLUE
#define CGL_ALPHA GL_ALPHA
#define CGL_LUMINANCE GL_LUMINANCE
#define CGL_LUMINANCE_ALPHA GL_LUMINANCE_ALPHA
#define CGL_ALPHA_BITS GL_ALPHA_BITS
#define CGL_RED_BITS GL_RED_BITS
#define CGL_GREEN_BITS GL_GREEN_BITS
#define CGL_BLUE_BITS GL_BLUE_BITS
#define CGL_INDEX_BITS GL_INDEX_BITS
#define CGL_SUBPIXEL_BITS GL_SUBPIXEL_BITS
#define CGL_AUX_BUFFERS GL_AUX_BUFFERS
#define CGL_READ_BUFFER GL_READ_BUFFER
#define CGL_DRAW_BUFFER GL_DRAW_BUFFER
#define CGL_DOUBLEBUFFER GL_DOUBLEBUFFER
#define CGL_STEREO GL_STEREO
#define CGL_BITMAP GL_BITMAP
#define CGL_COLOR GL_COLOR
#define CGL_DEPTH GL_DEPTH
#define CGL_STENCIL GL_STENCIL
#define CGL_DITHER GL_DITHER
#define CGL_RGB GL_RGB
#define CGL_RGBA GL_RGBA
#define CGL_MAX_LIST_NESTING GL_MAX_LIST_NESTING
#define CGL_MAX_EVAL_ORDER GL_MAX_EVAL_ORDER
#define CGL_MAX_LIGHTS GL_MAX_LIGHTS
#define CGL_MAX_CLIP_PLANES GL_MAX_CLIP_PLANES
#define CGL_MAX_TEXTURE_SIZE GL_MAX_TEXTURE_SIZE
#define CGL_MAX_PIXEL_MAP_TABLE GL_MAX_PIXEL_MAP_TABLE
#define CGL_MAX_ATTRIB_STACK_DEPTH GL_MAX_ATTRIB_STACK_DEPTH
#define CGL_MAX_MODELVIEW_STACK_DEPTH GL_MAX_MODELVIEW_STACK_DEPTH
#define CGL_MAX_NAME_STACK_DEPTH GL_MAX_NAME_STACK_DEPTH
#define CGL_MAX_PROJECTION_STACK_DEPTH GL_MAX_PROJECTION_STACK_DEPTH
#define CGL_MAX_TEXTURE_STACK_DEPTH GL_MAX_TEXTURE_STACK_DEPTH
#define CGL_MAX_VIEWPORT_DIMS GL_MAX_VIEWPORT_DIMS
#define CGL_MAX_CLIENT_ATTRIB_STACK_DEPTH GL_MAX_CLIENT_ATTRIB_STACK_DEPTH
#define CGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS GL_MAX_TEXTURE_UNITS
#define CGL_ATTRIB_STACK_DEPTH GL_ATTRIB_STACK_DEPTH
#define CGL_CLIENT_ATTRIB_STACK_DEPTH GL_CLIENT_ATTRIB_STACK_DEPTH
#define CGL_COLOR_CLEAR_VALUE GL_COLOR_CLEAR_VALUE
#define CGL_COLOR_WRITEMASK GL_COLOR_WRITEMASK
#define CGL_CURRENT_INDEX GL_CURRENT_INDEX
#define CGL_CURRENT_COLOR GL_CURRENT_COLOR
#define CGL_CURRENT_NORMAL GL_CURRENT_NORMAL
#define CGL_CURRENT_RASTER_COLOR GL_CURRENT_RASTER_COLOR
#define CGL_CURRENT_RASTER_DISTANCE GL_CURRENT_RASTER_DISTANCE
#define CGL_CURRENT_RASTER_INDEX GL_CURRENT_RASTER_INDEX
#define CGL_CURRENT_RASTER_POSITION GL_CURRENT_RASTER_POSITION
#define CGL_CURRENT_RASTER_TEXTURE_COORDS GL_CURRENT_RASTER_TEXTURE_COORDS
#define CGL_CURRENT_RASTER_POSITION_VALID GL_CURRENT_RASTER_POSITION_VALID
#define CGL_CURRENT_TEXTURE_COORDS GL_CURRENT_TEXTURE_COORDS
#define CGL_INDEX_CLEAR_VALUE GL_INDEX_CLEAR_VALUE
#define CGL_INDEX_MODE GL_INDEX_MODE
#define CGL_INDEX_WRITEMASK GL_INDEX_WRITEMASK
#define CGL_MODELVIEW_MATRIX GL_MODELVIEW_MATRIX
#define CGL_MODELVIEW_STACK_DEPTH GL_MODELVIEW_STACK_DEPTH
#define CGL_NAME_STACK_DEPTH GL_NAME_STACK_DEPTH
#define CGL_PROJECTION_MATRIX GL_PROJECTION_MATRIX
#define CGL_PROJECTION_STACK_DEPTH GL_PROJECTION_STACK_DEPTH
#define CGL_RENDER_MODE GL_RENDER_MODE
#define CGL_RGBA_MODE GL_RGBA_MODE
#define CGL_TEXTURE_MATRIX GL_TEXTURE_MATRIX
#define CGL_TEXTURE_STACK_DEPTH GL_TEXTURE_STACK_DEPTH
#define CGL_VIEWPORT GL_VIEWPORT
#define CGL_AUTO_NORMAL GL_AUTO_NORMAL
#define CGL_COEFF GL_COEFF
#define CGL_ORDER GL_ORDER
#define CGL_DOMAIN GL_DOMAIN
#define CGL_PERSPECTIVE_CORRECTION_HINT GL_PERSPECTIVE_CORRECTION_HINT
#define CGL_POINT_SMOOTH_HINT GL_POINT_SMOOTH_HINT
#define CGL_LINE_SMOOTH_HINT GL_LINE_SMOOTH_HINT
#define CGL_POLYGON_SMOOTH_HINT GL_POLYGON_SMOOTH_HINT
#define CGL_FOG_HINT GL_FOG_HINT
#define CGL_DONT_CARE GL_DONT_CARE
#define CGL_FASTEST GL_FASTEST
#define CGL_NICEST GL_NICEST
#define CGL_SCISSOR_BOX GL_SCISSOR_BOX
#define CGL_SCISSOR_TEST GL_SCISSOR_TEST
#define CGL_MAP_COLOR GL_MAP_COLOR
#define CGL_MAP_STENCIL GL_MAP_STENCIL
#define CGL_INDEX_SHIFT GL_INDEX_SHIFT
#define CGL_INDEX_OFFSET GL_INDEX_OFFSET
#define CGL_RED_SCALE GL_RED_SCALE
#define CGL_RED_BIAS GL_RED_BIAS
#define CGL_GREEN_SCALE GL_GREEN_SCALE
#define CGL_GREEN_BIAS GL_GREEN_BIAS
#define CGL_BLUE_SCALE GL_BLUE_SCALE
#define CGL_BLUE_BIAS GL_BLUE_BIAS
#define CGL_ALPHA_SCALE GL_ALPHA_SCALE
#define CGL_ALPHA_BIAS GL_ALPHA_BIAS
#define CGL_DEPTH_SCALE GL_DEPTH_SCALE
#define CGL_DEPTH_BIAS GL_DEPTH_BIAS
#define CGL_PIXEL_MAP_S_TO_S_SIZE GL_PIXEL_MAP_S_TO_S_SIZE
#define CGL_PIXEL_MAP_I_TO_I_SIZE GL_PIXEL_MAP_I_TO_I_SIZE
#define CGL_PIXEL_MAP_I_TO_R_SIZE GL_PIXEL_MAP_I_TO_R_SIZE
#define CGL_PIXEL_MAP_I_TO_G_SIZE GL_PIXEL_MAP_I_TO_G_SIZE
#define CGL_PIXEL_MAP_I_TO_B_SIZE GL_PIXEL_MAP_I_TO_B_SIZE
#define CGL_PIXEL_MAP_I_TO_A_SIZE GL_PIXEL_MAP_I_TO_A_SIZE
#define CGL_PIXEL_MAP_R_TO_R_SIZE GL_PIXEL_MAP_R_TO_R_SIZE
#define CGL_PIXEL_MAP_G_TO_G_SIZE GL_PIXEL_MAP_G_TO_G_SIZE
#define CGL_PIXEL_MAP_B_TO_B_SIZE GL_PIXEL_MAP_B_TO_B_SIZE
#define CGL_PIXEL_MAP_A_TO_A_SIZE GL_PIXEL_MAP_A_TO_A_SIZE
#define CGL_PIXEL_MAP_S_TO_S GL_PIXEL_MAP_S_TO_S
#define CGL_PIXEL_MAP_I_TO_I GL_PIXEL_MAP_I_TO_I
#define CGL_PIXEL_MAP_I_TO_R GL_PIXEL_MAP_I_TO_R
#define CGL_PIXEL_MAP_I_TO_G GL_PIXEL_MAP_I_TO_G
#define CGL_PIXEL_MAP_I_TO_B GL_PIXEL_MAP_I_TO_B
#define CGL_PIXEL_MAP_I_TO_A GL_PIXEL_MAP_I_TO_A
#define CGL_PIXEL_MAP_R_TO_R GL_PIXEL_MAP_R_TO_R
#define CGL_PIXEL_MAP_G_TO_G GL_PIXEL_MAP_G_TO_G
#define CGL_PIXEL_MAP_B_TO_B GL_PIXEL_MAP_B_TO_B
#define CGL_PIXEL_MAP_A_TO_A GL_PIXEL_MAP_A_TO_A
#define CGL_PACK_ALIGNMENT GL_PACK_ALIGNMENT
#define CGL_PACK_LSB_FIRST GL_PACK_LSB_FIRST
#define CGL_PACK_ROW_LENGTH GL_PACK_ROW_LENGTH
#define CGL_PACK_SKIP_PIXELS GL_PACK_SKIP_PIXELS
#define CGL_PACK_SKIP_ROWS GL_PACK_SKIP_ROWS
#define CGL_PACK_SWAP_BYTES GL_PACK_SWAP_BYTES
#define CGL_UNPACK_ALIGNMENT GL_UNPACK_ALIGNMENT
#define CGL_UNPACK_LSB_FIRST GL_UNPACK_LSB_FIRST
#define CGL_UNPACK_ROW_LENGTH GL_UNPACK_ROW_LENGTH
#define CGL_UNPACK_SKIP_PIXELS GL_UNPACK_SKIP_PIXELS
#define CGL_UNPACK_SKIP_ROWS GL_UNPACK_SKIP_ROWS
#define CGL_UNPACK_SWAP_BYTES GL_UNPACK_SWAP_BYTES
#define CGL_ZOOM_X GL_ZOOM_X
#define CGL_ZOOM_Y GL_ZOOM_Y
#define CGL_TEXTURE_ENV GL_TEXTURE_ENV
#define CGL_TEXTURE_ENV_MODE GL_TEXTURE_ENV_MODE
#define CGL_TEXTURE_WRAP_S GL_TEXTURE_WRAP_S
#define CGL_TEXTURE_WRAP_T GL_TEXTURE_WRAP_T
#define CGL_TEXTURE_MAG_FILTER GL_TEXTURE_MAG_FILTER
#define CGL_TEXTURE_MIN_FILTER GL_TEXTURE_MIN_FILTER
#define CGL_TEXTURE_ENV_COLOR GL_TEXTURE_ENV_COLOR
#define CGL_TEXTURE_GEN_S GL_TEXTURE_GEN_S
#define CGL_TEXTURE_GEN_T GL_TEXTURE_GEN_T
#define CGL_TEXTURE_GEN_MODE GL_TEXTURE_GEN_MODE
#define CGL_TEXTURE_BORDER_COLOR GL_TEXTURE_BORDER_COLOR
#define CGL_TEXTURE_WIDTH GL_TEXTURE_WIDTH
#define CGL_TEXTURE_HEIGHT GL_TEXTURE_HEIGHT
#define CGL_TEXTURE_BORDER GL_TEXTURE_BORDER
#define CGL_TEXTURE_COMPONENTS GL_TEXTURE_COMPONENTS
#define CGL_TEXTURE_RED_SIZE GL_TEXTURE_RED_SIZE
#define CGL_TEXTURE_GREEN_SIZE GL_TEXTURE_GREEN_SIZE
#define CGL_TEXTURE_BLUE_SIZE GL_TEXTURE_BLUE_SIZE
#define CGL_TEXTURE_ALPHA_SIZE GL_TEXTURE_ALPHA_SIZE
#define CGL_TEXTURE_LUMINANCE_SIZE GL_TEXTURE_LUMINANCE_SIZE
#define CGL_TEXTURE_INTENSITY_SIZE GL_TEXTURE_INTENSITY_SIZE
#define CGL_OBJECT_LINEAR GL_OBJECT_LINEAR
#define CGL_OBJECT_PLANE GL_OBJECT_PLANE
#define CGL_EYE_LINEAR GL_EYE_LINEAR
#define CGL_EYE_PLANE GL_EYE_PLANE
#define CGL_SPHERE_MAP GL_SPHERE_MAP
#define CGL_DECAL GL_DECAL
#define CGL_MODULATE GL_MODULATE
#define CGL_REPEAT GL_REPEAT
#define CGL_CLAMP GL_CLAMP
#define CGL_S GL_S
#define CGL_T GL_T
#define CGL_R GL_R
#define CGL_Q GL_Q
#define CGL_TEXTURE_GEN_R GL_TEXTURE_GEN_R
#define CGL_TEXTURE_GEN_Q GL_TEXTURE_GEN_Q
#define CGL_VENDOR GL_VENDOR
#define CGL_RENDERER GL_RENDERER
#define CGL_VERSION GL_VERSION
#define CGL_EXTENSIONS GL_EXTENSIONS
#define CGL_NO_ERROR GL_NO_ERROR
#define CGL_INVALID_ENUM GL_INVALID_ENUM
#define CGL_INVALID_VALUE GL_INVALID_VALUE
#define CGL_INVALID_OPERATION GL_INVALID_OPERATION
#define CGL_STACK_OVERFLOW GL_STACK_OVERFLOW
#define CGL_STACK_UNDERFLOW GL_STACK_UNDERFLOW
#define CGL_OUT_OF_MEMORY GL_OUT_OF_MEMORY
#define CGL_CURRENT_BIT GL_CURRENT_BIT
#define CGL_POINT_BIT GL_POINT_BIT
#define CGL_LINE_BIT GL_LINE_BIT
#define CGL_POLYGON_BIT GL_POLYGON_BIT
#define CGL_POLYGON_STIPPLE_BIT GL_POLYGON_STIPPLE_BIT
#define CGL_PIXEL_MODE_BIT GL_PIXEL_MODE_BIT
#define CGL_LIGHTING_BIT GL_LIGHTING_BIT
#define CGL_FOG_BIT GL_FOG_BIT
#define CGL_DEPTH_BUFFER_BIT GL_DEPTH_BUFFER_BIT
#define CGL_ACCUM_BUFFER_BIT GL_ACCUM_BUFFER_BIT
#define CGL_STENCIL_BUFFER_BIT GL_STENCIL_BUFFER_BIT
#define CGL_VIEWPORT_BIT GL_VIEWPORT_BIT
#define CGL_TRANSFORM_BIT GL_TRANSFORM_BIT
#define CGL_ENABLE_BIT GL_ENABLE_BIT
#define CGL_COLOR_BUFFER_BIT GL_COLOR_BUFFER_BIT
#define CGL_HINT_BIT GL_HINT_BIT
#define CGL_EVAL_BIT GL_EVAL_BIT
#define CGL_LIST_BIT GL_LIST_BIT
#define CGL_TEXTURE_BIT GL_TEXTURE_BIT
#define CGL_SCISSOR_BIT GL_SCISSOR_BIT
#define CGL_ALL_ATTRIB_BITS GL_ALL_ATTRIB_BITS
#define CGL_TEXTURE_PRIORITY GL_TEXTURE_PRIORITY
#define CGL_TEXTURE_RESIDENT GL_TEXTURE_RESIDENT
#define CGL_TEXTURE_INTERNAL_FORMAT GL_TEXTURE_INTERNAL_FORMAT
#define CGL_INTENSITY GL_INTENSITY
#define CGL_CLIENT_PIXEL_STORE_BIT GL_CLIENT_PIXEL_STORE_BIT
#define CGL_CLIENT_VERTEX_ARRAY_BIT GL_CLIENT_VERTEX_ARRAY_BIT
#define CGL_ALL_CLIENT_ATTRIB_BITS GL_ALL_CLIENT_ATTRIB_BITS
#define CGL_CLIENT_ALL_ATTRIB_BITS GL_CLIENT_ALL_ATTRIB_BITS
#define CGL_RESCALE_NORMAL GL_RESCALE_NORMAL
#define CGL_CLAMP_TO_EDGE GL_CLAMP_TO_EDGE
#define CGL_MAX_ELEMENTS_VERTICES GL_MAX_ELEMENTS_VERTICES
#define CGL_MAX_ELEMENTS_INDICES GL_MAX_ELEMENTS_INDICES
#define CGL_BGR GL_BGR
#define CGL_BGRA GL_BGRA
#define CGL_LIGHT_MODEL_COLOR_CONTROL GL_LIGHT_MODEL_COLOR_CONTROL
#define CGL_SINGLE_COLOR GL_SINGLE_COLOR
#define CGL_SEPARATE_SPECULAR_COLOR GL_SEPARATE_SPECULAR_COLOR
#define CGL_TEXTURE_MIN_LOD GL_TEXTURE_MIN_LOD
#define CGL_TEXTURE_MAX_LOD GL_TEXTURE_MAX_LOD
#define CGL_TEXTURE_BASE_LEVEL GL_TEXTURE_BASE_LEVEL
#define CGL_TEXTURE_MAX_LEVEL GL_TEXTURE_MAX_LEVEL
#define CGL_SMOOTH_POINT_SIZE_RANGE GL_SMOOTH_POINT_SIZE_RANGE
#define CGL_SMOOTH_POINT_SIZE_GRANULARITY GL_SMOOTH_POINT_SIZE_GRANULARITY
#define CGL_SMOOTH_LINE_WIDTH_RANGE GL_SMOOTH_LINE_WIDTH_RANGE
#define CGL_SMOOTH_LINE_WIDTH_GRANULARITY GL_SMOOTH_LINE_WIDTH_GRANULARITY
#define CGL_ALIASED_POINT_SIZE_RANGE GL_ALIASED_POINT_SIZE_RANGE
#define CGL_ALIASED_LINE_WIDTH_RANGE GL_ALIASED_LINE_WIDTH_RANGE
#define CGL_PACK_SKIP_IMAGES GL_PACK_SKIP_IMAGES
#define CGL_PACK_IMAGE_HEIGHT GL_PACK_IMAGE_HEIGHT
#define CGL_UNPACK_SKIP_IMAGES GL_UNPACK_SKIP_IMAGES
#define CGL_UNPACK_IMAGE_HEIGHT GL_UNPACK_IMAGE_HEIGHT
#define CGL_TEXTURE_DEPTH GL_TEXTURE_DEPTH
#define CGL_TEXTURE_WRAP_R GL_TEXTURE_WRAP_R
#define CGL_CONSTANT_COLOR GL_CONSTANT_COLOR
#define CGL_ONE_MINUS_CONSTANT_COLOR GL_ONE_MINUS_CONSTANT_COLOR
#define CGL_CONSTANT_ALPHA GL_CONSTANT_ALPHA
#define CGL_ONE_MINUS_CONSTANT_ALPHA GL_ONE_MINUS_CONSTANT_ALPHA
#define CGL_COLOR_TABLE GL_COLOR_TABLE
#define CGL_POST_CONVOLUTION_COLOR_TABLE GL_POST_CONVOLUTION_COLOR_TABLE
#define CGL_POST_COLOR_MATRIX_COLOR_TABLE GL_POST_COLOR_MATRIX_COLOR_TABLE
#define CGL_PROXY_COLOR_TABLE GL_PROXY_COLOR_TABLE
#define CGL_PROXY_POST_CONVOLUTION_COLOR_TABLE GL_PROXY_POST_CONVOLUTION_COLOR_TABLE
#define CGL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE
#define CGL_COLOR_TABLE_SCALE GL_COLOR_TABLE_SCALE
#define CGL_COLOR_TABLE_BIAS GL_COLOR_TABLE_BIAS
#define CGL_COLOR_TABLE_FORMAT GL_COLOR_TABLE_FORMAT
#define CGL_COLOR_TABLE_WIDTH GL_COLOR_TABLE_WIDTH
#define CGL_COLOR_TABLE_RED_SIZE GL_COLOR_TABLE_RED_SIZE
#define CGL_COLOR_TABLE_GREEN_SIZE GL_COLOR_TABLE_GREEN_SIZE
#define CGL_COLOR_TABLE_BLUE_SIZE GL_COLOR_TABLE_BLUE_SIZE
#define CGL_COLOR_TABLE_ALPHA_SIZE GL_COLOR_TABLE_ALPHA_SIZE
#define CGL_COLOR_TABLE_LUMINANCE_SIZE GL_COLOR_TABLE_LUMINANCE_SIZE
#define CGL_COLOR_TABLE_INTENSITY_SIZE GL_COLOR_TABLE_INTENSITY_SIZE
#define CGL_CONVOLUTION_BORDER_MODE GL_CONVOLUTION_BORDER_MODE
#define CGL_CONVOLUTION_FILTER_SCALE GL_CONVOLUTION_FILTER_SCALE
#define CGL_CONVOLUTION_FILTER_BIAS GL_CONVOLUTION_FILTER_BIAS
#define CGL_REDUCE GL_REDUCE
#define CGL_CONVOLUTION_FORMAT GL_CONVOLUTION_FORMAT
#define CGL_CONVOLUTION_WIDTH GL_CONVOLUTION_WIDTH
#define CGL_CONVOLUTION_HEIGHT GL_CONVOLUTION_HEIGHT
#define CGL_MAX_CONVOLUTION_WIDTH GL_MAX_CONVOLUTION_WIDTH
#define CGL_MAX_CONVOLUTION_HEIGHT GL_MAX_CONVOLUTION_HEIGHT
#define CGL_POST_CONVOLUTION_RED_SCALE GL_POST_CONVOLUTION_RED_SCALE
#define CGL_POST_CONVOLUTION_GREEN_SCALE GL_POST_CONVOLUTION_GREEN_SCALE
#define CGL_POST_CONVOLUTION_BLUE_SCALE GL_POST_CONVOLUTION_BLUE_SCALE
#define CGL_POST_CONVOLUTION_ALPHA_SCALE GL_POST_CONVOLUTION_ALPHA_SCALE
#define CGL_POST_CONVOLUTION_RED_BIAS GL_POST_CONVOLUTION_RED_BIAS
#define CGL_POST_CONVOLUTION_GREEN_BIAS GL_POST_CONVOLUTION_GREEN_BIAS
#define CGL_POST_CONVOLUTION_BLUE_BIAS GL_POST_CONVOLUTION_BLUE_BIAS
#define CGL_POST_CONVOLUTION_ALPHA_BIAS GL_POST_CONVOLUTION_ALPHA_BIAS
#define CGL_CONSTANT_BORDER GL_CONSTANT_BORDER
#define CGL_REPLICATE_BORDER GL_REPLICATE_BORDER
#define CGL_CONVOLUTION_BORDER_COLOR GL_CONVOLUTION_BORDER_COLOR
#define CGL_COLOR_MATRIX GL_COLOR_MATRIX
#define CGL_COLOR_MATRIX_STACK_DEPTH GL_COLOR_MATRIX_STACK_DEPTH
#define CGL_MAX_COLOR_MATRIX_STACK_DEPTH GL_MAX_COLOR_MATRIX_STACK_DEPTH
#define CGL_POST_COLOR_MATRIX_RED_SCALE GL_POST_COLOR_MATRIX_RED_SCALE
#define CGL_POST_COLOR_MATRIX_GREEN_SCALE GL_POST_COLOR_MATRIX_GREEN_SCALE
#define CGL_POST_COLOR_MATRIX_BLUE_SCALE GL_POST_COLOR_MATRIX_BLUE_SCALE
#define CGL_POST_COLOR_MATRIX_ALPHA_SCALE GL_POST_COLOR_MATRIX_ALPHA_SCALE
#define CGL_POST_COLOR_MATRIX_RED_BIAS GL_POST_COLOR_MATRIX_RED_BIAS
#define CGL_POST_COLOR_MATRIX_GREEN_BIAS GL_POST_COLOR_MATRIX_GREEN_BIAS
#define CGL_POST_COLOR_MATRIX_BLUE_BIAS GL_POST_COLOR_MATRIX_BLUE_BIAS
#define CGL_POST_COLOR_MATRIX_ALPHA_BIAS GL_POST_COLOR_MATRIX_ALPHA_BIAS
#define CGL_HISTOGRAM GL_HISTOGRAM
#define CGL_PROXY_HISTOGRAM GL_PROXY_HISTOGRAM
#define CGL_HISTOGRAM_WIDTH GL_HISTOGRAM_WIDTH
#define CGL_HISTOGRAM_FORMAT GL_HISTOGRAM_FORMAT
#define CGL_HISTOGRAM_RED_SIZE GL_HISTOGRAM_RED_SIZE
#define CGL_HISTOGRAM_GREEN_SIZE GL_HISTOGRAM_GREEN_SIZE
#define CGL_HISTOGRAM_BLUE_SIZE GL_HISTOGRAM_BLUE_SIZE
#define CGL_HISTOGRAM_ALPHA_SIZE GL_HISTOGRAM_ALPHA_SIZE
#define CGL_HISTOGRAM_LUMINANCE_SIZE GL_HISTOGRAM_LUMINANCE_SIZE
#define CGL_HISTOGRAM_SINK GL_HISTOGRAM_SINK
#define CGL_MINMAX GL_MINMAX
#define CGL_MINMAX_FORMAT GL_MINMAX_FORMAT
#define CGL_MINMAX_SINK GL_MINMAX_SINK
#define CGL_TABLE_TOO_LARGE GL_TABLE_TOO_LARGE
#define CGL_BLEND_EQUATION GL_BLEND_EQUATION
#define CGL_MIN GL_MIN
#define CGL_MAX GL_MAX
#define CGL_FUNC_ADD GL_FUNC_ADD
#define CGL_FUNC_SUBTRACT GL_FUNC_SUBTRACT
#define CGL_FUNC_REVERSE_SUBTRACT GL_FUNC_REVERSE_SUBTRACT
#define CGL_BLEND_COLOR GL_BLEND_COLOR
#define CGL_ACTIVE_TEXTURE GL_ACTIVE_TEXTURE
#define CGL_CLIENT_ACTIVE_TEXTURE GL_CLIENT_ACTIVE_TEXTURE
#define CGL_MAX_TEXTURE_UNITS GL_MAX_TEXTURE_UNITS
#define CGL_NORMAL_MAP GL_NORMAL_MAP
#define CGL_REFLECTION_MAP GL_REFLECTION_MAP
#define CGL_TEXTURE_CUBE_MAP GL_TEXTURE_CUBE_MAP
#define CGL_TEXTURE_BINDING_CUBE_MAP GL_TEXTURE_BINDING_CUBE_MAP
#define CGL_TEXTURE_CUBE_MAP_POSITIVE_X GL_TEXTURE_CUBE_MAP_POSITIVE_X
#define CGL_TEXTURE_CUBE_MAP_NEGATIVE_X GL_TEXTURE_CUBE_MAP_NEGATIVE_X
#define CGL_TEXTURE_CUBE_MAP_POSITIVE_Y GL_TEXTURE_CUBE_MAP_POSITIVE_Y
#define CGL_TEXTURE_CUBE_MAP_NEGATIVE_Y GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
#define CGL_TEXTURE_CUBE_MAP_POSITIVE_Z GL_TEXTURE_CUBE_MAP_POSITIVE_Z
#define CGL_TEXTURE_CUBE_MAP_NEGATIVE_Z GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
#define CGL_PROXY_TEXTURE_CUBE_MAP GL_PROXY_TEXTURE_CUBE_MAP
#define CGL_MAX_CUBE_MAP_TEXTURE_SIZE GL_MAX_CUBE_MAP_TEXTURE_SIZE
#define CGL_COMPRESSED_ALPHA GL_COMPRESSED_ALPHA
#define CGL_COMPRESSED_LUMINANCE GL_COMPRESSED_LUMINANCE
#define CGL_COMPRESSED_LUMINANCE_ALPHA GL_COMPRESSED_LUMINANCE_ALPHA
#define CGL_COMPRESSED_INTENSITY GL_COMPRESSED_INTENSITY
#define CGL_COMPRESSED_RGB GL_COMPRESSED_RGB
#define CGL_COMPRESSED_RGBA GL_COMPRESSED_RGBA
#define CGL_TEXTURE_COMPRESSION_HINT GL_TEXTURE_COMPRESSION_HINT
#define CGL_TEXTURE_COMPRESSED_IMAGE_SIZE GL_TEXTURE_COMPRESSED_IMAGE_SIZE
#define CGL_TEXTURE_COMPRESSED GL_TEXTURE_COMPRESSED
#define CGL_NUM_COMPRESSED_TEXTURE_FORMATS GL_NUM_COMPRESSED_TEXTURE_FORMATS
#define CGL_COMPRESSED_TEXTURE_FORMATS GL_COMPRESSED_TEXTURE_FORMATS
#define CGL_MULTISAMPLE GL_MULTISAMPLE
#define CGL_SAMPLE_ALPHA_TO_COVERAGE GL_SAMPLE_ALPHA_TO_COVERAGE
#define CGL_SAMPLE_ALPHA_TO_ONE GL_SAMPLE_ALPHA_TO_ONE
#define CGL_SAMPLE_COVERAGE GL_SAMPLE_COVERAGE
#define CGL_SAMPLE_BUFFERS GL_SAMPLE_BUFFERS
#define CGL_SAMPLES GL_SAMPLES
#define CGL_SAMPLE_COVERAGE_VALUE GL_SAMPLE_COVERAGE_VALUE
#define CGL_SAMPLE_COVERAGE_INVERT GL_SAMPLE_COVERAGE_INVERT
#define CGL_MULTISAMPLE_BIT GL_MULTISAMPLE_BIT
#define CGL_TRANSPOSE_MODELVIEW_MATRIX GL_TRANSPOSE_MODELVIEW_MATRIX
#define CGL_TRANSPOSE_PROJECTION_MATRIX GL_TRANSPOSE_PROJECTION_MATRIX
#define CGL_TRANSPOSE_TEXTURE_MATRIX GL_TRANSPOSE_TEXTURE_MATRIX
#define CGL_TRANSPOSE_COLOR_MATRIX GL_TRANSPOSE_COLOR_MATRIX
#define CGL_COMBINE GL_COMBINE
#define CGL_COMBINE_RGB GL_COMBINE_RGB
#define CGL_COMBINE_ALPHA GL_COMBINE_ALPHA
#define CGL_RGB_SCALE GL_RGB_SCALE
#define CGL_ADD_SIGNED GL_ADD_SIGNED
#define CGL_INTERPOLATE GL_INTERPOLATE
#define CGL_SUBTRACT GL_SUBTRACT
#define CGL_CONSTANT GL_CONSTANT
#define CGL_PRIMARY_COLOR GL_PRIMARY_COLOR
#define CGL_PREVIOUS GL_PREVIOUS
#define CGL_CLAMP_TO_BORDER GL_CLAMP_TO_BORDER
#define CGL_ACTIVE_TEXTURE_ARB GL_ACTIVE_TEXTURE_ARB
#define CGL_CLIENT_ACTIVE_TEXTURE_ARB GL_CLIENT_ACTIVE_TEXTURE_ARB
#define CGL_MAX_TEXTURE_UNITS_ARB GL_MAX_TEXTURE_UNITS_ARB
#define CGL_DEBUG_OBJECT_MESA GL_DEBUG_OBJECT_MESA
#define CGL_DEBUG_PRINT_MESA GL_DEBUG_PRINT_MESA
#define CGL_DEBUG_ASSERT_MESA GL_DEBUG_ASSERT_MESA
#define CGL_TRACE_ALL_BITS_MESA GL_TRACE_ALL_BITS_MESA
#define CGL_TRACE_OPERATIONS_BIT_MESA GL_TRACE_OPERATIONS_BIT_MESA
#define CGL_TRACE_PRIMITIVES_BIT_MESA GL_TRACE_PRIMITIVES_BIT_MESA
#define CGL_TRACE_ARRAYS_BIT_MESA GL_TRACE_ARRAYS_BIT_MESA
#define CGL_TRACE_TEXTURES_BIT_MESA GL_TRACE_TEXTURES_BIT_MESA
#define CGL_TRACE_PIXELS_BIT_MESA GL_TRACE_PIXELS_BIT_MESA
#define CGL_TRACE_ERRORS_BIT_MESA GL_TRACE_ERRORS_BIT_MESA
#define CGL_TRACE_MASK_MESA GL_TRACE_MASK_MESA
#define CGL_TRACE_NAME_MESA GL_TRACE_NAME_MESA
#define CGL_DEPTH_STENCIL_MESA GL_DEPTH_STENCIL_MESA
#define CGL_FRAGMENT_PROGRAM_POSITION_MESA GL_FRAGMENT_PROGRAM_POSITION_MESA
#define CGL_FRAGMENT_PROGRAM_CALLBACK_MESA GL_FRAGMENT_PROGRAM_CALLBACK_MESA
#define CGL_FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA GL_FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA
#define CGL_FRAGMENT_PROGRAM_CALLBACK_DATA_MESA GL_FRAGMENT_PROGRAM_CALLBACK_DATA_MESA
#define CGL_VERTEX_PROGRAM_POSITION_MESA GL_VERTEX_PROGRAM_POSITION_MESA
#define CGL_VERTEX_PROGRAM_CALLBACK_MESA GL_VERTEX_PROGRAM_CALLBACK_MESA
#define CGL_VERTEX_PROGRAM_CALLBACK_FUNC_MESA GL_VERTEX_PROGRAM_CALLBACK_FUNC_MESA
#define CGL_VERTEX_PROGRAM_CALLBACK_DATA_MESA GL_VERTEX_PROGRAM_CALLBACK_DATA_MESA
#define CGL_ALPHA_BLEND_EQUATION_ATI GL_ALPHA_BLEND_EQUATION_ATI
#define CGL_TIME_ELAPSED_EXT GL_TIME_ELAPSED_EXT
#define CGL_READ_FRAMEBUFFER_EXT GL_READ_FRAMEBUFFER_EXT
#define CGL_DRAW_FRAMEBUFFER_EXT GL_DRAW_FRAMEBUFFER_EXT
#define CGL_DRAW_FRAMEBUFFER_BINDING_EXT GL_DRAW_FRAMEBUFFER_BINDING_EXT
#define CGL_READ_FRAMEBUFFER_BINDING_EXT GL_READ_FRAMEBUFFER_BINDING_EXT
#define CGL_DEPTH_STENCIL_EXT GL_DEPTH_STENCIL_EXT
#define CGL_TEXTURE_STENCIL_SIZE_EXT GL_TEXTURE_STENCIL_SIZE_EXT
#define CGL_SRGB_EXT GL_SRGB_EXT
#define CGL_SRGB_ALPHA_EXT GL_SRGB_ALPHA_EXT
#define CGL_SLUMINANCE_ALPHA_EXT GL_SLUMINANCE_ALPHA_EXT
#define CGL_SLUMINANCE_EXT GL_SLUMINANCE_EXT
#define CGL_COMPRESSED_SRGB_EXT GL_COMPRESSED_SRGB_EXT
#define CGL_COMPRESSED_SRGB_ALPHA_EXT GL_COMPRESSED_SRGB_ALPHA_EXT
#define CGL_COMPRESSED_SLUMINANCE_EXT GL_COMPRESSED_SLUMINANCE_EXT
#define CGL_COMPRESSED_SLUMINANCE_ALPHA_EXT GL_COMPRESSED_SLUMINANCE_ALPHA_EXT
#define CGL_DOT3_RGB GL_DOT3_RGB
#define CGL_DOT3_RGBA GL_DOT3_RGBA
/* extras */
#define CGL_TEXTURE_2D GL_TEXTURE_2D
#define CGL_ARGB GL_ARGB
#define CGL_UNSIGNED_INT_8_8_8_8_REV GL_UNSIGNED_INT_8_8_8_8_REV
#ifdef GL_TEXTURE_RECTANGLE_ARB
#define CGL_TEXTURE_RECTANGLE_ARB GL_TEXTURE_RECTANGLE_ARB
#else
#define CGL_TEXTURE_RECTANGLE_ARB 0
#endif
#ifdef GL_YCBCR_MESA
#define CGL_YCBCR_MESA GL_YCBCR_MESA
#define CGL_UNSIGNED_SHORT_8_8_REV_MESA GL_UNSIGNED_SHORT_8_8_REV_MESA
#define CGL_UNSIGNED_SHORT_8_8_MESA GL_UNSIGNED_SHORT_8_8_MESA
#else
#define CGL_YCBCR_MESA 0
#define CGL_UNSIGNED_SHORT_8_8_REV_MESA 0
#define CGL_UNSIGNED_SHORT_8_8_MESA 0
#endif
#define CGL_OBJECT_COMPILE_STATUS GL_OBJECT_COMPILE_STATUS_ARB
#define CLUTTER_COGL_HAS_GL 1
#define COGL_HAS_GL 1

View File

@ -372,7 +372,7 @@ _cogl_texture_driver_allows_foreign_gl_target (GLenum gl_target)
(for example, no mipmapping and complicated shader support) */
/* Allow 2-dimensional or rectangle textures only */
if (gl_target != GL_TEXTURE_2D && gl_target != CGL_TEXTURE_RECTANGLE_ARB)
if (gl_target != GL_TEXTURE_2D && gl_target != GL_TEXTURE_RECTANGLE_ARB)
return FALSE;
return TRUE;

View File

@ -33,606 +33,9 @@ G_BEGIN_DECLS
#define @COGL_GLES_VERSION@ 1
/* ClearBufferMask */
#define CGL_DEPTH_BUFFER_BIT GL_DEPTH_BUFFER_BIT
#define CGL_STENCIL_BUFFER_BIT GL_STENCIL_BUFFER_BIT
#define CGL_COLOR_BUFFER_BIT GL_COLOR_BUFFER_BIT
/* Boolean */
#define CGL_FALSE GL_FALSE
#define CGL_TRUE GL_TRUE
/* BeginMode */
#define CGL_POINTS GL_POINTS
#define CGL_LINES GL_LINES
#define CGL_LINE_LOOP GL_LINE_LOOP
#define CGL_LINE_STRIP GL_LINE_STRIP
#define CGL_TRIANGLES GL_TRIANGLES
#define CGL_TRIANGLE_STRIP GL_TRIANGLE_STRIP
#define CGL_TRIANGLE_FAN GL_TRIANGLE_FAN
/* AlphaFunction */
#define CGL_NEVER GL_NEVER
#define CGL_LESS GL_LESS
#define CGL_EQUAL GL_EQUAL
#define CGL_LEQUAL GL_LEQUAL
#define CGL_GREATER GL_GREATER
#define CGL_NOTEQUAL GL_NOTEQUAL
#define CGL_GEQUAL GL_GEQUAL
#define CGL_ALWAYS GL_ALWAYS
/* BlendingFactorDest */
#define CGL_ZERO GL_ZERO
#define CGL_ONE GL_ONE
#define CGL_SRC_COLOR GL_SRC_COLOR
#define CGL_ONE_MINUS_SRC_COLOR GL_ONE_MINUS_SRC_COLOR
#define CGL_SRC_ALPHA GL_SRC_ALPHA
#define CGL_ONE_MINUS_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA
#define CGL_DST_ALPHA GL_DST_ALPHA
#define CGL_ONE_MINUS_DST_ALPHA GL_ONE_MINUS_DST_ALPHA
/* BlendingFactorSrc */
#define CGL_DST_COLOR GL_DST_COLOR
#define CGL_ONE_MINUS_DST_COLOR GL_ONE_MINUS_DST_COLOR
#define CGL_SRC_ALPHA_SATURATE GL_SRC_ALPHA_SATURATE
/* Missing; */
/* GL_ZERO */
/* GL_ONE */
/* GL_SRC_ALPHA */
/* GL_ONE_MINUS_SRC_ALPHA */
/* GL_DST_ALPHA */
/* GL_ONE_MINUS_DST_ALPHA */
/* CullFaceMode */
#define CGL_FRONT GL_FRONT
#define CGL_BACK GL_BACK
#define CGL_FRONT_AND_BACK GL_FRONT_AND_BACK
/* EnableCap */
#define CGL_FOG GL_FOG
#define CGL_LIGHTING GL_LIGHTING
#define CGL_CULL_FACE GL_CULL_FACE
#define CGL_ALPHA_TEST GL_ALPHA_TEST
#define CGL_BLEND GL_BLEND
#define CGL_COLOR_LOGIC_OP GL_COLOR_LOGIC_OP
#define CGL_DITHER GL_DITHER
#define CGL_STENCIL_TEST GL_STENCIL_TEST
#define CGL_DEPTH_TEST GL_DEPTH_TEST
#define CGL_POINT_SMOOTH GL_POINT_SMOOTH
#define CGL_LINE_SMOOTH GL_LINE_SMOOTH
#define CGL_SCISSOR_TEST GL_SCISSOR_TEST
#define CGL_COLOR_MATERIAL GL_COLOR_MATERIAL
#define CGL_NORMALIZE GL_NORMALIZE
#define CGL_RESCALE_NORMAL GL_RESCALE_NORMAL
#define CGL_POLYGON_OFFSET_FILL GL_POLYGON_OFFSET_FILL
#define CGL_VERTEX_ARRAY GL_VERTEX_ARRAY
#define CGL_NORMAL_ARRAY GL_NORMAL_ARRAY
#define CGL_COLOR_ARRAY GL_COLOR_ARRAY
#define CGL_TEXTURE_COORD_ARRAY GL_TEXTURE_COORD_ARRAY
#define CGL_MULTISAMPLE GL_MULTISAMPLE
#define CGL_SAMPLE_ALPHA_TO_COVERAGE GL_SAMPLE_ALPHA_TO_COVERAGE
#define CGL_SAMPLE_ALPHA_TO_ONE GL_SAMPLE_ALPHA_TO_ONE
#define CGL_SAMPLE_COVERAGE GL_SAMPLE_COVERAGE
/* Errors */
#define CGL_NO_ERROR GL_NO_ERROR
#define CGL_INVALID_ENUM GL_INVALID_ENUM
#define CGL_INVALID_VALUE GL_INVALID_VALUE
#define CGL_INVALID_OPERATION GL_INVALID_OPERATION
#define CGL_STACK_OVERFLOW GL_STACK_OVERFLOW
#define CGL_STACK_UNDERFLOW GL_STACK_UNDERFLOW
#define CGL_OUT_OF_MEMORY GL_OUT_OF_MEMORY
/* Fog mode */
#define CGL_EXP GL_EXP
#define CGL_EXP2 GL_EXP2
#define CGL_FOG_DENSITY GL_FOG_DENSITY
/* FogParameter */
#define CGL_FOG_START GL_FOG_START
#define CGL_FOG_END GL_FOG_END
#define CGL_FOG_MODE GL_FOG_MODE
#define CGL_FOG_COLOR GL_FOG_COLOR
#define CGL_CW GL_CW
#define CGL_CCW GL_CCW
/* GetPName */
#define CGL_CURRENT_COLOR GL_CURRENT_COLOR
#define CGL_CURRENT_NORMAL GL_CURRENT_NORMAL
#define CGL_CURRENT_TEXTURE_COORDS GL_CURRENT_TEXTURE_COORDS
#define CGL_POINT_SIZE GL_POINT_SIZE
#define CGL_POINT_SIZE_MIN GL_POINT_SIZE_MIN
#define CGL_POINT_SIZE_MAX GL_POINT_SIZE_MAX
#define CGL_POINT_FADE_THRESHOLD_SIZE GL_POINT_FADE_THRESHOLD_SIZE
#define CGL_POINT_DISTANCE_ATTENUATION GL_POINT_DISTANCE_ATTENUATION
#define CGL_SMOOTH_POINT_SIZE_RANGE GL_SMOOTH_POINT_SIZE_RANGE
#define CGL_LINE_WIDTH GL_LINE_WIDTH
#define CGL_SMOOTH_LINE_WIDTH_RANGE GL_SMOOTH_LINE_WIDTH_RANGE
#define CGL_ALIASED_POINT_SIZE_RANGE GL_ALIASED_POINT_SIZE_RANGE
#define CGL_ALIASED_LINE_WIDTH_RANGE GL_ALIASED_LINE_WIDTH_RANGE
#define CGL_CULL_FACE_MODE GL_CULL_FACE_MODE
#define CGL_FRONT_FACE GL_FRONT_FACE
#define CGL_SHADE_MODEL GL_SHADE_MODEL
#define CGL_DEPTH_RANGE GL_DEPTH_RANGE
#define CGL_DEPTH_WRITEMASK GL_DEPTH_WRITEMASK
#define CGL_DEPTH_CLEAR_VALUE GL_DEPTH_CLEAR_VALUE
#define CGL_DEPTH_FUNC GL_DEPTH_FUNC
#define CGL_STENCIL_CLEAR_VALUE GL_STENCIL_CLEAR_VALUE
#define CGL_STENCIL_FUNC GL_STENCIL_FUNC
#define CGL_STENCIL_VALUE_MASK GL_STENCIL_VALUE_MASK
#define CGL_STENCIL_FAIL GL_STENCIL_FAIL
#define CGL_STENCIL_PASS_DEPTH_FAIL GL_STENCIL_PASS_DEPTH_FAIL
#define CGL_STENCIL_PASS_DEPTH_PASS GL_STENCIL_PASS_DEPTH_PASS
#define CGL_STENCIL_REF GL_STENCIL_REF
#define CGL_STENCIL_WRITEMASK GL_STENCIL_WRITEMASK
#ifdef COGL_HAS_GLES2
#define CGL_MATRIX_MODE 0x0BA0 /* bad style but works for now */
#else
#define CGL_MATRIX_MODE GL_MATRIX_MODE
#endif
#define CGL_VIEWPORT GL_VIEWPORT
#define CGL_MODELVIEW_STACK_DEPTH GL_MODELVIEW_STACK_DEPTH
#define CGL_PROJECTION_STACK_DEPTH GL_PROJECTION_STACK_DEPTH
#define CGL_TEXTURE_STACK_DEPTH GL_TEXTURE_STACK_DEPTH
#define CGL_MODELVIEW_MATRIX GL_MODELVIEW_MATRIX
#define CGL_PROJECTION_MATRIX GL_PROJECTION_MATRIX
#define CGL_TEXTURE_MATRIX GL_TEXTURE_MATRIX
#define CGL_ALPHA_TEST_FUNC GL_ALPHA_TEST_FUNC
#define CGL_ALPHA_TEST_REF GL_ALPHA_TEST_REF
#define CGL_BLEND_DST GL_BLEND_DST
#define CGL_BLEND_SRC GL_BLEND_SRC
#define CGL_LOGIC_OP_MODE GL_LOGIC_OP_MODE
#define CGL_SCISSOR_BOX GL_SCISSOR_BOX
#define CGL_SCISSOR_TEST GL_SCISSOR_TEST
#define CGL_COLOR_CLEAR_VALUE GL_COLOR_CLEAR_VALUE
#define CGL_COLOR_WRITEMASK GL_COLOR_WRITEMASK
#define CGL_UNPACK_ALIGNMENT GL_UNPACK_ALIGNMENT
#define CGL_PACK_ALIGNMENT GL_PACK_ALIGNMENT
#define CGL_MAX_LIGHTS GL_MAX_LIGHTS
#define CGL_MAX_CLIP_PLANES GL_MAX_CLIP_PLANES
#define CGL_MAX_TEXTURE_SIZE GL_MAX_TEXTURE_SIZE
#define CGL_MAX_MODELVIEW_STACK_DEPTH GL_MAX_MODELVIEW_STACK_DEPTH
#define CGL_MAX_PROJECTION_STACK_DEPTH GL_MAX_PROJECTION_STACK_DEPTH
#define CGL_MAX_TEXTURE_STACK_DEPTH GL_MAX_TEXTURE_STACK_DEPTH
#define CGL_MAX_VIEWPORT_DIMS GL_MAX_VIEWPORT_DIMS
#define CGL_MAX_ELEMENTS_VERTICES GL_MAX_ELEMENTS_VERTICES
#define CGL_MAX_ELEMENTS_INDICES GL_MAX_ELEMENTS_INDICES
#ifdef COGL_HAS_GLES2
#define CGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
#else
#define CGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS GL_MAX_TEXTURE_UNITS
#endif
#define CGL_SUBPIXEL_BITS GL_SUBPIXEL_BITS
#define CGL_RED_BITS GL_RED_BITS
#define CGL_GREEN_BITS GL_GREEN_BITS
#define CGL_BLUE_BITS GL_BLUE_BITS
#define CGL_ALPHA_BITS GL_ALPHA_BITS
#define CGL_DEPTH_BITS GL_DEPTH_BITS
#define CGL_STENCIL_BITS GL_STENCIL_BITS
#define CGL_POLYGON_OFFSET_UNITS GL_POLYGON_OFFSET_UNITS
#define CGL_POLYGON_OFFSET_FILL GL_POLYGON_OFFSET_FILL
#define CGL_POLYGON_OFFSET_FACTOR GL_POLYGON_OFFSET_FACTOR
#define CGL_VERTEX_ARRAY_SIZE GL_VERTEX_ARRAY_SIZE
#define CGL_VERTEX_ARRAY_TYPE GL_VERTEX_ARRAY_TYPE
#define CGL_VERTEX_ARRAY_STRIDE GL_VERTEX_ARRAY_STRIDE
#define CGL_NORMAL_ARRAY_TYPE GL_NORMAL_ARRAY_TYPE
#define CGL_NORMAL_ARRAY_STRIDE GL_NORMAL_ARRAY_STRIDE
#define CGL_COLOR_ARRAY_SIZE GL_COLOR_ARRAY_SIZE
#define CGL_COLOR_ARRAY_TYPE GL_COLOR_ARRAY_TYPE
#define CGL_COLOR_ARRAY_STRIDE GL_COLOR_ARRAY_STRIDE
#define CGL_TEXTURE_COORD_ARRAY_SIZE GL_TEXTURE_COORD_ARRAY_SIZE
#define CGL_TEXTURE_COORD_ARRAY_TYPE GL_TEXTURE_COORD_ARRAY_TYPE
#define CGL_TEXTURE_COORD_ARRAY_STRIDE GL_TEXTURE_COORD_ARRAY_STRIDE
#define CGL_VERTEX_ARRAY_POINTER GL_VERTEX_ARRAY_POINTER
#define CGL_NORMAL_ARRAY_POINTER GL_NORMAL_ARRAY_POINTER
#define CGL_COLOR_ARRAY_POINTER GL_COLOR_ARRAY_POINTER
#define CGL_TEXTURE_COORD_ARRAY_POINTER GL_TEXTURE_COORD_ARRAY_POINTER
#define CGL_SAMPLE_BUFFERS GL_SAMPLE_BUFFERS
#define CGL_SAMPLES GL_SAMPLES
#define CGL_SAMPLE_COVERAGE_VALUE GL_SAMPLE_COVERAGE_VALUE
#define CGL_SAMPLE_COVERAGE_INVERT GL_SAMPLE_COVERAGE_INVERT
/* GetTextureParameter - missing */
/* GL_TEXTURE_MAG_FILTER */
/* GL_TEXTURE_MIN_FILTER */
/* GL_TEXTURE_WRAP_S */
/* GL_TEXTURE_WRAP_T */
#define CGL_IMPLEMENTATION_COLOR_READ_TYPE_OES GL_IMPLEMENTATION_COLOR_READ_TYPE_OES
#define CGL_IMPLEMENTATION_COLOR_READ_FORMAT_OES GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES
#define CGL_NUM_COMPRESSED_TEXTURE_FORMATS GL_NUM_COMPRESSED_TEXTURE_FORMATS
#define CGL_COMPRESSED_TEXTURE_FORMATS GL_COMPRESSED_TEXTURE_FORMATS
/* OES_matrix_get */
#define CGL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS
#define CGL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS
#define CGL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS
/* HintMode */
#define CGL_DONT_CARE GL_DONT_CARE
#define CGL_FASTEST GL_FASTEST
#define CGL_NICEST GL_NICEST
/* HintTarget */
#define CGL_PERSPECTIVE_CORRECTION_HINT GL_PERSPECTIVE_CORRECTION_HINT
#define CGL_POINT_SMOOTH_HINT GL_POINT_SMOOTH_HINT
#define CGL_LINE_SMOOTH_HINT GL_LINE_SMOOTH_HINT
#define CGL_POLYGON_SMOOTH_HINT GL_POLYGON_SMOOTH_HINT
#define CGL_FOG_HINT GL_FOG_HINT
#define CGL_GENERATE_MIPMAP_HINT GL_GENERATE_MIPMAP_HINT
/* LightModelParameter */
#define CGL_LIGHT_MODEL_AMBIENT GL_LIGHT_MODEL_AMBIENT
#define CGL_LIGHT_MODEL_TWO_SIDE GL_LIGHT_MODEL_TWO_SIDE
/* LightParameter */
#define CGL_POSITION GL_POSITION
#define CGL_SPOT_DIRECTION GL_SPOT_DIRECTION
#define CGL_SPOT_EXPONENT GL_SPOT_EXPONENT
#define CGL_SPOT_CUTOFF GL_SPOT_CUTOFF
#define CGL_CONSTANT_ATTENUATION GL_CONSTANT_ATTENUATION
#define CGL_LINEAR_ATTENUATION GL_LINEAR_ATTENUATION
#define CGL_QUADRATIC_ATTENUATION GL_QUADRATIC_ATTENUATION
/* DataType */
#define CGL_BYTE GL_BYTE
#define CGL_UNSIGNED_BYTE GL_UNSIGNED_BYTE
#define CGL_SHORT GL_SHORT
#define CGL_UNSIGNED_SHORT GL_UNSIGNED_SHORT
#define CGL_FLOAT GL_FLOAT
#define CGL_FIXED GL_FIXED
/* LogicOp */
#define CGL_CLEAR GL_CLEAR
#define CGL_AND GL_AND
#define CGL_AND_REVERSE GL_AND_REVERSE
#define CGL_COPY GL_COPY
#define CGL_AND_INVERTED GL_AND_INVERTED
#define CGL_NOOP GL_NOOP
#define CGL_XOR GL_XOR
#define CGL_OR GL_OR
#define CGL_NOR GL_NOR
#define CGL_EQUIV GL_EQUIV
#define CGL_INVERT GL_INVERT
#define CGL_OR_REVERSE GL_OR_REVERSE
#define CGL_COPY_INVERTED GL_COPY_INVERTED
#define CGL_OR_INVERTED GL_OR_INVERTED
#define CGL_NAND GL_NAND
#define CGL_SET GL_SET
/* MaterialParameter */
#define CGL_AMBIENT_AND_DIFFUSE GL_AMBIENT_AND_DIFFUSE
/* MatrixMode */
#define CGL_MODELVIEW GL_MODELVIEW
#define CGL_PROJECTION GL_PROJECTION
#define CGL_TEXTURE GL_TEXTURE
/* PixelFormat */
#define CGL_ALPHA GL_ALPHA
#define CGL_RGB GL_RGB
#define CGL_RGBA GL_RGBA
#define CGL_LUMINANCE GL_LUMINANCE
#define CGL_LUMINANCE_ALPHA GL_LUMINANCE_ALPHA
/* PixelStoreParameter */
#define CGL_UNPACK_ALIGNMENT GL_UNPACK_ALIGNMENT
#define CGL_PACK_ALIGNMENT GL_PACK_ALIGNMENT
/* PixelType */
/* GL_UNSIGNED_BYTE */
#define CGL_UNSIGNED_SHORT_4_4_4_4 GL_UNSIGNED_SHORT_4_4_4_4
#define CGL_UNSIGNED_SHORT_5_5_5_1 GL_UNSIGNED_SHORT_5_5_5_1
#define CGL_UNSIGNED_SHORT_5_6_5 CGL_UNSIGNED_SHORT_5_6_5
/* ShadingModel */
#define CGL_FLAT GL_FLAT
#define CGL_SMOOTH GL_SMOOTH
/* StencilFunction */
/* GL_NEVER */
/* GL_LESS */
/* GL_EQUAL */
/* GL_LEQUAL */
/* GL_GREATER */
/* GL_NOTEQUAL */
/* GL_GEQUAL */
/* GL_ALWAYS */
/* StencilOp */
#define CGL_KEEP GL_KEEP
#define CGL_REPLACE GL_REPLACE
#define CGL_INCR GL_INCR
#define CGL_DECR GL_DECR
/* StringName */
#define CGL_VENDOR GL_VENDOR
#define CGL_RENDERER GL_RENDERER
#define CGL_VERSION GL_VERSION
#define CGL_EXTENSIONS GL_EXTENSIONS
/* TextureEnvMode */
#define CGL_DECAL GL_DECAL
/* GL_BLEND */
/* GL_REPLACE */
/* TextureEnvParameter */
#define CGL_TEXTURE_ENV_MODE GL_TEXTURE_ENV_MODE
#define CGL_TEXTURE_ENV_COLOR GL_TEXTURE_ENV_COLOR
/* TextureEnvTarget */
#define CGL_TEXTURE_ENV GL_TEXTURE_ENV
/* TextureMagFilter */
#define CGL_NEAREST GL_NEAREST
#define CGL_LINEAR GL_LINEAR
/* TextureMinFilter */
/* GL_NEAREST */
/* GL_LINEAR */
#define CGL_NEAREST_MIPMAP_NEAREST GL_NEAREST_MIPMAP_NEAREST
#define CGL_LINEAR_MIPMAP_NEAREST GL_LINEAR_MIPMAP_NEAREST
#define CGL_NEAREST_MIPMAP_LINEAR GL_NEAREST_MIPMAP_LINEAR
#define CGL_LINEAR_MIPMAP_LINEAR GL_LINEAR_MIPMAP_LINEAR
/* TextureParameterName */
#define CGL_TEXTURE_MAG_FILTER GL_TEXTURE_MAG_FILTER
#define CGL_TEXTURE_MIN_FILTER GL_TEXTURE_MIN_FILTER
#define CGL_TEXTURE_WRAP_S GL_TEXTURE_WRAP_S
#define CGL_TEXTURE_WRAP_T GL_TEXTURE_WRAP_T
#define CGL_GENERATE_MIPMAP GL_GENERATE_MIPMAP
#define CGL_ACTIVE_TEXTURE GL_ACTIVE_TEXTURE
#define CGL_CLIENT_ACTIVE_TEXTURE GL_CLIENT_ACTIVE_TEXTURE
/* TextureWrapMode */
#define CGL_REPEAT GL_REPEAT
#define CGL_CLAMP_TO_EDGE GL_CLAMP_TO_EDGE
/* PixelInternalFormat */
/* Buffer Objects */
#define CGL_ARRAY_BUFFER GL_ARRAY_BUFFER
#define CGL_ELEMENT_ARRAY_BUFFER GL_ELEMENT_ARRAY_BUFFER
#define CGL_ARRAY_BUFFER_BINDING GL_ARRAY_BUFFER_BINDING
#define CGL_ELEMENT_ARRAY_BUFFER_BINDING GL_ELEMENT_ARRAY_BUFFER_BINDING
#define CGL_VERTEX_ARRAY_BUFFER_BINDING GL_VERTEX_ARRAY_BUFFER_BINDING
#define CGL_NORMAL_ARRAY_BUFFER_BINDING GL_NORMAL_ARRAY_BUFFER_BINDING
#define CGL_COLOR_ARRAY_BUFFER_BINDING GL_COLOR_ARRAY_BUFFER_BINDING
#define CGL_TEXTURE_COORD_ARRAY_BUFFER_BINDING GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING
#define CGL_STATIC_DRAW GL_STATIC_DRAW
#define CGL_DYNAMIC_DRAW GL_DYNAMIC_DRAW
#define CGL_WRITE_ONLY GL_WRITE_ONLY
#define CGL_BUFFER_SIZE GL_BUFFER_SIZE
#define CGL_BUFFER_USAGE GL_BUFFER_USAGE
#define CGL_BUFFER_ACCESS GL_BUFFER_ACCESS
#define CGL_RGB_SCALE GL_RGB_SCALE
#define CGL_ALPHA_SCALE GL_ALPHA_SCALE
#define CGL_POINT_SPRITE_OES GL_POINT_SPRITE_OES
#define CGL_COORD_REPLACE_OES GL_COORD_REPLACE_OES
#define CGL_POINT_SIZE_ARRAY_OES GL_POINT_SIZE_ARRAY_OES
#define CGL_POINT_SIZE_ARRAY_TYPE_OES GL_POINT_SIZE_ARRAY_TYPE_OES
#define CGL_POINT_SIZE_ARRAY_STRIDE_OES GL_POINT_SIZE_ARRAY_STRIDE_OES
#define CGL_POINT_SIZE_ARRAY_POINTER_OES GL_POINT_SIZE_ARRAY_POINTER_OES
#define CGL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES
#define CGL_MAX_VERTEX_UNITS_OES GL_MAX_VERTEX_UNITS_OES
#define CGL_MAX_PALETTE_MATRICES_OES GL_MAX_PALETTE_MATRICES_OES
#define CGL_MATRIX_PALETTE_OES GL_MATRIX_PALETTE_OES
#define CGL_MATRIX_INDEX_ARRAY_OES GL_MATRIX_INDEX_ARRAY_OES
#define CGL_WEIGHT_ARRAY_OES GL_WEIGHT_ARRAY_OES
#define CGL_MATRIX_INDEX_ARRAY_SIZE_OES GL_MATRIX_INDEX_ARRAY_SIZE_OES
#define CGL_MATRIX_INDEX_ARRAY_TYPE_OES GL_MATRIX_INDEX_ARRAY_TYPE_OES
#define CGL_MATRIX_INDEX_ARRAY_STRIDE_OES GL_MATRIX_INDEX_ARRAY_STRIDE_OES
#define CGL_MATRIX_INDEX_ARRAY_POINTER_OES GL_MATRIX_INDEX_ARRAY_POINTER_OES
#define CGL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES
#define CGL_WEIGHT_ARRAY_SIZE_OES GL_WEIGHT_ARRAY_SIZE_OES
#define CGL_WEIGHT_ARRAY_TYPE_OES GL_WEIGHT_ARRAY_TYPE_OES
#define CGL_WEIGHT_ARRAY_STRIDE_OES GL_WEIGHT_ARRAY_STRIDE_OES
#define CGL_WEIGHT_ARRAY_POINTER_OES GL_WEIGHT_ARRAY_POINTER_OES
#define CGL_WEIGHT_ARRAY_BUFFER_BINDING_OES GL_WEIGHT_ARRAY_BUFFER_BINDING_OES
#define CGL_TEXTURE_CROP_RECT_OES GL_TEXTURE_CROP_RECT_OES
/* extras */
/* YUV textures also unsupported */
#define CGL_YCBCR_MESA 0
#define CGL_UNSIGNED_SHORT_8_8_REV_MESA 0
#define CGL_UNSIGNED_SHORT_8_8_MESA 0
#if defined(GL_OBJECT_COMPILE_STATUS)
#define CGL_OBJECT_COMPILE_STATUS GL_OBJECT_COMPILE_STATUS
#elif defined(GL_COMPILE_STATUS)
#define CGL_OBJECT_COMPILE_STATUS GL_COMPILE_STATUS
#else
#define CGL_OBJECT_COMPILE_STATUS 0
#endif
#define CLUTTER_COGL_HAS_GLES 1
#define COGL_HAS_GLES 1
/* These aren't always defined under GLES 2 but if they are then we
should probably use the GL_* macro instead of assuming the
number */
#ifdef GL_MODULATE
#define CGL_MODULATE GL_MODULATE
#else
#define CGL_MODULATE 0x2100
#endif
#ifdef GL_ADD
#define CGL_ADD GL_ADD
#else
#define CGL_ADD 0x0104
#endif
#ifdef GL_ADD_SIGNED
#define CGL_ADD_SIGNED GL_ADD_SIGNED
#else
#define CGL_ADD_SIGNED 0x8574
#endif
#ifdef GL_INTERPOLATE
#define CGL_INTERPOLATE GL_INTERPOLATE
#else
#define CGL_INTERPOLATE 0x8575
#endif
#ifdef GL_SUBTRACT
#define CGL_SUBTRACT GL_SUBTRACT
#else
#define CGL_SUBTRACT 0x84e7
#endif
#ifdef GL_DOT3_RGB
#define CGL_DOT3_RGB GL_DOT3_RGB
#else
#define CGL_DOT3_RGB 0x86ae
#endif
#ifdef GL_DOT3_RGBA
#define CGL_DOT3_RGBA GL_DOT3_RGBA
#else
#define CGL_DOT3_RGBA 0x86af
#endif
#ifdef GL_CONSTANT
#define CGL_CONSTANT GL_CONSTANT
#else
#define CGL_CONSTANT 0x8576
#endif
#ifdef GL_PRIMARY_COLOR
#define CGL_PRIMARY_COLOR GL_PRIMARY_COLOR
#else
#define CGL_PRIMARY_COLOR 0x8577
#endif
#ifdef GL_PREVIOUS
#define CGL_PREVIOUS GL_PREVIOUS
#else
#define CGL_PREVIOUS 0x8578
#endif
#ifdef GL_COMBINE
#define CGL_COMBINE GL_COMBINE
#else
#define CGL_COMBINE 0x8570
#endif
#ifdef GL_COMBINE_RGB
#define CGL_COMBINE_RGB GL_COMBINE_RGB
#else
#define CGL_COMBINE_RGB 0x8571
#endif
#ifdef GL_COMBINE_ALPHA
#define CGL_COMBINE_ALPHA GL_COMBINE_ALPHA
#else
#define CGL_COMBINE_ALPHA 0x8572
#endif
#ifdef GL_SRC0_RGB
#define CGL_SRC0_RGB GL_SRC0_RGB
#else
#define CGL_SRC0_RGB 0x8580
#endif
#ifdef GL_OPERAND0_RGB
#define CGL_OPERAND0_RGB GL_OPERAND0_RGB
#else
#define CGL_OPERAND0_RGB 0x8590
#endif
#ifdef GL_SRC1_RGB
#define CGL_SRC1_RGB GL_SRC1_RGB
#else
#define CGL_SRC1_RGB 0x8581
#endif
#ifdef GL_OPERAND1_RGB
#define CGL_OPERAND1_RGB GL_OPERAND1_RGB
#else
#define CGL_OPERAND1_RGB 0x8591
#endif
#ifdef GL_SRC2_RGB
#define CGL_SRC2_RGB GL_SRC2_RGB
#else
#define CGL_SRC2_RGB 0x8582
#endif
#ifdef GL_OPERAND2_RGB
#define CGL_OPERAND2_RGB GL_OPERAND2_RGB
#else
#define CGL_OPERAND2_RGB 0x8592
#endif
#ifdef GL_SRC0_ALPHA
#define CGL_SRC0_ALPHA GL_SRC0_ALPHA
#else
#define CGL_SRC0_ALPHA 0x8588
#endif
#ifdef GL_OPERAND0_ALPHA
#define CGL_OPERAND0_ALPHA GL_OPERAND0_ALPHA
#else
#define CGL_OPERAND0_ALPHA 0x8598
#endif
#ifdef GL_SRC1_ALPHA
#define CGL_SRC1_ALPHA GL_SRC1_ALPHA
#else
#define CGL_SRC1_ALPHA 0x8589
#endif
#ifdef GL_OPERAND1_ALPHA
#define CGL_OPERAND1_ALPHA GL_OPERAND1_ALPHA
#else
#define CGL_OPERAND1_ALPHA 0x8599
#endif
#ifdef GL_SRC2_ALPHA
#define CGL_SRC2_ALPHA GL_SRC2_ALPHA
#else
#define CGL_SRC2_ALPHA 0x858a
#endif
#ifdef GL_OPERAND2_ALPHA
#define CGL_OPERAND2_ALPHA GL_OPERAND2_ALPHA
#else
#define CGL_OPERAND2_ALPHA 0x859a
#endif
#ifdef GL_AMBIENT
#define CGL_AMBIENT GL_AMBIENT
#else
#define CGL_AMBIENT 0x1200
#endif
#ifdef GL_DIFFUSE
#define CGL_DIFFUSE GL_DIFFUSE
#else
#define CGL_DIFFUSE 0x1201
#endif
#ifdef GL_SPECULAR
#define CGL_SPECULAR GL_SPECULAR
#else
#define CGL_SPECULAR 0x1202
#endif
#ifdef GL_EMISSION
#define CGL_EMISSION GL_EMISSION
#else
#define CGL_EMISSION 0x1600
#endif
#ifdef GL_SHININESS
#define CGL_SHININESS GL_SHININESS
#else
#define CGL_SHININESS 0x1601
#endif
G_END_DECLS
#endif

View File

@ -118,7 +118,7 @@ initialize_texture_units (CoglGles2Wrapper *w)
/* We will need to set the matrix mode to GL_TEXTURE to
* initialise any new texture units, so we save the current
* mode for restoring afterwards */
GE( cogl_wrap_glGetIntegerv (CGL_MATRIX_MODE, &prev_mode));
GE( cogl_wrap_glGetIntegerv (GL_MATRIX_MODE, &prev_mode));
for (i = 0; i < COGL_GLES2_MAX_TEXTURE_UNITS; i++)
{
@ -1281,7 +1281,7 @@ cogl_wrap_glGetIntegerv (GLenum pname, GLint *params)
*params = 0;
break;
case CGL_MATRIX_MODE:
case GL_MATRIX_MODE:
*params = w->matrix_mode;
break;

View File

@ -224,12 +224,14 @@ struct _CoglGles2WrapperShader
#ifndef GL_MODELVIEW
#define GL_MATRIX_MODE 0x0BA0
#define GL_MODELVIEW 0x1700
#define GL_PROJECTION 0x1701
#ifdef COGL_ENABLE_DEBUG
#define GL_STACK_OVERFLOW 0x0503
#define GL_STACK_UNDERFLOW 0x0504
#define GL_STACK_OVERFLOW 0x0503
#define GL_STACK_UNDERFLOW 0x0504
#endif
#define GL_VERTEX_ARRAY 0x8074
@ -268,35 +270,36 @@ struct _CoglGles2WrapperShader
#define GL_EXP 0x8000
#define GL_EXP2 0x8001
#define GL_ADD CGL_ADD
#define GL_ADD_SIGNED CGL_ADD_SIGNED
#define GL_INTERPOLATE CGL_INTERPOLATE
#define GL_SUBTRACT CGL_SUBTRACT
#define GL_DOT3_RGB CGL_DOT3_RGB
#define GL_DOT3_RGBA CGL_DOT3_RGBA
#define GL_CONSTANT CGL_CONSTANT
#define GL_PRIMARY_COLOR CGL_PRIMARY_COLOR
#define GL_PREVIOUS CGL_PREVIOUS
#define GL_COMBINE CGL_COMBINE
#define GL_COMBINE_RGB CGL_COMBINE_RGB
#define GL_COMBINE_ALPHA CGL_COMBINE_ALPHA
#define GL_SRC0_RGB CGL_SRC0_RGB
#define GL_OPERAND0_RGB CGL_OPERAND0_RGB
#define GL_SRC1_RGB CGL_SRC1_RGB
#define GL_OPERAND1_RGB CGL_OPERAND1_RGB
#define GL_SRC2_RGB CGL_SRC2_RGB
#define GL_OPERAND2_RGB CGL_OPERAND2_RGB
#define GL_SRC0_ALPHA CGL_SRC0_ALPHA
#define GL_OPERAND0_ALPHA CGL_OPERAND0_ALPHA
#define GL_SRC1_ALPHA CGL_SRC1_ALPHA
#define GL_OPERAND1_ALPHA CGL_OPERAND1_ALPHA
#define GL_SRC2_ALPHA CGL_SRC2_ALPHA
#define GL_OPERAND2_ALPHA CGL_OPERAND2_ALPHA
#define GL_AMBIENT CGL_AMBIENT
#define GL_DIFFUSE CGL_DIFFUSE
#define GL_SPECULAR CGL_SPECULAR
#define GL_EMISSION CGL_EMISSION
#define GL_SHININESS CGL_SHININESS
#define GL_MODULATE 0x2100
#define GL_ADD 0x0104
#define GL_ADD_SIGNED 0x8574
#define GL_INTERPOLATE 0x8575
#define GL_SUBTRACT 0x84e7
#define GL_DOT3_RGB 0x86ae
#define GL_DOT3_RGBA 0x86af
#define GL_CONSTANT 0x8576
#define GL_PRIMARY_COLOR 0x8577
#define GL_PREVIOUS 0x8578
#define GL_COMBINE 0x8570
#define GL_COMBINE_RGB 0x8571
#define GL_COMBINE_ALPHA 0x8572
#define GL_SRC0_RGB 0x8580
#define GL_OPERAND0_RGB 0x8590
#define GL_SRC1_RGB 0x8581
#define GL_OPERAND1_RGB 0x8591
#define GL_SRC2_RGB 0x8582
#define GL_OPERAND2_RGB 0x8592
#define GL_SRC0_ALPHA 0x8588
#define GL_OPERAND0_ALPHA 0x8598
#define GL_SRC1_ALPHA 0x8589
#define GL_OPERAND1_ALPHA 0x8599
#define GL_SRC2_ALPHA 0x858a
#define GL_OPERAND2_ALPHA 0x859a
#define GL_AMBIENT 0x1200
#define GL_DIFFUSE 0x1201
#define GL_SPECULAR 0x1202
#define GL_EMISSION 0x1600
#define GL_SHININESS 0x1601
#endif /* GL_MODELVIEW */

File diff suppressed because it is too large Load Diff

View File

@ -42,6 +42,7 @@
#include "clutter-backend-glx.h"
#include "clutter-stage-glx.h"
#include "clutter-glx.h"
#include "clutter-profile.h"
#include "../clutter-event.h"
#include "../clutter-main.h"
@ -51,12 +52,13 @@
#include "cogl/cogl.h"
G_DEFINE_TYPE (ClutterBackendGLX, clutter_backend_glx, CLUTTER_TYPE_BACKEND_X11);
/* singleton object */
static ClutterBackendGLX *backend_singleton = NULL;
static gchar *clutter_vblank_name = NULL;
static gchar *clutter_vblank_name = NULL;
#ifdef __linux__
#define DRM_VBLANK_RELATIVE 0x1;
@ -362,46 +364,86 @@ _clutter_backend_glx_get_fbconfig (ClutterBackendGLX *backend_glx,
GLXFBConfig *config)
{
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend_glx);
int attributes[] = {
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DOUBLEBUFFER, GL_TRUE,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_ALPHA_SIZE, 1,
GLX_DEPTH_SIZE, 1,
GLX_STENCIL_SIZE, 1,
GLXFBConfig *configs = NULL;
gboolean use_argb = clutter_x11_get_use_argb_visual ();
int n_configs, i;
static const int attributes[] = {
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DOUBLEBUFFER, GL_TRUE,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_ALPHA_SIZE, 1,
GLX_DEPTH_SIZE, 1,
GLX_STENCIL_SIZE, 1,
None
};
GLXFBConfig *configs = NULL;
int n_configs;
if (backend_x11->xdpy == None || backend_x11->xscreen == None)
return FALSE;
/* If we don't already have a cached config then try to get one */
if (!backend_glx->found_fbconfig)
{
CLUTTER_NOTE (BACKEND,
"Retrieving GL fbconfig, dpy: %p, xscreen; %p (%d)",
backend_x11->xdpy,
backend_x11->xscreen,
backend_x11->xscreen_num);
configs = glXChooseFBConfig (backend_x11->xdpy,
backend_x11->xscreen_num,
attributes,
&n_configs);
if (configs)
{
if (use_argb)
{
for (i = 0; i < n_configs; i++)
{
XVisualInfo *vinfo;
vinfo = glXGetVisualFromFBConfig (backend_x11->xdpy,
configs[i]);
if (vinfo == None)
continue;
if (vinfo->depth == 32 &&
(vinfo->red_mask == 0xff0000 &&
vinfo->green_mask == 0x00ff00 &&
vinfo->blue_mask == 0x0000ff))
{
CLUTTER_NOTE (BACKEND,
"Found GLX visual ARGB [index:%d]", i);
backend_glx->found_fbconfig = TRUE;
backend_glx->fbconfig = configs[i];
goto out;
}
}
/* If we make it here then we didn't find an RGBA config so
we'll fall back to using an RGB config */
CLUTTER_NOTE (BACKEND, "ARGB visual requested, but none found");
}
if (n_configs >= 1)
{
backend_glx->found_fbconfig = TRUE;
backend_glx->fbconfig = configs[0];
}
out:
XFree (configs);
}
}
if (backend_glx->found_fbconfig)
{
*config = backend_glx->fbconfig;
return TRUE;
}
CLUTTER_NOTE (BACKEND,
"Retrieving GL fbconfig, dpy: %p, xscreen; %p (%d)",
backend_x11->xdpy,
backend_x11->xscreen,
backend_x11->xscreen_num);
configs = glXChooseFBConfig (backend_x11->xdpy,
backend_x11->xscreen_num,
attributes,
&n_configs);
if (configs)
{
*config = configs[0];
backend_glx->found_fbconfig = TRUE;
backend_glx->fbconfig = configs[0];
XFree (configs);
return TRUE;
}
else
@ -436,12 +478,14 @@ clutter_backend_glx_create_context (ClutterBackend *backend,
{
g_set_error (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_BACKEND,
"Unable to find suitable fbconfig for GL context");
"Unable to find a suitable GLXFBConfig for "
"the GLX context");
return FALSE;
}
CLUTTER_NOTE (GL, "Creating GL Context (display: %p)",
CLUTTER_NOTE (GL, "Creating GLX Context (display: %p)",
backend_x11->xdpy);
backend_glx->gl_context =
glXCreateNewContext (backend_x11->xdpy,
config,
@ -460,7 +504,8 @@ clutter_backend_glx_create_context (ClutterBackend *backend,
is_direct = glXIsDirect (backend_x11->xdpy,
backend_glx->gl_context);
CLUTTER_NOTE (GL, "Setting %s context",
CLUTTER_NOTE (GL,
"Setting %s context",
is_direct ? "direct" : "indirect");
_cogl_set_indirect_context (!is_direct);
}
@ -611,6 +656,16 @@ clutter_backend_glx_redraw (ClutterBackend *backend,
ClutterStageGLX *stage_glx;
ClutterStageX11 *stage_x11;
ClutterStageWindow *impl;
CLUTTER_STATIC_TIMER (painting_timer,
"Redrawing", /* parent */
"Painting actors",
"The time spent painting actors",
0 /* no application private data */);
CLUTTER_STATIC_TIMER (swapbuffers_timer,
"Redrawing", /* parent */
"glXSwapBuffers",
"The time spent blocked by glXSwapBuffers",
0 /* no application private data */);
impl = _clutter_stage_get_window (stage);
if (G_UNLIKELY (impl == NULL))
@ -625,9 +680,11 @@ clutter_backend_glx_redraw (ClutterBackend *backend,
stage_x11 = CLUTTER_STAGE_X11 (impl);
stage_glx = CLUTTER_STAGE_GLX (impl);
CLUTTER_TIMER_START (_clutter_uprof_context, painting_timer);
/* this will cause the stage implementation to be painted */
clutter_actor_paint (CLUTTER_ACTOR (stage));
cogl_flush ();
CLUTTER_TIMER_STOP (_clutter_uprof_context, painting_timer);
if (stage_x11->xwin != None)
{
@ -639,7 +696,10 @@ clutter_backend_glx_redraw (ClutterBackend *backend,
CLUTTER_NOTE (BACKEND, "glXSwapBuffers (display: %p, window: 0x%lx)",
backend_x11->xdpy,
(unsigned long) stage_x11->xwin);
CLUTTER_TIMER_START (_clutter_uprof_context, swapbuffers_timer);
glXSwapBuffers (backend_x11->xdpy, stage_x11->xwin);
CLUTTER_TIMER_STOP (_clutter_uprof_context, swapbuffers_timer);
}
}

View File

@ -250,7 +250,7 @@ clutter_glx_texture_pixmap_free_rectangle (ClutterGLXTexturePixmap *texture)
cogl_texture_get_gl_texture (cogl_tex, &gl_handle, &gl_target);
if (gl_target == CGL_TEXTURE_RECTANGLE_ARB)
if (gl_target == GL_TEXTURE_RECTANGLE_ARB)
glDeleteTextures (1, &gl_handle);
}
@ -351,12 +351,12 @@ create_cogl_texture (ClutterTexture *texture,
using_rectangle = TRUE;
glGenTextures (1, &tex);
glBindTexture (CGL_TEXTURE_RECTANGLE_ARB, tex);
glTexImage2D (CGL_TEXTURE_RECTANGLE_ARB, 0,
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0,
gl_format, width, height,
0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
handle = cogl_texture_new_from_foreign (tex, CGL_TEXTURE_RECTANGLE_ARB,
handle = cogl_texture_new_from_foreign (tex, GL_TEXTURE_RECTANGLE_ARB,
width, height,
0, 0,
cogl_format | COGL_BGR_BIT |

View File

@ -43,9 +43,4 @@
#include <clutter/clutter.h>
#include <clutter/glx/clutter-glx-texture-pixmap.h>
G_BEGIN_DECLS
G_END_DECLS
#endif /* __CLUTTER_GLX_H__ */

View File

@ -105,18 +105,11 @@ clutter_stage_glx_realize (ClutterStageWindow *stage_window)
{
XSetWindowAttributes xattr;
unsigned long mask;
GLXFBConfig config;
XVisualInfo *xvisinfo;
CLUTTER_NOTE (MISC, "Creating stage X window");
if (!_clutter_backend_glx_get_fbconfig (backend_glx, &config))
{
g_critical ("Unable to find suitable FBConfig to realize stage.");
return FALSE;
}
xvisinfo = glXGetVisualFromFBConfig (backend_x11->xdpy, config);
xvisinfo = clutter_backend_x11_get_visual_info (backend_x11);
if (xvisinfo == NULL)
{
g_critical ("Unable to find suitable GL visual.");
@ -145,9 +138,9 @@ clutter_stage_glx_realize (ClutterStageWindow *stage_window)
XFree (xvisinfo);
}
if (clutter_x11_has_event_retrieval())
if (clutter_x11_has_event_retrieval ())
{
if (clutter_x11_has_xinput())
if (clutter_x11_has_xinput ())
{
XSelectInput (backend_x11->xdpy, stage_x11->xwin,
StructureNotifyMask |

View File

@ -97,6 +97,7 @@ static ClutterBackendX11 *backend_singleton = NULL;
/* various flags corresponding to pre init setup calls */
static gboolean _no_xevent_retrieval = FALSE;
static gboolean clutter_enable_xinput = FALSE;
static gboolean clutter_enable_argb = FALSE;
static Display *_foreign_dpy = NULL;
/* options */
@ -124,6 +125,13 @@ clutter_backend_x11_pre_parse (ClutterBackend *backend,
env_string = NULL;
}
env_string = g_getenv ("CLUTTER_DISABLE_ARGB_VISUAL");
if (env_string)
{
clutter_enable_argb = FALSE;
env_string = NULL;
}
return TRUE;
}
@ -980,6 +988,56 @@ clutter_x11_has_composite_extension (void)
return have_composite;
}
/**
* clutter_x11_set_use_argb_visual:
* @use_argb: %TRUE if ARGB visuals should be requested by default
*
* Sets whether the Clutter X11 backend should request ARGB visuals by default
* or not.
*
* By default, Clutter requests RGB visuals.
*
* <note>If no ARGB visuals are found, the X11 backend will fall back to
* requesting a RGB visual instead.</note>
*
* ARGB visuals are required for the #ClutterStage:use-alpha property to work.
*
* <note>This function can only be called once, and before clutter_init() is
* called.</note>
*
* Since: 1.2
*/
void
clutter_x11_set_use_argb_visual (gboolean use_argb)
{
if (backend_singleton != NULL)
{
g_warning ("%s() can only be used before calling clutter_init()",
G_STRFUNC);
return;
}
CLUTTER_NOTE (BACKEND, "ARGB visuals are %s",
use_argb ? "enabled" : "disabled");
clutter_enable_argb = use_argb;
}
/**
* clutter_x11_get_use_argb_visual:
*
* Retrieves whether the Clutter X11 backend is using ARGB visuals by default
*
* Return value: %TRUE if ARGB visuals are queried by default
*
* Since: 1.2
*/
gboolean
clutter_x11_get_use_argb_visual (void)
{
return clutter_enable_argb;
}
XVisualInfo *
clutter_backend_x11_get_visual_info (ClutterBackendX11 *backend_x11)
{
@ -994,3 +1052,24 @@ clutter_backend_x11_get_visual_info (ClutterBackendX11 *backend_x11)
return NULL;
}
/**
* clutter_x11_get_visual_info:
*
* Retrieves the <structname>XVisualInfo</structname> used by the Clutter X11
* backend.
*
* Return value: a <structname>XVisualInfo</structname>, or
* <varname>None</varname>. The returned value should be freed using XFree()
* when done
*
* Since: 1.2
*/
XVisualInfo *
clutter_x11_get_visual_info (void)
{
ClutterBackendX11 *backend_x11;
backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
return clutter_backend_x11_get_visual_info (backend_x11);
}

View File

@ -627,6 +627,32 @@ event_translate (ClutterBackend *backend,
break;
case KeyRelease:
/* old-style X11 terminals require that even modern X11 send
* KeyPress/KeyRelease pairs when auto-repeating. for this
* reason modern(-ish) API like XKB has a way to detect
* auto-repeat and do a single KeyRelease at the end of a
* KeyPress sequence.
*
* this check emulates XKB's detectable auto-repeat; we peek
* the next event and check if it's a KeyPress for the same key
* and timestamp - and then ignore it if it matches the
* KeyRelease
*/
if (XPending (xevent->xkey.display))
{
XEvent next_event;
XPeekEvent (xevent->xkey.display, &next_event);
if (next_event.type == KeyPress &&
next_event.xkey.keycode == xevent->xkey.keycode &&
next_event.xkey.time == xevent->xkey.time)
{
res = FALSE;
break;
}
}
event->key.type = event->type = CLUTTER_KEY_RELEASE;
translate_key_event (backend, event, xevent);
break;

View File

@ -525,16 +525,21 @@ clutter_stage_x11_set_user_resizable (ClutterStageWindow *stage_window,
static void
update_wm_hints (ClutterStageX11 *stage_x11)
{
ClutterBackend *backend = clutter_get_default_backend ();
ClutterBackend *backend;
ClutterBackendX11 *backend_x11;
XWMHints wm_hints;
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
backend_x11 = CLUTTER_BACKEND_X11 (backend);
if (stage_x11->wm_state & STAGE_X11_WITHDRAWN)
return;
if (stage_x11->is_foreign_xwin)
return;
backend = clutter_get_default_backend ();
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
backend_x11 = CLUTTER_BACKEND_X11 (backend);
wm_hints.flags = StateHint;
wm_hints.initial_state = NormalState;
@ -573,7 +578,7 @@ clutter_stage_x11_show (ClutterStageWindow *stage_window,
if (stage_x11->xwin != None)
{
if (do_raise)
if (do_raise && !stage_x11->is_foreign_xwin)
{
CLUTTER_NOTE (BACKEND, "Raising stage[%lu]",
(unsigned long) stage_x11->xwin);
@ -599,7 +604,8 @@ clutter_stage_x11_show (ClutterStageWindow *stage_window,
clutter_actor_map (CLUTTER_ACTOR (stage_x11->wrapper));
XMapWindow (backend_x11->xdpy, stage_x11->xwin);
if (!stage_x11->is_foreign_xwin)
XMapWindow (backend_x11->xdpy, stage_x11->xwin);
}
}
@ -622,9 +628,8 @@ clutter_stage_x11_hide (ClutterStageWindow *stage_window)
clutter_actor_unmap (CLUTTER_ACTOR (stage_x11->wrapper));
XWithdrawWindow (backend_x11->xdpy,
stage_x11->xwin,
0);
if (!stage_x11->is_foreign_xwin)
XWithdrawWindow (backend_x11->xdpy, stage_x11->xwin, 0);
}
}
@ -765,8 +770,10 @@ clutter_x11_get_stage_from_window (Window win)
* along the lines of clutter_backend_x11_get_foreign_visual () or perhaps
* clutter_stage_x11_get_foreign_visual ()
*
* Return value: An XVisualInfo suitable for creating a foreign stage.
* You should free this using XFree.
* Return value: An XVisualInfo suitable for creating a foreign stage. Use
* XFree() to free the returned value instead
*
* Deprecated: 1.2: Use clutter_x11_get_visual_info() instead
*
* Since: 0.4
*/

View File

@ -213,37 +213,41 @@ try_alloc_shm (ClutterX11TexturePixmap *texture)
priv->shminfo.shmid = shmget (IPC_PRIVATE,
dummy_image->bytes_per_line
* dummy_image->height,
IPC_CREAT|0777);
IPC_CREAT | 0777);
if (priv->shminfo.shmid == -1)
goto failed_shmget;
priv->shminfo.shmaddr =
shmat (priv->shminfo.shmid, 0, 0);
if (priv->shminfo.shmaddr == (void *)-1)
priv->shminfo.shmaddr = shmat (priv->shminfo.shmid, 0, 0);
if (priv->shminfo.shmaddr == (void *) -1)
goto failed_shmat;
priv->shminfo.readOnly = False;
if (XShmAttach(dpy, &priv->shminfo) == 0)
if (XShmAttach (dpy, &priv->shminfo) == 0)
goto failed_xshmattach;
if (clutter_x11_untrap_x_errors ())
g_warning ("X Error: Failed to setup XShm");
XDestroyImage (dummy_image);
priv->have_shm = TRUE;
return TRUE;
failed_xshmattach:
g_warning ("XShmAttach failed");
shmdt(priv->shminfo.shmaddr);
shmdt (priv->shminfo.shmaddr);
failed_shmat:
g_warning ("shmat failed");
shmctl(priv->shminfo.shmid, IPC_RMID, 0);
shmctl (priv->shminfo.shmid, IPC_RMID, 0);
failed_shmget:
g_warning ("shmget failed");
XDestroyImage(dummy_image);
failed_image_create:
XDestroyImage (dummy_image);
failed_image_create:
if (clutter_x11_untrap_x_errors ())
g_warning ("X Error: Failed to setup XShm");

View File

@ -98,10 +98,14 @@ gint clutter_x11_untrap_x_errors (void);
Display *clutter_x11_get_default_display (void);
int clutter_x11_get_default_screen (void);
Window clutter_x11_get_root_window (void);
XVisualInfo *clutter_x11_get_visual_info (void);
void clutter_x11_set_display (Display * xdpy);
#ifndef CLUTTER_DISABLE_DEPRECATED
XVisualInfo *clutter_x11_get_stage_visual (ClutterStage *stage) G_GNUC_DEPRECATED;
#endif
Window clutter_x11_get_stage_window (ClutterStage *stage);
XVisualInfo *clutter_x11_get_stage_visual (ClutterStage *stage);
gboolean clutter_x11_set_stage_foreign (ClutterStage *stage,
Window xwindow);
@ -124,6 +128,9 @@ gboolean clutter_x11_has_xinput (void);
gboolean clutter_x11_has_composite_extension (void);
void clutter_X11_set_use_argb_visual (gboolean use_argb);
gboolean clutter_x11_get_use_argb_visual (void);
Time clutter_x11_get_current_event_time (void);
G_END_DECLS

View File

@ -12,7 +12,7 @@
# - increase clutter_interface_version to the next odd number
m4_define([clutter_major_version], [1])
m4_define([clutter_minor_version], [1])
m4_define([clutter_micro_version], [3])
m4_define([clutter_micro_version], [5])
m4_define([clutter_release_status],
[m4_if(m4_eval(clutter_micro_version % 2), [1], [git],
@ -42,7 +42,7 @@ m4_define([clutter_api_version], [1.0])
# clutter 1.2.10 -> 100 * 2 + 10 = 210, interface age = 4 -> 206
# ...
#
m4_define([clutter_interface_age], [1])
m4_define([clutter_interface_age], [0])
m4_define([clutter_binary_age], [m4_eval(100 * clutter_minor_version + clutter_micro_version)])
AC_PREREQ([2.59])
@ -638,19 +638,6 @@ AS_CASE([$with_json],
AC_SUBST(JSON_PREFIX)
AM_CONDITIONAL(LOCAL_JSON_GLIB, test "x$have_json" = "xno")
dnl === Dependencies, compiler flags and linker libraries =====================
CLUTTER_REQUIRES="cairo >= 1.4 pangocairo >= 1.20 gobject-2.0 >= 2.16 gthread-2.0 gmodule-no-export-2.0 $IMAGE_PC_FILES $BACKEND_PC_FILES $JSON_GLIB_PC"
PKG_CHECK_MODULES(CLUTTER_DEPS, [$CLUTTER_REQUIRES])
AC_SUBST(CLUTTER_REQUIRES)
CLUTTER_CFLAGS="$SDL_CFLAGS $EGL_CFLAGS $GLX_CFLAGS $OSX_CFLAGS $WIN32_CFLAGS $CLUTTER_DEPS_CFLAGS"
CLUTTER_LIBS="$SDL_LIBS $EGL_LIBS $X11_LIBS $GLX_LIBS $OSX_LIBS $WIN32_LIBS $CLUTTER_DEPS_LIBS"
AC_SUBST(CLUTTER_CFLAGS)
AC_SUBST(CLUTTER_LIBS)
dnl === Enable debug level ====================================================
m4_define([debug_default], [m4_if(m4_eval(clutter_minor_version % 2), [1], [yes], [minimum])])
@ -702,6 +689,62 @@ AS_CASE([$enable_cogl_debug],
AC_SUBST(COGL_DEBUG_CFLAGS)
m4_define([profile_default], [no])
AC_ARG_ENABLE(profile,
AC_HELP_STRING([--enable-profile=@<:@no/yes@:>@],
[Turn on profiling support. yes; All profiling probe points are compiled in and may be runtime enabled. no; No profiling support will built into clutter. @<:@default=no@:>@]),
[],
[enable_profile=profile_default])
AS_CASE([$enable_profile],
[yes], [
if test "x$GCC" = "xyes"; then
PKG_CHECK_MODULES([PROFILE_DEP], [uprof-0.2])
CLUTTER_PROFILE_CFLAGS=" -DCLUTTER_ENABLE_PROFILE -DCOGL_ENABLE_PROFILE $PROFILE_DEP_CFLAGS"
CLUTTER_PROFILE_LDFLAGS=" $PROFILE_DEP_LIBS"
if test "x$enable_debug" = "xyes"; then
CLUTTER_PROFILE_CFLAGS+=" -DUPROF_DEBUG"
fi
else
AC_MSG_ERROR([--enable-profile is currently only supported if using GCC])
fi
],
[no], [
CLUTTER_PROFILE_CFLAGS=""
CLUTTER_PROFILE_LDFLAGS=""
],
[*], [AC_MSG_ERROR([Invalid value for --enable-profile])]
)
AM_CONDITIONAL(PROFILE, test "x$enable_profile" != "xno")
AC_SUBST(CLUTTER_PROFILE_CFLAGS)
AC_SUBST(CLUTTER_PROFILE_LDFLAGS)
dnl === Coverage report =======================================================
AC_PATH_PROG([GCOV], [gcov], [enable_gcov=no])
AC_MSG_CHECKING([whether to build with gcov testing])
AC_ARG_ENABLE([gcov],
[AS_HELP_STRING([--enable-gcov],
[Whether to enable coverage testing (requires gcc
and gcov)])],
[],
[enable_gcov=no])
AS_IF([test "x$enable_gcov" = "xyes" && test "x$GCC" = "xyes"],
[
GCOV_CFLAGS="-g -O0 -fprofile-arcs -ftest-coverage"
GCOV_LDFLAGS="-lgcov"
]
)
AM_CONDITIONAL([GCOV_ENABLED], [test "x$enable_gcov" = "xyes"])
AC_SUBST([GCOV_CFLAGS])
AC_SUBST([GCOV_LDFLAGS])
AC_MSG_RESULT([$enable_gcov])
dnl === Enable strict compiler flags ==========================================
# use strict compiler flags only on development releases
@ -723,6 +766,19 @@ AS_IF([test "x$enable_maintainer_flags" = "xyes" && test "x$GCC" = "xyes"],
AC_SUBST(MAINTAINER_CFLAGS)
dnl === Dependencies, compiler flags and linker libraries =====================
CLUTTER_REQUIRES="cairo >= 1.4 pangocairo >= 1.20 gobject-2.0 >= 2.16 gthread-2.0 gmodule-no-export-2.0 $IMAGE_PC_FILES $BACKEND_PC_FILES $JSON_GLIB_PC"
PKG_CHECK_MODULES(CLUTTER_DEPS, [$CLUTTER_REQUIRES])
AC_SUBST(CLUTTER_REQUIRES)
CLUTTER_CFLAGS="$SDL_CFLAGS $EGL_CFLAGS $GLX_CFLAGS $OSX_CFLAGS $WIN32_CFLAGS $CLUTTER_DEPS_CFLAGS $CLUTTER_PROFILE_CFLAGS"
CLUTTER_LIBS="$SDL_LIBS $EGL_LIBS $X11_LIBS $GLX_LIBS $OSX_LIBS $WIN32_LIBS $CLUTTER_DEPS_LIBS $CLUTTER_PROFILE_LDFLAGS"
AC_SUBST(CLUTTER_CFLAGS)
AC_SUBST(CLUTTER_LIBS)
dnl === GObject-Introspection check ===========================================
GOBJECT_INTROSPECTION_CHECK([0.6.4])
@ -876,6 +932,8 @@ echo " • Compiler options:"
echo " Clutter debug level: ${enable_debug}"
echo " COGL debug level: ${enable_cogl_debug}"
echo " Compiler flags: ${MAINTAINER_CFLAGS}"
echo " Profiling enabled: ${enable_profile}"
echo " Enable coverage tests: ${enable_gcov}"
# Documentation
echo ""

View File

@ -4,7 +4,7 @@ TARGET_DIR = $(HTML_DIR)/clutter-cookbook
HTML_FILES = $(srcdir)/html/*.html
IMAGE_FILES = $(srcdir)/images/*.png
EXTRA_DIST = $(IMAGE_FILES) clutter-cookbook.xml.in
EXTRA_DIST = clutter-cookbook.xml.in
CLEANFILES = \
pdf-build.stamp \

View File

@ -9,6 +9,10 @@ clutter_media_set_playing
clutter_media_get_playing
clutter_media_set_progress
clutter_media_get_progress
clutter_media_set_subtitle_uri
clutter_media_get_subtitle_uri
clutter_media_set_subtitle_font_name
clutter_media_get_subtitle_font_name
clutter_media_set_audio_volume
clutter_media_get_audio_volume
clutter_media_get_can_seek
@ -352,6 +356,8 @@ clutter_actor_lower
clutter_actor_raise_top
clutter_actor_lower_bottom
clutter_actor_get_stage
clutter_actor_push_internal
clutter_actor_pop_internal
<SUBSECTION>
clutter_actor_set_depth
@ -414,6 +420,8 @@ clutter_actor_box_get_size
clutter_actor_box_get_area
clutter_actor_box_contains
clutter_actor_box_from_vertices
clutter_actor_box_clamp_to_pixel
clutter_actor_box_interpolate
<SUBSECTION>
ClutterVertex
@ -522,6 +530,8 @@ clutter_stage_get_key_focus
clutter_stage_read_pixels
clutter_stage_set_throttle_motion_events
clutter_stage_get_throttle_motion_events
clutter_stage_set_use_alpha
clutter_stage_get_use_alpha
<SUBSECTION>
ClutterPerspective
@ -977,6 +987,7 @@ clutter_input_device_get_device_type
<SUBSECTION>
clutter_get_current_event_time
clutter_get_current_event
<SUBSECTION Standard>
CLUTTER_TYPE_EVENT
@ -1017,7 +1028,6 @@ clutter_set_font_flags
clutter_get_font_flags
clutter_get_font_map
ClutterTextDirection
clutter_set_default_text_direction
clutter_get_default_text_direction
<SUBSECTION>
@ -1073,6 +1083,9 @@ clutter_x11_trap_x_errors
clutter_x11_untrap_x_errors
clutter_x11_has_composite_extension
clutter_x11_get_current_event_time
clutter_x11_set_use_argb_visual
clutter_x11_get_use_argb_visual
clutter_x11_get_visual_info
<SUBSECTION>
ClutterX11FilterFunc
@ -1767,6 +1780,11 @@ clutter_layout_manager_child_get_property
clutter_layout_manager_find_child_property
clutter_layout_manager_list_child_properties
<SUBSECTION>
clutter_layout_manager_begin_animation
clutter_layout_manager_end_animation
clutter_layout_manager_get_animation_progress
<SUBSECTION Standard>
CLUTTER_TYPE_LAYOUT_MANAGER
CLUTTER_LAYOUT_MANAGER
@ -1836,6 +1854,9 @@ clutter_box_get_color
<SUBSECTION>
clutter_box_pack
clutter_box_packv
clutter_box_pack_after
clutter_box_pack_before
clutter_box_pack_at
<SUBSECTION Standard>
CLUTTER_TYPE_BOX
@ -1928,6 +1949,14 @@ clutter_box_layout_get_expand
clutter_box_layout_set_fill
clutter_box_layout_get_fill
<SUBSECTION>
clutter_box_layout_set_use_animations
clutter_box_layout_get_use_animations
clutter_box_layout_set_easing_duration
clutter_box_layout_get_easing_duration
clutter_box_layout_set_easing_mode
clutter_box_layout_get_easing_mode
<SUBSECTION Standard>
CLUTTER_TYPE_BOX_LAYOUT
CLUTTER_BOX_LAYOUT

View File

@ -24,6 +24,8 @@ test_conformance_SOURCES = \
test-cogl-viewport.c \
test-cogl-offscreen.c \
test-cogl-readpixels.c \
test-cogl-multitexture.c \
test-cogl-texture-mipmaps.c \
test-path.c \
test-pick.c \
test-clutter-rectangle.c \
@ -41,6 +43,7 @@ test_conformance_SOURCES = \
test-texture-fbo.c \
test-cogl-sub-texture.c \
test-script-parser.c \
test-actor-destroy.c \
$(NULL)
# For convenience, this provides a way to easily run individual unit tests:

View File

@ -0,0 +1,168 @@
#include <clutter/clutter.h>
#include "test-conform-common.h"
#define TEST_TYPE_DESTROY (test_destroy_get_type ())
#define TEST_DESTROY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_DESTROY, TestDestroy))
#define TEST_IS_DESTROY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_DESTROY))
typedef struct _TestDestroy TestDestroy;
typedef struct _TestDestroyClass TestDestroyClass;
struct _TestDestroy
{
ClutterActor parent_instance;
ClutterActor *bg;
ClutterActor *label;
ClutterActor *tex;
GList *children;
};
struct _TestDestroyClass
{
ClutterActorClass parent_class;
};
static void clutter_container_init (ClutterContainerIface *iface);
G_DEFINE_TYPE_WITH_CODE (TestDestroy, test_destroy, CLUTTER_TYPE_ACTOR,
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
clutter_container_init));
static void
test_destroy_add (ClutterContainer *container,
ClutterActor *actor)
{
TestDestroy *self = TEST_DESTROY (container);
if (g_test_verbose ())
g_print ("Adding '%s' (type:%s)\n",
clutter_actor_get_name (actor),
G_OBJECT_TYPE_NAME (actor));
self->children = g_list_prepend (self->children, actor);
clutter_actor_set_parent (actor, CLUTTER_ACTOR (container));
}
static void
test_destroy_remove (ClutterContainer *container,
ClutterActor *actor)
{
TestDestroy *self = TEST_DESTROY (container);
if (g_test_verbose ())
g_print ("Removing '%s' (type:%s)\n",
clutter_actor_get_name (actor),
G_OBJECT_TYPE_NAME (actor));
g_assert (actor != self->bg);
g_assert (actor != self->label);
if (!g_list_find (self->children, actor))
g_assert (actor == self->tex);
else
self->children = g_list_remove (self->children, actor);
clutter_actor_unparent (actor);
}
static void
clutter_container_init (ClutterContainerIface *iface)
{
iface->add = test_destroy_add;
iface->remove = test_destroy_remove;
}
static void
test_destroy_destroy (ClutterActor *self)
{
TestDestroy *test = TEST_DESTROY (self);
if (test->bg != NULL)
{
if (g_test_verbose ())
g_print ("Destroying '%s' (type:%s)\n",
clutter_actor_get_name (test->bg),
G_OBJECT_TYPE_NAME (test->bg));
clutter_actor_destroy (test->bg);
test->bg = NULL;
}
if (test->label != NULL)
{
if (g_test_verbose ())
g_print ("Destroying '%s' (type:%s)\n",
clutter_actor_get_name (test->label),
G_OBJECT_TYPE_NAME (test->label));
clutter_actor_destroy (test->label);
test->label = NULL;
}
if (test->tex != NULL)
{
if (g_test_verbose ())
g_print ("Destroying '%s' (type:%s)\n",
clutter_actor_get_name (test->tex),
G_OBJECT_TYPE_NAME (test->tex));
clutter_actor_destroy (test->tex);
test->tex = NULL;
}
g_list_foreach (test->children, (GFunc) clutter_actor_destroy, NULL);
g_list_free (test->children);
test->children = NULL;
if (CLUTTER_ACTOR_CLASS (test_destroy_parent_class)->destroy)
CLUTTER_ACTOR_CLASS (test_destroy_parent_class)->destroy (self);
}
static void
test_destroy_class_init (TestDestroyClass *klass)
{
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
actor_class->destroy = test_destroy_destroy;
}
static void
test_destroy_init (TestDestroy *self)
{
clutter_actor_push_internal ();
if (g_test_verbose ())
g_print ("Adding internal children...\n");
self->bg = clutter_rectangle_new ();
clutter_actor_set_parent (self->bg, CLUTTER_ACTOR (self));
clutter_actor_set_name (self->bg, "Background");
self->label = clutter_text_new ();
clutter_actor_set_parent (self->label, CLUTTER_ACTOR (self));
clutter_actor_set_name (self->label, "Label");
clutter_actor_pop_internal ();
self->tex = clutter_texture_new ();
clutter_actor_set_parent (self->tex, CLUTTER_ACTOR (self));
clutter_actor_set_name (self->tex, "Texture");
}
void
test_actor_destruction (TestConformSimpleFixture *fixture,
gconstpointer dummy)
{
ClutterActor *test = g_object_new (TEST_TYPE_DESTROY, NULL);
ClutterActor *child = clutter_rectangle_new ();
if (g_test_verbose ())
g_print ("Adding external child...\n");
clutter_actor_set_name (child, "Child");
clutter_container_add_actor (CLUTTER_CONTAINER (test), child);
clutter_actor_destroy (test);
}

View File

@ -61,10 +61,21 @@ test_units_string (TestConformSimpleFixture *fixture,
ClutterUnits units;
gchar *string;
g_assert (clutter_units_from_string (&units, "") == FALSE);
g_assert (clutter_units_from_string (&units, "10") == TRUE);
g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_PIXEL);
g_assert_cmpfloat (clutter_units_get_unit_value (&units), ==, 10);
g_assert (clutter_units_from_string (&units, "10 px") == TRUE);
g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_PIXEL);
g_assert (clutter_units_from_string (&units, "10 mm") == TRUE);
g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_MM);
g_assert (clutter_units_from_string (&units, "10 cm") == TRUE);
g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_CM);
g_assert (clutter_units_from_string (&units, "10 ") == TRUE);
g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_PIXEL);
g_assert_cmpfloat (clutter_units_get_unit_value (&units), ==, 10);

View File

@ -0,0 +1,209 @@
#include <clutter/clutter.h>
#include <cogl/cogl.h>
#include <string.h>
#include "test-conform-common.h"
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
#define QUAD_WIDTH 20
#define RED 0
#define GREEN 1
#define BLUE 2
#define ALPHA 3
typedef struct _TestState
{
guint frame;
} TestState;
static void
assert_region_color (int x,
int y,
int width,
int height,
guint8 red,
guint8 green,
guint8 blue,
guint8 alpha)
{
guint8 *data = g_malloc0 (width * height * 4);
cogl_read_pixels (x, y, width, height,
COGL_READ_PIXELS_COLOR_BUFFER,
COGL_PIXEL_FORMAT_RGBA_8888,
data);
for (y = 0; y < height; y++)
for (x = 0; x < width; x++)
{
guint8 *pixel = &data[y * width * 4 + x * 4];
#if 1
g_assert (pixel[RED] == red &&
pixel[GREEN] == green &&
pixel[BLUE] == blue &&
pixel[ALPHA] == alpha);
#endif
}
g_free (data);
}
/* Creates a texture divided into 4 quads with colors arranged as follows:
* (The same value are used in all channels for each texel)
*
* |-----------|
* |0x11 |0x00 |
* |+ref | |
* |-----------|
* |0x00 |0x33 |
* | |+ref |
* |-----------|
*
*
*/
static CoglHandle
make_texture (guchar ref)
{
int x;
int y;
guchar *tex_data, *p;
CoglHandle tex;
guchar val;
tex_data = g_malloc (QUAD_WIDTH * QUAD_WIDTH * 16);
for (y = 0; y < QUAD_WIDTH * 2; y++)
for (x = 0; x < QUAD_WIDTH * 2; x++)
{
p = tex_data + (QUAD_WIDTH * 8 * y) + x * 4;
if (x < QUAD_WIDTH && y < QUAD_WIDTH)
val = 0x11 + ref;
else if (x >= QUAD_WIDTH && y >= QUAD_WIDTH)
val = 0x33 + ref;
else
val = 0x00;
p[0] = p[1] = p[2] = p[3] = val;
}
/* Note: we don't use COGL_PIXEL_FORMAT_ANY for the internal format here
* since we don't want to allow Cogl to premultiply our data. */
tex = cogl_texture_new_from_data (QUAD_WIDTH * 2,
QUAD_WIDTH * 2,
COGL_TEXTURE_NONE,
COGL_PIXEL_FORMAT_RGBA_8888,
COGL_PIXEL_FORMAT_RGBA_8888,
QUAD_WIDTH * 8,
tex_data);
g_free (tex_data);
return tex;
}
static void
on_paint (ClutterActor *actor, TestState *state)
{
CoglHandle tex0, tex1;
CoglHandle material;
gboolean status;
GError *error = NULL;
float tex_coords[] = {
0, 0, 0.5, 0.5, /* tex0 */
0.5, 0.5, 1, 1 /* tex1 */
};
/* XXX:
* We haven't always had good luck with GL drivers implementing glReadPixels
* reliably and skipping the first two frames improves our chances... */
if (state->frame++ <= 2)
{
g_usleep (G_USEC_PER_SEC);
return;
}
tex0 = make_texture (0x00);
tex1 = make_texture (0x11);
material = cogl_material_new ();
/* An arbitrary color which should be replaced by the first texture layer */
cogl_material_set_color4ub (material, 0x80, 0x80, 0x80, 0x80);
cogl_material_set_blend (material, "RGBA = ADD (SRC_COLOR, 0)", NULL);
cogl_material_set_layer (material, 0, tex0);
cogl_material_set_layer_combine (material, 0,
"RGBA = REPLACE (TEXTURE)", NULL);
cogl_material_set_layer (material, 1, tex1);
status = cogl_material_set_layer_combine (material, 1,
"RGBA = ADD (PREVIOUS, TEXTURE)",
&error);
if (!status)
{
/* It's not strictly a test failure; you need a more capable GPU or
* driver to test this texture combine string. */
g_debug ("Failed to setup texture combine string "
"RGBA = ADD (PREVIOUS, TEXTURE): %s",
error->message);
}
cogl_set_source (material);
cogl_rectangle_with_multitexture_coords (0, 0, QUAD_WIDTH, QUAD_WIDTH,
tex_coords, 8);
cogl_material_unref (material);
cogl_handle_unref (tex0);
cogl_handle_unref (tex1);
/* See what we got... */
assert_region_color (0, 0, QUAD_WIDTH, QUAD_WIDTH,
0x55, 0x55, 0x55, 0x55);
/* Comment this out if you want visual feedback for what this test paints */
#if 1
clutter_main_quit ();
#endif
}
static gboolean
queue_redraw (gpointer stage)
{
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
return TRUE;
}
void
test_cogl_multitexture (TestConformSimpleFixture *fixture,
gconstpointer data)
{
TestState state;
ClutterActor *stage;
ClutterActor *group;
guint idle_source;
state.frame = 0;
stage = clutter_stage_get_default ();
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
group = clutter_group_new ();
clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
/* We force continuous redrawing of the stage, since we need to skip
* the first few frames, and we wont be doing anything else that
* will trigger redrawing. */
idle_source = g_idle_add (queue_redraw, stage);
g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
clutter_actor_show_all (stage);
clutter_main ();
g_source_remove (idle_source);
if (g_test_verbose ())
g_print ("OK\n");
}

View File

@ -0,0 +1,147 @@
#include <clutter/clutter.h>
#include <cogl/cogl.h>
#include <string.h>
#include "test-conform-common.h"
static const ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff };
#define TEX_SIZE 64
typedef struct _TestState
{
guint frame;
} TestState;
/* Creates a texture where the pixels are evenly divided between
selecting just one of the R,G and B components */
static CoglHandle
make_texture (void)
{
guchar *tex_data = g_malloc (TEX_SIZE * TEX_SIZE * 3), *p = tex_data;
CoglHandle tex;
int x, y;
for (y = 0; y < TEX_SIZE; y++)
for (x = 0; x < TEX_SIZE; x++)
{
memset (p, 0, 3);
/* Set one of the components to full. The components should be
evenly represented so that each gets a third of the
texture */
p[(p - tex_data) / (TEX_SIZE * TEX_SIZE * 3 / 3)] = 255;
p += 3;
}
tex = cogl_texture_new_from_data (TEX_SIZE, TEX_SIZE, COGL_TEXTURE_NONE,
COGL_PIXEL_FORMAT_RGB_888,
COGL_PIXEL_FORMAT_ANY,
TEX_SIZE * 3,
tex_data);
g_free (tex_data);
return tex;
}
static void
on_paint (ClutterActor *actor, TestState *state)
{
CoglHandle tex;
CoglHandle material;
guint8 pixels[8];
/* XXX:
* We haven't always had good luck with GL drivers implementing glReadPixels
* reliably and skipping the first two frames improves our chances... */
if (state->frame++ <= 2)
{
g_usleep (G_USEC_PER_SEC);
return;
}
tex = make_texture ();
material = cogl_material_new ();
cogl_material_set_layer (material, 0, tex);
cogl_handle_unref (tex);
/* Render a 1x1 pixel quad without mipmaps */
cogl_set_source (material);
cogl_material_set_layer_filters (material, 0,
COGL_MATERIAL_FILTER_NEAREST,
COGL_MATERIAL_FILTER_NEAREST);
cogl_rectangle (0, 0, 1, 1);
/* Then with mipmaps */
cogl_material_set_layer_filters (material, 0,
COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST,
COGL_MATERIAL_FILTER_NEAREST);
cogl_rectangle (1, 0, 2, 1);
cogl_material_unref (material);
/* Read back the two pixels we rendered */
cogl_read_pixels (0, 0, 2, 1,
COGL_READ_PIXELS_COLOR_BUFFER,
COGL_PIXEL_FORMAT_RGBA_8888,
pixels);
/* The first pixel should be just one of the colors from the
texture. It doesn't matter which one */
g_assert ((pixels[0] == 255 && pixels[1] == 0 && pixels[2] == 0) ||
(pixels[0] == 0 && pixels[1] == 255 && pixels[2] == 0) ||
(pixels[0] == 0 && pixels[1] == 0 && pixels[2] == 255));
/* The second pixel should be more or less the average of all of the
pixels in the texture. Each component gets a third of the image
so each component should be approximately 255/3 */
g_assert (ABS (pixels[4] - 255 / 3) <= 3 &&
ABS (pixels[5] - 255 / 3) <= 3 &&
ABS (pixels[6] - 255 / 3) <= 3);
/* Comment this out if you want visual feedback for what this test paints */
#if 1
clutter_main_quit ();
#endif
}
static gboolean
queue_redraw (gpointer stage)
{
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
return TRUE;
}
void
test_cogl_texture_mipmaps (TestConformSimpleFixture *fixture,
gconstpointer data)
{
TestState state;
ClutterActor *stage;
ClutterActor *group;
guint idle_source;
state.frame = 0;
stage = clutter_stage_get_default ();
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
group = clutter_group_new ();
clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
/* We force continuous redrawing of the stage, since we need to skip
* the first few frames, and we wont be doing anything else that
* will trigger redrawing. */
idle_source = g_idle_add (queue_redraw, stage);
g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
clutter_actor_show_all (stage);
clutter_main ();
g_source_remove (idle_source);
if (g_test_verbose ())
g_print ("OK\n");
}

View File

@ -166,3 +166,60 @@ test_color_to_string (TestConformSimpleFixture *fixture,
g_free (str);
}
void
test_color_operators (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterColor op1, op2;
ClutterColor res;
clutter_color_from_pixel (&op1, 0xff0000ff);
g_assert_cmpint (op1.red, ==, 0xff);
g_assert_cmpint (op1.green, ==, 0);
g_assert_cmpint (op1.blue, ==, 0);
g_assert_cmpint (op1.alpha, ==, 0xff);
clutter_color_from_pixel (&op2, 0x00ff00ff);
g_assert_cmpint (op2.red, ==, 0);
g_assert_cmpint (op2.green, ==, 0xff);
g_assert_cmpint (op2.blue, ==, 0);
g_assert_cmpint (op2.alpha, ==, 0xff);
if (g_test_verbose ())
g_print ("Adding %x, %x; expected result: %x\n",
clutter_color_to_pixel (&op1),
clutter_color_to_pixel (&op2),
0xffff00ff);
clutter_color_add (&op1, &op2, &res);
g_assert_cmpint (clutter_color_to_pixel (&res), ==, 0xffff00ff);
if (g_test_verbose ())
g_print ("Checking alpha channel on color add\n");
op1.alpha = 0xdd;
op2.alpha = 0xcc;
clutter_color_add (&op1, &op2, &res);
g_assert_cmpint (clutter_color_to_pixel (&res), ==, 0xffff00dd);
clutter_color_from_pixel (&op1, 0xffffffff);
clutter_color_from_pixel (&op2, 0xff00ffff);
if (g_test_verbose ())
g_print ("Subtracting %x, %x; expected result: %x\n",
clutter_color_to_pixel (&op1),
clutter_color_to_pixel (&op2),
0x00ff00ff);
clutter_color_subtract (&op1, &op2, &res);
g_assert_cmpint (clutter_color_to_pixel (&res), ==, 0x00ff00ff);
if (g_test_verbose ())
g_print ("Checking alpha channel on color subtract\n");
op1.alpha = 0xdd;
op2.alpha = 0xcc;
clutter_color_subtract (&op1, &op2, &res);
g_assert_cmpint (clutter_color_to_pixel (&res), ==, 0x00ff00cc);
}

View File

@ -152,6 +152,7 @@ main (int argc, char **argv)
TEST_CONFORM_SIMPLE ("/binding-pool", test_binding_pool);
TEST_CONFORM_SIMPLE ("/actor", test_anchors);
TEST_CONFORM_SIMPLE ("/actor", test_actor_destruction);
TEST_CONFORM_SIMPLE ("/model", test_list_model_populate);
TEST_CONFORM_SIMPLE ("/model", test_list_model_iterate);
@ -160,6 +161,7 @@ main (int argc, char **argv)
TEST_CONFORM_SIMPLE ("/color", test_color_from_string);
TEST_CONFORM_SIMPLE ("/color", test_color_to_string);
TEST_CONFORM_SIMPLE ("/color", test_color_hls_roundtrip);
TEST_CONFORM_SIMPLE ("/color", test_color_operators);
TEST_CONFORM_SIMPLE ("/units", test_units_constructors);
TEST_CONFORM_SIMPLE ("/units", test_units_string);
@ -185,6 +187,8 @@ main (int argc, char **argv)
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_readpixels);
TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_npot_texture);
TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_multitexture);
TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_texture_mipmaps);
TEST_CONFORM_SIMPLE ("/cogl/vertex-buffer", test_cogl_vertex_buffer_contiguous);
TEST_CONFORM_SIMPLE ("/cogl/vertex-buffer", test_cogl_vertex_buffer_interleved);

View File

@ -10,5 +10,5 @@
"width" : 100,
"height" : 16,
"color" : "white"
},
}
}

View File

@ -127,7 +127,6 @@ test_bin_layout_main (int argc, char *argv[])
clutter_actor_lower_bottom (rect);
clutter_actor_set_name (rect, "background");
{
ClutterActor *tex;
GError *error;

View File

@ -29,9 +29,12 @@
"Press v\t\342\236\236\tSwitch horizontal/vertical\n" \
"Press p\t\342\236\236\tSwitch pack start/end\n" \
"Press s\t\342\236\236\tIncrement spacing (up to 12px)\n" \
"Press a\t\342\236\236\tSwitch animations on/off\n" \
"Press q\t\342\236\236\tQuit"
static ClutterActor *hover_actor = NULL;
static ClutterActor *box = NULL;
static ClutterActor *label = NULL;
static guint last_index = 0;
static void
@ -88,7 +91,7 @@ leave_event (ClutterActor *actor,
static gboolean
button_release_event (ClutterActor *actor,
ClutterEvent *event,
ClutterBoxLayout *box)
ClutterBoxLayout *layout)
{
gboolean xfill, yfill;
ClutterBoxAlignment xalign, yalign;
@ -98,14 +101,14 @@ button_release_event (ClutterActor *actor,
if (button == 1)
{
clutter_box_layout_get_fill (box, actor, &xfill, &yfill);
clutter_box_layout_set_fill (box, actor,
clutter_box_layout_get_fill (layout, actor, &xfill, &yfill);
clutter_box_layout_set_fill (layout, actor,
xfill ? FALSE : TRUE,
yfill ? FALSE : TRUE);
}
else
{
clutter_box_layout_get_alignment (box, actor, &xalign, &yalign);
clutter_box_layout_get_alignment (layout, actor, &xalign, &yalign);
if (xalign < 2)
xalign += 1;
@ -117,14 +120,14 @@ button_release_event (ClutterActor *actor,
else
yalign = 0;
clutter_box_layout_set_alignment (box, actor, xalign, yalign);
clutter_box_layout_set_alignment (layout, actor, xalign, yalign);
}
return TRUE;
}
static void
add_actor (ClutterBoxLayout *box,
add_actor (ClutterBoxLayout *layout,
guint index_)
{
ClutterActor *rect;
@ -138,7 +141,7 @@ add_actor (ClutterBoxLayout *box,
rect = clutter_rectangle_new_with_color (&color);
clutter_actor_set_size (rect, 32, 64);
clutter_box_layout_pack (box, rect, expand,
clutter_box_layout_pack (layout, rect, expand,
FALSE, /* x-fill */
FALSE, /* y-fill */
CLUTTER_BOX_ALIGNMENT_CENTER,
@ -152,7 +155,7 @@ add_actor (ClutterBoxLayout *box,
g_signal_connect (rect, "leave-event", G_CALLBACK (leave_event), NULL);
g_signal_connect (rect, "button-release-event",
G_CALLBACK (button_release_event),
box);
layout);
expand = !expand;
}
@ -167,6 +170,11 @@ key_release_cb (ClutterActor *actor,
switch (clutter_event_get_key_symbol (event))
{
case CLUTTER_a:
toggle = clutter_box_layout_get_use_animations (layout);
clutter_box_layout_set_use_animations (layout, !toggle);
break;
case CLUTTER_v:
toggle = clutter_box_layout_get_vertical (layout);
clutter_box_layout_set_vertical (layout, !toggle);
@ -207,18 +215,21 @@ static void
stage_size_changed_cb (ClutterActor *stage,
const ClutterActorBox *allocation,
ClutterAllocationFlags flags,
ClutterActor *box)
gpointer dummy G_GNUC_UNUSED)
{
gfloat width, height;
clutter_actor_box_get_size (allocation, &width, &height);
clutter_actor_set_size (box, width - 100, height - 100);
clutter_actor_set_y (label,
height - clutter_actor_get_height (label) - 8);
}
G_MODULE_EXPORT int
test_box_layout_main (int argc, char *argv[])
{
ClutterActor *stage, *box, *label;
ClutterActor *stage;
ClutterLayoutManager *layout;
gint i;
@ -242,7 +253,7 @@ test_box_layout_main (int argc, char *argv[])
layout);
g_signal_connect (stage, "allocation-changed",
G_CALLBACK (stage_size_changed_cb),
box);
NULL);
label = clutter_text_new_with_text ("Sans 12px", INSTRUCTIONS);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), label);

View File

@ -31,6 +31,7 @@ typedef struct SuperOH
} SuperOH;
static gint n_hands = NHANDS;
static gint use_alpha = 255;
static GOptionEntry super_oh_entries[] = {
{
@ -39,6 +40,12 @@ static GOptionEntry super_oh_entries[] = {
G_OPTION_ARG_INT, &n_hands,
"Number of hands", "HANDS"
},
{
"use-alpha", 'a',
0,
G_OPTION_ARG_INT, &use_alpha,
"Stage opacity", "VALUE"
},
{ NULL }
};
@ -205,6 +212,12 @@ test_paint_wrapper_main (int argc, char *argv[])
stage = clutter_stage_get_default ();
clutter_actor_set_size (stage, 800, 600);
if (use_alpha != 255)
{
clutter_stage_set_use_alpha (CLUTTER_STAGE (stage), TRUE);
clutter_actor_set_opacity (stage, use_alpha);
}
clutter_stage_set_title (CLUTTER_STAGE (stage), "Paint Test");
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);

View File

@ -3,33 +3,13 @@
#include <gmodule.h>
#include <clutter/clutter.h>
#define FONT "Mono Bold 22px"
#define FONT "Mono Bold 24px"
static gchar *runes =
static const gchar *runes =
"ᚠᛇᚻ᛫ᛒᛦᚦ᛫ᚠᚱᚩᚠᚢᚱ᛫ᚠᛁᚱᚪ᛫ᚷᛖᚻᚹᛦᛚᚳᚢᛗ\n"
"ᛋᚳᛖᚪᛚ᛫ᚦᛖᚪᚻ᛫ᛗᚪᚾᚾᚪ᛫ᚷᛖᚻᚹᛦᛚᚳ᛫ᛗᛁᚳᛚᚢᚾ᛫ᚻᛦᛏ᛫ᛞᚫᛚᚪᚾ\n"
"ᚷᛁᚠ᛫ᚻᛖ᛫ᚹᛁᛚᛖ᛫ᚠᚩᚱ᛫ᛞᚱᛁᚻᛏᚾᛖ᛫ᛞᚩᛗᛖᛋ᛫ᚻᛚᛇᛏᚪᚾ᛬\n";
static void
cursor_event (ClutterText *text,
ClutterGeometry *geometry)
{
gint y;
y = clutter_actor_get_y (CLUTTER_ACTOR (text));
if (y + geometry->y < 50)
{
clutter_actor_set_y (CLUTTER_ACTOR (text), y + 100);
}
else if (y + geometry->y > 720)
{
clutter_actor_set_y (CLUTTER_ACTOR (text), y - 100);
}
}
G_MODULE_EXPORT gint
test_text_main (gint argc,
gchar **argv)
@ -78,8 +58,6 @@ test_text_main (gint argc,
else
clutter_text_set_text (CLUTTER_TEXT (text), runes);
g_signal_connect (text, "cursor-event", G_CALLBACK (cursor_event), NULL);
clutter_actor_set_size (stage, 1024, 768);
clutter_actor_show (stage);