Merge gobject-branch into trunk
authorMatthew Allum <mallum@openedhand.com>
Mon, 29 May 2006 08:59:36 +0000 (08:59 +0000)
committerMatthew Allum <mallum@openedhand.com>
Mon, 29 May 2006 08:59:36 +0000 (08:59 +0000)
123 files changed:
COPYING [new file with mode: 0644]
ChangeLog
Makefile.am
README
TODO [new file with mode: 0644]
autogen.sh [moved from bootstrap-autotools.sh with 81% similarity]
bindings/ChangeLog [new file with mode: 0644]
bindings/Makefile.am [new file with mode: 0644]
bindings/python/Makefile.am [new file with mode: 0644]
bindings/python/clutter-base-types.defs [new file with mode: 0644]
bindings/python/clutter-base.defs [new file with mode: 0644]
bindings/python/clutter.override [new file with mode: 0644]
bindings/python/cluttermodule.c [new file with mode: 0644]
clutter.pc.in [new file with mode: 0644]
clutter/Makefile.am
clutter/cltr-animator.c [deleted file]
clutter/cltr-animator.h [deleted file]
clutter/cltr-button.c [deleted file]
clutter/cltr-button.h [deleted file]
clutter/cltr-core.c [deleted file]
clutter/cltr-core.h [deleted file]
clutter/cltr-events.c [deleted file]
clutter/cltr-events.h [deleted file]
clutter/cltr-glu.c [deleted file]
clutter/cltr-glu.h [deleted file]
clutter/cltr-label.c [deleted file]
clutter/cltr-label.h [deleted file]
clutter/cltr-list.c [deleted file]
clutter/cltr-list.h [deleted file]
clutter/cltr-overlay.c [deleted file]
clutter/cltr-overlay.h [deleted file]
clutter/cltr-photo-grid.c [deleted file]
clutter/cltr-photo-grid.h [deleted file]
clutter/cltr-private.h [deleted file]
clutter/cltr-scratch.c [deleted file]
clutter/cltr-scratch.h [deleted file]
clutter/cltr-texture.c [deleted file]
clutter/cltr-texture.h [deleted file]
clutter/cltr-video.c [deleted file]
clutter/cltr-video.h [deleted file]
clutter/cltr-widget.c [deleted file]
clutter/cltr-widget.h [deleted file]
clutter/cltr-window.c [deleted file]
clutter/cltr-window.h [deleted file]
clutter/cltr.h [deleted file]
clutter/clutter-clone-texture.c [new file with mode: 0644]
clutter/clutter-clone-texture.h [new file with mode: 0644]
clutter/clutter-color.c [new file with mode: 0644]
clutter/clutter-color.h [new file with mode: 0644]
clutter/clutter-element.c [new file with mode: 0644]
clutter/clutter-element.h [new file with mode: 0644]
clutter/clutter-event.c [new file with mode: 0644]
clutter/clutter-event.h [new file with mode: 0644]
clutter/clutter-group.c [new file with mode: 0644]
clutter/clutter-group.h [new file with mode: 0644]
clutter/clutter-keysyms.h [new file with mode: 0644]
clutter/clutter-label.c [new file with mode: 0644]
clutter/clutter-label.h [new file with mode: 0644]
clutter/clutter-main.c [new file with mode: 0644]
clutter/clutter-main.h [new file with mode: 0644]
clutter/clutter-marshal.list [new file with mode: 0644]
clutter/clutter-private.h [new file with mode: 0644]
clutter/clutter-rectangle.c [new file with mode: 0644]
clutter/clutter-rectangle.h [new file with mode: 0644]
clutter/clutter-stage.c [new file with mode: 0644]
clutter/clutter-stage.h [new file with mode: 0644]
clutter/clutter-texture.c [new file with mode: 0644]
clutter/clutter-texture.h [new file with mode: 0644]
clutter/clutter-timeline.c [new file with mode: 0644]
clutter/clutter-timeline.h [new file with mode: 0644]
clutter/clutter-util.c [new file with mode: 0644]
clutter/clutter-util.h [new file with mode: 0644]
clutter/clutter-video-texture.c [new file with mode: 0644]
clutter/clutter-video-texture.h [new file with mode: 0644]
clutter/clutter.h [new file with mode: 0644]
clutter/fonts.c [deleted file]
clutter/fonts.h [deleted file]
clutter/pixbuf.c [deleted file]
clutter/pixbuf.h [deleted file]
clutter/util.c [deleted file]
clutter/util.h [deleted file]
configure.ac
doc/Makefile.am [new file with mode: 0644]
doc/reference/ChangeLog [new file with mode: 0644]
doc/reference/Makefile.am [new file with mode: 0644]
doc/reference/clutter-0.0-sections.txt [new file with mode: 0644]
doc/reference/clutter.types [new file with mode: 0644]
doc/reference/tmpl/clutter-0.0-unused.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter-clone-texture.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter-color.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter-element.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter-enum-types.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter-event.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter-group.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter-keysyms.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter-label.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter-main.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter-marshal.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter-rectangle.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter-stage.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter-texture.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter-timeline.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter-util.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter-video-texture.sgml [new file with mode: 0644]
doc/reference/tmpl/clutter.sgml [new file with mode: 0644]
examples/Makefile.am
examples/clutter-logo-800x600.png
examples/photos.c [deleted file]
examples/player.c [deleted file]
examples/rects.py [new file with mode: 0755]
examples/redhand.png [new file with mode: 0644]
examples/scratch.c [deleted file]
examples/select.c [deleted file]
examples/super-oh.c [new file with mode: 0644]
examples/test-text.c [new file with mode: 0644]
examples/test-video.c [new file with mode: 0644]
examples/test.c [new file with mode: 0644]
examples/video-cube.c [new file with mode: 0644]
gst/Makefile.am
gst/cltrimagesink.h [deleted file]
gst/clutterimagesink. [moved from gst/cltrimagesink.c with 100% similarity]
gst/clutterimagesink.c [new file with mode: 0644]
gst/clutterimagesink.h [new file with mode: 0644]

diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..b1e3f5a
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,504 @@
+                 GNU LESSER GENERAL PUBLIC LICENSE
+                      Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+                 GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                           NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General 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
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
index aab1f43..cb87c31 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,993 @@
+2006-05-29  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-element.c:
+       * clutter/clutter-element.h:
+       Add initial new element depth() getter and setter.
+
+       * clutter/clutter-group.c:
+       * clutter/clutter-group.h:
+       Add 2 new methods for listing a groups children externally.
+
+2006-05-27  Emmanuele Bassi  <ebassi@openedhand.com>
+
+       * clutter/clutter-clone-texture.c (set_parent_texture),
+       (clutter_clone_texture_set_property),
+       (clutter_clone_texture_get_property),
+       (clutter_clone_texture_class_init),
+       (clutter_clone_texture_new): Add a "parent-texture"
+       constructor-only property to simplify the constructor code.
+
+       * clutter/clutter-rectangle.c (clutter_rectangle_new):
+       * clutter/clutter-timeline.c (clutter_timeline_new): Simplify
+       the constructor code.
+
+       * examples/rect.py: Use the new method names for clutter.main()
+       and clutter.stage().
+
+2006-05-26  Emmanuele Bassi  <ebassi@openedhand.com>
+
+       * clutter/clutter-element.c: Fix gtk-doc annotations for public
+       functions; add sanity checks for public API; factor out some
+       pointer dereferences.
+
+2006-05-26  Emmanuele Bassi  <ebassi@openedhand.com>
+
+       Big entry, small changes.
+
+       * clutter/clutter-rectangle.c:
+       * clutter/clutter-clone-texture.c:
+       * clutter/clutter-group.c:
+       * clutter/clutter-element.c:
+       * clutter/clutter-label.c: Use the GObject built-in definition
+       of a private data structure; it removes the need for managing
+       the allocation/de-allocation of a private structure ourselves.
+
+       * clutter/clutter-group.h:
+       * clutter/clutter-label.h: Add padding, for adding signals and
+       other class-wide definitions without breaking ABI.
+
+       * clutter/clutter-element.h:
+       * clutter/clutter-element.c (clutter_element_box_get_type),
+       (clutter_element_box_copy): Make ClutterElementBox a GBoxed
+       type; clean up declarations of the enums and flags.
+
+       * clutter/clutter-group.h:
+       * clutter/clutter-group.c (clutter_group_add_many_valist),
+       (clutter_group_add_many): Add a _valist version of
+       clutter_group_add_many() function, and re-implement the latter
+       as a proxy for the former; language bindings do not cope
+       well with variable argument functions.
+
+       * clutter/clutter-video-texture.h:
+       * clutter/clutter-video-texture.c: Use the right prefix for
+       the error and for the ratio enumerations.
+
+       * clutter/*.c:
+       * clutter/*.h:
+       * clutter/Makefile.am: Use the <clutter/...> include path
+       for parallel installations.
+
+       * clutter/Makefile.am:
+       * clutter/clutter-enum-types.h:
+       * clutter/clutter-enum-types.c: Register the enumeration types
+       inside the GObject type system in order to use them as properties
+       and bindings automagically pick them up.
+
+       * bindings/python/ChangeLog: Add a changelog for the bindings...
+
+       * doc/reference/ChangeLog: ... and a changelog for the reference.
+
+       * examples/test.c:
+       * examples/video-cube.c:
+       * examples/test-video.c: Use the <clutter/clutter.h> header.
+
+2006-05-25  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-clone-texture.c:
+       (clone_texture_render_to_gl_quad):
+       Remove uneeded bogus warning. Fix a typo causing large
+       texture to get incorrectly rendered.  
+       * clutter/clutter-texture.c: (init_tiles),
+       (texture_render_to_gl_quad), (clutter_texture_sync_pixbuf),
+       (clutter_texture_realize):
+       Add some new debug info.
+       * clutter/clutter-video-texture.c: (fakesink_handoff_cb):
+       Set the pixbuf from GST_BUFFER_DATA() a little safer.
+
+2006-05-25  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter.pc.in:
+       Fix prefix snafu via Ross.
+
+2006-05-24  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-element.c: (clutter_element_paint),
+       (clutter_element_class_init):
+       * clutter/clutter-label.c: (clutter_label_make_pixbuf):
+       * clutter/clutter-main.c: (clutter_main):
+       * clutter/clutter-stage.c: (sync_fullscreen), (sync_gl_viewport):
+       * clutter/clutter-stage.h:
+       Various minor tweaks / fixes needed by o.p.t
+       * clutter/clutter-texture.c: (texture_render_to_gl_quad),
+       (clutter_texture_sync_pixbuf), (clutter_texture_set_property),
+       (clutter_texture_get_property), (clutter_texture_class_init):
+       Experiment adding currently borked repreating textures,
+       * clutter/clutter-timeline.c: (timeline_timeout_func),
+       (clutter_timeline_skip):
+       Fix timeline callback frame counting.
+       * examples/test-video.c: (main):
+       Experiment with repeated textures.
+
+2006-05-23  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-clone-texture.h:
+       Fix Include.
+       * clutter/clutter-element.c: (clutter_element_set_parent):
+       Only unref if parent non NULL
+       * clutter/clutter-label.c: (clutter_label_class_init),
+       (clutter_label_set_text), (clutter_label_set_font):
+       * clutter/clutter-stage.h:
+       Add some utility defines
+       * clutter/clutter-texture.c: (init_tiles):
+       * clutter/clutter-timeline.c: (clutter_timeline_class_init),
+       (timeline_timeout_func), (clutter_timeline_get_current_frame):
+       * clutter/clutter-timeline.h:
+       Add a 'completed' signal
+       Dont free priv when g_type_class_private used. 
+       * clutter/clutter.h:
+       Add missing clutter-rectangle.h
+       * examples/Makefile.am:
+       * examples/super-oh.c: (main):
+       * examples/test.c:
+       * examples/video-cube.c:
+       Fix includes
+
+2006-05-22  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-element.c:
+       * clutter/clutter-element.h:
+       * clutter/clutter-event.c:
+       * clutter/clutter-group.c: (clutter_group_remove_all):
+       * clutter/clutter-group.h:
+       * clutter/clutter-main.c: (translate_button_event),
+       (translate_motion_event):
+       Improve mouse event handling.
+       Add code to map arbituary ( i.e cursor ) position to
+       a clutter element using OpenGL 'picking'.       
+       * clutter/clutter-texture.c: 
+       * clutter/clutter-clone-texture.c:
+       re-realize parent texture if it gets hidden.
+       * clutter/clutter-stage.c:
+       * clutter/clutter-stage.h:
+       Make sure stage sets gl viewport up even if just default size.
+       (clutter_texture_hide), (clutter_texture_paint):
+       * doc/reference/Makefile.am:
+       * examples/super-oh.c: (input_cb), (frame_cb), (main):
+       Add test for mouse events, click to remove.
+
+2006-05-21  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-element.c: 
+       * clutter/clutter-element.h:
+       Add new core sizing methods and more documentation. 
+       * clutter/clutter-group.c: 
+       * clutter/clutter-group.h:
+       Use the sizing bits and documentation.
+       * clutter/clutter-main.c: 
+       * clutter/clutter-event.h:
+       Add FPS display when CLUTTER_SHOW_FPS env var set.
+       Add initial support for mouse events.
+       * clutter/clutter-stage.c: 
+       Add 'snapshot' method. 
+       * clutter/clutter-texture.c: (clutter_texture_new_from_pixbuf):
+       * clutter/clutter-texture.h:
+       Documentation.
+       * clutter/clutter-timeline.c:
+       Add support for changing FPS setting on the fly. Document.
+       * examples/super-oh.c: (frame_cb), (main):
+       Add an optional motion trails effect.
+
+2006-05-17  Matthew Allum  <mallum@openedhand.com>
+
+       * README:
+       Add a tiny bit of info
+       * TODO:
+       Sync up a little
+       * clutter/clutter-clone-texture.c:
+       (clone_texture_render_to_gl_quad):
+       * clutter/clutter-element.c: (clutter_element_show),
+       (clutter_element_realize), (clutter_element_unrealize),
+       (clutter_element_paint), (clutter_element_set_id),
+       (clutter_element_get_id):
+       * clutter/clutter-element.h:
+       Rename REALISE() to REALIZE()
+
+       * clutter/clutter-texture.c: (texture_render_to_gl_quad),
+       (clutter_texture_sync_pixbuf), (clutter_texture_set_pixbuf):
+       * clutter/clutter-video-texture.c: (query_timeout),
+       (got_video_size), (caps_set), (parse_stream_info),
+       (handle_element_message), (bus_message_cb),
+       (poll_for_state_change_full), (clutter_video_texture_get_property),
+       (clutter_video_texture_class_init), (clutter_video_texture_init),
+       (clutter_video_texture_open), (clutter_video_texture_seek_time),
+       (stop_play_pipeline):
+       * clutter/clutter-video-texture.h:
+       Move over using fakesink and handoff instead of custom element
+       Support 3 channel pixbufs as textures and thus increase efficiency
+       of video texture ( also avoids byte swapping. )
+       Clean up video texture code somemore.
+       Add some metadata support. 
+
+       * Makefile.am:
+       * configure.ac:
+       Disable old custom clutter gst element from build.      
+
+       * examples/test-video.c: (foo), (size_change), (tick), (main):
+       * examples/video-cube.c: (clutter_video_texture_cube_paint):
+       Sink with new API. Pause on key press.
+
+2006-05-13  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-element.c: (redraw_update_idle),
+       (clutter_element_show), (clutter_element_hide),
+       (clutter_element_realize), (clutter_element_unrealize),
+       (clutter_element_class_init), (clutter_element_init),
+       (clutter_element_queue_redraw), (clutter_element_set_geometry),
+       (clutter_element_get_geometry), (clutter_element_get_coords),
+       (clutter_element_set_position), (clutter_element_set_size),
+       (clutter_element_get_abs_position), (clutter_element_get_width),
+       (clutter_element_get_height), (clutter_element_get_x),
+       (clutter_element_get_y), (clutter_element_set_opacity):
+       * clutter/clutter-texture.c: (clutter_texture_get_base_size),
+       (clutter_texture_bind_tile), (clutter_texture_get_n_tiles),
+       (clutter_texture_get_x_tile_detail),
+       (clutter_texture_get_y_tile_detail):
+       * doc/reference/Makefile.am:
+       * doc/reference/clutter.types:
+       Documentation updates.
+
+2006-05-13  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter.pc.in:
+       Add @MAJORMINOR@ to installed dirs.
+       * clutter/clutter-main.c: (clutter_xscreen), (clutter_init):
+       * clutter/clutter-main.h:
+       * clutter/clutter-private.h:
+       Quick fix for debug statements so now only appear 
+        if CLUTTER_DBBUG env var set.
+
+2006-05-12  Matthew Allum  <mallum@openedhand.com>
+
+       * configure.ac:
+       * Makefile.am:
+       * clutter/Makefile.am:
+       * bindings/python/Makefile.am:
+       * examples/Makefile.am:
+       * gst/Makefile.am:
+       Clean up autofoo a bit fixing versioning.
+       * bootstrap-autotools.sh:
+       * clutter-1.0.pc.in:
+       Rename.
+
+2006-05-12  Matthew Allum  <mallum@openedhand.com>
+
+       * bindings/python/Makefile.am:
+       * bindings/python/clutter.override:
+       * clutter/Makefile.am:
+       * clutter/clutter-bin.c:
+       * clutter/clutter-bin.h:
+       * clutter/clutter-element.c: (clutter_element_dispose),
+       (clutter_element_raise), (clutter_element_lower):
+       * clutter/clutter-group.c:
+       * clutter/clutter-group.h:
+       * clutter/clutter-main.c: (clutter_threads_leave):
+       * clutter/clutter-main.h:
+       * clutter/clutter-stage.c: (clutter_stage_class_init):
+       * clutter/clutter-stage.h:
+       * clutter/clutter.h:
+       * examples/super-oh.c: (frame_cb), (main):
+       * examples/test-text.c: (main):
+       * examples/test-video.c: (main):
+       * examples/test.c: (main):
+       * examples/video-cube.c: (main):
+       Rename clutter-bin to clutter-group
+
+2006-05-11  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-clone-texture.c:
+       (clone_texture_render_to_gl_quad), (clutter_clone_texture_paint),
+       (clutter_clone_texture_class_init), (clutter_clone_texture_new):
+       Fix cloning.
+       * clutter/clutter-element.c: (clutter_element_rotate_z),
+       (clutter_element_rotate_x), (clutter_element_rotate_y):
+       Minor tweaks
+       * examples/Makefile.am:
+       * examples/super-oh.c:
+       Add a new demo - unsing rotations and clones.
+
+2006-05-11  Matthew Allum  <mallum@openedhand.com>
+
+       * bindings/python/Makefile.am:
+       * bindings/python/clutter-base-types.defs:
+       * bindings/python/clutter-base.defs:
+       * bindings/python/clutter.override:
+       Python goodiness from ebassi.
+        - Element geometry handled nicely.
+        - get_coords(), get_abs_position() added.
+
+       * clutter/clutter-element.c: (clutter_element_rotate_x),
+       (clutter_element_rotate_y), (clutter_element_mirror),
+       * clutter/clutter-element.h:
+       Add initial rotation API. Make Geometry boxed ( ebassi )
+
+       * clutter/clutter-stage.c: (sync_gl_viewport):
+       Set depth in main world transform.
+
+       * clutter/clutter-timeline.h:
+       Add missing new() api call.
+
+       * examples/test.c: (timeout_text_cb), (frame_cb), (main):
+       Tou with some rotation
+
+2006-05-11  Matthew Allum  <mallum@openedhand.com>
+
+       reviewed by: <delete if not using a buddy>
+
+       * bindings/python/Makefile.am:
+       * bindings/python/clutter-base-types.defs:
+       * bindings/python/clutter-base.defs:
+       * bindings/python/clutter.override:
+       * clutter/clutter-bin.c: (clutter_bin_paint):
+       * clutter/clutter-element.c: (clutter_element_paint),
+       (clutter_element_get_height), (clutter_element_get_x),
+       (clutter_element_get_y), (clutter_element_set_opacity),
+       (clutter_element_get_opacity), (clutter_element_set_id),
+       (clutter_element_get_id), (clutter_element_rotate_x),
+       (clutter_element_rotate_y), (clutter_element_mirror),
+       (clutter_element_set_clip), (clutter_element_remove_clip),
+       (clutter_element_set_parent), (clutter_element_get_parent),
+       (clutter_element_raise), (clutter_element_lower),
+       (clutter_element_raise_top), (clutter_element_lower_bottom):
+       * clutter/clutter-element.h:
+       * clutter/clutter-main.c: (clutter_redraw):
+       * clutter/clutter-stage.c: (sync_gl_viewport):
+       * clutter/clutter-timeline.h:
+       * examples/test.c: (timeout_text_cb), (frame_cb), (main):
+
+2006-05-09  Matthew Allum  <mallum@openedhand.com>
+
+       * COPYING:
+       * clutter/clutter-bin.c:
+       * clutter/clutter-bin.h:
+       * clutter/clutter-clone-texture.c:
+       * clutter/clutter-clone-texture.h:
+       * clutter/clutter-color.c:
+       * clutter/clutter-color.h:
+       * clutter/clutter-element.c:
+       * clutter/clutter-element.h:
+       * clutter/clutter-event.c:
+       * clutter/clutter-event.h:
+       * clutter/clutter-keysyms.h:
+       * clutter/clutter-label.c:
+       * clutter/clutter-label.h:
+       * clutter/clutter-main.c:
+       * clutter/clutter-main.h:
+       * clutter/clutter-private.h:
+       * clutter/clutter-rectangle.c:
+       * clutter/clutter-rectangle.h:
+       * clutter/clutter-stage.c:
+       * clutter/clutter-stage.h:
+       * clutter/clutter-texture.c:
+       * clutter/clutter-texture.h:
+       * clutter/clutter-timeline.c:
+       * clutter/clutter-timeline.h:
+       * clutter/clutter-util.c:
+       * clutter/clutter-util.h:
+       Add license info.
+
+2006-05-08  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/Makefile.am:
+       * clutter/clutter-event.c:
+       * clutter/clutter-event.h:
+       * clutter/clutter-keysyms.h:
+       * clutter/clutter-main.c: (clutter_dispatch_x_event):
+       * clutter/clutter-stage.c: (clutter_stage_class_init):
+       * clutter/clutter-stage.h:
+       * clutter/clutter.h:
+       * bindings/python/Makefile.am:
+       * bindings/python/clutter.override:
+       Add basic input event handling. Keys only atm.
+
+2006-05-08  Matthew Allum  <mallum@openedhand.com>
+
+       * TODO:
+       Sync a little.
+       * bindings/python/Makefile.am:
+       * bindings/python/clutter.override:
+       Fix up so pixbufs now work ( thanks ebassi! )
+       Add some missing newer headers.
+       * clutter/clutter-main.h:
+       Remove unused clutter_queue_redraw();
+
+2006-05-07  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-element.c: (clutter_element_class_init),
+       (clutter_element_init), (clutter_element_queue_redraw),
+       (clutter_element_set_geometry), (clutter_element_get_geometry),
+       (clutter_element_get_coords), (clutter_element_set_position),
+       (clutter_element_set_size), (clutter_element_get_abs_position),
+       (clutter_element_get_width), (clutter_element_get_height),
+       (clutter_element_get_x), (clutter_element_get_y),
+       (clutter_element_set_opacity):
+       * clutter/clutter-main.c: (clutter_dispatch_x_event):
+       * clutter/clutter-main.h:
+       * clutter/clutter-private.h:
+       * clutter/clutter-stage.c: (clutter_stage_set_color):
+       * clutter/clutter-texture.c: (clutter_texture_set_pixbuf):
+       Rename clutter_queue_redraw -> clutter_element_queue_redraw
+
+       * clutter/clutter-label.c: (clutter_label_make_pixbuf),
+       (clutter_label_set_property), (clutter_label_set_text_extents):
+       * clutter/clutter-label.h:
+       Fixes to extents
+
+       * examples/Makefile.am:
+       * examples/test-text.c:
+       Add sime test text example.
+
+2006-05-07  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-label.c: (clutter_label_make_pixbuf),
+       (clutter_label_get_property), (clutter_label_dispose),
+       (clutter_label_class_init), (clutter_label_init),
+       (clutter_label_new_with_text), (clutter_label_new),
+       (clutter_label_set_text), (clutter_label_set_font),
+       (clutter_label_set_text_extents), (clutter_label_set_fg_color):
+       * examples/test.c: (main):
+       Slight efficiency improvements. Add initial extents API.
+
+2006-05-07  Matthew Allum  <mallum@openedhand.com>
+
+       * TODO:
+       resync.
+       * clutter/Makefile.am:
+       * clutter/clutter-clone-texture.c:
+       * clutter/clutter-clone-texture.h:
+       Add new texture clone element.  
+       * clutter/clutter-color.c:
+       * clutter/clutter-color.h:
+       Add simple color API.
+       * clutter/clutter-util.c:
+       * clutter/clutter-util.h:
+       Move shared texture funcs into shared util code.
+       * clutter/clutter-texture.c: (can_create), (tile_dimension),
+       (init_tiles), (texture_render_to_gl_quad),
+       (clutter_texture_unrealize), (clutter_texture_sync_pixbuf),
+       (clutter_texture_realize), (clutter_texture_show),
+       (clutter_texture_hide), (clutter_texture_paint),
+       (clutter_texture_finalize), (clutter_texture_set_property),
+       (clutter_texture_get_property), (clutter_texture_class_init),
+       (clutter_texture_init), (clutter_texture_set_pixbuf),
+       (clutter_texture_new_from_pixbuf), (clutter_texture_get_base_size),
+       (clutter_texture_bind_tile):
+       Changes for clones to work.
+       * clutter/clutter-element.c: (clutter_element_paint),
+       (clutter_element_set_property), (clutter_element_get_property),
+       (clutter_element_set_position), (clutter_element_set_size),
+       (clutter_element_get_abs_position), (clutter_element_get_width),
+       (clutter_element_get_height), (clutter_element_get_x),
+       (clutter_element_get_y), (clutter_element_set_opacity),
+       (clutter_element_get_opacity), (clutter_element_set_id),
+       (clutter_element_get_id), (clutter_element_set_clip):
+       * clutter/clutter-element.h:
+       Add clipping and other tweaks.
+       * clutter/clutter-stage.c: (sync_gl_viewport),
+       (clutter_stage_paint), (clutter_stage_init):
+       Add psuedo 3D desktop like GL setup.
+       * clutter/clutter-label.c: (clutter_label_make_pixbuf):
+       * clutter/clutter-label.h:
+       * clutter/clutter-main.c: (clutter_redraw):
+       * clutter/clutter-main.h:
+       * clutter/clutter-private.h:
+       * clutter/clutter-rectangle.c: (clutter_rectangle_paint):
+       * clutter/clutter-stage.h:
+       * clutter/clutter-texture.h:
+       * clutter/clutter-timeline.c: (clutter_timeline_class_init):
+       * clutter/clutter-video-texture.c:
+       * clutter/clutter.h:
+       * examples/test-video.c: (foo), (size_change), (tick), (main):
+       * examples/test.c: (main):
+       * examples/video-cube.c: (clutter_video_texture_cube_paint),
+       (clutter_video_texture_cube_class_init),
+       (clutter_video_texture_cube_init):
+       Various minor tweaks for API changes, new features etc.
+
+2006-05-03  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-bin.c: (clutter_bin_paint):
+       * clutter/clutter-bin.h:
+       * clutter/clutter-element.c: (clutter_element_unrealize),
+       (clutter_element_paint), (clutter_element_set_property),
+       (clutter_element_get_property), (clutter_element_dispose),
+       (clutter_element_finalize), (clutter_element_class_init),
+       (clutter_element_init), (clutter_element_queue_redraw),
+       (clutter_element_set_geometry), (clutter_element_get_geometry),
+       (clutter_element_get_coords), (clutter_element_set_position),
+       (clutter_element_set_size), (clutter_element_get_abs_position),
+       (clutter_element_set_opacity), (clutter_element_get_opacity),
+       (clutter_element_set_clip), (clutter_element_remove_clip),
+       (clutter_element_set_parent), (clutter_element_get_parent),
+       (clutter_element_raise), (clutter_element_lower),
+       (clutter_element_raise_top), (clutter_element_lower_bottom):
+       * clutter/clutter-element.h:
+       * clutter/clutter-label.c: (clutter_label_set_fg_color):
+       * clutter/clutter-rectangle.c: (clutter_rectangle_paint),
+       (clutter_rectangle_set_property), (clutter_rectangle_init):
+       * clutter/clutter-stage.c: (sync_xwindow_size):
+       * clutter/clutter-texture.c: (clutter_texture_paint),
+       (clutter_texture_set_pixbuf):
+       Clean up ClutterElement, removing globals, improving sizing
+       and initial clipping code.
+
+       * clutter/clutter.h:
+       * clutter/clutter-timeline.c: (clutter_timeline_class_init),
+       (timeline_timeout_func), (clutter_timeline_start),
+       (clutter_timeline_pause), (clutter_timeline_rewind),
+       (clutter_timeline_skip), (clutter_timeline_advance),
+       (clutter_timeline_get_current_frame), (clutter_timeline_new):
+       * clutter/clutter-timeline.h:
+       Various fixes to timelines. Implement frame skipping.
+
+       * examples/test.c: (timeout_text_cb), (main):
+       Update to use timeline.
+
+2006-05-02  Matthew Allum  <mallum@openedhand.com>
+
+       * TODO:
+       Update
+       * clutter/clutter-element.h:
+       * clutter/clutter-rectangle.h:
+       Minor formatting cleanups
+
+2006-05-02  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/Makefile.am:
+       * clutter/clutter-timeline.c:
+       * clutter/clutter-timeline.h:
+       Add initial timeline implementation
+
+2006-05-02  Matthew Allum  <mallum@openedhand.com>
+
+       * bindings/python/Makefile.am:
+       * bindings/python/cluttermodule.c: (initclutter):
+       Fix python build with new -1.0 naming. Use of GdkPixbufs 
+        still causing crashes.
+
+2006-04-30  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-main.c: (events_init), (redraw_update_idle),
+       (clutter_queue_redraw), (clutter_redraw):
+       Fix repaint queueing, using idle handler now.
+       Clean up some minor compiler warnings.
+       * clutter/clutter-main.h:
+       * clutter/clutter-texture.c: (clutter_texture_unrealize),
+       (clutter_texture_set_pixbuf):
+       Rename gl_lock/unlock to threads_enter/leaver
+
+2006-04-30  Matthew Allum  <mallum@openedhand.com>
+
+       * Makefile.am:
+       * clutter-1.0.pc.in:
+       * clutter/Makefile.am:
+       * clutter/clutter-bin.h:
+       * clutter/clutter-label.h:
+       * clutter/clutter-rectangle.h:
+       * clutter/clutter-stage.h:
+       * clutter/clutter-texture.h:
+       * clutter/clutter-video-texture.h:
+       * clutter/clutter.h:
+       * configure.ac:
+       * examples/Makefile.am:
+       Add .pc file, tag -1.0 onto lib, includes dir naming.
+
+2006-04-29  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-main.c: (clutter_dispatch_x_event),
+       (clutter_queue_redraw), (clutter_redraw):
+       Simplify paint event queueing. Does not actually queue 
+       anymore (broken), needs wrong to reduce high number of 
+        uneeded paints.  
+
+       * clutter/clutter-texture.c: (clutter_texture_set_pixbuf):
+       Remove visible check which broke paints of resized texture pixmaps.
+
+2006-04-19  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-bin.c: (clutter_bin_paint), (clutter_bin_add):
+       * clutter/clutter-element.c: (clutter_element_paint):
+       * clutter/clutter-element.h:
+       * clutter/clutter-label.c: (clutter_label_set_property),
+       (clutter_label_get_property), (clutter_label_class_init):
+       * clutter/clutter-marshal.list:
+       * clutter/clutter-rectangle.c: (clutter_rectangle_set_property),
+       (clutter_rectangle_get_property), (clutter_rectangle_class_init):
+       * clutter/clutter-stage.c: (clutter_stage_dispose),
+       (clutter_stage_get_property), (clutter_stage_class_init):
+       * clutter/clutter-texture.c: (clutter_texture_realize),
+       (clutter_texture_class_init), (clutter_texture_set_pixbuf):
+       * clutter/clutter-texture.h:
+       More object cleanups. Add signal to texture size changes.
+       Fix color props. Adjust element realise flags workings ( broken ).
+       * examples/test-video.c: (main):
+       Broken due to realize flag changes. 
+
+2006-04-18  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-bin.c: (clutter_bin_get_property),
+       (clutter_bin_finalize), (clutter_bin_class_init),
+       (clutter_bin_new), (clutter_bin_show_all), (clutter_bin_hide_all),
+       (clutter_bin_add):
+       * clutter/clutter-bin.h:
+       * clutter/clutter-element.c: (clutter_element_get_property),
+       (clutter_element_finalize), (clutter_element_class_init),
+       (clutter_element_set_parent), (clutter_element_get_parent),
+       (clutter_element_raise), (clutter_element_lower):
+       * clutter/clutter-element.h:
+       * clutter/clutter-label.c: (clutter_label_make_pixbuf),
+       (clutter_label_get_property), (clutter_label_dispose),
+       (clutter_label_finalize), (clutter_label_class_init),
+       (clutter_label_init), (clutter_label_new_with_text),
+       (clutter_label_new), (clutter_label_set_text),
+       (clutter_label_set_font), (clutter_label_set_fg_color):
+       * clutter/clutter-label.h:
+       * clutter/clutter-rectangle.c: (clutter_rectangle_paint),
+       (clutter_rectangle_set_property), (clutter_rectangle_get_property),
+       (clutter_rectangle_finalize), (clutter_rectangle_dispose),
+       (clutter_rectangle_class_init), (clutter_rectangle_init),
+       (clutter_rectangle_new):
+       * clutter/clutter-texture.c: (clutter_texture_paint),
+       (clutter_texture_dispose), (clutter_texture_finalize),
+       (clutter_texture_set_property), (clutter_texture_get_property),
+       (clutter_texture_class_init), (clutter_texture_init),
+       (clutter_texture_set_pixbuf), (clutter_texture_new_from_pixbuf):
+       Various GObject usages cleanups, adding properties and
+       finalize/dispose functions properly.
+
+2006-04-18  Matthew Allum  <mallum@openedhand.com>
+
+       * bindings/python/Makefile.am:
+       * bindings/python/clutter.override:
+       * bindings/python/cluttermodule.c: (initclutter):
+       * clutter/clutter-label.h:
+       * clutter/clutter-rectangle.h:
+       * clutter/clutter-video-texture.h:
+       More fixups to now less broken python bindings
+       * examples/rects.py:
+       A simple python script using bindings
+
+2006-04-18  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-marshal.list:
+       Add missing. 
+
+2006-04-17  Matthew Allum  <mallum@openedhand.com>
+
+       * Makefile.am:
+       * bindings/Makefile.am:
+       * bindings/python/Makefile.am:
+       * bindings/python/clutter.override:
+       * bindings/python/cluttermodule.c:
+       * configure.ac:
+       First shot at some python bindings ( broken atm )
+       * clutter/clutter-bin.h:
+       * clutter/clutter-element.h:
+       * clutter/clutter-stage.h:
+       * clutter/clutter-texture.h:
+       * clutter/clutter.h:
+       Rejig headers a little so h2def.py happier
+
+2006-04-17  Matthew Allum  <mallum@openedhand.com>
+
+       * TODO:
+       * doc/clutter.types:
+       * doc/reference/Makefile.am:
+       Move gtk-doc gubbins to doc/reference
+
+2006-04-16  Matthew Allum  <mallum@openedhand.com>
+
+       * TODO:
+       More updates
+
+       * clutter/clutter-bin.c: (clutter_bin_paint):
+       Add translate call
+
+       * clutter/clutter-texture.c: (clutter_texture_dispose),
+       (clutter_texture_class_init), (clutter_texture_set_pixbuf):
+       Fixup object finalization a little.
+       
+       * bootstrap-autotools.sh:
+       * configure.ac:
+       * doc/Makefile.am:
+       * doc/clutter.types:
+       Add gtk-doc infrastructure
+
+2006-04-15  Matthew Allum  <mallum@openedhand.com>
+
+       * TODO:
+       More ideas.
+
+       * clutter/Makefile.am:
+       * clutter/clutter-rectangle.c: (clutter_rectangle_new):
+       Sync passed color alpha chan to element opacity, 
+
+       * clutter/clutter-video-texture.c:
+       (clutter_video_texture_error_quark), (signal_eos_delayed),
+       (query_timeout), (got_video_size), (caps_set), (parse_stream_info),
+       (handle_element_message)
+       * clutter/clutter-video-texture.h:
+       Port more of bacon video widget API.
+
+       * examples/test-video.c: (foo), (tick), (main):
+       Add a simple overlay displaying playback time.
+
+2006-04-15  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-element.c:
+       * clutter/clutter-label.c: (clutter_label_init),
+       (clutter_label_new_with_text):
+       * clutter/clutter-label.h:
+       * clutter/clutter-main.c: (clutter_redraw), (clutter_gl_unlock):
+       * clutter/clutter-main.h:
+       * clutter/clutter-rectangle.c: (clutter_rectangle_init),
+       (clutter_rectangle_new):
+       * clutter/clutter-rectangle.h:
+       * clutter/clutter-texture.c: (clutter_texture_class_init),
+       (clutter_texture_set_pixbuf), (clutter_texture_new_from_pixbuf):
+       * clutter/clutter-texture.h:
+       * clutter/clutter-video-texture.c: (clutter_video_texture_init):
+       * clutter/clutter-video-texture.h:
+       * examples/test-video.c: (main):
+       * examples/test.c: (main):
+       * examples/video-cube.c: (clutter_video_texture_cube_init), (main):
+       Make xxx_new() return there type as ClutterElement*
+
+2006-04-15  Matthew Allum  <mallum@openedhand.com>
+
+       * TODO:
+       Update
+       * clutter/clutter-main.c:
+       * clutter/clutter-stage.c:
+       * clutter/clutter-texture.c:
+       * clutter/clutter-texture.h:
+       * gst/clutterimagesink.c: (gst_clutterimagesink_clutterimage_put),
+       (gst_clutterimagesink_context_get):
+       Various experiments with textures and 3D views.
+
+       * clutter/clutter-video-texture.c:
+       (clutter_video_texture_class_init), (clutter_video_texture_init):
+       * examples/Makefile.am:
+       * examples/test-video.c: (main):
+       * examples/video-cube.c:
+       Add video-cube example
+
+2006-04-13  Matthew Allum  <mallum@openedhand.com>
+
+       * TODO:
+       Update
+
+       * clutter/clutter-bin.c:
+       * clutter/clutter-bin.h:
+       New container element
+
+       * clutter/clutter-stage.c:
+       * clutter/clutter-stage.h:
+       Make stage a proper element
+
+       * clutter/Makefile.am:
+       * clutter/clutter.h:
+       * clutter/clutter-element.c: (clutter_element_show),
+       (clutter_element_set_opacity):
+       * clutter/clutter-element.h:
+       * clutter/clutter-label.c: (clutter_label_make_pixbuf),
+       (clutter_label_set_text), (clutter_label_set_font):
+       * clutter/clutter-private.h:
+       Various tweaks new api calls.
+
+       * clutter/clutter-main.c: (events_init):
+       * clutter/clutter-main.h:
+       Make ClutterContex Private to main 
+
+       * clutter/clutter-texture.c:
+       * clutter/clutter-texture.h:
+       * clutter/clutter-video-texture.c:
+       (clutter_video_texture_finalize):
+       Fix video crash
+
+       * examples/test-video.c: (main):
+       * examples/test.c: (main):
+       Fix for API changes.
+
+2006-04-11  Matthew Allum  <mallum@openedhand.com>
+
+       * TODO:
+       Add
+       * clutter/clutter-video-texture.c:
+       (clutter_video_texture_finalize):
+       * clutter/clutter-video-texture.h:
+       Remove bogus pixbuf attribute
+
+2006-04-10  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-main.c: (clutter_dispatch_x_event),
+       (clutter_queue_redraw), (clutter_main), (clutter_set_stage_params),
+       (clutter_init):
+       * clutter/clutter-main.h:
+       * clutter/clutter-private.h:
+       Make Stage non fullscreen ( for now ). Change event loop to 
+       work better with video.
+
+       * clutter/Makefile.am:
+       * clutter/clutter-label.c: (clutter_label_make_pixbuf),
+       (clutter_label_class_init), (clutter_label_new_with_text),
+       (clutter_label_set_text), (clutter_label_set_font):
+       * clutter/clutter-texture.c: (texture_render_to_gl_quad),
+       (clutter_texture_unrealize), (clutter_texture_sync_pixbuf),
+       (clutter_texture_realize), (clutter_texture_show),
+       (clutter_texture_hide), (clutter_texture_paint),
+       (clutter_texture_finalize), (clutter_texture_set_property),
+       (clutter_texture_get_property), (clutter_texture_class_init),
+       (clutter_texture_init), (clutter_texture_get_pixbuf),
+       (clutter_texture_set_pixbuf), (clutter_texture_new_from_pixbuf):
+       * clutter/clutter-texture.h:
+       * clutter/clutter.h:
+       Fix leakage. Improve performance. Add support for non tiled
+       textures.
+
+       * examples/Makefile.am:
+       * examples/test.c: (timeout_text_cb), (main):
+       Experiments
+
+       * examples/test-video.c:
+       * configure.ac:
+       * gst/Makefile.am:
+       * gst/clutterimagesink.c:
+       * gst/clutterimagesink.h:
+       * clutter/clutter-video-texture.c:
+       * clutter/clutter-video-texture.h:
+       Add initial support for video textures with gst-0.10
+
+       * gst/cltrimagesink.c:
+       * gst/cltrimagesink.h:
+       Remove old gst-0.8 sink
+
+
+2006-04-05  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/Makefile.am:
+       * clutter/clutter-element.c: (clutter_element_show),
+       (clutter_element_hide), (clutter_element_realize),
+       (clutter_element_unrealize), (clutter_element_paint),
+       (clutter_element_finalize), (clutter_element_class_init),
+       (clutter_element_init), (clutter_element_new):
+       * clutter/clutter-element.h:
+       * clutter/clutter.h:
+       * clutter/clutter-main.c: (clutter_dispatch_x_event),
+       (events_init), (clutter_redraw), (clutter_main), (clutter_init),
+       (clutter_show_stage):
+       * clutter/clutter-main.h:
+       Various minor tweaks.
+
+       * clutter/clutter-private.h:
+       * clutter/clutter-texture.c: (can_create), (init_tiles),
+       (clutter_texture_unrealize), (clutter_texture_realize),
+       (clutter_texture_finalize), (clutter_texture_class_init),
+       (clutter_texture_init):
+       * clutter/clutter-texture.h:
+       Much improve texture class.
+
+       * clutter/clutter-label.c:
+       * clutter/clutter-label.h:
+       Add new text rendering class
+       
+       * clutter/clutter-rectangle.c:
+       * clutter/clutter-rectangle.h:
+       Add basic rectangle drawing class
+
+       * examples/test.c:
+       Add text rendering and animation to test.
+
+2006-04-04  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/Makefile.am:
+       * clutter/clutter-element.c: (clutter_element_realize):
+       * clutter/clutter-element.h:
+       * clutter/clutter-image.c:
+       * clutter/clutter-image.h:
+       * clutter/clutter-main.c: (clutter_dispatch_x_event),
+       (clutter_main), (clutter_set_stage_params), (clutter_init):
+       * clutter/clutter-texture.c: (next_p2), (can_create),
+       (tile_dimension), (init_tiles), (texture_render_to_gl_quad),
+       (clutter_texture_unrealize), (clutter_texture_realize),
+       (clutter_texture_get_pixbuf), (clutter_texture_paint),
+       (clutter_texture_finalize), (clutter_texture_class_init):
+       * clutter/clutter-texture.h:
+       * clutter/clutter.h:
+       * configure.ac:
+       * examples/test.c:
+       Implement basic tiled texture painting.
+
+2006-04-03  Matthew Allum  <mallum@openedhand.com>
+
+       reviewed by: <delete if not using a buddy>
+
+       * clutter/Makefile.am:
+       * clutter/clutter-element.c:
+       * clutter/clutter-element.h:
+       * clutter/clutter-image.c:
+       * clutter/clutter-image.h:
+       * clutter/clutter-main.c: (events_init), (stage_realize),
+       (clutter_queue_redraw), (clutter_redraw), (clutter_add_to_stage),
+       (clutter_remove_from_stage), (clutter_main),
+       (clutter_set_stage_params), (clutter_init):
+       * clutter/clutter-main.h:
+       * clutter/clutter-private.h:
+       * clutter/clutter.h:
+       * examples/test.c:
+
+2006-04-02  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/Makefile.am:
+       * clutter/cltr-animator.c:
+       * clutter/cltr-animator.h:
+       * clutter/cltr-button.c:
+       * clutter/cltr-button.h:
+       * clutter/cltr-core.c:
+       * clutter/cltr-core.h:
+       * clutter/cltr-events.c:
+       * clutter/cltr-events.h:
+       * clutter/cltr-glu.c:
+       * clutter/cltr-glu.h:
+       * clutter/cltr-label.c:
+       * clutter/cltr-label.h:
+       * clutter/cltr-list.c:
+       * clutter/cltr-list.h:
+       * clutter/cltr-overlay.c:
+       * clutter/cltr-overlay.h:
+       * clutter/cltr-photo-grid.c:
+       * clutter/cltr-photo-grid.h:
+       * clutter/cltr-private.h:
+       * clutter/cltr-scratch.c:
+       * clutter/cltr-scratch.h:
+       * clutter/cltr-texture.c:
+       * clutter/cltr-texture.h:
+       * clutter/cltr-video.c:
+       * clutter/cltr-video.h:
+       * clutter/cltr-widget.c:
+       * clutter/cltr-widget.h:
+       * clutter/cltr-window.c:
+       * clutter/cltr-window.h:
+       * clutter/cltr.h:
+       * clutter/clutter-main.c:
+       * clutter/clutter-main.h:
+       * clutter/clutter-private.h:
+       * clutter/clutter.h:
+       * clutter/fonts.c:
+       * clutter/fonts.h:
+       * clutter/pixbuf.c:
+       * clutter/pixbuf.h:
+       * clutter/util.c:
+       * clutter/util.h:
+       * configure.ac:
+       * examples/Makefile.am:
+       * examples/photos.c:
+       * examples/player.c:
+       * examples/scratch.c:
+       * examples/select.c:
+       * examples/test.c:
+       Remove old cltr files replacing with beginnings of
+       rejigged 'clutter' ones.
+
 2005-05-27  mallum,,,  <mallum@openedhand.com>
 
        * clutter/cltr-animator.c: (cltr_animator_zoom_new),
index 5a09d1b..5f19271 100644 (file)
@@ -1 +1,20 @@
-SUBDIRS=clutter gst examples
\ No newline at end of file
+SUBDIRS=clutter bindings doc examples 
+
+pcfiles = clutter-@CLUTTER_MAJORMINOR@.pc
+
+%-@CLUTTER_MAJORMINOR@.pc: %.pc
+       cp $< $@
+
+pkgconfig_DATA = $(pcfiles)
+pkgconfigdir   = $(libdir)/pkgconfig
+
+EXTRA_DIST = clutter.pc.in
+
+CLEANFILES = $(pcfiles)
+
+DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = aclocal.m4 compile config.guess config.sub \
+                       configure depcomp install-sh ltmain.sh     \
+                       Makefile.in missing config.h.in
\ No newline at end of file
diff --git a/README b/README
index e69de29..54d3713 100644 (file)
--- a/README
+++ b/README
@@ -0,0 +1,14 @@
+
+
+What it will do:
+ - Give a nice easy GObject based API for creating fast, mainly 2D
+   single window stylalised applications such as media box UI's, 
+   presentaions, kiosk style apps etc.
+   
+ - If you've ever used Director, thats the kind of functionality, 
+   clutter aims for. 
+
+What it wont do:
+
+ - Provide a general interface to all openGL functionality
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..c557c3d
--- /dev/null
+++ b/TODO
@@ -0,0 +1,39 @@
+TODO
+====
+
+- Element
+  o depth and z positioning ?
+  o can glscale -1 for mirroring / flipping, or just use rotation ?
+
+- Stage
+ o Events - mouse
+
+- Texture
+ o display lists ?
+
+- Rect
+ o rounded
+ o gradients ( or add to elements ? )
+ o general polygon handler ?
+
+- Video Texture
+ o complete API from bacon-video-widget *Mostly done*
+ o Work with pixel aspect and use this info to size element correctly ?
+ o mostly rewrite or check with orig author for LGPL.
+
+- Group
+ o apply tranforms to group of elements
+ o scissor to clip
+ o sizing ? how does set/get_geometry affect ?
+ o stacking orders with 'depth' value.
+
+- GST
+ o Fix FIXME's
+ o Remove and use fake sinc instead
+
+- Audio api for sound effects etc
+
+- Document, Document, Document!
+ o fix GTK Doc set up with index, grouping etc
+
+- Glitz integration ?
\ No newline at end of file
similarity index 81%
rename from bootstrap-autotools.sh
rename to autogen.sh
index b1376df..aecfb84 100755 (executable)
@@ -1,3 +1,4 @@
 #! /bin/sh
+gtkdocize || exit 1
 autoreconf -v --install || exit 1
 ./configure --enable-maintainer-mode "$@"
diff --git a/bindings/ChangeLog b/bindings/ChangeLog
new file mode 100644 (file)
index 0000000..22062c5
--- /dev/null
@@ -0,0 +1,55 @@
+2006-05-27  Emmanuele Bassi  <ebassi@openedhand.com>
+
+       * python/clutter-base.defs: Make static functions appear like
+       package methods, e.g.: clutter_main() is clutter.main() and
+       not clutter.clutter_main().  Changed functions are:
+           C name                        Python name
+         - clutter_main                - clutter.main
+         - clutter_stage               - clutter.stage
+         - clutter_want_debug          - clutter.want_debug
+         - clutter_redraw              - clutter.redraw
+         - clutter_threads_enter       - clutter.threads_enter
+         - clutter_threads_leave       - clutter.threads_leave
+       
+       * python/clutter.override: Ignore all X11 and GL related
+       functions, as we don't have type definitions for them; fix typos
+       and cut-and-paste errors; make the threads_enter and main static
+       function use the pygobject threading facilities.
+
+       * Makefile.am: Rework the build system.  The defs files have been
+       split in two: clutter-base-types.def for the type declarations
+       and clutter-base.defs for the methods and functions.  The python
+       glue code depends on two auto-generated files: clutter.defs and
+       clutter-types.defs; these two files includes the clutter-base
+       files.  If the API changes, run "make update-defs": it will
+       create a "clutter-api.defs" which should be hand-edited and
+       the new sections added to the clutter-base files.  This is needed
+       because we do some mangling of the namespace and static functions
+       names, so we can't rely on the h2defs generator.
+
+2006-05-27  Emmanuele Bassi  <ebassi@openedhand.com>
+
+       API coverage:
+         - global functions: 71.43% (10/14)
+         - methods:          95.40% (83/87)
+
+       * python/clutter.override: Implement bindings for the missing
+       ClutterTexture methods:
+         - get_base_size
+         - get_n_tiles
+         - get_x_tile_detail
+         - get_y_tile_detail
+       
+       * python/clutter.override: Implement the ClutterGroup.add_many
+       method.
+
+2006-05-26  Emmanuele Bassi  <ebassi@openedhand.com>
+
+       * python/clutter-base.defs:
+       * python/clutter-base-types.defs:
+       * python/clutter.override: Fix ClutterGeometry bindings;
+       implement ClutterElementBox bindings.
+
+       * python/Makefile.am: Use variables instead of hard-coded
+       file names.
+
diff --git a/bindings/Makefile.am b/bindings/Makefile.am
new file mode 100644 (file)
index 0000000..0f47450
--- /dev/null
@@ -0,0 +1,5 @@
+SUBDIRS =
+
+if ENABLE_PYTHON
+SUBDIRS += python
+endif
diff --git a/bindings/python/Makefile.am b/bindings/python/Makefile.am
new file mode 100644 (file)
index 0000000..1343766
--- /dev/null
@@ -0,0 +1,91 @@
+AUTOMAKE_OPTIONS = 1.7
+
+CLEANFILES =
+EXTRA_DIST =
+
+CLUTTER_DEFS = clutter-base.defs
+CLUTTER_TYPES_DEFS = clutter-base-types.defs
+
+CREATEDEFS = $(PYTHON) createdefs.py
+
+CLUTTER_OVERRIDES = clutter.override
+
+CLEANFILES +=                  \
+       clutter.defs            \
+       clutter-types.defs
+
+EXTRA_DIST +=                  \
+       $(CLUTTER_DEFS)         \
+       $(CLUTTER_TYPES_DEFS)   \
+       $(CLUTTER_OVERRIDES)
+
+clutter.defs: $(CLUTTER_DEFS)
+       @echo "*** Creating clutter.defs" &&                                    \
+       echo ";; -*- scheme -*-" > gen-cdefs &&                                 \
+       echo ";; THIS FILE IS AUTOGENERATED" >> gen-cdefs &&                    \
+       for p in $(CLUTTER_DEFS); do                                            \
+               echo "(include \"$$p\")" >> gen-cdefs;                          \
+       done &&                                                                 \
+       (cmp -s gen-cdefs clutter.defs || cp gen-cdefs clutter.defs) &&         \
+       rm -f gen-cdefs
+clutter.defs: Makefile
+
+clutter-types.defs: $(CLUTTER_TYPES_DEFS)
+       @echo "*** Creating clutter-types.defs" &&                                      \
+       echo ";; -*- scheme -*-" > gen-ctdefs &&                                        \
+       echo ";; THIS FILE IS AUTOGENERATED" >> gen-ctdefs &&                           \
+       for p in $(CLUTTER_TYPES_DEFS); do                                              \
+               echo "(include \"$$p\")" >> gen-ctdefs;                                 \
+       done &&                                                                         \
+       (cmp -s gen-ctdefs clutter-types.defs || cp gen-ctdefs clutter-types.defs) &&   \
+       rm -f gen-ctdefs
+clutter-types.defs: Makefile
+
+clutter-pyglue.c: clutter.defs clutter-types.defs $(CLUTTER_OVERRIDES)
+       $(PYGTK_CODEGEN)                                \
+        --register $(PYGTK_DEFSDIR)/gdk-types.defs     \
+        --register $(PYGTK_DEFSDIR)/gtk-types.defs     \
+        --register $(PYGTK_DEFSDIR)/pango-types.defs   \
+        --register clutter-types.defs                  \
+       --override $(CLUTTER_OVERRIDES)                 \
+       --prefix clutter                                \
+        clutter.defs > gen-$@ &&                       \
+       (cmp -s $@ gen-$@ || cp gen-$@ $@) &&           \
+       rm -f gen-$@
+
+CLEANFILES += clutter-pyglue.c
+
+pythondir = $(libdir)/python${PY_VER}/site-packages
+python_LTLIBRARIES = clutter.la
+
+INCLUDES = $(PYTHON_CFLAGS) $(PYGTK_CFLAGS) -I$(top_srcdir) $(CLUTTER_CFLAGS)
+
+clutter_la_DEPENDENCIES = cluttermodule.c clutter-pyglue.c
+clutter_la_SOURCES = clutter-pyglue.c cluttermodule.c
+clutter_la_LIBADD  = $(PYTHON_LIBS) $(PYGTK_LIBS) \
+                     $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la
+clutter_la_LDFLAGS = -module avoid-version -export-symbols-regex initclutter
+
+# Run this to update the API and then copy then newly generated
+# definitions into clutter-base.defs and clutter-base-types.defs;
+# it's manual, as my might do some name mangling for static
+# methods.
+update-defs:
+       $(PYTHON) $(PYGTK_CODEGENDIR)/h2def.py -v       \
+               $(top_srcdir)/clutter/clutter-keysyms.h         \
+               $(top_srcdir)/clutter/clutter-timeline.h        \
+               $(top_srcdir)/clutter/clutter-main.h            \
+               $(top_srcdir)/clutter/clutter-event.h           \
+               $(top_srcdir)/clutter/clutter-element.h         \
+               $(top_srcdir)/clutter/clutter-rectangle.h       \
+               $(top_srcdir)/clutter/clutter-texture.h         \
+               $(top_srcdir)/clutter/clutter-color.h           \
+               $(top_srcdir)/clutter/clutter-clone-texture.h   \
+               $(top_srcdir)/clutter/clutter-video-texture.h   \
+               $(top_srcdir)/clutter/clutter-label.h           \
+               $(top_srcdir)/clutter/clutter-group.h           \
+               $(top_srcdir)/clutter/clutter-stage.h           \
+               $(top_srcdir)/clutter/clutter-enum-types.h      \
+       > gen-cdefs && \
+       (cmp -s gen-cdefs clutter-api.def || cp gen-cdefs clutter-api.def) && \
+       rm -f gen-cdefs
diff --git a/bindings/python/clutter-base-types.defs b/bindings/python/clutter-base-types.defs
new file mode 100644 (file)
index 0000000..94e408d
--- /dev/null
@@ -0,0 +1,207 @@
+;; -*- scheme -*-
+;;
+;; Try and keep everything sorted
+;;
+
+;; Boxed types
+
+(define-boxed ElementBox
+  (in-module "Clutter")
+  (c-name "ClutterElementBox")
+  (gtype-id "CLUTTER_TYPE_ELEMENT_BOX")
+  (fields
+    '("gint" "x1")
+    '("gint" "y1")
+    '("gint" "x2")
+    '("gint" "y2")
+  )
+)
+
+(define-boxed Geometry
+  (in-module "Clutter")
+  (c-name "ClutterGeometry")
+  (gtype-id "CLUTTER_TYPE_GEOMETRY")
+  (fields
+    '("gint" "x")
+    '("gint" "y")
+    '("gint" "width")
+    '("gint" "height")
+  )
+)
+
+;; Enumerations and flags ...
+
+(define-flags ElementTransform
+  (in-module "Clutter")
+  (c-name "ClutterElementTransform")
+  (gtype-id "CLUTTER_TYPE_ELEMENT_TRANSFORM")
+  (values
+    '("x" "CLUTTER_ELEMENT_MIRROR_X")
+    '("y" "CLUTTER_ELEMENT_MIRROR_Y")
+  )
+)
+
+(define-flags ElementFlags
+  (in-module "Clutter")
+  (c-name "ClutterElementFlags")
+  (gtype-id "CLUTTER_TYPE_ELEMENT_FLAGS")
+  (values
+    '("mapped" "CLUTTER_ELEMENT_MAPPED")
+    '("realized" "CLUTTER_ELEMENT_REALIZED")
+  )
+)
+
+(define-enum EventType
+  (in-module "Clutter")
+  (c-name "ClutterEventType")
+  (gtype-id "CLUTTER_TYPE_EVENT_TYPE")
+  (values
+    '("key-press" "CLUTTER_KEY_PRESS")
+    '("key-release" "CLUTTER_KEY_RELEASE")
+    '("motion" "CLUTTER_MOTION")
+    '("button-press" "CLUTTER_BUTTON_PRESS")
+    '("2button-press" "CLUTTER_2BUTTON_PRESS")
+    '("button-release" "CLUTTER_BUTTON_RELEASE")
+  )
+)
+
+(define-enum VideoTextureAspectRatio
+  (in-module "Clutter")
+  (c-name "ClutterVideoTextureAspectRatio")
+  (gtype-id "CLUTTER_TYPE_VIDEO_TEXTURE_ASPECT_RATIO")
+  (values
+    '("auto" "CLUTTER_VIDEO_TEXTURE_AUTO")
+    '("square" "CLUTTER_VIDEO_TEXTURE_SQUARE")
+    '("fourbythree" "CLUTTER_VIDEO_TEXTURE_FOURBYTHREE")
+    '("anamorphic" "CLUTTER_VIDEO_TEXTURE_ANAMORPHIC")
+    '("dvb" "CLUTTER_VIDEO_TEXTURE_DVB")
+  )
+)
+
+(define-enum VideoTextureError
+  (in-module "Clutter")
+  (c-name "ClutterVideoTextureError")
+  (gtype-id "CLUTTER_TYPE_VIDEO_TEXTURE_ERROR")
+  (values
+    '("audio-plugin" "CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_PLUGIN")
+    '("no-plugin-for-file" "CLUTTER_VIDEO_TEXTURE_ERROR_NO_PLUGIN_FOR_FILE")
+    '("video-plugin" "CLUTTER_VIDEO_TEXTURE_ERROR_VIDEO_PLUGIN")
+    '("audio-busy" "CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_BUSY")
+    '("broken-file" "CLUTTER_VIDEO_TEXTURE_ERROR_BROKEN_FILE")
+    '("file-generic" "CLUTTER_VIDEO_TEXTURE_ERROR_FILE_GENERIC")
+    '("file-permission" "CLUTTER_VIDEO_TEXTURE_ERROR_FILE_PERMISSION")
+    '("file-encrypted" "CLUTTER_VIDEO_TEXTURE_ERROR_FILE_ENCRYPTED")
+    '("file-not-found" "CLUTTER_VIDEO_TEXTURE_ERROR_FILE_NOT_FOUND")
+    '("dvd-encrypted" "CLUTTER_VIDEO_TEXTURE_ERROR_DVD_ENCRYPTED")
+    '("invalid-device" "CLUTTER_VIDEO_TEXTURE_ERROR_INVALID_DEVICE")
+    '("unknown-host" "CLUTTER_VIDEO_TEXTURE_ERROR_UNKNOWN_HOST")
+    '("network-unreachable" "CLUTTER_VIDEO_TEXTURE_ERROR_NETWORK_UNREACHABLE")
+    '("connection-refused" "CLUTTER_VIDEO_TEXTURE_ERROR_CONNECTION_REFUSED")
+    '("unvalid-location" "CLUTTER_VIDEO_TEXTURE_ERROR_UNVALID_LOCATION")
+    '("generic" "CLUTTER_VIDEO_TEXTURE_ERROR_GENERIC")
+    '("codec-not-handled" "CLUTTER_VIDEO_TEXTURE_ERROR_CODEC_NOT_HANDLED")
+    '("audio-only" "CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_ONLY")
+    '("cannot-capture" "CLUTTER_VIDEO_TEXTURE_ERROR_CANNOT_CAPTURE")
+    '("read-error" "CLUTTER_VIDEO_TEXTURE_ERROR_READ_ERROR")
+    '("plugin-load" "CLUTTER_VIDEO_TEXTURE_ERROR_PLUGIN_LOAD")
+    '("still-image" "CLUTTER_VIDEO_TEXTURE_ERROR_STILL_IMAGE")
+    '("empty-file" "CLUTTER_VIDEO_TEXTURE_ERROR_EMPTY_FILE")
+  )
+)
+
+(define-enum VideoTextureMetadataType
+  (in-module "Clutter")
+  (c-name "ClutterVideoTextureMetadataType")
+  (gtype-id "CLUTTER_TYPE_VIDEO_TEXTURE_METADATA_TYPE")
+  (values
+    '("title" "CLUTTER_INFO_TITLE")
+    '("artist" "CLUTTER_INFO_ARTIST")
+    '("year" "CLUTTER_INFO_YEAR")
+    '("album" "CLUTTER_INFO_ALBUM")
+    '("duration" "CLUTTER_INFO_DURATION")
+    '("track-number" "CLUTTER_INFO_TRACK_NUMBER")
+    '("has-video" "CLUTTER_INFO_HAS_VIDEO")
+    '("dimension-x" "CLUTTER_INFO_DIMENSION_X")
+    '("dimension-y" "CLUTTER_INFO_DIMENSION_Y")
+    '("video-bitrate" "CLUTTER_INFO_VIDEO_BITRATE")
+    '("video-codec" "CLUTTER_INFO_VIDEO_CODEC")
+    '("fps" "CLUTTER_INFO_FPS")
+    '("has-audio" "CLUTTER_INFO_HAS_AUDIO")
+    '("audio-bitrate" "CLUTTER_INFO_AUDIO_BITRATE")
+    '("audio-codec" "CLUTTER_INFO_AUDIO_CODEC")
+  )
+)
+
+;; Objects
+
+(define-object Element
+  (in-module "Clutter")
+  (parent "GObject")
+  (c-name "ClutterElement")
+  (gtype-id "CLUTTER_TYPE_ELEMENT")
+)
+
+(define-object CloneTexture
+  (in-module "Clutter")
+  (parent "ClutterElement")
+  (c-name "ClutterCloneTexture")
+  (gtype-id "CLUTTER_TYPE_CLONE_TEXTURE")
+)
+
+(define-object Group
+  (in-module "Clutter")
+  (parent "ClutterElement")
+  (c-name "ClutterGroup")
+  (gtype-id "CLUTTER_TYPE_GROUP")
+)
+
+(define-object Rectangle
+  (in-module "Clutter")
+  (parent "ClutterElement")
+  (c-name "ClutterRectangle")
+  (gtype-id "CLUTTER_TYPE_RECTANGLE")
+)
+
+(define-object Stage
+  (in-module "Clutter")
+  (parent "ClutterGroup")
+  (c-name "ClutterStage")
+  (gtype-id "CLUTTER_TYPE_STAGE")
+)
+
+(define-object Texture
+  (in-module "Clutter")
+  (parent "ClutterElement")
+  (c-name "ClutterTexture")
+  (gtype-id "CLUTTER_TYPE_TEXTURE")
+)
+
+(define-object Label
+  (in-module "Clutter")
+  (parent "ClutterTexture")
+  (c-name "ClutterLabel")
+  (gtype-id "CLUTTER_TYPE_LABEL")
+)
+
+(define-object Timeline
+  (in-module "Clutter")
+  (parent "GObject")
+  (c-name "ClutterTimeline")
+  (gtype-id "CLUTTER_TYPE_TIMELINE")
+)
+
+(define-object VideoTexture
+  (in-module "Clutter")
+  (parent "ClutterTexture")
+  (c-name "ClutterVideoTexture")
+  (gtype-id "CLUTTER_TYPE_VIDEO_TEXTURE")
+)
+
+;; Pointers
+
+
+
+;; Unsupported
+
+
+
diff --git a/bindings/python/clutter-base.defs b/bindings/python/clutter-base.defs
new file mode 100644 (file)
index 0000000..79f5bfb
--- /dev/null
@@ -0,0 +1,1073 @@
+;; -*- scheme -*-
+
+(include "clutter-base-types.defs")
+
+;; From ../../clutter/clutter-keysyms.h
+
+
+
+;; From ../../clutter/clutter-timeline.h
+
+(define-function clutter_timeline_get_type
+  (c-name "clutter_timeline_get_type")
+  (return-type "GType")
+)
+
+(define-function clutter_timeline_new
+  (c-name "clutter_timeline_new")
+  (is-constructor-of "ClutterTimeline")
+  (return-type "ClutterTimeline*")
+  (properties
+    '("frames" (argname "frames"))
+    '("fps" (argsname "fps"))
+  )
+)
+
+(define-method set_speed
+  (of-object "ClutterTimeline")
+  (c-name "clutter_timeline_set_speed")
+  (return-type "none")
+  (parameters
+    '("guint" "fps")
+  )
+)
+
+(define-method start
+  (of-object "ClutterTimeline")
+  (c-name "clutter_timeline_start")
+  (return-type "none")
+)
+
+(define-method pause
+  (of-object "ClutterTimeline")
+  (c-name "clutter_timeline_pause")
+  (return-type "none")
+)
+
+(define-method stop
+  (of-object "ClutterTimeline")
+  (c-name "clutter_timeline_stop")
+  (return-type "none")
+)
+
+(define-method set_loop
+  (of-object "ClutterTimeline")
+  (c-name "clutter_timeline_set_loop")
+  (return-type "none")
+  (parameters
+    '("gboolean" "loop")
+  )
+)
+
+(define-method rewind
+  (of-object "ClutterTimeline")
+  (c-name "clutter_timeline_rewind")
+  (return-type "none")
+)
+
+(define-method skip
+  (of-object "ClutterTimeline")
+  (c-name "clutter_timeline_skip")
+  (return-type "none")
+  (parameters
+    '("guint" "nframes")
+  )
+)
+
+(define-method advance
+  (of-object "ClutterTimeline")
+  (c-name "clutter_timeline_advance")
+  (return-type "none")
+  (parameters
+    '("guint" "frame_num")
+  )
+)
+
+(define-method get_current_frame
+  (of-object "ClutterTimeline")
+  (c-name "clutter_timeline_get_current_frame")
+  (return-type "gint")
+)
+
+(define-method get_n_frames
+  (of-object "ClutterTimeline")
+  (c-name "clutter_timeline_get_n_frames")
+  (return-type "guint")
+)
+
+
+
+;; From ../../clutter/clutter-main.h
+
+(define-function clutter_init
+  (c-name "clutter_init")
+  (return-type "int")
+  (parameters
+    '("int*" "argc")
+    '("char***" "argv")
+  )
+)
+
+(define-function main
+  (c-name "clutter_main")
+  (return-type "none")
+)
+
+(define-function stage
+  (c-name "clutter_stage")
+  (return-type "ClutterGroup*")
+)
+
+(define-function redraw
+  (c-name "clutter_redraw")
+  (return-type "none")
+  (parameters
+  )
+)
+
+(define-function xdisplay
+  (c-name "clutter_xdisplay")
+  (return-type "Display*")
+)
+
+(define-function xscreen
+  (c-name "clutter_xscreen")
+  (return-type "int")
+)
+
+(define-function root_xwindow
+  (c-name "clutter_root_xwindow")
+  (return-type "Window")
+)
+
+(define-function gl_context
+  (c-name "clutter_gl_context")
+  (return-type "GLXContext")
+)
+
+(define-function want_debug
+  (c-name "clutter_want_debug")
+  (return-type "gboolean")
+)
+
+(define-function threads_enter
+  (c-name "clutter_threads_enter")
+  (return-type "none")
+)
+
+(define-function threads_leave
+  (c-name "clutter_threads_leave")
+  (return-type "none")
+)
+
+
+
+;; From ../../clutter/clutter-event.h
+
+(define-method type
+  (of-object "ClutterKeyEvent")
+  (c-name "clutter_key_event_type")
+  (return-type "ClutterEventType")
+)
+
+(define-method time
+  (of-object "ClutterKeyEvent")
+  (c-name "clutter_key_event_time")
+  (return-type "guint32")
+)
+
+(define-method state
+  (of-object "ClutterKeyEvent")
+  (c-name "clutter_key_event_state")
+  (return-type "guint")
+)
+
+(define-method symbol
+  (of-object "ClutterKeyEvent")
+  (c-name "clutter_key_event_symbol")
+  (return-type "guint")
+)
+
+(define-method code
+  (of-object "ClutterKeyEvent")
+  (c-name "clutter_key_event_code")
+  (return-type "guint16")
+)
+
+(define-method unicode
+  (of-object "ClutterKeyEvent")
+  (c-name "clutter_key_event_unicode")
+  (return-type "guint32")
+)
+
+(define-function clutter_keysym_to_unicode
+  (c-name "clutter_keysym_to_unicode")
+  (return-type "guint32")
+  (parameters
+    '("guint" "keyval")
+  )
+)
+
+
+
+;; From ../../clutter/clutter-element.h
+
+(define-function clutter_geometry_get_type
+  (c-name "clutter_geometry_get_type")
+  (return-type "GType")
+)
+
+(define-function geometry_new
+  (c-name "clutter_geometry_new")
+  (is-constructor-of "ClutterGeometry")
+  (return-type "ClutterGeometry")
+)
+
+(define-function clutter_element_box_get_type
+  (c-name "clutter_element_box_get_type")
+  (return-type "GType")
+)
+
+(define-function element_box_new
+  (c-name "clutter_element_box_new")
+  (is-constructor-of "ClutterElementBox")
+  (return-type "ClutterElementBox")
+)
+
+(define-function clutter_element_get_type
+  (c-name "clutter_element_get_type")
+  (return-type "GType")
+)
+
+(define-method show
+  (of-object "ClutterElement")
+  (c-name "clutter_element_show")
+  (return-type "none")
+)
+
+(define-method hide
+  (of-object "ClutterElement")
+  (c-name "clutter_element_hide")
+  (return-type "none")
+)
+
+(define-method realize
+  (of-object "ClutterElement")
+  (c-name "clutter_element_realize")
+  (return-type "none")
+)
+
+(define-method unrealize
+  (of-object "ClutterElement")
+  (c-name "clutter_element_unrealize")
+  (return-type "none")
+)
+
+(define-method paint
+  (of-object "ClutterElement")
+  (c-name "clutter_element_paint")
+  (return-type "none")
+)
+
+(define-method queue_redraw
+  (of-object "ClutterElement")
+  (c-name "clutter_element_queue_redraw")
+  (return-type "none")
+)
+
+(define-method request_coords
+  (of-object "ClutterElement")
+  (c-name "clutter_element_request_coords")
+  (return-type "none")
+  (parameters
+    '("ClutterElementBox*" "box")
+  )
+)
+
+(define-method allocate_coords
+  (of-object "ClutterElement")
+  (c-name "clutter_element_allocate_coords")
+  (return-type "none")
+  (parameters
+    '("ClutterElementBox*" "box")
+  )
+)
+
+(define-method set_geometry
+  (of-object "ClutterElement")
+  (c-name "clutter_element_set_geometry")
+  (return-type "none")
+  (parameters
+    '("ClutterGeometry*" "geom")
+  )
+)
+
+(define-method get_geometry
+  (of-object "ClutterElement")
+  (c-name "clutter_element_get_geometry")
+  (return-type "none")
+  (parameters
+    '("ClutterGeometry*" "geom")
+  )
+)
+
+(define-method get_coords
+  (of-object "ClutterElement")
+  (c-name "clutter_element_get_coords")
+  (return-type "none")
+  (parameters
+    '("gint*" "x1")
+    '("gint*" "y1")
+    '("gint*" "x2")
+    '("gint*" "y2")
+  )
+)
+
+(define-method set_position
+  (of-object "ClutterElement")
+  (c-name "clutter_element_set_position")
+  (return-type "none")
+  (parameters
+    '("gint" "x")
+    '("gint" "y")
+  )
+)
+
+(define-method set_size
+  (of-object "ClutterElement")
+  (c-name "clutter_element_set_size")
+  (return-type "none")
+  (parameters
+    '("gint" "width")
+    '("gint" "height")
+  )
+)
+
+(define-method get_abs_position
+  (of-object "ClutterElement")
+  (c-name "clutter_element_get_abs_position")
+  (return-type "none")
+  (parameters
+    '("gint*" "x")
+    '("gint*" "y")
+  )
+)
+
+(define-method get_width
+  (of-object "ClutterElement")
+  (c-name "clutter_element_get_width")
+  (return-type "guint")
+)
+
+(define-method get_height
+  (of-object "ClutterElement")
+  (c-name "clutter_element_get_height")
+  (return-type "guint")
+)
+
+(define-method get_x
+  (of-object "ClutterElement")
+  (c-name "clutter_element_get_x")
+  (return-type "gint")
+)
+
+(define-method get_y
+  (of-object "ClutterElement")
+  (c-name "clutter_element_get_y")
+  (return-type "gint")
+)
+
+(define-method rotate_z
+  (of-object "ClutterElement")
+  (c-name "clutter_element_rotate_z")
+  (return-type "none")
+  (parameters
+    '("gfloat" "angle")
+    '("gint" "x")
+    '("gint" "y")
+  )
+)
+
+(define-method rotate_x
+  (of-object "ClutterElement")
+  (c-name "clutter_element_rotate_x")
+  (return-type "none")
+  (parameters
+    '("gfloat" "angle")
+    '("gint" "y")
+    '("gint" "z")
+  )
+)
+
+(define-method rotate_y
+  (of-object "ClutterElement")
+  (c-name "clutter_element_rotate_y")
+  (return-type "none")
+  (parameters
+    '("gfloat" "angle")
+    '("gint" "x")
+    '("gint" "z")
+  )
+)
+
+(define-method set_opacity
+  (of-object "ClutterElement")
+  (c-name "clutter_element_set_opacity")
+  (return-type "none")
+  (parameters
+    '("guint8" "opacity")
+  )
+)
+
+(define-method get_opacity
+  (of-object "ClutterElement")
+  (c-name "clutter_element_get_opacity")
+  (return-type "guint8")
+)
+
+(define-method set_name
+  (of-object "ClutterElement")
+  (c-name "clutter_element_set_name")
+  (return-type "none")
+  (parameters
+    '("const-gchar*" "id")
+  )
+)
+
+(define-method get_name
+  (of-object "ClutterElement")
+  (c-name "clutter_element_get_name")
+  (return-type "const-gchar*")
+)
+
+(define-method get_id
+  (of-object "ClutterElement")
+  (c-name "clutter_element_get_id")
+  (return-type "guint32")
+)
+
+(define-method set_clip
+  (of-object "ClutterElement")
+  (c-name "clutter_element_set_clip")
+  (return-type "none")
+  (parameters
+    '("gint" "xoff")
+    '("gint" "yoff")
+    '("gint" "width")
+    '("gint" "height")
+  )
+)
+
+(define-method remove_clip
+  (of-object "ClutterElement")
+  (c-name "clutter_element_remove_clip")
+  (return-type "none")
+)
+
+(define-method set_parent
+  (of-object "ClutterElement")
+  (c-name "clutter_element_set_parent")
+  (return-type "none")
+  (parameters
+    '("ClutterElement*" "parent")
+  )
+)
+
+(define-method get_parent
+  (of-object "ClutterElement")
+  (c-name "clutter_element_get_parent")
+  (return-type "ClutterElement*")
+)
+
+(define-method raise
+  (of-object "ClutterElement")
+  (c-name "clutter_element_raise")
+  (return-type "none")
+  (parameters
+    '("ClutterElement*" "below")
+  )
+)
+
+(define-method lower
+  (of-object "ClutterElement")
+  (c-name "clutter_element_lower")
+  (return-type "none")
+  (parameters
+    '("ClutterElement*" "above")
+  )
+)
+
+(define-method raise_top
+  (of-object "ClutterElement")
+  (c-name "clutter_element_raise_top")
+  (return-type "none")
+)
+
+(define-method lower_bottom
+  (of-object "ClutterElement")
+  (c-name "clutter_element_lower_bottom")
+  (return-type "none")
+)
+
+
+
+;; From ../../clutter/clutter-rectangle.h
+
+(define-function clutter_rectangle_get_type
+  (c-name "clutter_rectangle_get_type")
+  (return-type "GType")
+)
+
+(define-function clutter_rectangle_new
+  (c-name "clutter_rectangle_new")
+  (is-constructor-of "ClutterRectangle")
+  (return-type "ClutterElement*")
+  (properties
+    '("color" (argname "col"))
+  )
+)
+
+
+
+;; From ../../clutter/clutter-texture.h
+
+(define-function clutter_texture_get_type
+  (c-name "clutter_texture_get_type")
+  (return-type "GType")
+)
+
+(define-function clutter_texture_new_from_pixbuf
+  (c-name "clutter_texture_new_from_pixbuf")
+  (return-type "ClutterElement*")
+  (parameters
+    '("GdkPixbuf*" "pixbuf")
+  )
+)
+
+(define-function clutter_texture_new
+  (c-name "clutter_texture_new")
+  (is-constructor-of "ClutterTexture")
+  (return-type "ClutterElement*")
+)
+
+(define-method set_pixbuf
+  (of-object "ClutterTexture")
+  (c-name "clutter_texture_set_pixbuf")
+  (return-type "none")
+  (parameters
+    '("GdkPixbuf*" "pixbuf")
+  )
+)
+
+(define-method get_pixbuf
+  (of-object "ClutterTexture")
+  (c-name "clutter_texture_get_pixbuf")
+  (return-type "GdkPixbuf*")
+)
+
+(define-method get_base_size
+  (of-object "ClutterTexture")
+  (c-name "clutter_texture_get_base_size")
+  (return-type "none")
+  (parameters
+    '("gint*" "width")
+    '("gint*" "height")
+  )
+)
+
+(define-method bind_tile
+  (of-object "ClutterTexture")
+  (c-name "clutter_texture_bind_tile")
+  (return-type "none")
+  (parameters
+    '("gint" "index")
+  )
+)
+
+(define-method get_n_tiles
+  (of-object "ClutterTexture")
+  (c-name "clutter_texture_get_n_tiles")
+  (return-type "none")
+  (parameters
+    '("gint*" "n_x_tiles")
+    '("gint*" "n_y_tiles")
+  )
+)
+
+(define-method get_x_tile_detail
+  (of-object "ClutterTexture")
+  (c-name "clutter_texture_get_x_tile_detail")
+  (return-type "none")
+  (parameters
+    '("gint" "x_index")
+    '("gint*" "pos")
+    '("gint*" "size")
+    '("gint*" "waste")
+  )
+)
+
+(define-method get_y_tile_detail
+  (of-object "ClutterTexture")
+  (c-name "clutter_texture_get_y_tile_detail")
+  (return-type "none")
+  (parameters
+    '("gint" "y_index")
+    '("gint*" "pos")
+    '("gint*" "size")
+    '("gint*" "waste")
+  )
+)
+
+(define-method has_generated_tiles
+  (of-object "ClutterTexture")
+  (c-name "clutter_texture_has_generated_tiles")
+  (return-type "gboolean")
+)
+
+(define-method is_tiled
+  (of-object "ClutterTexture")
+  (c-name "clutter_texture_is_tiled")
+  (return-type "gboolean")
+)
+
+
+
+;; From ../../clutter/clutter-color.h
+
+(define-function clutter_color_new
+  (c-name "clutter_color_new")
+  (return-type "ClutterColor")
+  (parameters
+    '("guint8" "r")
+    '("guint8" "g")
+    '("guint8" "b")
+    '("guint8" "a")
+  )
+)
+
+(define-method set
+  (of-object "ClutterColor")
+  (c-name "clutter_color_set")
+  (return-type "none")
+  (parameters
+    '("guint8" "r")
+    '("guint8" "g")
+    '("guint8" "b")
+    '("guint8" "a")
+  )
+)
+
+(define-method get
+  (of-object "ClutterColor")
+  (c-name "clutter_color_get")
+  (return-type "none")
+  (parameters
+    '("guint8*" "r")
+    '("guint8*" "g")
+    '("guint8*" "b")
+    '("guint8*" "a")
+  )
+)
+
+
+
+;; From ../../clutter/clutter-clone-texture.h
+
+(define-function clutter_clone_texture_get_type
+  (c-name "clutter_clone_texture_get_type")
+  (return-type "GType")
+)
+
+(define-function clutter_clone_texture_new
+  (c-name "clutter_clone_texture_new")
+  (is-constructor-of "ClutterCloneTexture")
+  (return-type "ClutterElement*")
+  (properties
+    '("parent-texture" (argname "texture"))
+  )
+)
+
+
+
+;; From ../../clutter/clutter-video-texture.h
+
+(define-function clutter_video_texture_error_quark
+  (c-name "clutter_video_texture_error_quark")
+  (return-type "GQuark")
+)
+
+(define-function clutter_video_texture_get_type
+  (c-name "clutter_video_texture_get_type")
+  (return-type "GType")
+)
+
+(define-function clutter_video_texture_new
+  (c-name "clutter_video_texture_new")
+  (is-constructor-of "ClutterVideoTexture")
+  (return-type "ClutterElement*")
+)
+
+(define-method open
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_open")
+  (return-type "gboolean")
+  (parameters
+    '("const-gchar*" "mrl")
+    '("const-gchar*" "subtitle_uri")
+    '("GError**" "error")
+  )
+)
+
+(define-method play
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_play")
+  (return-type "gboolean")
+  (parameters
+    '("GError**" "error")
+  )
+)
+
+(define-method pause
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_pause")
+  (return-type "none")
+)
+
+(define-method can_direct_seek
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_can_direct_seek")
+  (return-type "gboolean")
+)
+
+(define-method seek_time
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_seek_time")
+  (return-type "gboolean")
+  (parameters
+    '("gint64" "time")
+    '("GError**" "gerror")
+  )
+)
+
+(define-method seek
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_seek")
+  (return-type "gboolean")
+  (parameters
+    '("float" "position")
+    '("GError**" "error")
+  )
+)
+
+(define-method stop
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_stop")
+  (return-type "none")
+)
+
+(define-method can_set_volume
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_can_set_volume")
+  (return-type "gboolean")
+)
+
+(define-method set_volume
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_set_volume")
+  (return-type "none")
+  (parameters
+    '("int" "volume")
+  )
+)
+
+(define-method get_volume
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_get_volume")
+  (return-type "int")
+)
+
+(define-method get_current_time
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_get_current_time")
+  (return-type "gint64")
+)
+
+(define-method get_stream_length
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_get_stream_length")
+  (return-type "gint64")
+)
+
+(define-method is_playing
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_is_playing")
+  (return-type "gboolean")
+)
+
+(define-method is_seekable
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_is_seekable")
+  (return-type "gboolean")
+)
+
+(define-method get_position
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_get_position")
+  (return-type "float")
+)
+
+(define-method set_aspect_ratio
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_set_aspect_ratio")
+  (return-type "none")
+  (parameters
+    '("ClutterVideoTextureAspectRatio" "ratio")
+  )
+)
+
+(define-method get_aspect_ratio
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_get_aspect_ratio")
+  (return-type "ClutterVideoTextureAspectRatio")
+)
+
+(define-method get_metadata
+  (of-object "ClutterVideoTexture")
+  (c-name "clutter_video_texture_get_metadata")
+  (return-type "none")
+  (parameters
+    '("ClutterVideoTextureMetadataType" "type")
+    '("GValue*" "value")
+  )
+)
+
+
+
+;; From ../../clutter/clutter-label.h
+
+(define-function clutter_label_get_type
+  (c-name "clutter_label_get_type")
+  (return-type "GType")
+)
+
+(define-function clutter_label_new_with_text
+  (c-name "clutter_label_new_with_text")
+  (return-type "ClutterElement*")
+  (parameters
+    '("const-gchar*" "font_desc")
+    '("const-gchar*" "text")
+  )
+)
+
+(define-function clutter_label_new
+  (c-name "clutter_label_new")
+  (is-constructor-of "ClutterLabel")
+  (return-type "ClutterElement*")
+)
+
+(define-method set_text
+  (of-object "ClutterLabel")
+  (c-name "clutter_label_set_text")
+  (return-type "none")
+  (parameters
+    '("const-gchar*" "text")
+  )
+)
+
+(define-method set_font
+  (of-object "ClutterLabel")
+  (c-name "clutter_label_set_font")
+  (return-type "none")
+  (parameters
+    '("const-gchar*" "desc")
+  )
+)
+
+(define-method set_color
+  (of-object "ClutterLabel")
+  (c-name "clutter_label_set_color")
+  (return-type "none")
+  (parameters
+    '("guint32" "pixel")
+  )
+)
+
+(define-method set_text_extents
+  (of-object "ClutterLabel")
+  (c-name "clutter_label_set_text_extents")
+  (return-type "none")
+  (parameters
+    '("gint" "width")
+    '("gint" "height")
+  )
+)
+
+
+
+;; From ../../clutter/clutter-group.h
+
+(define-function clutter_group_get_type
+  (c-name "clutter_group_get_type")
+  (return-type "GType")
+)
+
+(define-function clutter_group_new
+  (c-name "clutter_group_new")
+  (is-constructor-of "ClutterGroup")
+  (return-type "ClutterGroup*")
+)
+
+(define-method add
+  (of-object "ClutterGroup")
+  (c-name "clutter_group_add")
+  (return-type "none")
+  (parameters
+    '("ClutterElement*" "element")
+  )
+)
+
+(define-method add_many_valist
+  (of-object "ClutterGroup")
+  (c-name "clutter_group_add_many_valist")
+  (return-type "none")
+  (parameters
+    '("ClutterElement*" "first_element")
+    '("va_list" "args")
+  )
+)
+
+(define-method add_many
+  (of-object "ClutterGroup")
+  (c-name "clutter_group_add_many")
+  (return-type "none")
+  (parameters
+    '("ClutterElement*" "first_element")
+  )
+  (varargs #t)
+)
+
+(define-method remove
+  (of-object "ClutterGroup")
+  (c-name "clutter_group_remove")
+  (return-type "none")
+  (parameters
+    '("ClutterElement*" "element")
+  )
+)
+
+(define-method show_all
+  (of-object "ClutterGroup")
+  (c-name "clutter_group_show_all")
+  (return-type "none")
+)
+
+(define-method hide_all
+  (of-object "ClutterGroup")
+  (c-name "clutter_group_hide_all")
+  (return-type "none")
+)
+
+(define-method find_child_by_id
+  (of-object "ClutterGroup")
+  (c-name "clutter_group_find_child_by_id")
+  (return-type "ClutterElement*")
+  (parameters
+    '("guint" "id")
+  )
+)
+
+(define-method raise
+  (of-object "ClutterGroup")
+  (c-name "clutter_group_raise")
+  (return-type "none")
+  (parameters
+    '("ClutterElement*" "element")
+    '("ClutterElement*" "sibling")
+  )
+)
+
+(define-method lower
+  (of-object "ClutterGroup")
+  (c-name "clutter_group_lower")
+  (return-type "none")
+  (parameters
+    '("ClutterElement*" "element")
+    '("ClutterElement*" "sibling")
+  )
+)
+
+
+
+;; From ../../clutter/clutter-stage.h
+
+(define-function clutter_stage_get_type
+  (c-name "clutter_stage_get_type")
+  (return-type "GType")
+)
+
+(define-method get_xwindow
+  (of-object "ClutterStage")
+  (c-name "clutter_stage_get_xwindow")
+  (return-type "Window")
+)
+
+(define-method set_color
+  (of-object "ClutterStage")
+  (c-name "clutter_stage_set_color")
+  (return-type "none")
+  (parameters
+    '("ClutterColor" "color")
+  )
+)
+
+(define-method get_color
+  (of-object "ClutterStage")
+  (c-name "clutter_stage_get_color")
+  (return-type "ClutterColor")
+)
+
+(define-method pick
+  (of-object "ClutterStage")
+  (c-name "clutter_stage_pick")
+  (return-type "ClutterElement*")
+  (parameters
+    '("gint" "x")
+    '("gint" "y")
+  )
+)
+
+
+
+;; From ../../clutter/clutter-enum-types.h
+
+(define-function clutter_event_type_get_type
+  (c-name "clutter_event_type_get_type")
+  (return-type "GType")
+)
+
+(define-function clutter_element_transform_get_type
+  (c-name "clutter_element_transform_get_type")
+  (return-type "GType")
+)
+
+(define-function clutter_element_flags_get_type
+  (c-name "clutter_element_flags_get_type")
+  (return-type "GType")
+)
+
+(define-function clutter_video_texture_error_get_type
+  (c-name "clutter_video_texture_error_get_type")
+  (return-type "GType")
+)
+
+(define-function clutter_video_texture_aspect_ratio_get_type
+  (c-name "clutter_video_texture_aspect_ratio_get_type")
+  (return-type "GType")
+)
+
+(define-function clutter_video_texture_metadata_type_get_type
+  (c-name "clutter_video_texture_metadata_type_get_type")
+  (return-type "GType")
+)
+
+
diff --git a/bindings/python/clutter.override b/bindings/python/clutter.override
new file mode 100644 (file)
index 0000000..19a96d7
--- /dev/null
@@ -0,0 +1,500 @@
+/* -*- C -*- */
+%%
+headers
+#define NO_IMPORT_PYGOBJECT
+#include "pygobject.h"
+#include <clutter/clutter-keysyms.h>
+#include <clutter/clutter-event.h>
+#include <clutter/clutter-main.h>
+#include <clutter/clutter-timeline.h>
+#include <clutter/clutter-stage.h>
+#include <clutter/clutter-color.h>
+#include <clutter/clutter-element.h>
+#include <clutter/clutter-rectangle.h>
+#include <clutter/clutter-group.h>
+#include <clutter/clutter-texture.h>
+#include <clutter/clutter-clone-texture.h>
+#include <clutter/clutter-video-texture.h>
+#include <clutter/clutter-label.h>
+#include <clutter/clutter-util.h>
+#include <clutter/clutter-enum-types.h>
+%%
+modulename clutter
+%%
+import gobject.GObject as PyGObject_Type
+import gtk.gdk.Pixbuf as PyGdkPixbuf_Type
+%%
+ignore
+  clutter_video_texture_error_quark
+  clutter_group_add_many_valist
+  clutter_stage_get_xwindow
+  clutter_init
+  clutter_xdisplay
+  clutter_root_xwindow
+  clutter_gl_context
+%%
+ignore-glob
+  *_get_type
+%%
+override clutter_geometry_new kwargs
+static int
+_wrap_clutter_geometry_new (PyGBoxed *self, PyObject *args, PyObject *kwargs)
+{
+       static char *kwlist[] = { "x", "y", "width", "height", NULL };
+       ClutterGeometry geom = { 0, 0, 0, 0 };
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                        "|iiii:ClutterGeometry.__init__",
+                                        kwlist,
+                                        &(geom.x), &(geom.y),
+                                        &(geom.width), &(geom.height)))
+               return -1;
+       
+       self->boxed = g_boxed_copy (CLUTTER_TYPE_GEOMETRY, &geom);
+       self->free_on_dealloc = TRUE;
+       self->gtype = CLUTTER_TYPE_GEOMETRY;
+       
+       return 0;
+}
+%%
+override-slot ClutterGeometry.tp_as_sequence
+static int
+_wrap_clutter_geometry_length (PyGBoxed *self)
+{
+       return 4;
+}
+static PyObject *
+_wrap_clutter_geometry_getitem(PyGBoxed *self, int pos)
+{
+       ClutterGeometry *geom;
+
+       if (pos < 0)
+               pos += 4;
+       
+       if (pos < 0 || pos >= 4) {
+               PyErr_SetString(PyExc_IndexError, "index out of range");
+               
+               return NULL;
+       }
+
+       geom = pyg_boxed_get (self, ClutterGeometry);
+       switch (pos) {
+               case 0: return PyInt_FromLong (geom->x);
+               case 1: return PyInt_FromLong (geom->y);
+               case 2: return PyInt_FromLong (geom->width);
+               case 3: return PyInt_FromLong (geom->height);
+               default:
+                       g_assert_not_reached();
+                       return NULL;
+       }
+}
+static int
+_wrap_clutter_geometry_setitem (PyGBoxed *self, int pos, PyObject *value)
+{
+       ClutterGeometry *geom;
+       gint val;
+
+       if (pos < 0)
+               pos += 4;
+       
+       if (pos < 0 || pos >= 4) {
+               PyErr_SetString(PyExc_IndexError, "index out of range");
+               
+               return -1;
+       }
+
+       geom = pyg_boxed_get (self, ClutterGeometry);
+       val = PyInt_AsLong (value);
+       if (PyErr_Occurred ())
+               return -1;
+       
+       switch(pos) {
+               case 0: geom->x      = val; break;
+               case 1: geom->y      = val; break;
+               case 2: geom->width  = val; break;
+               case 3: geom->height = val; break;
+               default:
+                       g_assert_not_reached();
+                       return -1;
+       }
+
+       return 0;
+}
+static PySequenceMethods _wrap_clutter_geometry_tp_as_sequence = {
+       (inquiry) _wrap_clutter_geometry_length,
+       (binaryfunc) 0,
+       (intargfunc) 0,
+       (intargfunc) _wrap_clutter_geometry_getitem,
+       (intintargfunc) 0,
+       (intobjargproc) _wrap_clutter_geometry_setitem,
+       (intintobjargproc) 0
+};
+%%
+override-attr ClutterGeometry.x
+static int
+_wrap_clutter_geomtry__set_x (PyGBoxed *self, PyObject *value, void *closure)
+{
+       gint val;
+
+       val = PyInt_AsLong (value);
+       if (PyErr_Occurred ())
+               return -1;
+
+       pyg_boxed_get (self, ClutterGeometry)->x = val;
+
+       return 0;
+}
+%%
+override-attr ClutterGeometry.y
+static int
+_wrap_clutter_geometry__set_y (PyGBoxed *self, PyObject *value, void *closure)
+{
+       gint val;
+
+       val = PyInt_AsLong (value);
+       if (PyErr_Occurred ())
+               return -1;
+
+       pyg_boxed_get (self, ClutterGeometry)->y = val;
+
+       return 0;
+}
+%%
+override-attr ClutterGeometry.width
+static int
+_wrap_clutter_geometry__set_width (PyGBoxed *self, PyObject *value, void *closure)
+{
+       gint val;
+
+       val = PyInt_AsLong (value);
+       if (PyErr_Occurred ())
+               return -1;
+       
+       pyg_boxed_get(self, ClutterGeometry)->width = val;
+       
+       return 0;
+}
+%%
+override-attr ClutterGeometry.height
+static int
+_wrap_clutter_geometry__set_height (PyGBoxed *self, PyObject *value, void *closure)
+{
+       gint val;
+
+       val = PyInt_AsLong (value);
+       if (PyErr_Occurred ())
+               return -1;
+       
+       pyg_boxed_get (self, ClutterGeometry)->height = val;
+
+       return 0;
+}
+%%
+override clutter_element_box_new kwargs
+static int
+_wrap_clutter_element_box_new (PyGBoxed *self, PyObject *args, PyObject *kwargs)
+{
+       static char *kwlist[] = { "x1", "y1", "x2", "y2", NULL };
+       ClutterElementBox box = { 0, 0, 0, 0 };
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                        "|iiii:ClutterElementBox.__init__",
+                                        kwlist,
+                                        &(box.x1), &(box.y1),
+                                        &(box.x2), &(box.y2)))
+               return -1;
+       
+       self->boxed = g_boxed_copy (CLUTTER_TYPE_ELEMENT_BOX, &box);
+       self->free_on_dealloc = TRUE;
+       self->gtype = CLUTTER_TYPE_ELEMENT_BOX;
+       
+       return 0;
+}
+%%
+override-slot ClutterElementBox.tp_as_sequence
+static int
+_wrap_clutter_element_box_length (PyGBoxed *self)
+{
+       return 4;
+}
+static PyObject *
+_wrap_clutter_element_box_getitem(PyGBoxed *self, int pos)
+{
+       ClutterElementBox *box;
+
+       if (pos < 0)
+               pos += 4;
+       
+       if (pos < 0 || pos >= 4) {
+               PyErr_SetString(PyExc_IndexError, "index out of range");
+               
+               return NULL;
+       }
+
+       box = pyg_boxed_get (self, ClutterElementBox);
+       switch (pos) {
+               case 0: return PyInt_FromLong (box->x1);
+               case 1: return PyInt_FromLong (box->y1);
+               case 2: return PyInt_FromLong (box->x2);
+               case 3: return PyInt_FromLong (box->y2);
+               default:
+                       g_assert_not_reached();
+                       return NULL;
+       }
+}
+static int
+_wrap_clutter_element_box_setitem (PyGBoxed *self, int pos, PyObject *value)
+{
+       ClutterElementBox *box;
+       gint val;
+
+       if (pos < 0)
+               pos += 4;
+       
+       if (pos < 0 || pos >= 4) {
+               PyErr_SetString(PyExc_IndexError, "index out of range");
+               
+               return -1;
+       }
+
+       box = pyg_boxed_get (self, ClutterElementBox);
+       val = PyInt_AsLong (value);
+       if (PyErr_Occurred ())
+               return -1;
+       
+       switch(pos) {
+               case 0: box->x1 = val; break;
+               case 1: box->y1 = val; break;
+               case 2: box->x2 = val; break;
+               case 3: box->y2 = val; break;
+               default:
+                       g_assert_not_reached();
+                       return -1;
+       }
+
+       return 0;
+}
+static PySequenceMethods _wrap_clutter_element_box_tp_as_sequence = {
+       (inquiry) _wrap_clutter_element_box_length,
+       (binaryfunc) 0,
+       (intargfunc) 0,
+       (intargfunc) _wrap_clutter_element_box_getitem,
+       (intintargfunc) 0,
+       (intobjargproc) _wrap_clutter_element_box_setitem,
+       (intintobjargproc) 0
+};
+%%
+override-attr ClutterElementBox.x1
+static int
+_wrap_clutter_element_box__set_x1 (PyGBoxed *self, PyObject *value, void *closure)
+{
+       gint val;
+
+       val = PyInt_AsLong (value);
+       if (PyErr_Occurred ())
+               return -1;
+
+       pyg_boxed_get (self, ClutterElementBox)->x1 = val;
+
+       return 0;
+}
+%%
+override-attr ClutterElementBox.y1
+static int
+_wrap_clutter_element_box__set_y1 (PyGBoxed *self, PyObject *value, void *closure)
+{
+       gint val;
+
+       val = PyInt_AsLong (value);
+       if (PyErr_Occurred ())
+               return -1;
+
+       pyg_boxed_get (self, ClutterElementBox)->y1 = val;
+
+       return 0;
+}
+%%
+override-attr ClutterElementBox.x2
+static int
+_wrap_clutter_element_box__set_x2 (PyGBoxed *self, PyObject *value, void *closure)
+{
+       gint val;
+
+       val = PyInt_AsLong (value);
+       if (PyErr_Occurred ())
+               return -1;
+       
+       pyg_boxed_get(self, ClutterElementBox)->x2 = val;
+       
+       return 0;
+}
+%%
+override-attr ClutterElementBox.y2
+static int
+_wrap_clutter_element_box__set_y2 (PyGBoxed *self, PyObject *value, void *closure)
+{
+       gint val;
+
+       val = PyInt_AsLong (value);
+       if (PyErr_Occurred ())
+               return -1;
+       
+       pyg_boxed_get (self, ClutterElementBox)->y2 = val;
+
+       return 0;
+}
+%%
+override clutter_element_get_coords
+static PyObject *
+_wrap_clutter_element_get_coords (PyGObject *self)
+{
+       gint x1, y1;
+       gint x2, y2;
+
+       clutter_element_get_coords (CLUTTER_ELEMENT (self->obj),
+                                   &x1, &y1,
+                                   &x2, &y2);
+       return Py_BuildValue("(iiii)", x1, y1, x2, y2);
+}
+%%
+override clutter_element_get_abs_position
+static PyObject *
+_wrap_clutter_element_get_abs_position (PyGObject *self)
+{
+       gint pos_x, pos_y;
+
+       clutter_element_get_abs_position (CLUTTER_ELEMENT (self->obj),
+                                         &pos_x,
+                                         &pos_y);
+       return Py_BuildValue("(ii)", pos_x, pos_y);
+}
+%%
+override clutter_texture_get_base_size
+static PyObject *
+_wrap_clutter_texture_get_base_size (PyGObject *self)
+{
+       gint width, height;
+
+       clutter_texture_get_base_size (CLUTTER_TEXTURE (self->obj),
+                                      &width,
+                                      &height);
+       return Py_BuildValue ("(ii)", width, height);
+}
+%%
+override clutter_texture_get_n_tiles
+static PyObject *
+_wrap_clutter_texture_get_n_tiles (PyGObject *self)
+{
+       gint n_x_tiles, n_y_tiles;
+
+       clutter_texture_get_n_tiles (CLUTTER_TEXTURE (self->obj),
+                                    &n_x_tiles,
+                                    &n_y_tiles);
+       return Py_BuildValue ("(ii)", n_x_tiles, n_y_tiles);
+}
+%%
+override clutter_texture_get_x_tile_detail kwargs
+static PyObject *
+_wrap_clutter_texture_get_x_tile_detail (PyGObject *self,
+                                         PyObject  *args,
+                                        PyObject  *kwargs)
+{
+       static char *kwlist[] = { "x_index", NULL };
+       gint x_index;
+       gint pos, size, waste;
+
+       if (!PyArg_ParseTupleAndKeywords (args, kwargs,
+                                         "i:ClutterTexture.get_x_tile_detail",
+                                         kwlist, &x_index))
+               return NULL;
+       
+       clutter_texture_get_x_tile_detail (CLUTTER_TEXTURE (self->obj),
+                                          x_index,
+                                          &pos, &size, &waste);
+       return Py_BuildValue ("(iii)", pos, size, waste);
+}
+%%
+override clutter_texture_get_y_tile_detail kwargs
+static PyObject *
+_wrap_clutter_texture_get_y_tile_detail (PyGObject *self,
+                                         PyObject  *args,
+                                        PyObject  *kwargs)
+{
+       static char *kwlist[] = { "y_index", NULL };
+       gint y_index;
+       gint pos, size, waste;
+
+       if (!PyArg_ParseTupleAndKeywords (args, kwargs,
+                                         "i:ClutterTexture.get_y_tile_detail",
+                                         kwlist, &y_index))
+               return NULL;
+       
+       clutter_texture_get_y_tile_detail (CLUTTER_TEXTURE (self->obj),
+                                          y_index,
+                                          &pos, &size, &waste);
+       return Py_BuildValue ("(iii)", pos, size, waste);
+}
+%%
+override clutter_group_add_many
+static PyObject *
+_wrap_clutter_group_add_many (PyGObject *self,
+                             PyObject  *args)
+{
+       ClutterGroup *group;
+       int i, len;
+
+       if ((len = PyTuple_Size(args)) < 1) {
+               PyErr_SetString(PyExc_TypeError,
+                               "requires at least one argument");
+               return NULL;
+       }
+
+       group = CLUTTER_GROUP (self->obj);
+
+       for (i = 0; i < len; i++) {
+               PyGObject *pyelement;
+               ClutterElement *element;
+
+               pyelement = (PyGObject *) PyTuple_GetItem (args, i);
+               if (!pygobject_check (pyelement, &PyClutterElement_Type)) {
+                       PyErr_SetString (PyExc_TypeError,
+                                        "Expected a ClutterElement");
+                       return NULL;
+               }
+               
+               element = CLUTTER_ELEMENT (pyelement->obj);
+
+               clutter_group_add (group, element);
+       }
+
+       Py_INCREF (Py_None);
+       return Py_None;
+}
+%%
+override clutter_main noargs
+static PyObject *
+_wrap_clutter_main (PyObject *self)
+{
+       pyg_begin_allow_threads;
+       clutter_main ();
+       pyg_end_allow_threads;
+
+       if (PyErr_Occurred ())
+               return NULL;
+       Py_INCREF (Py_None);
+       return Py_None;
+}
+%%
+override clutter_threads_enter noargs
+static PyObject *
+_wrap_clutter_threads_enter (PyObject *self)
+{
+       /* must allow threads while acquiring lock, or no other python
+         * code will execute while we wait! */
+       pyg_begin_allow_threads;
+       clutter_threads_enter ();
+       pyg_end_allow_threads;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
diff --git a/bindings/python/cluttermodule.c b/bindings/python/cluttermodule.c
new file mode 100644 (file)
index 0000000..6d11647
--- /dev/null
@@ -0,0 +1,26 @@
+#include <pygobject.h>
+/* #include <pygtk/pygtk.h> */
+
+void clutter_register_classes (PyObject *d);
+extern PyMethodDef clutter_functions[];
+
+DL_EXPORT (void)
+initclutter (void)
+{
+  PyObject *m, *d;
+
+  init_pygobject ();
+  /* init_pygtk(); */
+
+  m = Py_InitModule ("clutter", clutter_functions);
+  d = PyModule_GetDict (m);
+
+  clutter_register_classes (d);
+
+  if (PyErr_Occurred ()) 
+    {
+      Py_FatalError ("can't initialise module clutter");
+    }
+  else
+    clutter_init(NULL, NULL);
+}
diff --git a/clutter.pc.in b/clutter.pc.in
new file mode 100644 (file)
index 0000000..8ba3c1b
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: clutter-@CLUTTER_MAJORMINOR@
+Description: Clutter library
+Version: @VERSION@
+Libs: -L${libdir} -lclutter-@CLUTTER_MAJORMINOR@ 
+Cflags: -I${includedir}/clutter-@CLUTTER_MAJORMINOR@
+Requires: pangoft2 glib-2.0 >= 2.8 gthread-2.0 gdk-pixbuf-2.0 gstreamer-0.10 gstreamer-plugins-base-0.10
index 5cdba89..b1caab1 100644 (file)
-source_h = pixbuf.h util.h fonts.h \
-          cltr.h                  \
-          cltr-private.h          \
-          cltr-glu.h              \
-          cltr-animator.h         \
-          cltr-events.h           \
-          cltr-texture.h          \
-          cltr-widget.h           \
-          cltr-window.h           \
-          cltr-photo-grid.h       \
-          cltr-video.h            \
-          cltr-list.h             \
-          cltr-overlay.h          \
-          cltr-label.h            \
-          cltr-button.h           \
-          cltr-scratch.h
-
-source_c = pixbuf.c util.c fonts.c \
-           cltr-core.c             \
-           cltr-glu.c              \
-           cltr-animator.c         \
-           cltr-texture.c          \
-           cltr-widget.c           \
-           cltr-events.c          \
-           cltr-window.c           \
-           cltr-photo-grid.c      \
-           cltr-video.c           \
-           cltr-list.c                    \
-           cltr-overlay.c          \
-           cltr-label.c            \
-           cltr-button.c           \
-           cltr-scratch.c
-
-AM_CFLAGS = @GCC_FLAGS@ @CLTR_CFLAGS@  $(GST_CFLAGS) $(GCONF_CFLAGS)
-
-lib_LTLIBRARIES      = libclutter.la
-libclutter_la_SOURCES     = $(source_c) $(source_h)
-libclutter_la_LIBADD      = @CLTR_LIBS@ $(GST_LIBS) $(GCONF_LIBS)
-
-# http://sources.redhat.com/autobook/autobook/autobook_91.html#SEC91
-# current : revision : age
-
-libclutter_la_LDFLAGS = -version-info 0:0:0
-
-clutterheadersdir = $(includedir)/clutter
-clutterheaders_DATA = $(source_h)
+MARSHALFILES = clutter-marshal.c clutter-marshal.h
+ENUMFILES = clutter-enum-types.c clutter-enum-types.h
+GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0`
+GLIB_MKENUMS=`pkg-config --variable=glib_mkenums glib-2.0`
+
+BUILT_SOURCES = $(MARSHALFILES) $(ENUMFILES)
+
+source_h = clutter-keysyms.h       \
+          clutter-util.h          \
+           clutter-event.h         \
+          clutter-color.h         \
+          clutter-timeline.h      \
+          clutter-element.h       \
+          clutter-group.h         \
+          clutter-stage.h         \
+          clutter-rectangle.h     \
+          clutter-texture.h       \
+          clutter-clone-texture.h \
+          clutter-video-texture.h \
+          clutter-label.h         \
+           clutter-main.h          
+
+clutter-marshal.h: clutter-marshal.list
+       ( $(GLIB_GENMARSHAL) --prefix=clutter_marshal $(srcdir)/clutter-marshal.list --header > clutter-marshal.h )
+
+clutter-marshal.c: clutter-marshal.h
+       ( $(GLIB_GENMARSHAL) --prefix=clutter_marshal $(srcdir)/clutter-marshal.list --body --header > clutter-marshal.c )
+
+clutter-enum-types.h: stamp-clutter-enum-types.h
+       @true
+stamp-clutter-enum-types.h: $(source_h) Makefile
+       $(GLIB_MKENUMS) \
+               --fhead "#ifndef __CLUTTER_ENUM_TYPES_H__\n" \
+                --fhead "#define __CLUTTER_ENUM_TYPES_H__\n\n" \
+               --fhead "G_BEGIN_DECLS\n\n" \
+               --ftail "G_END_DECLS\n\n" \
+               --ftail "#endif\n" \
+               --fprod "/* --- @filename@ --- */\n" \
+               --eprod "#define CLUTTER_TYPE_@ENUMSHORT@ @enum_name@_get_type()\n" \
+               --eprod "GType @enum_name@_get_type (void);\n\n" \
+       $(source_h) >> xgen-ceth \
+       && (cmp xgen-ceth clutter-enum-types.h || cp xgen-ceth clutter-enum-types.h) \
+       && rm -f xgen-ceth \
+       && echo timestamp > $(@F)
+
+clutter-enum-types.c: clutter-enum-types.h
+       $(GLIB_MKENUMS) \
+               --fhead "#include <glib-object.h>\n" \
+               --fhead "#include \"clutter-enum-types.h\"\n" \
+               --fprod "\n/* enumerations from \"@filename@\" */" \
+               --fprod "\n#include \"@filename@\"" \
+               --vhead "static const G@Type@Value _@enum_name@_values[] = {" \
+               --vprod "  { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+               --vtail "  { 0, NULL, NULL }\n};\n\n" \
+               --vtail "GType\n@enum_name@_get_type (void)\n{\n" \
+               --vtail "  static GType type = 0;\n\n" \
+               --vtail "  if (!type)\n" \
+               --vtail "    type = g_@type@_register_static (\"@EnumName@\", _@enum_name@_values);\n\n" \
+               --vtail "  return type;\n}\n\n" \
+       $(source_h) >> xgen-cetc \
+       && cp xgen-cetc clutter-enum-types.c \
+       && rm -f xgen-cetc
+
+CLEANFILES = $(BUILT_SOURCES) stamp-clutter-enum-types.h
+
+source_c = clutter-main.c          \
+          clutter-util.c          \
+           clutter-event.c         \
+          clutter-color.c         \
+          clutter-timeline.c      \
+          clutter-group.c         \
+          clutter-stage.c         \
+          clutter-rectangle.c     \
+          clutter-texture.c       \
+          clutter-clone-texture.c \
+          clutter-video-texture.c \
+          clutter-label.c         \
+           clutter-element.c      \
+          clutter-enum-types.c
+
+source_h_priv = clutter-private.h
+
+libclutter_@CLUTTER_MAJORMINOR@_la_SOURCES = $(MARSHALFILES) \
+                                             $(source_c)     \
+                                             $(source_h)     \
+                                             $(source_h_priv)
+
+INCLUDES = @GCC_FLAGS@ @CLUTTER_CFLAGS@  $(GST_CFLAGS)
+
+lib_LTLIBRARIES = libclutter-@CLUTTER_MAJORMINOR@.la
+
+libclutter_@CLUTTER_MAJORMINOR@_la_LIBADD  = @CLUTTER_LIBS@ $(GST_LIBS)
+libclutter_@CLUTTER_MAJORMINOR@_la_LDFLAGS = @CLUTTER_LT_LDFLAGS@
+
+clutterheadersdir = $(includedir)/clutter-@CLUTTER_MAJORMINOR@/clutter
+clutterheaders_DATA = $(source_h)              \
+                     clutter-marshal.h         \
+                     clutter-enum-types.h      \
+                     clutter.h
+
+EXTRA_DIST = clutter-marshal.list
diff --git a/clutter/cltr-animator.c b/clutter/cltr-animator.c
deleted file mode 100644 (file)
index a472770..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-#include "cltr-animator.h"
-#include "cltr-private.h"
-
-
-struct CltrAnimator 
-{
-  CltrWidget      *widget;
-
-  CltrAnimatorType type;
-
-  gint        fps;
-  int         n_steps, step;
-
-  CltrAnimatorFinishFunc anim_finish_cb;
-  gpointer              *anim_finish_data;
-
-  WidgetPaintMethod      wrapped_paint_func;
-
-  int         zoom_end_x1, zoom_end_y1, zoom_end_x2, zoom_end_y2;
-  int         zoom_start_x1, zoom_start_y1, zoom_start_x2, zoom_start_y2;
-
-  int         move_start_x1, move_start_y1, move_end_x1, move_end_y1;
-};
-
-
-static void
-cltr_animator_wrapped_paint(CltrWidget *widget);
-
-CltrAnimator*
-cltr_animator_zoom_new(CltrWidget *widget,
-                      int         src_x1,
-                      int         src_y1,
-                      int         src_x2,
-                      int         src_y2,
-                      int         dst_x1,
-                      int         dst_y1,
-                      int         dst_x2,
-                      int         dst_y2)
-{
-  CltrAnimator *anim = g_malloc0(sizeof(CltrAnimator));
-
-  anim->type = CltrAnimatorZoom;
-
-  anim->zoom_end_x1 = dst_x1;
-  anim->zoom_end_x2 = dst_x2;
-  anim->zoom_end_y1 = dst_y1;
-  anim->zoom_end_y2 = dst_y2;
-
-  anim->zoom_start_x1 = src_x1;
-  anim->zoom_start_x2 = src_x2;
-  anim->zoom_start_y1 = src_y1;
-  anim->zoom_start_y2 = src_y2;
-
-  anim->wrapped_paint_func = widget->paint;
-
-  anim->widget = widget;
-  widget->anim = anim;
-
-  anim->n_steps = 10;
-  anim->step    = 0;
-  anim->fps     = 50;
-
-  return anim;
-}
-
-CltrAnimator*
-cltr_animator_move_new(CltrWidget *widget,
-                      int         src_x1,
-                      int         src_y1,
-                      int         dst_x1,
-                      int         dst_y1)
-{
-  CltrAnimator *anim = g_malloc0(sizeof(CltrAnimator));
-
-  anim->type = CltrAnimatorMove;
-
-  anim->move_start_x1 = src_x1;
-  anim->move_start_y1 = src_y1;
-  anim->move_end_x1   = dst_x1;
-  anim->move_end_y1   = dst_y1;
-
-  anim->wrapped_paint_func = widget->paint;
-
-  anim->widget = widget;
-  widget->anim = anim;
-
-  anim->n_steps = 10;
-  anim->step    = 0;
-  anim->fps     = 50;
-
-  return anim;
-}
-
-
-CltrAnimator*
-cltr_animator_fullzoom_new(CltrWidget *widget,
-                          int         x1,
-                          int         y1,
-                          int         x2,
-                          int         y2)
-{
-  CltrAnimator *anim = g_malloc0(sizeof(CltrAnimator));
-
-  anim->type = CltrAnimatorFullZoom;
-  anim->zoom_end_x1 = x1;
-  anim->zoom_end_x2 = x2;
-  anim->zoom_end_y1 = y1;
-  anim->zoom_end_y2 = y2;
-
-  anim->zoom_start_x1 = cltr_widget_abs_x(widget);
-  anim->zoom_start_x2 = cltr_widget_abs_x2(widget);
-  anim->zoom_start_y1 = cltr_widget_abs_y(widget);
-  anim->zoom_start_y2 = cltr_widget_abs_y2(widget);
-
-  anim->wrapped_paint_func = widget->paint;
-
-  anim->widget = widget;
-  widget->anim = anim;
-
-  anim->n_steps = 10;
-  anim->step    = 0;
-  anim->fps     = 50;
-
-  return anim;
-}
-
-
-CltrAnimator*
-cltr_animator_new(CltrWidget *widget)
-{
-  return NULL;
-}
-
-void
-cltr_animator_set_args(CltrAnimator *anim)
-{
-
-}
-
-static void
-cltr_animator_wrapped_move_paint(CltrWidget *widget)
-{
-  CltrAnimator *anim = widget->anim;
-  int           orig_x, orig_y;
-
-  float f = (float)anim->step/anim->n_steps;
-
-  orig_x = widget->x;
-  orig_y = widget->y;
-
-  widget->x = anim->move_start_x1 + ( (anim->move_end_x1 - anim->move_start_x1) * f );
-  widget->x = anim->move_start_y1 + ( (anim->move_end_y1 - anim->move_start_y1) * f );
-
-  anim->wrapped_paint_func(widget);
-
-  widget->x = orig_x;
-  widget->y = orig_y;
-}
-
-static void
-cltr_animator_wrapped_zoom_paint(CltrWidget *widget)
-{
-  CltrAnimator *anim = widget->anim;
-  float         tx = 0.0, ty = 0.0;
-  float            x1, x2, y1, y2;
-
-  /* zoom here */
-
-  float f = (float)anim->step/anim->n_steps;
-
-  int end_width = anim->zoom_end_x2 - anim->zoom_end_x1;
-  int start_width = anim->zoom_start_x2 - anim->zoom_start_x1;
-
-  int end_height = anim->zoom_end_y2 - anim->zoom_end_y1;
-  int start_height = anim->zoom_start_y2 - anim->zoom_start_y1;
-
-  float max_zoom_x = (float)start_width/end_width;
-  float max_zoom_y = (float)start_height/end_height;
-
-  float trans_y =  ((float)anim->zoom_end_y1);
-
-  CLTR_MARK();
-
-  glPushMatrix();
-
-  CLTR_DBG("f is %f ( %i/%i ) max_zoom x: %f y: %f, zooming to %f, %f", 
-          f, anim->step, anim->n_steps, max_zoom_x, max_zoom_y,
-          (f * max_zoom_x), (f * max_zoom_y)); 
-
-#if 0
-  glTranslatef (0.0 /* - (float)(anim->zoom_start_x1) * ( (max_zoom_x * f) )*/,
-               - trans_y * f * max_zoom_y,
-               0.0);
-
-  if ((f * max_zoom_x) > 1.0 && (f * max_zoom_y) > 1.0)
-    {
-      glScalef ((f * max_zoom_x), (f * max_zoom_y), 0.0);
-    }
-#endif
-
-  glMatrixMode(GL_PROJECTION);
-  glLoadIdentity();
-
-  /*   glOrtho (0, widget->width, widget->height, 0, -1, 1); */
-
-
-
-  /* 800 -> 80, 800-80 = 720/n_steps = x , cur = 80 + x * (n_steps - steps) */
-
-  x2 = anim->zoom_end_x2 + ( ( ((float)anim->zoom_start_x2 - anim->zoom_end_x2)/ (float)anim->n_steps) * (anim->n_steps - anim->step) ); 
-
-  x1 = anim->zoom_end_x1 + ( ( ((float)anim->zoom_start_x1 - anim->zoom_end_x1)/ (float)anim->n_steps) * (anim->n_steps - anim->step) ); 
-
-  y1 = anim->zoom_end_y1 + ( ( ((float)anim->zoom_start_y1 - anim->zoom_end_y1)/ (float)anim->n_steps) * (anim->n_steps - anim->step) ); 
-
-  y2 = anim->zoom_end_y2 + ( ( ((float)anim->zoom_start_y2 - anim->zoom_end_y2)/ (float)anim->n_steps) * (anim->n_steps - anim->step) ); 
-
-  /*
-  glOrtho( anim->zoom_end_x1, x2-1,
-          anim->zoom_end_y2-1, anim->zoom_end_y1,
-          -1, 1);
-  */
-
-  glOrtho( x1, x2-1, y2-1, y1,
-          -1, 1);
-
-  glMatrixMode (GL_MODELVIEW);
-  glLoadIdentity ();
-
-  anim->wrapped_paint_func(widget);
-
-  glPopMatrix();
-
-  /* reset here */
-}
-
-/* Hack, we need somehow to reset the viewport
- *    XXX Hook this into anim->widget hide()
- *    XXX Call this every time for every render ?
-*/ 
-void
-cltr_animator_reset(CltrAnimator *anim)
-{
-  ClutterMainContext *ctx = CLTR_CONTEXT();
-
-  clrt_window_set_gl_viewport(ctx->window);
-}
-
-
-static gboolean
-cltr_animator_timeout_cb(gpointer data)
-{
-  CltrAnimator *anim = (CltrAnimator *)data;
-
-  CLTR_MARK();
-
-  anim->step++;
-
-  if (anim->step > anim->n_steps)
-    {
-      if (anim->anim_finish_cb)
-       anim->anim_finish_cb(anim, anim->anim_finish_data);
-
-      anim->widget->paint = anim->wrapped_paint_func;
-
-      return FALSE;
-    }
-
-  cltr_widget_queue_paint(anim->widget);
-
-  return TRUE;
-}
-
-void
-cltr_animator_run(CltrAnimator            *anim,
-                 CltrAnimatorFinishFunc   finish_callback,
-                 gpointer                *finish_data)
-{
-  anim->anim_finish_cb   = finish_callback;
-  anim->anim_finish_data = finish_data;
-
-
-  switch (anim->type)
-    {
-    case CltrAnimatorZoom:
-      anim->widget->paint = cltr_animator_wrapped_zoom_paint;
-      break;
-    case CltrAnimatorFullZoom:
-      /* anim->widget->paint = cltr_animator_wrapped_fullzoom_paint; */
-      break;
-    case CltrAnimatorMove:
-      anim->widget->paint = cltr_animator_wrapped_move_paint;
-      break;
-    }
-
-  anim->step = 0;
-
-  g_timeout_add(FPS_TO_TIMEOUT(anim->fps), 
-               cltr_animator_timeout_cb, anim);
-}
-
diff --git a/clutter/cltr-animator.h b/clutter/cltr-animator.h
deleted file mode 100644 (file)
index d0014cd..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef _HAVE_CLTR_ANIMATOR_H
-#define _HAVE_CLTR_ANIMATOR_H
-
-#include "cltr.h"
-
-typedef struct CltrAnimator CltrAnimator;
-
-typedef enum CltrAnimatorType
-{
-  CltrAnimatorZoom,
-  CltrAnimatorFullZoom,
-  CltrAnimatorMove
-}
-CltrAnimatorType;
-
-typedef void (*CltrAnimatorFinishFunc) (CltrAnimator *anim, void *userdata) ;
-
-CltrAnimator*
-cltr_animator_zoom_new(CltrWidget *widget,
-                      int         src_x1,
-                      int         src_y1,
-                      int         src_x2,
-                      int         src_y2,
-                      int         dst_x1,
-                      int         dst_y1,
-                      int         dst_x2,
-                      int         dst_y2);
-
-CltrAnimator*
-cltr_animator_fullzoom_new(CltrWidget *widget,
-                          int         x1,
-                          int         y1,
-                          int         x2,
-                          int         y2);
-
-/* HACK */
-void
-cltr_animator_reset(CltrAnimator *anim);
-
-void
-cltr_animator_run(CltrAnimator            *anim,
-                 CltrAnimatorFinishFunc   finish_callback,
-                 gpointer                *finish_data);
-
-#endif
diff --git a/clutter/cltr-button.c b/clutter/cltr-button.c
deleted file mode 100644 (file)
index c353b2a..0000000
+++ /dev/null
@@ -1,296 +0,0 @@
-#include "cltr-button.h"
-#include "cltr-private.h"
-
-struct CltrButton
-{
-  CltrWidget       widget;  
-  CltrLabel       *label;
-  Pixmap          *pixb;
-  CltrTexture     *texture;
-
-  CltrButtonActivate  activate_cb;
-  void               *activate_cb_data;
-
-
-  CltrButtonState  state;      /* may be better in widget ? */
-};
-
-#define BUTTON_BORDER 1
-#define BUTTON_PAD    5
-
-static void
-cltr_button_show(CltrWidget *widget);
-
-static gboolean 
-cltr_button_handle_xevent (CltrWidget *widget, XEvent *xev);
-
-static void
-cltr_button_paint(CltrWidget *widget);
-
-static void
-cltr_button_focus(CltrWidget *widget);
-
-static void
-cltr_button_unfocus(CltrWidget *widget);
-
-
-CltrWidget*
-cltr_button_new(int width, int height)
-{
-  CltrButton *button;
-
-  button = g_malloc0(sizeof(CltrButton));
-  
-  button->widget.width          = width;
-  button->widget.height         = height;
-  
-  button->widget.show           = cltr_button_show;
-  button->widget.paint          = cltr_button_paint;
-  button->widget.focus_in       = cltr_button_focus;
-  button->widget.focus_out      = cltr_button_unfocus;
-  button->widget.xevent_handler = cltr_button_handle_xevent;
-
-  return CLTR_WIDGET(button);
-}
-
-void
-cltr_button_on_activate(CltrButton         *button,
-                       CltrButtonActivate  callback,
-                       void               *userdata)
-{
-  button->activate_cb      = callback;
-  button->activate_cb_data = userdata;
-}
-
-CltrWidget*
-cltr_button_new_with_label(const char  *label, 
-                          CltrFont    *font,
-                          PixbufPixel *col)
-{
-  CltrButton *button = NULL;
-
-  button = CLTR_BUTTON(cltr_button_new(-1, -1));
-
-  button->label = CLTR_LABEL(cltr_label_new(label, font, col));
-
-  button->widget.width  =   cltr_widget_width((CltrWidget*)button->label) + (2 * ( BUTTON_BORDER + BUTTON_PAD));
-  button->widget.height = cltr_widget_height((CltrWidget*)button->label) + ( 2 * ( BUTTON_BORDER + BUTTON_PAD));
-
-  CLTR_DBG("width: %i, height %i", 
-          cltr_widget_width((CltrWidget*)button->label),
-          cltr_widget_height((CltrWidget*)button->label));
-
-  cltr_widget_add_child(CLTR_WIDGET(button), 
-                       CLTR_WIDGET(button->label), 
-                       ( BUTTON_BORDER + BUTTON_PAD),
-                       ( BUTTON_BORDER + BUTTON_PAD));
-
-  return CLTR_WIDGET(button);
-}
-
-void
-cltr_button_set_label(CltrButton  *button, 
-                     const char  *text,
-                     CltrFont    *font,
-                     PixbufPixel *col)
-{
-  int x, y;
-
-  if (button->label)
-    {
-      cltr_label_set_text(button->label, text);
-    }
-  else
-    {
-      button->label = CLTR_LABEL(cltr_label_new(text, font, col));
-
-      x = (cltr_widget_width(CLTR_WIDGET(button)) - cltr_widget_width(CLTR_WIDGET(button->label)))/2;
-
-      y = (cltr_widget_height(CLTR_WIDGET(button)) - cltr_widget_height(CLTR_WIDGET(button->label)))/2;
-
-      cltr_widget_add_child(CLTR_WIDGET(button), 
-                           CLTR_WIDGET(button->label), 
-                           x, y);
-    }
-}
-
-CltrWidget*
-cltr_button_new_with_pixbuf(Pixbuf *pixb)
-{
-  CltrButton *button = NULL;
-
-  button = CLTR_BUTTON(cltr_button_new(-1, -1));
-
-  return CLTR_WIDGET(button);
-}
-
-static void
-cltr_button_show(CltrWidget *widget)
-{
-
-}
-
-static void
-cltr_button_focus(CltrWidget *widget)
-{
-  CltrButton *button = CLTR_BUTTON(widget);
-
-  if (button->state != CltrButtonStateFocused)
-    {
-      button->state = CltrButtonStateFocused;
-      cltr_widget_queue_paint(widget);
-    }
-}
-
-static void
-cltr_button_unfocus(CltrWidget *widget)
-{
-  CltrButton *button = CLTR_BUTTON(widget);
-
-  if (button->state != CltrButtonStateInactive)
-    {
-      button->state = CltrButtonStateInactive;
-      
-      cltr_widget_queue_paint(CLTR_WIDGET(button));
-    }
-}
-
-static void
-cltr_button_handle_xkeyevent(CltrButton *button, XKeyEvent *xkeyev)
-{
-  KeySym          kc;
-  CltrButtonState old_state;
-  CltrWidget     *next_focus = NULL;
-
-  old_state = button->state;
-
-  kc = XKeycodeToKeysym(xkeyev->display, xkeyev->keycode, 0);
-
-  switch (kc)
-    {
-    case XK_Left:
-    case XK_KP_Left:
-      if (xkeyev->type != KeyPress)
-       break;
-      next_focus = cltr_widget_get_focus_next(CLTR_WIDGET(button), CLTR_WEST);
-      break;
-    case XK_Up:
-    case XK_KP_Up:
-      if (xkeyev->type != KeyPress)
-       break;
-
-      next_focus = cltr_widget_get_focus_next(CLTR_WIDGET(button), CLTR_NORTH);
-      break;
-    case XK_Right:
-    case XK_KP_Right:
-      if (xkeyev->type != KeyPress)
-       break;
-
-      next_focus = cltr_widget_get_focus_next(CLTR_WIDGET(button), CLTR_EAST);
-      break;
-    case XK_Down:      
-    case XK_KP_Down:   
-      if (xkeyev->type != KeyPress)
-       break;
-
-      next_focus = cltr_widget_get_focus_next(CLTR_WIDGET(button), CLTR_SOUTH);
-      break;
-    case XK_Return:
-      if (xkeyev->type == KeyPress)
-       {
-         if (button->state != CltrButtonStateActive)
-           button->state = CltrButtonStateActive;
-         CLTR_DBG("press");
-
-         if (button->activate_cb)
-           button->activate_cb(CLTR_WIDGET(button), button->activate_cb_data);
-
-       }
-      else           /* KeyRelease */
-       {
-         CLTR_DBG("release");
-         if (button->state != CltrButtonStateFocused)
-           button->state = CltrButtonStateFocused;
-
-         /* What to do about key repeats ? */
-
-       }
-      break;
-    default:
-      /* ??? */
-      break;
-   }
-
-  if (button->state != old_state)
-    {
-      CLTR_DBG("queueing paint");
-      cltr_widget_queue_paint(CLTR_WIDGET(button));
-    }
-
-  if (next_focus)
-    {
-      /* Evil - need to centralise focus management */
-      ClutterMainContext *ctx = CLTR_CONTEXT();
-      cltr_window_focus_widget(CLTR_WIDGET(ctx->window), next_focus);
-    }
-}
-
-
-static gboolean 
-cltr_button_handle_xevent (CltrWidget *widget, XEvent *xev) 
-{
-  CltrButton *button = CLTR_BUTTON(widget);
-
-  switch (xev->type)
-    {
-    case KeyPress:
-    case KeyRelease:
-      CLTR_DBG("KeyPress");
-      cltr_button_handle_xkeyevent(button, &xev->xkey);
-      break;
-    }
-
-  return TRUE;
-}
-
-
-static void
-cltr_button_paint(CltrWidget *widget)
-{
-  PixbufPixel bgcol     = { 0xe7, 0xe7, 0xe7, 0xff };
-  PixbufPixel boxcol    = { 0xd7, 0xd7, 0xd7, 0xff };
-  PixbufPixel hlfontcol = { 0xe6, 0x99, 0x99, 0xff };
-
-  CltrButton *button = CLTR_BUTTON(widget);
-
-  CLTR_MARK();
-
-  glPushMatrix();
-
-  glEnable(GL_BLEND);
-
-  switch (button->state) 
-    {
-    case CltrButtonStateFocused:
-      cltr_glu_set_color(&hlfontcol);
-      break;
-    case CltrButtonStateActive:
-      glColor4f(1.0, 1.0, 1.0, 1.0);
-      break;
-    default:
-      cltr_glu_set_color(&bgcol);
-    }
-
-  cltr_glu_rounded_rect(cltr_widget_abs_x(widget),
-                       cltr_widget_abs_y(widget),
-                       cltr_widget_abs_x2(widget),
-                       cltr_widget_abs_y2(widget),
-                       1, 2,
-                       NULL);
-
-  glDisable(GL_BLEND);
-
-  glPopMatrix();
-}
-
-
diff --git a/clutter/cltr-button.h b/clutter/cltr-button.h
deleted file mode 100644 (file)
index c07ea79..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _HAVE_CLTR_BUTTON_H
-#define _HAVE_CLTR_BUTTON_H
-
-#include "cltr.h"
-
-typedef struct CltrButton CltrButton;
-
-typedef enum CltrButtonState
-{
-  CltrButtonStateDisabled,
-  CltrButtonStateInactive,
-  CltrButtonStateFocused,
-  CltrButtonStateActive,
- }
-CltrButtonState;
-
-typedef void (*CltrButtonActivate) (CltrWidget *widget, void *userdata) ;
-
-#define CLTR_BUTTON(w) ((CltrButton*)(w))
-
-CltrWidget*
-cltr_button_new(int width, int height);
-
-void
-cltr_button_on_activate(CltrButton         *button,
-                       CltrButtonActivate  callback,
-                       void*               userdata);
-
-void
-cltr_button_set_label(CltrButton  *button, 
-                     const char  *text,
-                     CltrFont    *font,
-                     PixbufPixel *col);
-
-#endif
diff --git a/clutter/cltr-core.c b/clutter/cltr-core.c
deleted file mode 100644 (file)
index d4294cb..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-#include "cltr-core.h"
-#include "cltr-private.h"
-
-int
-cltr_init(int *argc, char ***argv)
-{
-
-#define GLX_SAMPLE_BUFFERS_ARB             100000
-#define GLX_SAMPLES_ARB                    100001
-
-
-  int  gl_attributes[] =
-    {
-      GLX_RGBA, 
-      GLX_DOUBLEBUFFER,
-      GLX_STENCIL_SIZE, 1, 
-      GLX_DEPTH_SIZE, 24,
-
-      /*
-      GLX_SAMPLE_BUFFERS_ARB, 1, 
-      GLX_SAMPLES_ARB, 0,
-
-      */
-      /*
-      GLX_RED_SIZE, 1,
-      GLX_GREEN_SIZE, 1,
-      GLX_BLUE_SIZE, 1,
-      */
-      0
-    };
-
-  XVisualInfo         *vinfo;  
-
-  gst_init (argc, argv);
-
-  if (!g_thread_supported ())
-    g_thread_init (NULL);
-
-  /* XInitThreads (); */
-
-  if ((CltrCntx.xdpy = XOpenDisplay(getenv("DISPLAY"))) == NULL)
-    {
-      return 0;
-    }
-
-  CltrCntx.xscreen   = DefaultScreen(CltrCntx.xdpy);
-  CltrCntx.xwin_root = RootWindow(CltrCntx.xdpy, CltrCntx.xscreen);
-
-  CLTR_DBG("EXT : %s", glXQueryExtensionsString( CltrCntx.xdpy, 
-                                             CltrCntx.xscreen));
-
-
-  if ((vinfo = glXChooseVisual(CltrCntx.xdpy, 
-                              CltrCntx.xscreen,
-                              gl_attributes)) == NULL)
-    {
-      fprintf(stderr, "Unable to find visual\n");
-      return 0;
-    }
-
-  CltrCntx.gl_context = glXCreateContext(CltrCntx.xdpy, vinfo, 0, True);
-
-  pixel_set_vals(&CltrCntx.colors[CLTR_COL_BG], 0xff, 0xff, 0xff, 0xff );
-  pixel_set_vals(&CltrCntx.colors[CLTR_COL_BDR],0xff, 0xff, 0xff, 0xff );
-  pixel_set_vals(&CltrCntx.colors[CLTR_COL_FG], 0xff, 0xff, 0xff, 0xff );
-
-  cltr_events_init();
-
-  return 1;
-}
-
-int 
-cltr_display_width(void)
-{
-  ClutterMainContext *ctx = CLTR_CONTEXT();
-
-  return DisplayWidth(ctx->xdpy, ctx->xscreen);
-}
-
-int 
-cltr_display_height(void)
-{
-  ClutterMainContext *ctx = CLTR_CONTEXT();
-
-  return DisplayHeight(ctx->xdpy, ctx->xscreen);
-}
-
-PixbufPixel*
-cltr_core_get_color(CltrNamedColor col)
-{
-  ClutterMainContext *ctx = CLTR_CONTEXT();
-
-  return &ctx->colors[col];
-}
diff --git a/clutter/cltr-core.h b/clutter/cltr-core.h
deleted file mode 100644 (file)
index 9175b03..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _HAVE_CLTR_CORE_H
-#define _HAVE_CLTR_CORE_H
-
-#include "cltr.h"
-
-int
-cltr_init(int *argc, char ***argv);
-
-int 
-cltr_display_height(void);
-
-int 
-cltr_display_width(void);
-
-#endif
diff --git a/clutter/cltr-events.c b/clutter/cltr-events.c
deleted file mode 100644 (file)
index 8f9557b..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-#include <X11/keysym.h>
-
-#include "cltr-events.h"
-#include "cltr-private.h"
-
-typedef void (*CltrXEventFunc) (XEvent *xev, gpointer user_data);
-
-typedef struct 
-{
-  GSource  source;
-  Display *display;
-  GPollFD  event_poll_fd;
-} 
-CltrXEventSource;
-
-static gboolean  
-x_event_prepare (GSource  *source,
-                gint     *timeout)
-{
-  Display *display = ((CltrXEventSource*)source)->display;
-
-  *timeout = -1;
-
-  return XPending (display);
-}
-
-static gboolean  
-x_event_check (GSource *source) 
-{
-  CltrXEventSource *display_source = (CltrXEventSource*)source;
-  gboolean         retval;
-
-  if (display_source->event_poll_fd.revents & G_IO_IN)
-    retval = XPending (display_source->display);
-  else
-    retval = FALSE;
-
-  return retval;
-}
-
-static gboolean  
-x_event_dispatch (GSource    *source,
-                 GSourceFunc callback,
-                 gpointer    user_data)
-{
-  Display *display = ((CltrXEventSource*)source)->display;
-  CltrXEventFunc event_func = (CltrXEventFunc) callback;
-  
-  XEvent xev;
-
-  if (XPending (display))
-    {
-      XNextEvent (display, &xev);
-
-      if (event_func)
-       (*event_func) (&xev, user_data);
-    }
-
-  return TRUE;
-}
-
-static const GSourceFuncs x_event_funcs = {
-  x_event_prepare,
-  x_event_check,
-  x_event_dispatch,
-  NULL
-};
-
-void
-cltr_dispatch_expose(XExposeEvent *xexpev)
-{
-  // cltr_photo_grid_redraw(Grid);
-}
-
-void
-cltr_dispatch_x_event (XEvent  *xevent,
-                      gpointer data)
-{
-  /* Should actually forward on to focussed widget */
-
-  ClutterMainContext *ctx = CLTR_CONTEXT();
-
-  cltr_widget_handle_xevent(ctx->window, xevent);
-  
-#if 0
-  switch (xevent->type)
-    {
-    case MapNotify:
-      CLTR_DBG("Map Notify Event");
-      break;
-    case Expose:
-      CLTR_DBG("Expose");      /* TODO COMPRESS */
-      cltr_dispatch_expose(&xevent->xexpose);
-      break;
-    case KeyPress:
-      CLTR_DBG("KeyPress");
-      cltr_dispatch_keypress(&xevent->xkey);
-      break;
-    }
-#endif 
-}
-
-void
-cltr_events_init()
-{
-  GMainContext         *gmain_context;
-  int                   connection_number;
-  GSource              *source;
-  CltrXEventSource     *display_source;
-
-  ClutterMainContext   *ctx = CLTR_CONTEXT();
-
-  /* g_main loop stuff */
-
-  gmain_context = g_main_context_default ();
-
-  g_main_context_ref (gmain_context);
-
-  connection_number = ConnectionNumber (CltrCntx.xdpy);
-  
-  source = g_source_new ((GSourceFuncs *)&x_event_funcs, 
-                        sizeof (CltrXEventSource));
-
-  display_source = (CltrXEventSource *)source;
-
-  display_source->event_poll_fd.fd     = connection_number;
-  display_source->event_poll_fd.events = G_IO_IN;
-  display_source->display              = CltrCntx.xdpy;
-  
-  g_source_add_poll (source, &display_source->event_poll_fd);
-  g_source_set_can_recurse (source, TRUE);
-
-  g_source_set_callback (source, 
-                        (GSourceFunc) cltr_dispatch_x_event, 
-                        NULL  /* no userdata */, NULL);
-
-  g_source_attach (source, gmain_context);
-  g_source_unref (source);
-
-  ctx->internal_event_q = g_async_queue_new();  
-}
-
-void
-cltr_main_loop()
-{
-  ClutterMainContext *ctx = CLTR_CONTEXT();
-
-  /*
-  GMainLoop          *loop;
-
-  loop = g_main_loop_new (g_main_context_default (), FALSE);
-
-  g_main_loop_run (loop);
-  */
-
-  while (TRUE)
-    {
-      if (g_async_queue_length (ctx->internal_event_q))
-       {
-         CltrWindow *win    = CLTR_WINDOW(ctx->window);
-
-         /* Empty the queue  */
-         while (g_async_queue_try_pop(ctx->internal_event_q) != NULL) ;
-
-         /* Repaint everything visible from window down - URG. 
-           * GL workings make it difficult to paint single part with
-           * layering etc..
-           * Is this really bad ? time will tell...
-         */
-         cltr_widget_paint(CLTR_WIDGET(win));
-
-         /* pre paint in window paint method */
-         cltr_window_post_paint(win);
-
-         /* Swap Buffers */
-         glXSwapBuffers(ctx->xdpy, cltr_window_xwin(win));  
-       }
-
-      /* while (g_main_context_pending(g_main_context_default ())) */
-      g_main_context_iteration (g_main_context_default (), TRUE);
-
-    }
-}
diff --git a/clutter/cltr-events.h b/clutter/cltr-events.h
deleted file mode 100644 (file)
index 48180e9..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _HAVE_CLTR_EVENT_H
-#define _HAVE_CLTR_EVENT_H
-
-#include "cltr.h"
-
-
-
-void
-cltr_main_loop();
-
-void
-cltr_dispatch_x_event (XEvent  *xevent,
-                      gpointer data);
-
-void
-cltr_events_init();
-
-#endif
diff --git a/clutter/cltr-glu.c b/clutter/cltr-glu.c
deleted file mode 100644 (file)
index e658570..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-#include "cltr-glu.h"
-#include "cltr-private.h"
-
-/* Clutter GL Utility routines */
-
-#define PI 3.1415926535897932384626433832795
-
-void
-cltr_glu_set_color(PixbufPixel *p)
-{
-  glColor4ub(p->r, p->b, p->g, p->a); 
-}
-
-void
-cltr_glu_rounded_rect(int        x1, 
-                     int        y1, 
-                     int        x2, 
-                     int        y2,
-                     int        line_width,
-                     int        radius, 
-                     PixbufPixel *col)
-{  
-  double ang = 0;
-  int    width = x2-x1, height = y2-y1; 
-  float  cX = x1+radius, cY = y1+radius; 
-
-  if (col)
-    cltr_glu_set_color(col);
-
-  glLineWidth(line_width); 
-
-  glBegin(GL_LINES); 
-  glVertex2f(x1, y1 + radius); 
-  glVertex2f(x1, y1 + height - radius); /* Left Line */
-
-  glVertex2f(x1 + radius, y1); 
-  glVertex2f(x1 + width - radius, y1);  /* Top Line */
-
-  glVertex2f(x1 + width, y1 + radius); 
-  glVertex2f(x1 + width, y1 + height - radius); /* Right Line */
-
-  glVertex2f(x1 + radius, y1 + height); 
-  glVertex2f(x1 + width - radius, y1 + height); /* Bottom Line */
-  glEnd(); 
-
-  /* corners */
-
-  glBegin(GL_LINE_STRIP); 
-
-  /* Top Left  */
-  for(ang = PI; ang <= (1.5*PI); ang = ang + 0.05) 
-    { 
-      glVertex2d(radius* cos(ang) + cX, radius * sin(ang) + cY);
-    }  
-
-  glEnd(); 
-
-  /* Top Right */
-
-  cX = x1 + width-radius; 
-
-  glBegin(GL_LINE_STRIP); 
-
-  for(ang = (1.5*PI); ang <= (2 * PI); ang = ang + 0.05) 
-    { 
-      glVertex2d(radius* cos(ang) + cX, radius * sin(ang) + cY);
-    } 
-
-  glEnd(); 
-
-  glBegin(GL_LINE_STRIP); 
-
-  cY = y1 + height-radius; 
-
-  /* Bottom Right */
-
-  for(ang = 0; ang <= (0.5*PI); ang = ang + 0.05) 
-    { 
-      glVertex2d(radius* cos(ang) + cX, radius * sin(ang) + cY);
-    } 
-
-  glEnd(); 
-
-  glBegin(GL_LINE_STRIP); 
-
-  cX = x1 + radius; 
-
-  /* Bottom Left */
-
-  for(ang = (0.5*PI); ang <= PI; ang = ang + 0.05) 
-    { 
-      glVertex2d(radius* cos(ang) + cX, radius * sin(ang) + cY);
-
-    } 
-  glEnd(); 
-
-} 
-
-void 
-cltr_glu_rounded_rect_filled(int        x1, 
-                            int        y1, 
-                            int        x2, 
-                            int        y2,
-                            int        radius, 
-                            PixbufPixel *col)
-{  
-  double i   = 0; 
-  double gap = 0.05; 
-  float  cX  = x1 + radius, cY = y1 + radius; 
-
-  if (col)
-    cltr_glu_set_color(col);
-
-  glBegin(GL_POLYGON); 
-
- /* Left Line */
-  glVertex2f(x1, y2 - radius);
-  glVertex2f(x1, y1 + radius); 
-
- /* Top Left */
-  for(i = PI; i <= (1.5*PI); i += gap) 
-    glVertex2d(radius* cos(i) + cX, radius * sin(i) + cY);
-
- /* Top Line */
-  glVertex2f(x1 + radius, y1); 
-  glVertex2f(x2 - radius, y1);
-
-  cX = x2 - radius; 
-
-  /* Top Right */
-  for(i = (1.5*PI); i <= (2 * PI); i += gap) 
-    glVertex2d(radius* cos(i) + cX, radius * sin(i) + cY);
-
-  glVertex2f(x2, y1 + radius); 
-
-  /* Right Line */
-  glVertex2f(x2, y2 - radius);
-
-  cY = y2 - radius; 
-
-  /* Bottom Right */
-  for(i = 0; i <= (0.5*PI); i+=gap) 
-    glVertex2d(radius* cos(i) + cX, radius * sin(i) + cY);
-
-  /* Bottom Line */
-  glVertex2f(x1 + radius, y2); 
-  glVertex2f(x2 - radius, y2);
-
-  /* Bottom Left */
-  cX = x1 + radius; 
-  for(i = (0.5*PI); i <= PI; i += gap) 
-    glVertex2d(radius* cos(i) + cX, radius * sin(i) + cY);
-
-  glEnd(); 
-} 
-
diff --git a/clutter/cltr-glu.h b/clutter/cltr-glu.h
deleted file mode 100644 (file)
index 3d5de15..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _HAVE_CLTR_GLU_H
-#define _HAVE_CLTR_GLU_H
-
-#include "cltr.h"
-
-void
-cltr_glu_set_color(PixbufPixel *p);
-
-void
-cltr_glu_rounded_rect(int        x1, 
-                     int        y1, 
-                     int        x2, 
-                     int        y2,
-                     int        line_width,
-                     int        radius, 
-                     PixbufPixel *col);
-
-void 
-cltr_glu_rounded_rect_filled(int        x1, 
-                            int        y1, 
-                            int        x2, 
-                            int        y2,
-                            int        radius, 
-                            PixbufPixel *col);
-
-#endif
diff --git a/clutter/cltr-label.c b/clutter/cltr-label.c
deleted file mode 100644 (file)
index df1e3ba..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-#include "cltr-label.h"
-#include "cltr-private.h"
-
-struct CltrLabel
-{
-  CltrWidget  widget;
-
-  char        *text;
-  Pixbuf      *pixb;
-  PixbufPixel  col;
-  CltrFont    *font;
-  CltrTexture *texture;
-};
-
-static void
-cltr_label_show(CltrWidget *widget);
-
-static gboolean 
-cltr_label_handle_xevent (CltrWidget *widget, XEvent *xev);
-
-static void
-cltr_label_paint(CltrWidget *widget);
-
-
-CltrWidget*
-cltr_label_new(const char  *text, 
-              CltrFont    *font,
-              PixbufPixel *col)
-{
-  CltrLabel *label;
-  int        width,height;
-
-  label = g_malloc0(sizeof(CltrLabel));
-
-  font_get_pixel_size (font, text, &width, &height);
-
-  if (width && height)
-    {
-      PixbufPixel bg = { 0x00, 0x00, 0x00, 0x00 };
-
-      label->text = strdup(text);
-      label->pixb  = pixbuf_new(width, height);
-      
-      pixbuf_fill_rect(label->pixb, 0, 0, -1, -1, &bg);
-
-      font_draw(font, 
-               label->pixb, 
-               label->text,
-               0,
-               0,
-               col);
-
-      label->texture = cltr_texture_new(label->pixb);
-    }
-
-  label->font = font;          /* XXX Ref The font XXX*/
-
-  memcpy(&label->col, col, sizeof(PixbufPixel));
-
-  label->widget.width          = width;
-  label->widget.height         = height;
-  
-  label->widget.show           = cltr_label_show;
-  label->widget.paint          = cltr_label_paint;
-  
-  label->widget.xevent_handler = cltr_label_handle_xevent;
-
-  return CLTR_WIDGET(label);
-}
-
-void
-cltr_label_set_text(CltrLabel *label, char *text)
-{
-  int        width,height;
-
-  if (label->texture)
-    cltr_texture_unref(label->texture);
-
-  if (label->pixb)
-    cltr_texture_unref(label->pixb);
-
-  if (label->text)
-    free(label->text);
-
-  font_get_pixel_size (label->font, text, &width, &height);
-
-  if (width && height)
-    {
-      PixbufPixel bg = { 0x00, 0x00, 0x00, 0x00 };
-      PixbufPixel col = { 0xff, 0xff, 0xff, 0xff };
-
-      label->widget.width          = width;
-      label->widget.height         = height;
-
-      CLTR_DBG("** setting label to %s ***", text);
-
-      label->text = strdup(text);
-      label->pixb  = pixbuf_new(width, height);
-      
-      pixbuf_fill_rect(label->pixb, 0, 0, -1, -1, &bg);
-
-      font_draw(label->font, 
-               label->pixb, 
-               label->text,
-               0,
-               0,
-               &label->col);
-
-      label->texture = cltr_texture_new(label->pixb);
-
-    }
-
-}
-
-const char*
-cltr_label_get_text(CltrLabel *label)
-{
-  return label->text;
-}
-
-static void
-cltr_label_show(CltrWidget *widget)
-{
-  ;
-}
-
-static gboolean 
-cltr_label_handle_xevent (CltrWidget *widget, XEvent *xev) 
-{
-  ;
-}
-
-static void
-cltr_label_paint(CltrWidget *widget)
-{
-  CltrLabel *label = CLTR_LABEL(widget);
-
-  CLTR_MARK();
-
-  if (label->text)
-    {
-
-      glPushMatrix();
-
-      glEnable(GL_TEXTURE_2D);
-
-      glEnable(GL_BLEND);
-
-      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-      /* glColor4f(1.0, 1.0, 1.0, 1.0); */
-
-      cltr_texture_render_to_gl_quad(label->texture,
-                                    cltr_widget_abs_x(widget),
-                                    cltr_widget_abs_y(widget),
-                                    cltr_widget_abs_x2(widget),
-                                    cltr_widget_abs_y2(widget));
-
-      glDisable(GL_BLEND);
-
-      glDisable(GL_TEXTURE_2D);
-
-      glPopMatrix();
-    }
-}
diff --git a/clutter/cltr-label.h b/clutter/cltr-label.h
deleted file mode 100644 (file)
index d66ba49..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _HAVE_CLTR_LABEL_H
-#define _HAVE_CLTR_LABEL_H
-
-#include "cltr.h"
-
-typedef struct CltrLabel CltrLabel;
-
-#define CLTR_LABEL(w) ((CltrLabel*)(w))
-
-CltrWidget*
-cltr_label_new(const char  *text, 
-              CltrFont    *font,
-              PixbufPixel *col);
-
-void
-cltr_label_set_text(CltrLabel *label, char *text);
-
-#endif
diff --git a/clutter/cltr-list.c b/clutter/cltr-list.c
deleted file mode 100644 (file)
index 6bbd533..0000000
+++ /dev/null
@@ -1,514 +0,0 @@
-#include "cltr-list.h"
-#include "cltr-private.h"
-
-#define ANIM_FPS 50 
-#define FPS_TO_TIMEOUT(t) (1000/(t))
-
-struct CltrListCell
-{
-  CltrRect     rect;
-
-  Pixbuf      *thumb_pixb;
-  CltrTexture *thumb_texture;
-
-  Pixbuf      *text_pixb;
-  CltrTexture *text_texture;
-
-};
-
-struct CltrList
-{
-  CltrWidget    widget;  
-  GList        *cells, *active_cell;
-  int           active_cell_y;
-  int           cell_height;
-  int           cell_width;
-
-  int           n_cells;
-
-  CltrListCellActivate cell_activate_cb;
-  gpointer             cell_activate_data;
-
-  CltrListState state;
-  int           scroll_dir;
-
-};
-
-#define PAD 10
-
-static void
-cltr_list_show(CltrWidget *widget);
-
-static gboolean 
-cltr_list_handle_xevent (CltrWidget *widget, XEvent *xev);
-
-static void
-cltr_list_paint(CltrWidget *widget);
-
-static float
-distfunc(CltrList *list, int d)
-{
-  int maxdist = list->widget.height;
-
-  d = (maxdist-ABS(d)) ;
-  return ( exp( (float)d/maxdist * 0.8 ) / exp(0.8) ) ;
-}
-
-CltrListCell*
-cltr_list_cell_new(CltrList *list, 
-                  Pixbuf   *thumb_pixb, 
-                  char     *text)
-{
-  CltrListCell *cell = NULL;
-  ClutterFont  *font;
-  PixbufPixel   pixel = { 0, 0, 0, 0 }, font_pixel = { 255, 255, 255, 255};
-
-  font = font_new ("Sans Bold 24");
-
-  cell = g_malloc0(sizeof(CltrListCell));
-
-  cell->thumb_pixb = thumb_pixb;
-  pixbuf_ref(cell->thumb_pixb);
-  cell->thumb_texture = cltr_texture_new(cell->thumb_pixb);
-
-  cell->text_pixb = pixbuf_new(list->cell_width - (list->cell_width/4), 
-                              (list->cell_height/2) - (2*PAD));
-
-  pixbuf_fill_rect(cell->text_pixb, 0, 0, -1, -1, &pixel);
-  font_draw(font, cell->text_pixb, text, 0, 0, &font_pixel);
-  cell->text_texture = cltr_texture_new(cell->text_pixb);
-
-  return cell;
-}
-
-void
-cltr_list_cell_set_pixbuf(CltrListCell *cell,
-                         Pixbuf       *thumb_pixb)
-{
-  cltr_texture_unref(cell->thumb_texture); 
-
-  cell->thumb_pixb = thumb_pixb;
-
-  cell->thumb_texture = cltr_texture_new(cell->thumb_pixb);
-
-}
-
-CltrWidget*
-cltr_list_new(int width, 
-             int height,
-             int cell_width,
-             int cell_height)
-{
-  CltrList *list;
-
-  list = g_malloc0(sizeof(CltrList));
-  
-  list->widget.width          = width;
-  list->widget.height         = height;
-  
-  list->widget.show           = cltr_list_show;
-  list->widget.paint          = cltr_list_paint;
-  
-  list->cell_height = cell_height; /* maximum */
-  list->cell_width  = cell_width;  /* maximum */
-
-  list->widget.xevent_handler = cltr_list_handle_xevent;
-
-  return CLTR_WIDGET(list);
-}
-
-void
-cltr_list_append_cell(CltrList *list, CltrListCell *cell)
-{
-  list->cells = g_list_append(list->cells, cell);
-
-  if (!list->active_cell)
-    list->active_cell = g_list_first(list->cells);
-
-  list->n_cells++;
-}
-
-static void
-video_box_co_ords(CltrList    *list,
-                 CltrListCell *cell, 
-                 int          *x1, int *y1, int *x2, int *y2)
-{
-  CltrWidget *widget = CLTR_WIDGET(list);
-  int         vw, vh;
-
-  vh  = cltr_rect_y2(cell->rect) - cltr_rect_y1(cell->rect);
-  vh -= (PAD*2);
-  vw  = ( widget->width * vh ) / widget->height;
-  
-  *x1 = cltr_rect_x1(cell->rect) + PAD; *x2 = *x1 + vw;
-  *y1 = cltr_rect_y1(cell->rect) + PAD; *y2 = *y1 + vh;
-}
-
-/* 
- * This is messy hack as cells arn't real widgets :(
- *
- */
-gboolean
-cltr_list_get_active_cell_video_box_co_ords(CltrList *list,
-                                           int      *x1,
-                                           int      *y1,
-                                           int      *x2,
-                                           int      *y2)
-{
-  if (list->active_cell)
-    {
-      CltrListCell *cell = list->active_cell->data; 
-
-      video_box_co_ords(list, cell, x1, y1, x2, y2);
-
-      return TRUE;
-    }
-  return FALSE;
-}
-
-static void
-cltr_list_show(CltrWidget *widget)
-{
-  CltrList     *list = CLTR_LIST(widget);
-  CltrListCell *cell = NULL;
-  
-  if (list->active_cell_y == 0)
-    {
-      list->active_cell_y = (widget->height / 2) - (list->cell_height/2);
-
-      list->active_cell = g_list_first(list->cells);
-
-      cell = list->active_cell->data;
-
-      cell->rect.y = list->active_cell_y;
-    }
-
-  list->state = CLTR_LIST_STATE_BROWSE;
-
-  cltr_list_update_layout(list);
-
-  cltr_widget_queue_paint(widget);
-}
-
-void
-cltr_list_on_activate_cell(CltrList             *list,
-                          CltrListCellActivate  callback,
-                          gpointer             *userdata)
-{
-  list->cell_activate_cb      = callback;
-  list->cell_activate_data    = userdata;
-}
-
-CltrListCell*
-cltr_list_get_active_cell(CltrList *list)
-{
-  if (list->active_cell)
-    return list->active_cell->data;
-
-  return NULL;
-}
-
-static gboolean 
-cltr_list_handle_xevent (CltrWidget *widget, XEvent *xev) 
-{
-  CltrList *list = CLTR_LIST(widget);
-
-  switch (xev->type)
-    {
-    case KeyPress:
-      {
-       KeySym kc;
-
-       kc = XKeycodeToKeysym(xev->xkey.display, xev->xkey.keycode, 0);
-
-       switch (kc)
-         {
-         case XK_Up:
-         case XK_KP_Up:
-           cltr_list_scroll_up(list);
-           break;
-         case XK_Down: 
-         case XK_KP_Down:      
-           cltr_list_scroll_down(list);
-           break;
-         case XK_Return:
-           if (list->cell_activate_cb && list->active_cell)
-             list->cell_activate_cb(list, 
-                                    list->active_cell->data,
-                                    list->cell_activate_data);
-           break;
-         case XK_Left:
-         case XK_KP_Left:
-         case XK_Right:
-         case XK_KP_Right:
-         default:
-           CLTR_DBG("unhandled keysym");
-         }
-      }
-      break;
-    }
-
-  return TRUE;
-}
-
-static void
-cltr_list_animate(CltrList *list)
-{
-  GList        *cell_item = NULL;
-  CltrListCell *next_active = NULL, *cell_top = NULL;
-
-  cell_top  = (CltrListCell *)g_list_nth_data(list->cells, 0);
-  int i = 0;
-
-  for (;;)
-    {
-      if (list->state == CLTR_LIST_STATE_SCROLL_UP)
-       {
-         cell_item = g_list_previous(list->active_cell);
-         
-         if (!cell_item)
-           {
-             list->state = CLTR_LIST_STATE_BROWSE;
-             return;
-           }
-         
-         next_active = (CltrListCell *)cell_item->data;
-         
-         if (next_active->rect.y < list->active_cell_y)
-           {
-             cell_top->rect.y += 1;
-           }
-         else
-           {
-             list->active_cell = cell_item;
-             list->state = CLTR_LIST_STATE_BROWSE;
-             return;
-           }
-       }
-      else if (list->state == CLTR_LIST_STATE_SCROLL_DOWN)
-       {
-         cell_item = g_list_next(list->active_cell);
-         
-         if (!cell_item)
-           {
-             list->state = CLTR_LIST_STATE_BROWSE;
-             return;
-           }
-         
-         next_active = (CltrListCell *)cell_item->data;
-         
-         if (next_active->rect.y > list->active_cell_y)
-           {
-             cell_top->rect.y -= 1;
-           }
-         else
-           {
-             list->active_cell = cell_item;
-             list->state = CLTR_LIST_STATE_BROWSE;
-             return;
-           }
-       }
-
-      if (++i > 10)
-       return;
-
-      cltr_list_update_layout(list);
-    }
-}
-
-gboolean
-cltr_list_timeout_cb(gpointer data)
-{
-  CltrList *list = (CltrList *)data;
-
-  cltr_list_animate(list);
-
-  cltr_widget_queue_paint(CLTR_WIDGET(list));
-
-  switch(list->state)
-    {
-    case CLTR_LIST_STATE_SCROLL_UP:
-    case CLTR_LIST_STATE_SCROLL_DOWN:   
-      return TRUE;
-    case CLTR_LIST_STATE_LOADING:
-    case CLTR_LIST_STATE_LOAD_COMPLETE:
-    case CLTR_LIST_STATE_BROWSE:
-    default:
-      return FALSE;
-    }
-}
-
-static void 
-cltr_list_update_layout(CltrList *list)
-{
-  GList        *cell_item = NULL;
-  CltrListCell *cell = NULL;
-  int           last;
-
-  cell_item = g_list_first(list->cells);
-  cell = (CltrListCell *)cell_item->data;
-
-  last = cell->rect.y;
-
-  while (cell_item)
-    {
-      float scale = 0.0;
-
-      cell = (CltrListCell *)cell_item->data;
-
-      cell->rect.y = last;
-       
-      if (cell->rect.y + cell->rect.height >= 0)
-       {
-         scale = distfunc(list, cell->rect.y - list->active_cell_y);
-
-         cell->rect.width  = list->cell_width * scale;
-         cell->rect.height = list->cell_height * scale;
-         
-         cell->rect.x = (list->widget.width - cell->rect.width) / 2;  
-       }
-      
-      last = cell->rect.y + cell->rect.height;
-
-      cell_item = g_list_next(cell_item);
-    }
-
-}
-
-static void
-cltr_list_paint(CltrWidget *widget)
-{
-  GList        *cell_item = NULL;
-  CltrList     *list = CLTR_LIST(widget);
-  CltrListCell *cell = NULL;
-  int           last;
-
-  PixbufPixel col       = { 0xff, 0, 0, 0xff };
-  PixbufPixel bgcol     = { 0xe7, 0xe7, 0xe7, 0xff };
-  PixbufPixel boxcol    = { 0xd7, 0xd7, 0xd7, 0xff };
-  PixbufPixel hlfontcol = { 0xe6, 0x99, 0x99, 0xff };
-
-  CLTR_MARK();
-
-  cell_item = g_list_first(list->cells);
-  cell = (CltrListCell *)cell_item->data;
-  last = cell->rect.y;
-
-  glPushMatrix();
-
-  cltr_glu_set_color(&bgcol);
-
-  glRecti(0, 0, widget->width, widget->height);
-
-  glEnable(GL_TEXTURE_2D);
-
-  glEnable(GL_BLEND);
-
-  cltr_list_update_layout(list);
-
-  while (cell_item)
-    {
-      float scale = 0.0;
-
-      col.r = 0xff; col.g = 0;  col.b = 0; col.a = 0xff;
-
-      cell = (CltrListCell *)cell_item->data;
-
-      last = cell->rect.y + cell->rect.height;
-      
-      scale = distfunc(list, cell->rect.y - list->active_cell_y);
-
-      if (last > 0 && cell->rect.y < list->widget.width) /* crappy clip */
-       {
-         glDisable(GL_TEXTURE_2D);
-
-         if (cell_item == list->active_cell && list->state == CLTR_LIST_STATE_BROWSE)
-           col.b = 0xff;
-         else
-           col.b = 0x00;
-
-         cltr_glu_set_color(&boxcol);
-
-         cltr_glu_rounded_rect_filled(cltr_rect_x1(cell->rect),
-                                      cltr_rect_y1(cell->rect) + (5.0 * scale),
-                                      cltr_rect_x2(cell->rect),
-                                      cltr_rect_y2(cell->rect) - (5.0 * scale),
-                                      10,
-                                      &boxcol);
-
-         col.r = 0xff; col.g = 0xff;  col.b = 0xff; col.a = 0xff;
-
-         /*
-         cltr_glu_rounded_rect(cltr_rect_x1(cell->rect) + 10,
-                               cltr_rect_y1(cell->rect) + 12,
-                               cltr_rect_x2(cell->rect) - 10,
-                               cltr_rect_y2(cell->rect) - 12,
-                               10,
-                               &col);
-         */
-
-         glEnable(GL_TEXTURE_2D);
-
-         glEnable(GL_BLEND);
-
-         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-
-         {
-           /* Video Box */
-
-           int vx1, vx2, vy1, vy2;
-
-           video_box_co_ords(list, cell, &vx1, &vy1, &vx2, &vy2);
-
-           cltr_texture_render_to_gl_quad(cell->thumb_texture,
-                                          vx1, vy1, vx2, vy2);
-
-           /* Text */
-
-           if (cell_item == list->active_cell 
-               && list->state == CLTR_LIST_STATE_BROWSE)
-             cltr_glu_set_color(&hlfontcol);
-           else
-             glColor4f(0.4, 0.4, 0.4, 1.0); 
-
-           cltr_texture_render_to_gl_quad(cell->text_texture,
-                                          vx2 + PAD,
-                                          vy1,
-                                          cltr_rect_x2(cell->rect) - (2*PAD),
-                                          vy1 + (list->cell_height/2) - (2*PAD));
-
-         }
-
-         glDisable(GL_BLEND);
-
-       }
-
-      cell_item = g_list_next(cell_item);
-    }
-
-  glDisable(GL_BLEND);
-
-  glDisable(GL_TEXTURE_2D);
-
-  glPopMatrix();
-}
-
-
-void
-cltr_list_scroll_down(CltrList *list)
-{
-  list->state = CLTR_LIST_STATE_SCROLL_DOWN;
-
-  g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS), 
-               cltr_list_timeout_cb, list);
-}
-
-void
-cltr_list_scroll_up(CltrList *list)
-{
-  list->state = CLTR_LIST_STATE_SCROLL_UP;
-
-  g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS), 
-               cltr_list_timeout_cb, list);
-}
diff --git a/clutter/cltr-list.h b/clutter/cltr-list.h
deleted file mode 100644 (file)
index ec2d6e0..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef _HAVE_CLTR_LIST_H
-#define _HAVE_CLTR_LIST_H
-
-#include "cltr.h"
-
-typedef struct CltrList CltrList;
-
-typedef struct CltrListCell CltrListCell;
-
-#define CLTR_LIST(w) ((CltrList*)(w))
-
-typedef void (*CltrListCellActivate) (CltrList     *list, 
-                                     CltrListCell *cell,
-                                     void         *userdata) ;
-
-typedef enum CltrListState
-{
-  CLTR_LIST_STATE_LOADING       ,
-  CLTR_LIST_STATE_LOAD_COMPLETE ,
-  CLTR_LIST_STATE_BROWSE        ,
-  CLTR_LIST_STATE_SCROLL_UP     ,
-  CLTR_LIST_STATE_SCROLL_DOWN    
-} 
-CltrListState;
-
-CltrListCell*
-cltr_list_cell_new(CltrList *list, 
-                  Pixbuf   *thump_pixb, 
-                  char     *text);
-
-void
-cltr_list_cell_set_pixbuf(CltrListCell *cell,
-                         Pixbuf   *thump_pixb);
-
-void
-cltr_list_append_cell(CltrList *list, CltrListCell *cell);
-
-CltrWidget*
-cltr_list_new(int width, 
-             int height,
-             int cell_width,
-             int cell_height);
-
-CltrListCell*
-cltr_list_get_active_cell(CltrList *list);
-
-void
-cltr_list_on_activate_cell(CltrList             *list,
-                          CltrListCellActivate  callback,
-                          gpointer             *userdata);
-
-gboolean
-cltr_list_get_active_cell_video_box_co_ords(CltrList *list,
-                                           int      *x1,
-                                           int      *y1,
-                                           int      *x2,
-                                           int      *y2);
-
-void
-cltr_list_scroll_down(CltrList *list);
-
-void
-cltr_list_scroll_up(CltrList *list);
-
-
-#endif
diff --git a/clutter/cltr-overlay.c b/clutter/cltr-overlay.c
deleted file mode 100644 (file)
index b68103e..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-#include "cltr-overlay.h"
-#include "cltr-private.h"
-
-struct CltrOverlay
-{
-  CltrWidget   widget;  
-};
-
-static void
-cltr_overlay_show(CltrWidget *widget);
-
-static gboolean 
-cltr_overlay_handle_xevent (CltrWidget *widget, XEvent *xev);
-
-static void
-cltr_overlay_paint(CltrWidget *widget);
-
-
-CltrWidget*
-cltr_overlay_new(int width, int height)
-{
-  CltrOverlay *overlay;
-
-  overlay = g_malloc0(sizeof(CltrOverlay));
-  
-  overlay->widget.width          = width;
-  overlay->widget.height         = height;
-  
-  overlay->widget.show           = cltr_overlay_show;
-  overlay->widget.paint          = cltr_overlay_paint;
-  
-  overlay->widget.xevent_handler = cltr_overlay_handle_xevent;
-
-  return CLTR_WIDGET(overlay);
-}
-
-static void
-cltr_overlay_show(CltrWidget *widget)
-{
-
-}
-
-static gboolean 
-cltr_overlay_handle_xevent (CltrWidget *widget, XEvent *xev) 
-{
-
-  return FALSE;
-}
-
-static void
-cltr_overlay_paint(CltrWidget *widget)
-{
-  glEnable(GL_BLEND);
-
-  glColor4f(0.5, 0.5, 0.5, 0.5);
-
-  cltr_glu_rounded_rect_filled(widget->x,
-                              widget->y,
-                              widget->x + widget->width,
-                              widget->y + widget->height,
-                              widget->width/30,
-                              NULL);
-
-  glDisable(GL_BLEND);
-
-}
diff --git a/clutter/cltr-overlay.h b/clutter/cltr-overlay.h
deleted file mode 100644 (file)
index 2d6d1a3..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _HAVE_CLTR_OVERLAY_H
-#define _HAVE_CLTR_OVERLAY_H
-
-#include "cltr.h"
-
-typedef struct CltrOverlay CltrOverlay;
-
-#define CLTR_OVERLAY(w) ((CltrOverlay*)(w))
-
-CltrWidget*
-cltr_overlay_new(int width, int height);
-
-
-#endif
diff --git a/clutter/cltr-photo-grid.c b/clutter/cltr-photo-grid.c
deleted file mode 100644 (file)
index fa6a435..0000000
+++ /dev/null
@@ -1,855 +0,0 @@
-#include "cltr-photo-grid.h"
-#include "cltr-private.h"
-
-struct CltrPhotoGridCell
-{
-  Pixbuf      *pixb;
-  float        angle;
-  CltrTexture *texture;
-  gint         anim_step;
-
-  CltrPhotoGridCellState state;
-};
-
-struct CltrPhotoGrid
-{
-  CltrWidget     widget;
-
-  gchar         *img_path;
-
-  int            n_rows;
-  int            n_cols;
-  int            row_offset; /* where is the first visible row. */
-
-  int            cell_width;
-  int            cell_height;
-
-  GList         *cells_tail;
-  GList         *cell_active;
-
-  gboolean       is_populated;
-
-  /* animation / zoom etc stuff  */
-
-  /* current anim frame position */
-  int                 anim_fps, anim_n_steps, anim_step;
-
-  /* start / end points for animations */
-  float               zoom_min, zoom_max, zoom_step;
-  float               view_min_x, view_max_x, view_min_y, view_max_y; 
-  float               scroll_dist;
-
-  /* Values calucated from above for setting up the GL tranforms and 'view' */
-  float               paint_trans_x, paint_trans_y, paint_zoom; 
-  int                 paint_start_y;
-
-  GList              *paint_cell_item;
-
-  GMutex             *mutex;
-
-  CltrPhotoGridState  state;
-};
-
-static void
-cltr_photo_grid_paint(CltrWidget *widget);
-
-static gboolean 
-cltr_photo_grid_handle_xevent (CltrWidget *widget, XEvent *xev);
-
-static void
-cltr_photo_grid_show(CltrWidget *widget);
-
-static void
-cltr_photo_grid_update_visual_state(CltrPhotoGrid *grid);
-
-
-GMutex*
-cltr_photo_grid_mutex(CltrPhotoGrid *grid)
-{
-  return grid->mutex;
-}
-
-void
-cltr_photo_grid_set_populated(CltrPhotoGrid *grid, gboolean populated)
-{
-  grid->is_populated = populated;
-}
-
-static void
-cltr_photo_grid_handle_xkeyevent(CltrPhotoGrid *grid, XKeyEvent *xkeyev)
-{
-  KeySym kc;
-
-  kc = XKeycodeToKeysym(xkeyev->display, xkeyev->keycode, 0);
-
-  switch (kc)
-    {
-    case XK_Left:
-    case XK_KP_Left:
-      cltr_photo_grid_navigate(grid, CLTR_WEST);
-      break;
-    case XK_Up:
-    case XK_KP_Up:
-      cltr_photo_grid_navigate(grid, CLTR_NORTH);
-      break;
-    case XK_Right:
-    case XK_KP_Right:
-      cltr_photo_grid_navigate(grid, CLTR_EAST);
-      break;
-    case XK_Down:      
-    case XK_KP_Down:   
-      cltr_photo_grid_navigate(grid, CLTR_SOUTH);
-      break;
-    case XK_Return:
-      cltr_photo_grid_activate_cell(grid);
-      break;
-    default:
-      CLTR_DBG("unhandled keysym");
-    }
-}
-
-static gboolean 
-cltr_photo_grid_handle_xevent (CltrWidget *widget, XEvent *xev) 
-{
-  CltrPhotoGrid* grid = CLTR_PHOTO_GRID(widget);
-
-  switch (xev->type)
-    {
-    case KeyPress:
-      CLTR_DBG("KeyPress");
-      cltr_photo_grid_handle_xkeyevent(grid, &xev->xkey);
-      break;
-    }
-  
-  return TRUE;
-}
-
-
-CltrPhotoGridCell*
-cltr_photo_grid_cell_new(CltrPhotoGrid *grid,
-                        Pixbuf        *pixb)
-{
-  CltrPhotoGridCell *cell = NULL;
-  int                   maxw = grid->widget.width, maxh = grid->widget.height;
-  int                   neww = 0, newh = 0;
-
-  cell = g_malloc0(sizeof(CltrPhotoGridCell));
-
-  if (pixb->width > pixb->height) /* landscape */
-    {
-      if (pixb->width > maxw)
-       {
-         neww = maxw;
-         newh = (neww * pixb->height) / pixb->width;
-       }
-    }
-  else                            /* portrait */
-    {
-      if (pixb->height > maxh)
-       {
-         newh = maxh;
-         neww = (newh * pixb->width) / pixb->height;
-       }
-    }
-
-  if (neww || newh)
-    {
-      cell->pixb = pixbuf_scale_down(pixb, neww, newh);
-      pixbuf_unref(pixb);
-    }
-  else cell->pixb = pixb;
-
-  cell->texture = cltr_texture_new(cell->pixb);
-
-  cell->angle = 6.0 - (rand()%12);
-
-  cell->anim_step = 15;
-  cell->state = CLTR_PHOTO_GRID_CELL_STATE_APPEARING;
-
-  return cell;
-}
-
-Pixbuf*
-cltr_photo_grid_cell_pixbuf(CltrPhotoGridCell *cell)
-{
-  return cell->pixb;
-}
-
-CltrPhotoGridCell*
-cltr_photo_grid_get_active_cell(CltrPhotoGrid     *grid)
-{
-  if (grid->cell_active)
-    return grid->cell_active->data;
-  else
-    return NULL;
-}
-
-void
-cltr_photo_grid_set_active_cell(CltrPhotoGrid *grid, CltrPhotoGridCell *cell)
-{
-  GList *cell_item = NULL;
-
-  cell_item = g_list_find(g_list_first(grid->cells_tail), (gconstpointer)cell);
-
-  if (cell_item)
-    grid->cell_active = cell_item;
-}
-
-CltrPhotoGridCell*
-cltr_photo_grid_get_first_cell(CltrPhotoGrid     *grid)
-{
-  GList *cell_item = NULL;
-
-  cell_item = g_list_first(grid->cells_tail);
-
-  if (cell_item)
-    return cell_item->data;
-  return NULL;
-}
-
-void
-cltr_photo_grid_append_cell(CltrPhotoGrid     *grid,
-                           CltrPhotoGridCell *cell)
-{
-  grid->cells_tail = g_list_append(grid->cells_tail, cell);
-} 
-
-/* relative */
-static void
-ctrl_photo_grid_cell_to_coords(CltrPhotoGrid *grid,
-                              GList            *cell,
-                              int              *x,
-                              int              *y)
-{
-  int idx;
-
-  idx = g_list_position(grid->cells_tail, cell);  
-
-  *y = idx / grid->n_cols;
-  *x = idx % grid->n_cols;
-
-  CLTR_DBG("idx: %i x: %i, y: %i", idx, *x , *y);
-}
-
-static void
-ctrl_photo_grid_get_zoomed_coords(CltrPhotoGrid *grid,
-                                 int              x,
-                                 int              y,
-                                 float           *tx,
-                                 float           *ty)
-{
-  /* 
-   * figure out translate co-ords for the cell at x,y to get translated
-   * so its centered for glScale to zoom in on it.
-  */
-
-  *tx = (float)grid->cell_width  * (grid->zoom_max) * x * -1.0;
-  *ty = (float)grid->cell_height * (grid->zoom_max) * y * -1.0;
-}
-
-static gboolean
-cell_is_offscreen(CltrPhotoGrid *grid,
-                 GList            *cell,
-                 CltrDirection    *where)
-{
-  int idx;
-
-  idx = g_list_position(grid->cells_tail, cell);  
-
-  CLTR_DBG("idx %i, rows*cols %i", idx, grid->n_cols * grid->n_rows);
-
-  if (idx < (grid->row_offset * grid->n_cols))
-    {
-      if (where) *where = CLTR_NORTH;
-      return TRUE;             /* scroll up */
-    }
-
-  if (idx >= ((grid->row_offset * grid->n_cols)+(grid->n_cols * grid->n_rows)))
-    {
-      if (where) *where = CLTR_SOUTH;
-      return TRUE;             /* scroll down */
-    }
-
-  return FALSE;
-}
-
-gboolean
-cltr_photo_grid_idle_cb(gpointer data)
-{
-  CltrPhotoGrid *grid = (CltrPhotoGrid *)data;
-
-  cltr_photo_grid_update_visual_state(grid);
-
-  cltr_widget_queue_paint(CLTR_WIDGET(grid));
-
-  if (!grid->is_populated)
-    return TRUE;
-
-  switch(grid->state)
-    {
-    case CLTR_PHOTO_GRID_STATE_ZOOM_IN:
-    case CLTR_PHOTO_GRID_STATE_ZOOM_OUT:
-    case CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE:
-    case CLTR_PHOTO_GRID_STATE_SCROLLED_MOVE:
-      return TRUE;
-    case CLTR_PHOTO_GRID_STATE_ZOOMED:
-    case CLTR_PHOTO_GRID_STATE_BROWSE:        
-    default:
-      return FALSE;  /* no need for rapid updates now  */
-    }
-}
-
-
-void
-cltr_photo_grid_navigate(CltrPhotoGrid *grid,
-                        CltrDirection     direction) 
-{
-  GList *cell_orig = grid->cell_active;
-
-  switch (direction)
-    {
-    case CLTR_SOUTH:
-      if (g_list_nth(grid->cell_active, grid->n_cols))
-       grid->cell_active = g_list_nth(grid->cell_active, grid->n_cols);
-      break;
-    case CLTR_NORTH:
-      if (g_list_nth_prev(grid->cell_active, grid->n_cols))
-       grid->cell_active = g_list_nth_prev(grid->cell_active, grid->n_cols);
-      break;
-    case CLTR_EAST:
-      if (g_list_next(grid->cell_active))
-       grid->cell_active = g_list_next(grid->cell_active);
-      break;
-    case CLTR_WEST:
-      if (g_list_previous(grid->cell_active))
-       grid->cell_active = g_list_previous(grid->cell_active);
-      break;
-    }
-
-  if (cell_orig != grid->cell_active) /* we've moved */
-    {
-      int           x, y;
-      float         zoom = grid->zoom_min;
-      CltrDirection where;
-
-      if (cell_is_offscreen(grid, grid->cell_active, &where))
-       {
-         GList *cell_item = NULL;
-
-         cell_item = g_list_nth(grid->cells_tail, 
-                                grid->n_cols * grid->row_offset);
-
-         if (grid->state != CLTR_PHOTO_GRID_STATE_ZOOMED)
-           grid->state = CLTR_PHOTO_GRID_STATE_SCROLLED_MOVE;
-         
-         /* scroll */
-         if (where == CLTR_NORTH)
-           {           /* up */
-             grid->scroll_dist = grid->cell_height;
-             grid->row_offset--;
-           }
-         else
-           {
-             grid->scroll_dist = - grid->cell_height;
-             grid->row_offset++;
-           }
-         
-         if (grid->state != CLTR_PHOTO_GRID_STATE_ZOOMED)            
-           g_timeout_add(FPS_TO_TIMEOUT(grid->anim_fps), 
-                         cltr_photo_grid_idle_cb, grid);
-       }
-
-      if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED)
-       {
-         grid->state      = CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE;
-
-         grid->view_min_x = grid->view_max_x; 
-         grid->view_min_y = grid->view_max_y ;
-         grid->anim_step  = 0;
-         zoom             = grid->zoom_max;
-
-         g_timeout_add(FPS_TO_TIMEOUT(grid->anim_fps), 
-                       cltr_photo_grid_idle_cb, grid);
-       }
-         
-      ctrl_photo_grid_cell_to_coords(grid, grid->cell_active, &x, &y);
-
-      ctrl_photo_grid_get_zoomed_coords(grid, x, y,
-                                       &grid->view_max_x,
-                                       &grid->view_max_y);
-                                      
-      CLTR_DBG("x: %f, y: %f", grid->view_max_x , grid->view_max_y);
-
-      cltr_widget_queue_paint(CLTR_WIDGET(grid));
-    }
-}
-
-void                           /* bleh badly named */
-cltr_photo_grid_activate_cell(CltrPhotoGrid *grid)
-{
-  if (grid->state == CLTR_PHOTO_GRID_STATE_BROWSE)
-    {
-      grid->state = CLTR_PHOTO_GRID_STATE_ZOOM_IN;
-
-
-      g_timeout_add(FPS_TO_TIMEOUT(grid->anim_fps), 
-                   cltr_photo_grid_idle_cb, grid);
-    }
-  else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED)
-    {
-      grid->state = CLTR_PHOTO_GRID_STATE_ZOOM_OUT;
-       /* reset - zoomed moving will have reset */
-
-      grid->view_min_x = 0.0; 
-      grid->view_min_y = 0.0; /*- (grid->row_offset * grid->cell_height);*/
-
-      g_timeout_add(FPS_TO_TIMEOUT(grid->anim_fps), 
-                   cltr_photo_grid_idle_cb, grid);
-    }
-}                            
-
-
-static void
-cltr_photo_grid_update_visual_state(CltrPhotoGrid *grid)
-{
-  int view_x_diff  = grid->view_max_x - grid->view_min_x;
-  int view_y_diff  = grid->view_max_y - grid->view_min_y;
-  int zoom_diff    = grid->zoom_max - grid->zoom_min;
-  int row_offset_h = grid->row_offset * grid->cell_height;
-
-  /* Default states ( zoomed out ) */
-  grid->paint_zoom      = grid->zoom_min;
-  grid->paint_trans_x   = grid->view_min_x;
-  grid->paint_trans_y   = grid->view_min_y - row_offset_h;
-  grid->paint_start_y   = row_offset_h;
-  grid->paint_cell_item = g_list_nth(grid->cells_tail, 
-                                    grid->n_cols * grid->row_offset);
-
-  if (grid->state != CLTR_PHOTO_GRID_STATE_BROWSE)
-    {
-      float scroll_min_y_offset = (float)(row_offset_h);
-
-      /* Assume zoomed in */
-      grid->paint_zoom    = grid->zoom_max; 
-      grid->paint_trans_x = grid->view_max_x;
-      grid->paint_trans_y = grid->view_max_y;
-
-      if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOM_IN)
-       {
-         grid->anim_step++;
-
-         /* Are we zoomed all the way in > */
-         if (grid->anim_step >= grid->anim_n_steps)
-           {
-             grid->state     = CLTR_PHOTO_GRID_STATE_ZOOMED;
-             grid->anim_step = 0;
-           }
-         else 
-           {
-             float f = (float)grid->anim_step/grid->anim_n_steps;
-
-             scroll_min_y_offset *= grid->zoom_max;
-
-             grid->paint_zoom = grid->zoom_min + (zoom_diff * f);
-             grid->paint_trans_x = view_x_diff * f;
-             grid->paint_trans_y = (view_y_diff + scroll_min_y_offset) * f;
-
-             grid->paint_start_y = 0;
-           }
-       } 
-      else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOM_OUT)
-       {
-         grid->anim_step++;
-         
-         if (grid->anim_step >= grid->anim_n_steps)
-           {
-             grid->paint_zoom     = grid->zoom_min;
-             grid->anim_step      = 0;
-             grid->paint_trans_x  = grid->view_min_x;
-             grid->paint_trans_y  = grid->view_min_y - scroll_min_y_offset; 
-             grid->state          = CLTR_PHOTO_GRID_STATE_BROWSE;
-           }
-         else 
-           {
-             float f = (float)(grid->anim_n_steps - grid->anim_step ) 
-                       / grid->anim_n_steps;
-
-             scroll_min_y_offset *= grid->zoom_max;
-
-             grid->paint_zoom = grid->zoom_min + (zoom_diff * f);
-             grid->paint_trans_x = view_x_diff * f;
-             grid->paint_trans_y = (view_y_diff + scroll_min_y_offset) * f;
-             grid->paint_start_y = 0;
-
-           }
-       }
-      else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE)
-       {
-         grid->anim_step++;
-
-         if (grid->anim_step >= grid->anim_n_steps)
-           {
-             grid->state     = CLTR_PHOTO_GRID_STATE_ZOOMED;
-             grid->anim_step = 0;
-           }
-         else
-           {
-             float f = (float)grid->anim_step/grid->anim_n_steps;
-
-             grid->paint_trans_x = grid->view_min_x + (view_x_diff * f);
-             grid->paint_trans_y = grid->view_min_y + (view_y_diff * f);
-           }
-       }
-      else if (grid->state == CLTR_PHOTO_GRID_STATE_SCROLLED_MOVE)
-       {
-         grid->paint_zoom    = grid->zoom_min;
-         grid->paint_trans_x = grid->view_min_x;
-         grid->paint_trans_y = grid->view_min_y - row_offset_h;
-         grid->anim_step++;
-
-          if (grid->anim_step >= (grid->anim_n_steps/4))
-           {
-             grid->state      = CLTR_PHOTO_GRID_STATE_BROWSE;
-             grid->anim_step  = 0;
-             grid->paint_zoom = grid->zoom_min;
-           }
-         else
-           {
-             float f = (float)grid->anim_step / (grid->anim_n_steps/4);
-
-             grid->paint_trans_y += (grid->scroll_dist * f);
-
-             if (grid->scroll_dist > 0) /* up */
-               {
-                 grid->paint_start_y = (grid->row_offset-1) * grid->cell_height;
-               }
-             else              /* down */
-               {
-                 grid->paint_cell_item = g_list_nth(grid->cells_tail, 
-                                                    grid->n_cols * (grid->row_offset-1));
-               }
-           }
-       }
-    }
-}
-
-static void
-cltr_photo_grid_paint(CltrWidget *widget)
-{
-  int x = 0, y = 0, rows = 0, cols = 0, i =0;
-  GList *cell_item;
-
-  CltrPhotoGrid *grid = (CltrPhotoGrid *)widget;
-
-  rows = grid->n_rows+1;
-
-  CLTR_MARK();
-
-  glPushMatrix();
-
-  if (grid->cells_tail == NULL)
-    {
-      glColor3ub(0xc2, 0xc3, 0xc1);
-      glRecti(0, 0, widget->width, widget->height);
-
-      glPopMatrix();
-      return;
-    }
-
-  /*
-   * Using GL_POLYGON_SMOOTH with 'regular' alpha blends causes ugly seems
-   * in the textures and texture tile borders. We therefore do this 'saturate'
-   * trick painting front -> back.
-   * 
-   * see http://blog.metawrap.com/blog/PermaLink.aspx?guid=db82f92e-9fc8-4635-b3e5-e37a1ca6ee0a 
-   * for more info
-   *
-   * Note bg must be glClearColor( 0.0, 0.0, 0.0, 0.0 ) to work.
-   * Is there a better way.?
-   *  - multisample ?  
-  */
-
-  if (!grid->paint_cell_item)
-    cltr_photo_grid_update_visual_state(grid);
-
-  glEnable(GL_BLEND);
-
-  glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); /* needed  */
-
-  glEnable(GL_POLYGON_SMOOTH);
-
-  glDisable(GL_LIGHTING); 
-  glDisable(GL_DEPTH_TEST);
-
-  glBlendFunc(GL_SRC_ALPHA_SATURATE,GL_ONE);
-
-  glColor4f(1.0, 1.0, 1.0, 1.0);
-
-  /* values from  cltr_photo_grid_update_visual_state() */
-
-  cell_item = grid->paint_cell_item;
-  y         = grid->paint_start_y;
-
-  glTranslatef (grid->paint_trans_x, grid->paint_trans_y, 0.0);
-  glScalef (grid->paint_zoom, grid->paint_zoom, 0.0);
-
-  while (rows--)
-    {
-      cols = grid->n_cols;
-      x = 0; 
-      while (cols--)
-       {
-         CltrPhotoGridCell *cell = (CltrPhotoGridCell *)cell_item->data;
-         Pixbuf            *pixb = NULL;
-         int                x1, x2, y1, y2, thumb_w, thumb_h;
-         int                ns_border, ew_border, selected_offset = 0;
-
-         pixb = cell->pixb;
-
-         thumb_w = (pixb->width  / grid->n_cols);
-         thumb_h = (pixb->height / grid->n_rows);
-
-         if (cell->state == CLTR_PHOTO_GRID_CELL_STATE_APPEARING)
-           {
-             cell->anim_step -= 4;
-
-             if (cell->anim_step <= 0)
-               {
-                 cell->state = CLTR_PHOTO_GRID_CELL_STATE_STATIC;
-               }
-             else
-               {
-                 thumb_w = thumb_w + cell->anim_step;
-                 thumb_h = thumb_h + cell->anim_step;
-               }
-             /* set color here for developing effect 
-               * only fully develop when all picts loaded ?
-               * blur texture too ?
-             */
-             /* glColor4f(1.0, 1.0, 1.0, 0.5); */
-
-             cell->anim_step = 0;
-           }
-
-         if (cell_item == grid->cell_active 
-             && grid->state == CLTR_PHOTO_GRID_STATE_BROWSE)
-           selected_offset = 2;
-
-         ew_border = thumb_w/8;
-         ns_border = (thumb_h/8) + 4; 
-
-         thumb_w -= (2 * ew_border);
-         thumb_h -= (2 * ns_border);
-
-         x1 = x + ((grid->cell_width - thumb_w)/2);
-         y1 = y + ((grid->cell_height - thumb_h)/2);
-
-         x2 = x1 + thumb_w;
-         y2 = y1 + thumb_h;
-
-         glPushMatrix();
-
-         /* Translate origin to rotation point ( photo center ) */
-         glTranslatef( x1 + ((x2-x1)/2), y1 + ((y2-y1)/2), 0.0);
-
-         if (cell->state != CLTR_PHOTO_GRID_CELL_STATE_APPEARING)
-           /* Rotate around Z axis */
-           glRotatef ( cell->angle, 0.0, 0.0, 1.0);
-
-         glEnable(GL_TEXTURE_2D);
-
-         g_mutex_lock(grid->mutex);
-
-         cltr_texture_render_to_gl_quad(cell->texture,
-                                        -(thumb_w/2) - selected_offset,
-                                        -(thumb_h/2) - selected_offset,
-                                        (thumb_w/2) - selected_offset,
-                                        (thumb_h/2) - selected_offset);
-
-         g_mutex_unlock(grid->mutex);
-
-         glDisable(GL_TEXTURE_2D);
-
-
-         if (cell_item == grid->cell_active 
-             && grid->state == CLTR_PHOTO_GRID_STATE_BROWSE)
-           glColor4f(1.0, 1.0, 1.0, 1.0);
-         else
-           glColor4f(0.9, 0.95, 0.95, 1.0);
-
-         glColor4f(1.0, 1.0, 1.0, 1.0);
-
-         /* Draw with origin in center of photo */
-
-
-         glRecti(-(thumb_w/2)-6 - selected_offset, 
-                 -(thumb_h/2)-6 - selected_offset, 
-                 (thumb_w/2)+6 - selected_offset, 
-                 (thumb_h/2)+ns_border - selected_offset);
-
-
-         /*
-         cltr_glu_rounded_rect(-(thumb_w/2)-4, -(thumb_h/2)-4, 
-                               (thumb_w/2)+4, (thumb_h/2)+ns_border,
-                               thumb_w/30,
-                               NULL);
-         */
-
-
-         /* Nice colors */
-         /* glColor4ub(0x3c, 0xbb, 0x15,  0xff); */
-         /* glColor4ub(0x99, 0x99, 0xff,  0xff); */
-         /* glColor4ub(0x99, 0x99, 0x99,  0xff); */
-
-         /* shadow */
-
-             glColor4ub(0x99, 0x99, 0x99,  0xff);
-             glRecti(-(thumb_w/2)-6+2, -(thumb_h/2)-6+2, 
-                     (thumb_w/2)+6+2, (thumb_h/2)+ns_border+2);
-
-
-         /*
-         glColor4f(0.1, 0.1, 0.1, 0.3);
-
-
-         cltr_glu_rounded_rect(-(thumb_w/2)-4 + 1, -(thumb_h/2)-4 + 1, 
-                               (thumb_w/2)+4 + 1, (thumb_h/2)+ns_border +1,
-                               thumb_w/30,
-                               NULL);
-         */
-         
-
-         glColor4f(1.0, 1.0, 1.0, 1.0);
-
-         glEnable(GL_TEXTURE_2D);
-
-         glPopMatrix();
-
-         cell_item = g_list_next(cell_item);
-
-         if (!cell_item)
-           goto finish;
-
-         x += grid->cell_width;
-         i++;
-       }
-
-      y += grid->cell_height;
-    }
-
- finish:
-
-  glPopMatrix();
-
-  /* finally paint background  */
-
-  glDisable(GL_TEXTURE_2D);
-
-  glColor3ub(0xc2, 0xc3, 0xc1);
-
-  glRecti(0, 0, widget->width, widget->height);
-
-  /* reset */
-
-  glDisable(GL_POLYGON_SMOOTH);
-  glDisable(GL_BLEND);
-  glDisable(GL_TEXTURE_2D);
-}
-
-static void
-cltr_photo_grid_show(CltrWidget *widget)
-{
-  CltrPhotoGrid *grid = CLTR_PHOTO_GRID(widget);
-
-  /*
-  GThread       *loader_thread; 
-
-  loader_thread = g_thread_create (cltr_photo_grid_populate,
-                                  (gpointer)grid,
-                                  TRUE,
-                                  NULL);
-  */
-
-  grid->state = CLTR_PHOTO_GRID_STATE_BROWSE;
-
-  if (!grid->is_populated)
-    g_timeout_add(FPS_TO_TIMEOUT(20), 
-                 cltr_photo_grid_idle_cb, grid);
-
-  cltr_widget_queue_paint(widget);
-}
-
-void
-cltr_photo_grid_set_fps(CltrPhotoGrid *grid, int fps)
-{
-  grid->anim_fps = fps;
-}
-
-int
-cltr_photo_grid_get_fps(CltrPhotoGrid *grid)
-{
-  return grid->anim_fps;
-}
-
-void
-cltr_photo_grid_set_anim_steps(CltrPhotoGrid *grid, int steps)
-{
-  grid->anim_n_steps = steps;
-}
-
-int
-cltr_photo_grid_get_anim_steps(CltrPhotoGrid *grid)
-{
-  return grid->anim_n_steps;
-}
-
-
-
-CltrWidget*
-cltr_photo_grid_new(int            width, 
-                   int            height,
-                   int            n_cols,
-                   int            n_rows,
-                   const gchar   *img_path)
-{
-  CltrPhotoGrid *grid = NULL;
-
-  grid = g_malloc0(sizeof(CltrPhotoGrid));
-
-  grid->widget.width  = width;
-  grid->widget.height = height;
-
-  grid->widget.show   = cltr_photo_grid_show;
-  grid->widget.paint  = cltr_photo_grid_paint;
-
-  grid->widget.xevent_handler = cltr_photo_grid_handle_xevent;
-
-  grid->img_path = strdup(img_path);
-  grid->n_cols = n_cols;
-  grid->n_rows = n_rows;
-
-  grid->cell_width  = grid->widget.width  / n_cols;
-  grid->cell_height = grid->widget.height / n_rows;
-
-  grid->state        = CLTR_PHOTO_GRID_STATE_BROWSE;
-  grid->is_populated = FALSE;
-
-  grid->anim_fps     = 50;
-
-  grid->anim_n_steps = 10; /* value needs to be calced dep on rows */
-  grid->anim_step    = 0;
-
-  /* Default 'browse view' */
-  grid->zoom_min  = 1.0;                     
-  grid->view_min_x = (grid->widget.width - (grid->zoom_min * grid->widget.width))/2.0;
-  grid->view_min_y = 0.0;
-
-  /* Assmes cols == rows */
-  grid->zoom_max  = (float) (n_rows * 1.0);
-
-  grid->row_offset = 0;
-
-  grid->mutex = g_mutex_new();
-
-  return CLTR_WIDGET(grid);
-}
diff --git a/clutter/cltr-photo-grid.h b/clutter/cltr-photo-grid.h
deleted file mode 100644 (file)
index e26498f..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef _HAVE_CLTR_PHOTO_GRID_H
-#define _HAVE_CLTR_PHOTO_GRID_H
-
-#include "cltr.h"
-
-typedef struct CltrPhotoGrid CltrPhotoGrid;
-
-typedef struct CltrPhotoGridCell CltrPhotoGridCell;
-
-#define CLTR_PHOTO_GRID(w) (CltrPhotoGrid*)(w)
-
-typedef enum CltrPhotoGridState
-{
-  CLTR_PHOTO_GRID_STATE_BROWSE        ,
-  CLTR_PHOTO_GRID_STATE_ZOOM_IN       ,
-  CLTR_PHOTO_GRID_STATE_ZOOMED        ,
-  CLTR_PHOTO_GRID_STATE_ZOOM_OUT      ,
-  CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE   ,
-  CLTR_PHOTO_GRID_STATE_SCROLLED_MOVE ,
-} 
-CltrPhotoGridState;
-
-typedef enum CltrPhotoGridCellState
-{
-  CLTR_PHOTO_GRID_CELL_STATE_APPEARING,
-  CLTR_PHOTO_GRID_CELL_STATE_STATIC,
-} 
-CltrPhotoGridCellState;
-
-GMutex*
-cltr_photo_grid_mutex(CltrPhotoGrid *grid);
-
-void
-cltr_photo_grid_set_populated(CltrPhotoGrid *grid, gboolean populated);
-
-CltrPhotoGridCell*
-cltr_photo_grid_cell_new(CltrPhotoGrid *grid,
-                        Pixbuf           *pixb);
-
-Pixbuf*
-cltr_photo_grid_cell_pixbuf(CltrPhotoGridCell *cell);
-
-CltrPhotoGridCell*
-cltr_photo_grid_get_active_cell(CltrPhotoGrid *grid);
-
-void
-cltr_photo_grid_set_active_cell(CltrPhotoGrid *grid, CltrPhotoGridCell *cell);
-
-CltrPhotoGridCell*
-cltr_photo_grid_get_first_cell(CltrPhotoGrid *grid);
-
-
-void
-cltr_photo_grid_append_cell(CltrPhotoGrid     *grid,
-                           CltrPhotoGridCell *cell);
-
-void
-cltr_photo_grid_navigate(CltrPhotoGrid *grid,
-                        CltrDirection     direction) ;
-
-void                           /* bleh badly named */
-cltr_photo_grid_activate_cell(CltrPhotoGrid *grid);
-
-gpointer
-cltr_photo_grid_populate(gpointer data) ;
-
-void
-cltr_photo_grid_redraw(CltrPhotoGrid *grid);
-
-CltrWidget*
-cltr_photo_grid_new(int            width, 
-                   int            height,
-                   int            n_cols,
-                   int            n_rows,
-                   const gchar   *img_path);
-
-
-#endif
diff --git a/clutter/cltr-private.h b/clutter/cltr-private.h
deleted file mode 100644 (file)
index e7247b4..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-#ifndef _HAVE_CLTR_PRIVATE_H
-#define _HAVE_CLTR_PRIVATE_H
-
-#include "cltr.h"
-
-#define CLTR_WANT_DEBUG 1
-
-#if (CLTR_WANT_DEBUG)
-
-#define CLTR_DBG(x, a...) \
- g_printerr ( __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a)
-
-#define CLTR_GLERR()                                           \
- {                                                             \
-  GLenum err = glGetError ();  /* Roundtrip */                \
-  if (err != GL_NO_ERROR)                                      \
-    {                                                          \
-      g_printerr (__FILE__ ": GL Error: %x [at %s:%d]\n",      \
-                 err, __func__, __LINE__);                    \
-    }                                                          \
- }
-
-#else
-
-#define CLTR_DBG(x, a...) do {} while (0)
-#define CLTR_GLERR()      do {} while (0)
-
-#endif
-
-#define CLTR_MARK() CLTR_DBG("mark")
-
-typedef void     (*WidgetPaintMethod)   (CltrWidget *widget ) ;
-typedef void     (*WidgetShowMethod)    (CltrWidget *widget ) ;
-typedef void     (*WidgetDestroyMethod) (CltrWidget *widget) ;
-typedef void     (*WidgetFocusMethod)   (CltrWidget *widget) ;
-typedef void     (*WidgetUnfocusMethod) (CltrWidget *widget) ;
-typedef gboolean (*WidgetXEventHandler) (CltrWidget *widget, XEvent *xev) ;
-
-struct CltrWidget
-{
-  int         type;
-  int         x,y,width,height;
-  CltrWidget *parent;
-
-  gboolean    visible;
-
-  GList      *children;
-  int         refcnt;
-
-  /* focus */
-
-  CltrWidget *focus_next_north, *focus_next_south, 
-    *focus_next_west, *focus_next_east;
-
-  /* methods */
-
-  WidgetPaintMethod   paint;
-  WidgetShowMethod    show;
-  WidgetDestroyMethod destroy;
-  WidgetFocusMethod   focus_in;
-  WidgetUnfocusMethod focus_out;
-  WidgetXEventHandler xevent_handler;
-
-  /* Anim ref */
-  
-  CltrAnimator *anim;
-};
-
-typedef struct ClutterMainContext ClutterMainContext;
-
-struct ClutterMainContext
-{
-  Display        *xdpy;
-  Window          xwin_root;
-  int             xscreen;
-  GC              xgc;
-
-  GLXContext      gl_context;
-  
-  CltrWidget     *window;
-  GAsyncQueue    *internal_event_q;
-  
-  PixbufPixel    colors[CLTR_N_COLS];
-};
-
-ClutterMainContext CltrCntx;
-
-#define CLTR_CONTEXT() &CltrCntx
-
-#define FPS_TO_TIMEOUT(t) (1000/(t))
-
-#endif
diff --git a/clutter/cltr-scratch.c b/clutter/cltr-scratch.c
deleted file mode 100644 (file)
index 2b611b0..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-#include "cltr-scratch.h"
-#include "cltr-private.h"
-
-struct CltrScratch
-{
-  CltrWidget   widget;  
-
-  Pixbuf      *pixb;
-  CltrTexture *tex;
-};
-
-static void
-cltr_scratch_show(CltrWidget *widget);
-
-static gboolean 
-cltr_scratch_handle_xevent (CltrWidget *widget, XEvent *xev);
-
-static void
-cltr_scratch_paint(CltrWidget *widget);
-
-
-CltrWidget*
-cltr_scratch_new(int width, int height)
-{
-  CltrScratch *scratch;
-  ClutterFont  *font;
-  PixbufPixel   pixel = { 255, 255, 255, 100 };
-
-  scratch = g_malloc0(sizeof(CltrScratch));
-  
-  scratch->widget.width          = width;
-  scratch->widget.height         = height;
-  
-  scratch->widget.show           = cltr_scratch_show;
-  scratch->widget.paint          = cltr_scratch_paint;
-  
-  scratch->widget.xevent_handler = cltr_scratch_handle_xevent;
-
-  scratch->pixb = pixbuf_new(width, height);
-
-  pixel_set_vals(&pixel, 0, 0, 0, 255);
-
-  pixbuf_fill_rect(scratch->pixb, 0, 0, width, height, &pixel);
-
-  font = font_new ("Sans Bold 72");
-
-  pixel_set_vals(&pixel, 255, 255, 255, 255);
-
-  font_draw(font, scratch->pixb, "Hello", 0, 0, &pixel);  
-
-  scratch->tex = cltr_texture_new(scratch->pixb);
-
-  return CLTR_WIDGET(scratch);
-}
-
-static void
-cltr_scratch_show(CltrWidget *widget)
-{
-  cltr_widget_queue_paint(widget);
-}
-
-static gboolean 
-cltr_scratch_handle_xevent (CltrWidget *widget, XEvent *xev) 
-{
-
-  return TRUE;
-}
-
-static void
-cltr_scratch_paint_old(CltrWidget *widget)
-{
-  CltrScratch *scratch = CLTR_SCRATCH(widget);
-
-  int times = 100, num = 0;
-  int spost = 0;
-  float alphainc = 0.9f / times;
-  float alpha = 0.1f;
-
-  glPushMatrix();
-
-  glEnable(GL_TEXTURE_2D);
-  glDisable(GL_DEPTH_TEST);
-  glDisable(GL_LIGHTING); 
-
-  glBlendFunc(GL_SRC_ALPHA,GL_ONE);
-  glEnable(GL_BLEND);
-
-
-  /*
-  glEnable(GL_BLEND);
-
-  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-  */
-
-  for (num = 0;num < times;num++)
-    {
-      glColor4f(1.0f, 1.0f, 1.0f, alpha);
-      cltr_texture_render_to_gl_quad(scratch->tex,
-                                    widget->x - spost,
-                                    widget->y - spost,
-                                    widget->x + widget->width + spost,
-                                    widget->y + widget->height + spost);
-      spost += 2;
-      alpha = alpha - alphainc;
-    }
-
-  glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
-
-  cltr_texture_render_to_gl_quad(scratch->tex,
-                                widget->x,
-                                widget->y,
-                                widget->x + widget->width ,
-                                widget->y + widget->height);
-
-
-  glDisable(GL_BLEND);
-
-  glPopMatrix();
-}
-
-
-static void
-cltr_scratch_paint(CltrWidget *widget)
-{
-  CltrScratch *scratch = CLTR_SCRATCH(widget);
-  
-  glPushMatrix();
-
-  CLTR_MARK();
-
-  glEnable(GL_BLEND);
-
-  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-  glColor4ub(100, 200, 50, 100);  
-
-  glRecti(widget->x, widget->y, 
-         widget->x + widget->width, 
-         widget->y + widget->height);
-
-  glEnable(GL_TEXTURE_2D);
-
-  cltr_texture_render_to_gl_quad(scratch->tex,
-                                widget->x,
-                                widget->y,
-                                widget->x + widget->width ,
-                                widget->y + widget->height);
-
-  glDisable(GL_TEXTURE_2D);
-
-  glDisable(GL_BLEND);
-
-  glPopMatrix();
-}
diff --git a/clutter/cltr-scratch.h b/clutter/cltr-scratch.h
deleted file mode 100644 (file)
index f9b6de9..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _HAVE_CLTR_SCRATCH_H
-#define _HAVE_CLTR_SCRATCH_H
-
-#include "cltr.h"
-
-typedef struct CltrScratch CltrScratch;
-
-#define CLTR_SCRATCH(w) ((CltrScratch*)(w))
-
-CltrWidget*
-cltr_scratch_new(int width, int height);
-
-
-#endif
diff --git a/clutter/cltr-texture.c b/clutter/cltr-texture.c
deleted file mode 100644 (file)
index 1c5177f..0000000
+++ /dev/null
@@ -1,536 +0,0 @@
-#include "cltr-texture.h"
-#include "cltr-private.h"
-
-/* 
-   IDEAS or less memory
-
-   + texture compression - made no difference ?
-
-   + mipmaps - make zoom faster ? ( vs memory )
-
-   + check max texture size *DONE*
-
-   + how much texture mem available ?
- */
-
-
-
-static int 
-next_p2 ( int a )
-{
-  int rval=1;
-  while(rval < a) 
-    rval <<= 1;
-
-  return rval;
-}
-
-void
-cltr_texture_render_to_gl_quad(CltrTexture *texture, 
-                              int          x1, 
-                              int          y1, 
-                              int          x2, 
-                              int          y2)
-{
-  int   qx1 = 0, qx2 = 0, qy1 = 0, qy2 = 0;
-  int   qwidth = 0, qheight = 0;
-  int   x, y, i =0, lastx = 0, lasty = 0;
-  float tx, ty;
-
-  qwidth  = x2-x1;
-  qheight = y2-y1;
-
-  if (texture->tiles == NULL)
-    cltr_texture_realize(texture);
-
-  if (!texture->tiled)
-    {
-      glBindTexture(GL_TEXTURE_2D, texture->tiles[0]);
-
-      tx = (float) texture->pixb->width  / texture->width;
-      ty = (float) texture->pixb->height / texture->height;
-
-      qx1 = x1;
-      qx2 = x2;
-      
-      qy1 = y1;
-      qy2 = y2;
-      
-      glBegin (GL_QUADS);
-      glTexCoord2f (tx, ty);   glVertex2i   (qx2, qy2);
-      glTexCoord2f (0,  ty);   glVertex2i   (qx1, qy2);
-      glTexCoord2f (0,  0);    glVertex2i   (qx1, qy1);
-      glTexCoord2f (tx, 0);    glVertex2i   (qx2, qy1);
-      glEnd ();        
-      
-      return;
-    }
-
-  for (x=0; x < texture->n_x_tiles; x++)
-    {
-      lasty = 0;
-
-      for (y=0; y < texture->n_y_tiles; y++)
-       {
-         int actual_w, actual_h;
-
-         glBindTexture(GL_TEXTURE_2D, texture->tiles[i]);
-        
-         actual_w = texture->tile_x_size[x] - texture->tile_x_waste[x];
-         actual_h = texture->tile_y_size[y] - texture->tile_y_waste[y]; 
-
-         tx = (float) actual_w / texture->tile_x_size[x];
-         ty = (float) actual_h / texture->tile_y_size[y];
-         
-         qx1 = x1 + lastx;
-         qx2 = qx1 + ((qwidth * actual_w ) / texture->width );
-         
-         qy1 = y1 + lasty;
-         qy2 = qy1 + ((qheight * actual_h) / texture->height );
-
-         glBegin (GL_QUADS);
-         glTexCoord2f (tx, ty);   glVertex2i   (qx2, qy2);
-         glTexCoord2f (0,  ty);   glVertex2i   (qx1, qy2);
-         glTexCoord2f (0,  0);    glVertex2i   (qx1, qy1);
-         glTexCoord2f (tx, 0);    glVertex2i   (qx2, qy1);
-         glEnd ();     
-
-         lasty += qy2 - qy1;     
-
-         i++;
-       }
-      lastx += qx2 - qx1;
-    }
-}
-                         
-
-/* Code below based heavily from luminocity - copyright Owen Taylor */
-
-/*  MAX_WASTE: The maximum dimension of blank area we'll accept
- *       in a pixmap. Bigger values use less textures, smaller
- *       values less texture memory. The current value of 
- *       256 means that the smallest texture we'll split to
- *       save texture memory is 513x512. (That will be split into
- *       a 512x512 and, if overlap is 32, a 64x512 texture)
- */
-#define MAX_WASTE 64
-
-/*
- * OVERLAP: when we divide the full-resolution image into
- *          tiles to deal with hardware limitations, we overlap
- *          tiles by this much. This means that we can scale
- *          down by up to OVERLAP before we start getting
- *          seems.
- */
-
-#define OVERLAP 0 /* 32 */
-
-static gboolean
-can_create (int width, int height)
-{
-  GLint new_width;
-
-  glTexImage2D (GL_PROXY_TEXTURE_2D, 0, GL_RGBA,
-                width, height, 0 /* border */,
-                GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
-
-  glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0,
-                            GL_TEXTURE_WIDTH, &new_width);
-
-  return new_width != 0;
-}
-
-
-static int
-tile_dimension (int  to_fill,
-               int  start_size,
-               int *positions,
-               int *sizes,
-               int *waste)
-               
-{
-  int pos     = 0;
-  int n_tiles = 0;
-  int size    = start_size;
-
-  while (TRUE)
-    {
-      if (positions)
-       positions[n_tiles] = pos;
-      if (sizes)
-       sizes[n_tiles] = size;
-      if (waste)
-       waste[n_tiles] = 0;
-
-      n_tiles++;
-       
-      if (to_fill <= size)
-       {
-         if (waste)
-           waste[n_tiles-1] = size - to_fill;
-         break;
-       }
-      else
-       {
-
-         to_fill -= (size - OVERLAP);
-         pos += size - OVERLAP;
-         while (size >= 2 * to_fill || size - to_fill > MAX_WASTE)
-           size /= 2;
-       }
-
-
-    }
-
-  return n_tiles;
-}
-
-static void
-init_tiles (CltrTexture *texture)
-{
-  int x_pot = next_p2 (texture->width);
-  int y_pot = next_p2 (texture->height);
-
-  while (!(can_create (x_pot, y_pot) &&
-          (x_pot - texture->width < MAX_WASTE) &&
-          (y_pot - texture->height < MAX_WASTE)))
-    {
-      if (x_pot > y_pot)
-       x_pot /= 2;
-      else
-       y_pot /= 2;
-    }
-
-  texture->n_x_tiles = tile_dimension (texture->width, x_pot, 
-                                      NULL, NULL, NULL);
-
-  texture->tile_x_position = g_new (int, texture->n_x_tiles);
-  texture->tile_x_size     = g_new (int, texture->n_x_tiles);
-  texture->tile_x_waste    = g_new (int, texture->n_x_tiles);
-
-  tile_dimension (texture->width, x_pot,
-                 texture->tile_x_position, 
-                 texture->tile_x_size,
-                 texture->tile_x_waste);
-  
-  texture->n_y_tiles = tile_dimension (texture->height, y_pot, 
-                                      NULL, NULL, NULL);
-
-  texture->tile_y_position = g_new (int, texture->n_y_tiles);
-  texture->tile_y_size     = g_new (int, texture->n_y_tiles);
-  texture->tile_y_waste    = g_new (int, texture->n_y_tiles);
-
-  tile_dimension (texture->height, y_pot,
-                 texture->tile_y_position, 
-                 texture->tile_y_size,
-                 texture->tile_y_waste);
-  
-
-#if 0
-  /* debug info */
- {
-   int i;
-
-   g_print("n_x_tiles %i, n_y_tiles %i\n", 
-          texture->n_x_tiles, texture->n_y_tiles);
-
-   g_print ("Tiled %d x %d texture as [", texture->width, texture->height);
-   for (i = 0; i < texture->n_x_tiles; i++)
-     {
-       if (i != 0)
-        g_print (",");
-       g_print ("%d(%d)", texture->tile_x_size[i], texture->tile_x_position[i]);
-     }
-   g_print ("]x[");
-   for (i = 0; i < texture->n_y_tiles; i++)
-     {
-       if (i != 0)
-        g_print (",");
-       g_print ("%d(%d)", texture->tile_y_size[i], texture->tile_y_position[i]);
-     }
-   g_print ("]\n");
- }
-#endif
-
-}
-
-/* End borrowed luminocity code */
-
-void
-cltr_texture_unrealize(CltrTexture *texture)
-{
-  if (texture->tiles == NULL)
-    return;
-
-  if (!texture->tiled)
-    glDeleteTextures(1, texture->tiles);
-  else
-    glDeleteTextures(texture->n_x_tiles * texture->n_y_tiles, texture->tiles);
-
-  g_free(texture->tiles);
-
-  texture->tiles = NULL;
-
-}
-
-void
-cltr_texture_realize(CltrTexture *texture)
-{
-  int        x, y, i = 0;
-
-  if (!texture->tiled)
-    {
-      if (!texture->tiles)
-       {
-         texture->tiles = g_new (GLuint, 1);
-         glGenTextures (1, texture->tiles);
-       }
-
-      glBindTexture(GL_TEXTURE_2D, texture->tiles[0]);
-       
-      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-      /* glTexEnvi      (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); */
-      
-      glTexImage2D(GL_TEXTURE_2D, 0, /*GL_COMPRESSED_RGBA_ARB*/ GL_RGBA, 
-                  texture->width,
-                  texture->height,
-                  0, GL_RGBA, 
-                  GL_UNSIGNED_INT_8_8_8_8,
-                  NULL);
-
-      CLTR_GLERR();
-
-      cltr_texture_sync_pixbuf(texture);
-
-      return;
-    }
-
-  if (!texture->tiles)
-    {
-      texture->tiles = g_new (GLuint, texture->n_x_tiles * texture->n_y_tiles);
-      glGenTextures (texture->n_x_tiles * texture->n_y_tiles, texture->tiles);
-    }
-
-  for (x=0; x < texture->n_x_tiles; x++)
-    for (y=0; y < texture->n_y_tiles; y++)
-      {
-       Pixbuf *pixtmp;
-       int src_h, src_w;
-       
-       src_w = texture->tile_x_size[x];
-       src_h = texture->tile_y_size[y];
-       
-       /*
-         CLTR_DBG("%i+%i, %ix%i to %ix%i, waste %ix%i",
-         texture->tile_x_position[x],
-         texture->tile_y_position[y],
-         texture->tile_x_size[x], 
-         texture->tile_y_size[y],
-         texture->width,
-         texture->height,
-         texture->tile_x_waste[x], 
-         texture->tile_y_waste[y]);
-       */
-       
-       /* Only break the pixbuf up if we have multiple tiles */
-       /* if (texture->n_x_tiles > 1 && texture->n_y_tiles >1) */
-       {
-         pixtmp = pixbuf_new(texture->tile_x_size[x], 
-                             texture->tile_y_size[y]);
-         
-         pixbuf_copy(texture->pixb, 
-                     pixtmp,
-                     texture->tile_x_position[x],
-                     texture->tile_y_position[y],
-                     texture->tile_x_size[x], 
-                     texture->tile_y_size[y],
-                     0,0);
-       }
-       /* else pixtmp = texture->pixb; */
-       
-       
-       glBindTexture(GL_TEXTURE_2D, texture->tiles[i]);
-       
-       CLTR_GLERR();
-
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-glTexEnvi      (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-       /* glTexEnvi      (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,   GL_BLEND); */
-
-       /* glPixelStorei (GL_UNPACK_ALIGNMENT, 4); */
-       /* glPixelStorei (GL_UNPACK_ROW_LENGTH, texture->tile_x_size[x]); */
-
-       glTexImage2D(GL_TEXTURE_2D, 0, /*GL_COMPRESSED_RGBA_ARB*/ GL_RGBA, 
-                    pixtmp->width,
-                    pixtmp->height,
-                    0, GL_RGBA, 
-                    GL_UNSIGNED_INT_8_8_8_8, 
-                    /* GL_UNSIGNED_BYTE, */
-                    pixtmp->data);
-
-       CLTR_GLERR();
-
-       CLTR_DBG("pixtmp is %ix%i texture %ix%i\n", 
-                pixtmp->width, pixtmp->height, 
-                texture->width, texture->height); 
-
-       pixbuf_unref(pixtmp);
-
-       i++;
-
-      }
-
-}
-
-CltrTexture*
-cltr_texture_new(Pixbuf *pixb)
-{
-  CltrTexture *texture;
-
-  CLTR_MARK();
-
-  texture = g_malloc0(sizeof(CltrTexture));
-
-  texture->width  = pixb->width;
-  texture->height = pixb->height;
-  texture->tiled  = TRUE;
-
-  /* maybe we should copy the pixbuf - a change to refed one would explode */
-  texture->pixb   = pixb;
-  texture->mutex  = g_mutex_new();
-
-  pixbuf_ref(pixb);
-
-  init_tiles (texture);
-
-  cltr_texture_ref(texture);
-
-  return texture;
-}
-
-void
-cltr_texture_ref(CltrTexture *texture)
-{
-  texture->refcnt++;
-}
-
-void
-cltr_texture_unref(CltrTexture *texture)
-{
-  texture->refcnt--;
-
-  if (texture->refcnt <= 0)
-    {
-      cltr_texture_unrealize(texture);
-      if (texture->pixb)
-       pixbuf_unref(texture->pixb);
-      g_free(texture);
-    }
-}
-
-CltrTexture*
-cltr_texture_no_tile_new(Pixbuf *pixb)
-{
-  CltrTexture *texture;
-
-  CLTR_MARK();
-
-  texture = g_malloc0(sizeof(CltrTexture));
-  
-  texture->tiled  = FALSE;
-  texture->width  = next_p2(pixb->width);
-  texture->height = next_p2(pixb->height);
-
-  if (!can_create (texture->width, texture->height))
-    {
-      free(texture);
-      return NULL;
-    }
-
-  texture->pixb   = pixb;
-  texture->mutex  = g_mutex_new();
-
-  pixbuf_ref(pixb);
-  cltr_texture_ref(texture);
-
-  return texture;
-}
-
-
-Pixbuf*
-cltr_texture_get_pixbuf(CltrTexture* texture)
-{
-  return texture->pixb;
-}
-
-void
-cltr_texture_lock(CltrTexture* texture)
-{
-  g_mutex_lock(texture->mutex);
-}
-
-void
-cltr_texture_unlock(CltrTexture* texture)
-{
-  g_mutex_unlock(texture->mutex);
-}
-
-void
-cltr_texture_sync_pixbuf(CltrTexture* texture)
-{
-  if (texture->tiled)
-    {
-      cltr_texture_realize(texture);
-    }
-  else
-    {
-      if (!texture->tiles)
-       cltr_texture_realize(texture);
-
-      glBindTexture(GL_TEXTURE_2D, texture->tiles[0]);
-
-      glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0,
-                      texture->pixb->width,
-                      texture->pixb->height,
-                      GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 
-                      texture->pixb->data);
-    }
-}
-
-
-/*
- * This is a nasty hack to work round me not figuring out 
- * how to get RGBA data out of gstreamer in a format clutters
- * GL setup can handle :(
- *
- * The good side is it probably speeds video playback up by
- * avoiding copys of frame data. 
- */
-void
-cltr_texture_force_rgb_data(CltrTexture *texture,
-                           int          width,
-                           int          height,
-                           int         *data)
-{
-  if (texture->tiled)
-    return;
-
-  if (!texture->tiles)
-    cltr_texture_realize(texture);
-    
-  glBindTexture(GL_TEXTURE_2D, texture->tiles[0]);
-
-  glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0,
-                  width, 
-                  height,
-                  GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
-                  data);
-
-  CLTR_GLERR();
-}
diff --git a/clutter/cltr-texture.h b/clutter/cltr-texture.h
deleted file mode 100644 (file)
index 70a6380..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef _HAVE_CLTR_TEX_H
-#define _HAVE_CLTR_TEX_H
-
-#include "cltr.h"
-
-
-
-struct CltrTexture
-{
-  Pixbuf *pixb;
-
-  int    width, height;
-
-  gboolean tiled;
-
-  int     n_x_tiles, n_y_tiles;
-  int    *tile_x_position, *tile_x_size, *tile_x_waste;
-  int    *tile_y_position, *tile_y_size, *tile_y_waste;
-
-  GLuint *tiles;
-
-  GMutex *mutex;
-
-  gint    refcnt; 
-};
-
-
-CltrTexture*
-cltr_texture_new(Pixbuf *pixb);
-
-void
-cltr_texture_ref(CltrTexture *texture);
-
-void
-cltr_texture_unref(CltrTexture *texture);
-
-CltrTexture*
-cltr_texture_no_tile_new(Pixbuf *pixb);
-
-void
-cltr_texture_unrealize(CltrTexture *texture);
-
-void
-cltr_texture_realize(CltrTexture *texture);
-
-void
-cltr_texture_render_to_gl_quad(CltrTexture *texture, 
-                              int          x1, 
-                              int          y1, 
-                              int          x2, 
-                              int          y2);
-
-Pixbuf*
-cltr_texture_get_pixbuf(CltrTexture* texture);
-
-void
-cltr_texture_lock(CltrTexture* texture);
-
-void
-cltr_texture_unlock(CltrTexture* texture);
-
-void
-cltr_texture_sync_pixbuf(CltrTexture* texture);
-
-void
-cltr_texture_force_rgb_data(CltrTexture *texture,
-                           int          width,
-                           int          height,
-                           int         *data);
-
-
-#endif
diff --git a/clutter/cltr-video.c b/clutter/cltr-video.c
deleted file mode 100644 (file)
index 869ccf7..0000000
+++ /dev/null
@@ -1,923 +0,0 @@
-#include "cltr-video.h"
-#include "cltr-private.h"
-
-/* This is all very much based on the totem gst bacon video widget */
-
-struct CltrVideo
-{
-  CltrWidget  widget;  
-
-  GstElement  *play, *data_src, *video_sink, *audio_sink, *vis_element;
-
-  GAsyncQueue *queue;
-
-  gint         video_width, video_height;
-  gdouble      video_fps;
-  CltrTexture *frame_texture;
-  
-  gboolean     has_video, has_audio;
-
-  gint64       stream_length;
-  gint64       current_time_nanos;
-  gint64       current_time;
-  float        current_position;
-
-  guint        update_id;
-  gchar       *last_error_message;
-  gchar       *mrl;
-};
-
-
-static void
-cltr_video_show(CltrWidget *widget);
-
-static gboolean 
-cltr_video_handle_xevent (CltrWidget *widget, XEvent *xev);
-
-static void
-cltr_video_paint(CltrWidget *widget);
-
-static void
-parse_stream_info (CltrVideo *video);
-
-static gboolean
-cb_iterate (CltrVideo *video);
-
-static void
-reset_error_msg (CltrVideo *video);
-
-static gboolean
-cltr_video_idler (CltrVideo *video);
-
-
-static gint64     length = 0;  /* to go */
-
-static void
-cltr_video_print_tag (const GstTagList *list, 
-                     const gchar      *tag, 
-                     gpointer          unused)
-{
-  gint i, count;
-
-  count = gst_tag_list_get_tag_size (list, tag);
-
-  for (i = 0; i < count; i++) {
-    gchar *str;
-
-    if (gst_tag_get_type (tag) == G_TYPE_STRING) {
-      if (!gst_tag_list_get_string_index (list, tag, i, &str))
-        g_assert_not_reached ();
-    } else {
-      str =
-          g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i));
-    }
-
-    if (i == 0) {
-      g_print ("%15s: %s\n", gst_tag_get_nick (tag), str);
-    } else {
-      g_print ("               : %s\n", str);
-    }
-
-    g_free (str);
-  }
-}
-
-static void
-got_eos (GstPlay* play, CltrVideo *video)
-{
-  CLTR_DBG ("End Of Stream\n");
-
-  CltrVideoSignal *signal;
-
-  signal = g_new0 (CltrVideoSignal, 1);
-
-  signal->signal_id = CLTR_VIDEO_ASYNC_EOS;
-
-  g_async_queue_push (video->queue, signal);
-
-  gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY);
-}
-
-static void
-got_stream_length (GstElement *play, 
-                  gint64      length_nanos,
-                   CltrVideo  *video)
-{
-  video->stream_length = (gint64) length_nanos / GST_MSECOND;
-
-  CLTR_MARK();
-  /* fire off some callback here ? */
-
-  CLTR_DBG("length: %li", video->stream_length);
-}
-
-static void
-got_time_tick (GstElement *play, 
-              gint64      time_nanos, 
-              CltrVideo  *video)
-{
-  CLTR_MARK();
-
-  video->current_time_nanos = time_nanos;
-
-  video->current_time = (gint64) time_nanos / GST_MSECOND;
-
-  if (video->stream_length == 0)
-    video->current_position = 0;
-  else
-    {
-      video->current_position = (float) video->current_time / video->stream_length;
-    }
-
-  CLTR_DBG("current pos is %f\n", video->current_position);
-  
-  /* fire off callback here */
-}
-
-
-static void
-got_found_tag (GstPlay    *play, 
-              GstElement *source, 
-              GstTagList *tag_list,
-              CltrVideo  *video)
-{
-  CltrVideoSignal *signal;
-
-  CLTR_MARK();
-
-  signal = g_new0 (CltrVideoSignal, 1);
-  signal->signal_id                      = CLTR_VIDEO_ASYNC_FOUND_TAG;
-  signal->signal_data.found_tag.source   = source;
-  signal->signal_data.found_tag.tag_list = gst_tag_list_copy (tag_list);
-
-  g_async_queue_push (video->queue, signal);
-
-  /* gst_tag_list_foreach (tag_list, cltr_video_print_tag, NULL); */
-}
-
-static void
-got_state_change (GstElement     *play, 
-                 GstElementState old_state,
-                 GstElementState new_state, 
-                 CltrVideo      *video)
-{
-  if (old_state == GST_STATE_PLAYING) 
-    {
-      if (video->update_id != 0) 
-       {
-         g_source_remove (video->update_id);
-         video->update_id = 0;
-       }
-
-      g_idle_remove_by_data (video);
-
-
-    } 
-  else if (new_state == GST_STATE_PLAYING) 
-    {
-      if (video->update_id != 0)
-       g_source_remove (video->update_id);
-
-      video->update_id = g_timeout_add (200, (GSourceFunc) cb_iterate, video);
-
-      g_idle_add((GSourceFunc) cltr_video_idler, video);
-    }
-
-  if (old_state <= GST_STATE_READY && new_state >= GST_STATE_PAUSED) 
-    {
-      parse_stream_info (video);
-    } 
-  else if (new_state <= GST_STATE_READY && old_state >= GST_STATE_PAUSED) 
-    {
-      video->has_video = FALSE;
-      video->has_audio = FALSE;
-
-      /* blank the texture */
-
-      /* while (g_async_queue_try_pop (video->queue)) ; */
-
-      /*
-      if (bvw->priv->tagcache)
-       {
-         gst_tag_list_free (bvw->priv->tagcache);
-         bvw->priv->tagcache = NULL;
-       }
-      */      
-
-      video->video_width  = 0;
-      video->video_height = 0;
-    }
-}
-
-
-static void
-got_redirect (GstElement  *play, 
-             const gchar *new_location,
-             CltrVideo   *bvw)
-{
-  CLTR_MARK();
-
-  /*
-  bvw->priv->got_redirect = TRUE;
-
-  signal = g_new0 (BVWSignal, 1);
-  signal->signal_id = ASYNC_REDIRECT;
-  signal->signal_data.redirect.new_location = g_strdup (new_location);
-
-  g_async_queue_push (bvw->priv->queue, signal);
-
-  g_idle_add ((GSourceFunc) bacon_video_widget_signal_idler, bvw);
-  */
-}
-
-
-static void
-stream_info_set (GObject    *obj, 
-                GParamSpec *pspec, 
-                CltrVideo  *video)
-{
-
-  parse_stream_info (video);
-
-  /*
-  signal = g_new0 (BVWSignal, 1);
-  signal->signal_id = ASYNC_NOTIFY_STREAMINFO;
-
-  g_async_queue_push (bvw->priv->queue, signal);
-
-  g_idle_add ((GSourceFunc) bacon_video_widget_signal_idler, bvw);
-  */
-}
-
-static void
-got_source (GObject    *play,
-           GParamSpec *pspec,
-           CltrVideo  *video)
-{
-  GObject      *source = NULL;
-  GObjectClass *klass;
-
-  CLTR_MARK();
-
-  /*
-  if (bvw->priv->tagcache) {
-    gst_tag_list_free (bvw->priv->tagcache);
-    bvw->priv->tagcache = NULL;
-  }
-
-  if (!bvw->priv->media_device)
-    return;
-
-  g_object_get (play, "source", &source, NULL);
-  if (!source)
-    return;
-
-  klass = G_OBJECT_GET_CLASS (source);
-  if (!g_object_class_find_property (klass, "device"))
-    return;
-
-  g_object_set (source, "device", bvw->priv->media_device, NULL);
-  */
-}
-
-
-static void
-got_buffering (GstElement *play, 
-              gint        percentage,
-              CltrVideo  *video)
-{
-  CLTR_DBG("Buffering with %i", percentage);
-
-#if 0
-  BVWSignal *signal;
-
-  g_return_if_fail (bvw != NULL);
-  g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
-
-  signal = g_new0 (BVWSignal, 1);
-  signal->signal_id = ASYNC_BUFFERING;
-  signal->signal_data.buffering.percent = percentage;
-
-  g_async_queue_push (bvw->priv->queue, signal);
-
-  g_idle_add ((GSourceFunc) bacon_video_widget_signal_idler, bvw);
-#endif
-}
-
-static void
-reset_error_msg (CltrVideo *video)
-{
-  if (video->last_error_message)
-    {
-      g_free (video->last_error_message);
-      video->last_error_message = NULL;
-    }
-}
-
-
-static void
-got_error (GstElement *play, 
-          GstElement *orig, 
-          GError     *error,
-           gchar      *debug, 
-          CltrVideo  *video)
-{
-
-  /* 
-     XXX TODO cpy the error message to asyc queueu
-
-  */
-
-  CLTR_MARK();
-
-#if 0
-  /* since we're opening, we will never enter the mainloop
-   * until we return, so setting an idle handler doesn't
-   * help... Anyway, let's prepare a message. */
-  if (GST_STATE (play) != GST_STATE_PLAYING) {
-    g_free (bvw->priv->last_error_message);
-    bvw->priv->last_error_message = g_strdup (error->message);
-    return;
-  }
-  
-  signal = g_new0 (BVWSignal, 1);
-  signal->signal_id = ASYNC_ERROR;
-  signal->signal_data.error.element = orig;
-  signal->signal_data.error.error = g_error_copy (error);
-  if (debug)
-    signal->signal_data.error.debug_message = g_strdup (debug);
-
-  g_async_queue_push (bvw->priv->queue, signal);
-
-  g_idle_add ((GSourceFunc) bacon_video_widget_signal_idler, bvw);
-#endif
-}
-
-
-static void
-caps_set (GObject         *obj,
-         GParamSpec      *pspec, 
-         CltrVideo       *video)
-{
-  GstPad *pad = GST_PAD (obj);
-  GstStructure *s;
-
-  if (!GST_PAD_CAPS (pad))
-    return;
-
-  s = gst_caps_get_structure (GST_PAD_CAPS (pad), 0);
-
-  if (s) 
-    {
-      /* const GValue *par; */
-
-      if (!(gst_structure_get_double (s, "framerate", &video->video_fps) &&
-           gst_structure_get_int (s, "width", &video->video_width) &&
-           gst_structure_get_int (s, "height", &video->video_height)))
-       return;
-
-      /*
-      if ((par = gst_structure_get_value (s, "pixel-aspect-ratio"))) 
-       {
-         gint num = gst_value_get_fraction_numerator (par),
-           den = gst_value_get_fraction_denominator (par);
-
-         if (num > den)
-           bvw->priv->video_width *= (gfloat) num / den;
-         else
-           bvw->priv->video_height *= (gfloat) den / num;
-       }
-
-       got_video_size (bvw->priv->play, bvw->priv->video_width,
-       bvw->priv->video_height, bvw);
-
-      */
-  }
-}
-
-
-static void
-parse_stream_info (CltrVideo *video)
-{
-  GList  *streaminfo = NULL;
-  GstPad *videopad = NULL;
-
-  g_object_get (G_OBJECT (video->play), "stream-info", &streaminfo, NULL);
-
-  streaminfo = g_list_copy (streaminfo);
-
-  g_list_foreach (streaminfo, (GFunc) g_object_ref, NULL);
-
-  for ( ; streaminfo != NULL; streaminfo = streaminfo->next) 
-    {
-      GObject *info = streaminfo->data;
-      gint type;
-      GParamSpec *pspec;
-      GEnumValue *val;
-
-      if (!info)
-       continue;
-
-      g_object_get (info, "type", &type, NULL);
-
-      pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (info), "type");
-
-      val = g_enum_get_value (G_PARAM_SPEC_ENUM (pspec)->enum_class, type);
-
-    if (strstr (val->value_name, "AUDIO")) 
-      {
-       if (!video->has_audio) {
-         video->has_audio = TRUE;
-         /*if (!bvw->priv->media_has_video &&
-            bvw->priv->show_vfx && bvw->priv->vis_element) {
-           videopad = gst_element_get_pad (bvw->priv->vis_element, "src");
-           }*/
-       }
-      } 
-    else if (strstr (val->value_name, "VIDEO")) 
-      {
-       video->has_video = TRUE;
-       if (!videopad)
-         g_object_get (info, "object", &videopad, NULL);
-
-      }
-    }
-
-  if (videopad) 
-    {
-      GstPad *real = (GstPad *) GST_PAD_REALIZE (videopad);
-
-      /* handle explicit caps as well - they're set later */
-      if (((GstRealPad *) real)->link != NULL && GST_PAD_CAPS (real))
-       caps_set (G_OBJECT (real), NULL, video);
-
-      g_signal_connect (real, "notify::caps", G_CALLBACK (caps_set), video);
-
-    } 
-  /*
-  else if (bvw->priv->show_vfx && bvw->priv->vis_element) 
-    {
-      fixate_visualization (NULL, NULL, bvw);
-    }
-  */
-
-  g_list_foreach (streaminfo, (GFunc) g_object_unref, NULL);
-  g_list_free (streaminfo);
-}
-
-static gboolean
-cb_iterate (CltrVideo *video)
-{
-  GstFormat fmt = GST_FORMAT_TIME;
-  gint64          value;
-
-  CLTR_MARK();
-
-  /* check length/pos of stream */
-  if (gst_element_query (GST_ELEMENT (video->play),
-                        GST_QUERY_TOTAL, &fmt, &value) 
-      && GST_CLOCK_TIME_IS_VALID (value) 
-      && value / GST_MSECOND != video->stream_length) 
-    {
-      got_stream_length (GST_ELEMENT (video->play), value, video);
-    }
-
-  if (gst_element_query (GST_ELEMENT (video->play),
-                        GST_QUERY_POSITION, &fmt, &value)) 
-    {
-      got_time_tick (GST_ELEMENT (video->play), value, video);
-    }
-
-  return TRUE;
-}
-
-CltrWidget*
-cltr_video_new(int width, int height)
-{
-  CltrVideo *video;
-  GError    *error = NULL;
-
-  video = g_malloc0(sizeof(CltrVideo));
-  
-  video->widget.width          = width;
-  video->widget.height         = height;
-  
-  video->widget.show           = cltr_video_show;
-  video->widget.paint          = cltr_video_paint;
-  
-  video->widget.xevent_handler = cltr_video_handle_xevent;
-
-  /* Creating the GstPlay object */
-
-  video->play = gst_element_factory_make ("playbin", "play");
-  if (!video->play) {
-    g_error ("Could not make playbin element");
-    /* XXX Error */
-    return NULL;
-  }
-
-  video->audio_sink = gst_gconf_get_default_audio_sink ();
-
-  if (!GST_IS_ELEMENT (video->audio_sink))
-    g_error ("Could not get default audio sink from GConf");
-  
-  video->video_sink = gst_element_factory_make ("cltrimagesink", "cltr-output");
-
-  if (!GST_IS_ELEMENT (video->video_sink))
-    g_error ("Could not get clutter video sink");
-
-#if 0
-  sig1 = g_signal_connect (video_sink, "error", G_CALLBACK (out_error), err);
-  sig2 = g_signal_connect (audio_sink, "error", G_CALLBACK (out_error), err);
-  if (gst_element_set_state (video_sink,
-                            GST_STATE_READY) != GST_STATE_SUCCESS ||
-      gst_element_set_state (audio_sink,
-                            GST_STATE_READY) != GST_STATE_SUCCESS) {
-    if (err && !*err) {
-      g_set_error (err, 0, 0,
-                  "Failed to intialize %s output; check your configuration",
-                  GST_STATE (video_sink) == GST_STATE_NULL ?
-                  "video" : "audio");
-    }
-    gst_object_unref (GST_OBJECT (video_sink));
-    gst_object_unref (GST_OBJECT (audio_sink));
-    g_object_unref (G_OBJECT (bvw));
-    return NULL;
-  }
-  /* somehow, alsa hangs? */
-  gst_element_set_state (video->audio_sink, GST_STATE_NULL);
-  g_signal_handler_disconnect (video->video_sink, sig1);
-  g_signal_handler_disconnect (video->audio_sink, sig2);
-#endif
-  g_object_set (G_OBJECT (video->play), "video-sink",
-               video->video_sink, NULL);
-  g_object_set (G_OBJECT (video->play), "audio-sink",
-               video->audio_sink, NULL);
-
-  /* Needed ? */
-#if 0
-  g_signal_connect (GST_PAD_REALIZE (gst_element_get_pad (audio_sink, "sink")),
-                   "fixate", G_CALLBACK (cb_audio_fixate), (gpointer) bvw);
-#endif
-
-  g_signal_connect (G_OBJECT (video->play), "eos",
-                    G_CALLBACK (got_eos), (gpointer) video);
-
-  g_signal_connect (G_OBJECT (video->play), "state-change",
-                   G_CALLBACK (got_state_change), (gpointer) video);
-
-  g_signal_connect (G_OBJECT (video->play), "found_tag",
-                   G_CALLBACK (got_found_tag), (gpointer) video);
-
-  g_signal_connect (G_OBJECT (video->play), "error",
-                   G_CALLBACK (got_error), (gpointer) video);
-
-  g_signal_connect (G_OBJECT (video->play), "buffering",
-                   G_CALLBACK (got_buffering), (gpointer) video);
-
-  g_signal_connect (G_OBJECT (video->play), "notify::source",
-                   G_CALLBACK (got_source), (gpointer) video);
-
-  g_signal_connect (G_OBJECT (video->play), "notify::stream-info",
-                   G_CALLBACK (stream_info_set), (gpointer) video);
-
-  /* what does this do ?
-  g_signal_connect (G_OBJECT (video->play), "group-switch",
-                   G_CALLBACK (group_switch), (gpointer) video);
-  */
-
-  g_signal_connect (G_OBJECT (video->play), "got-redirect",
-                   G_CALLBACK (got_redirect), (gpointer) video);
-
-
-  video->queue = g_async_queue_new ();
-
-  gst_element_set(video->video_sink, "queue", video->queue, NULL);
-
-
-  return CLTR_WIDGET(video);
-}
-
-gboolean
-cltr_video_play ( CltrVideo *video, GError ** error)
-{
-  gboolean ret;
-
-  reset_error_msg (video);
-
-  ret = (gst_element_set_state (GST_ELEMENT (video->play),
-                               GST_STATE_PLAYING) == GST_STATE_SUCCESS);
-  if (!ret)
-    {
-      g_set_error (error, 0, 0, "%s", video->last_error_message ?
-          video->last_error_message : "Failed to play; reason unknown");
-    }
-
-  return ret;
-}
-
-gint64
-cltr_video_get_time (CltrVideo *video)
-{
-  CLTR_DBG("current pos is %f\n", video->current_position);
-
-  return video->current_time;
-}
-
-gboolean
-cltr_video_seek (CltrVideo *video, float position, GError **gerror)
-{
-  gint64 seek_time, length_nanos;
-
-  /* Resetting last_error_message to NULL */
-  if (video->last_error_message)
-    {
-      g_free (video->last_error_message);
-      video->last_error_message = NULL;
-    }
-
-  length_nanos = (gint64) (video->stream_length * GST_MSECOND);
-  seek_time    = (gint64) (length_nanos * position);
-
-  gst_element_seek (video->play, GST_SEEK_METHOD_SET |
-                   GST_SEEK_FLAG_FLUSH | GST_FORMAT_TIME,
-                   seek_time);
-
-  return TRUE;
-}
-
-gboolean
-cltr_video_seek_time (CltrVideo *video, gint64 time, GError **gerror)
-{
-  if (video->last_error_message)
-    {
-      g_free (video->last_error_message);
-      video->last_error_message = NULL;
-    }
-
-  gst_element_seek (video->play, GST_SEEK_METHOD_SET |
-                   GST_SEEK_FLAG_FLUSH | GST_FORMAT_TIME,
-                   time * GST_MSECOND);
-
-  return TRUE;
-}
-
-void
-cltr_video_stop ( CltrVideo *video)
-{
-  gst_element_set_state (GST_ELEMENT (video->play), GST_STATE_READY);
-}
-
-void
-cltr_video_close ( CltrVideo *video)
-{
-  gst_element_set_state (GST_ELEMENT (video->play), GST_STATE_READY);
-  
-  /* XX close callback here */
-}
-
-void
-cltr_video_pause ( CltrVideo *video)
-{
-  gst_element_set_state (GST_ELEMENT (video->play), GST_STATE_PAUSED);
-}
-
-
-gboolean
-cltr_video_can_set_volume ( CltrVideo *video )
-{
-  return TRUE;
-}
-
-void
-cltr_video_set_volume ( CltrVideo *video, int volume)
-{
-  if (cltr_video_can_set_volume (video) != FALSE)
-  {
-    volume = CLAMP (volume, 0, 100);
-    g_object_set (G_OBJECT (video->play), "volume",
-       (gdouble) (1. * volume / 100), NULL);
-  }
-}
-
-int
-cltr_video_get_volume ( CltrVideo *video)
-{
-  gdouble vol;
-
-  g_object_get (G_OBJECT (video->play), "volume", &vol, NULL);
-
-  return (gint) (vol * 100 + 0.5);
-}
-
-Pixbuf*
-cltr_video_get_pixbuf (CltrVideo *video)
-{
-  Pixbuf *pixb = NULL;
-
-  /* if (video->frame_texture) */
-    {
-      cltr_texture_lock(video->frame_texture);
-
-      pixb = pixbuf_clone(cltr_texture_get_pixbuf(video->frame_texture));
-
-      cltr_texture_unlock(video->frame_texture);
-    }
-
-  return pixb;
-}
-
-static gboolean
-cltr_video_idler (CltrVideo *video)
-{
-  gint  queue_length;
-  CltrVideoSignal *signal;
-
-  signal = g_async_queue_try_pop (video->queue);
-
-  if (!signal)
-    return TRUE;
-
-  switch (signal->signal_id)
-    {
-    case CLTR_VIDEO_ASYNC_TEXTURE:
-      {
-       Pixbuf *pixb = NULL;
-
-       video->frame_texture = signal->signal_data.texture.ref;
-
-       cltr_texture_lock(video->frame_texture);
-
-       if (cltr_texture_get_pixbuf(video->frame_texture))
-         cltr_texture_sync_pixbuf(video->frame_texture);
-
-       cltr_texture_unlock(video->frame_texture);
-
-       cltr_widget_queue_paint(CLTR_WIDGET(video));
-      }
-      break;
-    case CLTR_VIDEO_ASYNC_VIDEO_SIZE:
-      video->video_width  = signal->signal_data.video_size.width;
-      video->video_height = signal->signal_data.video_size.height;
-      break;
-    case CLTR_VIDEO_ASYNC_ERROR:
-      break;
-    case CLTR_VIDEO_ASYNC_FOUND_TAG:
-      break;
-    case CLTR_VIDEO_ASYNC_NOTIFY_STREAMINFO:
-      break;
-    case CLTR_VIDEO_ASYNC_EOS:
-      break; 
-    case CLTR_VIDEO_ASYNC_BUFFERING:
-      break;
-    case CLTR_VIDEO_ASYNC_REDIRECT:
-      break; 
-    }
-
-  g_free (signal);
-
-  return TRUE;
-}
-
-gboolean
-cltr_video_set_source(CltrVideo *video, char *mrl)
-{
-  gboolean ret;
-
-  if (video->mrl && !strcmp (video->mrl, mrl))
-    return TRUE;
-
-  if (video->mrl)
-    g_free (video->mrl);
-
-  video->mrl = g_strdup (mrl);
-
-  gst_element_set_state (GST_ELEMENT (video->play), GST_STATE_READY);
-
-  reset_error_msg (video);
-
-  /* video->got_redirect  = FALSE; */
-  video->has_video     = FALSE;
-  video->stream_length = 0;
-
-  /* Dont handle subtitles as yet
-  if (g_strrstr (video->mrl, "#subtitle:")) 
-    {
-      gchar **uris;
-
-      uris = g_strsplit (video->mrl, "#subtitle:", 2);
-      g_object_set (G_OBJECT (video->play), "uri",
-                   uris[0], "suburi", uris[1], NULL);
-      g_strfreev (uris);
-    } 
-  else 
-    {
-      g_object_set (G_OBJECT (video->play), "uri",
-                   video->mrl, "suburi", subtitle_uri, NULL);
-  }
-  */
-
-  g_object_set (G_OBJECT (video->play), "uri",
-               video->mrl, "suburi", NULL, NULL);
-
-  ret = (gst_element_set_state (video->play, 
-                               GST_STATE_PAUSED) == GST_STATE_SUCCESS);
-
-
-  if (!ret /* && !video->got_redirect */)
-    {
-
-      /*
-      g_set_error (error, 0, 0, "%s", video->last_error_message ?
-          video->last_error_message : "Failed to open; reason unknown");
-      */
-
-      g_free (video->mrl);
-      video->mrl = NULL;
-      
-      return FALSE;
-    }
-
-  /*
-  if (ret)
-    g_signal_emit (bvw, bvw_table_signals[SIGNAL_CHANNELS_CHANGE], 0);
-  */
-
-  return ret;
-}
-
-
-
-static void
-cltr_video_show(CltrWidget *widget)
-{
-  return;
-}
-
-static void
-cltr_video_hide(CltrWidget *widget)
-{
-  return;
-}
-
-static gboolean 
-cltr_video_handle_xevent (CltrWidget *widget, XEvent *xev) 
-{
-  CLTR_DBG("X Event");
-
-  return False;
-}
-
-static void
-cltr_video_paint(CltrWidget *widget)
-{
-  CltrVideo *video = CLTR_VIDEO(widget);
-
-  glPushMatrix();
-
-  if (video->frame_texture
-      && video->video_height
-      && video->video_width)
-    {
-      int dis_x = 0, dis_y = 0, dis_height = 0, dis_width = 0;
-
-      if (video->video_width > video->video_height)
-       {
-         dis_width  = widget->width;
-         dis_height = ( video->video_height * widget->width )
-                                 / video->video_width;
-         dis_y = (widget->height - dis_height)/2;
-         dis_x = 0;
-       }
-
-      glEnable(GL_TEXTURE_2D);
-
-      /*
-      glEnable(GL_BLEND);
-
-      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-      */
-
-      glColor4f(1.0, 1.0, 1.0, 1.0);
-
-      cltr_texture_lock(video->frame_texture);
-
-      cltr_texture_render_to_gl_quad(video->frame_texture, 
-                                    widget->x + dis_x, 
-                                    widget->y + dis_y,
-                                    widget->x + dis_x + dis_width,
-                                    widget->y + dis_y + dis_height);
-
-      cltr_texture_unlock(video->frame_texture);
-
-      glDisable(GL_TEXTURE_2D); 
-
-      glDisable(GL_BLEND); 
-
-      // glColor4f(1.0, 1.0, 1.0, 0.5);
-
-      // glRecti(100, 100, 600, 600);
-    }
-
-  glPopMatrix();
-}
diff --git a/clutter/cltr-video.h b/clutter/cltr-video.h
deleted file mode 100644 (file)
index 49754ef..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifndef _HAVE_CLTR_VIDEO_H
-#define _HAVE_CLTR_VIDEO_H
-
-#include "cltr.h"
-
-#include <gst/play/play.h>
-#include <gst/gconf/gconf.h>
-
-typedef struct CltrVideo CltrVideo;
-
-/* Signals - cltrimagesink needs to deliver texture signals :/ */
-
-enum {
-  CLTR_VIDEO_ASYNC_TEXTURE,
-  CLTR_VIDEO_ASYNC_VIDEO_SIZE,
-  CLTR_VIDEO_ASYNC_ERROR,
-  CLTR_VIDEO_ASYNC_FOUND_TAG,
-  CLTR_VIDEO_ASYNC_NOTIFY_STREAMINFO,
-  CLTR_VIDEO_ASYNC_EOS,
-  CLTR_VIDEO_ASYNC_BUFFERING,
-  CLTR_VIDEO_ASYNC_REDIRECT
-};
-
-typedef struct CltrVideoSignal
-{
-  gint signal_id;
-  union
-  {
-    struct
-    {
-      gint width;
-      gint height;
-    } video_size;
-    struct
-    {
-      GstElement *element;
-      GError *error;
-      char *debug_message;
-    } error;
-    struct
-    {
-      GstElement *source;
-      GstTagList *tag_list;
-    } found_tag;
-    struct
-    {
-      gint percent;
-    } buffering;
-    struct
-    {
-      gchar *new_location;
-    } redirect;
-    struct
-    {
-      CltrTexture *ref;
-    } texture;
-  } signal_data;
-}
-CltrVideoSignal;
-
-#define CLTR_VIDEO(w) ((CltrVideo*)(w))
-
-CltrWidget*
-cltr_video_new(int width, int height);
-
-gboolean
-cltr_video_set_source(CltrVideo *video, char *location);
-
-gboolean
-cltr_video_play ( CltrVideo *video, GError ** Error);
-
-gint64
-cltr_video_get_time (CltrVideo *video);
-
-gboolean
-cltr_video_seek (CltrVideo *video, float position, GError **gerror);
-
-gboolean
-cltr_video_seek_time (CltrVideo *video, gint64 time, GError **gerror);
-
-void
-cltr_video_stop ( CltrVideo *video);
-
-void
-cltr_video_close ( CltrVideo *video);
-
-void
-cltr_video_pause ( CltrVideo *video);
-
-gboolean
-cltr_video_can_set_volume ( CltrVideo *video );
-
-void
-cltr_video_set_volume ( CltrVideo *video, int volume);
-
-int
-cltr_video_get_volume ( CltrVideo *video);
-
-Pixbuf*
-cltr_video_get_pixbuf (CltrVideo *video);
-
-
-#endif
diff --git a/clutter/cltr-widget.c b/clutter/cltr-widget.c
deleted file mode 100644 (file)
index 908bbb5..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-#include "cltr-widget.h"
-#include "cltr-private.h"
-
-CltrWidget*
-cltr_widget_new(void)
-{
-  CltrWidget *w = NULL;
-
-  w = g_malloc0(sizeof(CltrWidget));
-
-  return w;
-}
-
-int
-cltr_widget_abs_x(CltrWidget *widget)
-{
-  int x = widget->x;
-
-  /* XXX we really need to identify top level window
-   *     this assummes its positioned at 0,0 - but really 
-   *     it could be anywhere and need to account for this. 
-  */
-
-  while ((widget = widget->parent) != NULL)
-    x += widget->x;
-
-  return x;
-}
-
-int
-cltr_widget_abs_y(CltrWidget *widget)
-{
-  int y = widget->y;
-
-  while ((widget = widget->parent) != NULL)
-    y += widget->y;
-
-  return y;
-}
-
-int
-cltr_widget_abs_x2(CltrWidget *widget)
-{
-  return cltr_widget_abs_x(widget) + cltr_widget_width(widget);
-}
-
-int
-cltr_widget_abs_y2(CltrWidget *widget)
-{
-  return cltr_widget_abs_y(widget) + cltr_widget_height(widget);
-}
-
-
-int
-cltr_widget_width(CltrWidget *widget)
-{
-  return widget->width;
-}
-
-int
-cltr_widget_height(CltrWidget *widget)
-{
-  return widget->height;
-}
-
-
-void
-cltr_widget_show(CltrWidget *widget)
-{
-  widget->visible = TRUE;
-
-  if (widget->show)
-    {
-      widget->show(widget);
-    }
-}
-
-void
-cltr_widget_unref(CltrWidget *widget)
-{
-  widget->refcnt--;
-
-  if (widget->refcnt < 0 && widget->destroy)
-    {
-      widget->destroy(widget);
-    }
-}
-
-
-/* XXX Focus hacks; 
- * 
- * Should not call directly but via cltr_window_focus_widget()
- *
- * need to sort this out. 
-*/
-void
-cltr_widget_focus(CltrWidget *widget)
-{
-  if (widget->focus_in)
-    {
-      widget->focus_in(widget);
-    }
-}
-
-void
-cltr_widget_unfocus(CltrWidget *widget)
-{
-  if (widget->focus_out)
-    {
-      widget->focus_out(widget);
-    }
-}
-
-void
-cltr_widget_set_focus_next(CltrWidget    *widget,
-                          CltrWidget    *widget_to_focus,
-                          CltrDirection  direction)
-{
-  switch (direction)
-    {
-    case CLTR_NORTH:
-      widget->focus_next_north = widget_to_focus;
-      break;
-    case CLTR_SOUTH:
-      widget->focus_next_south = widget_to_focus;
-      break;
-    case CLTR_EAST:
-      widget->focus_next_east = widget_to_focus;
-      break;
-    case CLTR_WEST:
-      widget->focus_next_west = widget_to_focus;
-      break;
-    }
-}
-
-CltrWidget*
-cltr_widget_get_focus_next(CltrWidget    *widget,
-                          CltrDirection  direction)
-{
-  switch (direction)
-    {
-    case CLTR_NORTH:
-      return widget->focus_next_north;
-    case CLTR_SOUTH:
-      return widget->focus_next_south;
-    case CLTR_EAST:
-      return widget->focus_next_east;
-    case CLTR_WEST:
-      return widget->focus_next_west;
-    }
-
-  return NULL;
-}
-
-
-void
-cltr_widget_show_all(CltrWidget *widget)
-{
-  GList *widget_item =  widget->children;;
-
-  if (widget_item)
-    {
-      do 
-       {
-         CltrWidget *child = CLTR_WIDGET(widget_item->data);
-
-         cltr_widget_show(child);
-
-         cltr_widget_show_all(child);
-       }
-      while ((widget_item = g_list_next(widget_item)) != NULL);
-    }
-
-  cltr_widget_show(widget);
-}
-
-void
-cltr_widget_add_child(CltrWidget *widget, CltrWidget *child, int x, int y)
-{
-
-  widget->children = g_list_append(widget->children, child);
-
-  child->parent = widget;
-  child->x      = x;
-  child->y      = y;
-
-}
-
-void
-cltr_widget_remove_child(CltrWidget *widget, CltrWidget *child)
-{
-  widget->children = g_list_remove(widget->children, child);
-
-  child->parent = NULL;
-  child->x      = 0;
-  child->y      = 0;
-}
-
-
-void
-cltr_widget_hide(CltrWidget *widget)
-{
-  widget->visible = FALSE;
-}
-
-void
-cltr_widget_paint(CltrWidget *widget)
-{
-  if (widget->visible)
-    {
-      GList *child_item =  widget->children;;
-
-      if (widget->paint)
-       widget->paint(widget);
-
-      /* Recurse down */
-      if (child_item)
-       {
-         do 
-           {
-             CltrWidget *child = CLTR_WIDGET(child_item->data);
-             
-             if (child->visible)
-               cltr_widget_paint(child);
-             
-           }
-         while ((child_item = g_list_next(child_item)) != NULL);
-       }
-    }
-}
-
-void
-cltr_widget_queue_paint(CltrWidget *widget)
-{
-  ClutterMainContext *ctx = CLTR_CONTEXT();
-
-  g_async_queue_push (ctx->internal_event_q, (gpointer)widget);
-}
-
-gboolean
-cltr_widget_handle_xevent(CltrWidget *widget, XEvent *xev)
-{
-  if (!widget->visible)
-    return FALSE;
-
-  if (widget && widget->xevent_handler)
-    return widget->xevent_handler(widget, xev);
-
-  return FALSE;
-}
diff --git a/clutter/cltr-widget.h b/clutter/cltr-widget.h
deleted file mode 100644 (file)
index ca106e0..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef _HAVE_CLTR_WIDGET_H
-#define _HAVE_CLTR_WIDGET_H
-
-#include "cltr.h"
-
-#define CLTR_WIDGET(w) ((CltrWidget*)(w))
-
-CltrWidget*
-cltr_widget_new(void);
-
-int
-cltr_widget_width(CltrWidget *widget);
-
-int
-cltr_widget_height(CltrWidget *widget);
-
-int
-cltr_widget_abs_x(CltrWidget *widget);
-
-int
-cltr_widget_abs_y(CltrWidget *widget);
-
-int
-cltr_widget_abs_x2(CltrWidget *widget);
-
-int
-cltr_widget_abs_y2(CltrWidget *widget);
-
-
-/* These are hacky see notes in .c */
-void
-cltr_widget_focus(CltrWidget *widget);
-
-void
-cltr_widget_unfocus(CltrWidget *widget);
-
-/* ******************************* */
-
-void
-cltr_widget_set_focus_next(CltrWidget    *widget,
-                          CltrWidget    *widget_to_focus,
-                          CltrDirection  direction);
-
-CltrWidget*
-cltr_widget_get_focus_next(CltrWidget    *widget,
-                          CltrDirection  direction);
-
-void
-cltr_widget_show(CltrWidget *widget);
-
-void
-cltr_widget_paint(CltrWidget *widget);
-
-void
-cltr_widget_unref(CltrWidget *widget);
-
-gboolean
-cltr_widget_handle_xevent(CltrWidget *widget, XEvent *xev);
-
-void
-cltr_widget_show_all(CltrWidget *widget);
-
-void
-cltr_widget_queue_paint(CltrWidget *widget);
-
-void
-cltr_widget_add_child(CltrWidget *widget, CltrWidget *child, int x, int y);
-
-void
-cltr_widget_remove_child(CltrWidget *widget, CltrWidget *child);
-
-#endif
diff --git a/clutter/cltr-window.c b/clutter/cltr-window.c
deleted file mode 100644 (file)
index 33beb83..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-#include "cltr-window.h"
-#include "cltr-private.h"
-
-static gboolean 
-cltr_window_handle_xevent (CltrWidget *widget, XEvent *xev);
-
-static void
-cltr_window_show(CltrWidget *widget);
-
-static void
-cltr_window_paint(CltrWidget *widget);
-
-struct CltrWindow
-{
-  CltrWidget    widget;  
-  Window        xwin;
-  CltrWidget   *focused_child;
-
-  CltrCallback *pre_paint_hook, *post_paint_hook;
-
-  CltrXEventCallback  xevent_cb;
-  gpointer           *xevent_cb_data;
-
-  CltrCallback        post_paint_cb;
-  gpointer           *post_paint_cb_data;
-
-  CltrCallback        pre_paint_cb;
-  gpointer           *pre_paint_cb_data;
-};
-
-void
-clrt_window_set_gl_viewport(CltrWindow *win)
-{
-  CltrWidget *widget = CLTR_WIDGET(win);
-
-  glViewport (0, 0, widget->width, widget->height);
-  glMatrixMode (GL_PROJECTION);
-  glLoadIdentity ();
-  glOrtho (0, widget->width, widget->height, 0, -1, 1); /* 2d */
-  glMatrixMode (GL_MODELVIEW);
-  glLoadIdentity ();
-}
-
-CltrWidget*
-cltr_window_new(int width, int height)
-{
-  ClutterMainContext *ctx = CLTR_CONTEXT();
-  CltrWindow *win;
-
-  win = util_malloc0(sizeof(CltrWindow));
-
-  win->widget.width          = width;
-  win->widget.height         = height;
-  win->widget.show           = cltr_window_show;
-  win->widget.paint          = cltr_window_paint;
-  win->widget.xevent_handler = cltr_window_handle_xevent;
-
-  win->xwin = XCreateSimpleWindow(CltrCntx.xdpy,
-                                 CltrCntx.xwin_root,
-                                 0, 0,
-                                 width, height,
-                                 0, 0, WhitePixel(CltrCntx.xdpy, 
-                                                  CltrCntx.xscreen));
-
-  XSelectInput(CltrCntx.xdpy, win->xwin, 
-              StructureNotifyMask|ExposureMask|
-              KeyPressMask|KeyReleaseMask|PropertyChangeMask);
-
-  glXMakeCurrent(CltrCntx.xdpy, win->xwin, CltrCntx.gl_context);
-
-  /* All likely better somewhere else */
-
-  ctx->window = CLTR_WIDGET(win);
-
-  clrt_window_set_gl_viewport(win);
-
-  return CLTR_WIDGET(win);
-}
-
-static void
-cltr_window_show(CltrWidget *widget)
-{
-  ClutterMainContext *ctx = CLTR_CONTEXT();
-  CltrWindow         *win = CLTR_WINDOW(widget);
-
-  /* XXX set focused call */
-  if (widget->children)
-    {
-      if (win->focused_child == NULL)
-       win->focused_child = g_list_nth_data(widget->children, 0);
-    }
-
-  XMapWindow(ctx->xdpy, win->xwin);
-}
-
-static void
-cltr_window_paint(CltrWidget *widget)
-{
-  CltrWindow         *win = CLTR_WINDOW(widget);
-
-  clrt_window_set_gl_viewport(win);
-
-  glClear(GL_COLOR_BUFFER_BIT);
-
-  glDisable(GL_LIGHTING); 
-  glDisable(GL_DEPTH_TEST);
-
-  glClearColor( 0.0, 0.0, 0.0, 0.0 ); /* needed for saturate to work */
-
-  if (win->pre_paint_cb)
-    win->pre_paint_cb(widget, win->pre_paint_cb_data);
-}
-
-static void
-cltr_window_handle_xconfigure(CltrWindow *win, XConfigureEvent *cxev)
-{
-  /* 
-     widget.width = cxev->width;
-     widget.height = cxev->height;
-  */
-
-}                            
-
-static gboolean 
-cltr_window_handle_xevent (CltrWidget *widget, XEvent *xev) 
-{
-  CltrWindow *win = CLTR_WINDOW(widget);
-
-  /* XXX handle exposes here too */
-
-  if (xev->type == Expose)
-    {
-      cltr_widget_queue_paint(widget);
-    }
-
-  /*
-    case ConfigureNotify:
-    wm_handle_configure_request(w, &ev.xconfigure); break;
-  */
-
-  if (xev->type == KeyPress)
-    {
-      if (XKeycodeToKeysym(xev->xkey.display, 
-                          xev->xkey.keycode, 0) == XK_Escape)
-       exit(0);
-    }
-
-  /* XXX Very basic - assumes we are only interested in mouse clicks */
-  if (win->focused_child)
-    cltr_widget_handle_xevent(win->focused_child, xev);
-
-  if (win->xevent_cb)
-    (win->xevent_cb)(widget, xev, win->xevent_cb_data);
-
-  return FALSE;
-}
-
-/* window only methods */
-
-void
-cltr_window_post_paint(CltrWindow *win)
-{
-  if (win->post_paint_cb)
-    win->post_paint_cb(CLTR_WIDGET(win), win->post_paint_cb_data);
-}
-
-/* naming is a little odd */
-void
-cltr_window_set_paint_funcs(CltrWindow  *win,
-                           CltrCallback pre_paint,
-                           gpointer     pre_userdata,
-                           CltrCallback post_paint,
-                           gpointer     post_userdata)
-{
-  win->post_paint_cb      = post_paint;
-  win->post_paint_cb_data = post_userdata;
-  win->pre_paint_cb       = pre_paint;
-  win->pre_paint_cb_data = pre_userdata;
-}
-
-
-Window
-cltr_window_xwin(CltrWindow *win)
-{
-  return win->xwin;
-}
-
-void
-cltr_window_hide_cursor(CltrWindow *win)
-{
-  ClutterMainContext *ctx = CLTR_CONTEXT();
-  XColor              col;
-  Pixmap              pix;
-  Cursor              curs;
-
-  pix = XCreatePixmap (ctx->xdpy, win->xwin, 1, 1, 1);
-
-  memset (&col, 0, sizeof (col));
-
-  curs = XCreatePixmapCursor (ctx->xdpy, pix, pix, &col, &col, 1, 1);
-
-  XFreePixmap (ctx->xdpy, pix);
-
-  XDefineCursor(ctx->xdpy, win->xwin, curs);
-}
-
-void
-cltr_window_set_fullscreen(CltrWindow *win)
-{
-  ClutterMainContext *ctx = CLTR_CONTEXT();
-
-  Atom atom_WINDOW_STATE, atom_WINDOW_STATE_FULLSCREEN;
-
-  atom_WINDOW_STATE 
-    = XInternAtom(ctx->xdpy, "_NET_WM_STATE", False);
-  atom_WINDOW_STATE_FULLSCREEN 
-    = XInternAtom(ctx->xdpy, "_NET_WM_STATE_FULLSCREEN",False);
-
-  XChangeProperty(ctx->xdpy, win->xwin,
-                 atom_WINDOW_STATE, XA_ATOM, 32,
-                 PropModeReplace,
-                 (unsigned char *)&atom_WINDOW_STATE_FULLSCREEN, 1);
-
-  /* 
-    XF86VidModeSwitchToMode (GLWin.dpy, GLWin.screen, &GLWin.deskMode);
-    XF86VidModeSetViewPort (GLWin.dpy, GLWin.screen, 0, 0);
-  */
-
-  cltr_window_hide_cursor(win);
-}
-
-
-void
-cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget)
-{
-  /* XXX Should check widget is an actual child of the window */
-
-  /* ClutterMainContext *ctx = CLTR_CONTEXT(); */
-
-  if (win->focused_child)
-    cltr_widget_unfocus(win->focused_child);
-
-  cltr_widget_focus(widget);
-
-  win->focused_child = widget;
-}
-
-void
-cltr_window_on_xevent(CltrWindow         *win,
-                     CltrXEventCallback  callback,
-                     void               *userdata)
-{
-  win->xevent_cb      = callback;
-  win->xevent_cb_data = userdata;
-}
-
-
diff --git a/clutter/cltr-window.h b/clutter/cltr-window.h
deleted file mode 100644 (file)
index b0a3c68..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef _HAVE_CLTR_WINDOW_H
-#define _HAVE_CLTR_WINDOW_H
-
-#include "cltr.h"
-
-typedef struct CltrWindow CltrWindow;
-
-#define CLTR_WINDOW(w) ((CltrWindow*)(w))
-
-CltrWidget*
-cltr_window_new(int width, int height);
-
-void
-cltr_window_add_widget(CltrWindow *win, CltrWidget *widget, int x, int y);
-
-/* win only methods */
-
-Window
-cltr_window_xwin(CltrWindow *win);
-
-void
-cltr_window_hide_cursor(CltrWindow *win);
-
-void
-cltr_window_set_fullscreen(CltrWindow *win);
-
-void
-cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget);
-
-void
-cltr_window_on_xevent(CltrWindow         *win,
-                     CltrXEventCallback  callback,
-                     void               *userdata);
-void
-cltr_window_post_paint(CltrWindow *win);
-
-
-#endif
diff --git a/clutter/cltr.h b/clutter/cltr.h
deleted file mode 100644 (file)
index 134bad4..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef _HAVE_CLTR_H
-#define _HAVE_CLTR_H
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <math.h>
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/keysym.h>
-
-#include <GL/glx.h>
-#include <GL/gl.h>
-
-#include <glib.h>
-
-#include <gst/gconf/gconf.h>
-
-#include "pixbuf.h"
-#include "fonts.h"
-
-typedef enum CltrDirection
-{
-  CLTR_NORTH,
-  CLTR_SOUTH,
-  CLTR_EAST,
-  CLTR_WEST
-} 
-CltrDirection;
-
-typedef enum CltrNamedColor
-{
-  CLTR_COL_BG = 0,
-  CLTR_COL_BDR,
-  CLTR_COL_FG,
-  CLTR_N_COLS
-} 
-CltrNamedColor;
-
-typedef struct CltrRect
-{
-  int x, y, width, height;
-}
-CltrRect;
-
-typedef struct CltrTexture CltrTexture;
-
-#define cltr_rect_x1(r) ((r).x)
-#define cltr_rect_y1(r) ((r).y)
-#define cltr_rect_x2(r) ((r).x + (r).width)
-#define cltr_rect_y2(r) ((r).y + (r).height)
-
-typedef struct CltrWidget CltrWidget;
-
-
-
-typedef void (*CltrCallback) (CltrWidget *widget, void *userdata) ;
-
-typedef void (*CltrXEventCallback) (CltrWidget *widget, 
-                                   XEvent     *xev,
-                                   void       *userdata) ;
-
-
-/* texture stuff */
-
-/* ******************* */
-
-#include "cltr-core.h"
-#include "cltr-glu.h"
-#include "cltr-texture.h"
-#include "cltr-events.h"
-#include "cltr-widget.h"
-#include "cltr-animator.h"
-#include "cltr-window.h"
-#include "cltr-overlay.h"
-#include "cltr-label.h"
-#include "cltr-button.h"
-#include "cltr-photo-grid.h"
-#include "cltr-list.h"
-#include "cltr-video.h"
-
-#endif
diff --git a/clutter/clutter-clone-texture.c b/clutter/clutter-clone-texture.c
new file mode 100644 (file)
index 0000000..d54f648
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "clutter-clone-texture.h"
+#include "clutter-main.h"
+#include "clutter-util.h" 
+#include "clutter-enum-types.h"
+#include "clutter-private.h"   /* for DBG */
+
+enum
+{
+  PROP_0,
+  PROP_PARENT_TEXTURE
+};
+
+G_DEFINE_TYPE (ClutterCloneTexture,
+              clutter_clone_texture,
+              CLUTTER_TYPE_ELEMENT);
+
+#define CLUTTER_CLONE_TEXTURE_GET_PRIVATE(obj) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_CLONE_TEXTURE, ClutterCloneTexturePrivate))
+
+struct _ClutterCloneTexturePrivate
+{
+  ClutterTexture      *parent_texture;
+};
+
+static void
+clone_texture_render_to_gl_quad (ClutterCloneTexture *ctexture, 
+                                int             x1, 
+                                int             y1, 
+                                int             x2, 
+                                int             y2)
+{
+  gint   qx1 = 0, qx2 = 0, qy1 = 0, qy2 = 0;
+  gint   qwidth = 0, qheight = 0;
+  gint   x, y, i =0, lastx = 0, lasty = 0;
+  gint   n_x_tiles, n_y_tiles; 
+  gint   pwidth, pheight;
+  float tx, ty;
+
+  ClutterCloneTexturePrivate *priv = ctexture->priv;
+  ClutterElement *parent_element = CLUTTER_ELEMENT (priv->parent_texture);
+
+  priv = ctexture->priv;
+
+  qwidth  = x2 - x1;
+  qheight = y2 - y1;
+
+  if (!CLUTTER_ELEMENT_IS_REALIZED (parent_element))
+      clutter_element_realize (parent_element);
+
+  /* Only paint if parent is in a state to do so */
+  if (!clutter_texture_has_generated_tiles (priv->parent_texture))
+    return;
+  
+  clutter_texture_get_base_size (priv->parent_texture, &pwidth, &pheight); 
+
+  if (!clutter_texture_is_tiled (priv->parent_texture))
+    {
+      clutter_texture_bind_tile (priv->parent_texture, 0);
+
+      tx = (float) pwidth / clutter_util_next_p2 (pwidth);  
+      ty = (float) pheight / clutter_util_next_p2 (pheight);
+
+      qx1 = x1; qx2 = x2;
+      qy1 = y1; qy2 = y2;
+      
+      glBegin (GL_QUADS);
+      glTexCoord2f (tx, ty);   glVertex2i   (qx2, qy2);
+      glTexCoord2f (0,  ty);   glVertex2i   (qx1, qy2);
+      glTexCoord2f (0,  0);    glVertex2i   (qx1, qy1);
+      glTexCoord2f (tx, 0);    glVertex2i   (qx2, qy1);
+      glEnd ();        
+      
+      return;
+    }
+
+  clutter_texture_get_n_tiles (priv->parent_texture, &n_x_tiles, &n_y_tiles); 
+
+  for (x=0; x < n_x_tiles; x++)
+    {
+      lasty = 0;
+
+      for (y=0; y < n_y_tiles; y++)
+       {
+         gint actual_w, actual_h;
+         gint xpos, ypos, xsize, ysize, ywaste, xwaste;
+         
+         clutter_texture_bind_tile (priv->parent_texture, i);
+        
+         clutter_texture_get_x_tile_detail (priv->parent_texture, 
+                                            x, &xpos, &xsize, &xwaste);
+
+         clutter_texture_get_y_tile_detail (priv->parent_texture, 
+                                            y, &ypos, &ysize, &ywaste);
+
+         actual_w = xsize - xwaste;
+         actual_h = ysize - ywaste;
+
+         tx = (float) actual_w / xsize;
+         ty = (float) actual_h / ysize;
+
+         qx1 = x1 + lastx;
+         qx2 = qx1 + ((qwidth * actual_w ) / pwidth );
+         
+         qy1 = y1 + lasty;
+         qy2 = qy1 + ((qheight * actual_h) / pheight );
+
+         glBegin (GL_QUADS);
+         glTexCoord2f (tx, ty);   glVertex2i   (qx2, qy2);
+         glTexCoord2f (0,  ty);   glVertex2i   (qx1, qy2);
+         glTexCoord2f (0,  0);    glVertex2i   (qx1, qy1);
+         glTexCoord2f (tx, 0);    glVertex2i   (qx2, qy1);
+         glEnd ();     
+
+         lasty += qy2 - qy1;     
+
+         i++;
+       }
+      lastx += qx2 - qx1;
+    }
+}
+
+static void
+clutter_clone_texture_paint (ClutterElement *self)
+{
+  ClutterCloneTexturePrivate  *priv;
+  ClutterElement              *parent_texture;
+  gint                         x1, y1, x2, y2;
+
+  priv = CLUTTER_CLONE_TEXTURE (self)->priv;
+
+  /* parent texture may have been hidden, there for need to make sure its 
+   * realised with resources available.  
+  */
+  parent_texture = CLUTTER_ELEMENT (priv->parent_texture);
+  if (!CLUTTER_ELEMENT_IS_REALIZED (parent_texture))
+    clutter_element_realize (parent_texture);
+
+  glEnable(GL_BLEND);
+  glEnable(GL_TEXTURE_2D);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+  glColor4ub(255, 255, 255, clutter_element_get_opacity(self));
+
+  clutter_element_get_coords (self, &x1, &y1, &x2, &y2);
+  clone_texture_render_to_gl_quad (CLUTTER_CLONE_TEXTURE(self), 
+                                  x1, y1, x2, y2);
+
+  glDisable(GL_TEXTURE_2D);
+  glDisable(GL_BLEND);
+}
+
+static void
+set_parent_texture (ClutterCloneTexture *ctexture,
+                   ClutterTexture      *texture)
+{
+  ClutterCloneTexturePrivate *priv = ctexture->priv;
+
+  if (priv->parent_texture)
+    {
+      g_object_unref (priv->parent_texture);
+      priv->parent_texture = NULL;
+    }
+
+  if (texture)
+    priv->parent_texture = g_object_ref (texture);
+}
+
+static void 
+clutter_clone_texture_dispose (GObject *object)
+{
+  ClutterCloneTexture         *self = CLUTTER_CLONE_TEXTURE(object);
+  ClutterCloneTexturePrivate  *priv = self->priv;  
+
+  if (priv->parent_texture)
+    g_object_unref (priv->parent_texture);
+
+  priv->parent_texture = NULL;
+
+  G_OBJECT_CLASS (clutter_clone_texture_parent_class)->dispose (object);
+}
+
+static void 
+clutter_clone_texture_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (clutter_clone_texture_parent_class)->finalize (object);
+}
+
+static void
+clutter_clone_texture_set_property (GObject      *object,
+                                   guint         prop_id,
+                                   const GValue *value,
+                                   GParamSpec   *pspec)
+{
+  ClutterCloneTexture *ctexture = CLUTTER_CLONE_TEXTURE (object);
+
+  switch (prop_id)
+    {
+    case PROP_PARENT_TEXTURE:
+      set_parent_texture (ctexture, g_value_get_object (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+clutter_clone_texture_get_property (GObject    *object,
+                                   guint       prop_id,
+                                   GValue     *value,
+                                   GParamSpec *pspec)
+{
+  ClutterCloneTexture *ctexture = CLUTTER_CLONE_TEXTURE (object);
+
+  switch (prop_id)
+    {
+    case PROP_PARENT_TEXTURE:
+      g_value_set_object (value, ctexture->priv->parent_texture);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+clutter_clone_texture_class_init (ClutterCloneTextureClass *klass)
+{
+  GObjectClass        *gobject_class = G_OBJECT_CLASS (klass);
+  ClutterElementClass *element_class = CLUTTER_ELEMENT_CLASS (klass);
+
+  element_class->paint        = clutter_clone_texture_paint;
+
+  gobject_class->finalize     = clutter_clone_texture_finalize;
+  gobject_class->dispose      = clutter_clone_texture_dispose;
+  gobject_class->set_property = clutter_clone_texture_set_property;
+  gobject_class->get_property = clutter_clone_texture_get_property;
+
+  g_object_class_install_property (gobject_class,
+                                  PROP_PARENT_TEXTURE,
+                                  g_param_spec_object ("parent-texture",
+                                                       "Parent Texture",
+                                                       "The parent texture to clone",
+                                                       CLUTTER_TYPE_TEXTURE,
+                                                       (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)));
+
+  g_type_class_add_private (gobject_class, sizeof (ClutterCloneTexturePrivate));
+}
+
+static void
+clutter_clone_texture_init (ClutterCloneTexture *self)
+{
+  ClutterCloneTexturePrivate *priv;
+
+  self->priv = priv = CLUTTER_CLONE_TEXTURE_GET_PRIVATE (self);
+  priv->parent_texture = NULL;
+}
+
+/**
+ * clutter_clone_texture_new:
+ * @texture: a #ClutterTexture
+ *
+ * FIXME
+ *
+ * Return value: the newly created #ClutterCloneTexture
+ */
+ClutterElement *
+clutter_clone_texture_new (ClutterTexture *texture)
+{
+  gint width, height;
+
+  g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), NULL);
+
+  clutter_texture_get_base_size (texture, &width, &height);
+
+  return g_object_new (CLUTTER_TYPE_CLONE_TEXTURE,
+                      "parent-texture", texture,
+                      "width", width,
+                      "height", height,
+                      NULL);
+}
diff --git a/clutter/clutter-clone-texture.h b/clutter/clutter-clone-texture.h
new file mode 100644 (file)
index 0000000..85a1fdd
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _HAVE_CLUTTER_CLONE_TEXTURE_H
+#define _HAVE_CLUTTER_CLONE_TEXTURE_H
+
+#include <glib-object.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <clutter/clutter-texture.h>
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_CLONE_TEXTURE (clutter_clone_texture_get_type ())
+
+#define CLUTTER_CLONE_TEXTURE(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+  CLUTTER_TYPE_CLONE_TEXTURE, ClutterCloneTexture))
+
+#define CLUTTER_CLONE_TEXTURE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), \
+  CLUTTER_TYPE_CLONE_TEXTURE, ClutterCloneTextureClass))
+
+#define CLUTTER_IS_CLONE_TEXTURE(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+  CLUTTER_TYPE_CLONE_TEXTURE))
+
+#define CLUTTER_IS_CLONE_TEXTURE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+  CLUTTER_TYPE_CLONE_TEXTURE))
+
+#define CLUTTER_CLONE_TEXTURE_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+  CLUTTER_TYPE_CLONE_TEXTURE, ClutterCloneTextureClass))
+
+typedef struct _ClutterCloneTexture        ClutterCloneTexture;
+typedef struct _ClutterCloneTexturePrivate ClutterCloneTexturePrivate;
+typedef struct _ClutterCloneTextureClass   ClutterCloneTextureClass;
+
+struct _ClutterCloneTexture
+{
+  ClutterElement                 parent;
+  
+  /*< priv >*/
+  ClutterCloneTexturePrivate    *priv;
+};
+
+struct _ClutterCloneTextureClass 
+{
+  ClutterElementClass parent_class;
+
+  /* padding for future expansion */
+  void (*_clutter_clone_1) (void);
+  void (*_clutter_clone_2) (void);
+  void (*_clutter_clone_3) (void);
+  void (*_clutter_clone_4) (void);
+}; 
+
+GType           clutter_clone_texture_get_type (void);
+ClutterElement *clutter_clone_texture_new      (ClutterTexture *texture);
+
+G_END_DECLS
+
+#endif
diff --git a/clutter/clutter-color.c b/clutter/clutter-color.c
new file mode 100644 (file)
index 0000000..f2bc38e
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "clutter-color.h"
+
+ClutterColor
+clutter_color_new (guint8 r, guint8 g, guint8 b, guint8 a)
+{
+  return ( r | g << 8 | b << 16 | a << 24 );
+}
+
+void
+clutter_color_set (ClutterColor *color, 
+                  guint8        r, 
+                  guint8        g, 
+                  guint8        b, 
+                  guint8        a)
+{
+  *color = ( r | g << 8 | b << 16 | a << 24 );
+}
+
+void
+clutter_color_get (ClutterColor  color, 
+                  guint8        *r, 
+                  guint8        *g, 
+                  guint8        *b, 
+                  guint8        *a)
+{
+  if (r)
+    *r = clutter_color_r(color);
+  if (g)
+    *g = clutter_color_g(color);
+  if (b)
+    *b = clutter_color_b(color);
+  if (a)
+    *a = clutter_color_a(color);
+}
+
+
diff --git a/clutter/clutter-color.h b/clutter/clutter-color.h
new file mode 100644 (file)
index 0000000..eab24a4
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _HAVE_CLUTTER_COLOR_H
+#define _HAVE_CLUTTER_COLOR_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define clutter_color_r(col) ((col) >> 24)
+#define clutter_color_g(col) (((col) >> 16) & 0xff)
+#define clutter_color_b(col) (((col) >> 8) & 0xff)
+#define clutter_color_a(col) ((col) & 0xff)
+
+#define clutter_color_set_r(col,r) ((col) &= (r)) 
+#define clutter_color_set_g(col,g) ((col) &= (g << 8)) 
+#define clutter_color_set_b(col,b) ((col) &= (b << 16)) 
+#define clutter_color_set_a(col,a) ((col) &= (a << 24)) 
+
+typedef guint32 ClutterColor;
+
+ClutterColor
+clutter_color_new (guint8 r, guint8 g, guint8 b, guint8 a);
+
+void
+clutter_color_set (ClutterColor *color, 
+                  guint8        r, 
+                  guint8        g, 
+                  guint8        b, 
+                  guint8        a);
+
+void
+clutter_color_get (ClutterColor  color, 
+                  guint8        *r, 
+                  guint8        *g, 
+                  guint8        *b, 
+                  guint8        *a);
+
+G_END_DECLS
+
+#endif
diff --git a/clutter/clutter-element.c b/clutter/clutter-element.c
new file mode 100644 (file)
index 0000000..c8be3ea
--- /dev/null
@@ -0,0 +1,1285 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:clutter-elementy
+ * @short_description: Base abstract class for all visual stage elements. 
+ * 
+ * #ClutterElement is an blah blah
+ */
+
+#include "config.h"
+
+#include "clutter-element.h"
+#include "clutter-main.h"
+#include "clutter-private.h"
+
+G_DEFINE_ABSTRACT_TYPE (ClutterElement, clutter_element, G_TYPE_OBJECT);
+
+static guint32 __id = 0;
+
+#define CLUTTER_ELEMENT_GET_PRIVATE(obj) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_ELEMENT, ClutterElementPrivate))
+
+struct _ClutterElementPrivate
+{
+  ClutterElementBox       coords;
+
+  ClutterGeometry         clip;
+  gboolean                has_clip;
+
+  ClutterElementTransform mirror_transform;
+  gfloat                  rxang, ryang, rzang; /* Rotation foo. */
+  gint                    rzx, rzy, rxy, rxz, ryx, ryz;
+  gint                    z;   /* to element box ? */
+
+  guint8                  opacity;
+  ClutterElement         *parent_element;
+  gchar                  *name;
+  guint32                 id;  /* Unique ID */
+};
+
+enum
+{
+  PROP_0,
+  PROP_X,
+  PROP_Y,
+  PROP_WIDTH,
+  PROP_HEIGHT,
+  /* PROP_CLIP FIXME: add */
+  PROP_OPACITY,
+  PROP_NAME,
+};
+
+extern ClutterMainContext ClutterCntx;
+
+static gboolean
+redraw_update_idle (gpointer data)
+{
+  ClutterMainContext *ctx = CLUTTER_CONTEXT();
+
+  clutter_threads_enter();
+
+  if (ctx->update_idle)
+    {
+      g_source_remove (ctx->update_idle);
+      ctx->update_idle = 0;
+    }
+
+  clutter_threads_leave();
+
+  clutter_redraw ();
+
+  return FALSE;
+}
+
+/**
+ * clutter_element_show
+ * @self: A #ClutterElement
+ *
+ * Flags a clutter element to be displayed. An element not shown will not 
+ * appear on the display.
+ **/
+void
+clutter_element_show (ClutterElement *self)
+{
+  ClutterElementClass *klass;
+
+  if (CLUTTER_ELEMENT_IS_VISIBLE (self))
+    return;
+
+  if (!CLUTTER_ELEMENT_IS_REALIZED (self))
+    clutter_element_realize(self);
+
+  CLUTTER_ELEMENT_SET_FLAGS (self, CLUTTER_ELEMENT_MAPPED);
+
+  klass = CLUTTER_ELEMENT_GET_CLASS (self);
+
+  if (klass->show)
+    (klass->show) (self);
+
+  if (CLUTTER_ELEMENT_IS_VISIBLE (self))
+    clutter_element_queue_redraw (self);
+}
+
+/**
+ * clutter_element_hide
+ * @self: A #ClutterElement
+ *
+ * Flags a clutter element to be hidden. An element not shown will not 
+ * appear on the display.
+ **/
+void
+clutter_element_hide (ClutterElement *self)
+{
+  ClutterElementClass *klass;
+
+  if (!CLUTTER_ELEMENT_IS_VISIBLE (self))
+    return;
+
+  CLUTTER_ELEMENT_UNSET_FLAGS (self, CLUTTER_ELEMENT_MAPPED);
+
+  klass = CLUTTER_ELEMENT_GET_CLASS (self);
+
+  if (klass->hide)
+    (klass->hide) (self);
+
+  clutter_element_queue_redraw (self);
+}
+
+/**
+ * clutter_element_realize
+ * @self: A #ClutterElement
+ *
+ * Creates any underlying graphics resources needed by the element to be
+ * displayed.  
+ **/
+void
+clutter_element_realize (ClutterElement *self)
+{
+  ClutterElementClass *klass;
+
+  if (CLUTTER_ELEMENT_IS_REALIZED (self))
+    return;
+
+  CLUTTER_ELEMENT_SET_FLAGS (self, CLUTTER_ELEMENT_REALIZED);
+
+  klass = CLUTTER_ELEMENT_GET_CLASS (self);
+
+  if (klass->realize)
+    (klass->realize) (self);
+}
+
+/**
+ * clutter_element_realize
+ * @self: A #ClutterElement
+ *
+ * Frees up any underlying graphics resources needed by the element to be
+ * displayed.  
+ **/
+void
+clutter_element_unrealize (ClutterElement *self)
+{
+  ClutterElementClass *klass;
+
+  if (!CLUTTER_ELEMENT_IS_REALIZED (self))
+    return;
+
+  CLUTTER_ELEMENT_UNSET_FLAGS (self, CLUTTER_ELEMENT_REALIZED);
+
+  klass = CLUTTER_ELEMENT_GET_CLASS (self);
+
+  if (klass->unrealize)
+    (klass->unrealize) (self);
+}
+
+/**
+ * clutter_element_paint:
+ * @self: A #ClutterElement
+ *
+ * Renders the element to display.
+ *
+ * This function should not be called directly by applications instead 
+ * #clutter_element_queue_redraw should be used to queue paints. 
+ **/
+void
+clutter_element_paint (ClutterElement *self)
+{
+  ClutterElementClass *klass;
+
+  if (!CLUTTER_ELEMENT_IS_REALIZED (self))
+    {
+      CLUTTER_DBG("@@@ Attempting realize via paint() @@@");
+      clutter_element_realize(self);
+
+      if (!CLUTTER_ELEMENT_IS_REALIZED (self))
+       {
+         CLUTTER_DBG("*** Attempt failed, aborting paint ***");
+         return;
+       }
+    }
+
+  klass = CLUTTER_ELEMENT_GET_CLASS (self);
+
+  if (self->priv->has_clip)
+    {
+      ClutterGeometry *clip = &self->priv->clip;
+      gint             absx, absy;
+
+      clutter_element_get_abs_position (self, &absx, &absy);
+
+      CLUTTER_DBG("clip +%i+%i, %ix%i\n", 
+                 absx + clip->x, 
+                 clutter_element_get_height(CLUTTER_ELEMENT(clutter_stage())) 
+                 - (absy + clip->y) - clip->height, 
+                 clip->width, 
+                 clip->height);
+
+      glEnable (GL_SCISSOR_TEST);
+
+      glScissor (absx + clip->x, 
+                clutter_element_get_height(CLUTTER_ELEMENT(clutter_stage())) 
+                    - (absy + clip->y) - clip->height, 
+                clip->width, 
+                clip->height);
+    }
+
+  glPushMatrix();
+
+  glLoadName (clutter_element_get_id (self));
+
+  /* FIXME: Less clunky */
+
+  if (self->priv->rzang)
+    {
+      glTranslatef ( (float)(self->priv->coords.x1) + self->priv->rzx,
+                    (float)(self->priv->coords.y1) + self->priv->rzy,
+                    0.0);
+
+      glRotatef (self->priv->rzang, 0.0f, 0.0f, 1.0f);
+
+      glTranslatef ( (-1.0 * self->priv->coords.x1) - self->priv->rzx,
+                    (-1.0 * self->priv->coords.y1) - self->priv->rzy,
+                    0.0 );
+    }
+
+  if (self->priv->ryang)
+    {
+      glTranslatef ( (float)(self->priv->coords.x1) + self->priv->ryx,
+                    0.0,
+                    (float)(self->priv->z) + self->priv->ryz);
+
+      glRotatef (self->priv->ryang, 0.0f, 1.0f, 0.0f);
+
+      glTranslatef ( (float)(-1.0 * self->priv->coords.x1) - self->priv->ryx,
+                    0.0,
+                    (float)(-1.0 * self->priv->z) - self->priv->ryz);
+    }
+
+  if (self->priv->rxang)
+    {
+      glTranslatef ( 0.0,
+                    (float)(self->priv->coords.x1) + self->priv->rxy,
+                    (float)(self->priv->z) + self->priv->rxz);
+
+      glRotatef (self->priv->rxang, 1.0f, 0.0f, 0.0f);
+
+      glTranslatef ( 0.0,
+                    (float)(-1.0 * self->priv->coords.x1) - self->priv->rxy,
+                    (float)(-1.0 * self->priv->z) - self->priv->rxz);
+    }
+
+  
+
+  if (klass->paint)
+    (klass->paint) (self);
+
+  glPopMatrix();
+
+  if (self->priv->has_clip)
+    glDisable (GL_SCISSOR_TEST);
+}
+
+/**
+ * clutter_element_request_coords:
+ * @self: A #ClutterElement
+ * @box: A #ClutterElementBox with requested new co-ordinates.
+ *
+ * Requests new co-ordinates for the #ClutterElement ralative to any parent.
+ *
+ * This function should not be called directly by applications instead 
+ * the various position/geometry methods should be used.
+ **/
+void
+clutter_element_request_coords (ClutterElement    *self,
+                               ClutterElementBox *box)
+{
+  ClutterElementClass *klass;
+
+  klass = CLUTTER_ELEMENT_GET_CLASS (self);
+
+  /* FIXME: Kludgy see allocate co-ords */
+  if (klass->request_coords)
+    klass->request_coords(self, box);
+
+  self->priv->coords.x1 = box->x1;
+  self->priv->coords.y1 = box->y1; 
+  self->priv->coords.x2 = box->x2; 
+  self->priv->coords.y2 = box->y2; 
+
+  /* TODO: Fire a signal ? Could be usage for WM resizing stage */
+
+  if (CLUTTER_ELEMENT_IS_VISIBLE (self))
+    clutter_element_queue_redraw (self);
+}
+
+/**
+ * clutter_element_allocate_coords:
+ * @self: A #ClutterElement
+ * @box: A location to store the elements #ClutterElementBox co-ordinates
+ *
+ * Requests the allocated co-ordinates for the #ClutterElement ralative 
+ * to any parent.
+ *
+ * This function should not be called directly by applications instead 
+ * the various position/geometry methods should be used.
+ **/
+void
+clutter_element_allocate_coords (ClutterElement    *self,
+                                ClutterElementBox *box)
+{
+  ClutterElementClass *klass;
+
+  klass = CLUTTER_ELEMENT_GET_CLASS (self);
+
+  box->x1 = self->priv->coords.x1;
+  box->y1 = self->priv->coords.y1;
+  box->x2 = self->priv->coords.x2;
+  box->y2 = self->priv->coords.y2;
+
+  if (klass->request_coords)
+    {
+      /* FIXME: This is kind of a cludge - we pass out *private* 
+       *        co-ords down to any subclasses so they can modify
+       *        we then resync any changes. Needed for group class.
+       *        Need to figure out nicer way.
+      */
+      klass->allocate_coords(self, box);
+
+      self->priv->coords.x1 = box->x1;
+      self->priv->coords.y1 = box->y1; 
+      self->priv->coords.x2 = box->x2; 
+      self->priv->coords.y2 = box->y2; 
+    }
+}
+
+static void 
+clutter_element_set_property (GObject      *object, 
+                             guint         prop_id,
+                             const GValue *value, 
+                             GParamSpec   *pspec)
+{
+
+  ClutterElement        *element;
+  ClutterElementPrivate *priv;
+
+  element = CLUTTER_ELEMENT(object);
+  priv = element->priv;
+
+  switch (prop_id) 
+    {
+    case PROP_X:
+      clutter_element_set_position (element, 
+                                   g_value_get_int (value), 
+                                   clutter_element_get_y (element));
+      break;
+    case PROP_Y:
+      clutter_element_set_position (element, 
+                                   clutter_element_get_x (element),
+                                   g_value_get_int (value));
+      break;
+    case PROP_WIDTH:
+      clutter_element_set_size (element, 
+                               g_value_get_int (value),
+                               clutter_element_get_height (element));
+      break;
+    case PROP_HEIGHT:
+      clutter_element_set_size (element, 
+                               clutter_element_get_width (element),
+                               g_value_get_int (value));
+      break;
+    case PROP_OPACITY:
+      clutter_element_set_opacity (element, g_value_get_uchar (value));
+      break;
+    case PROP_NAME:
+      clutter_element_set_name (element, g_value_get_string (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void 
+clutter_element_get_property (GObject    *object, 
+                             guint       prop_id,
+                             GValue     *value, 
+                             GParamSpec *pspec)
+{
+  ClutterElement        *element;
+  ClutterElementPrivate *priv;
+
+  element = CLUTTER_ELEMENT(object);
+  priv = element->priv;
+
+  switch (prop_id) 
+    {
+    case PROP_X:
+      g_value_set_int (value, clutter_element_get_x (element));
+      break;
+    case PROP_Y:
+      g_value_set_int (value, clutter_element_get_y (element));
+      break;
+    case PROP_WIDTH:
+      g_value_set_int (value, clutter_element_get_width (element));
+      break;
+    case PROP_HEIGHT:
+      g_value_set_int (value, clutter_element_get_height (element));
+      break;
+    case PROP_OPACITY:
+      g_value_set_uchar (value, priv->opacity);
+      break;
+    case PROP_NAME:
+      g_value_set_string (value, priv->name);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void 
+clutter_element_dispose (GObject *object)
+{
+  ClutterElement *self = CLUTTER_ELEMENT(object); 
+
+  if (self->priv->parent_element)
+    {
+      clutter_group_remove (CLUTTER_GROUP(self->priv->parent_element), self);
+    }
+
+  G_OBJECT_CLASS (clutter_element_parent_class)->dispose (object);
+}
+
+static void 
+clutter_element_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (clutter_element_parent_class)->finalize (object);
+}
+
+static void
+clutter_element_class_init (ClutterElementClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->set_property = clutter_element_set_property;
+  object_class->get_property = clutter_element_get_property;
+  object_class->dispose      = clutter_element_dispose;
+  object_class->finalize     = clutter_element_finalize;
+
+  g_type_class_add_private (klass, sizeof (ClutterElementPrivate));
+
+  g_object_class_install_property
+    (object_class, PROP_X,
+     g_param_spec_int ("x",
+                      "X co-ord",
+                      "X co-ord of element",
+                      0,
+                      G_MAXINT,
+                      0,
+                      G_PARAM_READWRITE));
+
+  g_object_class_install_property
+    (object_class, PROP_Y,
+     g_param_spec_int ("y",
+                      "Y co-ord",
+                      "Y co-ord of element",
+                      0,
+                      G_MAXINT,
+                      0,
+                      G_PARAM_READWRITE));
+
+  g_object_class_install_property
+    (object_class, PROP_WIDTH,
+     g_param_spec_int ("width",
+                      "Width",
+                      "Width of element in pixels",
+                      0,
+                      G_MAXINT,
+                      0,
+                      G_PARAM_READWRITE));
+
+  g_object_class_install_property
+    (object_class, PROP_HEIGHT,
+     g_param_spec_int ("height",
+                      "Height",
+                      "Height of element in pixels",
+                      0,
+                      G_MAXINT,
+                      0,
+                      G_PARAM_READWRITE));
+  
+  g_object_class_install_property
+    (object_class, PROP_OPACITY,
+     g_param_spec_uchar ("opacity",
+                        "Opacity",
+                        "Opacity of element",
+                        0,
+                        0xff,
+                        0xff,
+                        G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+
+  /* FIXME: add - as boxed ?  
+   *  g_object_class_install_property
+   * (gobject_class, PROP_CLIP,
+   *  g_param_spec_pointer ("clip",
+   *                      "Clip",
+   *                      "Clip",
+   *                      G_PARAM_READWRITE));
+  */
+}
+
+static void
+clutter_element_init (ClutterElement *self)
+{
+  self->priv = CLUTTER_ELEMENT_GET_PRIVATE (self); 
+
+  self->priv->parent_element = NULL;
+  self->priv->has_clip       = FALSE;
+  self->priv->opacity        = 0xff;
+  self->priv->id             = __id++;
+
+  clutter_element_set_position (self, 0, 0);
+  clutter_element_set_size (self, 0, 0);
+}
+
+/**
+ * clutter_element_queue_redraw:
+ * @self: A #ClutterElement
+ *
+ * Queues up a redraw of an element and any children. The redraw occurs 
+ * once the main loop becomes idle (after the current batch of events 
+ * has been processed, roughly).
+ *
+ * Applications rarely need to call this as redraws are handled automatically
+ * by modification functions. 
+ */
+void
+clutter_element_queue_redraw (ClutterElement *self)
+{
+  ClutterMainContext *ctx = CLUTTER_CONTEXT();
+
+  clutter_threads_enter();
+
+  if (!ctx->update_idle)
+    {
+      ctx->update_idle = g_idle_add_full (-100 , /* very high priority */
+                                         redraw_update_idle, 
+                                         NULL, NULL);
+    }
+
+  clutter_threads_leave();
+}
+
+/**
+ * clutter_element_set_geometry:
+ * @self: A #ClutterElement
+ * @geom: A #ClutterGeometry
+ *
+ * Sets the elements geometry in pixels relative to any parent element.
+ */
+void
+clutter_element_set_geometry (ClutterElement  *self,
+                             ClutterGeometry *geom)
+{
+  ClutterElementBox box;
+
+  box.x1 = geom->x;
+  box.y1 = geom->y;
+  box.x2 = geom->x + geom->width;
+  box.y2 = geom->y + geom->height;
+  
+  clutter_element_request_coords (self, &box);
+}
+
+/**
+ * clutter_element_get_geometry:
+ * @self: A #ClutterElement
+ * @geom: A location to store elements #ClutterGeometry
+ *
+ * Gets the elements geometry in pixels relative to any parent element.
+ */
+void
+clutter_element_get_geometry (ClutterElement  *self,
+                             ClutterGeometry *geom)
+{
+  ClutterElementBox box;
+
+  g_return_if_fail (CLUTTER_IS_ELEMENT (self));
+  
+  clutter_element_allocate_coords (self, &box);
+
+  geom->x      = box.x1;
+  geom->y      = box.y1;
+  geom->width  = box.x2 - box.x1;
+  geom->height = box.y2 - box.y1;
+}
+
+/**
+ * clutter_element_get_coords:
+ * @self: A #ClutterElement
+ * @x1: A location to store elements left position if non NULL.
+ * @y1: A location to store elements top position if non NULL.
+ * @x2: A location to store elements right position if non NULL.
+ * @y2: A location to store elements bottom position if non NULL.
+ *
+ * Gets the elements bounding rectangle co-ordinates in pixels 
+ * relative to any parent element. 
+ */
+void
+clutter_element_get_coords (ClutterElement *self,
+                           gint           *x1,
+                           gint           *y1,
+                           gint           *x2,
+                           gint           *y2)
+{
+  ClutterElementBox box;
+
+  g_return_if_fail (CLUTTER_IS_ELEMENT (self));
+  
+  clutter_element_allocate_coords (self, &box);
+
+  if (x1) *x1 = box.x1;
+  if (y1) *y1 = box.y1;
+  if (x2) *x2 = box.x2;
+  if (y2) *y2 = box.y2;
+}
+
+/**
+ * clutter_element_set_position
+ * @self: A #ClutterElement
+ * @x: New left position of element in pixels.
+ * @y: New top position of element in pixels.
+ *
+ * Sets the elements position in pixels relative to any
+ * parent element. 
+ */
+void
+clutter_element_set_position (ClutterElement *self,
+                             gint            x,
+                             gint            y)
+{
+  ClutterElementBox box;
+
+  g_return_if_fail (CLUTTER_IS_ELEMENT (self));
+
+  clutter_element_allocate_coords (self, &box);
+
+  box.x2 += (x - box.x1);
+  box.y2 += (y - box.y1);
+
+  box.x1 = x;
+  box.y1 = y;
+
+  clutter_element_request_coords (self, &box);
+}
+
+/**
+ * clutter_element_set_size
+ * @self: A #ClutterElement
+ * @width: New width of element in pixels 
+ * @height: New height of element in pixels
+ *
+ * Sets the elements position in pixels relative to any
+ * parent element. 
+ */
+void
+clutter_element_set_size (ClutterElement *self,
+                         gint            width,
+                         gint            height)
+{
+  ClutterElementBox box;
+
+  g_return_if_fail (CLUTTER_IS_ELEMENT (self));
+
+  clutter_element_allocate_coords (self, &box);
+
+  box.x2 = box.x1 + width;
+  box.y2 = box.y1 + height;
+
+  clutter_element_request_coords (self, &box);
+}
+
+/**
+ * clutter_element_set_position
+ * @self: A #ClutterElement
+ * @x: Location to store x position if non NULL.
+ * @y: Location to store y position if non NULL.
+ *
+ * Gets the absolute position of an element in pixels relative
+ * to the stage.
+ */
+void
+clutter_element_get_abs_position (ClutterElement *self,
+                                 gint           *x,
+                                 gint           *y)
+{
+  ClutterElementBox  box;
+  ClutterElement    *parent;
+  gint               px = 0, py = 0;
+  
+  g_return_if_fail (CLUTTER_IS_ELEMENT (self));
+
+  clutter_element_allocate_coords (self, &box);
+
+  parent = self->priv->parent_element;
+
+  /* FIXME: must be nicer way to get 0,0 for stage ? */
+  if (parent && !CLUTTER_IS_STAGE (parent))
+    clutter_element_get_abs_position (parent, &px, &py);
+
+  if (x)
+    *x = px + box.x1;
+  
+  if (y)
+    *y = py + box.y1;
+}
+
+/**
+ * clutter_element_get_width
+ * @self: A #ClutterElement
+ *
+ * Retrieves the elements width.
+ *
+ * Return value: The element width in pixels
+ **/
+guint
+clutter_element_get_width (ClutterElement *self)
+{
+  ClutterElementBox box;
+
+  g_return_val_if_fail (CLUTTER_IS_ELEMENT (self), 0);
+  
+  clutter_element_allocate_coords (self, &box);
+
+  return box.x2 - box.x1;
+}
+
+/**
+ * clutter_element_get_height
+ * @self: A #ClutterElement
+ *
+ * Retrieves the elements height.
+ * 
+ * Return value: The element height in pixels
+ **/
+guint
+clutter_element_get_height (ClutterElement *self)
+{
+  ClutterElementBox box;
+
+  g_return_val_if_fail (CLUTTER_IS_ELEMENT (self), 0);
+  
+  clutter_element_allocate_coords (self, &box);
+
+  return box.y2 - box.y1;
+}
+
+/**
+ * clutter_element_get_x
+ * @self: A #ClutterElement
+ *
+ * Retrieves the elements x position relative to any parent.
+ *
+ * Return value: The element x position in pixels
+ **/
+gint
+clutter_element_get_x (ClutterElement *self)
+{
+  ClutterElementBox box;
+  
+  g_return_val_if_fail (CLUTTER_IS_ELEMENT (self), 0);
+
+  clutter_element_allocate_coords (self, &box);
+
+  return box.x1;
+}
+
+/**
+ * clutter_element_get_y:
+ * @self: A #ClutterElement
+ *
+ * Retrieves the elements y position relative to any parent.
+ *
+ * Return value: The element y position in pixels
+ **/
+gint
+clutter_element_get_y (ClutterElement *self)
+{
+  ClutterElementBox box;
+
+  g_return_val_if_fail (CLUTTER_IS_ELEMENT (self), 0);
+
+  clutter_element_allocate_coords (self, &box);
+
+  return box.y1;
+}
+
+/**
+ * clutter_element_set_opacity:
+ * @self: A #ClutterElement
+ * @opacity: New opacity value for element.
+ *
+ * Sets the elements opacity, with zero being completely transparent.
+ */
+void
+clutter_element_set_opacity (ClutterElement *self,
+                            guint8          opacity)
+{
+  g_return_if_fail (CLUTTER_IS_ELEMENT (self));
+  
+  self->priv->opacity = opacity;
+
+  if (CLUTTER_ELEMENT_IS_VISIBLE (self))
+    clutter_element_queue_redraw (self);
+}
+
+/**
+ * clutter_element_get_opacity:
+ * @self: A #ClutterElement
+ *
+ * Retrieves the elements opacity.
+ *
+ * Return value: The element opacity value.
+ */
+guint8
+clutter_element_get_opacity (ClutterElement *self)
+{
+  ClutterElement *parent;
+  
+  g_return_val_if_fail (CLUTTER_IS_ELEMENT (self), 0);
+
+  parent = self->priv->parent_element;
+  
+  /* FIXME: need to factor in the actual elements opacity with parents */
+  if (parent && clutter_element_get_opacity (parent) != 0xff)
+    return clutter_element_get_opacity(parent);
+
+  return self->priv->opacity;
+}
+
+/**
+ * clutter_element_set_name:
+ * @self: A #ClutterElement
+ * @id: Textual tag to apply to element
+ *
+ * Sets a textual tag to the element.
+ */
+void
+clutter_element_set_name (ClutterElement *self,
+                         const gchar    *name)
+{
+  g_return_if_fail (CLUTTER_IS_ELEMENT (self));
+  
+  if (name || name[0] != '\0')
+    {
+      g_free (self->priv->name);
+      
+      self->priv->name = g_strdup(name);
+    }
+}
+
+/**
+ * clutter_element_get_name:
+ * @self: A #ClutterElement
+ *
+ * Return value: pointer to textual tag for the element.  The
+ *   returned string is owned by the element and should not
+ *   be modified or freed.
+ */
+const gchar*
+clutter_element_get_name (ClutterElement *self)
+{
+  g_return_val_if_fail (CLUTTER_IS_ELEMENT (self), NULL);
+  
+  return self->priv->name;
+}
+
+/**
+ * clutter_element_get_id:
+ * @self: A #ClutterElement
+ *
+ * FIXME
+ * 
+ * Return value: Globally unique value for object instance.
+ */
+guint32
+clutter_element_get_id (ClutterElement *self)
+{
+  g_return_val_if_fail (CLUTTER_IS_ELEMENT (self), 0);
+  
+  return self->priv->id;
+}
+
+static void
+depth_sorter_foreach (ClutterElement *element, gpointer user_data)
+{
+  ClutterElement *element_to_sort = CLUTTER_ELEMENT(user_data);
+
+  if (element_to_sort->priv->z > element->priv->z) 
+    clutter_element_raise (element_to_sort, element);
+}
+
+/**
+ * clutter_element_set_depth:
+ * @self: a #ClutterElement
+ * @depth: FIXME
+ *
+ * FIXME
+ */
+void
+clutter_element_set_depth (ClutterElement *self,
+                           gint            depth)
+{
+  /* Sets Z value. Note probably need to sort via stacking order
+   * so rendering correct with alpha values. 
+  */
+  self->priv->z = depth;
+
+  if (self->priv->parent_element)
+    {
+      /* Fix stacking ordering so rendering correct */
+
+      clutter_element_lower_bottom (self);
+
+      clutter_group_foreach (CLUTTER_GROUP(self->priv->parent_element),
+                            depth_sorter_foreach,
+                            (gpointer)self);
+    }
+}
+
+/**
+ * clutter_element_get_depth:
+ * @self: a #ClutterElement
+ *
+ * Retrieves the depth of @self.
+ *
+ * Return value: the depth of a #ClutterElement
+ */
+gint
+clutter_element_get_depth (ClutterElement *self)
+{
+  g_return_val_if_fail (CLUTTER_IS_ELEMENT (self), -1);
+  
+  return self->priv->z;
+}
+
+/**
+ * clutter_element_rotate_z:
+ * @self: A #ClutterElement
+ * @angle: Angle of rotation
+ * @x:     X co-ord to rotate element around ( relative to element position )
+ * @y:     Y co-ord to rotate element around ( relative to element position )
+ *
+ * Rotates element around the Z axis.
+ */
+void
+clutter_element_rotate_z (ClutterElement          *self,
+                         gfloat                   angle,
+                         gint                     x,
+                         gint                     y)
+{
+  g_return_if_fail (CLUTTER_IS_ELEMENT (self));
+
+  self->priv->rzang = angle;
+  self->priv->rzx   = x;
+  self->priv->rzy   = y;
+
+  if (CLUTTER_ELEMENT_IS_VISIBLE (self))
+    clutter_element_queue_redraw (self);
+}
+
+/**
+ * clutter_element_rotate_x:
+ * @self:  A #ClutterElement
+ * @angle: Angle of rotation
+ * @y:     Y co-ord to rotate element around ( relative to element position )
+ * @z:     Z co-ord to rotate element around ( relative to element position )
+ *
+ * Rotates element around the X axis.
+ */
+void
+clutter_element_rotate_x (ClutterElement          *self,
+                         gfloat                   angle,
+                         gint                     y,
+                         gint                     z)
+{
+  g_return_if_fail (CLUTTER_IS_ELEMENT (self));
+  
+  self->priv->rxang = angle;
+  self->priv->rxy   = y;
+  self->priv->rxz   = z;
+
+  if (CLUTTER_ELEMENT_IS_VISIBLE (self))
+    clutter_element_queue_redraw (self);
+}
+
+/**
+ * clutter_element_rotate_y:
+ * @self:  A #ClutterElement
+ * @angle: Angle of rotation
+ * @x:     X co-ord to rotate element around ( relative to element position )
+ * @z:     Z co-ord to rotate element around ( relative to element position )
+ *
+ * Rotates element around the X axis.
+ */
+void
+clutter_element_rotate_y (ClutterElement          *self,
+                         gfloat                   angle,
+                         gint                     x,
+                         gint                     z)
+{
+  g_return_if_fail (CLUTTER_IS_ELEMENT (self));
+  
+  self->priv->ryang = angle;
+  self->priv->ryx   = x;
+  self->priv->ryz   = z;
+
+  if (CLUTTER_ELEMENT_IS_VISIBLE (self))
+    clutter_element_queue_redraw (self);
+}
+
+/**
+ * clutter_element_mirror:
+ * @self: a #ClutterElement
+ * @transform: a #ClutterElementTransform
+ *
+ * FIXME
+ */
+void
+clutter_element_mirror (ClutterElement          *self,
+                       ClutterElementTransform  transform)
+{
+  g_return_if_fail (CLUTTER_IS_ELEMENT (self));
+  
+  self->priv->mirror_transform = transform;
+}
+
+/**
+ * clutter_element_set_clip:
+ * @self: A #ClutterElement
+ * @xoff: FIXME
+ * @yoff: FIXME
+ * @width: FIXME
+ * @height: FIXME
+ *
+ * Sets clip area for @self.
+ */
+void
+clutter_element_set_clip (ClutterElement *self,
+                         gint            xoff, 
+                         gint            yoff, 
+                         gint            width, 
+                         gint            height)
+{
+  ClutterGeometry *clip;
+  
+  g_return_if_fail (CLUTTER_IS_ELEMENT (self));
+  
+  clip = &self->priv->clip;
+  
+  clip->x      = xoff;
+  clip->y      = yoff;
+  clip->width  = width;
+  clip->height = height;
+
+  self->priv->has_clip = TRUE;
+} 
+
+/**
+ * clutter_element_remove_clip
+ * @self: A #ClutterElement
+ *
+ * Removes clip area from @self.
+ */
+void
+clutter_element_remove_clip (ClutterElement *self)
+{
+  g_return_if_fail (CLUTTER_IS_ELEMENT (self));
+  
+  self->priv->has_clip = FALSE;
+} 
+
+/**
+ * clutter_element_set_parent:
+ * @self: A #ClutterElement
+ * @parent: A new #ClutterElement parent or NULL
+ *
+ * This function should not be used by applications.
+ */
+void
+clutter_element_set_parent (ClutterElement *self,
+                           ClutterElement *parent)
+{
+  g_return_if_fail (CLUTTER_IS_ELEMENT (self));
+  g_return_if_fail ((parent == NULL) || CLUTTER_IS_ELEMENT (parent));
+
+  if (self->priv->parent_element == parent)
+    return;
+  
+  if (self->priv->parent_element && self->priv->parent_element != parent)
+    g_object_unref (self->priv->parent_element);
+  
+  self->priv->parent_element = parent;
+
+  if (self->priv->parent_element)
+    g_object_ref (self->priv->parent_element);
+}
+
+/**
+ * clutter_element_get_parent:
+ * @self: A #ClutterElement
+ *
+ * Return Value: The #ClutterElement parent or NULL
+ */
+ClutterElement*
+clutter_element_get_parent (ClutterElement *self)
+{
+  return self->priv->parent_element;
+}
+
+/**
+ * clutter_element_raise:
+ * @self: A #ClutterElement
+ * @below: A #ClutterElement to raise above.
+ *
+ * Both elements must have the same parent.
+ */
+void
+clutter_element_raise (ClutterElement *self, ClutterElement *below)
+{
+  g_return_if_fail (clutter_element_get_parent (self) != NULL);
+  g_return_if_fail 
+    (clutter_element_get_parent (self) != clutter_element_get_parent (below));
+
+  clutter_group_raise (CLUTTER_GROUP(clutter_element_get_parent (self)),
+                    self,
+                    below);
+}
+
+/**
+ * clutter_element_lower:
+ * @self: A #ClutterElement
+ * @above: A #ClutterElement to lower below
+ *
+ * Both elements must have the same parent.
+ */
+void
+clutter_element_lower (ClutterElement *self, ClutterElement *above)
+{
+  g_return_if_fail (CLUTTER_IS_ELEMENT(self));
+  g_return_if_fail (clutter_element_get_parent (self) != NULL);
+
+  /* FIXME: fix Z ordering ? */
+  if (above != NULL)
+    {
+      g_return_if_fail 
+       (clutter_element_get_parent (self) 
+          != clutter_element_get_parent (above));
+    }
+
+  /* FIXME: group_lower should be an overidable method ? */
+  clutter_group_lower (CLUTTER_GROUP(clutter_element_get_parent (self)),
+                      self,
+                      above);
+}
+
+/**
+ * clutter_element_rise_top:
+ * @self: A #ClutterElement
+ *
+ * Rises @self to the top.
+ */
+void
+clutter_element_raise_top (ClutterElement *self)
+{
+  clutter_element_raise (self, NULL);
+}
+
+/**
+ * clutter_element_lower_bottom:
+ * @self: A #ClutterElement
+ *
+ * Lowers @self to the bottom.
+ */
+void
+clutter_element_lower_bottom (ClutterElement *self)
+{
+  clutter_element_lower (self, NULL);
+}
+
+/*
+ * ClutterGemoetry
+ */
+
+static ClutterGeometry*
+clutter_geometry_copy (const ClutterGeometry *geometry)
+{
+  ClutterGeometry *result = g_new (ClutterGeometry, 1);
+
+  *result = *geometry;
+
+  return result;
+}
+
+GType
+clutter_geometry_get_type (void)
+{
+  static GType our_type = 0;
+
+  if (our_type == 0)
+    our_type = g_boxed_type_register_static (
+              g_intern_static_string ("ClutterGeometry"),
+             (GBoxedCopyFunc) clutter_geometry_copy,
+             (GBoxedFreeFunc) g_free);
+
+  return our_type;
+}
+
+/*
+ * ClutterElementBox
+ */
+static ClutterElementBox *
+clutter_element_box_copy (const ClutterElementBox *box)
+{
+  ClutterElementBox *result = g_new (ClutterElementBox, 1);
+
+  *result = *box;
+
+  return result;
+}
+
+GType
+clutter_element_box_get_type (void)
+{
+  static GType our_type = 0;
+
+  if (our_type == 0)
+    our_type = g_boxed_type_register_static (
+              g_intern_static_string ("ClutterElementBox"),
+             (GBoxedCopyFunc) clutter_element_box_copy,
+             (GBoxedFreeFunc) g_free);
+  return our_type;
+}
diff --git a/clutter/clutter-element.h b/clutter/clutter-element.h
new file mode 100644 (file)
index 0000000..355e84d
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _HAVE_CLUTTER_ELEMENT_H
+#define _HAVE_CLUTTER_ELEMENT_H
+
+/* clutter-element.h */
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_GEOMETRY (clutter_geometry_get_type ())
+#define CLUTTER_TYPE_ELEMENT_BOX (clutter_element_box_get_type ())
+
+#define CLUTTER_TYPE_ELEMENT clutter_element_get_type()
+
+#define CLUTTER_ELEMENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ELEMENT, ClutterElement))
+#define CLUTTER_ELEMENT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ELEMENT, ClutterElementClass))
+#define CLUTTER_IS_ELEMENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ELEMENT))
+#define CLUTTER_IS_ELEMENT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ELEMENT))
+#define CLUTTER_ELEMENT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ELEMENT, ClutterElementClass))
+
+#define CLUTTER_ELEMENT_SET_FLAGS(e,f) ((e)->flags |= (f))  
+#define CLUTTER_ELEMENT_UNSET_FLAGS(e,f) ((e)->flags &= ~(f))  
+
+#define CLUTTER_ELEMENT_IS_MAPPED(e) ((e)->flags & CLUTTER_ELEMENT_MAPPED)  
+#define CLUTTER_ELEMENT_IS_REALIZED(e) ((e)->flags & CLUTTER_ELEMENT_REALIZED)
+#define CLUTTER_ELEMENT_IS_VISIBLE(e) \
+ (CLUTTER_ELEMENT_IS_MAPPED(e) && CLUTTER_ELEMENT_IS_REALIZED(e))  
+
+typedef struct _ClutterElement         ClutterElement;
+typedef struct _ClutterElementClass    ClutterElementClass;
+typedef struct _ClutterElementBox      ClutterElementBox;
+typedef struct _ClutterElementPrivate  ClutterElementPrivate;
+typedef struct _ClutterGeometry        ClutterGeometry;
+
+typedef void (*ClutterCallback) (ClutterElement *element, gpointer data);
+
+struct _ClutterGeometry
+{ 
+  gint x;
+  gint y;
+  guint width;
+  guint height;
+};
+
+GType clutter_geometry_get_type (void) G_GNUC_CONST;
+
+typedef enum 
+{
+  CLUTTER_ELEMENT_MIRROR_X = 1 << 1,
+  CLUTTER_ELEMENT_MIRROR_Y = 1 << 2
+} ClutterElementTransform;
+
+typedef enum
+{
+  CLUTTER_ELEMENT_MAPPED   = 1 << 1,
+  CLUTTER_ELEMENT_REALIZED = 1 << 2
+} ClutterElementFlags;
+
+struct _ClutterElementBox { gint x1, y1, x2, y2; };
+
+GType clutter_element_box_get_type (void) G_GNUC_CONST;
+
+struct _ClutterElement
+{
+  /*< public >*/
+  GObject                 parent;
+  guint32                 flags;
+
+  /*< private >*/
+  ClutterElementPrivate  *priv;
+};
+
+struct _ClutterElementClass
+{
+  GObjectClass parent_class;
+
+  void (* show)                (ClutterElement        *element);
+  void (* hide)                (ClutterElement        *element);
+  void (* realize)             (ClutterElement        *element);
+  void (* unrealize)           (ClutterElement        *element);
+  void (* paint)               (ClutterElement        *element);
+  void (* request_coords)      (ClutterElement        *element,
+                               ClutterElementBox     *box);
+  void (* allocate_coords)     (ClutterElement        *element,
+                               ClutterElementBox     *box);
+  void (* set_depth)           (ClutterElement        *element,
+                               gint                   depth);
+  gint (* get_depth)           (ClutterElement        *element);
+
+  /* to go ? */
+  void (* show_all)            (ClutterElement        *element);
+  void (* hide_all)            (ClutterElement        *element);
+  void (* queue_redraw)        (ClutterElement        *element);
+};
+
+GType clutter_element_get_type (void);
+
+void
+clutter_element_show (ClutterElement *self);
+
+void
+clutter_element_hide (ClutterElement *self);
+
+void
+clutter_element_realize (ClutterElement *self);
+
+void
+clutter_element_unrealize (ClutterElement *self);
+
+void
+clutter_element_paint (ClutterElement *self);
+
+void
+clutter_element_queue_redraw (ClutterElement  *self);
+
+void
+clutter_element_request_coords (ClutterElement    *self,
+                               ClutterElementBox *box);
+
+void
+clutter_element_allocate_coords (ClutterElement    *self,
+                                ClutterElementBox *box);
+
+void
+clutter_element_set_geometry (ClutterElement  *self,
+                             ClutterGeometry *geom);
+
+void
+clutter_element_get_geometry (ClutterElement  *self,
+                             ClutterGeometry *geom);
+
+void
+clutter_element_get_coords (ClutterElement *self,
+                           gint           *x1,
+                           gint           *y1,
+                           gint           *x2,
+                           gint           *y2);
+
+void
+clutter_element_set_position (ClutterElement *self,
+                             gint            x,
+                             gint            y);
+
+void
+clutter_element_set_size (ClutterElement *self,
+                         gint            width,
+                         gint            height);
+
+void
+clutter_element_get_abs_position (ClutterElement *self,
+                                 gint           *x,
+                                 gint           *y);
+
+guint
+clutter_element_get_width (ClutterElement *self);
+
+guint
+clutter_element_get_height (ClutterElement *self);
+
+gint
+clutter_element_get_x (ClutterElement *self);
+
+gint
+clutter_element_get_y (ClutterElement *self);
+
+void
+clutter_element_rotate_z (ClutterElement          *self,
+                         gfloat                   angle,
+                         gint                     x,
+                         gint                     y);
+
+void
+clutter_element_rotate_x (ClutterElement          *self,
+                         gfloat                   angle,
+                         gint                     y,
+                         gint                     z);
+
+void
+clutter_element_rotate_y (ClutterElement          *self,
+                         gfloat                   angle,
+                         gint                     x,
+                         gint                     z);
+
+void
+clutter_element_set_opacity (ClutterElement *self,
+                            guint8          opacity);
+
+guint8
+clutter_element_get_opacity (ClutterElement *self);
+
+void
+clutter_element_set_name (ClutterElement *self,
+                         const gchar    *id);
+
+const gchar*
+clutter_element_get_name (ClutterElement *self);
+
+guint32
+clutter_element_get_id (ClutterElement *self);
+
+void
+clutter_element_set_clip (ClutterElement *self,
+                         gint            xoff, 
+                         gint            yoff, 
+                         gint            width, 
+                         gint            height);
+
+void
+clutter_element_remove_clip (ClutterElement *self);
+
+void
+clutter_element_set_parent (ClutterElement *self, ClutterElement *parent);
+
+ClutterElement*
+clutter_element_get_parent (ClutterElement *self);
+
+void
+clutter_element_raise (ClutterElement *self, ClutterElement *below);
+
+void
+clutter_element_lower (ClutterElement *self, ClutterElement *above);
+
+void
+clutter_element_raise_top (ClutterElement *self);
+
+void
+clutter_element_lower_bottom (ClutterElement *self);
+
+G_END_DECLS
+
+#endif
diff --git a/clutter/clutter-event.c b/clutter/clutter-event.c
new file mode 100644 (file)
index 0000000..e552630
--- /dev/null
@@ -0,0 +1,990 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "clutter-event.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+ClutterEventType
+clutter_event_type (ClutterEvent *event)
+{
+  return event->type;
+}
+
+guint32
+clutter_button_event_time (ClutterButtonEvent *buttev)
+{
+  return buttev->time;
+}
+
+gint
+clutter_button_event_x (ClutterButtonEvent *buttev)
+{
+  return buttev->x;
+}
+
+gint
+clutter_button_event_y (ClutterButtonEvent *buttev)
+{
+  return buttev->y;
+}
+
+guint32
+clutter_button_event_state (ClutterButtonEvent *buttev)
+{
+  return buttev->modifier_state;
+}
+
+guint32
+clutter_button_event_button (ClutterButtonEvent *buttev)
+{
+  return buttev->button;
+}
+
+/* Motion */
+
+guint32
+clutter_motion_event_time (ClutterMotionEvent *motionev)
+{
+  return motionev->time;
+}
+
+gint
+clutter_motion_event_x (ClutterMotionEvent *motionev)
+{
+  return motionev->x;
+}
+
+gint
+clutter_motion_event_y (ClutterMotionEvent *motionev)
+{
+  return motionev->y;
+}
+
+guint32
+clutter_motion_event_state (ClutterMotionEvent *motionev)
+{
+  return motionev->modifier_state;
+}
+
+/* keys */
+
+guint32
+clutter_key_event_time (ClutterKeyEvent *keyev)
+{
+  return keyev->time;
+}
+
+guint
+clutter_key_event_state (ClutterKeyEvent *keyev)
+{
+  return keyev->modifier_state;
+}
+
+guint
+clutter_key_event_symbol (ClutterKeyEvent *keyev)
+{
+  return keyev->keyval;
+}
+
+guint16
+clutter_key_event_code (ClutterKeyEvent *keyev)
+{
+  return keyev->hardware_keycode;
+}
+
+guint32
+clutter_key_event_unicode (ClutterKeyEvent *keyev)
+{
+  return clutter_keysym_to_unicode (keyev->keyval);
+}
+
+/* Code below from GDK, which contains following comment; 
+ *
+ * Thanks to Markus G. Kuhn <mkuhn@acm.org> for the ksysym<->Unicode
+ * mapping functions, from the xterm sources.
+ */
+static struct {
+  unsigned short keysym;
+  unsigned short ucs;
+} clutter_keysym_to_unicode_tab[] = {
+  { 0x01a1, 0x0104 }, /*                     Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */
+  { 0x01a2, 0x02d8 }, /*                       breve ˘ BREVE */
+  { 0x01a3, 0x0141 }, /*                     Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE */
+  { 0x01a5, 0x013d }, /*                      Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */
+  { 0x01a6, 0x015a }, /*                      Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE */
+  { 0x01a9, 0x0160 }, /*                      Scaron Š LATIN CAPITAL LETTER S WITH CARON */
+  { 0x01aa, 0x015e }, /*                    Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA */
+  { 0x01ab, 0x0164 }, /*                      Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */
+  { 0x01ac, 0x0179 }, /*                      Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */
+  { 0x01ae, 0x017d }, /*                      Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */
+  { 0x01af, 0x017b }, /*                   Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE */
+  { 0x01b1, 0x0105 }, /*                     aogonek ą LATIN SMALL LETTER A WITH OGONEK */
+  { 0x01b2, 0x02db }, /*                      ogonek ˛ OGONEK */
+  { 0x01b3, 0x0142 }, /*                     lstroke ł LATIN SMALL LETTER L WITH STROKE */
+  { 0x01b5, 0x013e }, /*                      lcaron ľ LATIN SMALL LETTER L WITH CARON */
+  { 0x01b6, 0x015b }, /*                      sacute ś LATIN SMALL LETTER S WITH ACUTE */
+  { 0x01b7, 0x02c7 }, /*                       caron ˇ CARON */
+  { 0x01b9, 0x0161 }, /*                      scaron š LATIN SMALL LETTER S WITH CARON */
+  { 0x01ba, 0x015f }, /*                    scedilla ş LATIN SMALL LETTER S WITH CEDILLA */
+  { 0x01bb, 0x0165 }, /*                      tcaron ť LATIN SMALL LETTER T WITH CARON */
+  { 0x01bc, 0x017a }, /*                      zacute ź LATIN SMALL LETTER Z WITH ACUTE */
+  { 0x01bd, 0x02dd }, /*                 doubleacute ˝ DOUBLE ACUTE ACCENT */
+  { 0x01be, 0x017e }, /*                      zcaron ž LATIN SMALL LETTER Z WITH CARON */
+  { 0x01bf, 0x017c }, /*                   zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */
+  { 0x01c0, 0x0154 }, /*                      Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE */
+  { 0x01c3, 0x0102 }, /*                      Abreve Ă LATIN CAPITAL LETTER A WITH BREVE */
+  { 0x01c5, 0x0139 }, /*                      Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */
+  { 0x01c6, 0x0106 }, /*                      Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */
+  { 0x01c8, 0x010c }, /*                      Ccaron Č LATIN CAPITAL LETTER C WITH CARON */
+  { 0x01ca, 0x0118 }, /*                     Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */
+  { 0x01cc, 0x011a }, /*                      Ecaron Ě LATIN CAPITAL LETTER E WITH CARON */
+  { 0x01cf, 0x010e }, /*                      Dcaron Ď LATIN CAPITAL LETTER D WITH CARON */
+  { 0x01d0, 0x0110 }, /*                     Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE */
+  { 0x01d1, 0x0143 }, /*                      Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */
+  { 0x01d2, 0x0147 }, /*                      Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */
+  { 0x01d5, 0x0150 }, /*                Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
+  { 0x01d8, 0x0158 }, /*                      Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */
+  { 0x01d9, 0x016e }, /*                       Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE */
+  { 0x01db, 0x0170 }, /*                Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
+  { 0x01de, 0x0162 }, /*                    Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */
+  { 0x01e0, 0x0155 }, /*                      racute ŕ LATIN SMALL LETTER R WITH ACUTE */
+  { 0x01e3, 0x0103 }, /*                      abreve ă LATIN SMALL LETTER A WITH BREVE */
+  { 0x01e5, 0x013a }, /*                      lacute ĺ LATIN SMALL LETTER L WITH ACUTE */
+  { 0x01e6, 0x0107 }, /*                      cacute ć LATIN SMALL LETTER C WITH ACUTE */
+  { 0x01e8, 0x010d }, /*                      ccaron č LATIN SMALL LETTER C WITH CARON */
+  { 0x01ea, 0x0119 }, /*                     eogonek ę LATIN SMALL LETTER E WITH OGONEK */
+  { 0x01ec, 0x011b }, /*                      ecaron ě LATIN SMALL LETTER E WITH CARON */
+  { 0x01ef, 0x010f }, /*                      dcaron ď LATIN SMALL LETTER D WITH CARON */
+  { 0x01f0, 0x0111 }, /*                     dstroke đ LATIN SMALL LETTER D WITH STROKE */
+  { 0x01f1, 0x0144 }, /*                      nacute ń LATIN SMALL LETTER N WITH ACUTE */
+  { 0x01f2, 0x0148 }, /*                      ncaron ň LATIN SMALL LETTER N WITH CARON */
+  { 0x01f5, 0x0151 }, /*                odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE */
+  { 0x01f8, 0x0159 }, /*                      rcaron ř LATIN SMALL LETTER R WITH CARON */
+  { 0x01f9, 0x016f }, /*                       uring ů LATIN SMALL LETTER U WITH RING ABOVE */
+  { 0x01fb, 0x0171 }, /*                udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */
+  { 0x01fe, 0x0163 }, /*                    tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */
+  { 0x01ff, 0x02d9 }, /*                    abovedot ˙ DOT ABOVE */
+  { 0x02a1, 0x0126 }, /*                     Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */
+  { 0x02a6, 0x0124 }, /*                 Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
+  { 0x02a9, 0x0130 }, /*                   Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */
+  { 0x02ab, 0x011e }, /*                      Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE */
+  { 0x02ac, 0x0134 }, /*                 Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
+  { 0x02b1, 0x0127 }, /*                     hstroke ħ LATIN SMALL LETTER H WITH STROKE */
+  { 0x02b6, 0x0125 }, /*                 hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */
+  { 0x02b9, 0x0131 }, /*                    idotless ı LATIN SMALL LETTER DOTLESS I */
+  { 0x02bb, 0x011f }, /*                      gbreve ğ LATIN SMALL LETTER G WITH BREVE */
+  { 0x02bc, 0x0135 }, /*                 jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */
+  { 0x02c5, 0x010a }, /*                   Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE */
+  { 0x02c6, 0x0108 }, /*                 Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
+  { 0x02d5, 0x0120 }, /*                   Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE */
+  { 0x02d8, 0x011c }, /*                 Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
+  { 0x02dd, 0x016c }, /*                      Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */
+  { 0x02de, 0x015c }, /*                 Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
+  { 0x02e5, 0x010b }, /*                   cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE */
+  { 0x02e6, 0x0109 }, /*                 ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */
+  { 0x02f5, 0x0121 }, /*                   gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE */
+  { 0x02f8, 0x011d }, /*                 gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX */
+  { 0x02fd, 0x016d }, /*                      ubreve ŭ LATIN SMALL LETTER U WITH BREVE */
+  { 0x02fe, 0x015d }, /*                 scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX */
+  { 0x03a2, 0x0138 }, /*                         kra ĸ LATIN SMALL LETTER KRA */
+  { 0x03a3, 0x0156 }, /*                    Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA */
+  { 0x03a5, 0x0128 }, /*                      Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */
+  { 0x03a6, 0x013b }, /*                    Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA */
+  { 0x03aa, 0x0112 }, /*                     Emacron Ē LATIN CAPITAL LETTER E WITH MACRON */
+  { 0x03ab, 0x0122 }, /*                    Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */
+  { 0x03ac, 0x0166 }, /*                      Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */
+  { 0x03b3, 0x0157 }, /*                    rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA */
+  { 0x03b5, 0x0129 }, /*                      itilde ĩ LATIN SMALL LETTER I WITH TILDE */
+  { 0x03b6, 0x013c }, /*                    lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */
+  { 0x03ba, 0x0113 }, /*                     emacron ē LATIN SMALL LETTER E WITH MACRON */
+  { 0x03bb, 0x0123 }, /*                    gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */
+  { 0x03bc, 0x0167 }, /*                      tslash ŧ LATIN SMALL LETTER T WITH STROKE */
+  { 0x03bd, 0x014a }, /*                         ENG Ŋ LATIN CAPITAL LETTER ENG */
+  { 0x03bf, 0x014b }, /*                         eng ŋ LATIN SMALL LETTER ENG */
+  { 0x03c0, 0x0100 }, /*                     Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */
+  { 0x03c7, 0x012e }, /*                     Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK */
+  { 0x03cc, 0x0116 }, /*                   Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE */
+  { 0x03cf, 0x012a }, /*                     Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */
+  { 0x03d1, 0x0145 }, /*                    Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA */
+  { 0x03d2, 0x014c }, /*                     Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */
+  { 0x03d3, 0x0136 }, /*                    Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */
+  { 0x03d9, 0x0172 }, /*                     Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */
+  { 0x03dd, 0x0168 }, /*                      Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */
+  { 0x03de, 0x016a }, /*                     Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */
+  { 0x03e0, 0x0101 }, /*                     amacron ā LATIN SMALL LETTER A WITH MACRON */
+  { 0x03e7, 0x012f }, /*                     iogonek į LATIN SMALL LETTER I WITH OGONEK */
+  { 0x03ec, 0x0117 }, /*                   eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE */
+  { 0x03ef, 0x012b }, /*                     imacron ī LATIN SMALL LETTER I WITH MACRON */
+  { 0x03f1, 0x0146 }, /*                    ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */
+  { 0x03f2, 0x014d }, /*                     omacron ō LATIN SMALL LETTER O WITH MACRON */
+  { 0x03f3, 0x0137 }, /*                    kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA */
+  { 0x03f9, 0x0173 }, /*                     uogonek ų LATIN SMALL LETTER U WITH OGONEK */
+  { 0x03fd, 0x0169 }, /*                      utilde ũ LATIN SMALL LETTER U WITH TILDE */
+  { 0x03fe, 0x016b }, /*                     umacron ū LATIN SMALL LETTER U WITH MACRON */
+  { 0x047e, 0x203e }, /*                    overline ‾ OVERLINE */
+  { 0x04a1, 0x3002 }, /*               kana_fullstop 。 IDEOGRAPHIC FULL STOP */
+  { 0x04a2, 0x300c }, /*         kana_openingbracket 「 LEFT CORNER BRACKET */
+  { 0x04a3, 0x300d }, /*         kana_closingbracket 」 RIGHT CORNER BRACKET */
+  { 0x04a4, 0x3001 }, /*                  kana_comma 、 IDEOGRAPHIC COMMA */
+  { 0x04a5, 0x30fb }, /*            kana_conjunctive ・ KATAKANA MIDDLE DOT */
+  { 0x04a6, 0x30f2 }, /*                     kana_WO ヲ KATAKANA LETTER WO */
+  { 0x04a7, 0x30a1 }, /*                      kana_a ァ KATAKANA LETTER SMALL A */
+  { 0x04a8, 0x30a3 }, /*                      kana_i ィ KATAKANA LETTER SMALL I */
+  { 0x04a9, 0x30a5 }, /*                      kana_u ゥ KATAKANA LETTER SMALL U */
+  { 0x04aa, 0x30a7 }, /*                      kana_e ェ KATAKANA LETTER SMALL E */
+  { 0x04ab, 0x30a9 }, /*                      kana_o ォ KATAKANA LETTER SMALL O */
+  { 0x04ac, 0x30e3 }, /*                     kana_ya ャ KATAKANA LETTER SMALL YA */
+  { 0x04ad, 0x30e5 }, /*                     kana_yu ュ KATAKANA LETTER SMALL YU */
+  { 0x04ae, 0x30e7 }, /*                     kana_yo ョ KATAKANA LETTER SMALL YO */
+  { 0x04af, 0x30c3 }, /*                    kana_tsu ッ KATAKANA LETTER SMALL TU */
+  { 0x04b0, 0x30fc }, /*              prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */
+  { 0x04b1, 0x30a2 }, /*                      kana_A ア KATAKANA LETTER A */
+  { 0x04b2, 0x30a4 }, /*                      kana_I イ KATAKANA LETTER I */
+  { 0x04b3, 0x30a6 }, /*                      kana_U ウ KATAKANA LETTER U */
+  { 0x04b4, 0x30a8 }, /*                      kana_E エ KATAKANA LETTER E */
+  { 0x04b5, 0x30aa }, /*                      kana_O オ KATAKANA LETTER O */
+  { 0x04b6, 0x30ab }, /*                     kana_KA カ KATAKANA LETTER KA */
+  { 0x04b7, 0x30ad }, /*                     kana_KI キ KATAKANA LETTER KI */
+  { 0x04b8, 0x30af }, /*                     kana_KU ク KATAKANA LETTER KU */
+  { 0x04b9, 0x30b1 }, /*                     kana_KE ケ KATAKANA LETTER KE */
+  { 0x04ba, 0x30b3 }, /*                     kana_KO コ KATAKANA LETTER KO */
+  { 0x04bb, 0x30b5 }, /*                     kana_SA サ KATAKANA LETTER SA */
+  { 0x04bc, 0x30b7 }, /*                    kana_SHI シ KATAKANA LETTER SI */
+  { 0x04bd, 0x30b9 }, /*                     kana_SU ス KATAKANA LETTER SU */
+  { 0x04be, 0x30bb }, /*                     kana_SE セ KATAKANA LETTER SE */
+  { 0x04bf, 0x30bd }, /*                     kana_SO ソ KATAKANA LETTER SO */
+  { 0x04c0, 0x30bf }, /*                     kana_TA タ KATAKANA LETTER TA */
+  { 0x04c1, 0x30c1 }, /*                    kana_CHI チ KATAKANA LETTER TI */
+  { 0x04c2, 0x30c4 }, /*                    kana_TSU ツ KATAKANA LETTER TU */
+  { 0x04c3, 0x30c6 }, /*                     kana_TE テ KATAKANA LETTER TE */
+  { 0x04c4, 0x30c8 }, /*                     kana_TO ト KATAKANA LETTER TO */
+  { 0x04c5, 0x30ca }, /*                     kana_NA ナ KATAKANA LETTER NA */
+  { 0x04c6, 0x30cb }, /*                     kana_NI ニ KATAKANA LETTER NI */
+  { 0x04c7, 0x30cc }, /*                     kana_NU ヌ KATAKANA LETTER NU */
+  { 0x04c8, 0x30cd }, /*                     kana_NE ネ KATAKANA LETTER NE */
+  { 0x04c9, 0x30ce }, /*                     kana_NO ノ KATAKANA LETTER NO */
+  { 0x04ca, 0x30cf }, /*                     kana_HA ハ KATAKANA LETTER HA */
+  { 0x04cb, 0x30d2 }, /*                     kana_HI ヒ KATAKANA LETTER HI */
+  { 0x04cc, 0x30d5 }, /*                     kana_FU フ KATAKANA LETTER HU */
+  { 0x04cd, 0x30d8 }, /*                     kana_HE ヘ KATAKANA LETTER HE */
+  { 0x04ce, 0x30db }, /*                     kana_HO ホ KATAKANA LETTER HO */
+  { 0x04cf, 0x30de }, /*                     kana_MA マ KATAKANA LETTER MA */
+  { 0x04d0, 0x30df }, /*                     kana_MI ミ KATAKANA LETTER MI */
+  { 0x04d1, 0x30e0 }, /*                     kana_MU ム KATAKANA LETTER MU */
+  { 0x04d2, 0x30e1 }, /*                     kana_ME メ KATAKANA LETTER ME */
+  { 0x04d3, 0x30e2 }, /*                     kana_MO モ KATAKANA LETTER MO */
+  { 0x04d4, 0x30e4 }, /*                     kana_YA ヤ KATAKANA LETTER YA */
+  { 0x04d5, 0x30e6 }, /*                     kana_YU ユ KATAKANA LETTER YU */
+  { 0x04d6, 0x30e8 }, /*                     kana_YO ヨ KATAKANA LETTER YO */
+  { 0x04d7, 0x30e9 }, /*                     kana_RA ラ KATAKANA LETTER RA */
+  { 0x04d8, 0x30ea }, /*                     kana_RI リ KATAKANA LETTER RI */
+  { 0x04d9, 0x30eb }, /*                     kana_RU ル KATAKANA LETTER RU */
+  { 0x04da, 0x30ec }, /*                     kana_RE レ KATAKANA LETTER RE */
+  { 0x04db, 0x30ed }, /*                     kana_RO ロ KATAKANA LETTER RO */
+  { 0x04dc, 0x30ef }, /*                     kana_WA ワ KATAKANA LETTER WA */
+  { 0x04dd, 0x30f3 }, /*                      kana_N ン KATAKANA LETTER N */
+  { 0x04de, 0x309b }, /*                 voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK */
+  { 0x04df, 0x309c }, /*             semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */
+  { 0x05ac, 0x060c }, /*                Arabic_comma ، ARABIC COMMA */
+  { 0x05bb, 0x061b }, /*            Arabic_semicolon ؛ ARABIC SEMICOLON */
+  { 0x05bf, 0x061f }, /*        Arabic_question_mark ؟ ARABIC QUESTION MARK */
+  { 0x05c1, 0x0621 }, /*                Arabic_hamza ء ARABIC LETTER HAMZA */
+  { 0x05c2, 0x0622 }, /*          Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */
+  { 0x05c3, 0x0623 }, /*          Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */
+  { 0x05c4, 0x0624 }, /*           Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */
+  { 0x05c5, 0x0625 }, /*       Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */
+  { 0x05c6, 0x0626 }, /*           Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */
+  { 0x05c7, 0x0627 }, /*                 Arabic_alef ا ARABIC LETTER ALEF */
+  { 0x05c8, 0x0628 }, /*                  Arabic_beh ب ARABIC LETTER BEH */
+  { 0x05c9, 0x0629 }, /*           Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA */
+  { 0x05ca, 0x062a }, /*                  Arabic_teh ت ARABIC LETTER TEH */
+  { 0x05cb, 0x062b }, /*                 Arabic_theh ث ARABIC LETTER THEH */
+  { 0x05cc, 0x062c }, /*                 Arabic_jeem ج ARABIC LETTER JEEM */
+  { 0x05cd, 0x062d }, /*                  Arabic_hah ح ARABIC LETTER HAH */
+  { 0x05ce, 0x062e }, /*                 Arabic_khah خ ARABIC LETTER KHAH */
+  { 0x05cf, 0x062f }, /*                  Arabic_dal د ARABIC LETTER DAL */
+  { 0x05d0, 0x0630 }, /*                 Arabic_thal ذ ARABIC LETTER THAL */
+  { 0x05d1, 0x0631 }, /*                   Arabic_ra ر ARABIC LETTER REH */
+  { 0x05d2, 0x0632 }, /*                 Arabic_zain ز ARABIC LETTER ZAIN */
+  { 0x05d3, 0x0633 }, /*                 Arabic_seen س ARABIC LETTER SEEN */
+  { 0x05d4, 0x0634 }, /*                Arabic_sheen ش ARABIC LETTER SHEEN */
+  { 0x05d5, 0x0635 }, /*                  Arabic_sad ص ARABIC LETTER SAD */
+  { 0x05d6, 0x0636 }, /*                  Arabic_dad ض ARABIC LETTER DAD */
+  { 0x05d7, 0x0637 }, /*                  Arabic_tah ط ARABIC LETTER TAH */
+  { 0x05d8, 0x0638 }, /*                  Arabic_zah ظ ARABIC LETTER ZAH */
+  { 0x05d9, 0x0639 }, /*                  Arabic_ain ع ARABIC LETTER AIN */
+  { 0x05da, 0x063a }, /*                Arabic_ghain غ ARABIC LETTER GHAIN */
+  { 0x05e0, 0x0640 }, /*              Arabic_tatweel ـ ARABIC TATWEEL */
+  { 0x05e1, 0x0641 }, /*                  Arabic_feh ف ARABIC LETTER FEH */
+  { 0x05e2, 0x0642 }, /*                  Arabic_qaf ق ARABIC LETTER QAF */
+  { 0x05e3, 0x0643 }, /*                  Arabic_kaf ك ARABIC LETTER KAF */
+  { 0x05e4, 0x0644 }, /*                  Arabic_lam ل ARABIC LETTER LAM */
+  { 0x05e5, 0x0645 }, /*                 Arabic_meem م ARABIC LETTER MEEM */
+  { 0x05e6, 0x0646 }, /*                 Arabic_noon ن ARABIC LETTER NOON */
+  { 0x05e7, 0x0647 }, /*                   Arabic_ha ه ARABIC LETTER HEH */
+  { 0x05e8, 0x0648 }, /*                  Arabic_waw و ARABIC LETTER WAW */
+  { 0x05e9, 0x0649 }, /*          Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA */
+  { 0x05ea, 0x064a }, /*                  Arabic_yeh ي ARABIC LETTER YEH */
+  { 0x05eb, 0x064b }, /*             Arabic_fathatan ً ARABIC FATHATAN */
+  { 0x05ec, 0x064c }, /*             Arabic_dammatan ٌ ARABIC DAMMATAN */
+  { 0x05ed, 0x064d }, /*             Arabic_kasratan ٍ ARABIC KASRATAN */
+  { 0x05ee, 0x064e }, /*                Arabic_fatha َ ARABIC FATHA */
+  { 0x05ef, 0x064f }, /*                Arabic_damma ُ ARABIC DAMMA */
+  { 0x05f0, 0x0650 }, /*                Arabic_kasra ِ ARABIC KASRA */
+  { 0x05f1, 0x0651 }, /*               Arabic_shadda ّ ARABIC SHADDA */
+  { 0x05f2, 0x0652 }, /*                Arabic_sukun ْ ARABIC SUKUN */
+  { 0x06a1, 0x0452 }, /*                 Serbian_dje ђ CYRILLIC SMALL LETTER DJE */
+  { 0x06a2, 0x0453 }, /*               Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE */
+  { 0x06a3, 0x0451 }, /*                 Cyrillic_io ё CYRILLIC SMALL LETTER IO */
+  { 0x06a4, 0x0454 }, /*                Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE */
+  { 0x06a5, 0x0455 }, /*               Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE */
+  { 0x06a6, 0x0456 }, /*                 Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
+  { 0x06a7, 0x0457 }, /*                Ukrainian_yi ї CYRILLIC SMALL LETTER YI */
+  { 0x06a8, 0x0458 }, /*                 Cyrillic_je ј CYRILLIC SMALL LETTER JE */
+  { 0x06a9, 0x0459 }, /*                Cyrillic_lje љ CYRILLIC SMALL LETTER LJE */
+  { 0x06aa, 0x045a }, /*                Cyrillic_nje њ CYRILLIC SMALL LETTER NJE */
+  { 0x06ab, 0x045b }, /*                Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE */
+  { 0x06ac, 0x045c }, /*               Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */
+  { 0x06ad, 0x0491 }, /*   Ukrainian_ghe_with_upturn ґ CYRILLIC SMALL LETTER GHE WITH UPTURN */
+  { 0x06ae, 0x045e }, /*         Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U */
+  { 0x06af, 0x045f }, /*               Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE */
+  { 0x06b0, 0x2116 }, /*                  numerosign № NUMERO SIGN */
+  { 0x06b1, 0x0402 }, /*                 Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */
+  { 0x06b2, 0x0403 }, /*               Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */
+  { 0x06b3, 0x0401 }, /*                 Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO */
+  { 0x06b4, 0x0404 }, /*                Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */
+  { 0x06b5, 0x0405 }, /*               Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE */
+  { 0x06b6, 0x0406 }, /*                 Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
+  { 0x06b7, 0x0407 }, /*                Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */
+  { 0x06b8, 0x0408 }, /*                 Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */
+  { 0x06b9, 0x0409 }, /*                Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */
+  { 0x06ba, 0x040a }, /*                Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */
+  { 0x06bb, 0x040b }, /*                Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */
+  { 0x06bc, 0x040c }, /*               Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */
+  { 0x06bd, 0x0490 }, /*   Ukrainian_GHE_WITH_UPTURN Ґ CYRILLIC CAPITAL LETTER GHE WITH UPTURN */
+  { 0x06be, 0x040e }, /*         Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U */
+  { 0x06bf, 0x040f }, /*               Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE */
+  { 0x06c0, 0x044e }, /*                 Cyrillic_yu ю CYRILLIC SMALL LETTER YU */
+  { 0x06c1, 0x0430 }, /*                  Cyrillic_a а CYRILLIC SMALL LETTER A */
+  { 0x06c2, 0x0431 }, /*                 Cyrillic_be б CYRILLIC SMALL LETTER BE */
+  { 0x06c3, 0x0446 }, /*                Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */
+  { 0x06c4, 0x0434 }, /*                 Cyrillic_de д CYRILLIC SMALL LETTER DE */
+  { 0x06c5, 0x0435 }, /*                 Cyrillic_ie е CYRILLIC SMALL LETTER IE */
+  { 0x06c6, 0x0444 }, /*                 Cyrillic_ef ф CYRILLIC SMALL LETTER EF */
+  { 0x06c7, 0x0433 }, /*                Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */
+  { 0x06c8, 0x0445 }, /*                 Cyrillic_ha х CYRILLIC SMALL LETTER HA */
+  { 0x06c9, 0x0438 }, /*                  Cyrillic_i и CYRILLIC SMALL LETTER I */
+  { 0x06ca, 0x0439 }, /*             Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */
+  { 0x06cb, 0x043a }, /*                 Cyrillic_ka к CYRILLIC SMALL LETTER KA */
+  { 0x06cc, 0x043b }, /*                 Cyrillic_el л CYRILLIC SMALL LETTER EL */
+  { 0x06cd, 0x043c }, /*                 Cyrillic_em м CYRILLIC SMALL LETTER EM */
+  { 0x06ce, 0x043d }, /*                 Cyrillic_en н CYRILLIC SMALL LETTER EN */
+  { 0x06cf, 0x043e }, /*                  Cyrillic_o о CYRILLIC SMALL LETTER O */
+  { 0x06d0, 0x043f }, /*                 Cyrillic_pe п CYRILLIC SMALL LETTER PE */
+  { 0x06d1, 0x044f }, /*                 Cyrillic_ya я CYRILLIC SMALL LETTER YA */
+  { 0x06d2, 0x0440 }, /*                 Cyrillic_er р CYRILLIC SMALL LETTER ER */
+  { 0x06d3, 0x0441 }, /*                 Cyrillic_es с CYRILLIC SMALL LETTER ES */
+  { 0x06d4, 0x0442 }, /*                 Cyrillic_te т CYRILLIC SMALL LETTER TE */
+  { 0x06d5, 0x0443 }, /*                  Cyrillic_u у CYRILLIC SMALL LETTER U */
+  { 0x06d6, 0x0436 }, /*                Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */
+  { 0x06d7, 0x0432 }, /*                 Cyrillic_ve в CYRILLIC SMALL LETTER VE */
+  { 0x06d8, 0x044c }, /*           Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */
+  { 0x06d9, 0x044b }, /*               Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU */
+  { 0x06da, 0x0437 }, /*                 Cyrillic_ze з CYRILLIC SMALL LETTER ZE */
+  { 0x06db, 0x0448 }, /*                Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */
+  { 0x06dc, 0x044d }, /*                  Cyrillic_e э CYRILLIC SMALL LETTER E */
+  { 0x06dd, 0x0449 }, /*              Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */
+  { 0x06de, 0x0447 }, /*                Cyrillic_che ч CYRILLIC SMALL LETTER CHE */
+  { 0x06df, 0x044a }, /*           Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN */
+  { 0x06e0, 0x042e }, /*                 Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */
+  { 0x06e1, 0x0410 }, /*                  Cyrillic_A А CYRILLIC CAPITAL LETTER A */
+  { 0x06e2, 0x0411 }, /*                 Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */
+  { 0x06e3, 0x0426 }, /*                Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */
+  { 0x06e4, 0x0414 }, /*                 Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */
+  { 0x06e5, 0x0415 }, /*                 Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */
+  { 0x06e6, 0x0424 }, /*                 Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */
+  { 0x06e7, 0x0413 }, /*                Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */
+  { 0x06e8, 0x0425 }, /*                 Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */
+  { 0x06e9, 0x0418 }, /*                  Cyrillic_I И CYRILLIC CAPITAL LETTER I */
+  { 0x06ea, 0x0419 }, /*             Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */
+  { 0x06eb, 0x041a }, /*                 Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */
+  { 0x06ec, 0x041b }, /*                 Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */
+  { 0x06ed, 0x041c }, /*                 Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */
+  { 0x06ee, 0x041d }, /*                 Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN */
+  { 0x06ef, 0x041e }, /*                  Cyrillic_O О CYRILLIC CAPITAL LETTER O */
+  { 0x06f0, 0x041f }, /*                 Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */
+  { 0x06f1, 0x042f }, /*                 Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */
+  { 0x06f2, 0x0420 }, /*                 Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */
+  { 0x06f3, 0x0421 }, /*                 Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */
+  { 0x06f4, 0x0422 }, /*                 Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */
+  { 0x06f5, 0x0423 }, /*                  Cyrillic_U У CYRILLIC CAPITAL LETTER U */
+  { 0x06f6, 0x0416 }, /*                Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */
+  { 0x06f7, 0x0412 }, /*                 Cyrillic_VE В CYRILLIC CAPITAL LETTER VE */
+  { 0x06f8, 0x042c }, /*           Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */
+  { 0x06f9, 0x042b }, /*               Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */
+  { 0x06fa, 0x0417 }, /*                 Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */
+  { 0x06fb, 0x0428 }, /*                Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */
+  { 0x06fc, 0x042d }, /*                  Cyrillic_E Э CYRILLIC CAPITAL LETTER E */
+  { 0x06fd, 0x0429 }, /*              Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */
+  { 0x06fe, 0x0427 }, /*                Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */
+  { 0x06ff, 0x042a }, /*           Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */
+  { 0x07a1, 0x0386 }, /*           Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */
+  { 0x07a2, 0x0388 }, /*         Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */
+  { 0x07a3, 0x0389 }, /*             Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */
+  { 0x07a4, 0x038a }, /*            Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */
+  { 0x07a5, 0x03aa }, /*          Greek_IOTAdieresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
+  { 0x07a7, 0x038c }, /*         Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */
+  { 0x07a8, 0x038e }, /*         Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */
+  { 0x07a9, 0x03ab }, /*       Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
+  { 0x07ab, 0x038f }, /*           Greek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS */
+  { 0x07ae, 0x0385 }, /*        Greek_accentdieresis ΅ GREEK DIALYTIKA TONOS */
+  { 0x07af, 0x2015 }, /*              Greek_horizbar ― HORIZONTAL BAR */
+  { 0x07b1, 0x03ac }, /*           Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */
+  { 0x07b2, 0x03ad }, /*         Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */
+  { 0x07b3, 0x03ae }, /*             Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */
+  { 0x07b4, 0x03af }, /*            Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */
+  { 0x07b5, 0x03ca }, /*          Greek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA */
+  { 0x07b6, 0x0390 }, /*    Greek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
+  { 0x07b7, 0x03cc }, /*         Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */
+  { 0x07b8, 0x03cd }, /*         Greek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS */
+  { 0x07b9, 0x03cb }, /*       Greek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */
+  { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
+  { 0x07bb, 0x03ce }, /*           Greek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS */
+  { 0x07c1, 0x0391 }, /*                 Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */
+  { 0x07c2, 0x0392 }, /*                  Greek_BETA Β GREEK CAPITAL LETTER BETA */
+  { 0x07c3, 0x0393 }, /*                 Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */
+  { 0x07c4, 0x0394 }, /*                 Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */
+  { 0x07c5, 0x0395 }, /*               Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */
+  { 0x07c6, 0x0396 }, /*                  Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */
+  { 0x07c7, 0x0397 }, /*                   Greek_ETA Η GREEK CAPITAL LETTER ETA */
+  { 0x07c8, 0x0398 }, /*                 Greek_THETA Θ GREEK CAPITAL LETTER THETA */
+  { 0x07c9, 0x0399 }, /*                  Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */
+  { 0x07ca, 0x039a }, /*                 Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */
+  { 0x07cb, 0x039b }, /*                Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */
+  { 0x07cc, 0x039c }, /*                    Greek_MU Μ GREEK CAPITAL LETTER MU */
+  { 0x07cd, 0x039d }, /*                    Greek_NU Ν GREEK CAPITAL LETTER NU */
+  { 0x07ce, 0x039e }, /*                    Greek_XI Ξ GREEK CAPITAL LETTER XI */
+  { 0x07cf, 0x039f }, /*               Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */
+  { 0x07d0, 0x03a0 }, /*                    Greek_PI Π GREEK CAPITAL LETTER PI */
+  { 0x07d1, 0x03a1 }, /*                   Greek_RHO Ρ GREEK CAPITAL LETTER RHO */
+  { 0x07d2, 0x03a3 }, /*                 Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */
+  { 0x07d4, 0x03a4 }, /*                   Greek_TAU Τ GREEK CAPITAL LETTER TAU */
+  { 0x07d5, 0x03a5 }, /*               Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */
+  { 0x07d6, 0x03a6 }, /*                   Greek_PHI Φ GREEK CAPITAL LETTER PHI */
+  { 0x07d7, 0x03a7 }, /*                   Greek_CHI Χ GREEK CAPITAL LETTER CHI */
+  { 0x07d8, 0x03a8 }, /*                   Greek_PSI Ψ GREEK CAPITAL LETTER PSI */
+  { 0x07d9, 0x03a9 }, /*                 Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */
+  { 0x07e1, 0x03b1 }, /*                 Greek_alpha α GREEK SMALL LETTER ALPHA */
+  { 0x07e2, 0x03b2 }, /*                  Greek_beta β GREEK SMALL LETTER BETA */
+  { 0x07e3, 0x03b3 }, /*                 Greek_gamma γ GREEK SMALL LETTER GAMMA */
+  { 0x07e4, 0x03b4 }, /*                 Greek_delta δ GREEK SMALL LETTER DELTA */
+  { 0x07e5, 0x03b5 }, /*               Greek_epsilon ε GREEK SMALL LETTER EPSILON */
+  { 0x07e6, 0x03b6 }, /*                  Greek_zeta ζ GREEK SMALL LETTER ZETA */
+  { 0x07e7, 0x03b7 }, /*                   Greek_eta η GREEK SMALL LETTER ETA */
+  { 0x07e8, 0x03b8 }, /*                 Greek_theta θ GREEK SMALL LETTER THETA */
+  { 0x07e9, 0x03b9 }, /*                  Greek_iota ι GREEK SMALL LETTER IOTA */
+  { 0x07ea, 0x03ba }, /*                 Greek_kappa κ GREEK SMALL LETTER KAPPA */
+  { 0x07eb, 0x03bb }, /*                Greek_lambda λ GREEK SMALL LETTER LAMDA */
+  { 0x07ec, 0x03bc }, /*                    Greek_mu μ GREEK SMALL LETTER MU */
+  { 0x07ed, 0x03bd }, /*                    Greek_nu ν GREEK SMALL LETTER NU */
+  { 0x07ee, 0x03be }, /*                    Greek_xi ξ GREEK SMALL LETTER XI */
+  { 0x07ef, 0x03bf }, /*               Greek_omicron ο GREEK SMALL LETTER OMICRON */
+  { 0x07f0, 0x03c0 }, /*                    Greek_pi π GREEK SMALL LETTER PI */
+  { 0x07f1, 0x03c1 }, /*                   Greek_rho ρ GREEK SMALL LETTER RHO */
+  { 0x07f2, 0x03c3 }, /*                 Greek_sigma σ GREEK SMALL LETTER SIGMA */
+  { 0x07f3, 0x03c2 }, /*       Greek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA */
+  { 0x07f4, 0x03c4 }, /*                   Greek_tau τ GREEK SMALL LETTER TAU */
+  { 0x07f5, 0x03c5 }, /*               Greek_upsilon υ GREEK SMALL LETTER UPSILON */
+  { 0x07f6, 0x03c6 }, /*                   Greek_phi φ GREEK SMALL LETTER PHI */
+  { 0x07f7, 0x03c7 }, /*                   Greek_chi χ GREEK SMALL LETTER CHI */
+  { 0x07f8, 0x03c8 }, /*                   Greek_psi ψ GREEK SMALL LETTER PSI */
+  { 0x07f9, 0x03c9 }, /*                 Greek_omega ω GREEK SMALL LETTER OMEGA */
+/*  0x08a1                               leftradical ? ??? */
+/*  0x08a2                            topleftradical ? ??? */
+/*  0x08a3                            horizconnector ? ??? */
+  { 0x08a4, 0x2320 }, /*                 topintegral ⌠ TOP HALF INTEGRAL */
+  { 0x08a5, 0x2321 }, /*                 botintegral ⌡ BOTTOM HALF INTEGRAL */
+  { 0x08a6, 0x2502 }, /*               vertconnector │ BOX DRAWINGS LIGHT VERTICAL */
+/*  0x08a7                          topleftsqbracket ? ??? */
+/*  0x08a8                          botleftsqbracket ? ??? */
+/*  0x08a9                         toprightsqbracket ? ??? */
+/*  0x08aa                         botrightsqbracket ? ??? */
+/*  0x08ab                             topleftparens ? ??? */
+/*  0x08ac                             botleftparens ? ??? */
+/*  0x08ad                            toprightparens ? ??? */
+/*  0x08ae                            botrightparens ? ??? */
+/*  0x08af                      leftmiddlecurlybrace ? ??? */
+/*  0x08b0                     rightmiddlecurlybrace ? ??? */
+/*  0x08b1                          topleftsummation ? ??? */
+/*  0x08b2                          botleftsummation ? ??? */
+/*  0x08b3                 topvertsummationconnector ? ??? */
+/*  0x08b4                 botvertsummationconnector ? ??? */
+/*  0x08b5                         toprightsummation ? ??? */
+/*  0x08b6                         botrightsummation ? ??? */
+/*  0x08b7                      rightmiddlesummation ? ??? */
+  { 0x08bc, 0x2264 }, /*               lessthanequal ≤ LESS-THAN OR EQUAL TO */
+  { 0x08bd, 0x2260 }, /*                    notequal ≠ NOT EQUAL TO */
+  { 0x08be, 0x2265 }, /*            greaterthanequal ≥ GREATER-THAN OR EQUAL TO */
+  { 0x08bf, 0x222b }, /*                    integral ∫ INTEGRAL */
+  { 0x08c0, 0x2234 }, /*                   therefore ∴ THEREFORE */
+  { 0x08c1, 0x221d }, /*                   variation ∝ PROPORTIONAL TO */
+  { 0x08c2, 0x221e }, /*                    infinity ∞ INFINITY */
+  { 0x08c5, 0x2207 }, /*                       nabla ∇ NABLA */
+  { 0x08c8, 0x2245 }, /*                 approximate ≅ APPROXIMATELY EQUAL TO */
+/*  0x08c9                              similarequal ? ??? */
+  { 0x08cd, 0x21d4 }, /*                    ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */
+  { 0x08ce, 0x21d2 }, /*                     implies ⇒ RIGHTWARDS DOUBLE ARROW */
+  { 0x08cf, 0x2261 }, /*                   identical ≡ IDENTICAL TO */
+  { 0x08d6, 0x221a }, /*                     radical √ SQUARE ROOT */
+  { 0x08da, 0x2282 }, /*                  includedin ⊂ SUBSET OF */
+  { 0x08db, 0x2283 }, /*                    includes ⊃ SUPERSET OF */
+  { 0x08dc, 0x2229 }, /*                intersection ∩ INTERSECTION */
+  { 0x08dd, 0x222a }, /*                       union ∪ UNION */
+  { 0x08de, 0x2227 }, /*                  logicaland ∧ LOGICAL AND */
+  { 0x08df, 0x2228 }, /*                   logicalor ∨ LOGICAL OR */
+  { 0x08ef, 0x2202 }, /*           partialderivative ∂ PARTIAL DIFFERENTIAL */
+  { 0x08f6, 0x0192 }, /*                    function ƒ LATIN SMALL LETTER F WITH HOOK */
+  { 0x08fb, 0x2190 }, /*                   leftarrow ← LEFTWARDS ARROW */
+  { 0x08fc, 0x2191 }, /*                     uparrow ↑ UPWARDS ARROW */
+  { 0x08fd, 0x2192 }, /*                  rightarrow → RIGHTWARDS ARROW */
+  { 0x08fe, 0x2193 }, /*                   downarrow ↓ DOWNWARDS ARROW */
+  { 0x09df, 0x2422 }, /*                       blank ␢ BLANK SYMBOL */
+  { 0x09e0, 0x25c6 }, /*                soliddiamond ◆ BLACK DIAMOND */
+  { 0x09e1, 0x2592 }, /*                checkerboard ▒ MEDIUM SHADE */
+  { 0x09e2, 0x2409 }, /*                          ht ␉ SYMBOL FOR HORIZONTAL TABULATION */
+  { 0x09e3, 0x240c }, /*                          ff ␌ SYMBOL FOR FORM FEED */
+  { 0x09e4, 0x240d }, /*                          cr ␍ SYMBOL FOR CARRIAGE RETURN */
+  { 0x09e5, 0x240a }, /*                          lf ␊ SYMBOL FOR LINE FEED */
+  { 0x09e8, 0x2424 }, /*                          nl ␤ SYMBOL FOR NEWLINE */
+  { 0x09e9, 0x240b }, /*                          vt ␋ SYMBOL FOR VERTICAL TABULATION */
+  { 0x09ea, 0x2518 }, /*              lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */
+  { 0x09eb, 0x2510 }, /*               uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */
+  { 0x09ec, 0x250c }, /*                upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */
+  { 0x09ed, 0x2514 }, /*               lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */
+  { 0x09ee, 0x253c }, /*               crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
+/*  0x09ef                            horizlinescan1 ? ??? */
+/*  0x09f0                            horizlinescan3 ? ??? */
+  { 0x09f1, 0x2500 }, /*              horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */
+/*  0x09f2                            horizlinescan7 ? ??? */
+/*  0x09f3                            horizlinescan9 ? ??? */
+  { 0x09f4, 0x251c }, /*                       leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
+  { 0x09f5, 0x2524 }, /*                      rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */
+  { 0x09f6, 0x2534 }, /*                        bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */
+  { 0x09f7, 0x252c }, /*                        topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
+  { 0x09f8, 0x2502 }, /*                     vertbar │ BOX DRAWINGS LIGHT VERTICAL */
+  { 0x0aa1, 0x2003 }, /*                     emspace   EM SPACE */
+  { 0x0aa2, 0x2002 }, /*                     enspace   EN SPACE */
+  { 0x0aa3, 0x2004 }, /*                    em3space   THREE-PER-EM SPACE */
+  { 0x0aa4, 0x2005 }, /*                    em4space   FOUR-PER-EM SPACE */
+  { 0x0aa5, 0x2007 }, /*                  digitspace   FIGURE SPACE */
+  { 0x0aa6, 0x2008 }, /*                  punctspace   PUNCTUATION SPACE */
+  { 0x0aa7, 0x2009 }, /*                   thinspace   THIN SPACE */
+  { 0x0aa8, 0x200a }, /*                   hairspace   HAIR SPACE */
+  { 0x0aa9, 0x2014 }, /*                      emdash — EM DASH */
+  { 0x0aaa, 0x2013 }, /*                      endash – EN DASH */
+/*  0x0aac                               signifblank ? ??? */
+  { 0x0aae, 0x2026 }, /*                    ellipsis … HORIZONTAL ELLIPSIS */
+/*  0x0aaf                           doubbaselinedot ? ??? */
+  { 0x0ab0, 0x2153 }, /*                    onethird ⅓ VULGAR FRACTION ONE THIRD */
+  { 0x0ab1, 0x2154 }, /*                   twothirds ⅔ VULGAR FRACTION TWO THIRDS */
+  { 0x0ab2, 0x2155 }, /*                    onefifth ⅕ VULGAR FRACTION ONE FIFTH */
+  { 0x0ab3, 0x2156 }, /*                   twofifths ⅖ VULGAR FRACTION TWO FIFTHS */
+  { 0x0ab4, 0x2157 }, /*                 threefifths ⅗ VULGAR FRACTION THREE FIFTHS */
+  { 0x0ab5, 0x2158 }, /*                  fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS */
+  { 0x0ab6, 0x2159 }, /*                    onesixth ⅙ VULGAR FRACTION ONE SIXTH */
+  { 0x0ab7, 0x215a }, /*                  fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */
+  { 0x0ab8, 0x2105 }, /*                      careof ℅ CARE OF */
+  { 0x0abb, 0x2012 }, /*                     figdash ‒ FIGURE DASH */
+  { 0x0abc, 0x2329 }, /*            leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */
+  { 0x0abd, 0x002e }, /*                decimalpoint . FULL STOP */
+  { 0x0abe, 0x232a }, /*           rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */
+/*  0x0abf                                    marker ? ??? */
+  { 0x0ac3, 0x215b }, /*                   oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */
+  { 0x0ac4, 0x215c }, /*                threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */
+  { 0x0ac5, 0x215d }, /*                 fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS */
+  { 0x0ac6, 0x215e }, /*                seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS */
+  { 0x0ac9, 0x2122 }, /*                   trademark ™ TRADE MARK SIGN */
+  { 0x0aca, 0x2613 }, /*               signaturemark ☓ SALTIRE */
+/*  0x0acb                         trademarkincircle ? ??? */
+  { 0x0acc, 0x25c1 }, /*            leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */
+  { 0x0acd, 0x25b7 }, /*           rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */
+  { 0x0ace, 0x25cb }, /*                emopencircle ○ WHITE CIRCLE */
+  { 0x0acf, 0x25a1 }, /*             emopenrectangle □ WHITE SQUARE */
+  { 0x0ad0, 0x2018 }, /*         leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */
+  { 0x0ad1, 0x2019 }, /*        rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */
+  { 0x0ad2, 0x201c }, /*         leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */
+  { 0x0ad3, 0x201d }, /*        rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */
+  { 0x0ad4, 0x211e }, /*                prescription ℞ PRESCRIPTION TAKE */
+  { 0x0ad6, 0x2032 }, /*                     minutes ′ PRIME */
+  { 0x0ad7, 0x2033 }, /*                     seconds ″ DOUBLE PRIME */
+  { 0x0ad9, 0x271d }, /*                  latincross ✝ LATIN CROSS */
+/*  0x0ada                                  hexagram ? ??? */
+  { 0x0adb, 0x25ac }, /*            filledrectbullet ▬ BLACK RECTANGLE */
+  { 0x0adc, 0x25c0 }, /*         filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */
+  { 0x0add, 0x25b6 }, /*        filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */
+  { 0x0ade, 0x25cf }, /*              emfilledcircle ● BLACK CIRCLE */
+  { 0x0adf, 0x25a0 }, /*                emfilledrect ■ BLACK SQUARE */
+  { 0x0ae0, 0x25e6 }, /*            enopencircbullet ◦ WHITE BULLET */
+  { 0x0ae1, 0x25ab }, /*          enopensquarebullet ▫ WHITE SMALL SQUARE */
+  { 0x0ae2, 0x25ad }, /*              openrectbullet ▭ WHITE RECTANGLE */
+  { 0x0ae3, 0x25b3 }, /*             opentribulletup △ WHITE UP-POINTING TRIANGLE */
+  { 0x0ae4, 0x25bd }, /*           opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE */
+  { 0x0ae5, 0x2606 }, /*                    openstar ☆ WHITE STAR */
+  { 0x0ae6, 0x2022 }, /*          enfilledcircbullet • BULLET */
+  { 0x0ae7, 0x25aa }, /*            enfilledsqbullet ▪ BLACK SMALL SQUARE */
+  { 0x0ae8, 0x25b2 }, /*           filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */
+  { 0x0ae9, 0x25bc }, /*         filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE */
+  { 0x0aea, 0x261c }, /*                 leftpointer ☜ WHITE LEFT POINTING INDEX */
+  { 0x0aeb, 0x261e }, /*                rightpointer ☞ WHITE RIGHT POINTING INDEX */
+  { 0x0aec, 0x2663 }, /*                        club ♣ BLACK CLUB SUIT */
+  { 0x0aed, 0x2666 }, /*                     diamond ♦ BLACK DIAMOND SUIT */
+  { 0x0aee, 0x2665 }, /*                       heart ♥ BLACK HEART SUIT */
+  { 0x0af0, 0x2720 }, /*                maltesecross ✠ MALTESE CROSS */
+  { 0x0af1, 0x2020 }, /*                      dagger † DAGGER */
+  { 0x0af2, 0x2021 }, /*                doubledagger ‡ DOUBLE DAGGER */
+  { 0x0af3, 0x2713 }, /*                   checkmark ✓ CHECK MARK */
+  { 0x0af4, 0x2717 }, /*                 ballotcross ✗ BALLOT X */
+  { 0x0af5, 0x266f }, /*                musicalsharp ♯ MUSIC SHARP SIGN */
+  { 0x0af6, 0x266d }, /*                 musicalflat ♭ MUSIC FLAT SIGN */
+  { 0x0af7, 0x2642 }, /*                  malesymbol ♂ MALE SIGN */
+  { 0x0af8, 0x2640 }, /*                femalesymbol ♀ FEMALE SIGN */
+  { 0x0af9, 0x260e }, /*                   telephone ☎ BLACK TELEPHONE */
+  { 0x0afa, 0x2315 }, /*           telephonerecorder ⌕ TELEPHONE RECORDER */
+  { 0x0afb, 0x2117 }, /*         phonographcopyright ℗ SOUND RECORDING COPYRIGHT */
+  { 0x0afc, 0x2038 }, /*                       caret ‸ CARET */
+  { 0x0afd, 0x201a }, /*          singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */
+  { 0x0afe, 0x201e }, /*          doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */
+/*  0x0aff                                    cursor ? ??? */
+  { 0x0ba3, 0x003c }, /*                   leftcaret < LESS-THAN SIGN */
+  { 0x0ba6, 0x003e }, /*                  rightcaret > GREATER-THAN SIGN */
+  { 0x0ba8, 0x2228 }, /*                   downcaret ∨ LOGICAL OR */
+  { 0x0ba9, 0x2227 }, /*                     upcaret ∧ LOGICAL AND */
+  { 0x0bc0, 0x00af }, /*                     overbar ¯ MACRON */
+  { 0x0bc2, 0x22a4 }, /*                    downtack ⊤ DOWN TACK */
+  { 0x0bc3, 0x2229 }, /*                      upshoe ∩ INTERSECTION */
+  { 0x0bc4, 0x230a }, /*                   downstile ⌊ LEFT FLOOR */
+  { 0x0bc6, 0x005f }, /*                    underbar _ LOW LINE */
+  { 0x0bca, 0x2218 }, /*                         jot ∘ RING OPERATOR */
+  { 0x0bcc, 0x2395 }, /*                        quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */
+  { 0x0bce, 0x22a5 }, /*                      uptack ⊥ UP TACK */
+  { 0x0bcf, 0x25cb }, /*                      circle ○ WHITE CIRCLE */
+  { 0x0bd3, 0x2308 }, /*                     upstile ⌈ LEFT CEILING */
+  { 0x0bd6, 0x222a }, /*                    downshoe ∪ UNION */
+  { 0x0bd8, 0x2283 }, /*                   rightshoe ⊃ SUPERSET OF */
+  { 0x0bda, 0x2282 }, /*                    leftshoe ⊂ SUBSET OF */
+  { 0x0bdc, 0x22a3 }, /*                    lefttack ⊣ LEFT TACK */
+  { 0x0bfc, 0x22a2 }, /*                   righttack ⊢ RIGHT TACK */
+  { 0x0cdf, 0x2017 }, /*        hebrew_doublelowline ‗ DOUBLE LOW LINE */
+  { 0x0ce0, 0x05d0 }, /*                hebrew_aleph א HEBREW LETTER ALEF */
+  { 0x0ce1, 0x05d1 }, /*                  hebrew_bet ב HEBREW LETTER BET */
+  { 0x0ce2, 0x05d2 }, /*                hebrew_gimel ג HEBREW LETTER GIMEL */
+  { 0x0ce3, 0x05d3 }, /*                hebrew_dalet ד HEBREW LETTER DALET */
+  { 0x0ce4, 0x05d4 }, /*                   hebrew_he ה HEBREW LETTER HE */
+  { 0x0ce5, 0x05d5 }, /*                  hebrew_waw ו HEBREW LETTER VAV */
+  { 0x0ce6, 0x05d6 }, /*                 hebrew_zain ז HEBREW LETTER ZAYIN */
+  { 0x0ce7, 0x05d7 }, /*                 hebrew_chet ח HEBREW LETTER HET */
+  { 0x0ce8, 0x05d8 }, /*                  hebrew_tet ט HEBREW LETTER TET */
+  { 0x0ce9, 0x05d9 }, /*                  hebrew_yod י HEBREW LETTER YOD */
+  { 0x0cea, 0x05da }, /*            hebrew_finalkaph ך HEBREW LETTER FINAL KAF */
+  { 0x0ceb, 0x05db }, /*                 hebrew_kaph כ HEBREW LETTER KAF */
+  { 0x0cec, 0x05dc }, /*                hebrew_lamed ל HEBREW LETTER LAMED */
+  { 0x0ced, 0x05dd }, /*             hebrew_finalmem ם HEBREW LETTER FINAL MEM */
+  { 0x0cee, 0x05de }, /*                  hebrew_mem מ HEBREW LETTER MEM */
+  { 0x0cef, 0x05df }, /*             hebrew_finalnun ן HEBREW LETTER FINAL NUN */
+  { 0x0cf0, 0x05e0 }, /*                  hebrew_nun נ HEBREW LETTER NUN */
+  { 0x0cf1, 0x05e1 }, /*               hebrew_samech ס HEBREW LETTER SAMEKH */
+  { 0x0cf2, 0x05e2 }, /*                 hebrew_ayin ע HEBREW LETTER AYIN */
+  { 0x0cf3, 0x05e3 }, /*              hebrew_finalpe ף HEBREW LETTER FINAL PE */
+  { 0x0cf4, 0x05e4 }, /*                   hebrew_pe פ HEBREW LETTER PE */
+  { 0x0cf5, 0x05e5 }, /*            hebrew_finalzade ץ HEBREW LETTER FINAL TSADI */
+  { 0x0cf6, 0x05e6 }, /*                 hebrew_zade צ HEBREW LETTER TSADI */
+  { 0x0cf7, 0x05e7 }, /*                 hebrew_qoph ק HEBREW LETTER QOF */
+  { 0x0cf8, 0x05e8 }, /*                 hebrew_resh ר HEBREW LETTER RESH */
+  { 0x0cf9, 0x05e9 }, /*                 hebrew_shin ש HEBREW LETTER SHIN */
+  { 0x0cfa, 0x05ea }, /*                  hebrew_taw ת HEBREW LETTER TAV */
+  { 0x0da1, 0x0e01 }, /*                  Thai_kokai ก THAI CHARACTER KO KAI */
+  { 0x0da2, 0x0e02 }, /*                Thai_khokhai ข THAI CHARACTER KHO KHAI */
+  { 0x0da3, 0x0e03 }, /*               Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */
+  { 0x0da4, 0x0e04 }, /*               Thai_khokhwai ค THAI CHARACTER KHO KHWAI */
+  { 0x0da5, 0x0e05 }, /*                Thai_khokhon ฅ THAI CHARACTER KHO KHON */
+  { 0x0da6, 0x0e06 }, /*             Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */
+  { 0x0da7, 0x0e07 }, /*                 Thai_ngongu ง THAI CHARACTER NGO NGU */
+  { 0x0da8, 0x0e08 }, /*                Thai_chochan จ THAI CHARACTER CHO CHAN */
+  { 0x0da9, 0x0e09 }, /*               Thai_choching ฉ THAI CHARACTER CHO CHING */
+  { 0x0daa, 0x0e0a }, /*               Thai_chochang ช THAI CHARACTER CHO CHANG */
+  { 0x0dab, 0x0e0b }, /*                   Thai_soso ซ THAI CHARACTER SO SO */
+  { 0x0dac, 0x0e0c }, /*                Thai_chochoe ฌ THAI CHARACTER CHO CHOE */
+  { 0x0dad, 0x0e0d }, /*                 Thai_yoying ญ THAI CHARACTER YO YING */
+  { 0x0dae, 0x0e0e }, /*                Thai_dochada ฎ THAI CHARACTER DO CHADA */
+  { 0x0daf, 0x0e0f }, /*                Thai_topatak ฏ THAI CHARACTER TO PATAK */
+  { 0x0db0, 0x0e10 }, /*                Thai_thothan ฐ THAI CHARACTER THO THAN */
+  { 0x0db1, 0x0e11 }, /*          Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */
+  { 0x0db2, 0x0e12 }, /*             Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */
+  { 0x0db3, 0x0e13 }, /*                  Thai_nonen ณ THAI CHARACTER NO NEN */
+  { 0x0db4, 0x0e14 }, /*                  Thai_dodek ด THAI CHARACTER DO DEK */
+  { 0x0db5, 0x0e15 }, /*                  Thai_totao ต THAI CHARACTER TO TAO */
+  { 0x0db6, 0x0e16 }, /*               Thai_thothung ถ THAI CHARACTER THO THUNG */
+  { 0x0db7, 0x0e17 }, /*              Thai_thothahan ท THAI CHARACTER THO THAHAN */
+  { 0x0db8, 0x0e18 }, /*               Thai_thothong ธ THAI CHARACTER THO THONG */
+  { 0x0db9, 0x0e19 }, /*                   Thai_nonu น THAI CHARACTER NO NU */
+  { 0x0dba, 0x0e1a }, /*               Thai_bobaimai บ THAI CHARACTER BO BAIMAI */
+  { 0x0dbb, 0x0e1b }, /*                  Thai_popla ป THAI CHARACTER PO PLA */
+  { 0x0dbc, 0x0e1c }, /*               Thai_phophung ผ THAI CHARACTER PHO PHUNG */
+  { 0x0dbd, 0x0e1d }, /*                   Thai_fofa ฝ THAI CHARACTER FO FA */
+  { 0x0dbe, 0x0e1e }, /*                Thai_phophan พ THAI CHARACTER PHO PHAN */
+  { 0x0dbf, 0x0e1f }, /*                  Thai_fofan ฟ THAI CHARACTER FO FAN */
+  { 0x0dc0, 0x0e20 }, /*             Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */
+  { 0x0dc1, 0x0e21 }, /*                   Thai_moma ม THAI CHARACTER MO MA */
+  { 0x0dc2, 0x0e22 }, /*                  Thai_yoyak ย THAI CHARACTER YO YAK */
+  { 0x0dc3, 0x0e23 }, /*                  Thai_rorua ร THAI CHARACTER RO RUA */
+  { 0x0dc4, 0x0e24 }, /*                     Thai_ru ฤ THAI CHARACTER RU */
+  { 0x0dc5, 0x0e25 }, /*                 Thai_loling ล THAI CHARACTER LO LING */
+  { 0x0dc6, 0x0e26 }, /*                     Thai_lu ฦ THAI CHARACTER LU */
+  { 0x0dc7, 0x0e27 }, /*                 Thai_wowaen ว THAI CHARACTER WO WAEN */
+  { 0x0dc8, 0x0e28 }, /*                 Thai_sosala ศ THAI CHARACTER SO SALA */
+  { 0x0dc9, 0x0e29 }, /*                 Thai_sorusi ษ THAI CHARACTER SO RUSI */
+  { 0x0dca, 0x0e2a }, /*                  Thai_sosua ส THAI CHARACTER SO SUA */
+  { 0x0dcb, 0x0e2b }, /*                  Thai_hohip ห THAI CHARACTER HO HIP */
+  { 0x0dcc, 0x0e2c }, /*                Thai_lochula ฬ THAI CHARACTER LO CHULA */
+  { 0x0dcd, 0x0e2d }, /*                   Thai_oang อ THAI CHARACTER O ANG */
+  { 0x0dce, 0x0e2e }, /*               Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */
+  { 0x0dcf, 0x0e2f }, /*              Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */
+  { 0x0dd0, 0x0e30 }, /*                  Thai_saraa ะ THAI CHARACTER SARA A */
+  { 0x0dd1, 0x0e31 }, /*             Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */
+  { 0x0dd2, 0x0e32 }, /*                 Thai_saraaa า THAI CHARACTER SARA AA */
+  { 0x0dd3, 0x0e33 }, /*                 Thai_saraam ำ THAI CHARACTER SARA AM */
+  { 0x0dd4, 0x0e34 }, /*                  Thai_sarai ิ THAI CHARACTER SARA I */
+  { 0x0dd5, 0x0e35 }, /*                 Thai_saraii ี THAI CHARACTER SARA II */
+  { 0x0dd6, 0x0e36 }, /*                 Thai_saraue ึ THAI CHARACTER SARA UE */
+  { 0x0dd7, 0x0e37 }, /*                Thai_sarauee ื THAI CHARACTER SARA UEE */
+  { 0x0dd8, 0x0e38 }, /*                  Thai_sarau ุ THAI CHARACTER SARA U */
+  { 0x0dd9, 0x0e39 }, /*                 Thai_sarauu ู THAI CHARACTER SARA UU */
+  { 0x0dda, 0x0e3a }, /*                Thai_phinthu ฺ THAI CHARACTER PHINTHU */
+  { 0x0dde, 0x0e3e }, /*      Thai_maihanakat_maitho ฾ ??? */
+  { 0x0ddf, 0x0e3f }, /*                   Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */
+  { 0x0de0, 0x0e40 }, /*                  Thai_sarae เ THAI CHARACTER SARA E */
+  { 0x0de1, 0x0e41 }, /*                 Thai_saraae แ THAI CHARACTER SARA AE */
+  { 0x0de2, 0x0e42 }, /*                  Thai_sarao โ THAI CHARACTER SARA O */
+  { 0x0de3, 0x0e43 }, /*          Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */
+  { 0x0de4, 0x0e44 }, /*         Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */
+  { 0x0de5, 0x0e45 }, /*            Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */
+  { 0x0de6, 0x0e46 }, /*               Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */
+  { 0x0de7, 0x0e47 }, /*              Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */
+  { 0x0de8, 0x0e48 }, /*                  Thai_maiek ่ THAI CHARACTER MAI EK */
+  { 0x0de9, 0x0e49 }, /*                 Thai_maitho ้ THAI CHARACTER MAI THO */
+  { 0x0dea, 0x0e4a }, /*                 Thai_maitri ๊ THAI CHARACTER MAI TRI */
+  { 0x0deb, 0x0e4b }, /*            Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */
+  { 0x0dec, 0x0e4c }, /*            Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */
+  { 0x0ded, 0x0e4d }, /*               Thai_nikhahit ํ THAI CHARACTER NIKHAHIT */
+  { 0x0df0, 0x0e50 }, /*                 Thai_leksun ๐ THAI DIGIT ZERO */
+  { 0x0df1, 0x0e51 }, /*                Thai_leknung ๑ THAI DIGIT ONE */
+  { 0x0df2, 0x0e52 }, /*                Thai_leksong ๒ THAI DIGIT TWO */
+  { 0x0df3, 0x0e53 }, /*                 Thai_leksam ๓ THAI DIGIT THREE */
+  { 0x0df4, 0x0e54 }, /*                  Thai_leksi ๔ THAI DIGIT FOUR */
+  { 0x0df5, 0x0e55 }, /*                  Thai_lekha ๕ THAI DIGIT FIVE */
+  { 0x0df6, 0x0e56 }, /*                 Thai_lekhok ๖ THAI DIGIT SIX */
+  { 0x0df7, 0x0e57 }, /*                Thai_lekchet ๗ THAI DIGIT SEVEN */
+  { 0x0df8, 0x0e58 }, /*                Thai_lekpaet ๘ THAI DIGIT EIGHT */
+  { 0x0df9, 0x0e59 }, /*                 Thai_lekkao ๙ THAI DIGIT NINE */
+  { 0x0ea1, 0x3131 }, /*               Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */
+  { 0x0ea2, 0x3132 }, /*          Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */
+  { 0x0ea3, 0x3133 }, /*           Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */
+  { 0x0ea4, 0x3134 }, /*                Hangul_Nieun ㄴ HANGUL LETTER NIEUN */
+  { 0x0ea5, 0x3135 }, /*           Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */
+  { 0x0ea6, 0x3136 }, /*           Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */
+  { 0x0ea7, 0x3137 }, /*               Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT */
+  { 0x0ea8, 0x3138 }, /*          Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */
+  { 0x0ea9, 0x3139 }, /*                Hangul_Rieul ㄹ HANGUL LETTER RIEUL */
+  { 0x0eaa, 0x313a }, /*          Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */
+  { 0x0eab, 0x313b }, /*           Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM */
+  { 0x0eac, 0x313c }, /*           Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */
+  { 0x0ead, 0x313d }, /*            Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */
+  { 0x0eae, 0x313e }, /*           Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */
+  { 0x0eaf, 0x313f }, /*          Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH */
+  { 0x0eb0, 0x3140 }, /*           Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH */
+  { 0x0eb1, 0x3141 }, /*                Hangul_Mieum ㅁ HANGUL LETTER MIEUM */
+  { 0x0eb2, 0x3142 }, /*                Hangul_Pieub ㅂ HANGUL LETTER PIEUP */
+  { 0x0eb3, 0x3143 }, /*           Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP */
+  { 0x0eb4, 0x3144 }, /*            Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS */
+  { 0x0eb5, 0x3145 }, /*                 Hangul_Sios ㅅ HANGUL LETTER SIOS */
+  { 0x0eb6, 0x3146 }, /*            Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS */
+  { 0x0eb7, 0x3147 }, /*                Hangul_Ieung ㅇ HANGUL LETTER IEUNG */
+  { 0x0eb8, 0x3148 }, /*                Hangul_Jieuj ㅈ HANGUL LETTER CIEUC */
+  { 0x0eb9, 0x3149 }, /*           Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC */
+  { 0x0eba, 0x314a }, /*                Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH */
+  { 0x0ebb, 0x314b }, /*               Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH */
+  { 0x0ebc, 0x314c }, /*                Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */
+  { 0x0ebd, 0x314d }, /*               Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH */
+  { 0x0ebe, 0x314e }, /*                Hangul_Hieuh ㅎ HANGUL LETTER HIEUH */
+  { 0x0ebf, 0x314f }, /*                    Hangul_A ㅏ HANGUL LETTER A */
+  { 0x0ec0, 0x3150 }, /*                   Hangul_AE ㅐ HANGUL LETTER AE */
+  { 0x0ec1, 0x3151 }, /*                   Hangul_YA ㅑ HANGUL LETTER YA */
+  { 0x0ec2, 0x3152 }, /*                  Hangul_YAE ㅒ HANGUL LETTER YAE */
+  { 0x0ec3, 0x3153 }, /*                   Hangul_EO ㅓ HANGUL LETTER EO */
+  { 0x0ec4, 0x3154 }, /*                    Hangul_E ㅔ HANGUL LETTER E */
+  { 0x0ec5, 0x3155 }, /*                  Hangul_YEO ㅕ HANGUL LETTER YEO */
+  { 0x0ec6, 0x3156 }, /*                   Hangul_YE ㅖ HANGUL LETTER YE */
+  { 0x0ec7, 0x3157 }, /*                    Hangul_O ㅗ HANGUL LETTER O */
+  { 0x0ec8, 0x3158 }, /*                   Hangul_WA ㅘ HANGUL LETTER WA */
+  { 0x0ec9, 0x3159 }, /*                  Hangul_WAE ㅙ HANGUL LETTER WAE */
+  { 0x0eca, 0x315a }, /*                   Hangul_OE ㅚ HANGUL LETTER OE */
+  { 0x0ecb, 0x315b }, /*                   Hangul_YO ㅛ HANGUL LETTER YO */
+  { 0x0ecc, 0x315c }, /*                    Hangul_U ㅜ HANGUL LETTER U */
+  { 0x0ecd, 0x315d }, /*                  Hangul_WEO ㅝ HANGUL LETTER WEO */
+  { 0x0ece, 0x315e }, /*                   Hangul_WE ㅞ HANGUL LETTER WE */
+  { 0x0ecf, 0x315f }, /*                   Hangul_WI ㅟ HANGUL LETTER WI */
+  { 0x0ed0, 0x3160 }, /*                   Hangul_YU ㅠ HANGUL LETTER YU */
+  { 0x0ed1, 0x3161 }, /*                   Hangul_EU ㅡ HANGUL LETTER EU */
+  { 0x0ed2, 0x3162 }, /*                   Hangul_YI ㅢ HANGUL LETTER YI */
+  { 0x0ed3, 0x3163 }, /*                    Hangul_I ㅣ HANGUL LETTER I */
+  { 0x0ed4, 0x11a8 }, /*             Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */
+  { 0x0ed5, 0x11a9 }, /*        Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */
+  { 0x0ed6, 0x11aa }, /*         Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */
+  { 0x0ed7, 0x11ab }, /*              Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */
+  { 0x0ed8, 0x11ac }, /*         Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */
+  { 0x0ed9, 0x11ad }, /*         Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */
+  { 0x0eda, 0x11ae }, /*             Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */
+  { 0x0edb, 0x11af }, /*              Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */
+  { 0x0edc, 0x11b0 }, /*        Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */
+  { 0x0edd, 0x11b1 }, /*         Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */
+  { 0x0ede, 0x11b2 }, /*         Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */
+  { 0x0edf, 0x11b3 }, /*          Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */
+  { 0x0ee0, 0x11b4 }, /*         Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */
+  { 0x0ee1, 0x11b5 }, /*        Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */
+  { 0x0ee2, 0x11b6 }, /*         Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */
+  { 0x0ee3, 0x11b7 }, /*              Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */
+  { 0x0ee4, 0x11b8 }, /*              Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */
+  { 0x0ee5, 0x11b9 }, /*          Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */
+  { 0x0ee6, 0x11ba }, /*               Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */
+  { 0x0ee7, 0x11bb }, /*          Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */
+  { 0x0ee8, 0x11bc }, /*              Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */
+  { 0x0ee9, 0x11bd }, /*              Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */
+  { 0x0eea, 0x11be }, /*              Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */
+  { 0x0eeb, 0x11bf }, /*             Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */
+  { 0x0eec, 0x11c0 }, /*              Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */
+  { 0x0eed, 0x11c1 }, /*             Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */
+  { 0x0eee, 0x11c2 }, /*              Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */
+  { 0x0eef, 0x316d }, /*     Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH */
+  { 0x0ef0, 0x3171 }, /*    Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */
+  { 0x0ef1, 0x3178 }, /*    Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */
+  { 0x0ef2, 0x317f }, /*              Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */
+/*  0x0ef3                  Hangul_KkogjiDalrinIeung ? ??? */
+  { 0x0ef4, 0x3184 }, /*   Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */
+  { 0x0ef5, 0x3186 }, /*          Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */
+  { 0x0ef6, 0x318d }, /*                Hangul_AraeA ㆍ HANGUL LETTER ARAEA */
+  { 0x0ef7, 0x318e }, /*               Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */
+  { 0x0ef8, 0x11eb }, /*            Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */
+/*  0x0ef9                Hangul_J_KkogjiDalrinIeung ? ??? */
+  { 0x0efa, 0x11f9 }, /*        Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */
+  { 0x0eff, 0x20a9 }, /*                  Korean_Won ₩ WON SIGN */
+  { 0x13bc, 0x0152 }, /*                          OE Œ LATIN CAPITAL LIGATURE OE */
+  { 0x13bd, 0x0153 }, /*                          oe œ LATIN SMALL LIGATURE OE */
+  { 0x13be, 0x0178 }, /*                  Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */
+  { 0x20a0, 0x20a0 }, /*                     EcuSign ₠ EURO-CURRENCY SIGN */
+  { 0x20a1, 0x20a1 }, /*                   ColonSign ₡ COLON SIGN */
+  { 0x20a2, 0x20a2 }, /*                CruzeiroSign ₢ CRUZEIRO SIGN */
+  { 0x20a3, 0x20a3 }, /*                  FFrancSign ₣ FRENCH FRANC SIGN */
+  { 0x20a4, 0x20a4 }, /*                    LiraSign ₤ LIRA SIGN */
+  { 0x20a5, 0x20a5 }, /*                    MillSign ₥ MILL SIGN */
+  { 0x20a6, 0x20a6 }, /*                   NairaSign ₦ NAIRA SIGN */
+  { 0x20a7, 0x20a7 }, /*                  PesetaSign ₧ PESETA SIGN */
+  { 0x20a8, 0x20a8 }, /*                   RupeeSign ₨ RUPEE SIGN */
+  { 0x20a9, 0x20a9 }, /*                     WonSign ₩ WON SIGN */
+  { 0x20aa, 0x20aa }, /*               NewSheqelSign ₪ NEW SHEQEL SIGN */
+  { 0x20ab, 0x20ab }, /*                    DongSign ₫ DONG SIGN */
+  { 0x20ac, 0x20ac }, /*                    EuroSign € EURO SIGN */
+
+
+  /* Following items added to GTK, not in the xterm table */
+
+  /* Numeric keypad */
+  
+  { 0xFF80 /* Space */, ' ' },
+  { 0xFFAA /* Multiply */, '*' },
+  { 0xFFAB /* Add */, '+' },
+  { 0xFFAC /* Separator */, ',' },
+  { 0xFFAD /* Subtract */, '-' },
+  { 0xFFAE /* Decimal */, '.' },
+  { 0xFFAF /* Divide */, '/' },
+  { 0xFFB0 /* 0 */, '0' },
+  { 0xFFB1 /* 1 */, '1' },
+  { 0xFFB2 /* 2 */, '2' },
+  { 0xFFB3 /* 3 */, '3' },
+  { 0xFFB4 /* 4 */, '4' },
+  { 0xFFB5 /* 5 */, '5' },
+  { 0xFFB6 /* 6 */, '6' },
+  { 0xFFB7 /* 7 */, '7' },
+  { 0xFFB8 /* 8 */, '8' },
+  { 0xFFB9 /* 9 */, '9' },
+  { 0xFFBD /* Equal */, '=' },  
+
+  /* End numeric keypad */
+};
+
+/**
+ * clutter_keysym_to_unicode:
+ * @keyval: a clutter key symbol 
+ * 
+ * Convert from a GDK key symbol to the corresponding ISO10646 (Unicode)
+ * character.
+ * 
+ * Return value: the corresponding unicode character, or 0 if there
+ *               is no corresponding character.
+ **/
+guint32
+clutter_keysym_to_unicode (guint keyval)
+{
+  int min = 0;
+  int max = G_N_ELEMENTS (clutter_keysym_to_unicode_tab) - 1;
+  int mid;
+
+  /* First check for Latin-1 characters (1:1 mapping) */
+  if ((keyval >= 0x0020 && keyval <= 0x007e) ||
+      (keyval >= 0x00a0 && keyval <= 0x00ff))
+    return keyval;
+
+  /* Also check for directly encoded 24-bit UCS characters:
+   */
+  if ((keyval & 0xff000000) == 0x01000000)
+    return keyval & 0x00ffffff;
+
+  /* binary search in table */
+  while (max >= min) {
+    mid = (min + max) / 2;
+    if (clutter_keysym_to_unicode_tab[mid].keysym < keyval)
+      min = mid + 1;
+    else if (clutter_keysym_to_unicode_tab[mid].keysym > keyval)
+      max = mid - 1;
+    else {
+      /* found it */
+      return clutter_keysym_to_unicode_tab[mid].ucs;
+    }
+  }
+  /* No matching Unicode value found */
+  return 0;
+}
+
diff --git a/clutter/clutter-event.h b/clutter/clutter-event.h
new file mode 100644 (file)
index 0000000..7e0d7da
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _HAVE_CLUTTER_EVENT_H
+#define _HAVE_CLUTTER_EVENT_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+
+enum
+{
+  /* Map to xlibs masks */
+  CLUTTER_BUTTON1_MASK = (1<<8),
+  CLUTTER_BUTTON2_MASK = (1<<9),
+  CLUTTER_BUTTON3_MASK = (1<<10),
+  CLUTTER_BUTTON4_MASK = (1<<11),
+  CLUTTER_BUTTON5_MASK = (1<<12)
+};
+
+typedef enum 
+{
+  CLUTTER_KEY_PRESS,
+  CLUTTER_KEY_RELEASE,
+  CLUTTER_MOTION,
+  CLUTTER_BUTTON_PRESS,
+  CLUTTER_2BUTTON_PRESS,       /* Double click */
+  CLUTTER_BUTTON_RELEASE
+} ClutterEventType;
+
+typedef union _ClutterEvent ClutterEvent;
+
+typedef struct _ClutterKeyEvent    ClutterKeyEvent;
+typedef struct _ClutterButtonEvent ClutterButtonEvent;
+typedef struct _ClutterMotionEvent ClutterMotionEvent;
+
+typedef struct _ClutterInputDevice ClutterInputDevice;
+
+struct _ClutterKeyEvent
+{
+  ClutterEventType type;
+  guint32          time;
+  guint            modifier_state;
+  guint            keyval;
+  guint16          hardware_keycode;
+};
+
+struct _ClutterButtonEvent
+{
+  ClutterEventType     type;
+  guint32              time;
+  gint                 x;
+  gint                 y;
+  guint32              modifier_state;
+  guint32              button;
+  gdouble             *axes;   /* Future use */
+  ClutterInputDevice *device;  /* Future use */
+};
+
+struct _ClutterMotionEvent
+{
+  ClutterEventType     type;
+  guint32              time;
+  gint                 x;
+  gint                 y;
+  guint32              modifier_state;
+  gdouble             *axes;   /* Future use */
+  ClutterInputDevice *device;  /* Future use */
+};
+
+union _ClutterEvent
+{
+  ClutterEventType   type;
+  
+  ClutterKeyEvent    key_event;
+  ClutterButtonEvent button_event;
+  ClutterMotionEvent motion_event;
+};
+
+ClutterEventType
+clutter_key_event_type (ClutterKeyEvent *keyev);
+
+guint32
+clutter_key_event_time (ClutterKeyEvent *keyev);
+
+guint
+clutter_key_event_state (ClutterKeyEvent *keyev);
+
+guint
+clutter_key_event_symbol (ClutterKeyEvent *keyev);
+
+guint16
+clutter_key_event_code (ClutterKeyEvent *keyev);
+
+guint32
+clutter_key_event_unicode (ClutterKeyEvent *keyev);
+
+guint32
+clutter_keysym_to_unicode (guint keyval);
+
+G_END_DECLS
+
+#endif
diff --git a/clutter/clutter-group.c b/clutter/clutter-group.c
new file mode 100644 (file)
index 0000000..5fc3dbc
--- /dev/null
@@ -0,0 +1,481 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include <stdarg.h>
+
+#include "clutter-group.h"
+#include "clutter-main.h"
+
+G_DEFINE_TYPE (ClutterGroup, clutter_group, CLUTTER_TYPE_ELEMENT);
+
+#define CLUTTER_GROUP_GET_PRIVATE(obj) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_GROUP, ClutterGroupPrivate))
+
+struct _ClutterGroupPrivate
+{
+  GList *children;
+};
+
+static void
+clutter_group_paint (ClutterElement *element)
+{
+  ClutterGroup *self = CLUTTER_GROUP(element);
+  GList      *child_item;
+
+  child_item = self->priv->children;
+
+  glPushMatrix();
+
+  /* Translate if parent ( i.e not stage window ).
+  */
+  if (clutter_element_get_parent(element) != NULL)
+    {
+      ClutterGeometry geom;      
+
+      clutter_element_get_geometry (element, &geom);
+
+      if (geom.x != 0 && geom.y != 0)
+       glTranslatef(geom.x, geom.y, 0.0);
+
+    }
+
+  if (child_item)
+    {
+      do 
+       {
+         ClutterElement *child = CLUTTER_ELEMENT(child_item->data);
+             
+         if (CLUTTER_ELEMENT_IS_MAPPED (child))
+           {
+             clutter_element_paint(child);
+           }
+       }
+      while ((child_item = g_list_next(child_item)) != NULL);
+    }
+
+  glPopMatrix();
+}
+
+static void
+clutter_group_request_coords (ClutterElement    *self,
+                             ClutterElementBox *box)
+{
+  /* FIXME: what to do here ?
+   *        o clip if smaller ?
+   *        o scale each element ? 
+  */
+}
+
+static void
+clutter_group_allocate_coords (ClutterElement    *self,
+                              ClutterElementBox *box)
+{
+  ClutterGroupPrivate *priv;
+  GList               *child_item;
+
+  priv = CLUTTER_GROUP(self)->priv;
+
+  child_item = priv->children;
+
+  if (child_item)
+    {
+      do 
+       {
+         ClutterElement *child = CLUTTER_ELEMENT(child_item->data);
+             
+         if (CLUTTER_ELEMENT_IS_VISIBLE (child))
+           {
+             ClutterElementBox cbox;
+
+             clutter_element_allocate_coords (child, &cbox);
+             
+             /*
+             if (box->x1 == 0 || cbox.x1 < box->x1)
+               box->x1 = cbox.x1;
+
+             if (box->y1 == 0 || cbox.y1 < box->y1)
+               box->y1 = cbox.y1;
+             */                
+
+             if (box->x2 == 0 || cbox.x2 > box->x2)
+               box->x2 = cbox.x2;
+
+             if (box->y2 == 0 || cbox.y2 < box->y2)
+               box->y2 = cbox.y2;
+           }
+       }
+      while ((child_item = g_list_next(child_item)) != NULL);
+    }
+}
+
+static void 
+clutter_group_dispose (GObject *object)
+{
+  ClutterGroup *self = CLUTTER_GROUP(object); 
+
+  if (self->priv)
+    {
+      /* FIXME: Do we need to actually free anything here ?
+       *        Children ref us so this wont get called till
+       *        they are all removed.
+      */
+    }
+
+  G_OBJECT_CLASS (clutter_group_parent_class)->dispose (object);
+}
+
+
+static void 
+clutter_group_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (clutter_group_parent_class)->finalize (object);
+}
+
+static void
+clutter_group_class_init (ClutterGroupClass *klass)
+{
+  GObjectClass        *object_class = G_OBJECT_CLASS (klass);
+  ClutterElementClass *element_class = CLUTTER_ELEMENT_CLASS (klass);
+
+  element_class->paint      = clutter_group_paint;
+  /*
+  element_class->show       = clutter_group_show_all;
+  element_class->hide       = clutter_group_hide_all;
+  */
+  element_class->request_coords  = clutter_group_request_coords;
+  element_class->allocate_coords = clutter_group_allocate_coords;
+
+  /* GObject */
+  object_class->finalize     = clutter_group_finalize;
+  object_class->dispose      = clutter_group_dispose;
+
+  g_type_class_add_private (object_class, sizeof (ClutterGroupPrivate));
+}
+
+static void
+clutter_group_init (ClutterGroup *self)
+{
+  self->priv = CLUTTER_GROUP_GET_PRIVATE (self);
+}
+
+/**
+ * clutter_group_new:
+ *
+ * Create a new  #ClutterGroup instance.
+ *
+ * returns a new #ClutterGroup
+ **/
+ClutterGroup*
+clutter_group_new (void)
+{
+  return g_object_new (CLUTTER_TYPE_GROUP, NULL);
+}
+
+/**
+ * clutter_group_get_children:
+ * @self: A #ClutterGroup
+ * 
+ * Get a list containing all elements contained in the group.
+ * 
+ * Return value: A GList containing child #ClutterElements.
+ **/
+GList*
+clutter_group_get_children (ClutterGroup *self)
+{
+  g_return_val_if_fail (CLUTTER_IS_GROUP (self), NULL);
+
+  return g_list_copy(self->priv->children);
+}
+
+/**
+ * clutter_group_forall:
+ * @self: A #ClutterGroup
+ * @callback: a callback
+ * @user_data: callback user data 
+ * 
+ * Invokes callback on each child of the group.
+ **/
+void
+clutter_group_foreach (ClutterGroup      *self,
+                      ClutterCallback   callback,
+                      gpointer          user_data)
+{
+  ClutterElement *child;
+  GList          *children;
+
+  g_return_if_fail (CLUTTER_IS_GROUP (self));
+  g_return_if_fail (callback != NULL);
+
+  children = self->priv->children;
+
+  while (children)
+    {
+      child = children->data;
+
+      (*callback) (child, user_data);
+
+      children = g_list_next(children);
+    }
+}
+
+/**
+ * clutter_group_show_all:
+ * @self: A #ClutterGroup
+ * 
+ * Show all child elements of the group. Note, does not recurse.
+ **/
+void
+clutter_group_show_all (ClutterGroup *self)
+{
+  g_return_if_fail (CLUTTER_IS_GROUP (self));
+
+  clutter_element_show(CLUTTER_ELEMENT(self));
+
+  g_list_foreach (self->priv->children,
+                 (GFunc)clutter_element_show,
+                 NULL);
+}
+
+/**
+ * clutter_group_hide_all:
+ * @self: A #ClutterGroup
+ * 
+ * Hide all child elements of the group. Note, does not recurse.
+ **/
+void
+clutter_group_hide_all (ClutterGroup *self)
+{
+  g_return_if_fail (CLUTTER_IS_GROUP (self));
+
+  clutter_element_hide(CLUTTER_ELEMENT(self));
+
+  g_list_foreach (self->priv->children,
+                 (GFunc)clutter_element_hide,
+                 NULL);
+}
+
+/**
+ * clutter_group_add:
+ * @self: A #ClutterGroup
+ * @element: A #ClutterElement 
+ *
+ * Add a new child #ClutterElement to the #ClutterGroup.
+ **/
+void
+clutter_group_add (ClutterGroup *self, ClutterElement *element)
+{
+  g_return_if_fail (CLUTTER_IS_GROUP (self));
+  g_return_if_fail (CLUTTER_IS_ELEMENT (element));
+
+  self->priv->children = g_list_append (self->priv->children, element);
+  /* below refs */
+  clutter_element_set_parent (element, CLUTTER_ELEMENT(self));
+
+  /* FIXME: Force Sort any Z ordering, or set to 0 ? */
+  if (clutter_element_get_depth (element) != 0)
+    clutter_element_set_depth (element, clutter_element_get_depth (element));
+}
+
+/**
+ * clutter_group_add_manyv:
+ * @self: a #ClutterGroup
+ * @first_element: the #ClutterElement element to add to the group
+ * @args: the elements to be added
+ *
+ * Similar to clutter_group_add_many() but using a va_list.  Use this
+ * function inside bindings.
+ */
+void
+clutter_group_add_many_valist (ClutterGroup   *group,
+                              ClutterElement *first_element,
+                              va_list         args)
+{
+  ClutterElement *element;
+  
+  g_return_if_fail (CLUTTER_IS_GROUP (group));
+  g_return_if_fail (CLUTTER_IS_ELEMENT (first_element));
+
+  element = first_element;
+  while (element)
+    {
+      clutter_group_add (group, element);
+      element = va_arg (args, ClutterElement *);
+    }
+}
+
+/**
+ * clutter_group_add_many:
+ * @self: A #ClutterGroup
+ * @first_element: the #ClutterElement element to add to the group
+ * @Varargs: additional elements to add to the group
+ *
+ * Adds a NULL-terminated list of elements to a group.  This function is
+ * equivalent to calling clutter_group_add() for each member of the list.
+ */
+void
+clutter_group_add_many (ClutterGroup   *self,
+                       ClutterElement *first_element,
+                       ...)
+{
+  va_list args;
+
+  va_start (args, first_element);
+  clutter_group_add_many_valist (self, first_element, args);
+  va_end (args);
+}
+
+/**
+ * clutter_group_remove
+ * @self: A #ClutterGroup
+ * @element: A #ClutterElement 
+ *
+ * Remove a child #ClutterElement from the #ClutterGroup.
+ **/
+void
+clutter_group_remove (ClutterGroup *self, ClutterElement *element)
+{
+  g_return_if_fail (CLUTTER_IS_GROUP (self));
+  g_return_if_fail (CLUTTER_IS_ELEMENT (element));
+
+  /* FIXME: Check we actually are a child ? */
+  self->priv->children = g_list_remove (self->priv->children, element);
+  clutter_element_set_parent (element, NULL);
+}
+
+/**
+ * clutter_group_remove_all:
+ * @self: A #ClutterGroup
+ *
+ * Remove all child #ClutterElement from the #ClutterGroup.
+ **/
+void
+clutter_group_remove_all (ClutterGroup *self)
+{
+  GList *child_item;
+
+  g_return_if_fail (CLUTTER_IS_GROUP (self));
+
+  child_item = self->priv->children;
+
+  if (child_item)
+    {
+      do 
+       {
+         clutter_group_remove (self, CLUTTER_ELEMENT(child_item->data));
+       }
+      while ((child_item = g_list_next(child_item)) != NULL);
+    }
+}
+
+/**
+ * clutter_group_find_child_by_id:
+ * @self: A #ClutterGroup
+ * @id: A unique #Clutterelement ID
+ *
+ * Finds a child element of a group by its unique ID. Search recurses
+ * into any child groups. 
+ **/
+ClutterElement*
+clutter_group_find_child_by_id (ClutterGroup *self, guint id)
+{
+  ClutterElement *element = NULL, *inner_element;
+  GList          *child_item;
+
+  g_return_val_if_fail (CLUTTER_IS_GROUP (self), NULL);
+
+  if (clutter_element_get_id (CLUTTER_ELEMENT(self)) == id)
+    return CLUTTER_ELEMENT(self);
+
+  child_item = self->priv->children;
+
+  if (child_item)
+    {
+      do 
+       {
+         inner_element = (ClutterElement*)child_item->data;
+
+         if (clutter_element_get_id (inner_element) == id)
+           return inner_element;
+         
+         if (CLUTTER_IS_GROUP(inner_element))
+           {
+             element = 
+               clutter_group_find_child_by_id (CLUTTER_GROUP(inner_element), 
+                                               id);
+             if (element)
+               return element;
+           }
+
+       }
+      while ((child_item = g_list_next(child_item)) != NULL);
+    }
+
+  return element;
+}
+
+void
+clutter_group_raise (ClutterGroup     *self,
+                    ClutterElement *element, 
+                    ClutterElement *sibling)
+{
+  ClutterGroupPrivate *priv;
+  gint               pos;
+
+  g_return_if_fail (element != sibling);
+
+  priv = self->priv;
+
+  pos = g_list_index (priv->children, element) + 1;
+
+  priv->children = g_list_remove (priv->children, element); 
+
+  if (sibling == NULL)
+    priv->children = g_list_append (priv->children, element);
+  else
+    priv->children = g_list_insert (priv->children, element, pos);
+}
+
+void
+clutter_group_lower (ClutterGroup     *self,
+                    ClutterElement *element, 
+                    ClutterElement *sibling)
+{
+  ClutterGroupPrivate *priv;
+  gint               pos;
+
+  g_return_if_fail (element != sibling);
+
+  priv = self->priv;
+
+  pos = g_list_index (priv->children, element) - 1;
+
+  priv->children = g_list_remove (priv->children, element); 
+
+  if (sibling == NULL)
+    priv->children = g_list_prepend (priv->children, element);
+  else
+    priv->children = g_list_insert (priv->children, element, pos);
+}
diff --git a/clutter/clutter-group.h b/clutter/clutter-group.h
new file mode 100644 (file)
index 0000000..25dd7d6
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _HAVE_CLUTTER_GROUP_H
+#define _HAVE_CLUTTER_GROUP_H
+
+#include <glib-object.h>
+#include <clutter/clutter-element.h>
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_GROUP clutter_group_get_type()
+
+#define CLUTTER_GROUP(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+  CLUTTER_TYPE_GROUP, ClutterGroup))
+
+#define CLUTTER_GROUP_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), \
+  CLUTTER_TYPE_GROUP, ClutterGroupClass))
+
+#define CLUTTER_IS_GROUP(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+  CLUTTER_TYPE_GROUP))
+
+#define CLUTTER_IS_GROUP_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+  CLUTTER_TYPE_GROUP))
+
+#define CLUTTER_GROUP_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+  CLUTTER_TYPE_GROUP, ClutterGroupClass))
+
+typedef struct _ClutterGroupPrivate ClutterGroupPrivate;
+typedef struct _ClutterGroup        ClutterGroup;
+typedef struct _ClutterGroupClass   ClutterGroupClass;
+struct _ClutterGroup
+{
+  ClutterElement          parent;
+
+  /*< private >*/
+  ClutterGroupPrivate      *priv;
+};
+
+struct _ClutterGroupClass
+{
+  /*< private >*/
+  ClutterElementClass     parent_class;
+
+  void (*_clutter_group_1) (void);
+  void (*_clutter_group_2) (void);
+  void (*_clutter_group_3) (void);
+  void (*_clutter_group_4) (void);
+  void (*_clutter_group_5) (void);
+  void (*_clutter_group_6) (void);
+};
+
+GType clutter_group_get_type (void);
+
+ClutterGroup *clutter_group_new (void);
+
+GList*
+clutter_group_get_children (ClutterGroup *self);
+
+void
+clutter_group_foreach (ClutterGroup      *self,
+                      ClutterCallback   callback,
+                      gpointer          user_data);
+
+void
+clutter_group_add (ClutterGroup *group, ClutterElement *element); 
+
+void
+clutter_group_add_many_valist (ClutterGroup   *group,
+                              ClutterElement *first_element,
+                              va_list         args);
+
+void
+clutter_group_add_many (ClutterGroup   *group,
+                       ClutterElement *first_element,
+                       ...) G_GNUC_NULL_TERMINATED;
+
+void
+clutter_group_remove (ClutterGroup *group, ClutterElement *element); 
+
+void
+clutter_group_show_all (ClutterGroup *self);
+
+void
+clutter_group_hide_all (ClutterGroup *self);
+
+ClutterElement*
+clutter_group_find_child_by_id (ClutterGroup *self, guint id);
+
+void
+clutter_group_raise (ClutterGroup     *self,
+                    ClutterElement *element, 
+                    ClutterElement *sibling);
+
+void
+clutter_group_lower (ClutterGroup     *self,
+                    ClutterElement *element, 
+                    ClutterElement *sibling);
+
+G_END_DECLS
+
+#endif
diff --git a/clutter/clutter-keysyms.h b/clutter/clutter-keysyms.h
new file mode 100644 (file)
index 0000000..b5b0d9d
--- /dev/null
@@ -0,0 +1,1374 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __CLUTTER_KEYSYMS_H__
+#define __CLUTTER_KEYSYMS_H__
+
+/* This file based on GDK's gdkkeysyms.h which in turn
+ * I think is from xlibs keysymdef.h
+*/
+
+#define CLUTTER_VoidSymbol 0xFFFFFF
+#define CLUTTER_BackSpace 0xFF08
+#define CLUTTER_Tab 0xFF09
+#define CLUTTER_Linefeed 0xFF0A
+#define CLUTTER_Clear 0xFF0B
+#define CLUTTER_Return 0xFF0D
+#define CLUTTER_Pause 0xFF13
+#define CLUTTER_Scroll_Lock 0xFF14
+#define CLUTTER_Sys_Req 0xFF15
+#define CLUTTER_Escape 0xFF1B
+#define CLUTTER_Delete 0xFFFF
+#define CLUTTER_Multi_key 0xFF20
+#define CLUTTER_Codeinput 0xFF37
+#define CLUTTER_SingleCandidate 0xFF3C
+#define CLUTTER_MultipleCandidate 0xFF3D
+#define CLUTTER_PreviousCandidate 0xFF3E
+#define CLUTTER_Kanji 0xFF21
+#define CLUTTER_Muhenkan 0xFF22
+#define CLUTTER_Henkan_Mode 0xFF23
+#define CLUTTER_Henkan 0xFF23
+#define CLUTTER_Romaji 0xFF24
+#define CLUTTER_Hiragana 0xFF25
+#define CLUTTER_Katakana 0xFF26
+#define CLUTTER_Hiragana_Katakana 0xFF27
+#define CLUTTER_Zenkaku 0xFF28
+#define CLUTTER_Hankaku 0xFF29
+#define CLUTTER_Zenkaku_Hankaku 0xFF2A
+#define CLUTTER_Touroku 0xFF2B
+#define CLUTTER_Massyo 0xFF2C
+#define CLUTTER_Kana_Lock 0xFF2D
+#define CLUTTER_Kana_Shift 0xFF2E
+#define CLUTTER_Eisu_Shift 0xFF2F
+#define CLUTTER_Eisu_toggle 0xFF30
+#define CLUTTER_Kanji_Bangou 0xFF37
+#define CLUTTER_Zen_Koho 0xFF3D
+#define CLUTTER_Mae_Koho 0xFF3E
+#define CLUTTER_Home 0xFF50
+#define CLUTTER_Left 0xFF51
+#define CLUTTER_Up 0xFF52
+#define CLUTTER_Right 0xFF53
+#define CLUTTER_Down 0xFF54
+#define CLUTTER_Prior 0xFF55
+#define CLUTTER_Page_Up 0xFF55
+#define CLUTTER_Next 0xFF56
+#define CLUTTER_Page_Down 0xFF56
+#define CLUTTER_End 0xFF57
+#define CLUTTER_Begin 0xFF58
+#define CLUTTER_Select 0xFF60
+#define CLUTTER_Print 0xFF61
+#define CLUTTER_Execute 0xFF62
+#define CLUTTER_Insert 0xFF63
+#define CLUTTER_Undo 0xFF65
+#define CLUTTER_Redo 0xFF66
+#define CLUTTER_Menu 0xFF67
+#define CLUTTER_Find 0xFF68
+#define CLUTTER_Cancel 0xFF69
+#define CLUTTER_Help 0xFF6A
+#define CLUTTER_Break 0xFF6B
+#define CLUTTER_Mode_switch 0xFF7E
+#define CLUTTER_script_switch 0xFF7E
+#define CLUTTER_Num_Lock 0xFF7F
+#define CLUTTER_KP_Space 0xFF80
+#define CLUTTER_KP_Tab 0xFF89
+#define CLUTTER_KP_Enter 0xFF8D
+#define CLUTTER_KP_F1 0xFF91
+#define CLUTTER_KP_F2 0xFF92
+#define CLUTTER_KP_F3 0xFF93
+#define CLUTTER_KP_F4 0xFF94
+#define CLUTTER_KP_Home 0xFF95
+#define CLUTTER_KP_Left 0xFF96
+#define CLUTTER_KP_Up 0xFF97
+#define CLUTTER_KP_Right 0xFF98
+#define CLUTTER_KP_Down 0xFF99
+#define CLUTTER_KP_Prior 0xFF9A
+#define CLUTTER_KP_Page_Up 0xFF9A
+#define CLUTTER_KP_Next 0xFF9B
+#define CLUTTER_KP_Page_Down 0xFF9B
+#define CLUTTER_KP_End 0xFF9C
+#define CLUTTER_KP_Begin 0xFF9D
+#define CLUTTER_KP_Insert 0xFF9E
+#define CLUTTER_KP_Delete 0xFF9F
+#define CLUTTER_KP_Equal 0xFFBD
+#define CLUTTER_KP_Multiply 0xFFAA
+#define CLUTTER_KP_Add 0xFFAB
+#define CLUTTER_KP_Separator 0xFFAC
+#define CLUTTER_KP_Subtract 0xFFAD
+#define CLUTTER_KP_Decimal 0xFFAE
+#define CLUTTER_KP_Divide 0xFFAF
+#define CLUTTER_KP_0 0xFFB0
+#define CLUTTER_KP_1 0xFFB1
+#define CLUTTER_KP_2 0xFFB2
+#define CLUTTER_KP_3 0xFFB3
+#define CLUTTER_KP_4 0xFFB4
+#define CLUTTER_KP_5 0xFFB5
+#define CLUTTER_KP_6 0xFFB6
+#define CLUTTER_KP_7 0xFFB7
+#define CLUTTER_KP_8 0xFFB8
+#define CLUTTER_KP_9 0xFFB9
+#define CLUTTER_F1 0xFFBE
+#define CLUTTER_F2 0xFFBF
+#define CLUTTER_F3 0xFFC0
+#define CLUTTER_F4 0xFFC1
+#define CLUTTER_F5 0xFFC2
+#define CLUTTER_F6 0xFFC3
+#define CLUTTER_F7 0xFFC4
+#define CLUTTER_F8 0xFFC5
+#define CLUTTER_F9 0xFFC6
+#define CLUTTER_F10 0xFFC7
+#define CLUTTER_F11 0xFFC8
+#define CLUTTER_L1 0xFFC8
+#define CLUTTER_F12 0xFFC9
+#define CLUTTER_L2 0xFFC9
+#define CLUTTER_F13 0xFFCA
+#define CLUTTER_L3 0xFFCA
+#define CLUTTER_F14 0xFFCB
+#define CLUTTER_L4 0xFFCB
+#define CLUTTER_F15 0xFFCC
+#define CLUTTER_L5 0xFFCC
+#define CLUTTER_F16 0xFFCD
+#define CLUTTER_L6 0xFFCD
+#define CLUTTER_F17 0xFFCE
+#define CLUTTER_L7 0xFFCE
+#define CLUTTER_F18 0xFFCF
+#define CLUTTER_L8 0xFFCF
+#define CLUTTER_F19 0xFFD0
+#define CLUTTER_L9 0xFFD0
+#define CLUTTER_F20 0xFFD1
+#define CLUTTER_L10 0xFFD1
+#define CLUTTER_F21 0xFFD2
+#define CLUTTER_R1 0xFFD2
+#define CLUTTER_F22 0xFFD3
+#define CLUTTER_R2 0xFFD3
+#define CLUTTER_F23 0xFFD4
+#define CLUTTER_R3 0xFFD4
+#define CLUTTER_F24 0xFFD5
+#define CLUTTER_R4 0xFFD5
+#define CLUTTER_F25 0xFFD6
+#define CLUTTER_R5 0xFFD6
+#define CLUTTER_F26 0xFFD7
+#define CLUTTER_R6 0xFFD7
+#define CLUTTER_F27 0xFFD8
+#define CLUTTER_R7 0xFFD8
+#define CLUTTER_F28 0xFFD9
+#define CLUTTER_R8 0xFFD9
+#define CLUTTER_F29 0xFFDA
+#define CLUTTER_R9 0xFFDA
+#define CLUTTER_F30 0xFFDB
+#define CLUTTER_R10 0xFFDB
+#define CLUTTER_F31 0xFFDC
+#define CLUTTER_R11 0xFFDC
+#define CLUTTER_F32 0xFFDD
+#define CLUTTER_R12 0xFFDD
+#define CLUTTER_F33 0xFFDE
+#define CLUTTER_R13 0xFFDE
+#define CLUTTER_F34 0xFFDF
+#define CLUTTER_R14 0xFFDF
+#define CLUTTER_F35 0xFFE0
+#define CLUTTER_R15 0xFFE0
+#define CLUTTER_Shift_L 0xFFE1
+#define CLUTTER_Shift_R 0xFFE2
+#define CLUTTER_Control_L 0xFFE3
+#define CLUTTER_Control_R 0xFFE4
+#define CLUTTER_Caps_Lock 0xFFE5
+#define CLUTTER_Shift_Lock 0xFFE6
+#define CLUTTER_Meta_L 0xFFE7
+#define CLUTTER_Meta_R 0xFFE8
+#define CLUTTER_Alt_L 0xFFE9
+#define CLUTTER_Alt_R 0xFFEA
+#define CLUTTER_Super_L 0xFFEB
+#define CLUTTER_Super_R 0xFFEC
+#define CLUTTER_Hyper_L 0xFFED
+#define CLUTTER_Hyper_R 0xFFEE
+#define CLUTTER_ISO_Lock 0xFE01
+#define CLUTTER_ISO_Level2_Latch 0xFE02
+#define CLUTTER_ISO_Level3_Shift 0xFE03
+#define CLUTTER_ISO_Level3_Latch 0xFE04
+#define CLUTTER_ISO_Level3_Lock 0xFE05
+#define CLUTTER_ISO_Group_Shift 0xFF7E
+#define CLUTTER_ISO_Group_Latch 0xFE06
+#define CLUTTER_ISO_Group_Lock 0xFE07
+#define CLUTTER_ISO_Next_Group 0xFE08
+#define CLUTTER_ISO_Next_Group_Lock 0xFE09
+#define CLUTTER_ISO_Prev_Group 0xFE0A
+#define CLUTTER_ISO_Prev_Group_Lock 0xFE0B
+#define CLUTTER_ISO_First_Group 0xFE0C
+#define CLUTTER_ISO_First_Group_Lock 0xFE0D
+#define CLUTTER_ISO_Last_Group 0xFE0E
+#define CLUTTER_ISO_Last_Group_Lock 0xFE0F
+#define CLUTTER_ISO_Left_Tab 0xFE20
+#define CLUTTER_ISO_Move_Line_Up 0xFE21
+#define CLUTTER_ISO_Move_Line_Down 0xFE22
+#define CLUTTER_ISO_Partial_Line_Up 0xFE23
+#define CLUTTER_ISO_Partial_Line_Down 0xFE24
+#define CLUTTER_ISO_Partial_Space_Left 0xFE25
+#define CLUTTER_ISO_Partial_Space_Right 0xFE26
+#define CLUTTER_ISO_Set_Margin_Left 0xFE27
+#define CLUTTER_ISO_Set_Margin_Right 0xFE28
+#define CLUTTER_ISO_Release_Margin_Left 0xFE29
+#define CLUTTER_ISO_Release_Margin_Right 0xFE2A
+#define CLUTTER_ISO_Release_Both_Margins 0xFE2B
+#define CLUTTER_ISO_Fast_Cursor_Left 0xFE2C
+#define CLUTTER_ISO_Fast_Cursor_Right 0xFE2D
+#define CLUTTER_ISO_Fast_Cursor_Up 0xFE2E
+#define CLUTTER_ISO_Fast_Cursor_Down 0xFE2F
+#define CLUTTER_ISO_Continuous_Underline 0xFE30
+#define CLUTTER_ISO_Discontinuous_Underline 0xFE31
+#define CLUTTER_ISO_Emphasize 0xFE32
+#define CLUTTER_ISO_Center_Object 0xFE33
+#define CLUTTER_ISO_Enter 0xFE34
+#define CLUTTER_dead_grave 0xFE50
+#define CLUTTER_dead_acute 0xFE51
+#define CLUTTER_dead_circumflex 0xFE52
+#define CLUTTER_dead_tilde 0xFE53
+#define CLUTTER_dead_macron 0xFE54
+#define CLUTTER_dead_breve 0xFE55
+#define CLUTTER_dead_abovedot 0xFE56
+#define CLUTTER_dead_diaeresis 0xFE57
+#define CLUTTER_dead_abovering 0xFE58
+#define CLUTTER_dead_doubleacute 0xFE59
+#define CLUTTER_dead_caron 0xFE5A
+#define CLUTTER_dead_cedilla 0xFE5B
+#define CLUTTER_dead_ogonek 0xFE5C
+#define CLUTTER_dead_iota 0xFE5D
+#define CLUTTER_dead_voiced_sound 0xFE5E
+#define CLUTTER_dead_semivoiced_sound 0xFE5F
+#define CLUTTER_dead_belowdot 0xFE60
+#define CLUTTER_dead_hook 0xFE61
+#define CLUTTER_dead_horn 0xFE62
+#define CLUTTER_First_Virtual_Screen 0xFED0
+#define CLUTTER_Prev_Virtual_Screen 0xFED1
+#define CLUTTER_Next_Virtual_Screen 0xFED2
+#define CLUTTER_Last_Virtual_Screen 0xFED4
+#define CLUTTER_Terminate_Server 0xFED5
+#define CLUTTER_AccessX_Enable 0xFE70
+#define CLUTTER_AccessX_Feedback_Enable 0xFE71
+#define CLUTTER_RepeatKeys_Enable 0xFE72
+#define CLUTTER_SlowKeys_Enable 0xFE73
+#define CLUTTER_BounceKeys_Enable 0xFE74
+#define CLUTTER_StickyKeys_Enable 0xFE75
+#define CLUTTER_MouseKeys_Enable 0xFE76
+#define CLUTTER_MouseKeys_Accel_Enable 0xFE77
+#define CLUTTER_Overlay1_Enable 0xFE78
+#define CLUTTER_Overlay2_Enable 0xFE79
+#define CLUTTER_AudibleBell_Enable 0xFE7A
+#define CLUTTER_Pointer_Left 0xFEE0
+#define CLUTTER_Pointer_Right 0xFEE1
+#define CLUTTER_Pointer_Up 0xFEE2
+#define CLUTTER_Pointer_Down 0xFEE3
+#define CLUTTER_Pointer_UpLeft 0xFEE4
+#define CLUTTER_Pointer_UpRight 0xFEE5
+#define CLUTTER_Pointer_DownLeft 0xFEE6
+#define CLUTTER_Pointer_DownRight 0xFEE7
+#define CLUTTER_Pointer_Button_Dflt 0xFEE8
+#define CLUTTER_Pointer_Button1 0xFEE9
+#define CLUTTER_Pointer_Button2 0xFEEA
+#define CLUTTER_Pointer_Button3 0xFEEB
+#define CLUTTER_Pointer_Button4 0xFEEC
+#define CLUTTER_Pointer_Button5 0xFEED
+#define CLUTTER_Pointer_DblClick_Dflt 0xFEEE
+#define CLUTTER_Pointer_DblClick1 0xFEEF
+#define CLUTTER_Pointer_DblClick2 0xFEF0
+#define CLUTTER_Pointer_DblClick3 0xFEF1
+#define CLUTTER_Pointer_DblClick4 0xFEF2
+#define CLUTTER_Pointer_DblClick5 0xFEF3
+#define CLUTTER_Pointer_Drag_Dflt 0xFEF4
+#define CLUTTER_Pointer_Drag1 0xFEF5
+#define CLUTTER_Pointer_Drag2 0xFEF6
+#define CLUTTER_Pointer_Drag3 0xFEF7
+#define CLUTTER_Pointer_Drag4 0xFEF8
+#define CLUTTER_Pointer_Drag5 0xFEFD
+#define CLUTTER_Pointer_EnableKeys 0xFEF9
+#define CLUTTER_Pointer_Accelerate 0xFEFA
+#define CLUTTER_Pointer_DfltBtnNext 0xFEFB
+#define CLUTTER_Pointer_DfltBtnPrev 0xFEFC
+#define CLUTTER_3270_Duplicate 0xFD01
+#define CLUTTER_3270_FieldMark 0xFD02
+#define CLUTTER_3270_Right2 0xFD03
+#define CLUTTER_3270_Left2 0xFD04
+#define CLUTTER_3270_BackTab 0xFD05
+#define CLUTTER_3270_EraseEOF 0xFD06
+#define CLUTTER_3270_EraseInput 0xFD07
+#define CLUTTER_3270_Reset 0xFD08
+#define CLUTTER_3270_Quit 0xFD09
+#define CLUTTER_3270_PA1 0xFD0A
+#define CLUTTER_3270_PA2 0xFD0B
+#define CLUTTER_3270_PA3 0xFD0C
+#define CLUTTER_3270_Test 0xFD0D
+#define CLUTTER_3270_Attn 0xFD0E
+#define CLUTTER_3270_CursorBlink 0xFD0F
+#define CLUTTER_3270_AltCursor 0xFD10
+#define CLUTTER_3270_KeyClick 0xFD11
+#define CLUTTER_3270_Jump 0xFD12
+#define CLUTTER_3270_Ident 0xFD13
+#define CLUTTER_3270_Rule 0xFD14
+#define CLUTTER_3270_Copy 0xFD15
+#define CLUTTER_3270_Play 0xFD16
+#define CLUTTER_3270_Setup 0xFD17
+#define CLUTTER_3270_Record 0xFD18
+#define CLUTTER_3270_ChangeScreen 0xFD19
+#define CLUTTER_3270_DeleteWord 0xFD1A
+#define CLUTTER_3270_ExSelect 0xFD1B
+#define CLUTTER_3270_CursorSelect 0xFD1C
+#define CLUTTER_3270_PrintScreen 0xFD1D
+#define CLUTTER_3270_Enter 0xFD1E
+#define CLUTTER_space 0x020
+#define CLUTTER_exclam 0x021
+#define CLUTTER_quotedbl 0x022
+#define CLUTTER_numbersign 0x023
+#define CLUTTER_dollar 0x024
+#define CLUTTER_percent 0x025
+#define CLUTTER_ampersand 0x026
+#define CLUTTER_apostrophe 0x027
+#define CLUTTER_quoteright 0x027
+#define CLUTTER_parenleft 0x028
+#define CLUTTER_parenright 0x029
+#define CLUTTER_asterisk 0x02a
+#define CLUTTER_plus 0x02b
+#define CLUTTER_comma 0x02c
+#define CLUTTER_minus 0x02d
+#define CLUTTER_period 0x02e
+#define CLUTTER_slash 0x02f
+#define CLUTTER_0 0x030
+#define CLUTTER_1 0x031
+#define CLUTTER_2 0x032
+#define CLUTTER_3 0x033
+#define CLUTTER_4 0x034
+#define CLUTTER_5 0x035
+#define CLUTTER_6 0x036
+#define CLUTTER_7 0x037
+#define CLUTTER_8 0x038
+#define CLUTTER_9 0x039
+#define CLUTTER_colon 0x03a
+#define CLUTTER_semicolon 0x03b
+#define CLUTTER_less 0x03c
+#define CLUTTER_equal 0x03d
+#define CLUTTER_greater 0x03e
+#define CLUTTER_question 0x03f
+#define CLUTTER_at 0x040
+#define CLUTTER_A 0x041
+#define CLUTTER_B 0x042
+#define CLUTTER_C 0x043
+#define CLUTTER_D 0x044
+#define CLUTTER_E 0x045
+#define CLUTTER_F 0x046
+#define CLUTTER_G 0x047
+#define CLUTTER_H 0x048
+#define CLUTTER_I 0x049
+#define CLUTTER_J 0x04a
+#define CLUTTER_K 0x04b
+#define CLUTTER_L 0x04c
+#define CLUTTER_M 0x04d
+#define CLUTTER_N 0x04e
+#define CLUTTER_O 0x04f
+#define CLUTTER_P 0x050
+#define CLUTTER_Q 0x051
+#define CLUTTER_R 0x052
+#define CLUTTER_S 0x053
+#define CLUTTER_T 0x054
+#define CLUTTER_U 0x055
+#define CLUTTER_V 0x056
+#define CLUTTER_W 0x057
+#define CLUTTER_X 0x058
+#define CLUTTER_Y 0x059
+#define CLUTTER_Z 0x05a
+#define CLUTTER_bracketleft 0x05b
+#define CLUTTER_backslash 0x05c
+#define CLUTTER_bracketright 0x05d
+#define CLUTTER_asciicircum 0x05e
+#define CLUTTER_underscore 0x05f
+#define CLUTTER_grave 0x060
+#define CLUTTER_quoteleft 0x060
+#define CLUTTER_a 0x061
+#define CLUTTER_b 0x062
+#define CLUTTER_c 0x063
+#define CLUTTER_d 0x064
+#define CLUTTER_e 0x065
+#define CLUTTER_f 0x066
+#define CLUTTER_g 0x067
+#define CLUTTER_h 0x068
+#define CLUTTER_i 0x069
+#define CLUTTER_j 0x06a
+#define CLUTTER_k 0x06b
+#define CLUTTER_l 0x06c
+#define CLUTTER_m 0x06d
+#define CLUTTER_n 0x06e
+#define CLUTTER_o 0x06f
+#define CLUTTER_p 0x070
+#define CLUTTER_q 0x071
+#define CLUTTER_r 0x072
+#define CLUTTER_s 0x073
+#define CLUTTER_t 0x074
+#define CLUTTER_u 0x075
+#define CLUTTER_v 0x076
+#define CLUTTER_w 0x077
+#define CLUTTER_x 0x078
+#define CLUTTER_y 0x079
+#define CLUTTER_z 0x07a
+#define CLUTTER_braceleft 0x07b
+#define CLUTTER_bar 0x07c
+#define CLUTTER_braceright 0x07d
+#define CLUTTER_asciitilde 0x07e
+#define CLUTTER_nobreakspace 0x0a0
+#define CLUTTER_exclamdown 0x0a1
+#define CLUTTER_cent 0x0a2
+#define CLUTTER_sterling 0x0a3
+#define CLUTTER_currency 0x0a4
+#define CLUTTER_yen 0x0a5
+#define CLUTTER_brokenbar 0x0a6
+#define CLUTTER_section 0x0a7
+#define CLUTTER_diaeresis 0x0a8
+#define CLUTTER_copyright 0x0a9
+#define CLUTTER_ordfeminine 0x0aa
+#define CLUTTER_guillemotleft 0x0ab
+#define CLUTTER_notsign 0x0ac
+#define CLUTTER_hyphen 0x0ad
+#define CLUTTER_registered 0x0ae
+#define CLUTTER_macron 0x0af
+#define CLUTTER_degree 0x0b0
+#define CLUTTER_plusminus 0x0b1
+#define CLUTTER_twosuperior 0x0b2
+#define CLUTTER_threesuperior 0x0b3
+#define CLUTTER_acute 0x0b4
+#define CLUTTER_mu 0x0b5
+#define CLUTTER_paragraph 0x0b6
+#define CLUTTER_periodcentered 0x0b7
+#define CLUTTER_cedilla 0x0b8
+#define CLUTTER_onesuperior 0x0b9
+#define CLUTTER_masculine 0x0ba
+#define CLUTTER_guillemotright 0x0bb
+#define CLUTTER_onequarter 0x0bc
+#define CLUTTER_onehalf 0x0bd
+#define CLUTTER_threequarters 0x0be
+#define CLUTTER_questiondown 0x0bf
+#define CLUTTER_Agrave 0x0c0
+#define CLUTTER_Aacute 0x0c1
+#define CLUTTER_Acircumflex 0x0c2
+#define CLUTTER_Atilde 0x0c3
+#define CLUTTER_Adiaeresis 0x0c4
+#define CLUTTER_Aring 0x0c5
+#define CLUTTER_AE 0x0c6
+#define CLUTTER_Ccedilla 0x0c7
+#define CLUTTER_Egrave 0x0c8
+#define CLUTTER_Eacute 0x0c9
+#define CLUTTER_Ecircumflex 0x0ca
+#define CLUTTER_Ediaeresis 0x0cb
+#define CLUTTER_Igrave 0x0cc
+#define CLUTTER_Iacute 0x0cd
+#define CLUTTER_Icircumflex 0x0ce
+#define CLUTTER_Idiaeresis 0x0cf
+#define CLUTTER_ETH 0x0d0
+#define CLUTTER_Eth 0x0d0
+#define CLUTTER_Ntilde 0x0d1
+#define CLUTTER_Ograve 0x0d2
+#define CLUTTER_Oacute 0x0d3
+#define CLUTTER_Ocircumflex 0x0d4
+#define CLUTTER_Otilde 0x0d5
+#define CLUTTER_Odiaeresis 0x0d6
+#define CLUTTER_multiply 0x0d7
+#define CLUTTER_Ooblique 0x0d8
+#define CLUTTER_Ugrave 0x0d9
+#define CLUTTER_Uacute 0x0da
+#define CLUTTER_Ucircumflex 0x0db
+#define CLUTTER_Udiaeresis 0x0dc
+#define CLUTTER_Yacute 0x0dd
+#define CLUTTER_THORN 0x0de
+#define CLUTTER_Thorn 0x0de
+#define CLUTTER_ssharp 0x0df
+#define CLUTTER_agrave 0x0e0
+#define CLUTTER_aacute 0x0e1
+#define CLUTTER_acircumflex 0x0e2
+#define CLUTTER_atilde 0x0e3
+#define CLUTTER_adiaeresis 0x0e4
+#define CLUTTER_aring 0x0e5
+#define CLUTTER_ae 0x0e6
+#define CLUTTER_ccedilla 0x0e7
+#define CLUTTER_egrave 0x0e8
+#define CLUTTER_eacute 0x0e9
+#define CLUTTER_ecircumflex 0x0ea
+#define CLUTTER_ediaeresis 0x0eb
+#define CLUTTER_igrave 0x0ec
+#define CLUTTER_iacute 0x0ed
+#define CLUTTER_icircumflex 0x0ee
+#define CLUTTER_idiaeresis 0x0ef
+#define CLUTTER_eth 0x0f0
+#define CLUTTER_ntilde 0x0f1
+#define CLUTTER_ograve 0x0f2
+#define CLUTTER_oacute 0x0f3
+#define CLUTTER_ocircumflex 0x0f4
+#define CLUTTER_otilde 0x0f5
+#define CLUTTER_odiaeresis 0x0f6
+#define CLUTTER_division 0x0f7
+#define CLUTTER_oslash 0x0f8
+#define CLUTTER_ugrave 0x0f9
+#define CLUTTER_uacute 0x0fa
+#define CLUTTER_ucircumflex 0x0fb
+#define CLUTTER_udiaeresis 0x0fc
+#define CLUTTER_yacute 0x0fd
+#define CLUTTER_thorn 0x0fe
+#define CLUTTER_ydiaeresis 0x0ff
+#define CLUTTER_Aogonek 0x1a1
+#define CLUTTER_breve 0x1a2
+#define CLUTTER_Lstroke 0x1a3
+#define CLUTTER_Lcaron 0x1a5
+#define CLUTTER_Sacute 0x1a6
+#define CLUTTER_Scaron 0x1a9
+#define CLUTTER_Scedilla 0x1aa
+#define CLUTTER_Tcaron 0x1ab
+#define CLUTTER_Zacute 0x1ac
+#define CLUTTER_Zcaron 0x1ae
+#define CLUTTER_Zabovedot 0x1af
+#define CLUTTER_aogonek 0x1b1
+#define CLUTTER_ogonek 0x1b2
+#define CLUTTER_lstroke 0x1b3
+#define CLUTTER_lcaron 0x1b5
+#define CLUTTER_sacute 0x1b6
+#define CLUTTER_caron 0x1b7
+#define CLUTTER_scaron 0x1b9
+#define CLUTTER_scedilla 0x1ba
+#define CLUTTER_tcaron 0x1bb
+#define CLUTTER_zacute 0x1bc
+#define CLUTTER_doubleacute 0x1bd
+#define CLUTTER_zcaron 0x1be
+#define CLUTTER_zabovedot 0x1bf
+#define CLUTTER_Racute 0x1c0
+#define CLUTTER_Abreve 0x1c3
+#define CLUTTER_Lacute 0x1c5
+#define CLUTTER_Cacute 0x1c6
+#define CLUTTER_Ccaron 0x1c8
+#define CLUTTER_Eogonek 0x1ca
+#define CLUTTER_Ecaron 0x1cc
+#define CLUTTER_Dcaron 0x1cf
+#define CLUTTER_Dstroke 0x1d0
+#define CLUTTER_Nacute 0x1d1
+#define CLUTTER_Ncaron 0x1d2
+#define CLUTTER_Odoubleacute 0x1d5
+#define CLUTTER_Rcaron 0x1d8
+#define CLUTTER_Uring 0x1d9
+#define CLUTTER_Udoubleacute 0x1db
+#define CLUTTER_Tcedilla 0x1de
+#define CLUTTER_racute 0x1e0
+#define CLUTTER_abreve 0x1e3
+#define CLUTTER_lacute 0x1e5
+#define CLUTTER_cacute 0x1e6
+#define CLUTTER_ccaron 0x1e8
+#define CLUTTER_eogonek 0x1ea
+#define CLUTTER_ecaron 0x1ec
+#define CLUTTER_dcaron 0x1ef
+#define CLUTTER_dstroke 0x1f0
+#define CLUTTER_nacute 0x1f1
+#define CLUTTER_ncaron 0x1f2
+#define CLUTTER_odoubleacute 0x1f5
+#define CLUTTER_udoubleacute 0x1fb
+#define CLUTTER_rcaron 0x1f8
+#define CLUTTER_uring 0x1f9
+#define CLUTTER_tcedilla 0x1fe
+#define CLUTTER_abovedot 0x1ff
+#define CLUTTER_Hstroke 0x2a1
+#define CLUTTER_Hcircumflex 0x2a6
+#define CLUTTER_Iabovedot 0x2a9
+#define CLUTTER_Gbreve 0x2ab
+#define CLUTTER_Jcircumflex 0x2ac
+#define CLUTTER_hstroke 0x2b1
+#define CLUTTER_hcircumflex 0x2b6
+#define CLUTTER_idotless 0x2b9
+#define CLUTTER_gbreve 0x2bb
+#define CLUTTER_jcircumflex 0x2bc
+#define CLUTTER_Cabovedot 0x2c5
+#define CLUTTER_Ccircumflex 0x2c6
+#define CLUTTER_Gabovedot 0x2d5
+#define CLUTTER_Gcircumflex 0x2d8
+#define CLUTTER_Ubreve 0x2dd
+#define CLUTTER_Scircumflex 0x2de
+#define CLUTTER_cabovedot 0x2e5
+#define CLUTTER_ccircumflex 0x2e6
+#define CLUTTER_gabovedot 0x2f5
+#define CLUTTER_gcircumflex 0x2f8
+#define CLUTTER_ubreve 0x2fd
+#define CLUTTER_scircumflex 0x2fe
+#define CLUTTER_kra 0x3a2
+#define CLUTTER_kappa 0x3a2
+#define CLUTTER_Rcedilla 0x3a3
+#define CLUTTER_Itilde 0x3a5
+#define CLUTTER_Lcedilla 0x3a6
+#define CLUTTER_Emacron 0x3aa
+#define CLUTTER_Gcedilla 0x3ab
+#define CLUTTER_Tslash 0x3ac
+#define CLUTTER_rcedilla 0x3b3
+#define CLUTTER_itilde 0x3b5
+#define CLUTTER_lcedilla 0x3b6
+#define CLUTTER_emacron 0x3ba
+#define CLUTTER_gcedilla 0x3bb
+#define CLUTTER_tslash 0x3bc
+#define CLUTTER_ENG 0x3bd
+#define CLUTTER_eng 0x3bf
+#define CLUTTER_Amacron 0x3c0
+#define CLUTTER_Iogonek 0x3c7
+#define CLUTTER_Eabovedot 0x3cc
+#define CLUTTER_Imacron 0x3cf
+#define CLUTTER_Ncedilla 0x3d1
+#define CLUTTER_Omacron 0x3d2
+#define CLUTTER_Kcedilla 0x3d3
+#define CLUTTER_Uogonek 0x3d9
+#define CLUTTER_Utilde 0x3dd
+#define CLUTTER_Umacron 0x3de
+#define CLUTTER_amacron 0x3e0
+#define CLUTTER_iogonek 0x3e7
+#define CLUTTER_eabovedot 0x3ec
+#define CLUTTER_imacron 0x3ef
+#define CLUTTER_ncedilla 0x3f1
+#define CLUTTER_omacron 0x3f2
+#define CLUTTER_kcedilla 0x3f3
+#define CLUTTER_uogonek 0x3f9
+#define CLUTTER_utilde 0x3fd
+#define CLUTTER_umacron 0x3fe
+#define CLUTTER_OE 0x13bc
+#define CLUTTER_oe 0x13bd
+#define CLUTTER_Ydiaeresis 0x13be
+#define CLUTTER_overline 0x47e
+#define CLUTTER_kana_fullstop 0x4a1
+#define CLUTTER_kana_openingbracket 0x4a2
+#define CLUTTER_kana_closingbracket 0x4a3
+#define CLUTTER_kana_comma 0x4a4
+#define CLUTTER_kana_conjunctive 0x4a5
+#define CLUTTER_kana_middledot 0x4a5
+#define CLUTTER_kana_WO 0x4a6
+#define CLUTTER_kana_a 0x4a7
+#define CLUTTER_kana_i 0x4a8
+#define CLUTTER_kana_u 0x4a9
+#define CLUTTER_kana_e 0x4aa
+#define CLUTTER_kana_o 0x4ab
+#define CLUTTER_kana_ya 0x4ac
+#define CLUTTER_kana_yu 0x4ad
+#define CLUTTER_kana_yo 0x4ae
+#define CLUTTER_kana_tsu 0x4af
+#define CLUTTER_kana_tu 0x4af
+#define CLUTTER_prolongedsound 0x4b0
+#define CLUTTER_kana_A 0x4b1
+#define CLUTTER_kana_I 0x4b2
+#define CLUTTER_kana_U 0x4b3
+#define CLUTTER_kana_E 0x4b4
+#define CLUTTER_kana_O 0x4b5
+#define CLUTTER_kana_KA 0x4b6
+#define CLUTTER_kana_KI 0x4b7
+#define CLUTTER_kana_KU 0x4b8
+#define CLUTTER_kana_KE 0x4b9
+#define CLUTTER_kana_KO 0x4ba
+#define CLUTTER_kana_SA 0x4bb
+#define CLUTTER_kana_SHI 0x4bc
+#define CLUTTER_kana_SU 0x4bd
+#define CLUTTER_kana_SE 0x4be
+#define CLUTTER_kana_SO 0x4bf
+#define CLUTTER_kana_TA 0x4c0
+#define CLUTTER_kana_CHI 0x4c1
+#define CLUTTER_kana_TI 0x4c1
+#define CLUTTER_kana_TSU 0x4c2
+#define CLUTTER_kana_TU 0x4c2
+#define CLUTTER_kana_TE 0x4c3
+#define CLUTTER_kana_TO 0x4c4
+#define CLUTTER_kana_NA 0x4c5
+#define CLUTTER_kana_NI 0x4c6
+#define CLUTTER_kana_NU 0x4c7
+#define CLUTTER_kana_NE 0x4c8
+#define CLUTTER_kana_NO 0x4c9
+#define CLUTTER_kana_HA 0x4ca
+#define CLUTTER_kana_HI 0x4cb
+#define CLUTTER_kana_FU 0x4cc
+#define CLUTTER_kana_HU 0x4cc
+#define CLUTTER_kana_HE 0x4cd
+#define CLUTTER_kana_HO 0x4ce
+#define CLUTTER_kana_MA 0x4cf
+#define CLUTTER_kana_MI 0x4d0
+#define CLUTTER_kana_MU 0x4d1
+#define CLUTTER_kana_ME 0x4d2
+#define CLUTTER_kana_MO 0x4d3
+#define CLUTTER_kana_YA 0x4d4
+#define CLUTTER_kana_YU 0x4d5
+#define CLUTTER_kana_YO 0x4d6
+#define CLUTTER_kana_RA 0x4d7
+#define CLUTTER_kana_RI 0x4d8
+#define CLUTTER_kana_RU 0x4d9
+#define CLUTTER_kana_RE 0x4da
+#define CLUTTER_kana_RO 0x4db
+#define CLUTTER_kana_WA 0x4dc
+#define CLUTTER_kana_N 0x4dd
+#define CLUTTER_voicedsound 0x4de
+#define CLUTTER_semivoicedsound 0x4df
+#define CLUTTER_kana_switch 0xFF7E
+#define CLUTTER_Arabic_comma 0x5ac
+#define CLUTTER_Arabic_semicolon 0x5bb
+#define CLUTTER_Arabic_question_mark 0x5bf
+#define CLUTTER_Arabic_hamza 0x5c1
+#define CLUTTER_Arabic_maddaonalef 0x5c2
+#define CLUTTER_Arabic_hamzaonalef 0x5c3
+#define CLUTTER_Arabic_hamzaonwaw 0x5c4
+#define CLUTTER_Arabic_hamzaunderalef 0x5c5
+#define CLUTTER_Arabic_hamzaonyeh 0x5c6
+#define CLUTTER_Arabic_alef 0x5c7
+#define CLUTTER_Arabic_beh 0x5c8
+#define CLUTTER_Arabic_tehmarbuta 0x5c9
+#define CLUTTER_Arabic_teh 0x5ca
+#define CLUTTER_Arabic_theh 0x5cb
+#define CLUTTER_Arabic_jeem 0x5cc
+#define CLUTTER_Arabic_hah 0x5cd
+#define CLUTTER_Arabic_khah 0x5ce
+#define CLUTTER_Arabic_dal 0x5cf
+#define CLUTTER_Arabic_thal 0x5d0
+#define CLUTTER_Arabic_ra 0x5d1
+#define CLUTTER_Arabic_zain 0x5d2
+#define CLUTTER_Arabic_seen 0x5d3
+#define CLUTTER_Arabic_sheen 0x5d4
+#define CLUTTER_Arabic_sad 0x5d5
+#define CLUTTER_Arabic_dad 0x5d6
+#define CLUTTER_Arabic_tah 0x5d7
+#define CLUTTER_Arabic_zah 0x5d8
+#define CLUTTER_Arabic_ain 0x5d9
+#define CLUTTER_Arabic_ghain 0x5da
+#define CLUTTER_Arabic_tatweel 0x5e0
+#define CLUTTER_Arabic_feh 0x5e1
+#define CLUTTER_Arabic_qaf 0x5e2
+#define CLUTTER_Arabic_kaf 0x5e3
+#define CLUTTER_Arabic_lam 0x5e4
+#define CLUTTER_Arabic_meem 0x5e5
+#define CLUTTER_Arabic_noon 0x5e6
+#define CLUTTER_Arabic_ha 0x5e7
+#define CLUTTER_Arabic_heh 0x5e7
+#define CLUTTER_Arabic_waw 0x5e8
+#define CLUTTER_Arabic_alefmaksura 0x5e9
+#define CLUTTER_Arabic_yeh 0x5ea
+#define CLUTTER_Arabic_fathatan 0x5eb
+#define CLUTTER_Arabic_dammatan 0x5ec
+#define CLUTTER_Arabic_kasratan 0x5ed
+#define CLUTTER_Arabic_fatha 0x5ee
+#define CLUTTER_Arabic_damma 0x5ef
+#define CLUTTER_Arabic_kasra 0x5f0
+#define CLUTTER_Arabic_shadda 0x5f1
+#define CLUTTER_Arabic_sukun 0x5f2
+#define CLUTTER_Arabic_switch 0xFF7E
+#define CLUTTER_Serbian_dje 0x6a1
+#define CLUTTER_Macedonia_gje 0x6a2
+#define CLUTTER_Cyrillic_io 0x6a3
+#define CLUTTER_Ukrainian_ie 0x6a4
+#define CLUTTER_Ukranian_je 0x6a4
+#define CLUTTER_Macedonia_dse 0x6a5
+#define CLUTTER_Ukrainian_i 0x6a6
+#define CLUTTER_Ukranian_i 0x6a6
+#define CLUTTER_Ukrainian_yi 0x6a7
+#define CLUTTER_Ukranian_yi 0x6a7
+#define CLUTTER_Cyrillic_je 0x6a8
+#define CLUTTER_Serbian_je 0x6a8
+#define CLUTTER_Cyrillic_lje 0x6a9
+#define CLUTTER_Serbian_lje 0x6a9
+#define CLUTTER_Cyrillic_nje 0x6aa
+#define CLUTTER_Serbian_nje 0x6aa
+#define CLUTTER_Serbian_tshe 0x6ab
+#define CLUTTER_Macedonia_kje 0x6ac
+#define CLUTTER_Ukrainian_ghe_with_upturn 0x6ad
+#define CLUTTER_Byelorussian_shortu 0x6ae
+#define CLUTTER_Cyrillic_dzhe 0x6af
+#define CLUTTER_Serbian_dze 0x6af
+#define CLUTTER_numerosign 0x6b0
+#define CLUTTER_Serbian_DJE 0x6b1
+#define CLUTTER_Macedonia_GJE 0x6b2
+#define CLUTTER_Cyrillic_IO 0x6b3
+#define CLUTTER_Ukrainian_IE 0x6b4
+#define CLUTTER_Ukranian_JE 0x6b4
+#define CLUTTER_Macedonia_DSE 0x6b5
+#define CLUTTER_Ukrainian_I 0x6b6
+#define CLUTTER_Ukranian_I 0x6b6
+#define CLUTTER_Ukrainian_YI 0x6b7
+#define CLUTTER_Ukranian_YI 0x6b7
+#define CLUTTER_Cyrillic_JE 0x6b8
+#define CLUTTER_Serbian_JE 0x6b8
+#define CLUTTER_Cyrillic_LJE 0x6b9
+#define CLUTTER_Serbian_LJE 0x6b9
+#define CLUTTER_Cyrillic_NJE 0x6ba
+#define CLUTTER_Serbian_NJE 0x6ba
+#define CLUTTER_Serbian_TSHE 0x6bb
+#define CLUTTER_Macedonia_KJE 0x6bc
+#define CLUTTER_Ukrainian_GHE_WITH_UPTURN 0x6bd
+#define CLUTTER_Byelorussian_SHORTU 0x6be
+#define CLUTTER_Cyrillic_DZHE 0x6bf
+#define CLUTTER_Serbian_DZE 0x6bf
+#define CLUTTER_Cyrillic_yu 0x6c0
+#define CLUTTER_Cyrillic_a 0x6c1
+#define CLUTTER_Cyrillic_be 0x6c2
+#define CLUTTER_Cyrillic_tse 0x6c3
+#define CLUTTER_Cyrillic_de 0x6c4
+#define CLUTTER_Cyrillic_ie 0x6c5
+#define CLUTTER_Cyrillic_ef 0x6c6
+#define CLUTTER_Cyrillic_ghe 0x6c7
+#define CLUTTER_Cyrillic_ha 0x6c8
+#define CLUTTER_Cyrillic_i 0x6c9
+#define CLUTTER_Cyrillic_shorti 0x6ca
+#define CLUTTER_Cyrillic_ka 0x6cb
+#define CLUTTER_Cyrillic_el 0x6cc
+#define CLUTTER_Cyrillic_em 0x6cd
+#define CLUTTER_Cyrillic_en 0x6ce
+#define CLUTTER_Cyrillic_o 0x6cf
+#define CLUTTER_Cyrillic_pe 0x6d0
+#define CLUTTER_Cyrillic_ya 0x6d1
+#define CLUTTER_Cyrillic_er 0x6d2
+#define CLUTTER_Cyrillic_es 0x6d3
+#define CLUTTER_Cyrillic_te 0x6d4
+#define CLUTTER_Cyrillic_u 0x6d5
+#define CLUTTER_Cyrillic_zhe 0x6d6
+#define CLUTTER_Cyrillic_ve 0x6d7
+#define CLUTTER_Cyrillic_softsign 0x6d8
+#define CLUTTER_Cyrillic_yeru 0x6d9
+#define CLUTTER_Cyrillic_ze 0x6da
+#define CLUTTER_Cyrillic_sha 0x6db
+#define CLUTTER_Cyrillic_e 0x6dc
+#define CLUTTER_Cyrillic_shcha 0x6dd
+#define CLUTTER_Cyrillic_che 0x6de
+#define CLUTTER_Cyrillic_hardsign 0x6df
+#define CLUTTER_Cyrillic_YU 0x6e0
+#define CLUTTER_Cyrillic_A 0x6e1
+#define CLUTTER_Cyrillic_BE 0x6e2
+#define CLUTTER_Cyrillic_TSE 0x6e3
+#define CLUTTER_Cyrillic_DE 0x6e4
+#define CLUTTER_Cyrillic_IE 0x6e5
+#define CLUTTER_Cyrillic_EF 0x6e6
+#define CLUTTER_Cyrillic_GHE 0x6e7
+#define CLUTTER_Cyrillic_HA 0x6e8
+#define CLUTTER_Cyrillic_I 0x6e9
+#define CLUTTER_Cyrillic_SHORTI 0x6ea
+#define CLUTTER_Cyrillic_KA 0x6eb
+#define CLUTTER_Cyrillic_EL 0x6ec
+#define CLUTTER_Cyrillic_EM 0x6ed
+#define CLUTTER_Cyrillic_EN 0x6ee
+#define CLUTTER_Cyrillic_O 0x6ef
+#define CLUTTER_Cyrillic_PE 0x6f0
+#define CLUTTER_Cyrillic_YA 0x6f1
+#define CLUTTER_Cyrillic_ER 0x6f2
+#define CLUTTER_Cyrillic_ES 0x6f3
+#define CLUTTER_Cyrillic_TE 0x6f4
+#define CLUTTER_Cyrillic_U 0x6f5
+#define CLUTTER_Cyrillic_ZHE 0x6f6
+#define CLUTTER_Cyrillic_VE 0x6f7
+#define CLUTTER_Cyrillic_SOFTSIGN 0x6f8
+#define CLUTTER_Cyrillic_YERU 0x6f9
+#define CLUTTER_Cyrillic_ZE 0x6fa
+#define CLUTTER_Cyrillic_SHA 0x6fb
+#define CLUTTER_Cyrillic_E 0x6fc
+#define CLUTTER_Cyrillic_SHCHA 0x6fd
+#define CLUTTER_Cyrillic_CHE 0x6fe
+#define CLUTTER_Cyrillic_HARDSIGN 0x6ff
+#define CLUTTER_Greek_ALPHAaccent 0x7a1
+#define CLUTTER_Greek_EPSILONaccent 0x7a2
+#define CLUTTER_Greek_ETAaccent 0x7a3
+#define CLUTTER_Greek_IOTAaccent 0x7a4
+#define CLUTTER_Greek_IOTAdieresis 0x7a5
+#define CLUTTER_Greek_IOTAdiaeresis CLUTTER_Greek_IOTAdieresis
+#define CLUTTER_Greek_OMICRONaccent 0x7a7
+#define CLUTTER_Greek_UPSILONaccent 0x7a8
+#define CLUTTER_Greek_UPSILONdieresis 0x7a9
+#define CLUTTER_Greek_OMEGAaccent 0x7ab
+#define CLUTTER_Greek_accentdieresis 0x7ae
+#define CLUTTER_Greek_horizbar 0x7af
+#define CLUTTER_Greek_alphaaccent 0x7b1
+#define CLUTTER_Greek_epsilonaccent 0x7b2
+#define CLUTTER_Greek_etaaccent 0x7b3
+#define CLUTTER_Greek_iotaaccent 0x7b4
+#define CLUTTER_Greek_iotadieresis 0x7b5
+#define CLUTTER_Greek_iotaaccentdieresis 0x7b6
+#define CLUTTER_Greek_omicronaccent 0x7b7
+#define CLUTTER_Greek_upsilonaccent 0x7b8
+#define CLUTTER_Greek_upsilondieresis 0x7b9
+#define CLUTTER_Greek_upsilonaccentdieresis 0x7ba
+#define CLUTTER_Greek_omegaaccent 0x7bb
+#define CLUTTER_Greek_ALPHA 0x7c1
+#define CLUTTER_Greek_BETA 0x7c2
+#define CLUTTER_Greek_GAMMA 0x7c3
+#define CLUTTER_Greek_DELTA 0x7c4
+#define CLUTTER_Greek_EPSILON 0x7c5
+#define CLUTTER_Greek_ZETA 0x7c6
+#define CLUTTER_Greek_ETA 0x7c7
+#define CLUTTER_Greek_THETA 0x7c8
+#define CLUTTER_Greek_IOTA 0x7c9
+#define CLUTTER_Greek_KAPPA 0x7ca
+#define CLUTTER_Greek_LAMDA 0x7cb
+#define CLUTTER_Greek_LAMBDA 0x7cb
+#define CLUTTER_Greek_MU 0x7cc
+#define CLUTTER_Greek_NU 0x7cd
+#define CLUTTER_Greek_XI 0x7ce
+#define CLUTTER_Greek_OMICRON 0x7cf
+#define CLUTTER_Greek_PI 0x7d0
+#define CLUTTER_Greek_RHO 0x7d1
+#define CLUTTER_Greek_SIGMA 0x7d2
+#define CLUTTER_Greek_TAU 0x7d4
+#define CLUTTER_Greek_UPSILON 0x7d5
+#define CLUTTER_Greek_PHI 0x7d6
+#define CLUTTER_Greek_CHI 0x7d7
+#define CLUTTER_Greek_PSI 0x7d8
+#define CLUTTER_Greek_OMEGA 0x7d9
+#define CLUTTER_Greek_alpha 0x7e1
+#define CLUTTER_Greek_beta 0x7e2
+#define CLUTTER_Greek_gamma 0x7e3
+#define CLUTTER_Greek_delta 0x7e4
+#define CLUTTER_Greek_epsilon 0x7e5
+#define CLUTTER_Greek_zeta 0x7e6
+#define CLUTTER_Greek_eta 0x7e7
+#define CLUTTER_Greek_theta 0x7e8
+#define CLUTTER_Greek_iota 0x7e9
+#define CLUTTER_Greek_kappa 0x7ea
+#define CLUTTER_Greek_lamda 0x7eb
+#define CLUTTER_Greek_lambda 0x7eb
+#define CLUTTER_Greek_mu 0x7ec
+#define CLUTTER_Greek_nu 0x7ed
+#define CLUTTER_Greek_xi 0x7ee
+#define CLUTTER_Greek_omicron 0x7ef
+#define CLUTTER_Greek_pi 0x7f0
+#define CLUTTER_Greek_rho 0x7f1
+#define CLUTTER_Greek_sigma 0x7f2
+#define CLUTTER_Greek_finalsmallsigma 0x7f3
+#define CLUTTER_Greek_tau 0x7f4
+#define CLUTTER_Greek_upsilon 0x7f5
+#define CLUTTER_Greek_phi 0x7f6
+#define CLUTTER_Greek_chi 0x7f7
+#define CLUTTER_Greek_psi 0x7f8
+#define CLUTTER_Greek_omega 0x7f9
+#define CLUTTER_Greek_switch 0xFF7E
+#define CLUTTER_leftradical 0x8a1
+#define CLUTTER_topleftradical 0x8a2
+#define CLUTTER_horizconnector 0x8a3
+#define CLUTTER_topintegral 0x8a4
+#define CLUTTER_botintegral 0x8a5
+#define CLUTTER_vertconnector 0x8a6
+#define CLUTTER_topleftsqbracket 0x8a7
+#define CLUTTER_botleftsqbracket 0x8a8
+#define CLUTTER_toprightsqbracket 0x8a9
+#define CLUTTER_botrightsqbracket 0x8aa
+#define CLUTTER_topleftparens 0x8ab
+#define CLUTTER_botleftparens 0x8ac
+#define CLUTTER_toprightparens 0x8ad
+#define CLUTTER_botrightparens 0x8ae
+#define CLUTTER_leftmiddlecurlybrace 0x8af
+#define CLUTTER_rightmiddlecurlybrace 0x8b0
+#define CLUTTER_topleftsummation 0x8b1
+#define CLUTTER_botleftsummation 0x8b2
+#define CLUTTER_topvertsummationconnector 0x8b3
+#define CLUTTER_botvertsummationconnector 0x8b4
+#define CLUTTER_toprightsummation 0x8b5
+#define CLUTTER_botrightsummation 0x8b6
+#define CLUTTER_rightmiddlesummation 0x8b7
+#define CLUTTER_lessthanequal 0x8bc
+#define CLUTTER_notequal 0x8bd
+#define CLUTTER_greaterthanequal 0x8be
+#define CLUTTER_integral 0x8bf
+#define CLUTTER_therefore 0x8c0
+#define CLUTTER_variation 0x8c1
+#define CLUTTER_infinity 0x8c2
+#define CLUTTER_nabla 0x8c5
+#define CLUTTER_approximate 0x8c8
+#define CLUTTER_similarequal 0x8c9
+#define CLUTTER_ifonlyif 0x8cd
+#define CLUTTER_implies 0x8ce
+#define CLUTTER_identical 0x8cf
+#define CLUTTER_radical 0x8d6
+#define CLUTTER_includedin 0x8da
+#define CLUTTER_includes 0x8db
+#define CLUTTER_intersection 0x8dc
+#define CLUTTER_union 0x8dd
+#define CLUTTER_logicaland 0x8de
+#define CLUTTER_logicalor 0x8df
+#define CLUTTER_partialderivative 0x8ef
+#define CLUTTER_function 0x8f6
+#define CLUTTER_leftarrow 0x8fb
+#define CLUTTER_uparrow 0x8fc
+#define CLUTTER_rightarrow 0x8fd
+#define CLUTTER_downarrow 0x8fe
+#define CLUTTER_blank 0x9df
+#define CLUTTER_soliddiamond 0x9e0
+#define CLUTTER_checkerboard 0x9e1
+#define CLUTTER_ht 0x9e2
+#define CLUTTER_ff 0x9e3
+#define CLUTTER_cr 0x9e4
+#define CLUTTER_lf 0x9e5
+#define CLUTTER_nl 0x9e8
+#define CLUTTER_vt 0x9e9
+#define CLUTTER_lowrightcorner 0x9ea
+#define CLUTTER_uprightcorner 0x9eb
+#define CLUTTER_upleftcorner 0x9ec
+#define CLUTTER_lowleftcorner 0x9ed
+#define CLUTTER_crossinglines 0x9ee
+#define CLUTTER_horizlinescan1 0x9ef
+#define CLUTTER_horizlinescan3 0x9f0
+#define CLUTTER_horizlinescan5 0x9f1
+#define CLUTTER_horizlinescan7 0x9f2
+#define CLUTTER_horizlinescan9 0x9f3
+#define CLUTTER_leftt 0x9f4
+#define CLUTTER_rightt 0x9f5
+#define CLUTTER_bott 0x9f6
+#define CLUTTER_topt 0x9f7
+#define CLUTTER_vertbar 0x9f8
+#define CLUTTER_emspace 0xaa1
+#define CLUTTER_enspace 0xaa2
+#define CLUTTER_em3space 0xaa3
+#define CLUTTER_em4space 0xaa4
+#define CLUTTER_digitspace 0xaa5
+#define CLUTTER_punctspace 0xaa6
+#define CLUTTER_thinspace 0xaa7
+#define CLUTTER_hairspace 0xaa8
+#define CLUTTER_emdash 0xaa9
+#define CLUTTER_endash 0xaaa
+#define CLUTTER_signifblank 0xaac
+#define CLUTTER_ellipsis 0xaae
+#define CLUTTER_doubbaselinedot 0xaaf
+#define CLUTTER_onethird 0xab0
+#define CLUTTER_twothirds 0xab1
+#define CLUTTER_onefifth 0xab2
+#define CLUTTER_twofifths 0xab3
+#define CLUTTER_threefifths 0xab4
+#define CLUTTER_fourfifths 0xab5
+#define CLUTTER_onesixth 0xab6
+#define CLUTTER_fivesixths 0xab7
+#define CLUTTER_careof 0xab8
+#define CLUTTER_figdash 0xabb
+#define CLUTTER_leftanglebracket 0xabc
+#define CLUTTER_decimalpoint 0xabd
+#define CLUTTER_rightanglebracket 0xabe
+#define CLUTTER_marker 0xabf
+#define CLUTTER_oneeighth 0xac3
+#define CLUTTER_threeeighths 0xac4
+#define CLUTTER_fiveeighths 0xac5
+#define CLUTTER_seveneighths 0xac6
+#define CLUTTER_trademark 0xac9
+#define CLUTTER_signaturemark 0xaca
+#define CLUTTER_trademarkincircle 0xacb
+#define CLUTTER_leftopentriangle 0xacc
+#define CLUTTER_rightopentriangle 0xacd
+#define CLUTTER_emopencircle 0xace
+#define CLUTTER_emopenrectangle 0xacf
+#define CLUTTER_leftsinglequotemark 0xad0
+#define CLUTTER_rightsinglequotemark 0xad1
+#define CLUTTER_leftdoublequotemark 0xad2
+#define CLUTTER_rightdoublequotemark 0xad3
+#define CLUTTER_prescription 0xad4
+#define CLUTTER_minutes 0xad6
+#define CLUTTER_seconds 0xad7
+#define CLUTTER_latincross 0xad9
+#define CLUTTER_hexagram 0xada
+#define CLUTTER_filledrectbullet 0xadb
+#define CLUTTER_filledlefttribullet 0xadc
+#define CLUTTER_filledrighttribullet 0xadd
+#define CLUTTER_emfilledcircle 0xade
+#define CLUTTER_emfilledrect 0xadf
+#define CLUTTER_enopencircbullet 0xae0
+#define CLUTTER_enopensquarebullet 0xae1
+#define CLUTTER_openrectbullet 0xae2
+#define CLUTTER_opentribulletup 0xae3
+#define CLUTTER_opentribulletdown 0xae4
+#define CLUTTER_openstar 0xae5
+#define CLUTTER_enfilledcircbullet 0xae6
+#define CLUTTER_enfilledsqbullet 0xae7
+#define CLUTTER_filledtribulletup 0xae8
+#define CLUTTER_filledtribulletdown 0xae9
+#define CLUTTER_leftpointer 0xaea
+#define CLUTTER_rightpointer 0xaeb
+#define CLUTTER_club 0xaec
+#define CLUTTER_diamond 0xaed
+#define CLUTTER_heart 0xaee
+#define CLUTTER_maltesecross 0xaf0
+#define CLUTTER_dagger 0xaf1
+#define CLUTTER_doubledagger 0xaf2
+#define CLUTTER_checkmark 0xaf3
+#define CLUTTER_ballotcross 0xaf4
+#define CLUTTER_musicalsharp 0xaf5
+#define CLUTTER_musicalflat 0xaf6
+#define CLUTTER_malesymbol 0xaf7
+#define CLUTTER_femalesymbol 0xaf8
+#define CLUTTER_telephone 0xaf9
+#define CLUTTER_telephonerecorder 0xafa
+#define CLUTTER_phonographcopyright 0xafb
+#define CLUTTER_caret 0xafc
+#define CLUTTER_singlelowquotemark 0xafd
+#define CLUTTER_doublelowquotemark 0xafe
+#define CLUTTER_cursor 0xaff
+#define CLUTTER_leftcaret 0xba3
+#define CLUTTER_rightcaret 0xba6
+#define CLUTTER_downcaret 0xba8
+#define CLUTTER_upcaret 0xba9
+#define CLUTTER_overbar 0xbc0
+#define CLUTTER_downtack 0xbc2
+#define CLUTTER_upshoe 0xbc3
+#define CLUTTER_downstile 0xbc4
+#define CLUTTER_underbar 0xbc6
+#define CLUTTER_jot 0xbca
+#define CLUTTER_quad 0xbcc
+#define CLUTTER_uptack 0xbce
+#define CLUTTER_circle 0xbcf
+#define CLUTTER_upstile 0xbd3
+#define CLUTTER_downshoe 0xbd6
+#define CLUTTER_rightshoe 0xbd8
+#define CLUTTER_leftshoe 0xbda
+#define CLUTTER_lefttack 0xbdc
+#define CLUTTER_righttack 0xbfc
+#define CLUTTER_hebrew_doublelowline 0xcdf
+#define CLUTTER_hebrew_aleph 0xce0
+#define CLUTTER_hebrew_bet 0xce1
+#define CLUTTER_hebrew_beth 0xce1
+#define CLUTTER_hebrew_gimel 0xce2
+#define CLUTTER_hebrew_gimmel 0xce2
+#define CLUTTER_hebrew_dalet 0xce3
+#define CLUTTER_hebrew_daleth 0xce3
+#define CLUTTER_hebrew_he 0xce4
+#define CLUTTER_hebrew_waw 0xce5
+#define CLUTTER_hebrew_zain 0xce6
+#define CLUTTER_hebrew_zayin 0xce6
+#define CLUTTER_hebrew_chet 0xce7
+#define CLUTTER_hebrew_het 0xce7
+#define CLUTTER_hebrew_tet 0xce8
+#define CLUTTER_hebrew_teth 0xce8
+#define CLUTTER_hebrew_yod 0xce9
+#define CLUTTER_hebrew_finalkaph 0xcea
+#define CLUTTER_hebrew_kaph 0xceb
+#define CLUTTER_hebrew_lamed 0xcec
+#define CLUTTER_hebrew_finalmem 0xced
+#define CLUTTER_hebrew_mem 0xcee
+#define CLUTTER_hebrew_finalnun 0xcef
+#define CLUTTER_hebrew_nun 0xcf0
+#define CLUTTER_hebrew_samech 0xcf1
+#define CLUTTER_hebrew_samekh 0xcf1
+#define CLUTTER_hebrew_ayin 0xcf2
+#define CLUTTER_hebrew_finalpe 0xcf3
+#define CLUTTER_hebrew_pe 0xcf4
+#define CLUTTER_hebrew_finalzade 0xcf5
+#define CLUTTER_hebrew_finalzadi 0xcf5
+#define CLUTTER_hebrew_zade 0xcf6
+#define CLUTTER_hebrew_zadi 0xcf6
+#define CLUTTER_hebrew_qoph 0xcf7
+#define CLUTTER_hebrew_kuf 0xcf7
+#define CLUTTER_hebrew_resh 0xcf8
+#define CLUTTER_hebrew_shin 0xcf9
+#define CLUTTER_hebrew_taw 0xcfa
+#define CLUTTER_hebrew_taf 0xcfa
+#define CLUTTER_Hebrew_switch 0xFF7E
+#define CLUTTER_Thai_kokai 0xda1
+#define CLUTTER_Thai_khokhai 0xda2
+#define CLUTTER_Thai_khokhuat 0xda3
+#define CLUTTER_Thai_khokhwai 0xda4
+#define CLUTTER_Thai_khokhon 0xda5
+#define CLUTTER_Thai_khorakhang 0xda6
+#define CLUTTER_Thai_ngongu 0xda7
+#define CLUTTER_Thai_chochan 0xda8
+#define CLUTTER_Thai_choching 0xda9
+#define CLUTTER_Thai_chochang 0xdaa
+#define CLUTTER_Thai_soso 0xdab
+#define CLUTTER_Thai_chochoe 0xdac
+#define CLUTTER_Thai_yoying 0xdad
+#define CLUTTER_Thai_dochada 0xdae
+#define CLUTTER_Thai_topatak 0xdaf
+#define CLUTTER_Thai_thothan 0xdb0
+#define CLUTTER_Thai_thonangmontho 0xdb1
+#define CLUTTER_Thai_thophuthao 0xdb2
+#define CLUTTER_Thai_nonen 0xdb3
+#define CLUTTER_Thai_dodek 0xdb4
+#define CLUTTER_Thai_totao 0xdb5
+#define CLUTTER_Thai_thothung 0xdb6
+#define CLUTTER_Thai_thothahan 0xdb7
+#define CLUTTER_Thai_thothong 0xdb8
+#define CLUTTER_Thai_nonu 0xdb9
+#define CLUTTER_Thai_bobaimai 0xdba
+#define CLUTTER_Thai_popla 0xdbb
+#define CLUTTER_Thai_phophung 0xdbc
+#define CLUTTER_Thai_fofa 0xdbd
+#define CLUTTER_Thai_phophan 0xdbe
+#define CLUTTER_Thai_fofan 0xdbf
+#define CLUTTER_Thai_phosamphao 0xdc0
+#define CLUTTER_Thai_moma 0xdc1
+#define CLUTTER_Thai_yoyak 0xdc2
+#define CLUTTER_Thai_rorua 0xdc3
+#define CLUTTER_Thai_ru 0xdc4
+#define CLUTTER_Thai_loling 0xdc5
+#define CLUTTER_Thai_lu 0xdc6
+#define CLUTTER_Thai_wowaen 0xdc7
+#define CLUTTER_Thai_sosala 0xdc8
+#define CLUTTER_Thai_sorusi 0xdc9
+#define CLUTTER_Thai_sosua 0xdca
+#define CLUTTER_Thai_hohip 0xdcb
+#define CLUTTER_Thai_lochula 0xdcc
+#define CLUTTER_Thai_oang 0xdcd
+#define CLUTTER_Thai_honokhuk 0xdce
+#define CLUTTER_Thai_paiyannoi 0xdcf
+#define CLUTTER_Thai_saraa 0xdd0
+#define CLUTTER_Thai_maihanakat 0xdd1
+#define CLUTTER_Thai_saraaa 0xdd2
+#define CLUTTER_Thai_saraam 0xdd3
+#define CLUTTER_Thai_sarai 0xdd4
+#define CLUTTER_Thai_saraii 0xdd5
+#define CLUTTER_Thai_saraue 0xdd6
+#define CLUTTER_Thai_sarauee 0xdd7
+#define CLUTTER_Thai_sarau 0xdd8
+#define CLUTTER_Thai_sarauu 0xdd9
+#define CLUTTER_Thai_phinthu 0xdda
+#define CLUTTER_Thai_maihanakat_maitho 0xdde
+#define CLUTTER_Thai_baht 0xddf
+#define CLUTTER_Thai_sarae 0xde0
+#define CLUTTER_Thai_saraae 0xde1
+#define CLUTTER_Thai_sarao 0xde2
+#define CLUTTER_Thai_saraaimaimuan 0xde3
+#define CLUTTER_Thai_saraaimaimalai 0xde4
+#define CLUTTER_Thai_lakkhangyao 0xde5
+#define CLUTTER_Thai_maiyamok 0xde6
+#define CLUTTER_Thai_maitaikhu 0xde7
+#define CLUTTER_Thai_maiek 0xde8
+#define CLUTTER_Thai_maitho 0xde9
+#define CLUTTER_Thai_maitri 0xdea
+#define CLUTTER_Thai_maichattawa 0xdeb
+#define CLUTTER_Thai_thanthakhat 0xdec
+#define CLUTTER_Thai_nikhahit 0xded
+#define CLUTTER_Thai_leksun 0xdf0
+#define CLUTTER_Thai_leknung 0xdf1
+#define CLUTTER_Thai_leksong 0xdf2
+#define CLUTTER_Thai_leksam 0xdf3
+#define CLUTTER_Thai_leksi 0xdf4
+#define CLUTTER_Thai_lekha 0xdf5
+#define CLUTTER_Thai_lekhok 0xdf6
+#define CLUTTER_Thai_lekchet 0xdf7
+#define CLUTTER_Thai_lekpaet 0xdf8
+#define CLUTTER_Thai_lekkao 0xdf9
+#define CLUTTER_Hangul 0xff31
+#define CLUTTER_Hangul_Start 0xff32
+#define CLUTTER_Hangul_End 0xff33
+#define CLUTTER_Hangul_Hanja 0xff34
+#define CLUTTER_Hangul_Jamo 0xff35
+#define CLUTTER_Hangul_Romaja 0xff36
+#define CLUTTER_Hangul_Codeinput 0xff37
+#define CLUTTER_Hangul_Jeonja 0xff38
+#define CLUTTER_Hangul_Banja 0xff39
+#define CLUTTER_Hangul_PreHanja 0xff3a
+#define CLUTTER_Hangul_PostHanja 0xff3b
+#define CLUTTER_Hangul_SingleCandidate 0xff3c
+#define CLUTTER_Hangul_MultipleCandidate 0xff3d
+#define CLUTTER_Hangul_PreviousCandidate 0xff3e
+#define CLUTTER_Hangul_Special 0xff3f
+#define CLUTTER_Hangul_switch 0xFF7E
+#define CLUTTER_Hangul_Kiyeog 0xea1
+#define CLUTTER_Hangul_SsangKiyeog 0xea2
+#define CLUTTER_Hangul_KiyeogSios 0xea3
+#define CLUTTER_Hangul_Nieun 0xea4
+#define CLUTTER_Hangul_NieunJieuj 0xea5
+#define CLUTTER_Hangul_NieunHieuh 0xea6
+#define CLUTTER_Hangul_Dikeud 0xea7
+#define CLUTTER_Hangul_SsangDikeud 0xea8
+#define CLUTTER_Hangul_Rieul 0xea9
+#define CLUTTER_Hangul_RieulKiyeog 0xeaa
+#define CLUTTER_Hangul_RieulMieum 0xeab
+#define CLUTTER_Hangul_RieulPieub 0xeac
+#define CLUTTER_Hangul_RieulSios 0xead
+#define CLUTTER_Hangul_RieulTieut 0xeae
+#define CLUTTER_Hangul_RieulPhieuf 0xeaf
+#define CLUTTER_Hangul_RieulHieuh 0xeb0
+#define CLUTTER_Hangul_Mieum 0xeb1
+#define CLUTTER_Hangul_Pieub 0xeb2
+#define CLUTTER_Hangul_SsangPieub 0xeb3
+#define CLUTTER_Hangul_PieubSios 0xeb4
+#define CLUTTER_Hangul_Sios 0xeb5
+#define CLUTTER_Hangul_SsangSios 0xeb6
+#define CLUTTER_Hangul_Ieung 0xeb7
+#define CLUTTER_Hangul_Jieuj 0xeb8
+#define CLUTTER_Hangul_SsangJieuj 0xeb9
+#define CLUTTER_Hangul_Cieuc 0xeba
+#define CLUTTER_Hangul_Khieuq 0xebb
+#define CLUTTER_Hangul_Tieut 0xebc
+#define CLUTTER_Hangul_Phieuf 0xebd
+#define CLUTTER_Hangul_Hieuh 0xebe
+#define CLUTTER_Hangul_A 0xebf
+#define CLUTTER_Hangul_AE 0xec0
+#define CLUTTER_Hangul_YA 0xec1
+#define CLUTTER_Hangul_YAE 0xec2
+#define CLUTTER_Hangul_EO 0xec3
+#define CLUTTER_Hangul_E 0xec4
+#define CLUTTER_Hangul_YEO 0xec5
+#define CLUTTER_Hangul_YE 0xec6
+#define CLUTTER_Hangul_O 0xec7
+#define CLUTTER_Hangul_WA 0xec8
+#define CLUTTER_Hangul_WAE 0xec9
+#define CLUTTER_Hangul_OE 0xeca
+#define CLUTTER_Hangul_YO 0xecb
+#define CLUTTER_Hangul_U 0xecc
+#define CLUTTER_Hangul_WEO 0xecd
+#define CLUTTER_Hangul_WE 0xece
+#define CLUTTER_Hangul_WI 0xecf
+#define CLUTTER_Hangul_YU 0xed0
+#define CLUTTER_Hangul_EU 0xed1
+#define CLUTTER_Hangul_YI 0xed2
+#define CLUTTER_Hangul_I 0xed3
+#define CLUTTER_Hangul_J_Kiyeog 0xed4
+#define CLUTTER_Hangul_J_SsangKiyeog 0xed5
+#define CLUTTER_Hangul_J_KiyeogSios 0xed6
+#define CLUTTER_Hangul_J_Nieun 0xed7
+#define CLUTTER_Hangul_J_NieunJieuj 0xed8
+#define CLUTTER_Hangul_J_NieunHieuh 0xed9
+#define CLUTTER_Hangul_J_Dikeud 0xeda
+#define CLUTTER_Hangul_J_Rieul 0xedb
+#define CLUTTER_Hangul_J_RieulKiyeog 0xedc
+#define CLUTTER_Hangul_J_RieulMieum 0xedd
+#define CLUTTER_Hangul_J_RieulPieub 0xede
+#define CLUTTER_Hangul_J_RieulSios 0xedf
+#define CLUTTER_Hangul_J_RieulTieut 0xee0
+#define CLUTTER_Hangul_J_RieulPhieuf 0xee1
+#define CLUTTER_Hangul_J_RieulHieuh 0xee2
+#define CLUTTER_Hangul_J_Mieum 0xee3
+#define CLUTTER_Hangul_J_Pieub 0xee4
+#define CLUTTER_Hangul_J_PieubSios 0xee5
+#define CLUTTER_Hangul_J_Sios 0xee6
+#define CLUTTER_Hangul_J_SsangSios 0xee7
+#define CLUTTER_Hangul_J_Ieung 0xee8
+#define CLUTTER_Hangul_J_Jieuj 0xee9
+#define CLUTTER_Hangul_J_Cieuc 0xeea
+#define CLUTTER_Hangul_J_Khieuq 0xeeb
+#define CLUTTER_Hangul_J_Tieut 0xeec
+#define CLUTTER_Hangul_J_Phieuf 0xeed
+#define CLUTTER_Hangul_J_Hieuh 0xeee
+#define CLUTTER_Hangul_RieulYeorinHieuh 0xeef
+#define CLUTTER_Hangul_SunkyeongeumMieum 0xef0
+#define CLUTTER_Hangul_SunkyeongeumPieub 0xef1
+#define CLUTTER_Hangul_PanSios 0xef2
+#define CLUTTER_Hangul_KkogjiDalrinIeung 0xef3
+#define CLUTTER_Hangul_SunkyeongeumPhieuf 0xef4
+#define CLUTTER_Hangul_YeorinHieuh 0xef5
+#define CLUTTER_Hangul_AraeA 0xef6
+#define CLUTTER_Hangul_AraeAE 0xef7
+#define CLUTTER_Hangul_J_PanSios 0xef8
+#define CLUTTER_Hangul_J_KkogjiDalrinIeung 0xef9
+#define CLUTTER_Hangul_J_YeorinHieuh 0xefa
+#define CLUTTER_Korean_Won 0xeff
+#define CLUTTER_EcuSign 0x20a0
+#define CLUTTER_ColonSign 0x20a1
+#define CLUTTER_CruzeiroSign 0x20a2
+#define CLUTTER_FFrancSign 0x20a3
+#define CLUTTER_LiraSign 0x20a4
+#define CLUTTER_MillSign 0x20a5
+#define CLUTTER_NairaSign 0x20a6
+#define CLUTTER_PesetaSign 0x20a7
+#define CLUTTER_RupeeSign 0x20a8
+#define CLUTTER_WonSign 0x20a9
+#define CLUTTER_NewSheqelSign 0x20aa
+#define CLUTTER_DongSign 0x20ab
+#define CLUTTER_EuroSign 0x20ac
+
+#endif /* __CLUTTER_KEYSYMS_H__ */
diff --git a/clutter/clutter-label.c b/clutter/clutter-label.c
new file mode 100644 (file)
index 0000000..b8fe7f5
--- /dev/null
@@ -0,0 +1,419 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "clutter-label.h"
+#include "clutter-main.h"
+#include "clutter-enum-types.h"
+#include "clutter-private.h"   /* for DBG */
+
+#include <pango/pangoft2.h>
+
+G_DEFINE_TYPE (ClutterLabel, clutter_label, CLUTTER_TYPE_TEXTURE);
+
+enum
+{
+  PROP_0,
+  PROP_FONT,
+  PROP_TEXT,
+  PROP_COL
+};
+
+#define CLUTTER_LABEL_GET_PRIVATE(obj) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_LABEL, ClutterLabelPrivate))
+
+struct _ClutterLabelPrivate
+{
+  PangoLayout          *layout;
+  PangoContext         *context;
+  PangoFontDescription *desc;
+  guint32               fgcol;
+  gchar                *text;
+  gchar                *font;
+  gint                  extents_width, extents_height;
+};
+
+static void
+clutter_label_make_pixbuf (ClutterLabel *label)
+{
+  gint                 bx, by, w, h;
+  FT_Bitmap            ft_bitmap;
+  guint8 const         *ps;
+  guint8               *pd;
+  ClutterLabelPrivate  *priv;
+  ClutterTexture       *texture;
+  GdkPixbuf            *pixbuf;
+  
+  priv  = label->priv;
+
+  texture = CLUTTER_TEXTURE(label);
+
+  if (priv->layout == NULL || priv->desc == NULL || priv->text == NULL)
+    {
+      CLUTTER_DBG("*** FAIL: layout: %p , desc: %p, text %p ***",
+                 priv->layout, priv->desc, priv->text);
+      return;
+    }
+
+  pango_layout_set_font_description (priv->layout, priv->desc);
+  pango_layout_set_text (priv->layout, priv->text, -1);
+
+  if (priv->extents_width != 0)
+    {
+      CLUTTER_DBG("forcing width to '%i'", priv->extents_width);
+      pango_layout_set_width (priv->layout, PANGO_SCALE * priv->extents_width);
+      pango_layout_set_wrap  (priv->layout, PANGO_WRAP_WORD);
+    }
+
+  pango_layout_get_pixel_size (priv->layout, 
+                              &w, 
+                              &h);
+
+  if (w == 0 || h == 0)
+    return;
+
+  ft_bitmap.rows         = h;
+  ft_bitmap.width        = w;
+  ft_bitmap.pitch        = (w+3) & ~3;
+  ft_bitmap.buffer       = g_malloc0 (ft_bitmap.rows * ft_bitmap.pitch);
+  ft_bitmap.num_grays    = 256;
+  ft_bitmap.pixel_mode   = ft_pixel_mode_grays;
+  ft_bitmap.palette_mode = 0;
+  ft_bitmap.palette      = NULL;
+
+  pango_ft2_render_layout (&ft_bitmap, priv->layout, 0, 0);
+
+  pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 
+                          TRUE, 
+                          8,
+                          ft_bitmap.width, 
+                          ft_bitmap.rows);
+
+  for (by = 0; by < ft_bitmap.rows; by++) 
+    {
+      pd = gdk_pixbuf_get_pixels (pixbuf)
+       + by * gdk_pixbuf_get_rowstride (pixbuf);
+      ps = ft_bitmap.buffer + by * ft_bitmap.pitch;
+
+      for (bx = 0; bx < ft_bitmap.width; bx++) 
+       {
+         *pd++ = clutter_color_r(priv->fgcol);
+         *pd++ = clutter_color_g(priv->fgcol);
+         *pd++ = clutter_color_b(priv->fgcol);
+         *pd++ = *ps++;
+       }
+    }
+
+  g_free (ft_bitmap.buffer);
+
+  CLUTTER_DBG("Calling set_pixbuf with text : '%s' , pixb %ix%i", 
+             priv->text, w, h);
+  clutter_texture_set_pixbuf (CLUTTER_TEXTURE (label), pixbuf);
+  
+  /* Texture has the ref now */
+  g_object_unref (pixbuf); 
+}
+
+static void
+clutter_label_set_property (GObject      *object, 
+                           guint         prop_id,
+                           const GValue *value, 
+                           GParamSpec   *pspec)
+{
+  ClutterLabel        *label;
+  ClutterLabelPrivate *priv;
+
+  label = CLUTTER_LABEL(object);
+  priv = label->priv;
+
+  switch (prop_id) 
+    {
+    case PROP_FONT:
+      clutter_label_set_font (label, g_value_get_string(value));
+      break;
+    case PROP_TEXT:
+      clutter_label_set_text (label, g_value_get_string(value));
+      break;
+    case PROP_COL:
+      clutter_label_set_color (label, g_value_get_uint(value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+clutter_label_get_property (GObject    *object, 
+                           guint       prop_id,
+                           GValue     *value, 
+                           GParamSpec *pspec)
+{
+  ClutterLabel        *label;
+  ClutterLabelPrivate *priv;
+
+  label = CLUTTER_LABEL(object);
+  priv = label->priv;
+
+  switch (prop_id) 
+    {
+    case PROP_FONT:
+      g_value_set_string (value, priv->font);
+      break;
+    case PROP_TEXT:
+      g_value_set_string (value, priv->text);
+      break;
+    case PROP_COL:
+      g_value_set_uint (value, priv->fgcol);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    } 
+}
+
+
+static void 
+clutter_label_dispose (GObject *object)
+{
+  ClutterLabel         *self = CLUTTER_LABEL(object);
+  ClutterLabelPrivate  *priv;  
+
+  priv = self->priv;
+
+  if (priv)
+    {
+      if (priv->layout)
+       {
+         g_object_unref (priv->layout);
+         priv->layout = NULL;
+       }
+      if (priv->desc)
+       {
+         pango_font_description_free (priv->desc);    
+         priv->desc = NULL;
+       }
+
+      if (priv->text)
+       {
+         g_free (priv->text);
+         priv->text = NULL;
+       }
+
+      if (priv->font)
+       {
+         g_free (priv->font);
+         priv->font = NULL;
+       }
+
+      if (priv->context)
+       {
+         g_object_unref (priv->context);
+         priv->context = NULL;
+       }
+    }
+
+  G_OBJECT_CLASS (clutter_label_parent_class)->dispose (object);
+}
+
+static void 
+clutter_label_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (clutter_label_parent_class)->finalize (object);
+}
+
+static void
+clutter_label_class_init (ClutterLabelClass *klass)
+{
+  GObjectClass        *gobject_class = G_OBJECT_CLASS (klass);
+  ClutterElementClass *element_class = CLUTTER_ELEMENT_CLASS (klass);
+  ClutterTextureClass *texture_class = CLUTTER_TEXTURE_CLASS (klass);
+  ClutterElementClass *parent_class = CLUTTER_ELEMENT_CLASS (clutter_label_parent_class);
+
+  element_class->paint      = parent_class->paint;
+  element_class->realize    = parent_class->realize;
+  element_class->unrealize  = parent_class->unrealize;
+  element_class->show       = parent_class->show;
+  element_class->hide       = parent_class->hide;
+
+  gobject_class->finalize   = clutter_label_finalize;
+  gobject_class->dispose    = clutter_label_dispose;
+  gobject_class->set_property = clutter_label_set_property;
+  gobject_class->get_property = clutter_label_get_property;
+
+  g_object_class_install_property
+    (gobject_class, PROP_FONT,
+     g_param_spec_string ("font",
+                         "Font",
+                         "Pango font description",
+                         "sans 10",
+                         G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+
+  g_object_class_install_property
+    (gobject_class, PROP_TEXT,
+     g_param_spec_string ("text",
+                         "Text",
+                         "Text to render",
+                         "",
+                         G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+
+  g_object_class_install_property
+    (gobject_class, PROP_COL,
+     g_param_spec_uint ("color",
+                       "Font Colour",
+                       "Font Colour specified as 8 byte RGBA value",
+                       0,
+                       0xffffffff,
+                       0x000000ff,
+                       G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+
+  g_type_class_add_private (gobject_class, sizeof (ClutterLabelPrivate));
+}
+
+static void
+clutter_label_init (ClutterLabel *self)
+{
+  ClutterLabelPrivate *priv;
+  PangoFT2FontMap     *font_map;
+
+  self->priv = priv = CLUTTER_LABEL_GET_PRIVATE (self);
+
+  font_map = PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ());
+
+  pango_ft2_font_map_set_resolution (font_map, 96.0, 96.0);
+
+  priv->context = pango_ft2_font_map_create_context (font_map);
+
+  priv->layout  = pango_layout_new (priv->context);
+
+  /* See http://bugzilla.gnome.org/show_bug.cgi?id=143542  ?? 
+  pango_ft2_font_map_substitute_changed (font_map);
+  g_object_unref (font_map);
+  */
+}
+
+ClutterElement*
+clutter_label_new_with_text (const gchar *font_desc, const gchar *text)
+{
+  ClutterLabel *label;
+
+  label = g_object_new (CLUTTER_TYPE_LABEL, 
+                       "font", font_desc,
+                       "text", text,
+                       NULL);
+
+  return CLUTTER_ELEMENT(label);
+}
+
+ClutterElement*
+clutter_label_new (void)
+{
+  return CLUTTER_ELEMENT(g_object_new (CLUTTER_TYPE_LABEL, NULL));
+}
+
+void
+clutter_label_set_text (ClutterLabel *label, const gchar *text)
+{
+  ClutterLabelPrivate  *priv;  
+
+  g_return_if_fail (CLUTTER_IS_LABEL (label));
+
+  priv = label->priv;
+
+  if (priv->text)
+    g_free (priv->text);
+
+  priv->text = g_strdup(text);
+
+  clutter_label_make_pixbuf (label);
+
+  if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT(label)))
+    clutter_element_queue_redraw (CLUTTER_ELEMENT(label));
+}
+
+void
+clutter_label_set_font (ClutterLabel *label, const gchar *desc)
+{
+  ClutterLabelPrivate  *priv;  
+
+  g_return_if_fail (CLUTTER_IS_LABEL (label));
+
+  priv = label->priv;
+
+  if (priv->desc)
+    pango_font_description_free (priv->desc);    
+
+  if (priv->font)
+    g_free(priv->font);
+
+  priv->font = g_strdup(desc);
+
+  priv->desc = pango_font_description_from_string (desc);
+
+  if (label->priv->text && label->priv->text[0] != '\0')
+    {
+      clutter_label_make_pixbuf (label);
+
+      if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT(label)))
+       clutter_element_queue_redraw (CLUTTER_ELEMENT(label));
+    }
+}
+
+void
+clutter_label_set_text_extents (ClutterLabel *label, 
+                               gint          width,
+                               gint          height)
+{
+  /* FIXME: height extents is broken.... 
+  */
+
+  label->priv->extents_width = width;
+  label->priv->extents_height = height;
+
+  clutter_label_make_pixbuf (label);
+
+  if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT(label)))
+    clutter_element_queue_redraw (CLUTTER_ELEMENT(label));
+}
+
+void
+clutter_label_set_color (ClutterLabel *label, ClutterColor pixel)
+{
+  ClutterLabelPrivate  *priv;  
+
+  priv = label->priv;
+
+  priv->fgcol = pixel;
+
+  clutter_element_set_opacity(CLUTTER_ELEMENT(label), priv->fgcol & 0xff);
+
+  clutter_label_make_pixbuf (label);
+
+  if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT(label)))
+    clutter_element_queue_redraw (CLUTTER_ELEMENT(label));
+}
+
+
diff --git a/clutter/clutter-label.h b/clutter/clutter-label.h
new file mode 100644 (file)
index 0000000..356e3c0
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _HAVE_CLUTTER_LABEL_H
+#define _HAVE_CLUTTER_LABEL_H
+
+#include <glib-object.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <clutter/clutter-texture.h>
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_LABEL clutter_label_get_type()
+
+#define CLUTTER_LABEL(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+  CLUTTER_TYPE_LABEL, ClutterLabel))
+
+#define CLUTTER_LABEL_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), \
+  CLUTTER_TYPE_LABEL, ClutterLabelClass))
+
+#define CLUTTER_IS_LABEL(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+  CLUTTER_TYPE_LABEL))
+
+#define CLUTTER_IS_LABEL_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+  CLUTTER_TYPE_LABEL))
+
+#define CLUTTER_LABEL_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+  CLUTTER_TYPE_LABEL, ClutterLabelClass))
+
+typedef struct _ClutterLabel ClutterLabel;
+typedef struct _ClutterLabelPrivate ClutterLabelPrivate ;
+typedef struct _ClutterLabelClass ClutterLabelClass;
+
+struct _ClutterLabel
+{
+  ClutterTexture         parent;
+
+  /*< private >*/
+  ClutterLabelPrivate   *priv;
+};
+
+struct _ClutterLabelClass 
+{
+  /*< private >*/
+  ClutterTextureClass parent_class;
+
+  void (*_clutter_label_1) (void);
+  void (*_clutter_label_2) (void);
+  void (*_clutter_label_3) (void);
+  void (*_clutter_label_4) (void);
+}; 
+
+GType clutter_label_get_type (void);
+
+ClutterElement*
+clutter_label_new_with_text (const gchar *font_desc, const gchar *text);
+
+ClutterElement*
+clutter_label_new (void);
+
+void
+clutter_label_set_text (ClutterLabel *label, const gchar *text);
+
+void
+clutter_label_set_font (ClutterLabel *label, const gchar *desc);
+
+void
+clutter_label_set_color (ClutterLabel *label, guint32 pixel);
+
+void
+clutter_label_set_text_extents (ClutterLabel *label, 
+                               gint          width,
+                               gint          height);
+
+G_END_DECLS
+
+#endif
diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c
new file mode 100644 (file)
index 0000000..2b79287
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "clutter-main.h"
+#include "clutter-element.h"
+#include "clutter-stage.h"
+#include "clutter-private.h"
+
+#include <gst/gst.h>           /* for gst_init() */
+
+typedef struct 
+{
+  GSource  source;
+  Display *display;
+  GPollFD  event_poll_fd;
+} 
+ClutterXEventSource;
+
+ClutterMainContext ClutterCntx;
+
+#define GLX_SAMPLE_BUFFERS_ARB             100000
+#define GLX_SAMPLES_ARB                    100001
+
+typedef void (*ClutterXEventFunc) (XEvent *xev, gpointer user_data);
+
+static gboolean __clutter_has_debug = FALSE;
+static gboolean __clutter_has_fps   = FALSE;
+
+static gboolean  
+x_event_prepare (GSource  *source,
+                gint     *timeout)
+{
+  Display *display = ((ClutterXEventSource*)source)->display;
+
+  *timeout = -1;
+
+  return XPending (display);
+}
+
+static gboolean  
+x_event_check (GSource *source) 
+{
+  ClutterXEventSource *display_source = (ClutterXEventSource*)source;
+  gboolean         retval;
+
+  if (display_source->event_poll_fd.revents & G_IO_IN)
+    retval = XPending (display_source->display);
+  else
+    retval = FALSE;
+
+  return retval;
+}
+
+static gboolean  
+x_event_dispatch (GSource    *source,
+                 GSourceFunc callback,
+                 gpointer    user_data)
+{
+  Display *display = ((ClutterXEventSource*)source)->display;
+  ClutterXEventFunc event_func = (ClutterXEventFunc) callback;
+  
+  XEvent xev;
+
+  if (XPending (display))
+    {
+      XNextEvent (display, &xev);
+
+      if (event_func)
+       (*event_func) (&xev, user_data);
+    }
+
+  return TRUE;
+}
+
+static const GSourceFuncs x_event_funcs = {
+  x_event_prepare,
+  x_event_check,
+  x_event_dispatch,
+  NULL
+};
+
+static void
+translate_key_event (ClutterKeyEvent   *event,
+                    XEvent            *xevent)
+{
+  event->type = xevent->xany.type 
+    == KeyPress ? CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE;
+  event->time = xevent->xkey.time;
+  event->modifier_state = xevent->xkey.state; /* FIXME: handle modifiers */
+  event->hardware_keycode = xevent->xkey.keycode;
+  event->keyval = XKeycodeToKeysym(xevent->xkey.display, 
+                                  xevent->xkey.keycode,
+                                  0 ); /* FIXME: index with modifiers */
+}
+
+static void
+translate_button_event (ClutterButtonEvent   *event,
+                       XEvent               *xevent)
+{
+  /* FIXME: catch double click */
+ CLUTTER_DBG("button event at %ix%i", xevent->xbutton.x, xevent->xbutton.y);
+
+  event->type = xevent->xany.type 
+    == ButtonPress ? CLUTTER_BUTTON_PRESS : CLUTTER_BUTTON_RELEASE;
+  event->time = xevent->xbutton.time;
+  event->x = xevent->xbutton.x;
+  event->y = xevent->xbutton.y;
+  event->modifier_state = xevent->xbutton.state; /* includes button masks */
+  event->button = xevent->xbutton.button;
+}
+
+static void
+translate_motion_event (ClutterMotionEvent   *event,
+                       XEvent               *xevent)
+{
+  event->type = CLUTTER_MOTION;
+  event->time = xevent->xbutton.time;
+  event->x = xevent->xmotion.x;
+  event->y = xevent->xmotion.y;
+  event->modifier_state = xevent->xmotion.state;
+}
+
+void
+clutter_dispatch_x_event (XEvent  *xevent,
+                         gpointer data)
+{
+  ClutterMainContext *ctx = CLUTTER_CONTEXT();
+  ClutterEvent        event;
+
+  switch (xevent->type)
+    {
+    case Expose:
+      {
+       XEvent foo_xev;
+
+       /* Cheap compress */
+       while (XCheckTypedWindowEvent(ctx->xdpy, 
+                                     xevent->xexpose.window,
+                                     Expose, 
+                                     &foo_xev));
+
+       /* FIXME: need to make stage an 'element' so can que
+         * a paint direct from there rather than hack here...
+       */
+       clutter_element_queue_redraw (CLUTTER_ELEMENT(clutter_stage()));
+      }
+      break;
+    case KeyPress:
+    case KeyRelease:
+      translate_key_event ((ClutterKeyEvent*)&event, xevent);
+      g_signal_emit_by_name (clutter_stage(), "input-event", &event);
+      break;
+    case ButtonPress:
+    case ButtonRelease:
+      translate_button_event ((ClutterButtonEvent*)&event, xevent);
+      g_signal_emit_by_name (clutter_stage(), "input-event", &event);
+      break;
+    case MotionNotify:
+      translate_motion_event ((ClutterMotionEvent*)&event, xevent);
+      g_signal_emit_by_name (clutter_stage(), "input-event", &event);
+      break;
+    }
+}
+
+static void
+events_init()
+{
+  GMainContext         *gmain_context;
+  int                   connection_number;
+  GSource              *source;
+  ClutterXEventSource  *display_source;
+
+  gmain_context = g_main_context_default ();
+
+  g_main_context_ref (gmain_context);
+
+  connection_number = ConnectionNumber (ClutterCntx.xdpy);
+  
+  source = g_source_new ((GSourceFuncs *)&x_event_funcs, 
+                        sizeof (ClutterXEventSource));
+
+  display_source = (ClutterXEventSource *)source;
+
+  display_source->event_poll_fd.fd     = connection_number;
+  display_source->event_poll_fd.events = G_IO_IN;
+  display_source->display              = ClutterCntx.xdpy;
+  
+  g_source_add_poll (source, &display_source->event_poll_fd);
+  g_source_set_can_recurse (source, TRUE);
+
+  g_source_set_callback (source, 
+                        (GSourceFunc) clutter_dispatch_x_event, 
+                        NULL  /* no userdata */, NULL);
+
+  g_source_attach (source, gmain_context);
+  g_source_unref (source);
+}
+
+static gboolean
+clutter_want_fps(void)
+{
+  return __clutter_has_fps;
+}
+
+void
+clutter_redraw ()
+{
+  ClutterMainContext *ctx = CLUTTER_CONTEXT();
+  ClutterStage       *stage = CLUTTER_STAGE(clutter_stage());
+  ClutterColor        stage_color;
+  
+  static GTimer      *timer = NULL; 
+  static guint        timer_n_frames = 0;
+
+  CLUTTER_DBG("@@@ Redraw enter @@@");
+
+  clutter_threads_enter();
+
+  if (clutter_want_fps())
+    {
+      if (!timer)
+       timer = g_timer_new();
+    }
+
+  stage_color = clutter_stage_get_color (stage);
+
+  glClearColor( ( (float)clutter_color_r(stage_color) / 0xff ) * 1.0,
+               ( (float)clutter_color_g(stage_color) / 0xff ) * 1.0,
+               ( (float)clutter_color_b(stage_color) / 0xff ) * 1.0,
+               0.0 );
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  glDisable(GL_LIGHTING); 
+  glDisable(GL_DEPTH_TEST);
+
+  clutter_element_paint(CLUTTER_ELEMENT(stage));
+
+  glXSwapBuffers(ctx->xdpy, clutter_stage_get_xwindow (stage));  
+
+  if (clutter_want_fps())
+    {
+      timer_n_frames++;
+
+      if (g_timer_elapsed (timer, NULL) >= 1.0)
+       {
+         g_print ("*** FPS: %i ***\n", timer_n_frames);
+         timer_n_frames = 0;
+         g_timer_start (timer);
+       }
+    }
+
+  clutter_threads_leave();
+
+  CLUTTER_DBG("@@@ Redraw leave @@@");
+}
+
+
+void
+clutter_main()
+{
+  GMainLoop *loop;
+
+  loop = g_main_loop_new (g_main_context_default (), TRUE);
+
+  g_main_loop_run (loop);
+}
+
+void
+clutter_threads_enter(void)
+{
+  g_mutex_lock(ClutterCntx.gl_lock);
+}
+
+void
+clutter_threads_leave(void)
+{
+  g_mutex_unlock(ClutterCntx.gl_lock);
+}
+
+ClutterGroup*
+clutter_stage(void)
+{
+  return CLUTTER_GROUP(ClutterCntx.stage);
+}
+
+Display*
+clutter_xdisplay(void)
+{
+  return ClutterCntx.xdpy;
+}
+
+int
+clutter_xscreen(void)
+{
+  return ClutterCntx.xscreen;
+}
+
+Window
+clutter_root_xwindow(void)
+{
+  return ClutterCntx.xwin_root;
+}
+
+gboolean
+clutter_want_debug(void)
+{
+  return __clutter_has_debug;
+}
+
+GLXContext
+clutter_gl_context(void)
+{
+  return ClutterCntx.gl_context;
+}
+
+int
+clutter_init(int *argc, char ***argv)
+{
+  XVisualInfo  *vinfo;  
+
+  int  gl_attributes[] =
+    {
+      GLX_RGBA, 
+      GLX_DOUBLEBUFFER, 
+      GLX_RED_SIZE, 1,
+      GLX_GREEN_SIZE, 1,
+      GLX_BLUE_SIZE, 1,
+      /* GLX_DEPTH_SIZE, 1, */
+      /* GLX_DEPTH_SIZE, 32, */
+      0
+    };
+
+  if (getenv("CLUTTER_DEBUG"))
+    __clutter_has_debug = TRUE;
+
+  if (getenv("CLUTTER_SHOW_FPS"))
+    __clutter_has_fps = TRUE;
+
+  g_type_init();
+
+  if (!g_thread_supported ())
+    g_thread_init (NULL);
+
+  XInitThreads();
+
+  gst_init (argc, argv);
+
+  if ((ClutterCntx.xdpy = XOpenDisplay(getenv("DISPLAY"))) == NULL)
+    {
+      g_warning("Unable to connect to X DISPLAY.");
+      return -1;
+    }
+
+  ClutterCntx.xscreen   = DefaultScreen(ClutterCntx.xdpy);
+  ClutterCntx.xwin_root = RootWindow(ClutterCntx.xdpy, ClutterCntx.xscreen);
+
+  if ((vinfo = glXChooseVisual(ClutterCntx.xdpy, 
+                              ClutterCntx.xscreen,
+                              gl_attributes)) == NULL)
+    {
+      g_warning("Unable to find suitable GL visual.");
+      return -2;
+    }
+
+  ClutterCntx.gl_context = glXCreateContext(ClutterCntx.xdpy, vinfo, 0, True);
+
+  ClutterCntx.font_map = PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ());
+
+  pango_ft2_font_map_set_resolution (ClutterCntx.font_map, 96.0, 96.0);
+
+  ClutterCntx.gl_lock = g_mutex_new ();
+
+  ClutterCntx.stage = g_object_new (CLUTTER_TYPE_STAGE, NULL);
+
+  g_return_val_if_fail (ClutterCntx.stage != NULL, -3);
+
+  clutter_element_realize(CLUTTER_ELEMENT(ClutterCntx.stage));
+
+  events_init();
+
+  return 1;
+}
+
diff --git a/clutter/clutter-main.h b/clutter/clutter-main.h
new file mode 100644 (file)
index 0000000..1c493d3
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _HAVE_CLUTTER_MAIN_H
+#define _HAVE_CLUTTER_MAIN_H
+
+#include <clutter/clutter-element.h>
+#include <clutter/clutter-stage.h>
+
+#include <X11/Xlib.h>
+
+#include <GL/glx.h>
+#include <GL/gl.h>
+
+#define CLUTTER_HAS_DEBUG_MESSGES 1
+
+#if (CLUTTER_HAS_DEBUG_MESSGES)
+
+#define CLUTTER_DBG(x, a...) \
+ if (clutter_want_debug())   \
+   { g_printerr ( __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a); }
+
+#define CLUTTER_GLERR()                                        \
+ if (clutter_want_debug())                                     \
+ {                                                             \
+  GLenum err = glGetError ();  /* Roundtrip */                \
+  if (err != GL_NO_ERROR)                                      \
+    {                                                          \
+      g_printerr (__FILE__ ": GL Error: %x [at %s:%d]\n",      \
+                 err, __func__, __LINE__);                    \
+    }                                                          \
+ }
+#else
+#define CLUTTER_DBG(x, a...) do {} while (0)
+#define CLUTTER_GLERR()      do {} while (0)
+#endif /* CLUTTER_HAS_DEBUG */
+
+#define CLUTTER_MARK() CLUTTER_DBG("mark")
+
+int
+clutter_init (int *argc, char ***argv);
+
+void
+clutter_main(void);
+
+ClutterGroup*
+clutter_stage(void);
+
+void
+clutter_redraw ();
+
+Display*
+clutter_xdisplay (void);
+
+int
+clutter_xscreen (void);
+
+Window
+clutter_root_xwindow (void);
+
+GLXContext
+clutter_gl_context (void);
+
+gboolean
+clutter_want_debug (void);
+
+void
+clutter_threads_enter (void);
+
+void
+clutter_threads_leave (void);
+
+
+#endif
diff --git a/clutter/clutter-marshal.list b/clutter/clutter-marshal.list
new file mode 100644 (file)
index 0000000..435c9ac
--- /dev/null
@@ -0,0 +1,4 @@
+VOID:INT64,INT64,FLOAT,BOOLEAN
+VOID:STRING,BOOLEAN,BOOLEAN
+VOID:INT,INT
+
diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h
new file mode 100644 (file)
index 0000000..5ebea0b
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _HAVE_CLUTTER_PRIVATE_H
+#define _HAVE_CLUTTER_PRIVATE_H
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+
+#include <GL/glx.h>
+#include <GL/gl.h>
+
+#include <glib.h>
+
+#include <pango/pangoft2.h>
+
+
+typedef struct ClutterMainContext
+{
+  Display          *xdpy;
+  Window            xwin_root;
+  int               xscreen;
+  GC                xgc;
+  PangoFT2FontMap *font_map;
+  GLXContext       gl_context;
+  GMutex          *gl_lock;
+  guint            update_idle;
+  ClutterStage    *stage;
+} 
+ClutterMainContext;
+
+#define CLUTTER_CONTEXT() &ClutterCntx
+
+#endif
diff --git a/clutter/clutter-rectangle.c b/clutter/clutter-rectangle.c
new file mode 100644 (file)
index 0000000..47207dd
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "clutter-rectangle.h"
+#include "clutter-main.h"
+#include "clutter-private.h"   /* for DBG */
+
+#include <GL/glx.h>
+#include <GL/gl.h>
+
+G_DEFINE_TYPE (ClutterRectangle, clutter_rectangle, CLUTTER_TYPE_ELEMENT);
+
+enum
+{
+  PROP_0,
+  PROP_COL
+
+  /* FIXME: Add gradient, rounded corner props etc */
+};
+
+#define CLUTTER_RECTANGLE_GET_PRIVATE(obj) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_RECTANGLE, ClutterRectanglePrivate))
+
+struct _ClutterRectanglePrivate
+{
+  guint32                  col;
+};
+
+static void
+clutter_rectangle_paint (ClutterElement *self)
+{
+  ClutterRectangle        *rectangle = CLUTTER_RECTANGLE(self);
+  ClutterRectanglePrivate *priv;
+  ClutterGeometry          geom;
+
+  rectangle = CLUTTER_RECTANGLE(self);
+  priv = rectangle->priv;
+
+  glPushMatrix();
+
+  glEnable(GL_BLEND);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+  clutter_element_get_geometry (self, &geom);
+
+  glColor4ub(clutter_color_r(priv->col),
+            clutter_color_g(priv->col),
+            clutter_color_b(priv->col), 
+            clutter_element_get_opacity(self));
+
+  glRecti (geom.x,
+          geom.y,
+          geom.x + geom.width,
+          geom.y + geom.height);
+
+  glDisable(GL_BLEND);
+
+  glPopMatrix();
+}
+
+static void
+clutter_rectangle_set_property (GObject      *object, 
+                               guint         prop_id,
+                               const GValue *value, 
+                               GParamSpec   *pspec)
+{
+  ClutterRectangle        *rectangle;
+  ClutterRectanglePrivate *priv;
+
+  rectangle = CLUTTER_RECTANGLE(object);
+  priv = rectangle->priv;
+
+  switch (prop_id) 
+    {
+    case PROP_COL:
+      priv->col = g_value_get_uint(value);
+      clutter_element_set_opacity(CLUTTER_ELEMENT(rectangle), 
+                                 priv->col & 0xff);
+      /* FIXME: queue paint */
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+clutter_rectangle_get_property (GObject    *object, 
+                               guint       prop_id,
+                               GValue     *value, 
+                               GParamSpec *pspec)
+{
+  ClutterRectangle        *rectangle;
+  ClutterRectanglePrivate *priv;
+
+  rectangle = CLUTTER_RECTANGLE(object);
+  priv = rectangle->priv;
+
+  switch (prop_id) 
+    {
+    case PROP_COL:
+      g_value_set_uint (value, priv->col);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    } 
+}
+
+
+static void 
+clutter_rectangle_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (clutter_rectangle_parent_class)->finalize (object);
+}
+
+static void 
+clutter_rectangle_dispose (GObject *object)
+{
+  G_OBJECT_CLASS (clutter_rectangle_parent_class)->dispose (object);
+}
+
+
+static void
+clutter_rectangle_class_init (ClutterRectangleClass *klass)
+{
+  GObjectClass        *gobject_class = G_OBJECT_CLASS (klass);
+  ClutterElementClass *element_class = CLUTTER_ELEMENT_CLASS (klass);
+
+  element_class->paint        = clutter_rectangle_paint;
+
+  gobject_class->finalize     = clutter_rectangle_finalize;
+  gobject_class->dispose      = clutter_rectangle_dispose;
+  gobject_class->set_property = clutter_rectangle_set_property;
+  gobject_class->get_property = clutter_rectangle_get_property;
+
+  g_object_class_install_property
+    (gobject_class, PROP_COL,
+     g_param_spec_uint ("color",
+                      "Rectangle Colour",
+                      "Rectangle Colour specified as 8 byte RGBA value",
+                       0,
+                       0xffffffff,
+                       0xff,
+                       G_PARAM_READWRITE));
+
+  g_type_class_add_private (gobject_class, sizeof (ClutterRectanglePrivate));
+}
+
+static void
+clutter_rectangle_init (ClutterRectangle *self)
+{
+  self->priv = CLUTTER_RECTANGLE_GET_PRIVATE (self);
+}
+
+ClutterElement*
+clutter_rectangle_new (guint32 colour)
+{
+  return g_object_new (CLUTTER_TYPE_RECTANGLE,
+                      "color", colour,
+                      NULL);
+}
+
diff --git a/clutter/clutter-rectangle.h b/clutter/clutter-rectangle.h
new file mode 100644 (file)
index 0000000..c13a91e
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _HAVE_CLUTTER_RECTANGLE_H
+#define _HAVE_CLUTTER_RECTANGLE_H
+
+#include <glib-object.h>
+#include <clutter/clutter-element.h>
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_RECTANGLE clutter_rectangle_get_type()
+
+#define CLUTTER_RECTANGLE(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+  CLUTTER_TYPE_RECTANGLE, ClutterRectangle))
+
+#define CLUTTER_RECTANGLE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), \
+  CLUTTER_TYPE_RECTANGLE, ClutterRectangleClass))
+
+#define CLUTTER_IS_RECTANGLE(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+  CLUTTER_TYPE_RECTANGLE))
+
+#define CLUTTER_IS_RECTANGLE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+  CLUTTER_TYPE_RECTANGLE))
+
+#define CLUTTER_RECTANGLE_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+  CLUTTER_TYPE_RECTANGLE, ClutterRectangleClass))
+
+typedef struct _ClutterRectanglePrivate ClutterRectanglePrivate;
+typedef struct _ClutterRectangle        ClutterRectangle;
+typedef struct _ClutterRectangleClass   ClutterRectangleClass;
+
+struct _ClutterRectangle
+{
+  ClutterElement           parent;
+
+  /*< priv >*/
+  ClutterRectanglePrivate *priv;
+}; 
+
+struct _ClutterRectangleClass 
+{
+  ClutterElementClass parent_class;
+};
+
+GType clutter_rectangle_get_type (void);
+
+ClutterElement*
+clutter_rectangle_new (guint32 col);
+
+G_END_DECLS
+
+#endif
diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c
new file mode 100644 (file)
index 0000000..fd2e7b4
--- /dev/null
@@ -0,0 +1,620 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "clutter-stage.h"
+#include "clutter-main.h"
+#include "clutter-color.h"
+#include "clutter-private.h"   /* for DBG */
+
+#include <GL/glx.h>
+#include <GL/gl.h>
+
+G_DEFINE_TYPE (ClutterStage, clutter_stage, CLUTTER_TYPE_GROUP);
+
+static ClutterElementClass *parent_class;
+
+struct ClutterStagePrivate
+{
+  Window          xwin;  
+  gint            xwin_width, xwin_height;
+  gboolean        want_fullscreen;
+  gboolean        hide_cursor;
+  ClutterColor    color;
+};
+
+enum
+{
+  PROP_0,
+  PROP_FULLSCREEN,
+  PROP_HIDE_CURSOR
+};
+
+enum
+{
+  SIGNAL_INPUT_EVENT,
+  LAST_SIGNAL
+};
+
+static int stage_signals[LAST_SIGNAL] = { 0 };
+
+static void
+sync_fullscreen (ClutterStage *stage)
+{
+  Atom                 atom_WINDOW_STATE, atom_WINDOW_STATE_FULLSCREEN;
+
+  atom_WINDOW_STATE 
+    = XInternAtom(clutter_xdisplay(), "_NET_WM_STATE", False);
+  atom_WINDOW_STATE_FULLSCREEN 
+    = XInternAtom(clutter_xdisplay(), "_NET_WM_STATE_FULLSCREEN",False);
+
+  if (stage->priv->want_fullscreen)
+    {
+      clutter_element_set_size (CLUTTER_ELEMENT(stage),
+                               DisplayWidth(clutter_xdisplay(), 
+                                            clutter_xscreen()),
+                               DisplayHeight(clutter_xdisplay(), 
+                                             clutter_xscreen()));
+
+      if (stage->priv->xwin != None)
+       XChangeProperty(clutter_xdisplay(), stage->priv->xwin,
+                       atom_WINDOW_STATE, XA_ATOM, 32,
+                       PropModeReplace,
+                       (unsigned char *)&atom_WINDOW_STATE_FULLSCREEN, 1);
+    }
+  else
+    {
+      /* FIXME */
+      if (stage->priv->xwin != None)
+       XDeleteProperty(clutter_xdisplay(), 
+                       stage->priv->xwin, atom_WINDOW_STATE);
+    }
+}
+
+static void
+sync_cursor_visible (ClutterStage *stage)
+{
+  if (stage->priv->xwin == None)
+    return;
+  
+  if (stage->priv->hide_cursor)
+    {
+      XColor col;
+      Pixmap pix;
+      Cursor curs;
+
+      pix = XCreatePixmap (clutter_xdisplay(), 
+                          stage->priv->xwin, 1, 1, 1);
+      memset (&col, 0, sizeof (col));
+      curs = XCreatePixmapCursor (clutter_xdisplay(), 
+                                 pix, pix, &col, &col, 1, 1);
+      XFreePixmap (clutter_xdisplay(), pix);
+      XDefineCursor(clutter_xdisplay(), stage->priv->xwin, curs);
+    }
+  else
+    {
+      XUndefineCursor(clutter_xdisplay(), stage->priv->xwin);
+    }
+}
+
+static void
+frustum (GLfloat left,
+        GLfloat right,
+        GLfloat bottom,
+        GLfloat top,
+        GLfloat nearval,
+        GLfloat farval)
+{
+  GLfloat x, y, a, b, c, d;
+  GLfloat m[16];
+
+  x = (2.0 * nearval) / (right - left);
+  y = (2.0 * nearval) / (top - bottom);
+  a = (right + left) / (right - left);
+  b = (top + bottom) / (top - bottom);
+  c = -(farval + nearval) / ( farval - nearval);
+  d = -(2.0 * farval * nearval) / (farval - nearval);
+
+#define M(row,col)  m[col*4+row]
+  M(0,0) = x;     M(0,1) = 0.0F;  M(0,2) = a;      M(0,3) = 0.0F;
+  M(1,0) = 0.0F;  M(1,1) = y;     M(1,2) = b;      M(1,3) = 0.0F;
+  M(2,0) = 0.0F;  M(2,1) = 0.0F;  M(2,2) = c;      M(2,3) = d;
+  M(3,0) = 0.0F;  M(3,1) = 0.0F;  M(3,2) = -1.0F;  M(3,3) = 0.0F;
+#undef M
+
+  glMultMatrixf (m);
+}
+
+static void
+perspective (GLfloat fovy,
+            GLfloat aspect,
+            GLfloat zNear,
+            GLfloat zFar)
+{
+  GLfloat xmin, xmax, ymin, ymax;
+
+  ymax = zNear * tan (fovy * M_PI / 360.0);
+  ymin = -ymax;
+  xmin = ymin * aspect;
+  xmax = ymax * aspect;
+
+  frustum (xmin, xmax, ymin, ymax, zNear, zFar);
+}
+
+static void
+sync_gl_viewport (ClutterStage *stage)
+{
+  /* Set For 2D */
+#if 0
+  glViewport (0, 0, stage->priv->xwin_width, stage->priv->xwin_height);
+  glMatrixMode (GL_PROJECTION);
+  glLoadIdentity ();
+  glOrtho (0, stage->priv->xwin_width, stage->priv->xwin_height, 0, -1, 1);
+  glMatrixMode (GL_MODELVIEW);
+  glLoadIdentity ();
+
+#endif
+  /* For 3D */
+
+  glViewport (0, 0, stage->priv->xwin_width, stage->priv->xwin_height);
+  glMatrixMode (GL_PROJECTION);
+  glLoadIdentity ();
+  perspective (60.0f, 1.0f, 0.1f, 100.0f);
+  glMatrixMode (GL_MODELVIEW);
+  glLoadIdentity ();
+
+  /* Then for 2D like transform */
+
+  /* camera distance from screen, 0.5 * tan (FOV) */
+#define DEFAULT_Z_CAMERA 0.866025404f
+
+  glTranslatef (-0.5f, -0.5f, -DEFAULT_Z_CAMERA);
+  glScalef (1.0f / stage->priv->xwin_width, 
+           -1.0f / stage->priv->xwin_height, 1.0f / stage->priv->xwin_width);
+  glTranslatef (0.0f, -stage->priv->xwin_height, 0.0f);
+}
+
+static void
+clutter_stage_show (ClutterElement *self)
+{
+  XMapWindow (clutter_xdisplay(), 
+             clutter_stage_get_xwindow (CLUTTER_STAGE(self)));
+}
+
+static void
+clutter_stage_hide (ClutterElement *self)
+{
+  XUnmapWindow (clutter_xdisplay(), 
+               clutter_stage_get_xwindow (CLUTTER_STAGE(self)));
+}
+
+static void
+clutter_stage_unrealize (ClutterElement *element)
+{
+  ClutterStage        *stage;
+  ClutterStagePrivate *priv;
+
+  stage = CLUTTER_STAGE(element);
+  priv = stage->priv;
+
+  XDestroyWindow (clutter_xdisplay(), priv->xwin);
+  priv->xwin = None;
+}
+
+static void
+clutter_stage_realize (ClutterElement *element)
+{
+  ClutterStage        *stage;
+  ClutterStagePrivate *priv;
+
+  stage = CLUTTER_STAGE(element);
+
+  priv = stage->priv;
+
+  priv->xwin = XCreateSimpleWindow(clutter_xdisplay(),
+                                  clutter_root_xwindow(),
+                                  0, 0,
+                                  priv->xwin_width, priv->xwin_height,
+                                  0, 0, 
+                                  WhitePixel(clutter_xdisplay(), 
+                                             clutter_xscreen()));
+
+  XSelectInput(clutter_xdisplay(), 
+              priv->xwin, 
+              StructureNotifyMask
+              |ExposureMask
+              |KeyPressMask
+              |KeyReleaseMask
+              |ButtonPressMask     /* FIXME: Make optional ? */
+              |ButtonReleaseMask
+              |PropertyChangeMask);
+
+  sync_fullscreen (stage);  
+  sync_cursor_visible (stage);  
+
+  glXMakeCurrent(clutter_xdisplay(), priv->xwin, clutter_gl_context());
+  sync_gl_viewport (stage);
+}
+
+static void
+clutter_stage_paint (ClutterElement *self)
+{
+  parent_class->paint(self);
+}
+
+static void
+clutter_stage_allocate_coords (ClutterElement    *self,
+                              ClutterElementBox *box)
+{
+  /* Do nothing, just stop group_allocate getting called */
+
+  /* TODO: sync up with any configure events from WM ??  */
+  return;
+}
+
+static void
+clutter_stage_request_coords (ClutterElement    *self,
+                             ClutterElementBox *box)
+{
+  ClutterStage        *stage;
+  ClutterStagePrivate *priv;
+  gint                 new_width, new_height;
+
+  stage = CLUTTER_STAGE(self);
+
+  priv = stage->priv;
+
+  new_width  = ABS(box->x2 - box->x1);
+  new_height = ABS(box->y2 - box->y1); 
+
+  if (new_width != priv->xwin_width || new_height != priv->xwin_height)
+    {
+      priv->xwin_width  = new_width;
+      priv->xwin_height = new_height;
+
+      if (priv->xwin)
+       XResizeWindow (clutter_xdisplay(), 
+                      priv->xwin, 
+                      priv->xwin_width, 
+                      priv->xwin_height);
+      sync_gl_viewport (stage);
+    }
+
+  if (priv->xwin) /* Do we want to bother ? */
+    XMoveWindow (clutter_xdisplay(), 
+                priv->xwin,
+                box->x1,
+                box->y1);
+}
+
+static void 
+clutter_stage_dispose (GObject *object)
+{
+  ClutterStage *self = CLUTTER_STAGE(object);
+
+  if (self->priv)
+    {
+      if (self->priv->xwin)
+       clutter_stage_unrealize (CLUTTER_ELEMENT(self));
+    }
+
+  G_OBJECT_CLASS (clutter_stage_parent_class)->dispose (object);
+}
+
+static void 
+clutter_stage_finalize (GObject *object)
+{
+  ClutterStage *self = CLUTTER_STAGE(object);
+
+  if (self->priv)
+    {
+      g_free(self->priv);
+      self->priv = NULL;
+    }
+
+  G_OBJECT_CLASS (clutter_stage_parent_class)->finalize (object);
+}
+
+
+static void
+clutter_stage_set_property (GObject      *object, 
+                           guint         prop_id,
+                           const GValue *value, 
+                           GParamSpec   *pspec)
+{
+  ClutterStage        *stage;
+  ClutterStagePrivate *priv;
+
+  stage = CLUTTER_STAGE(object);
+  priv = stage->priv;
+
+  switch (prop_id) 
+    {
+    case PROP_FULLSCREEN:
+      if (priv->want_fullscreen != g_value_get_boolean (value))
+       {
+         priv->want_fullscreen = g_value_get_boolean (value);
+         sync_fullscreen (stage);
+       }
+      break;
+    case PROP_HIDE_CURSOR:
+      if (priv->hide_cursor != g_value_get_boolean (value))
+       {
+         priv->hide_cursor = g_value_get_boolean (value);
+         sync_cursor_visible (stage);
+       }
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+clutter_stage_get_property (GObject    *object, 
+                             guint       prop_id,
+                             GValue     *value, 
+                             GParamSpec *pspec)
+{
+  ClutterStage        *stage;
+  ClutterStagePrivate *priv;
+
+  stage = CLUTTER_STAGE(object);
+  priv = stage->priv;
+
+  switch (prop_id) 
+    {
+    case PROP_FULLSCREEN:
+      g_value_set_boolean (value, priv->want_fullscreen);
+      break;
+    case PROP_HIDE_CURSOR:
+      g_value_set_boolean (value, priv->hide_cursor);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    } 
+}
+
+static void
+clutter_stage_class_init (ClutterStageClass *klass)
+{
+  GObjectClass        *gobject_class;
+  ClutterElementClass *element_class;
+  ClutterGroupClass     *group_class;
+
+  gobject_class = (GObjectClass*)klass;
+  element_class = (ClutterElementClass*)klass;
+  group_class     = (ClutterGroupClass*)klass;
+
+  element_class->realize    = clutter_stage_realize;
+  element_class->unrealize  = clutter_stage_unrealize;
+  element_class->show       = clutter_stage_show;
+  element_class->hide       = clutter_stage_hide;
+  element_class->paint      = clutter_stage_paint;
+
+  element_class->request_coords  = clutter_stage_request_coords;
+  element_class->allocate_coords = clutter_stage_allocate_coords;
+
+  gobject_class->dispose      = clutter_stage_dispose;
+  gobject_class->finalize     = clutter_stage_finalize;
+  gobject_class->set_property = clutter_stage_set_property;
+  gobject_class->get_property = clutter_stage_get_property;
+
+  parent_class = g_type_class_peek_parent(group_class);
+
+  g_object_class_install_property
+    (gobject_class, PROP_FULLSCREEN,
+     g_param_spec_boolean ("fullscreen",
+                          "Fullscreen",
+                          "Make Clutter stage fullscreen",
+                          FALSE,
+                          G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+
+  g_object_class_install_property
+    (gobject_class, PROP_HIDE_CURSOR,
+     g_param_spec_boolean ("hide-cursor",
+                          "Hide Cursor",
+                          "Make Clutter stage cursor-less",
+                          FALSE,
+                          G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+
+  stage_signals[SIGNAL_INPUT_EVENT] =
+    g_signal_new ("input-event",
+                 G_TYPE_FROM_CLASS (gobject_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterStageClass, input_event),
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__POINTER,
+                 G_TYPE_NONE, 
+                 1, G_TYPE_POINTER);
+}
+
+static void
+clutter_stage_init (ClutterStage *self)
+{
+  ClutterStagePrivate *priv;
+
+  priv        = g_new0 (ClutterStagePrivate, 1);
+
+  priv->xwin_width  = 100;
+  priv->xwin_height = 100;
+  priv->color       = 0xffffffff;
+  self->priv  = priv;
+
+  clutter_element_set_size (CLUTTER_ELEMENT(self), 640, 480);
+}
+
+/**
+ * clutter_stage_get_xwindow
+ * @stage: A #ClutterStage
+ *
+ * Get the stages underlying x window ID.
+ *
+ * Return Value: Stage X Window XID
+ **/
+Window
+clutter_stage_get_xwindow (ClutterStage *stage)
+{
+  return stage->priv->xwin;
+}
+
+/**
+ * clutter_stage_set_color
+ * @stage: A #ClutterStage
+ * @color: A #ClutterColor
+ * 
+ * Set the stage color.
+ **/
+void
+clutter_stage_set_color (ClutterStage *stage,
+                        ClutterColor  color)
+{
+  stage->priv->color = color;
+
+  if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT(stage)))
+    clutter_element_queue_redraw (CLUTTER_ELEMENT(stage));
+}
+
+/**
+ * clutter_stage_set_color
+ * @stage: A #ClutterStage
+ * 
+ * Request the stage color.
+ * 
+ * Return Value: The stages #ClutterColor
+ **/
+ClutterColor
+clutter_stage_get_color (ClutterStage *stage)
+{
+  return stage->priv->color;
+}
+
+static void
+snapshot_pixbuf_free(guchar  *pixels, gpointer data)
+{
+  g_free(pixels);
+}
+
+/**
+ * clutter_stage_snapshot
+ * @stage A #ClutterStage
+ * @x     x  coordinate of the first pixel that is read from stage
+ * @y     y  coordinate of the first pixel that is read from stage
+ * @width Width dimention of pixels to be read.
+ * @height Height dimention of pixels to be read.
+ *
+ * Gets a pixel based representation of the current rendered stage.
+ *
+ * Return value: pixel representation as a  #GdkPixbuf
+ **/
+GdkPixbuf*
+clutter_stage_snapshot (ClutterStage *stage,
+                       gint          x,
+                       gint          y,
+                       guint         width,
+                       guint         height)
+{
+  guchar    *data;
+  GdkPixbuf *pixb, *fpixb;
+
+  data = g_malloc0(sizeof(guchar)*width*height*3);
+
+  glReadPixels (x, 
+               clutter_element_get_height(CLUTTER_ELEMENT(clutter_stage())) 
+               - y - height,
+               width, 
+               height, GL_RGB, GL_UNSIGNED_BYTE, data);
+
+  pixb = gdk_pixbuf_new_from_data (data,
+                                  GDK_COLORSPACE_RGB, 
+                                  FALSE, 
+                                  8, 
+                                  width, 
+                                  height,
+                                  width * 3,
+                                  snapshot_pixbuf_free,
+                                  NULL);
+
+  if (pixb == NULL)
+    return NULL;
+
+  fpixb = gdk_pixbuf_flip (pixb, TRUE);
+
+  g_object_unref (pixb);
+
+  return fpixb;
+}
+
+/* FIXME: better name - pos_to_element */
+ClutterElement*
+clutter_stage_pick (ClutterStage *stage, gint x, gint y)
+{
+  ClutterElement *found = NULL;
+  GLuint          buff[64] = {0};
+  GLint           hits, view[4], i;
+  glSelectBuffer(64, buff);
+  glGetIntegerv(GL_VIEWPORT, view);
+  glRenderMode(GL_SELECT);
+
+  glInitNames();
+
+  glPushName(0);
+  glMatrixMode(GL_PROJECTION);
+  glPushMatrix();
+  glLoadIdentity();
+
+  /* This is gluPickMatrix(x, y, 1.0, 1.0, view); */
+  glTranslatef((view[2] - 2 * (x - view[0])),
+              (view[3] - 2 * (y - view[1])), 0);
+  glScalef(view[2], -view[3], 1.0);
+
+  perspective (60.0f, 1.0f, 0.1f, 100.0f); 
+
+  glMatrixMode(GL_MODELVIEW);
+
+  clutter_element_paint(CLUTTER_ELEMENT(stage));
+
+  glMatrixMode(GL_PROJECTION);
+  glPopMatrix();
+
+  hits = glRenderMode(GL_RENDER);
+
+  if (hits != 0)
+    {
+      /*
+      for (i=0; i<hits; i++)
+       g_print ("Hit at %i\n", buff[i * 4 + 3]);
+      */
+  
+      found = clutter_group_find_child_by_id (clutter_stage(), buff[3]);
+    }
+  
+  sync_gl_viewport (stage);
+
+  return found;
+}
+
diff --git a/clutter/clutter-stage.h b/clutter/clutter-stage.h
new file mode 100644 (file)
index 0000000..a7d46ac
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _HAVE_CLUTTER_STAGE_H
+#define _HAVE_CLUTTER_STAGE_H
+
+#include <glib-object.h>
+
+#include <clutter/clutter-group.h>
+#include <clutter/clutter-color.h>
+#include <clutter/clutter-event.h>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_STAGE clutter_stage_get_type()
+
+#define CLUTTER_STAGE_WIDTH() \
+ clutter_element_get_width(CLUTTER_ELEMENT(clutter_stage()))
+
+#define CLUTTER_STAGE_HEIGHT() \
+ clutter_element_get_height(CLUTTER_ELEMENT(clutter_stage()))
+
+
+#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))
+
+typedef struct ClutterStagePrivate ClutterStagePrivate;
+typedef struct _ClutterStage       ClutterStage;
+typedef struct _ClutterStageClass  ClutterStageClass;
+
+struct _ClutterStage
+{
+  ClutterGroup         parent;
+  ClutterStagePrivate *priv;
+}; 
+
+struct _ClutterStageClass 
+{
+  ClutterGroupClass parent_class;
+
+  void (*input_event) (ClutterStage *stage,
+                      ClutterEvent *event);
+}; 
+
+GType clutter_stage_get_type (void);
+
+/* FIXME: no need for below to take stage arg ? 
+ *        convert to defines also ?
+*/
+
+Window
+clutter_stage_get_xwindow (ClutterStage *stage);
+
+void
+clutter_stage_set_color (ClutterStage *stage,
+                        ClutterColor  color);
+
+ClutterColor
+clutter_stage_get_color (ClutterStage *stage);
+
+ClutterElement*
+clutter_stage_pick (ClutterStage *stage, gint x, gint y);
+
+G_END_DECLS
+
+#endif
diff --git a/clutter/clutter-texture.c b/clutter/clutter-texture.c
new file mode 100644 (file)
index 0000000..02a2a75
--- /dev/null
@@ -0,0 +1,1216 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "clutter-texture.h"
+#include "clutter-main.h"
+#include "clutter-marshal.h"
+#include "clutter-private.h"   /* for DBG */
+
+#include <GL/glx.h>
+#include <GL/gl.h>
+
+G_DEFINE_TYPE (ClutterTexture, clutter_texture, CLUTTER_TYPE_ELEMENT);
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define PIXEL_TYPE GL_UNSIGNED_BYTE
+#else
+#define PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
+#endif
+
+#define PIXEL_FORMAT GL_RGBA
+
+/* Some code below based on luminocity - copyright Owen Taylor */
+
+/*  MAX_WASTE: The maximum dimension of blank area we'll accept
+ *       in a pixmap. Bigger values use less textures, smaller
+ *       values less texture memory. The current value of 
+ *       256 means that the smallest texture we'll split to
+ *       save texture memory is 513x512. (That will be split into
+ *       a 512x512 and, if overlap is 32, a 64x512 texture)
+ */
+#define MAX_WASTE 64           /* FIXME: Make property */
+
+/*
+ * OVERLAP: when we divide the full-resolution image into
+ *          tiles to deal with hardware limitations, we overlap
+ *          tiles by this much. This means that we can scale
+ *          down by up to OVERLAP before we start getting
+ *          seems.
+ */
+
+#define OVERLAP 0 /* 32 */
+
+/* FIXME: actually use */
+typedef struct ClutterTextureTileDimention
+{
+  gint pos, size, waste;
+}
+ClutterTextureTileDimention;
+
+struct ClutterTexturePrivate
+{
+  GdkPixbuf                   *pixbuf; 
+  gint                         width, height;
+  GLenum                       pixel_format;
+  GLenum                       pixel_type;
+
+  gboolean                     sync_element_size;
+  gint                         tile_max_waste;
+  gboolean                     repeat_x, repeat_y;
+  
+  gboolean                     tiled;
+  ClutterTextureTileDimention *x_tiles, *y_tiles;
+  gint                         n_x_tiles, n_y_tiles;
+  GLuint                      *tiles;
+};
+
+enum
+{
+  PROP_0,
+  PROP_PIXBUF,
+  PROP_USE_TILES,
+  PROP_MAX_TILE_WASTE,
+  PROP_PIXEL_TYPE,             /* Texture type */
+  PROP_PIXEL_FORMAT,           /* Texture format */
+  PROP_SYNC_SIZE,
+  PROP_REPEAT_Y,
+  PROP_REPEAT_X
+};
+
+enum
+{
+  SIGNAL_SIZE_CHANGE,
+  SIGNAL_PIXBUF_CHANGE,
+  LAST_SIGNAL
+};
+
+static int texture_signals[LAST_SIGNAL] = { 0 };
+
+static void
+init_tiles (ClutterTexture *texture);
+
+static int 
+next_p2 (int a)
+{
+  int rval=1;
+
+  while(rval < a) 
+    rval <<= 1;
+
+  return rval;
+}
+
+static gboolean
+can_create (int    width, 
+           int    height,
+           GLenum pixel_format,
+           GLenum pixel_type)
+{
+  GLint new_width;
+
+  CLUTTER_DBG("checking %ix%i", width, height);
+
+
+  glTexImage2D (GL_PROXY_TEXTURE_2D, 0, GL_RGBA,
+                width, height, 0 /* border */,
+                pixel_format, pixel_type, NULL);
+
+  glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0,
+                            GL_TEXTURE_WIDTH, &new_width);
+
+
+  return new_width != 0;
+}
+
+static int
+tile_dimension (int                          to_fill,
+               int                          start_size,
+               ClutterTextureTileDimention *tiles)
+{
+  int pos     = 0;
+  int n_tiles = 0;
+  int size    = start_size;
+
+  while (TRUE)
+    {
+      if (tiles)
+       {
+         tiles[n_tiles].pos = pos;
+         tiles[n_tiles].size = size;
+         tiles[n_tiles].waste = 0;
+       }
+
+      n_tiles++;
+       
+      if (to_fill <= size)
+       {
+         if (tiles)
+           tiles[n_tiles-1].waste = size - to_fill;
+         break;
+       }
+      else
+       {
+         to_fill -= (size - OVERLAP);
+         pos += size - OVERLAP;
+         while (size >= 2 * to_fill || size - to_fill > MAX_WASTE)
+           size /= 2;
+       }
+    }
+
+  return n_tiles;
+}
+
+static void
+init_tiles (ClutterTexture *texture)
+{
+  ClutterTexturePrivate *priv;
+  gint                   x_pot, y_pot;
+
+  priv = texture->priv;
+
+  x_pot = next_p2 (priv->width);
+  y_pot = next_p2 (priv->height);
+  
+  if (x_pot - priv->width > MAX_WASTE && y_pot - priv->height > MAX_WASTE)
+    {
+      while (!(can_create (x_pot, y_pot, priv->pixel_format, priv->pixel_type) 
+              && (x_pot - priv->width < MAX_WASTE) 
+              && (y_pot - priv->height < MAX_WASTE)))
+       {
+         CLUTTER_DBG("x_pot:%i - width:%i < max_waste:%i", 
+                     x_pot, priv->width, MAX_WASTE );
+         
+         CLUTTER_DBG("y_pot:%i - height:%i < max_waste:%i", 
+                     y_pot, priv->height, MAX_WASTE );
+         
+         if (x_pot > y_pot)
+           x_pot /= 2;
+         else
+           y_pot /= 2;
+       }
+      } 
+
+  if (priv->x_tiles)
+    g_free(priv->x_tiles);
+
+  priv->n_x_tiles = tile_dimension (priv->width, x_pot, NULL);
+  priv->x_tiles = g_new (ClutterTextureTileDimention, priv->n_x_tiles);
+  tile_dimension (priv->width, x_pot, priv->x_tiles);
+
+  if (priv->y_tiles)
+    g_free(priv->y_tiles);
+
+  priv->n_y_tiles = tile_dimension (priv->height, y_pot, NULL);
+  priv->y_tiles = g_new (ClutterTextureTileDimention, priv->n_y_tiles);
+  tile_dimension (priv->height, y_pot, priv->y_tiles);
+
+  CLUTTER_DBG("x_pot:%i, width:%i, y_pot:%i, height: %i max_waste:%i, "
+              " n_x_tiles: %i, n_y_tiles: %i",
+             x_pot, priv->width, y_pot, priv->height, MAX_WASTE,
+             priv->n_x_tiles, priv->n_y_tiles);
+
+}
+
+static void
+texture_render_to_gl_quad (ClutterTexture *texture, 
+                          int             x1, 
+                          int             y1, 
+                          int             x2, 
+                          int             y2)
+{
+  int   qx1 = 0, qx2 = 0, qy1 = 0, qy2 = 0;
+  int   qwidth = 0, qheight = 0;
+  int   x, y, i =0, lastx = 0, lasty = 0;
+  float tx, ty;
+
+  ClutterTexturePrivate *priv;
+
+  priv = texture->priv;
+
+  qwidth  = x2-x1;
+  qheight = y2-y1;
+
+  if (!CLUTTER_ELEMENT_IS_REALIZED (CLUTTER_ELEMENT(texture)))
+      clutter_element_realize (CLUTTER_ELEMENT(texture));
+
+  g_return_if_fail(priv->tiles != NULL);
+
+  /* OPT: Put in display list */
+
+  /* OPT: Optionally avoid tiling and use texture rectangles ext if
+   *      supported. 
+  */
+
+  if (!priv->tiled)
+    {
+      glBindTexture(GL_TEXTURE_2D, priv->tiles[0]);
+
+      tx = (float) priv->width / next_p2 (priv->width);  
+      ty = (float) priv->height / next_p2 (priv->height);
+
+      qx1 = x1; qx2 = x2;
+      qy1 = y1; qy2 = y2;
+      
+      glBegin (GL_QUADS);
+      glTexCoord2f (tx, ty);   glVertex2i   (qx2, qy2);
+      glTexCoord2f (0,  ty);   glVertex2i   (qx1, qy2);
+      glTexCoord2f (0,  0);    glVertex2i   (qx1, qy1);
+      glTexCoord2f (tx, 0);    glVertex2i   (qx2, qy1);
+      glEnd ();        
+      
+      return;
+    }
+
+  for (x=0; x < priv->n_x_tiles; x++)
+    {
+      lasty = 0;
+
+      for (y=0; y < priv->n_y_tiles; y++)
+       {
+         int actual_w, actual_h;
+
+         glBindTexture(GL_TEXTURE_2D, priv->tiles[i]);
+        
+         actual_w = priv->x_tiles[x].size - priv->x_tiles[x].waste;
+         actual_h = priv->y_tiles[y].size - priv->y_tiles[y].waste;
+
+         CLUTTER_DBG("rendering text tile x: %i, y: %i - %ix%i", 
+                     x, y, actual_w, actual_h);
+
+         tx = (float) actual_w / priv->x_tiles[x].size;
+         ty = (float) actual_h / priv->y_tiles[y].size;
+
+         qx1 = x1 + lastx;
+         qx2 = qx1 + ((qwidth * actual_w ) / priv->width );
+         
+         qy1 = y1 + lasty;
+         qy2 = qy1 + ((qheight * actual_h) / priv->height );
+
+         glBegin (GL_QUADS);
+         glTexCoord2f (tx, ty);   glVertex2i   (qx2, qy2);
+         glTexCoord2f (0,  ty);   glVertex2i   (qx1, qy2);
+         glTexCoord2f (0,  0);    glVertex2i   (qx1, qy1);
+         glTexCoord2f (tx, 0);    glVertex2i   (qx2, qy1);
+         glEnd ();     
+
+         lasty += qy2 - qy1;     
+
+         i++;
+       }
+      lastx += qx2 - qx1;
+    }
+}
+
+static void
+clutter_texture_unrealize (ClutterElement *element)
+{
+  ClutterTexture        *texture;
+  ClutterTexturePrivate *priv;
+
+  texture = CLUTTER_TEXTURE(element);
+  priv = texture->priv;
+
+  if (priv->tiles == NULL)
+    return;
+
+  CLUTTER_MARK();
+
+  clutter_threads_enter ();
+
+  /* Free up texture memory */
+  if (!priv->tiled)
+    glDeleteTextures(1, priv->tiles);
+  else
+    glDeleteTextures(priv->n_x_tiles * priv->n_y_tiles, priv->tiles);
+
+  clutter_threads_leave ();
+
+  CLUTTER_MARK();
+
+  if (priv->tiles)
+    {
+      g_free(priv->tiles);
+      priv->tiles = NULL;
+    }
+
+  if (priv->x_tiles)
+    {
+      g_free(priv->x_tiles);
+      priv->x_tiles = NULL;
+    }
+
+  if (priv->y_tiles)
+    {
+      g_free(priv->y_tiles);
+      priv->y_tiles = NULL;
+    }
+
+  CLUTTER_DBG("Texture unrealized");
+}
+
+static void
+clutter_texture_sync_pixbuf (ClutterTexture *texture)
+{
+  ClutterTexturePrivate *priv;
+  int                    x, y, i = 0;
+  gboolean               create_textures = FALSE;
+
+  priv = texture->priv;
+
+  g_return_if_fail (priv->pixbuf != NULL);
+
+  CLUTTER_MARK();
+
+  if (!priv->tiled)
+    {
+      /* Single Texture 
+       *        
+      */
+      if (!priv->tiles)
+       {
+         priv->tiles = g_new (GLuint, 1);
+         glGenTextures (1, priv->tiles);
+         create_textures = TRUE;
+       }
+
+      CLUTTER_DBG("syncing for single tile");
+
+      glBindTexture(GL_TEXTURE_2D, priv->tiles[0]);
+
+      glTexParameteri(GL_TEXTURE_2D, 
+                     GL_TEXTURE_WRAP_S, 
+                     priv->repeat_x ? GL_REPEAT : GL_CLAMP);
+
+      glTexParameteri(GL_TEXTURE_2D, 
+                     GL_TEXTURE_WRAP_T, 
+                     priv->repeat_y ? GL_REPEAT : GL_CLAMP);
+
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+      glPixelStorei (GL_UNPACK_ROW_LENGTH, 
+                    gdk_pixbuf_get_width(priv->pixbuf));
+      glPixelStorei (GL_UNPACK_ALIGNMENT, 
+                    gdk_pixbuf_get_n_channels (priv->pixbuf));
+         
+      if (create_textures)
+       {
+         /* NOTE: Change to GL_RGB for non alpha textures */
+         glTexImage2D(GL_TEXTURE_2D, 
+                      0, 
+                      (gdk_pixbuf_get_n_channels (priv->pixbuf) == 4) ? 
+                             GL_RGBA : GL_RGB,
+                      next_p2(priv->width),
+                      next_p2(priv->height),
+                      0, 
+                      priv->pixel_format, 
+                      priv->pixel_type, 
+                      NULL);
+       }
+
+      glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0,
+                      priv->width,
+                      priv->height,
+                      priv->pixel_format, 
+                      priv->pixel_type, 
+                      gdk_pixbuf_get_pixels(priv->pixbuf));
+
+      return;
+    }
+
+  /* Multiple tiled texture */
+  
+  CLUTTER_DBG("syncing for multiple tiles for %ix%i pixbuf",
+             priv->width, priv->height);
+
+  if (priv->tiles == NULL)
+    {
+      priv->tiles = g_new (GLuint, priv->n_x_tiles * priv->n_y_tiles);
+      glGenTextures (priv->n_x_tiles * priv->n_y_tiles, priv->tiles);
+      create_textures = TRUE;
+    }
+
+  for (x=0; x < priv->n_x_tiles; x++)
+    for (y=0; y < priv->n_y_tiles; y++)
+      {
+       GdkPixbuf *pixtmp;
+       int src_h, src_w;
+       
+       src_w = priv->x_tiles[x].size;
+       src_h = priv->y_tiles[y].size;
+       
+       pixtmp 
+         = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
+                          (gdk_pixbuf_get_n_channels (priv->pixbuf) == 4) ? 
+                          TRUE : FALSE,
+                          8,
+                          priv->x_tiles[x].size,
+                          priv->y_tiles[y].size);
+       
+       /* clip */
+       if (priv->x_tiles[x].pos + src_w > priv->width)
+         {
+           src_w = priv->width - priv->x_tiles[x].pos;
+         }
+
+       if (priv->y_tiles[y].pos + src_h > priv->height)
+         {
+           src_h = priv->height - priv->y_tiles[y].pos;
+         }
+
+       CLUTTER_DBG("copying tile %i,%i - %ix%i to 0,0 %ix%i", 
+                   priv->x_tiles[x].pos,
+                   priv->y_tiles[y].pos,
+                   src_w,
+                   src_h,
+                   priv->x_tiles[x].size,
+                   priv->y_tiles[y].size);
+
+       gdk_pixbuf_copy_area(priv->pixbuf, 
+                            priv->x_tiles[x].pos,
+                            priv->y_tiles[y].pos,
+                            src_w,
+                            src_h,
+                            pixtmp,
+                            0,0);
+
+#ifdef CLUTTER_DUMP_TILES
+       {
+         gchar  *filename;
+
+         filename = g_strdup_printf("/tmp/%i-%i-%i.png",
+                                    clutter_element_get_id(CLUTTER_ELEMENT(texture)), 
+                                    x, y);
+         printf("saving %s\n", filename);
+         gdk_pixbuf_save (pixtmp, filename , "png", NULL, NULL);
+       }
+#endif
+
+       glBindTexture(GL_TEXTURE_2D, priv->tiles[i]);
+
+       glTexParameteri(GL_TEXTURE_2D, 
+                       GL_TEXTURE_WRAP_S, 
+                       priv->repeat_x ? GL_REPEAT : GL_CLAMP);
+
+       glTexParameteri(GL_TEXTURE_2D, 
+                       GL_TEXTURE_WRAP_T, 
+                       priv->repeat_y ? GL_REPEAT : GL_CLAMP);
+
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+       glTexEnvi      (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+       
+       glPixelStorei (GL_UNPACK_ROW_LENGTH, gdk_pixbuf_get_width(pixtmp));
+       glPixelStorei (GL_UNPACK_ALIGNMENT, 
+                      gdk_pixbuf_get_n_channels (priv->pixbuf));
+       
+       if (create_textures)
+         {
+
+           glTexImage2D(GL_TEXTURE_2D, 
+                        0, 
+                        (gdk_pixbuf_get_n_channels (priv->pixbuf) == 4) ? 
+                        GL_RGBA : GL_RGB,
+                        priv->x_tiles[x].size,
+                        priv->y_tiles[y].size,
+                        /*
+                        gdk_pixbuf_get_width(pixtmp),
+                        gdk_pixbuf_get_height(pixtmp),
+                        */
+                        0, 
+                        priv->pixel_format, 
+                        priv->pixel_type, 
+                        gdk_pixbuf_get_pixels(pixtmp));
+         }
+       else 
+         {
+           /* Textures already created, so just update whats inside 
+           */
+           glTexSubImage2D (GL_TEXTURE_2D, 0, 
+                            0, 0,
+                            priv->x_tiles[x].size,
+                            priv->y_tiles[y].size,
+                            /*
+                            gdk_pixbuf_get_width(pixtmp),
+                            gdk_pixbuf_get_height(pixtmp),
+                            */
+                            priv->pixel_format, 
+                            priv->pixel_type, 
+                            gdk_pixbuf_get_pixels(pixtmp));
+         }
+
+       g_object_unref(pixtmp);
+
+       i++;
+      }
+}
+
+static void
+clutter_texture_realize (ClutterElement *element)
+{
+  ClutterTexture *texture;
+
+  texture = CLUTTER_TEXTURE(element);
+
+  CLUTTER_MARK();
+
+  if (texture->priv->pixbuf == NULL)
+    {
+      /* Dont allow realization with no pixbuf */
+      CLUTTER_DBG("*** Texture has no pixbuf cannot realize ***");
+      CLUTTER_DBG("*** flags %i ***", element->flags);
+      CLUTTER_ELEMENT_UNSET_FLAGS (element, CLUTTER_ELEMENT_REALIZED);
+      CLUTTER_DBG("*** flags %i ***", element->flags);
+      return;
+    }
+  CLUTTER_DBG("Texture realized");
+
+  if (texture->priv->tiled)
+    init_tiles(texture);
+
+  clutter_texture_sync_pixbuf (texture);
+}
+
+static void
+clutter_texture_show (ClutterElement *self)
+{
+  clutter_element_realize (self);
+}
+
+static void
+clutter_texture_hide (ClutterElement *self)
+{
+  clutter_element_unrealize (self);
+}
+
+static void
+clutter_texture_paint (ClutterElement *self)
+{
+  ClutterTexture *texture = CLUTTER_TEXTURE(self);
+  gint            x1, y1, x2, y2;
+
+  CLUTTER_DBG("@@@ for '%s' @@@", 
+             clutter_element_get_name(self) ? 
+                          clutter_element_get_name(self) : "unknown");
+  glPushMatrix();
+
+  glEnable(GL_BLEND);
+  glEnable(GL_TEXTURE_2D);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+  glColor4ub(255, 255, 255, clutter_element_get_opacity(self));
+
+  clutter_element_get_coords (self, &x1, &y1, &x2, &y2);
+  texture_render_to_gl_quad (texture, x1, y1, x2, y2);
+
+  glDisable(GL_TEXTURE_2D);
+  glDisable(GL_BLEND);
+
+  glPopMatrix();
+}
+
+static void 
+clutter_texture_dispose (GObject *object)
+{
+  ClutterTexture *self = CLUTTER_TEXTURE(object);
+  ClutterTexturePrivate *priv;
+
+  priv = self->priv;
+
+  if (priv != NULL)
+    {
+      clutter_element_unrealize (CLUTTER_ELEMENT(self));
+
+      if (priv->pixbuf != NULL)
+       {
+         g_object_unref (priv->pixbuf);
+         priv->pixbuf = NULL;
+       }
+    }
+
+  G_OBJECT_CLASS (clutter_texture_parent_class)->dispose (object);
+}
+
+static void 
+clutter_texture_finalize (GObject *object)
+{
+  ClutterTexture *self = CLUTTER_TEXTURE(object);
+
+  if (self->priv)
+    {
+      g_free(self->priv);
+      self->priv = NULL;
+    }
+
+  G_OBJECT_CLASS (clutter_texture_parent_class)->finalize (object);
+}
+
+static void
+clutter_texture_set_property (GObject      *object, 
+                             guint         prop_id,
+                             const GValue *value, 
+                             GParamSpec   *pspec)
+{
+  ClutterTexture        *texture;
+  ClutterTexturePrivate *priv;
+
+  texture = CLUTTER_TEXTURE(object);
+  priv = texture->priv;
+
+  switch (prop_id) 
+    {
+    case PROP_PIXBUF:
+      clutter_texture_set_pixbuf (texture, 
+                                 (GdkPixbuf*)g_value_get_pointer(value));
+      break;
+    case PROP_USE_TILES:
+      priv->tiled = g_value_get_boolean (value);
+      CLUTTER_DBG("Texture is tiled ? %i", priv->tiled);
+      break;
+    case PROP_MAX_TILE_WASTE:
+      priv->tile_max_waste = g_value_get_int (value);
+      break;
+    case PROP_PIXEL_TYPE:
+      priv->pixel_type = g_value_get_int (value);
+      break;
+    case PROP_PIXEL_FORMAT:
+      priv->pixel_format = g_value_get_int (value);
+      break;
+    case PROP_SYNC_SIZE:
+      priv->sync_element_size = g_value_get_boolean (value);
+      break;
+    case PROP_REPEAT_X:
+      priv->repeat_x = g_value_get_boolean (value);
+      break;
+    case PROP_REPEAT_Y:
+      priv->repeat_y = g_value_get_boolean (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+clutter_texture_get_property (GObject    *object, 
+                             guint       prop_id,
+                             GValue     *value, 
+                             GParamSpec *pspec)
+{
+  ClutterTexture        *texture;
+  ClutterTexturePrivate *priv;
+
+  texture = CLUTTER_TEXTURE(object);
+  priv = texture->priv;
+
+  switch (prop_id) 
+    {
+    case PROP_PIXBUF:
+      g_value_set_pointer (value, priv->pixbuf);
+      break;
+    case PROP_USE_TILES:
+      g_value_set_boolean (value, priv->tiled);
+      break;
+    case PROP_MAX_TILE_WASTE:
+      g_value_set_int (value, priv->tile_max_waste);
+      break;
+    case PROP_PIXEL_TYPE:
+      g_value_set_int (value, priv->pixel_type);
+      break;
+    case PROP_PIXEL_FORMAT:
+      g_value_set_int (value, priv->pixel_format);
+      break;
+    case PROP_SYNC_SIZE:
+      g_value_set_boolean (value, priv->sync_element_size);
+      break;
+    case PROP_REPEAT_X:
+      g_value_set_boolean (value, priv->repeat_x);
+      break;
+    case PROP_REPEAT_Y:
+      g_value_set_boolean (value, priv->repeat_y);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    } 
+}
+
+
+static void
+clutter_texture_class_init (ClutterTextureClass *klass)
+{
+  GObjectClass        *gobject_class;
+  ClutterElementClass *element_class;
+
+  gobject_class = (GObjectClass*)klass;
+  element_class = (ClutterElementClass*)klass;
+
+  element_class->paint      = clutter_texture_paint;
+  element_class->realize    = clutter_texture_realize;
+  element_class->unrealize  = clutter_texture_unrealize;
+  element_class->show       = clutter_texture_show;
+  element_class->hide       = clutter_texture_hide;
+
+  gobject_class->dispose      = clutter_texture_dispose;
+  gobject_class->finalize     = clutter_texture_finalize;
+  gobject_class->set_property = clutter_texture_set_property;
+  gobject_class->get_property = clutter_texture_get_property;
+
+  g_object_class_install_property
+    (gobject_class, PROP_PIXBUF,
+     g_param_spec_pointer ("pixbuf",
+                          "Pixbuf source for Texture.",
+                          "Pixbuf source for Texture.",
+                          G_PARAM_READWRITE));
+
+  g_object_class_install_property
+    (gobject_class, PROP_USE_TILES,
+     g_param_spec_boolean ("tiled",
+                          "Enable use of tiled textures",
+                          "Enables the use of tiled GL textures to more "
+                          "efficiently use available texture memory",
+                          TRUE,
+                          G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+
+  g_object_class_install_property
+    (gobject_class, PROP_SYNC_SIZE,
+     g_param_spec_boolean ("sync-size",
+                          "Sync size of element",
+                          "Auto sync size of element to underlying pixbuf"
+                          "dimentions",
+                          TRUE,
+                          G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+
+  g_object_class_install_property
+    (gobject_class, PROP_REPEAT_X,
+     g_param_spec_boolean ("repeat-x",
+                          "Tile underlying pixbuf in x direction",
+                          "Reapeat underlying pixbuf rather than scale" 
+                          "in x direction",
+                          FALSE,
+                          G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+
+  g_object_class_install_property
+    (gobject_class, PROP_REPEAT_Y,
+     g_param_spec_boolean ("repeat-y",
+                          "Tile underlying pixbuf in y direction",
+                          "Reapeat underlying pixbuf rather than scale" 
+                          "in y direction",
+                          FALSE,
+                          G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+
+  /* FIXME: non working atm */
+  g_object_class_install_property
+    (gobject_class, PROP_MAX_TILE_WASTE,
+     g_param_spec_int ("tile-waste",
+                      "Tile dimention to waste",
+                      "The maximum dimension of blank area we'll accept"
+                      "in a pixmap. Bigger values use less textures, "
+                      "smaller values less texture memory. ",
+                      0,
+                      G_MAXINT,
+                      64,
+                      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+
+  g_object_class_install_property
+    (gobject_class, PROP_PIXEL_TYPE,
+     g_param_spec_int ("pixel-type",
+                      "Texture Pixel Type",
+                      "GL texture pixel type used",
+                      0,
+                      G_MAXINT,
+                      PIXEL_TYPE,
+                      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+
+  g_object_class_install_property
+    (gobject_class, PROP_PIXEL_FORMAT,
+     g_param_spec_int ("pixel-format",
+                      "Texture pixel format",
+                      "GL texture pixel format used",
+                      0,
+                      G_MAXINT,
+                      PIXEL_FORMAT,
+                      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+
+
+
+
+  texture_signals[SIGNAL_SIZE_CHANGE] =
+    g_signal_new ("size-change",
+                 G_TYPE_FROM_CLASS (gobject_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterTextureClass, size_change),
+                 NULL, NULL,
+                 clutter_marshal_VOID__INT_INT,
+                 G_TYPE_NONE, 
+                 2, G_TYPE_INT, G_TYPE_INT);
+
+  texture_signals[SIGNAL_PIXBUF_CHANGE] =
+    g_signal_new ("pixbuf-change",
+                 G_TYPE_FROM_CLASS (gobject_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterTextureClass, pixbuf_change),
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__VOID,
+                 G_TYPE_NONE, 
+                 0); 
+
+}
+
+static void
+clutter_texture_init (ClutterTexture *self)
+{
+  ClutterTexturePrivate *priv;
+
+  priv        = g_new0 (ClutterTexturePrivate, 1);
+  priv->pixbuf = NULL;
+
+  self->priv  = priv;
+}
+
+/**
+ * clutter_texture_get_pixbuf
+ * @texture A #ClutterTexture
+ *
+ * Gets the underlying #GdkPixbuf for the #ClutterTexture
+ *
+ * Return value: The underlying #GdkPixbuf
+ **/
+GdkPixbuf*
+clutter_texture_get_pixbuf (ClutterTexture* texture)
+{
+  return texture->priv->pixbuf;
+}
+
+/**
+ * clutter_texture_set_pixbuf
+ * @texture A #ClutterTexture
+ * @pixbuf: A #GdkPixbuf
+ *
+ * Sets the underlying #GdkPixbuf for the #ClutterTexture
+ *
+ **/
+void
+clutter_texture_set_pixbuf (ClutterTexture *texture, GdkPixbuf *pixbuf)
+{
+  ClutterTexturePrivate *priv;
+  gboolean               texture_dirty = TRUE;
+
+  priv = texture->priv;
+
+  g_return_if_fail (pixbuf != NULL);
+
+  if (priv->pixbuf != NULL)
+    {
+      texture_dirty = (gdk_pixbuf_get_width (pixbuf) 
+                      != gdk_pixbuf_get_width (priv->pixbuf)
+                      ||
+                      gdk_pixbuf_get_height (pixbuf) 
+                      != gdk_pixbuf_get_height (priv->pixbuf)
+                      ||
+                      gdk_pixbuf_get_n_channels (pixbuf)
+                      != gdk_pixbuf_get_n_channels (priv->pixbuf));
+
+      g_object_unref(priv->pixbuf);
+
+      /* If the actual pixbuf has changed size/format destroy
+       * existing textures ready for recreation. If
+       * size matches we can reuse. 
+      */
+      if (texture_dirty)
+       {
+         clutter_element_unrealize (CLUTTER_ELEMENT(texture));
+       }
+      else
+       {
+         /* If texture realised sync things for change */
+         if (CLUTTER_ELEMENT_IS_REALIZED(CLUTTER_ELEMENT(texture)))
+           {
+             priv->pixbuf = pixbuf; 
+
+             /* FIXME: better locking stratergy 
+             */
+             clutter_threads_enter();
+             clutter_texture_sync_pixbuf (texture);
+             clutter_threads_leave();
+           }
+       }
+    }
+
+  clutter_threads_enter();
+      
+  priv->pixbuf = pixbuf; 
+  priv->width  = gdk_pixbuf_get_width (pixbuf);
+  priv->height = gdk_pixbuf_get_height (pixbuf);
+
+  g_object_ref (pixbuf);
+
+  if (gdk_pixbuf_get_n_channels (pixbuf) == 3)
+    priv->pixel_format = GL_RGB;
+  else
+    priv->pixel_format = GL_RGBA;
+
+  /* Force tiling if pixbuf is too big for single texture */
+  if (priv->tiled == FALSE 
+      && texture_dirty 
+      && !can_create(next_p2(priv->width), next_p2(priv->height),
+                    priv->pixel_format, priv->pixel_type))
+    priv->tiled = TRUE;
+  clutter_threads_leave();
+
+  /* FIXME: for priv->tiled = FALSE textures, pixbuf could be 
+   *        format we dont like ( ie no alpha ). therfore
+   *        we need to pixbuf_copy it into one that is.
+   *
+   * Actually I dont think this is worth worrying about...
+   * is non tiled textures are being used, texture data
+   * type can be set at initialisation.
+  */
+
+  /* reset set if element does not yet have size */
+  /* FIXME: caller has to handle this via signal, OR
+            set prop so its always handled automatically OR
+            always happens and client can resize via signal
+  if (clutter_element_width (CLUTTER_ELEMENT(texture)) == 0
+      || clutter_element_height (CLUTTER_ELEMENT(texture)) == 0)
+  */
+  if (priv->sync_element_size)
+    clutter_element_set_size (CLUTTER_ELEMENT(texture), 
+                             priv->width, 
+                             priv->height);
+
+  CLUTTER_DBG("set size %ix%i\n", priv->width, priv->height);
+
+  if (texture_dirty)
+    g_signal_emit (texture, texture_signals[SIGNAL_SIZE_CHANGE], 
+                  0, priv->width, priv->height);
+
+  if (priv->tiled && texture_dirty)
+      init_tiles (texture); 
+
+  g_signal_emit (texture, texture_signals[SIGNAL_PIXBUF_CHANGE], 0); 
+
+  /* If resized element may need resizing but paint() will do this */
+  if (CLUTTER_ELEMENT_IS_MAPPED (CLUTTER_ELEMENT(texture)))
+    clutter_element_queue_redraw (CLUTTER_ELEMENT(texture));
+}
+
+/**
+ * clutter_texture_new_from_pixbuf
+ * @pixbuf: A #GdkPixbuf
+ *
+ * Creates a new #ClutterTexture object.
+ *
+ * Return value: A newly created #ClutterTexture object.
+ **/
+ClutterElement*
+clutter_texture_new_from_pixbuf (GdkPixbuf *pixbuf)
+{
+  ClutterTexture *texture;
+
+  texture = g_object_new (CLUTTER_TYPE_TEXTURE, "pixbuf", pixbuf, NULL);
+
+  return CLUTTER_ELEMENT(texture);
+}
+
+/**
+ * clutter_texture_new
+ *
+ * Creates a new empty #ClutterTexture object.
+ *
+ * Return value: A newly created #ClutterTexture object.
+ **/
+ClutterElement*
+clutter_texture_new (void)
+{
+  ClutterTexture *texture;
+
+  texture = g_object_new (CLUTTER_TYPE_TEXTURE, NULL);
+
+  return CLUTTER_ELEMENT(texture);
+}
+
+/**
+ * clutter_texture_get_base_size
+ * @texture: A #ClutterTexture
+ * @width:   Pointer to gint to be populated with width value if non NULL.
+ * @height:  Pointer to gint to be populated with height value if non NULL.
+ *
+ * Gets the size in pixels of the untransformed underlying texture pixbuf data.
+ *
+ **/
+void
+clutter_texture_get_base_size (ClutterTexture *texture, 
+                              gint           *width,
+                              gint           *height)
+{
+  if (width)
+    *width = texture->priv->width;
+
+  if (height)
+    *height = texture->priv->height;
+
+}
+
+/**
+ * clutter_texture_bind_tile
+ * @texture A #ClutterTexture
+ * @index: Tile index to bind
+ *
+ * Proxys a call to glBindTexture a to bind an internal 'tile'. 
+ *
+ * This function is only useful for sub class implementations 
+ * and never should be called by an application.
+ **/
+void
+clutter_texture_bind_tile (ClutterTexture *texture, gint index)
+{
+  ClutterTexturePrivate *priv;
+
+  priv = texture->priv;
+  glBindTexture(GL_TEXTURE_2D, priv->tiles[index]);
+}
+
+/**
+ * clutter_texture_get_n_tiles
+ * @texture A #ClutterTexture
+ * @n_x_tiles: Location to store number of tiles in horizonally axis
+ * @n_y_tiles: Location to store number of tiles in vertical axis
+ *
+ * Retreives internal tile dimentioning.
+ *
+ * This function is only useful for sub class implementations 
+ * and never should be called by an application.
+ **/
+void
+clutter_texture_get_n_tiles (ClutterTexture *texture, 
+                            gint           *n_x_tiles,
+                            gint           *n_y_tiles)
+{
+  if (n_x_tiles)
+    *n_x_tiles = texture->priv->n_x_tiles;
+
+  if (n_y_tiles)
+    *n_y_tiles = texture->priv->n_y_tiles;
+
+}
+
+/**
+ * clutter_texture_get_x_tile_detail
+ * @texture A #ClutterTexture
+ * @x_index: X index of tile to query
+ * @pos: Location to store tiles X position
+ * @size: Location to store tiles horizontal size in pixels 
+ * @waste: Location to store tiles horizontal wastage in pixels
+ *
+ * Retreives details of a tile on x axis.
+ *
+ * This function is only useful for sub class implementations 
+ * and never should be called by an application.
+ **/
+void
+clutter_texture_get_x_tile_detail (ClutterTexture *texture, 
+                                  gint            x_index,
+                                  gint           *pos,
+                                  gint           *size,
+                                  gint           *waste)
+{
+  g_return_if_fail(x_index < texture->priv->n_x_tiles);
+
+  if (pos)
+    *pos = texture->priv->x_tiles[x_index].pos;
+
+  if (size)
+    *size = texture->priv->x_tiles[x_index].size;
+
+  if (waste)
+    *waste = texture->priv->x_tiles[x_index].waste;
+}
+
+/**
+ * clutter_texture_get_y_tile_detail
+ * @texture A #ClutterTexture
+ * @x_index: Y index of tile to query
+ * @pos: Location to store tiles Y position
+ * @size: Location to store tiles vertical size in pixels 
+ * @waste: Location to store tiles vertical wastage in pixels
+ *
+ * Retreives details of a tile on y axis.
+ *
+ * This function is only useful for sub class implementations 
+ * and never should be called by an application.
+ **/
+void
+clutter_texture_get_y_tile_detail (ClutterTexture *texture, 
+                                  gint            y_index,
+                                  gint           *pos,
+                                  gint           *size,
+                                  gint           *waste)
+{
+  g_return_if_fail(y_index < texture->priv->n_y_tiles);
+
+  if (pos)
+    *pos = texture->priv->y_tiles[y_index].pos;
+
+  if (size)
+    *size = texture->priv->y_tiles[y_index].size;
+
+  if (waste)
+    *waste = texture->priv->y_tiles[y_index].waste;
+}
+
+/**
+ * clutter_texture_has_generated_tiles
+ * @texture A #ClutterTexture
+ *
+ * Checks if #ClutterTexture has generated underlying GL texture tiles.
+ *
+ * This function is only useful for sub class implementations 
+ * and never should be called by an application.
+ *
+ * Return value: TRUE if texture has pregenerated GL tiles.
+ **/
+gboolean
+clutter_texture_has_generated_tiles (ClutterTexture *texture)
+{
+  return (texture->priv->tiles != NULL);
+}
+
+/**
+ * clutter_texture_has_generated_tiles
+ * @texture A #ClutterTexture
+ *
+ * Checks if #ClutterTexture is tiled.
+ *
+ * This function is only useful for sub class implementations 
+ * and never should be called by an application.
+ *
+ * Return value: TRUE if texture is tiled
+ **/
+gboolean
+clutter_texture_is_tiled (ClutterTexture *texture)
+{
+  return texture->priv->tiled;
+}
diff --git a/clutter/clutter-texture.h b/clutter/clutter-texture.h
new file mode 100644 (file)
index 0000000..0ab89f5
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _HAVE_CLUTTER_TEXTURE_H
+#define _HAVE_CLUTTER_TEXTURE_H
+
+#include <glib-object.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <clutter/clutter-element.h>
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_TEXTURE clutter_texture_get_type()
+
+#define CLUTTER_TEXTURE(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+  CLUTTER_TYPE_TEXTURE, ClutterTexture))
+
+#define CLUTTER_TEXTURE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), \
+  CLUTTER_TYPE_TEXTURE, ClutterTextureClass))
+
+#define CLUTTER_IS_TEXTURE(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+  CLUTTER_TYPE_TEXTURE))
+
+#define CLUTTER_IS_TEXTURE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+  CLUTTER_TYPE_TEXTURE))
+
+#define CLUTTER_TEXTURE_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+  CLUTTER_TYPE_TEXTURE, ClutterTextureClass))
+
+typedef struct ClutterTexturePrivate ClutterTexturePrivate ;
+typedef struct _ClutterTexture      ClutterTexture;
+typedef struct _ClutterTextureClass ClutterTextureClass;
+
+struct _ClutterTexture
+{
+  ClutterElement         parent;
+
+  ClutterTexturePrivate *priv;
+}; 
+
+struct _ClutterTextureClass 
+{
+  ClutterElementClass parent_class;
+
+  void (*size_change) (ClutterTexture *texture, gint width, gint height);
+  void (*pixbuf_change) (ClutterTexture *texture );
+}; 
+
+GType clutter_texture_get_type (void);
+
+ClutterElement*
+clutter_texture_new_from_pixbuf (GdkPixbuf *pixbuf);
+
+ClutterElement*
+clutter_texture_new (void);
+
+void
+clutter_texture_set_pixbuf (ClutterTexture *texture, GdkPixbuf *pixbuf);
+
+GdkPixbuf*
+clutter_texture_get_pixbuf (ClutterTexture* texture);
+
+void
+clutter_texture_get_base_size (ClutterTexture *texture, 
+                              gint           *width,
+                              gint           *height);
+
+/* Below mainly for subclassed texture based elements */
+
+void
+clutter_texture_bind_tile (ClutterTexture *texture, gint index);
+
+void
+clutter_texture_get_n_tiles (ClutterTexture *texture, 
+                            gint           *n_x_tiles,
+                            gint           *n_y_tiles);
+
+void
+clutter_texture_get_x_tile_detail (ClutterTexture *texture, 
+                                  gint            x_index,
+                                  gint           *pos,
+                                  gint           *size,
+                                  gint           *waste);
+
+void
+clutter_texture_get_y_tile_detail (ClutterTexture *texture, 
+                                  gint            y_index,
+                                  gint           *pos,
+                                  gint           *size,
+                                  gint           *waste);
+
+gboolean
+clutter_texture_has_generated_tiles (ClutterTexture *texture);
+
+gboolean
+clutter_texture_is_tiled (ClutterTexture *texture);
+
+G_END_DECLS
+
+#endif
diff --git a/clutter/clutter-timeline.c b/clutter/clutter-timeline.c
new file mode 100644 (file)
index 0000000..bcbf03f
--- /dev/null
@@ -0,0 +1,482 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "clutter-timeline.h"
+#include "clutter-main.h"
+#include "clutter-private.h"   /* for DBG */
+
+G_DEFINE_TYPE (ClutterTimeline, clutter_timeline, G_TYPE_OBJECT);
+
+#define FPS_TO_INTERVAL(f) (1000/f)
+
+struct ClutterTimelinePrivate
+{
+  guint    timeout_id;
+  guint    fps;
+  guint    nframes;
+  guint    current_frame_num;
+  gulong   last_frame_msecs;
+  gulong   start_frame_secs;
+  gboolean loop;
+};
+
+enum
+{
+  PROP_0,
+  PROP_FPS,
+  PROP_NFRAMES,
+  PROP_LOOP
+};
+
+enum
+{
+  SIGNAL_NEW_FRAME,
+  SIGNAL_COMPLETED,
+  LAST_SIGNAL
+};
+
+static int timeline_signals[LAST_SIGNAL] = { 0 };
+
+static void 
+clutter_timeline_set_property (GObject      *object, 
+                              guint         prop_id,
+                              const GValue *value, 
+                              GParamSpec   *pspec)
+{
+  ClutterTimeline        *timeline;
+  ClutterTimelinePrivate *priv;
+
+  timeline = CLUTTER_TIMELINE(object);
+  priv = timeline->priv;
+
+  switch (prop_id) 
+    {
+    case PROP_FPS:
+      clutter_timeline_set_speed (timeline, g_value_get_int (value));
+      break;
+    case PROP_NFRAMES:
+      priv->nframes = g_value_get_int (value);
+      break;
+    case PROP_LOOP:
+      priv->loop = g_value_get_boolean (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void 
+clutter_timeline_get_property (GObject    *object, 
+                              guint       prop_id,
+                              GValue     *value, 
+                              GParamSpec *pspec)
+{
+  ClutterTimeline        *timeline;
+  ClutterTimelinePrivate *priv;
+
+  timeline = CLUTTER_TIMELINE(object);
+  priv = timeline->priv;
+
+  switch (prop_id) 
+    {
+    case PROP_FPS:
+      g_value_set_int (value, priv->fps);
+      break;
+    case PROP_NFRAMES:
+      g_value_set_int (value, priv->nframes);
+      break;
+    case PROP_LOOP:
+      g_value_set_boolean (value, priv->loop);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void 
+clutter_timeline_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (clutter_timeline_parent_class)->finalize (object);
+}
+
+static void 
+clutter_timeline_dispose (GObject *object)
+{
+  ClutterTimeline *self = CLUTTER_TIMELINE(object);
+  ClutterTimelinePrivate *priv;
+
+  priv = self->priv;
+
+  if (priv != NULL)
+    {
+      if (priv->timeout_id)
+       {
+         g_source_remove (priv->timeout_id);
+         priv->timeout_id = 0;
+       }
+    }
+
+  G_OBJECT_CLASS (clutter_timeline_parent_class)->dispose (object);
+}
+
+
+static void
+clutter_timeline_class_init (ClutterTimelineClass *klass)
+{
+  GObjectClass *object_class;
+
+  object_class = (GObjectClass*) klass;
+
+  object_class->set_property = clutter_timeline_set_property;
+  object_class->get_property = clutter_timeline_get_property;
+  object_class->finalize     = clutter_timeline_finalize;
+  object_class->dispose      = clutter_timeline_dispose;
+
+  g_type_class_add_private (klass, sizeof (ClutterTimelinePrivate));
+
+  g_object_class_install_property
+    (object_class, PROP_FPS,
+     g_param_spec_int ("fps",
+                      "Frames Per Second",
+                      "Timeline frames per second",
+                      0,
+                      1000,
+                      50,
+                      G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+
+  g_object_class_install_property
+    (object_class, PROP_NFRAMES,
+     g_param_spec_int ("num-frames",
+                      "Total number of frames",
+                      "Timelines total number of frames",
+                      0,
+                      G_MAXINT,
+                      0,
+                      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+
+  g_object_class_install_property
+    (object_class, PROP_LOOP,
+     g_param_spec_boolean ("loop",
+                          "Loop",
+                          "Should the timeline automatically restart",
+                          FALSE,
+                          G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+
+  timeline_signals[SIGNAL_NEW_FRAME] =
+    g_signal_new ("new-frame",
+                 G_TYPE_FROM_CLASS (object_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterTimelineClass, new_frame),
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__INT,
+                 G_TYPE_NONE, 
+                 1, G_TYPE_INT);
+
+  timeline_signals[SIGNAL_COMPLETED] =
+    g_signal_new ("completed",
+                 G_TYPE_FROM_CLASS (object_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterTimelineClass, completed),
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__VOID,
+                 G_TYPE_NONE, 0);
+
+}
+
+static void
+clutter_timeline_init (ClutterTimeline *self)
+{
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self,
+                                          CLUTTER_TYPE_TIMELINE,
+                                          ClutterTimelinePrivate);
+}
+
+static gboolean
+timeline_timeout_func (gpointer data)
+{
+  ClutterTimeline        *timeline = CLUTTER_TIMELINE(data);
+  ClutterTimelinePrivate *priv;
+  GTimeVal                timeval;
+  gint                    nframes;
+  gulong                  msecs;
+
+  priv = timeline->priv;
+
+  /* Figure out potential frame skips */
+  g_get_current_time (&timeval);
+
+  /* Fire off signal */
+  g_signal_emit (timeline, timeline_signals[SIGNAL_NEW_FRAME], 
+                0, priv->current_frame_num);
+
+  /* Signal frees timeline ? */
+  if (timeline == NULL)
+    return FALSE;
+
+  /* Signal removes source ? */
+  if (!priv->timeout_id)
+    {
+      clutter_timeline_stop (timeline);
+      return FALSE;
+    }
+  
+  if (priv->last_frame_msecs)
+    {
+      /* Check time diff from out last call and adjust number 
+       * of frames to advance accordingly. 
+      */
+      msecs = ((timeval.tv_sec - priv->start_frame_secs) * 1000) 
+                 + (timeval.tv_usec / 1000);
+      nframes =  (msecs - priv->last_frame_msecs ) / (1000 / priv->fps);
+      if (nframes < 0) nframes = 1;
+
+      if (nframes > 1)
+       CLUTTER_DBG("*** Skipping %i frames ***", nframes);
+    }
+  else 
+    {
+      /* First frame, set up timings.*/
+      priv->start_frame_secs = timeval.tv_sec;
+      msecs     = timeval.tv_usec / 1000;
+      nframes   = 1;
+    }
+
+  priv->last_frame_msecs = msecs; 
+
+  /* Advance frames */
+  priv->current_frame_num += nframes;;
+
+  /* Handle loop or stop */
+  if (priv->current_frame_num > priv->nframes)
+    {
+      priv->current_frame_num = priv->nframes;
+
+      if (nframes > 1)
+       g_signal_emit (timeline, timeline_signals[SIGNAL_NEW_FRAME], 
+                      0, priv->current_frame_num);
+
+      if (priv->loop)
+       clutter_timeline_rewind (timeline);
+      else
+       {
+         clutter_timeline_stop (timeline);
+         g_signal_emit (timeline, timeline_signals[SIGNAL_COMPLETED], 0); 
+         return FALSE;
+       }
+    }
+
+  return TRUE;
+}
+
+/**
+ * clutter_timeline_start:
+ * @timeline: A #ClutterTimeline
+ *
+ * Starts the #ClutterTimeline playing.
+ **/
+void
+clutter_timeline_start (ClutterTimeline *timeline)
+{
+  ClutterTimelinePrivate *priv;
+
+  priv = timeline->priv;
+
+  if (!priv->timeout_id)
+    priv->timeout_id = g_timeout_add (FPS_TO_INTERVAL(priv->fps),
+                                     timeline_timeout_func,
+                                     (gpointer)timeline);
+}
+
+/**
+ * clutter_timeline_pause:
+ * @timeline: A #ClutterTimeline
+ *
+ * Pauses the #ClutterTimeline on current frame
+ **/
+void
+clutter_timeline_pause (ClutterTimeline *timeline)
+{
+  g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
+
+  if (timeline->priv->timeout_id)
+    g_source_remove (timeline->priv->timeout_id);
+
+  timeline->priv->timeout_id = 0;
+  timeline->priv->last_frame_msecs = 0;
+}
+
+/**
+ * clutter_timeline_stop:
+ * @timeline: A #ClutterTimeline
+ *
+ * Stops the #ClutterTimeline and moves to frame 0
+ **/
+void
+clutter_timeline_stop (ClutterTimeline *timeline)
+{
+  clutter_timeline_pause (timeline);
+  clutter_timeline_rewind (timeline);
+}
+
+void
+clutter_timeline_set_loop (ClutterTimeline *timeline, gboolean loop)
+{
+  timeline->priv->loop = loop;
+}
+
+/**
+ * clutter_timeline_rewind:
+ * @timeline: A #ClutterTimeline
+ *
+ * Rewinds #ClutterTimeline to frame 0.
+ **/
+void
+clutter_timeline_rewind (ClutterTimeline *timeline)
+{
+  clutter_timeline_advance (timeline, 0);
+}
+
+/**
+ * clutter_timeline_advance:
+ * @timeline: A #ClutterTimeline
+ * @nframes: Number of frames to skip
+ *
+ * Advance timeline by requested number of frames.
+ **/
+void
+clutter_timeline_skip (ClutterTimeline *timeline, guint nframes)
+{
+  ClutterTimelinePrivate *priv;
+
+  g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
+
+  priv = timeline->priv;
+
+  priv->current_frame_num += nframes;
+
+  if (priv->current_frame_num > priv->nframes)
+    priv->current_frame_num = 1;
+}
+
+/**
+ * clutter_timeline_advance:
+ * @timeline: A #ClutterTimeline
+ * @frame_num: Frame number to advance to
+ *
+ * Advance timeline to requested frame number
+ **/
+void
+clutter_timeline_advance (ClutterTimeline *timeline, guint frame_num)
+{
+  ClutterTimelinePrivate *priv;
+
+  g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
+
+  priv = timeline->priv;
+
+  if (frame_num < priv->nframes)
+    priv->current_frame_num = frame_num;
+}
+
+/**
+ * clutter_timeline_get_current_frame:
+ * @timeline: A #ClutterTimeline
+ *
+ * Request the current frame number of the timeline.
+ *
+ * Return Value: current frame number
+ **/
+gint
+clutter_timeline_get_current_frame (ClutterTimeline *timeline)
+{
+  g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0);
+
+  return timeline->priv->current_frame_num;
+}
+
+/**
+ * clutter_timeline_get_n_frames:
+ * @timeline: A #ClutterTimeline
+ *
+ * Request the totle number of frames for the #ClutterTimeline.
+ *
+ * Return Value: Number of frames for this #ClutterTimeline.
+ **/
+guint
+clutter_timeline_get_n_frames (ClutterTimeline *timeline)
+{
+  g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0);
+
+  return timeline->priv->nframes;
+}
+
+/**
+ * clutter_timeline_get_current_frame:
+ * @timeline: A #ClutterTimeline
+ * @fps: New speed of timeline as frames per second
+ *
+ * Set the speed in frames per second of the timeline.
+ **/
+void
+clutter_timeline_set_speed (ClutterTimeline *timeline, guint fps)
+{
+  ClutterTimelinePrivate *priv;
+
+  g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
+
+  priv = timeline->priv;
+
+  priv->fps = fps;
+
+  /* if the timeline is playing restart */
+  if (priv->timeout_id)
+    {
+      g_source_remove (priv->timeout_id);
+      priv->timeout_id = g_timeout_add (FPS_TO_INTERVAL(priv->fps),
+                                       timeline_timeout_func,
+                                       (gpointer)timeline);
+    }
+}
+
+/**
+ * clutter_timeline_new:
+ * @nframes: #ClutterTimeline number of frames
+ * @fps: #ClutterTimeline  frames per second
+ *
+ * Create a new  #ClutterTimeline instance.
+ *
+ * Return Value: a new #ClutterTimeline
+ */
+ClutterTimeline *
+clutter_timeline_new (guint nframes,
+                     guint fps)
+{
+  return g_object_new (CLUTTER_TYPE_TIMELINE, 
+                      "fps", fps, 
+                      "num-frames", nframes, 
+                      NULL);
+}
diff --git a/clutter/clutter-timeline.h b/clutter/clutter-timeline.h
new file mode 100644 (file)
index 0000000..9604323
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _HAVE_CLUTTER_TIMELINE_H
+#define _HAVE_CLUTTER_TIMELINE_H
+
+/* clutter-timeline.h */
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_TIMELINE clutter_timeline_get_type()
+
+#define CLUTTER_TIMELINE(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+  CLUTTER_TYPE_TIMELINE, ClutterTimeline))
+
+#define CLUTTER_TIMELINE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), \
+  CLUTTER_TYPE_TIMELINE, ClutterTimelineClass))
+
+#define CLUTTER_IS_TIMELINE(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+  CLUTTER_TYPE_TIMELINE))
+
+#define CLUTTER_IS_TIMELINE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+  CLUTTER_TYPE_TIMELINE))
+
+#define CLUTTER_TIMELINE_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+  CLUTTER_TYPE_TIMELINE, ClutterTimelineClass))
+
+typedef struct _ClutterTimeline ClutterTimeline;
+typedef struct _ClutterTimelineClass ClutterTimelineClass; 
+typedef struct ClutterTimelinePrivate ClutterTimelinePrivate;
+
+struct _ClutterTimeline
+{
+  GObject                 parent;
+  ClutterTimelinePrivate *priv;
+};
+
+struct _ClutterTimelineClass
+{
+  GObjectClass parent_class;
+  
+  void (*new_frame) (ClutterTimeline *timeline, gint frame_num);
+  void (*completed) (ClutterTimeline *timeline);
+}; 
+
+GType clutter_timeline_get_type (void);
+
+ClutterTimeline*
+clutter_timeline_new (guint nframes, guint fps);
+
+void
+clutter_timeline_set_speed (ClutterTimeline *timeline, guint fps);
+
+void
+clutter_timeline_start (ClutterTimeline *timeline);
+
+void
+clutter_timeline_pause (ClutterTimeline *timeline);
+
+void
+clutter_timeline_stop (ClutterTimeline *timeline);
+
+void
+clutter_timeline_set_loop (ClutterTimeline *timeline, gboolean loop);
+
+void
+clutter_timeline_rewind (ClutterTimeline *timeline);
+
+void
+clutter_timeline_skip (ClutterTimeline *timeline, guint nframes);
+
+void
+clutter_timeline_advance (ClutterTimeline *timeline, guint frame_num);
+
+gint
+clutter_timeline_get_current_frame (ClutterTimeline *timeline);
+
+guint
+clutter_timeline_get_n_frames (ClutterTimeline *timeline);
+
+G_END_DECLS
+
+#endif
diff --git a/clutter/clutter-util.c b/clutter/clutter-util.c
new file mode 100644 (file)
index 0000000..2b9deb4
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "clutter-util.h"
+#include "clutter-main.h"
+
+int 
+clutter_util_next_p2 (int a)
+{
+  int rval=1;
+
+  while(rval < a) 
+    rval <<= 1;
+
+  return rval;
+}
+
+#if 0
+gboolean
+clutter_util_can_create_texture (int width, int height)
+{
+  GLint new_width;
+
+  glTexImage2D (GL_PROXY_VIDEO_TEXTURE_2D, 0, GL_RGBA,
+                width, height, 0 /* border */,
+                GL_RGBA, PIXEL_TYPE, NULL);
+
+  glGetTexLevelParameteriv (GL_PROXY_VIDEO_TEXTURE_2D, 0,
+                            GL_VIDEO_TEXTURE_WIDTH, &new_width);
+
+  return new_width != 0;
+}
+#endif
diff --git a/clutter/clutter-util.h b/clutter/clutter-util.h
new file mode 100644 (file)
index 0000000..9a4d61e
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _HAVE_CLUTTER_UTIL_H
+#define _HAVE_CLUTTER_UTIL_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+int 
+clutter_util_next_p2 (int a);
+
+gboolean
+clutter_util_can_create_texture (int width, int height);
+
+G_END_DECLS
+
+#endif
diff --git a/clutter/clutter-video-texture.c b/clutter/clutter-video-texture.c
new file mode 100644 (file)
index 0000000..a2fa630
--- /dev/null
@@ -0,0 +1,1853 @@
+/* Heavily based on totems bacon-video-widget .. */
+
+#include "clutter-video-texture.h"
+#include "clutter-main.h"
+#include "clutter-private.h"   /* for DBG */
+#include "clutter-marshal.h"
+
+#include <gst/gst.h>
+#include <gst/video/gstvideosink.h>
+#include <gst/audio/gstbaseaudiosink.h>
+
+#include <GL/glx.h>
+#include <GL/gl.h>
+
+#include <glib.h>
+
+static void
+got_time_tick (GstElement          *play, 
+              gint64               time_nanos, 
+              ClutterVideoTexture *video_texture);
+static void
+stop_play_pipeline (ClutterVideoTexture *video_texture);
+
+G_DEFINE_TYPE (ClutterVideoTexture,   \
+               clutter_video_texture, \
+               CLUTTER_TYPE_TEXTURE);
+
+enum
+{
+  SIGNAL_ERROR,
+  SIGNAL_EOS,
+  SIGNAL_REDIRECT,
+  SIGNAL_TITLE_CHANGE,
+  SIGNAL_CHANNELS_CHANGE,
+  SIGNAL_TICK,
+  SIGNAL_GOT_METADATA,
+  SIGNAL_BUFFERING,
+  SIGNAL_SPEED_WARNING,
+  LAST_SIGNAL
+};
+
+/* Properties */
+enum
+{
+  PROP_0,
+  PROP_POSITION,
+  PROP_CURRENT_TIME,
+  PROP_STREAM_LENGTH,
+  PROP_PLAYING,
+  PROP_SEEKABLE,
+};
+
+struct ClutterVideoTexturePrivate
+{
+  GstElement                     *play, *video_sink, *audio_sink;
+  gboolean                        has_video, has_audio;
+  gint64                          stream_length;
+  gint64                          current_time_nanos;
+  gint64                          current_time;
+  float                           current_position;
+  gchar                          *mrl;
+
+  gboolean                        got_redirect;
+  gint                            eos_id;
+  guint                           update_id;
+
+  GstTagList                     *tagcache, *audiotags, *videotags;
+
+  const GValue                   *movie_par; /* Movie pixel aspect ratio */
+  gint                            video_fps_d, video_fps_n;
+  gint                            video_width, video_height;
+  ClutterVideoTextureAspectRatio  ratio_type;
+
+  GstMessageType                  ignore_messages_mask;
+  GstBus                         *bus;
+  gulong                          sig_bus_async;
+};
+
+static int cvt_signals[LAST_SIGNAL] = { 0 };
+
+GQuark
+clutter_video_texture_error_quark (void)
+{
+  return g_quark_from_static_string ("clutter-video-texture-error-quark");
+}
+
+/* This is a hack to avoid doing poll_for_state_change() indirectly
+ * from the bus message callback (via EOS => totem => close => wait for READY)
+ * and deadlocking there. We need something like a
+ * gst_bus_set_auto_flushing(bus, FALSE) ... */
+static gboolean
+signal_eos_delayed (gpointer user_data)
+{
+  ClutterVideoTexture *video_texture = (ClutterVideoTexture*)user_data;
+
+  g_signal_emit (video_texture, cvt_signals[SIGNAL_EOS], 0, NULL);
+
+  video_texture->priv->eos_id = 0;
+
+  return FALSE;
+}
+
+static gboolean
+query_timeout (ClutterVideoTexture *video_texture)
+{
+  ClutterVideoTexturePrivate *priv;
+  GstFormat                   fmt = GST_FORMAT_TIME;
+  gint64                      prev_len = -1, pos = -1, len = -1;
+
+  priv = video_texture->priv;
+  
+  /* check length/pos of stream */
+  prev_len = priv->stream_length;
+
+  if (gst_element_query_duration (priv->play, &fmt, &len)) 
+    {
+      if (len != -1 && fmt == GST_FORMAT_TIME) 
+       {
+         priv->stream_length = len / GST_MSECOND;
+         if (priv->stream_length != prev_len) 
+           {
+             g_signal_emit (video_texture, 
+                            cvt_signals[SIGNAL_GOT_METADATA], 0, NULL);
+           }
+       }
+    } 
+  else 
+    {
+      CLUTTER_DBG ("could not get duration");
+    }
+
+  if (gst_element_query_position (priv->play, &fmt, &pos)) 
+    {
+      if (pos != -1 && fmt == GST_FORMAT_TIME) 
+       {
+         got_time_tick (GST_ELEMENT (priv->play), pos, video_texture);
+       }
+    } 
+  else 
+    CLUTTER_DBG ("could not get position");
+
+  return TRUE;
+}
+
+static void
+got_video_size (ClutterVideoTexture *video_texture)
+{
+  GstMessage *msg;
+
+  g_return_if_fail (video_texture != NULL);
+
+  /* Do we even care about this info as comes from texture sizing ? */
+  CLUTTER_DBG("%ix%i", 
+             video_texture->priv->video_width,
+             video_texture->priv->video_height);
+
+  msg = gst_message_new_application 
+    (GST_OBJECT (video_texture->priv->play),
+        gst_structure_new ("video-size", 
+                          "width", G_TYPE_INT,
+                          video_texture->priv->video_width, 
+                          "height", G_TYPE_INT,
+                          video_texture->priv->video_height, NULL));
+
+  gst_element_post_message (video_texture->priv->play, msg);
+}
+
+
+static void
+caps_set (GObject             *obj,
+         GParamSpec          *pspec, 
+         ClutterVideoTexture *video_texture)
+{
+  ClutterVideoTexturePrivate *priv;
+  GstPad                     *pad = GST_PAD (obj);
+  GstStructure               *s;
+  GstCaps                    *caps;
+
+  priv = video_texture->priv;
+
+  if (!(caps = gst_pad_get_negotiated_caps (pad)))
+    return;
+
+  /* Get video decoder caps */
+  s = gst_caps_get_structure (caps, 0);
+
+  /* Again do we even need this - sizing info from texture signal.. */
+
+  if (s) 
+    {
+      /* We need at least width/height and framerate */
+      if (!(gst_structure_get_fraction (s, "framerate", 
+                                       &priv->video_fps_n, 
+                                       &priv->video_fps_d) 
+           &&
+           gst_structure_get_int (s, "width", &priv->video_width) &&
+           gst_structure_get_int (s, "height", &priv->video_height)))
+       return;
+
+    /* Get the movie PAR if available */
+    priv->movie_par = gst_structure_get_value (s, "pixel-aspect-ratio");
+    
+    /* Now set for real */
+    clutter_video_texture_set_aspect_ratio (video_texture, priv->ratio_type);
+  }
+
+  gst_caps_unref (caps);
+}
+
+static void
+parse_stream_info (ClutterVideoTexture *video_texture)
+{
+  ClutterVideoTexturePrivate *priv;
+  GList                      *streaminfo = NULL;
+  GstPad                     *videopad = NULL;
+
+  priv = video_texture->priv;
+
+  g_object_get (priv->play, "stream-info", &streaminfo, NULL);
+
+  streaminfo = g_list_copy (streaminfo);
+
+  g_list_foreach (streaminfo, (GFunc) g_object_ref, NULL);
+
+  for ( ; streaminfo != NULL; streaminfo = streaminfo->next) 
+    {
+      GObject    *info = streaminfo->data;
+      gint        type;
+      GParamSpec *pspec;
+      GEnumValue *val;
+
+      if (!info)
+       continue;
+
+      g_object_get (info, "type", &type, NULL);
+
+      pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (info), "type");
+      val = g_enum_get_value (G_PARAM_SPEC_ENUM (pspec)->enum_class, type);
+
+      if (!g_strcasecmp (val->value_nick, "audio")) 
+       {
+         priv->has_audio = TRUE;
+       } 
+      else if (!g_strcasecmp (val->value_nick, "video")) 
+       {
+         priv->has_video = TRUE;
+
+         if (!videopad) 
+           g_object_get (info, "object", &videopad, NULL);
+       }
+    }
+
+  if (videopad) 
+    {
+      GstCaps *caps;
+
+      if ((caps = gst_pad_get_negotiated_caps (videopad))) 
+       {
+         caps_set (G_OBJECT (videopad), NULL, video_texture);
+         gst_caps_unref (caps);
+       }
+
+      g_signal_connect (videopad, "notify::caps",
+                       G_CALLBACK (caps_set), video_texture);
+    } 
+
+  g_list_foreach (streaminfo, (GFunc) g_object_unref, NULL);
+  g_list_free (streaminfo);
+}
+
+static void
+handle_element_message (ClutterVideoTexture *video_texture, GstMessage *msg)
+{
+  const gchar *type_name = NULL;
+  gchar       *src_name;
+
+  CLUTTER_MARK();
+
+  src_name = gst_object_get_name (msg->src);
+
+  if (msg->structure)
+    type_name = gst_structure_get_name (msg->structure);
+
+  if (type_name == NULL)
+    goto unhandled;
+
+  if (strcmp (type_name, "redirect") == 0) 
+    {
+      const gchar *new_location;
+
+      new_location = gst_structure_get_string (msg->structure, "new-location");
+
+      CLUTTER_DBG ("Got redirect to '%s'", GST_STR_NULL (new_location));
+
+      if (new_location && *new_location) 
+       {
+         g_signal_emit (video_texture, 
+                        cvt_signals[SIGNAL_REDIRECT], 
+                        0, 
+                        new_location);
+         goto done;
+       }
+    }
+
+ unhandled:
+  CLUTTER_DBG ("Unhandled element message '%s' from element '%s'",
+              GST_STR_NULL (type_name), src_name);
+ done:
+  g_free (src_name);
+}
+
+static void
+handle_application_message (ClutterVideoTexture *video_texture, 
+                           GstMessage          *msg)
+{
+  const gchar *msg_name;
+
+  msg_name = gst_structure_get_name (msg->structure);
+
+  g_return_if_fail (msg_name != NULL);
+
+  CLUTTER_DBG ("Handling application message");
+
+  if (strcmp (msg_name, "notify-streaminfo") == 0) 
+    {
+      g_signal_emit (video_texture, cvt_signals[SIGNAL_GOT_METADATA], 0, NULL);
+      g_signal_emit (video_texture, cvt_signals[SIGNAL_CHANNELS_CHANGE], 0);
+    }
+  else if (strcmp (msg_name, "video-size") == 0)
+    {
+      g_signal_emit (video_texture, cvt_signals[SIGNAL_GOT_METADATA], 0, NULL);
+
+      CLUTTER_DBG("Got video size");
+    }
+  else
+    CLUTTER_DBG ("Unhandled application message %s", msg_name);
+}
+
+static void
+bus_message_cb (GstBus *bus, GstMessage *message, gpointer data)
+{
+  ClutterVideoTexturePrivate *priv;
+  ClutterVideoTexture        *video_texture = (ClutterVideoTexture*)data;
+  GstMessageType              msg_type;
+
+  g_return_if_fail (video_texture != NULL);
+  g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE(video_texture));
+
+  priv = video_texture->priv;
+
+  msg_type = GST_MESSAGE_TYPE (message);
+
+  /* somebody else is handling the message, 
+     probably in poll_for_state_change */
+  if (priv->ignore_messages_mask & msg_type) 
+    {
+      gchar *src_name = gst_object_get_name (message->src);
+      CLUTTER_DBG ("Ignoring %s message from element %s as requested",
+                  gst_message_type_get_name (msg_type), src_name);
+      g_free (src_name);
+      return;
+    }
+
+  if (msg_type != GST_MESSAGE_STATE_CHANGED && clutter_want_debug()) 
+    {
+      gchar *src_name = gst_object_get_name (message->src);
+      CLUTTER_DBG ("Handling %s message from element %s",
+                  gst_message_type_get_name (msg_type), src_name);
+      g_free (src_name);
+    }
+
+  switch (msg_type) 
+    {
+    case GST_MESSAGE_ERROR: 
+      {
+       GError *error = NULL;
+       gchar  *debug = NULL;
+
+       gst_message_parse_error (message, &error, &debug);
+
+       CLUTTER_DBG ("Error message: %s [%s]", 
+                    GST_STR_NULL (error->message),
+                    GST_STR_NULL (debug));
+
+       g_signal_emit (video_texture, 
+                      cvt_signals[SIGNAL_ERROR], 
+                      0,
+                      error->message, 
+                      TRUE, 
+                      FALSE);
+
+       g_error_free (error);
+
+       if (priv->play)
+         gst_element_set_state (priv->play, GST_STATE_NULL);
+
+       g_free (debug);
+       break;
+      }
+    case GST_MESSAGE_WARNING: 
+      {
+       GError *error = NULL;
+       gchar  *debug = NULL;
+
+       gst_message_parse_warning (message, &error, &debug);
+
+       g_warning ("%s [%s]", 
+                  GST_STR_NULL (error->message), 
+                  GST_STR_NULL (debug));
+
+       g_error_free (error);
+       g_free (debug);
+       break;
+      }
+    case GST_MESSAGE_TAG: 
+      {
+       GstTagList *tag_list, *result;
+       GstElementFactory *f;
+
+       gst_message_parse_tag (message, &tag_list);
+
+       CLUTTER_DBG ("Tags: %p", tag_list);
+
+       /* all tags */
+       result = gst_tag_list_merge (priv->tagcache, 
+                                    tag_list, 
+                                    GST_TAG_MERGE_KEEP);
+
+       if (priv->tagcache)
+         gst_tag_list_free (priv->tagcache);
+       priv->tagcache = result;
+       
+       /* media-type-specific tags */
+       if (GST_IS_ELEMENT (message->src) &&
+           (f = gst_element_get_factory (GST_ELEMENT (message->src)))) 
+         {
+           const gchar *klass = gst_element_factory_get_klass (f);
+           GstTagList **cache = NULL;
+         
+         if (g_strrstr (klass, "Video")) 
+           {
+             cache = &priv->videotags;
+           } 
+         else if (g_strrstr (klass, "Audio")) 
+           {
+             cache = &priv->audiotags;
+           }
+         
+         if (cache) 
+           {
+             result = gst_tag_list_merge (*cache, tag_list, 
+                                          GST_TAG_MERGE_KEEP);
+             if (*cache)
+               gst_tag_list_free (*cache);
+             *cache = result;
+           }
+         }
+
+       gst_tag_list_free (tag_list);
+       g_signal_emit (video_texture, cvt_signals[SIGNAL_GOT_METADATA], 0);
+       break;
+    }
+    case GST_MESSAGE_EOS:
+      CLUTTER_DBG ("GST_MESSAGE_EOS");
+
+      if (priv->eos_id == 0)
+        priv->eos_id = g_idle_add (signal_eos_delayed, video_texture);
+      break;
+    case GST_MESSAGE_BUFFERING: 
+      {
+       gint percent = 0;
+       gst_structure_get_int (message->structure, "buffer-percent", &percent);
+
+       CLUTTER_DBG ("Buffering message (%u%%)", percent);
+
+       g_signal_emit (video_texture, 
+                      cvt_signals[SIGNAL_BUFFERING], 
+                      0, 
+                      percent);
+       break;
+      }
+
+    case GST_MESSAGE_APPLICATION: 
+      handle_application_message (video_texture, message);
+      break;
+
+    case GST_MESSAGE_STATE_CHANGED: 
+      {
+       GstState old_state, new_state;
+       gchar   *src_name;
+
+       CLUTTER_DBG ("GST_MESSAGE_STATE_CHANGED");
+
+       gst_message_parse_state_changed (message, 
+                                        &old_state, &new_state, NULL);
+
+       if (old_state == new_state)
+         break;
+
+       /* we only care about playbin (pipeline) state changes */
+       if (GST_MESSAGE_SRC (message) != GST_OBJECT (priv->play))
+         break;
+
+       src_name = gst_object_get_name (message->src);
+
+       CLUTTER_DBG ("%s changed state from %s to %s", src_name,
+                    gst_element_state_get_name (old_state),
+                    gst_element_state_get_name (new_state));
+
+       g_free (src_name);
+
+      if (new_state <= GST_STATE_PAUSED) 
+       {
+         if (priv->update_id != 0) 
+           {
+             CLUTTER_DBG ("removing tick timeout");
+             g_source_remove (priv->update_id);
+             priv->update_id = 0;
+           }
+       } 
+      else if (new_state > GST_STATE_PAUSED) 
+       {
+         if (priv->update_id == 0) 
+           {
+             CLUTTER_DBG ("starting tick timeout");
+
+             priv->update_id = g_timeout_add (200, 
+                                              (GSourceFunc) query_timeout, 
+                                              video_texture);
+           }
+       }
+
+      if (old_state == GST_STATE_READY && new_state == GST_STATE_PAUSED) 
+       {
+         parse_stream_info (video_texture);
+       } 
+      else if (old_state == GST_STATE_PAUSED && new_state == GST_STATE_READY) 
+       {
+         priv->has_video = FALSE;
+         priv->has_audio = FALSE;
+
+         /* clean metadata cache */
+         if (priv->tagcache) 
+           {
+             gst_tag_list_free (priv->tagcache);
+             priv->tagcache = NULL;
+           }
+
+         if (priv->audiotags) 
+           {
+             gst_tag_list_free (priv->audiotags);
+             priv->audiotags = NULL;
+           }
+
+         if (priv->videotags) 
+           {
+             gst_tag_list_free (priv->videotags);
+             priv->videotags = NULL;
+           }
+         
+         priv->video_width = 0;
+         priv->video_height = 0;
+       }
+      break;
+    }
+
+    case GST_MESSAGE_ELEMENT:
+      handle_element_message (video_texture, message);
+      break;
+
+    case GST_MESSAGE_DURATION: 
+      {
+       CLUTTER_DBG ("GST_MESSAGE_DURATION");
+       /* force _get_stream_length() to do new duration query */
+       priv->stream_length = 0;
+       if (clutter_video_texture_get_stream_length (video_texture) == 0)
+         CLUTTER_DBG ("Failed to query duration after DURATION message?!");
+       break;
+      }
+
+    case GST_MESSAGE_CLOCK_PROVIDE:
+    case GST_MESSAGE_CLOCK_LOST:
+    case GST_MESSAGE_NEW_CLOCK:
+    case GST_MESSAGE_STATE_DIRTY:
+      break;
+    default:
+      CLUTTER_DBG ("Unhandled message of type '%s' (0x%x)", 
+                  gst_message_type_get_name (msg_type), msg_type);
+      break;
+    }
+}
+
+static void
+got_time_tick (GstElement          *play, 
+              gint64               time_nanos, 
+              ClutterVideoTexture *video_texture)
+{
+  gboolean                    seekable;
+  ClutterVideoTexturePrivate *priv;
+
+  g_return_if_fail (video_texture != NULL);
+  g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE(video_texture));
+
+  priv = video_texture->priv;
+
+  priv->current_time_nanos = time_nanos;
+  priv->current_time       = (gint64) time_nanos / GST_MSECOND;
+
+  if (priv->stream_length == 0) 
+    {
+      priv->current_position = 0;
+      seekable = clutter_video_texture_is_seekable (video_texture);
+    }
+  else
+    {
+      priv->current_position =
+       (gfloat) priv->current_time / priv->stream_length;
+      seekable = TRUE;
+    }
+
+  g_signal_emit (video_texture, 
+                cvt_signals[SIGNAL_TICK], 
+                0,
+                 priv->current_time, 
+                priv->stream_length,
+                 priv->current_position,
+                 seekable);
+}
+
+static void
+playbin_got_source (GObject             *play,
+                   GParamSpec          *pspec,
+                   ClutterVideoTexture *video_texture)
+{
+  /* Called via notify::source on playbin */
+
+  ClutterVideoTexturePrivate *priv;
+  GObject                    *source = NULL;
+
+  priv = video_texture->priv;
+
+  if (priv->tagcache) 
+    {
+      gst_tag_list_free (priv->tagcache);
+      priv->tagcache = NULL;
+    }
+
+  if (priv->audiotags) 
+    {
+      gst_tag_list_free (priv->audiotags);
+      priv->audiotags = NULL;
+    }
+
+  if (priv->videotags) 
+    {
+      gst_tag_list_free (priv->videotags);
+      priv->videotags = NULL;
+    }
+
+  g_object_get (play, "source", &source, NULL);
+
+  if (!source)
+    return;
+
+  g_object_unref (source);
+}
+
+static void
+playbin_stream_info_set (GObject             *obj, 
+                        GParamSpec          *pspec, 
+                        ClutterVideoTexture *video_texture)
+{
+  ClutterVideoTexturePrivate *priv;
+  GstMessage                 *msg;
+
+  priv = video_texture->priv;  
+
+  parse_stream_info (video_texture);
+
+  msg = gst_message_new_application (GST_OBJECT (priv->play),
+                                    gst_structure_new ("notify-streaminfo", 
+                                                       NULL));
+  gst_element_post_message (priv->play, msg);
+}
+
+
+static gboolean
+poll_for_state_change_full (ClutterVideoTexture *video_texture,
+                           GstElement          *element,
+                           GstState             state, 
+                           GError             **error, 
+                           gint64               timeout)
+{
+  GstBus                     *bus;
+  GstMessageType              events, saved_events;
+  ClutterVideoTexturePrivate *priv;
+
+  priv         = video_texture->priv;
+  bus          = gst_element_get_bus (element);
+  saved_events = priv->ignore_messages_mask;
+
+  events  = GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS;
+
+  if (element != NULL && element == priv->play) 
+    {
+      /* we do want the main handler to process state changed messages for
+       * playbin as well, otherwise it won't hook up the timeout etc. */
+      priv->ignore_messages_mask |= (events ^ GST_MESSAGE_STATE_CHANGED);
+    } 
+  else 
+    priv->ignore_messages_mask |= events;
+
+  while (TRUE) 
+    {
+      GstMessage *message;
+      GstElement *src;
+
+      message = gst_bus_poll (bus, events, timeout);
+    
+      if (!message)
+       goto timed_out;
+    
+      src = (GstElement*)GST_MESSAGE_SRC (message);
+
+      switch (GST_MESSAGE_TYPE (message)) 
+       {
+       case GST_MESSAGE_STATE_CHANGED:
+         {
+           GstState old, new, pending;
+
+           if (src == element) 
+             {
+               gst_message_parse_state_changed (message, 
+                                                &old, &new, &pending);
+               if (new == state) 
+                 {
+                   gst_message_unref (message);
+                   goto success;
+                 }
+             }
+         }
+         break;
+       case GST_MESSAGE_ERROR:
+         {
+           gchar  *debug = NULL;
+           GError *gsterror = NULL;
+
+           gst_message_parse_error (message, &gsterror, &debug);
+
+           g_warning ("Error: %s (%s)", gsterror->message, debug);
+
+           gst_message_unref (message);
+           g_error_free (gsterror);
+           g_free (debug);
+           goto error;
+         }
+         break;
+       case GST_MESSAGE_EOS:
+         g_set_error (error, CLUTTER_VIDEO_TEXTURE_ERROR,
+                      CLUTTER_VIDEO_TEXTURE_ERROR_FILE_GENERIC,
+                      "Media file could not be played.");
+         gst_message_unref (message);
+         goto error;
+         break;
+       default:
+         g_assert_not_reached ();
+         break;
+       }
+      gst_message_unref (message);
+    }
+  
+  g_assert_not_reached ();
+
+success:
+  /* state change succeeded */
+  CLUTTER_DBG ("state change to %s succeeded", 
+              gst_element_state_get_name (state));
+
+  priv->ignore_messages_mask = saved_events;
+  return TRUE;
+
+timed_out:
+  /* it's taking a long time to open -- just tell totem it was ok, this allows
+   * the user to stop the loading process with the normal stop button */
+  CLUTTER_DBG ("state change to %s timed out, returning success and handling "
+              "errors asynchroneously", gst_element_state_get_name (state));
+  priv->ignore_messages_mask = saved_events;
+  return TRUE;
+
+error:
+  CLUTTER_DBG ("error while waiting for state change to %s: %s",
+              gst_element_state_get_name (state),
+              (error && *error) ? (*error)->message : "unknown");
+  priv->ignore_messages_mask = saved_events;
+  return FALSE;
+}
+
+static gboolean
+poll_for_state_change (ClutterVideoTexture *video_texture, 
+                      GstElement          *element,
+                      GstState             state, 
+                      GError             **error)
+{
+  return poll_for_state_change_full (video_texture, 
+                                    element, 
+                                    state, 
+                                    error, 
+                                    GST_SECOND/4 );
+}
+
+static void
+fakesink_handoff_cb (GstElement *fakesrc, 
+                    GstBuffer  *buffer,
+                    GstPad     *pad, 
+                    gpointer    user_data)
+{
+
+  GstStructure  *structure;
+  int            width, height;
+  GdkPixbuf     *pixb;
+
+  structure = gst_caps_get_structure(GST_CAPS(buffer->caps), 0);
+  gst_structure_get_int(structure, "width", &width);
+  gst_structure_get_int(structure, "height", &height);
+
+  /* FIXME: We really dont want to do this every time as gobject creation
+   *        really need a clutter_texture_set_from_data call ?
+  */
+  pixb = gdk_pixbuf_new_from_data (GST_BUFFER_DATA (buffer),
+                                  GDK_COLORSPACE_RGB, 
+                                  FALSE, 
+                                  8, 
+                                  width, 
+                                  height,
+                                  (3 * width + 3) &~ 3,
+                                  NULL,
+                                  NULL);
+
+  if (pixb)
+    {
+      clutter_texture_set_pixbuf (CLUTTER_TEXTURE(user_data), pixb);
+      g_object_unref(G_OBJECT(pixb));
+    }
+}
+
+static void 
+clutter_video_texture_finalize (GObject *object)
+{
+  ClutterVideoTexture        *self;
+  ClutterVideoTexturePrivate *priv; 
+
+  self = CLUTTER_VIDEO_TEXTURE(object); 
+  priv = self->priv;
+
+  if (priv->bus) 
+    {
+      /* make bus drop all messages to make sure none of our callbacks is ever
+       * called again (main loop might be run again to display error dialog) */
+      gst_bus_set_flushing (priv->bus, TRUE);
+
+      if (priv->sig_bus_async)
+       g_signal_handler_disconnect (priv->bus, priv->sig_bus_async);
+      
+      gst_object_unref (priv->bus);
+      priv->bus = NULL;
+    }
+
+  if (priv->mrl)
+    g_free (priv->mrl);
+  priv->mrl = NULL;
+  
+  if (priv->play != NULL && GST_IS_ELEMENT (priv->play)) 
+    {
+      gst_element_set_state (priv->play, GST_STATE_NULL);
+      gst_object_unref (priv->play);
+      priv->play = NULL;
+    }
+
+  if (priv->update_id) 
+    {
+      g_source_remove (priv->update_id);
+      priv->update_id = 0;
+    }
+
+  if (priv->tagcache) 
+    {
+      gst_tag_list_free (priv->tagcache);
+      priv->tagcache = NULL;
+    }
+
+  if (priv->audiotags) 
+    {
+      gst_tag_list_free (priv->audiotags);
+      priv->audiotags = NULL;
+    }
+
+  if (priv->videotags) 
+    {
+      gst_tag_list_free (priv->videotags);
+      priv->videotags = NULL;
+    }
+
+  if (priv->eos_id != 0)
+    g_source_remove (priv->eos_id);
+
+  g_free (priv);
+
+  self->priv = NULL;
+
+  G_OBJECT_CLASS (clutter_video_texture_parent_class)->finalize (object);
+}
+
+static void
+clutter_video_texture_set_property (GObject      *object, 
+                                   guint         property_id,
+                                   const GValue *value, 
+                                   GParamSpec   *pspec)
+{
+  switch (property_id)
+    {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+static void
+clutter_video_texture_get_property (GObject    *object, 
+                                   guint       property_id,
+                                   GValue     *value, 
+                                   GParamSpec *pspec)
+{
+  ClutterVideoTexture *video_texture;
+
+  video_texture = CLUTTER_VIDEO_TEXTURE (object);
+
+  switch (property_id)
+    {
+      case PROP_POSITION:
+       g_value_set_int64 (value, 
+                          clutter_video_texture_get_position (video_texture));
+       break;
+      case PROP_STREAM_LENGTH:
+       g_value_set_int64 (value,
+           clutter_video_texture_get_stream_length (video_texture));
+       break;
+      case PROP_PLAYING:
+       g_value_set_boolean (value,
+           clutter_video_texture_is_playing (video_texture));
+       break;
+      case PROP_SEEKABLE:
+       g_value_set_boolean (value,
+           clutter_video_texture_is_seekable (video_texture));
+       break;
+      default:
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+
+static void
+clutter_video_texture_class_init (ClutterVideoTextureClass *klass)
+{
+  GObjectClass        *object_class;
+  ClutterElementClass *element_class;
+
+  object_class = (GObjectClass*)klass;
+  element_class = (ClutterElementClass*)klass;
+
+  object_class->finalize = clutter_video_texture_finalize;
+  object_class->set_property = clutter_video_texture_set_property;
+  object_class->get_property = clutter_video_texture_get_property;
+
+  /* Properties */
+  g_object_class_install_property (object_class, PROP_POSITION,
+                                  g_param_spec_int ("position", NULL, NULL,
+                                                    0, G_MAXINT, 0,
+                                                    G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_STREAM_LENGTH,
+                                  g_param_spec_int64 ("stream_length", NULL,
+                                                    NULL, 0, G_MAXINT64, 0,
+                                                    G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_PLAYING,
+                                  g_param_spec_boolean ("playing", NULL,
+                                                        NULL, FALSE,
+                                                        G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_SEEKABLE,
+                                  g_param_spec_boolean ("seekable", NULL,
+                                                        NULL, FALSE,
+                                                        G_PARAM_READABLE));
+
+  /* Signals */
+  cvt_signals[SIGNAL_ERROR] =
+    g_signal_new ("error",
+                 G_TYPE_FROM_CLASS (object_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterVideoTextureClass, error),
+                 NULL, NULL,
+                 clutter_marshal_VOID__STRING_BOOLEAN_BOOLEAN,
+                 G_TYPE_NONE, 3, G_TYPE_STRING,
+                 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
+
+  cvt_signals[SIGNAL_EOS] =
+    g_signal_new ("eos",
+                 G_TYPE_FROM_CLASS (object_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterVideoTextureClass, eos),
+                 NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+  cvt_signals[SIGNAL_GOT_METADATA] =
+    g_signal_new ("got-metadata",
+                 G_TYPE_FROM_CLASS (object_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterVideoTextureClass, got_metadata),
+                 NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+  cvt_signals[SIGNAL_REDIRECT] =
+    g_signal_new ("got-redirect",
+                 G_TYPE_FROM_CLASS (object_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterVideoTextureClass, got_redirect),
+                 NULL, NULL, g_cclosure_marshal_VOID__STRING,
+                 G_TYPE_NONE, 1, G_TYPE_STRING);
+
+  cvt_signals[SIGNAL_TITLE_CHANGE] =
+    g_signal_new ("title-change",
+                 G_TYPE_FROM_CLASS (object_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterVideoTextureClass, title_change),
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__STRING,
+                 G_TYPE_NONE, 1, G_TYPE_STRING);
+
+  cvt_signals[SIGNAL_CHANNELS_CHANGE] =
+    g_signal_new ("channels-change",
+                 G_TYPE_FROM_CLASS (object_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterVideoTextureClass, channels_change),
+                 NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+  cvt_signals[SIGNAL_TICK] =
+    g_signal_new ("tick",
+                 G_TYPE_FROM_CLASS (object_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterVideoTextureClass, tick),
+                 NULL, NULL,
+                 clutter_marshal_VOID__INT64_INT64_FLOAT_BOOLEAN,
+                 G_TYPE_NONE, 4, G_TYPE_INT64, G_TYPE_INT64, G_TYPE_FLOAT,
+                  G_TYPE_BOOLEAN);
+
+  cvt_signals[SIGNAL_BUFFERING] =
+    g_signal_new ("buffering",
+                 G_TYPE_FROM_CLASS (object_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterVideoTextureClass, buffering),
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
+
+  cvt_signals[SIGNAL_SPEED_WARNING] =
+    g_signal_new ("speed-warning",
+                 G_TYPE_FROM_CLASS (object_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterVideoTextureClass, speed_warning),
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__VOID,
+                 G_TYPE_NONE, 0);
+
+}
+
+
+static void
+clutter_video_texture_init (ClutterVideoTexture *video_texture)
+{
+  ClutterVideoTexturePrivate *priv;
+  GstElement                 *audio_sink, *video_sink, *bin, *capsfilter;
+  GstCaps                    *filtercaps;
+  GstPad                     *ghost_pad;
+
+  priv                 = g_new0 (ClutterVideoTexturePrivate, 1);
+  video_texture->priv  = priv;
+
+  priv->ratio_type     = CLUTTER_VIDEO_TEXTURE_AUTO;
+
+  priv->play = gst_element_factory_make ("playbin", "play");
+  
+  if (!priv->play) 
+    {
+      g_warning ("Could not create element 'playbin'");
+      return;
+    }
+
+  priv->bus = gst_element_get_bus (priv->play);
+  gst_bus_add_signal_watch (priv->bus);
+  priv->sig_bus_async = g_signal_connect (priv->bus, 
+                                         "message", 
+                                         G_CALLBACK (bus_message_cb),
+                                         video_texture);
+
+  audio_sink = gst_element_factory_make ("gconfaudiosink", "audio-sink");
+
+  if (audio_sink == NULL) 
+    {
+      g_warning ("Could not create element 'gconfaudiosink' trying autosink");
+      audio_sink = gst_element_factory_make ("autoaudiosink", "audio-sink");
+
+      if (audio_sink == NULL)
+       {
+         g_warning ("Could not create element 'autoaudiosink' "
+                    "trying fakesink");
+         audio_sink = gst_element_factory_make ("fakesink",  
+                                                "audio-fake-sink");
+         if (audio_sink == NULL)
+           {
+             g_warning ("Could not create element 'fakesink' for audio, giving up. ");
+           }
+       }
+    }
+  
+  priv->audio_sink = audio_sink;
+
+  video_sink = gst_element_factory_make ("fakesink", "fakesink");
+
+  if (video_sink == NULL) 
+    {
+      g_warning ("Could not create element 'fakesink' for video playback");
+      return;
+    }
+
+  bin = gst_bin_new  ("video-bin");
+
+  capsfilter = gst_element_factory_make ("capsfilter", "vfilter");
+
+  filtercaps 
+    = gst_caps_new_simple("video/x-raw-rgb",
+                         "bpp", G_TYPE_INT, 24,
+                         "depth", G_TYPE_INT, 24,
+                         "endianness", G_TYPE_INT, G_BIG_ENDIAN, 
+                         "red_mask", G_TYPE_INT, 0xff0000 /* >> 8 for 24bpp */, 
+                         "green_mask", G_TYPE_INT, 0xff00,
+                         "blue_mask", G_TYPE_INT,  0xff,
+                         "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
+                         "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
+                         "framerate", GST_TYPE_FRACTION_RANGE, 
+                         0, 1, G_MAXINT, 1, 
+                         NULL);
+
+  g_object_set(G_OBJECT(capsfilter), "caps", filtercaps, NULL);
+
+  gst_bin_add(GST_BIN(bin), capsfilter);
+  gst_bin_add(GST_BIN(bin), video_sink);
+
+  gst_element_link (capsfilter, video_sink);
+
+  ghost_pad = gst_ghost_pad_new ("sink", 
+                                gst_element_get_pad (capsfilter, "sink"));
+
+  gst_element_add_pad (bin, ghost_pad);
+
+  g_object_set (G_OBJECT(video_sink), 
+               "signal-handoffs", TRUE, 
+               "sync", TRUE,
+               NULL);
+
+  g_signal_connect(G_OBJECT (video_sink), "handoff",
+                  G_CALLBACK(fakesink_handoff_cb), video_texture);
+
+  priv->video_sink = bin;
+
+  if (priv->video_sink)
+    g_object_set (priv->play, "video-sink", bin, NULL);
+
+  if (priv->audio_sink)
+    g_object_set (priv->play, "audio-sink", audio_sink, NULL);
+  
+  g_signal_connect (priv->play, "notify::source",
+                   G_CALLBACK (playbin_got_source), video_texture);
+  g_signal_connect (priv->play, "notify::stream-info",
+                   G_CALLBACK (playbin_stream_info_set), video_texture);
+  return;
+}
+
+ClutterElement*
+clutter_video_texture_new (void)
+{
+  ClutterVideoTexture        *video_texture;
+
+  video_texture = g_object_new (CLUTTER_TYPE_VIDEO_TEXTURE, 
+                               "tiled", FALSE, 
+                               "pixel-format", GL_RGB,
+                               NULL);
+
+  return CLUTTER_ELEMENT(video_texture);
+}
+
+gboolean
+clutter_video_texture_open (ClutterVideoTexture *video_texture,
+                           const gchar         *mrl, 
+                           const gchar         *subtitle_uri, 
+                           GError             **error)
+{
+  ClutterVideoTexturePrivate *priv;
+  gboolean                    ret;
+
+  priv = video_texture->priv;
+
+  g_return_val_if_fail (video_texture != NULL, FALSE);
+  g_return_val_if_fail (mrl != NULL, FALSE);
+  g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE(video_texture), FALSE);
+  g_return_val_if_fail (priv->play != NULL, FALSE);
+  
+  if (priv->mrl && strcmp (priv->mrl, mrl) == 0) 
+    return TRUE;
+
+  /* this allows non-URI type of files in the thumbnailer and so on */
+  if (priv->mrl)
+    g_free (priv->mrl);
+
+  if (mrl[0] == '/') 
+    {
+      priv->mrl = g_strdup_printf ("file://%s", mrl);
+    }
+  else 
+    {
+      if (strchr (mrl, ':')) 
+       {
+         priv->mrl = g_strdup (mrl);
+       } 
+      else 
+       {
+         gchar *cur_dir = g_get_current_dir ();
+         if (!cur_dir) 
+           {
+             g_set_error (error, CLUTTER_VIDEO_TEXTURE_ERROR,
+                          CLUTTER_VIDEO_TEXTURE_ERROR_GENERIC,
+                          "Failed to retrieve working directory");
+             return FALSE;
+           }
+         priv->mrl = g_strdup_printf ("file://%s/%s", cur_dir, mrl);
+         g_free (cur_dir);
+       }
+    }
+
+  priv->got_redirect = FALSE;
+  priv->has_video    = FALSE;
+  priv->has_audio    = FALSE;
+  priv->stream_length = 0;
+  
+  if (g_strrstr (priv->mrl, "#subtitle:")) 
+    {
+      gchar **uris;
+      gchar *subtitle_uri;
+
+      uris = g_strsplit (priv->mrl, "#subtitle:", 2);
+      /* Try to fix subtitle uri if needed */
+      if (uris[1][0] == '/') 
+       {
+         subtitle_uri = g_strdup_printf ("file://%s", uris[1]);
+       }
+      else 
+       {
+         if (strchr (uris[1], ':')) 
+           {
+             subtitle_uri = g_strdup (uris[1]);
+           } 
+         else 
+           {
+             gchar *cur_dir = g_get_current_dir ();
+             if (!cur_dir) 
+               {
+                 g_set_error (error, CLUTTER_VIDEO_TEXTURE_ERROR,
+                              CLUTTER_VIDEO_TEXTURE_ERROR_GENERIC,
+                              "Failed to retrieve working directory");
+                 return FALSE;
+               }
+
+             subtitle_uri = g_strdup_printf ("file://%s/%s", 
+                                             cur_dir, uris[1]);
+             g_free (cur_dir);
+           }
+       }
+
+      g_object_set (priv->play, 
+                   "uri", priv->mrl,
+                   "suburi", subtitle_uri, 
+                   NULL);
+      g_free (subtitle_uri);
+      g_strfreev (uris);
+    } 
+  else 
+    {
+      g_object_set (priv->play, 
+                   "uri", priv->mrl,
+                   "suburi", subtitle_uri, 
+                   NULL);
+    }
+  
+  gst_element_set_state (priv->play, GST_STATE_PAUSED);
+
+  ret = poll_for_state_change (video_texture, 
+                              priv->play, 
+                              GST_STATE_PAUSED, 
+                              NULL);
+
+  if (!ret) 
+    {
+      priv->ignore_messages_mask |= GST_MESSAGE_ERROR;
+      stop_play_pipeline (video_texture);
+      g_free (priv->mrl);
+      priv->mrl = NULL;
+    }
+  else
+    g_signal_emit (video_texture, cvt_signals[SIGNAL_CHANNELS_CHANGE], 0);
+
+  return ret;
+}
+
+gboolean
+clutter_video_texture_play (ClutterVideoTexture *video_texture, 
+                           GError             ** error)
+{
+  ClutterVideoTexturePrivate *priv;
+  gboolean                    ret;
+
+  priv = video_texture->priv;
+
+  g_return_val_if_fail (video_texture != NULL, FALSE);
+  g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE(video_texture), FALSE);
+  g_return_val_if_fail (priv->play != NULL, FALSE);
+
+  gst_element_set_state (priv->play, GST_STATE_PLAYING); 
+
+  ret = poll_for_state_change (video_texture, 
+                              priv->play, 
+                              GST_STATE_PLAYING, 
+                              error);
+  return ret;
+}
+
+void
+clutter_video_texture_pause (ClutterVideoTexture *video_texture)
+{
+  g_return_if_fail (video_texture != NULL);
+  g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture));
+  g_return_if_fail (GST_IS_ELEMENT (video_texture->priv->play));
+
+  CLUTTER_DBG ("Pausing");
+
+  gst_element_set_state (GST_ELEMENT (video_texture->priv->play), 
+                        GST_STATE_PAUSED);
+}
+
+
+gboolean
+clutter_video_texture_can_direct_seek (ClutterVideoTexture *video_texture)
+{
+  g_return_val_if_fail (video_texture != NULL, FALSE);
+  g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), FALSE);
+  g_return_val_if_fail (GST_IS_ELEMENT (video_texture->priv->play), FALSE);
+
+  if (!video_texture->priv->mrl)
+    return FALSE;
+
+  /* (instant seeking only make sense with video, hence no cdda:// here) */
+  if (g_str_has_prefix (video_texture->priv->mrl, "file://") ||
+      g_str_has_prefix (video_texture->priv->mrl, "dvd://") ||
+      g_str_has_prefix (video_texture->priv->mrl, "vcd://"))
+    return TRUE;
+
+  return FALSE;
+}
+
+gboolean
+clutter_video_texture_seek_time (ClutterVideoTexture *video_texture, 
+                                gint64               time, 
+                                GError             **gerror)
+{
+  g_return_val_if_fail (video_texture != NULL, FALSE);
+  g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), FALSE);
+  g_return_val_if_fail (GST_IS_ELEMENT (video_texture->priv->play), FALSE);
+
+  got_time_tick (video_texture->priv->play, time * GST_MSECOND, video_texture);
+  
+  gst_element_seek (video_texture->priv->play, 
+                   1.0,
+                   GST_FORMAT_TIME, 
+                   GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT,
+                   GST_SEEK_TYPE_SET, 
+                   time * GST_MSECOND,
+                   GST_SEEK_TYPE_NONE, 
+                   GST_CLOCK_TIME_NONE);
+
+  gst_element_get_state (video_texture->priv->play, 
+                        NULL, NULL, 100 * GST_MSECOND);
+  return TRUE;
+}
+
+gboolean
+clutter_video_texture_seek (ClutterVideoTexture *video_texture, 
+                           float                position, 
+                           GError             **error)
+{
+  gint64 seek_time, length_nanos;
+
+  g_return_val_if_fail (video_texture != NULL, FALSE);
+  g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), FALSE);
+  g_return_val_if_fail (GST_IS_ELEMENT (video_texture->priv->play), FALSE);
+
+  length_nanos = (gint64) (video_texture->priv->stream_length * GST_MSECOND);
+  seek_time    = (gint64) (length_nanos * position);
+
+  return clutter_video_texture_seek_time (video_texture, 
+                                         seek_time / GST_MSECOND, error);
+}
+
+static void
+stop_play_pipeline (ClutterVideoTexture *video_texture)
+{
+  GstElement *playbin = video_texture->priv->play;
+  GstState    current_state;
+
+  /* first go to ready, that way our state change handler gets to see
+   * our state change messages (before the bus goes to flushing) and
+   * cleans up */
+  gst_element_get_state (playbin, &current_state, NULL, 0);
+
+  if (current_state > GST_STATE_READY) 
+    {
+      GError *err = NULL;
+
+      gst_element_set_state (playbin, GST_STATE_READY);
+      poll_for_state_change_full (video_texture, 
+                                 playbin, 
+                                 GST_STATE_READY, &err, -1);
+      if (err)
+       g_error_free (err);
+    }
+
+  /* now finally go to null state */
+  gst_element_set_state (playbin, GST_STATE_NULL);
+  gst_element_get_state (playbin, NULL, NULL, -1);
+}
+
+void
+clutter_video_texture_stop (ClutterVideoTexture *video_texture)
+{
+  g_return_if_fail (video_texture != NULL);
+  g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture));
+  g_return_if_fail (GST_IS_ELEMENT (video_texture->priv->play));
+
+  stop_play_pipeline (video_texture);
+  
+  /* Reset position to 0 when stopping */
+  got_time_tick (GST_ELEMENT (video_texture->priv->play), 0, video_texture);
+}
+
+gboolean
+clutter_video_texture_can_set_volume (ClutterVideoTexture *video_texture)
+{
+  g_return_val_if_fail (video_texture != NULL, FALSE);
+  g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), FALSE);
+  g_return_val_if_fail (GST_IS_ELEMENT (video_texture->priv->play), FALSE);
+  
+  return TRUE;
+}
+
+void
+clutter_video_texture_set_volume (ClutterVideoTexture *video_texture, 
+                                 int                  volume)
+{
+  g_return_if_fail (video_texture != NULL);
+  g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture));
+  g_return_if_fail (GST_IS_ELEMENT (video_texture->priv->play));
+
+  if (clutter_video_texture_can_set_volume (video_texture) != FALSE)
+  {
+    volume = CLAMP (volume, 0, 100);
+    g_object_set (video_texture->priv->play, "volume",
+                 (gdouble) (1. * volume / 100), NULL);
+  }
+}
+
+int
+clutter_video_texture_get_volume (ClutterVideoTexture *video_texture)
+{
+  gdouble vol;
+
+  g_return_val_if_fail (video_texture != NULL, -1);
+  g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), -1);
+  g_return_val_if_fail (GST_IS_ELEMENT (video_texture->priv->play), -1);
+
+  g_object_get (G_OBJECT (video_texture->priv->play), "volume", &vol, NULL);
+
+  return (gint) (vol * 100 + 0.5);
+}
+
+gint64
+clutter_video_texture_get_current_time (ClutterVideoTexture *video_texture)
+{
+  g_return_val_if_fail (video_texture != NULL, -1);
+  g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), -1);
+
+  return video_texture->priv->current_time;
+}
+
+gint64
+clutter_video_texture_get_stream_length (ClutterVideoTexture *video_texture)
+{
+  ClutterVideoTexturePrivate *priv;
+
+  g_return_val_if_fail (video_texture != NULL, -1);
+  g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), -1);
+
+  priv = video_texture->priv;
+
+  if (priv->stream_length == 0  && priv->play != NULL) 
+    {
+      GstFormat fmt = GST_FORMAT_TIME;
+      gint64    len = -1;
+
+      if (gst_element_query_duration (priv->play, &fmt, &len) && len != -1)
+       priv->stream_length = len / GST_MSECOND;
+    }
+
+  return priv->stream_length;
+}
+
+gboolean
+clutter_video_texture_is_playing (ClutterVideoTexture *video_texture)
+{
+  GstState cur, pending;
+
+  g_return_val_if_fail (video_texture != NULL, FALSE);
+  g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), FALSE);
+  g_return_val_if_fail (GST_IS_ELEMENT (video_texture->priv->play), FALSE);
+
+  gst_element_get_state (video_texture->priv->play, &cur, &pending, 0);
+
+  if (cur == GST_STATE_PLAYING || pending == GST_STATE_PLAYING)
+    return TRUE;
+
+  return FALSE;
+}
+
+gboolean
+clutter_video_texture_is_seekable (ClutterVideoTexture *video_texture)
+{
+  gboolean res;
+
+  g_return_val_if_fail (video_texture != NULL, FALSE);
+  g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), FALSE);
+  g_return_val_if_fail (GST_IS_ELEMENT (video_texture->priv->play), FALSE);
+
+  if (video_texture->priv->stream_length == 0) 
+    res = (clutter_video_texture_get_stream_length (video_texture) > 0);
+  else 
+    res = (video_texture->priv->stream_length > 0);
+
+  return res;
+}
+
+float
+clutter_video_texture_get_position (ClutterVideoTexture  *video_texture)
+{
+  g_return_val_if_fail (video_texture != NULL, -1);
+  g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), -1);
+
+  return video_texture->priv->current_position;
+}
+
+void
+clutter_video_texture_set_aspect_ratio (ClutterVideoTexture  *video_texture,
+                                       ClutterVideoTextureAspectRatio ratio)
+{
+  g_return_if_fail (video_texture != NULL);
+  g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture));
+
+  video_texture->priv->ratio_type = ratio;
+  got_video_size (video_texture);
+}
+
+ClutterVideoTextureAspectRatio
+clutter_video_texture_get_aspect_ratio (ClutterVideoTexture  *video_texture)
+{
+  g_return_val_if_fail (video_texture != NULL, 0);
+  g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), 0);
+
+  return video_texture->priv->ratio_type;
+}
+
+/* Metadata */
+
+static const struct _metadata_map_info 
+{
+  ClutterVideoTextureMetadataType type;
+  const gchar *str;
+} metadata_str_map[] = {
+  { CLUTTER_INFO_TITLE,        "title" },
+  { CLUTTER_INFO_ARTIST,       "artist" },
+  { CLUTTER_INFO_YEAR,         "year" },
+  { CLUTTER_INFO_ALBUM,        "album" },
+  { CLUTTER_INFO_DURATION,     "duration" },
+  { CLUTTER_INFO_TRACK_NUMBER, "track-number" },
+  { CLUTTER_INFO_HAS_VIDEO,    "has-video" },
+  { CLUTTER_INFO_DIMENSION_X,  "dimension-x" },
+  { CLUTTER_INFO_DIMENSION_Y,  "dimension-y" },
+  { CLUTTER_INFO_VIDEO_BITRATE,"video-bitrate" },
+  { CLUTTER_INFO_VIDEO_CODEC,  "video-codec" },
+  { CLUTTER_INFO_FPS,          "fps" },
+  { CLUTTER_INFO_HAS_AUDIO,    "has-audio" },
+  { CLUTTER_INFO_AUDIO_BITRATE,"audio-bitrate" },
+  { CLUTTER_INFO_AUDIO_CODEC,  "audio-codec" }
+};
+
+static const gchar*
+get_metadata_type_name (ClutterVideoTextureMetadataType type)
+{
+  guint i;
+  for (i = 0; i < G_N_ELEMENTS (metadata_str_map); ++i) 
+    {
+      if (metadata_str_map[i].type == type)
+       return metadata_str_map[i].str;
+    }
+  return "unknown";
+}
+
+static void
+get_metadata_string (ClutterVideoTexture            *video_texture,
+                    ClutterVideoTextureMetadataType type,
+                    GValue                         *value)
+{
+  ClutterVideoTexturePrivate *priv;
+  char                       *string = NULL;
+  gboolean                    res = FALSE;
+
+  priv = video_texture->priv;
+
+  g_value_init (value, G_TYPE_STRING);
+
+  if (priv->play == NULL || priv->tagcache == NULL)
+    {
+      g_value_set_string (value, NULL);
+      return;
+    }
+
+  switch (type)
+    {
+    case CLUTTER_INFO_TITLE:
+      res = gst_tag_list_get_string_index (priv->tagcache,
+                                          GST_TAG_TITLE, 0, &string);
+      break;
+    case CLUTTER_INFO_ARTIST:
+      res = gst_tag_list_get_string_index (priv->tagcache,
+                                          GST_TAG_ARTIST, 0, &string);
+      break;
+    case CLUTTER_INFO_YEAR: 
+      {
+       GDate *date;
+       if ((res = gst_tag_list_get_date (priv->tagcache,
+                                         GST_TAG_DATE, &date))) 
+         {
+           string = g_strdup_printf ("%d", g_date_get_year (date));
+           g_date_free (date);
+         }
+       break;
+      }
+    case CLUTTER_INFO_ALBUM:
+      res = gst_tag_list_get_string_index (priv->tagcache,
+                                          GST_TAG_ALBUM, 0, &string);
+      break;
+    case CLUTTER_INFO_VIDEO_CODEC:
+      res = gst_tag_list_get_string (priv->tagcache,
+                                    GST_TAG_VIDEO_CODEC, &string);
+      break;
+    case CLUTTER_INFO_AUDIO_CODEC:
+      res = gst_tag_list_get_string (priv->tagcache,
+                                    GST_TAG_AUDIO_CODEC, &string);
+      break;
+    default:
+      g_assert_not_reached ();
+    }
+
+  if (res) 
+    {
+      g_value_take_string (value, string);
+      CLUTTER_DBG ("%s = '%s'", get_metadata_type_name (type), string);
+    } 
+  else
+    g_value_set_string (value, NULL);
+
+  return;
+}
+
+static void
+get_metadata_int (ClutterVideoTexture            *video_texture,
+                 ClutterVideoTextureMetadataType type,
+                 GValue                         *value)
+{
+  ClutterVideoTexturePrivate *priv;
+  int                         integer = 0;
+
+  priv = video_texture->priv;
+
+  g_value_init (value, G_TYPE_INT);
+
+  if (priv->play == NULL)
+    {
+      g_value_set_int (value, 0);
+      return;
+    }
+
+  switch (type)
+    {
+    case CLUTTER_INFO_DURATION:
+      integer = clutter_video_texture_get_stream_length (video_texture) / 1000;
+      break;
+    case CLUTTER_INFO_TRACK_NUMBER:
+      if (!gst_tag_list_get_uint (priv->tagcache,
+                                 GST_TAG_TRACK_NUMBER, (guint *) &integer))
+        integer = 0;
+      break;
+    case CLUTTER_INFO_DIMENSION_X:
+      integer = priv->video_width;
+      break;
+    case CLUTTER_INFO_DIMENSION_Y:
+      integer = priv->video_height;
+      break;
+    case CLUTTER_INFO_FPS:
+      if (priv->video_fps_d > 0) 
+       {
+         /* Round up/down to the nearest integer framerate */
+         integer = (priv->video_fps_n + priv->video_fps_d/2) /
+           priv->video_fps_d;
+       }
+      else
+        integer = 0;
+      break;
+    case CLUTTER_INFO_AUDIO_BITRATE:
+      if (priv->audiotags == NULL)
+        break;
+      if (gst_tag_list_get_uint (priv->audiotags, GST_TAG_BITRATE,
+          (guint *)&integer) ||
+          gst_tag_list_get_uint (priv->audiotags, GST_TAG_NOMINAL_BITRATE,
+          (guint *)&integer)) {
+        integer /= 1000;
+      }
+      break;
+    case CLUTTER_INFO_VIDEO_BITRATE:
+      if (priv->videotags == NULL)
+        break;
+      if (gst_tag_list_get_uint (priv->videotags, GST_TAG_BITRATE,
+                                (guint *)&integer) ||
+          gst_tag_list_get_uint (priv->videotags, GST_TAG_NOMINAL_BITRATE,
+                                (guint *)&integer)) {
+        integer /= 1000;
+      }
+      break;
+    default:
+      g_assert_not_reached ();
+    }
+
+  g_value_set_int (value, integer);
+  CLUTTER_DBG ("%s = %d", get_metadata_type_name (type), integer);
+
+  return;
+}
+
+static void
+get_metadata_bool (ClutterVideoTexture            *video_texture,
+                  ClutterVideoTextureMetadataType type,
+                  GValue                         *value)
+{
+  ClutterVideoTexturePrivate *priv;
+  gboolean                    boolean = FALSE;
+
+  priv = video_texture->priv;
+
+  g_value_init (value, G_TYPE_BOOLEAN);
+
+  if (priv->play == NULL) 
+    {
+      g_value_set_boolean (value, FALSE);
+      return;
+    }
+
+  switch (type)
+    {
+    case CLUTTER_INFO_HAS_VIDEO:
+      boolean = priv->has_video;
+      /* if properties dialog, show the metadata we
+       * have even if we cannot decode the stream */
+      if (!boolean
+         && priv->tagcache != NULL 
+         && gst_structure_has_field ((GstStructure *) priv->tagcache,
+                                     GST_TAG_VIDEO_CODEC)) 
+        boolean = TRUE;
+      break;
+    case CLUTTER_INFO_HAS_AUDIO:
+      boolean = priv->has_audio;
+      /* if properties dialog, show the metadata we
+       * have even if we cannot decode the stream */
+      if (!boolean
+         && priv->tagcache != NULL 
+         && gst_structure_has_field ((GstStructure *) priv->tagcache,
+                                     GST_TAG_AUDIO_CODEC)) 
+        boolean = TRUE;
+      break;
+    default:
+      g_assert_not_reached ();
+  }
+
+  g_value_set_boolean (value, boolean);
+  CLUTTER_DBG ("%s = %s", get_metadata_type_name (type), 
+                                        (boolean) ? "yes" : "no");
+  return;
+}
+
+void
+clutter_video_texture_get_metadata (ClutterVideoTexture *video_texture,
+                                   ClutterVideoTextureMetadataType type,
+                                   GValue                         *value)
+{
+  g_return_if_fail (video_texture != NULL);
+  g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture));
+  g_return_if_fail (GST_IS_ELEMENT (video_texture->priv->play));
+
+  switch (type)
+    {
+    case CLUTTER_INFO_TITLE:
+    case CLUTTER_INFO_ARTIST:
+    case CLUTTER_INFO_YEAR:
+    case CLUTTER_INFO_ALBUM:
+    case CLUTTER_INFO_VIDEO_CODEC:
+    case CLUTTER_INFO_AUDIO_CODEC:
+      get_metadata_string (video_texture, type, value);
+      break;
+    case CLUTTER_INFO_DURATION:
+    case CLUTTER_INFO_DIMENSION_X:
+    case CLUTTER_INFO_DIMENSION_Y:
+    case CLUTTER_INFO_FPS:
+    case CLUTTER_INFO_AUDIO_BITRATE:
+    case CLUTTER_INFO_VIDEO_BITRATE:
+    case CLUTTER_INFO_TRACK_NUMBER:
+      get_metadata_int (video_texture, type, value);
+      break;
+    case CLUTTER_INFO_HAS_VIDEO:
+    case CLUTTER_INFO_HAS_AUDIO:
+      get_metadata_bool (video_texture, type, value);
+      break;
+    default:
+      g_return_if_reached ();
+    }
+
+  return;
+}
diff --git a/clutter/clutter-video-texture.h b/clutter/clutter-video-texture.h
new file mode 100644 (file)
index 0000000..94e6b63
--- /dev/null
@@ -0,0 +1,213 @@
+#ifndef _HAVE_CLUTTER_VIDEO_TEXTURE_H
+#define _HAVE_CLUTTER_VIDEO_TEXTURE_H
+
+#include <glib-object.h>
+#include <clutter/clutter-element.h>
+#include <clutter/clutter-texture.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_VIDEO_TEXTURE clutter_video_texture_get_type()
+
+#define CLUTTER_VIDEO_TEXTURE(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+  CLUTTER_TYPE_VIDEO_TEXTURE, ClutterVideoTexture))
+
+#define CLUTTER_VIDEO_TEXTURE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), \
+  CLUTTER_TYPE_VIDEO_TEXTURE, ClutterVideoTextureClass))
+
+#define CLUTTER_IS_VIDEO_TEXTURE(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+  CLUTTER_TYPE_VIDEO_TEXTURE))
+
+#define CLUTTER_IS_VIDEO_TEXTURE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+  CLUTTER_TYPE_VIDEO_TEXTURE))
+
+#define CLUTTER_VIDEO_TEXTURE_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+  CLUTTER_TYPE_VIDEO_TEXTURE, ClutterVideoTextureClass))
+
+typedef struct ClutterVideoTexturePrivate ClutterVideoTexturePrivate ;
+typedef struct _ClutterVideoTexture ClutterVideoTexture;
+typedef struct _ClutterVideoTextureClass ClutterVideoTextureClass;
+
+
+#define CLUTTER_VIDEO_TEXTURE_ERROR clutter_video_texture_error_quark()
+
+typedef enum
+{
+  /* Plugins */
+  CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_PLUGIN,
+  CLUTTER_VIDEO_TEXTURE_ERROR_NO_PLUGIN_FOR_FILE,
+  CLUTTER_VIDEO_TEXTURE_ERROR_VIDEO_PLUGIN,
+  CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_BUSY,
+       
+  /* File */
+  CLUTTER_VIDEO_TEXTURE_ERROR_BROKEN_FILE,
+  CLUTTER_VIDEO_TEXTURE_ERROR_FILE_GENERIC,
+  CLUTTER_VIDEO_TEXTURE_ERROR_FILE_PERMISSION,
+  CLUTTER_VIDEO_TEXTURE_ERROR_FILE_ENCRYPTED,
+  CLUTTER_VIDEO_TEXTURE_ERROR_FILE_NOT_FOUND,
+       
+  /* Devices */
+  CLUTTER_VIDEO_TEXTURE_ERROR_DVD_ENCRYPTED,
+  CLUTTER_VIDEO_TEXTURE_ERROR_INVALID_DEVICE,
+       
+  /* Network */
+  CLUTTER_VIDEO_TEXTURE_ERROR_UNKNOWN_HOST,
+  CLUTTER_VIDEO_TEXTURE_ERROR_NETWORK_UNREACHABLE,
+  CLUTTER_VIDEO_TEXTURE_ERROR_CONNECTION_REFUSED,
+       
+  /* Generic */
+  CLUTTER_VIDEO_TEXTURE_ERROR_UNVALID_LOCATION,
+  CLUTTER_VIDEO_TEXTURE_ERROR_GENERIC,
+  CLUTTER_VIDEO_TEXTURE_ERROR_CODEC_NOT_HANDLED,
+  CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_ONLY,
+  CLUTTER_VIDEO_TEXTURE_ERROR_CANNOT_CAPTURE,
+  CLUTTER_VIDEO_TEXTURE_ERROR_READ_ERROR,
+  CLUTTER_VIDEO_TEXTURE_ERROR_PLUGIN_LOAD,
+  CLUTTER_VIDEO_TEXTURE_ERROR_STILL_IMAGE,
+  CLUTTER_VIDEO_TEXTURE_ERROR_EMPTY_FILE
+} ClutterVideoTextureError;
+
+GQuark clutter_video_texture_error_quark (void);
+
+typedef enum
+{
+  CLUTTER_VIDEO_TEXTURE_AUTO,
+  CLUTTER_VIDEO_TEXTURE_SQUARE,
+  CLUTTER_VIDEO_TEXTURE_FOURBYTHREE,
+  CLUTTER_VIDEO_TEXTURE_ANAMORPHIC,
+  CLUTTER_VIDEO_TEXTURE_DVB
+} ClutterVideoTextureAspectRatio;
+
+struct _ClutterVideoTexture
+{
+  ClutterTexture              parent;
+  ClutterVideoTexturePrivate *priv;
+}; 
+
+struct _ClutterVideoTextureClass 
+{
+  ClutterTextureClass parent_class;
+
+  void (*error) (ClutterVideoTexture *cvt, const char *message,
+                gboolean playback_stopped, gboolean fatal);
+  void (*eos) (ClutterVideoTexture *cvt);
+  void (*got_metadata) (ClutterVideoTexture *cvt);
+  void (*got_redirect) (ClutterVideoTexture *cvt, const char *mrl);
+  void (*title_change) (ClutterVideoTexture *cvt, const char *title);
+  void (*channels_change) (ClutterVideoTexture *cvt);
+  void (*tick) (ClutterVideoTexture *cvt, 
+               gint64 current_time, 
+               gint64 stream_length,
+               float current_position, 
+               gboolean seekable);
+  void (*buffering) (ClutterVideoTexture *cvt, guint progress);
+  void (*speed_warning) (ClutterVideoTexture *cvt);
+}; 
+
+GType clutter_video_texture_get_type (void);
+
+ClutterElement*
+clutter_video_texture_new (void);
+
+gboolean
+clutter_video_texture_open (ClutterVideoTexture *video_texture,
+                           const gchar         *mrl, 
+                           const gchar         *subtitle_uri, 
+                           GError             **error);
+
+gboolean
+clutter_video_texture_play (ClutterVideoTexture *video_texture, 
+                           GError             ** error);
+
+void
+clutter_video_texture_pause (ClutterVideoTexture *video_texture);
+
+gboolean
+clutter_video_texture_can_direct_seek (ClutterVideoTexture *video_texture);
+
+gboolean
+clutter_video_texture_seek_time (ClutterVideoTexture *video_texture, 
+                                gint64               time, 
+                                GError             **gerror);
+
+gboolean
+clutter_video_texture_seek (ClutterVideoTexture *video_texture, 
+                           float                position, 
+                           GError             **error);
+
+void
+clutter_video_texture_stop (ClutterVideoTexture *video_texture);
+
+gboolean
+clutter_video_texture_can_set_volume (ClutterVideoTexture *video_texture);
+
+void
+clutter_video_texture_set_volume (ClutterVideoTexture *video_texture, 
+                                 int                  volume);
+int
+clutter_video_texture_get_volume (ClutterVideoTexture *video_texture);
+
+gint64
+clutter_video_texture_get_current_time (ClutterVideoTexture *video_texture);
+
+gint64
+clutter_video_texture_get_stream_length (ClutterVideoTexture *video_texture);
+
+gboolean
+clutter_video_texture_is_playing (ClutterVideoTexture *video_texture);
+
+gboolean
+clutter_video_texture_is_seekable (ClutterVideoTexture * video_texture);
+
+float
+clutter_video_texture_get_position (ClutterVideoTexture  *video_texture);
+
+void
+clutter_video_texture_set_aspect_ratio (ClutterVideoTexture  *video_texture,
+                                       ClutterVideoTextureAspectRatio ratio);
+
+ClutterVideoTextureAspectRatio
+clutter_video_texture_get_aspect_ratio (ClutterVideoTexture  *video_texture);
+
+/* Metadata 
+ * FIXME: This should probably go in some kind of genric 'Media' class
+ *        You would open the media, get a media object and then pass 
+ *        that to the video texture. media object could handle being
+ *        just a metadata reader etc...
+*/
+typedef enum 
+{
+    CLUTTER_INFO_TITLE,
+    CLUTTER_INFO_ARTIST,
+    CLUTTER_INFO_YEAR,
+    CLUTTER_INFO_ALBUM,
+    CLUTTER_INFO_DURATION,
+    CLUTTER_INFO_TRACK_NUMBER,
+    /* Video */
+    CLUTTER_INFO_HAS_VIDEO,
+    CLUTTER_INFO_DIMENSION_X,
+    CLUTTER_INFO_DIMENSION_Y,
+    CLUTTER_INFO_VIDEO_BITRATE,
+    CLUTTER_INFO_VIDEO_CODEC,
+    CLUTTER_INFO_FPS,
+    /* Audio */
+    CLUTTER_INFO_HAS_AUDIO,
+    CLUTTER_INFO_AUDIO_BITRATE,
+    CLUTTER_INFO_AUDIO_CODEC,
+} ClutterVideoTextureMetadataType;
+
+
+void
+clutter_video_texture_get_metadata (ClutterVideoTexture *video_texture,
+                                   ClutterVideoTextureMetadataType type,
+                                   GValue                         *value);
+
+G_END_DECLS
+
+#endif
diff --git a/clutter/clutter.h b/clutter/clutter.h
new file mode 100644 (file)
index 0000000..9b6cd64
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef _HAVE_CLUTTER_H
+#define _HAVE_CLUTTER_H
+
+#include "clutter-keysyms.h" 
+#include "clutter-main.h"
+#include "clutter-color.h"
+#include "clutter-util.h"
+#include "clutter-event.h"
+#include "clutter-timeline.h"
+#include "clutter-stage.h"
+#include "clutter-element.h"
+#include "clutter-rectangle.h"
+#include "clutter-group.h"
+#include "clutter-texture.h"
+#include "clutter-clone-texture.h"
+#include "clutter-video-texture.h"
+#include "clutter-label.h"
+#include "clutter-enum-types.h"
+
+#endif
diff --git a/clutter/fonts.c b/clutter/fonts.c
deleted file mode 100644 (file)
index dc76726..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-#include "fonts.h"
-
-ClutterFont*
-font_new (const char *face)
-{
-  ClutterFont          *font; 
-  PangoFontDescription *desc;
-
-  font = util_malloc0(sizeof(ClutterFont));
-
-  font->font_map = pango_ft2_font_map_new ();
-
-  pango_ft2_font_map_set_resolution (PANGO_FT2_FONT_MAP (font->font_map),
-                                    96., 96.);
-  
-  desc = pango_font_description_from_string (face);
-
-  font->context 
-    = pango_ft2_font_map_create_context (PANGO_FT2_FONT_MAP (font->font_map));
-
-  pango_context_set_font_description (font->context, desc);
-
-  pango_font_description_free (desc);
-
-  cltr_font_ref(font);
-
-  return font;
-}
-
-#if 0
-static int
-decoration_get_title_width (LmcDecoration *decoration)
-{
-  int title_space;
-  int width;
-  
-  title_space = (decoration->window_width
-                + lmc_theme->border_info.left
-                + lmc_theme->border_info.right
-                - lmc_theme->border_info.left_unscaled
-                - lmc_theme->border_info.right_unscaled);
-  title_space = MAX (title_space, 0);
-
-  pango_layout_get_pixel_size (decoration->layout, &width, NULL);
-
-  return MIN (width + TITLE_RIGHT_PAD, title_space);
-}
-#endif
-
-static void
-get_layout_bitmap (PangoLayout    *layout,
-                  FT_Bitmap      *bitmap,
-                  PangoRectangle *ink)
-{
-  PangoRectangle ink_rect;
-  
-  pango_layout_get_extents (layout, &ink_rect, NULL);
-
-  printf("%s() gave width:%i, height %i\n", __func__, ink->width, ink->height);
-
-  /* XXX why the >> 10 */
-  ink->x      = ink_rect.x >> 10;
-  ink->width  = ((ink_rect.x + ink_rect.width + 1023) >> 10) - ink->x;
-  ink->y      = ink_rect.y >> 10;
-  ink->height = ((ink_rect.y + ink_rect.height + 1023) >> 10) - ink->y;
-
-  if (ink->width == 0)
-    ink->width = 1;
-  if (ink->height == 0)
-    ink->height = 1;
-
-  bitmap->width      = ink->width;
-  bitmap->pitch      = (bitmap->width + 3) & ~3;
-  bitmap->rows       = ink->height;
-  bitmap->buffer     = malloc (bitmap->pitch * bitmap->rows);
-  bitmap->num_grays  = 256;
-  bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
-
-  memset (bitmap->buffer, 0, bitmap->pitch * bitmap->rows);
-
-  pango_ft2_render_layout (bitmap, layout, - ink->x, - ink->y);
-}
-
-static void
-draw_layout_on_pixbuf (PangoLayout       *layout,
-                      Pixbuf            *pixb,
-                      const PixbufPixel *color,
-                      int                x,
-                      int                y,
-                      int                clip_x,
-                      int                clip_y,
-                      int                clip_width,
-                      int                clip_height)
-{
-  PangoRectangle ink;
-  FT_Bitmap      bitmap;
-  int            i, j;
-  unsigned char *layout_bits;
-
-  get_layout_bitmap (layout, &bitmap, &ink);
-
-  layout_bits = bitmap.buffer;
-  
-  for (j = y + ink.y; j < y + ink.y + ink.height; j++)
-    {
-      if (j >= clip_y && j < clip_y + clip_height)
-       {
-         int start_x, end_x;
-
-         start_x = MAX (x + ink.x, clip_x);
-         end_x   = MIN (x + ink.x + ink.width, clip_x + clip_width);
-
-         if (start_x < end_x)
-           {
-             unsigned char *b = layout_bits + (start_x - (x + ink.x));
-
-             for (i = start_x ; i < end_x; i++)
-               {
-                 PixbufPixel pixel;
-
-#if 0
-                 int tr1, tg1, tb1, tr2, tg2, tb2;
-                 int a = (*b * color->a + 0x80) >> 8;
-
-                 /* 
-                    this is wrong for when the backing has an
-                     alpha of zero. we need a different algorythm
-                     to handle that - so we can overlay just a font
-                     text texture with no bg
-                 */
-
-                 if (!a)
-                   { b++; continue; }
-
-                 pixbuf_get_pixel (pixb, i, j, &pixel);
-
-                 tr1 = (255 - a) * pixel.r + 0x80;
-                 tr2 = a * color->r + 0x80;
-                 pixel.r = ((tr1 + (tr1 >> 8)) >> 8) + ((tr2 + (tr2 >> 8)) >> 8);
-                 tg1 = (255 - a) * pixel.g + 0x80;
-                 tg2 = a * color->g + 0x80;
-                 pixel.g = ((tg1 + (tg1 >> 8)) >> 8) + ((tg2 + (tg2 >> 8)) >> 8);
-                 tb1 = (255 - a) * pixel.b + 0x80;
-                 tb2 = a * color->b + 0x80;
-                 pixel.b = ((tb1 + (tb1 >> 8)) >> 8) + ((tb2 + (tb2 >> 8)) >> 8);
-                 tb1 = (255 - a) * pixel.a + 0x80;
-                 tb2 = a * color->a + 0x80;
-                 pixel.a = ((tb1 + (tb1 >> 8)) >> 8) + ((tb2 + (tb2 >> 8)) >> 8);
-#endif           
-                 pixel.r = color->r; 
-                 pixel.g = color->g; 
-                 pixel.b = color->b; 
-                 pixel.a = (( *b * color->a ) >> 8 );
-
-                 pixbuf_set_pixel (pixb, i, j, &pixel);
-                 b++;
-               }
-           }
-       }
-
-      layout_bits += bitmap.pitch;
-    }
-
-  free (bitmap.buffer);
-}
-
-
-void
-font_draw(ClutterFont *font, 
-         Pixbuf      *pixb, 
-         const char  *text,
-         int          x, 
-         int          y,
-         PixbufPixel *p)
-{
-  int layout_width, layout_height;
-  PangoLayout *layout;
-
-  layout = pango_layout_new (font->context);
-
-  pango_layout_set_text (layout, text, -1);
-
-  /* cant rely on just clip - need to set layout width too ? */
-  /* pango_layout_set_width(layout, (pixb->width - x) << 10); */
-
-  draw_layout_on_pixbuf (layout, pixb, p, x, y, 
-                        x, 
-                        y, 
-                        pixb->width  - x,
-                        pixb->height - y);
-
-  g_object_unref(G_OBJECT(layout));
-}
-
-void
-font_get_pixel_size (ClutterFont *font, 
-                    const char  *text,
-                    int         *width,
-                    int         *height)
-{
-  PangoLayout *layout;
-
-  layout = pango_layout_new (font->context);
-
-  pango_layout_set_text (layout, text, -1);
-
-  pango_layout_get_pixel_size (layout, width, height);
-
-  printf("%s() gave width:%i, height %i\n", __func__, *width, *height);
-
-  g_object_unref(G_OBJECT(layout));
-}
-
-void
-cltr_font_ref(CltrFont *font)
-{
-  font->refcnt++;
-}
-
-void
-cltr_font_unref(CltrFont *font)
-{
-  font->refcnt--;
-
-  if (font->refcnt <= 0)
-    {
-      /* XXX free up pango stuff  */
-      g_free(font);
-    }
-}
diff --git a/clutter/fonts.h b/clutter/fonts.h
deleted file mode 100644 (file)
index eb10351..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef _HAVE_FONTS_H
-#define _HAVE_FONTS_H
-
-#include <pango/pangoft2.h>
-
-#include "pixbuf.h"
-#include "util.h"
-
-/* Code based on stuff found in luminocity */
-
-typedef struct ClutterFont ClutterFont;
-
-struct ClutterFont
-{
-  PangoFontMap *font_map;
-  PangoContext *context;
-  int refcnt;
-};
-
-typedef ClutterFont CltrFont ;         /* Tsk Tsk .. */
-
-ClutterFont*
-font_new (const char *face);
-
-void
-cltr_font_ref(CltrFont *font);
-
-void
-cltr_font_unref(CltrFont *font);
-
-void
-font_draw(ClutterFont *font, 
-         Pixbuf      *pixb, 
-         const char  *text,
-         int          x, 
-         int          y,
-         PixbufPixel *p);
-
-void
-font_get_pixel_size (ClutterFont *font, 
-                    const char  *text,
-                    int         *width,
-                    int         *height);
-
-#endif
diff --git a/clutter/pixbuf.c b/clutter/pixbuf.c
deleted file mode 100644 (file)
index d23594a..0000000
+++ /dev/null
@@ -1,1232 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <string.h> /* For memset() */
-#include <unistd.h> /* For read() */
-
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <sys/mman.h> /* For mmap()/munmap() */
-#include <sys/types.h>
-
-
-#include <png.h>
-#include <jpeglib.h>
-
-#include "pixbuf.h"
-#include "util.h"
-
-#define CLTR_CLAMP(x, y)  ((x) > (y)) ? (y) : (x);
-
-static void
-fix_png_write_data (png_structp   png, 
-                   png_row_infop row_info, 
-                   png_bytep     data)
-{
-  int i;
-
-  for (i = 0; i < row_info->rowbytes; i += 4) 
-    {
-      unsigned char *b = &data[i];
-      unsigned int pixel;
-
-      memcpy (&pixel, b, sizeof (unsigned int));
-
-      b[0] = (pixel >> 24) & 0xff; 
-      b[1] = (pixel >> 16) & 0xff; 
-      b[2] = (pixel >> 8) & 0xff; 
-      b[3] = pixel & 0xff;
-    }
-}
-
-static void
-fix_png_read_data (png_structp   png, 
-                  png_row_infop row_info, 
-                  png_bytep     data)
-{
-  int i;
-
-  for (i = 0; i < row_info->rowbytes; i += 4) 
-    {
-      unsigned char *b = &data[i];
-      unsigned int pixel;
-
-      memcpy (&pixel, b, sizeof (unsigned int));
-
-      b[0] = (pixel >> 24) & 0xff; 
-      b[1] = (pixel >> 16) & 0xff; 
-      b[2] = (pixel >> 8) & 0xff; 
-      b[3] = pixel & 0xff;
-    }
-}
-
-int
-pixbuf_write_png(Pixbuf *pixb, char *filename)
-{
-  FILE         *f;
-  int           i;
-  png_struct   *png;
-  png_info     *info;
-  png_byte    **rows;
-  png_color_16  white;
-    
-  f = fopen (filename, "w");
-
-  rows = malloc (pixb->height * sizeof(png_byte*));
-
-  for (i = 0; i < pixb->height; i++) 
-    {
-      rows[i] = pixb->data + (i * (pixb->width));
-    }
-
-  png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-
-  info = png_create_info_struct (png);
-
-  png_init_io (png, f);
-
-  png_set_IHDR (png, info,
-               pixb->width, pixb->height, 8,
-               PNG_COLOR_TYPE_RGB_ALPHA, 
-               PNG_INTERLACE_NONE,
-               PNG_COMPRESSION_TYPE_DEFAULT,
-               PNG_FILTER_TYPE_DEFAULT);
-
-  white.red = 0xff;
-  white.blue = 0xff;
-  white.green = 0xff;
-  png_set_bKGD (png, info, &white);
-
-  /* png_set_write_user_transform_fn (png, unpremultiply_data); */
-
-  /* png_set_bgr (png); */
-
-  /* png_set_filler(png, 0, PNG_FILLER_BEFORE); */
-
-  /*
-  png_set_packswap(png); 
-
-  png_set_swap(png);
-  */
-
-  png_set_write_user_transform_fn (png, fix_png_write_data);
-
-  png_write_info (png, info);
-  png_write_image (png, rows);
-  png_write_end (png, info);
-
-  png_destroy_write_struct (&png, &info);
-
-  free (rows);
-  fclose (f);
-
-  return 1;
-}
-
-static int*
-load_png_file( const char *file, 
-              int        *width, 
-              int        *height) 
-{
-  FILE *fd;
-  /* GLubyte *data; */
-  int  *data;
-  unsigned char header[8];
-  int          bit_depth, color_type;
-  png_uint_32  png_width, png_height, i, rowbytes;
-  png_structp  png_ptr;
-  png_infop    info_ptr;
-  png_bytep   *row_pointers;
-
-  if ((fd = fopen( file, "rb" )) == NULL) return NULL;
-
-  /* check header etc */
-
-  fread(header, 1, 8, fd);
-
-  if (!png_check_sig(header, 8)) 
-    {
-      fclose(fd);
-      return NULL;
-    }
-
-  png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-
-  if (!png_ptr) 
-    {
-      fclose(fd);
-      return NULL;
-    }
-
-  info_ptr = png_create_info_struct(png_ptr);
-
-  if (!info_ptr) 
-    {
-      png_destroy_read_struct( &png_ptr, (png_infopp)NULL, (png_infopp)NULL);
-      fclose(fd);
-      return NULL;
-    }
-
-  if (setjmp( png_ptr->jmpbuf ) ) 
-    {
-      png_destroy_read_struct( &png_ptr, &info_ptr, NULL);
-      fclose(fd);
-      return NULL;
-    }
-
-  png_init_io( png_ptr, fd );
-
-  png_set_sig_bytes( png_ptr, 8);
-  png_read_info( png_ptr, info_ptr);
-
-  png_get_IHDR( png_ptr, info_ptr, 
-               &png_width, &png_height, &bit_depth, 
-               &color_type, NULL, NULL, NULL);
-
-  *width =  (int) png_width;
-  *height = (int) png_height;
-
-  /* Tranform to req 8888 */
-
-  if (bit_depth == 16 ) png_set_strip_16(png_ptr);      /* 16 -> 8 */
-
-  if (bit_depth < 8)   png_set_packing(png_ptr);        /* 1,2,4 -> 8 */
-
-  if (( color_type == PNG_COLOR_TYPE_GRAY ) ||
-            ( color_type == PNG_COLOR_TYPE_GRAY_ALPHA ))
-    png_set_gray_to_rgb(png_ptr);
-
-  if (( color_type == PNG_COLOR_TYPE_GRAY ) ||
-      ( color_type == PNG_COLOR_TYPE_RGB ))
-    png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_BEFORE); /* req 1.2.7 */
-  else          /*  */
-    {
-      if (( color_type == PNG_COLOR_TYPE_PALETTE )||
-         ( png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS )))
-       png_set_expand(png_ptr);
-
-      /* Needed to fix endianess */
-      png_set_read_user_transform_fn (png_ptr, fix_png_read_data);    
-    }
-
-
-  /* png_set_packswap(png_ptr); */
-
-  png_read_update_info( png_ptr, info_ptr);
-  /* Now load the actual data */
-
-  rowbytes = png_get_rowbytes( png_ptr, info_ptr);
-
-  data = (int *) malloc( (rowbytes*(*height + 1)));
-
-  row_pointers = (png_bytep *) malloc( (*height)*sizeof(png_bytep));
-
-  if (( data == NULL ) || ( row_pointers == NULL )) 
-    {
-      png_destroy_read_struct( &png_ptr, &info_ptr, NULL);
-      if (data) free(data);
-      if (row_pointers) free(row_pointers);
-      return NULL;
-    }
-
-  for ( i = 0;  i < *height; i++ )
-    row_pointers[i] = (png_bytep) data + i*rowbytes;
-
-  png_read_image( png_ptr, row_pointers );
-  png_read_end( png_ptr, NULL);
-
-  free(row_pointers);
-  png_destroy_read_struct( &png_ptr, &info_ptr, NULL);
-  fclose(fd);
-
-  return data;
-}
-
-struct local_error_mgr 
-{
-  struct jpeg_error_mgr pub;   /* "public" fields */
-  jmp_buf setjmp_buffer;       /* for return to caller */
-};
-
-typedef struct local_error_mgr * local_error_ptr;
-
-static void
-_jpeg_error_exit (j_common_ptr cinfo)
-{
-  local_error_ptr err = (local_error_ptr) cinfo->err;
-  (*cinfo->err->output_message) (cinfo);
-  longjmp(err->setjmp_buffer, 1);
-}
-
-static int* 
-load_jpg_file( const char *file, 
-              int        *width, 
-              int        *height)
-{
-  struct jpeg_decompress_struct cinfo;
-  struct local_error_mgr jerr;
-  FILE    *infile;             /* source file */
-  JSAMPLE *buffer;             /* Output row buffer */
-  int      row_stride;         /* physical row width in output buffer */
-  int     *data = NULL, *d = NULL;
-
-  if ((infile = fopen(file, "rb")) == NULL) 
-    return NULL;
-
-  cinfo.err = jpeg_std_error(&jerr.pub);
-  jerr.pub.error_exit = _jpeg_error_exit;
-
-  if (setjmp(jerr.setjmp_buffer)) {
-    jpeg_destroy_decompress(&cinfo);
-    fclose(infile);
-    return NULL;
-  }
-
-  jpeg_create_decompress(&cinfo);
-  jpeg_stdio_src(&cinfo, infile);
-  jpeg_read_header(&cinfo, TRUE);
-
-  cinfo.do_fancy_upsampling = FALSE;
-  cinfo.do_block_smoothing  = FALSE;
-  cinfo.out_color_space     = JCS_RGB;
-  cinfo.scale_num           = 1;
-
-  jpeg_start_decompress(&cinfo);
-
-  if( cinfo.output_components != 3 ) 
-    {
-      /*
-      fprintf( stderr, "mbpixbuf: jpegs with %d channles not supported\n", 
-              cinfo.output_components );
-      */
-      jpeg_finish_decompress(&cinfo);
-      jpeg_destroy_decompress(&cinfo);
-      return NULL;
-    }
-
-  *width     = cinfo.output_width;
-  *height    = cinfo.output_height;
-  d = data = malloc(*width * *height * 4 );
-
-  row_stride = cinfo.output_width * cinfo.output_components;
-  buffer = malloc( sizeof(JSAMPLE)*row_stride );
-
-  while (cinfo.output_scanline < cinfo.output_height) 
-    {
-      int off = 0;
-
-      jpeg_read_scanlines(&cinfo, &buffer, 1);
-
-      while (off < row_stride)
-       {
-         /* XXX Endianess */
-         *d++ = 
-           (buffer[off]   << 24) |  /* RGBA */
-           (buffer[off+1] << 16) |
-           (buffer[off+2] << 8)  |
-           (0xff << 0); 
-         off += 3;
-       }
-    }
-
-  jpeg_finish_decompress(&cinfo);
-  jpeg_destroy_decompress(&cinfo);
-  fclose(infile);
-
-  if (buffer) free(buffer);
-
-  return data;
-}
-
-/* X pcx code, based on usplash code by paul coden */
-/* http://courses.ece.uiuc.edu/ece390/books/labmanual/graphics-pcx.html */
-
-typedef struct 
-{
-  unsigned char manufacturer;
-  unsigned char version;
-  unsigned char encoding;
-  unsigned char bits_per_pixel;
-  unsigned short xmin;
-  unsigned short ymin;
-  unsigned short xmax;
-  unsigned short ymax;
-  unsigned short xdpi;
-  unsigned short ydpi;
-  unsigned char colourmap[48];
-  unsigned char reserved;
-  unsigned char planes;
-  unsigned short scanline_length;
-  unsigned short palette_info;
-  unsigned short xsize;
-  unsigned short ysize;
-  unsigned char fill[54];
-  unsigned char data[0];
-} pcx;
-
-enum 
-{
-  PCX_ZSOFT = 10,
-  PCX_RLE = 1,
-  PCX_WITH_PALETTE = 2,
-  PCX_COLOUR_MAP_LENGTH = 769
-};
-
-
-/*
-** Reads the first 128 bytes of a PCX headers, from an file
-** descriptor, into memory.
-** RETURN zero on success.
-*/
-int 
-pcx_read_header(pcx *header, int fd)
-{
-  if(!lseek(fd, 0, SEEK_SET))
-    if(read(fd, header, sizeof(pcx)) == sizeof(pcx))
-      return 0;
-  return -1;
-}
-
-/*
-** Does the file descriptor point to a PCX file, which is of a
-** suitable colour-depth (8-bit) for us to use?
-** RETURN zero on success.
-*/
-static int 
-pcx_is_suitable(int fd)
-{
-  pcx header;
-  if(!pcx_read_header(&header, fd))
-    if(header.manufacturer == PCX_ZSOFT 
-       /* && header.version >= PCX_WITH_PALETTE && */
-       && header.encoding == PCX_RLE 
-       && header.planes == 3           /* 24bpp */
-       && header.bits_per_pixel == 8 ) /* why not 24 from gimp */
-      return 0;
-  
-  return -1;
-}
-
-/*
-** Takes a raw PCX RLE stream and decompresses it into the destination
-** buffer, which must be big enough!
-** RETURN zero on success
-**
-** PCX images are RLE (Run Length Encoded as follows:
-**  if(top two bits are set)  // >= 0xc0
-**    use bottom six bit (& 0x3f) as RLE count for next byte;
-**  else // < 0xc0
-**    copy one byte normally;
-*/
-static void 
-pcx_raw_decode24(int           *dest, 
-                unsigned char *src, 
-                int            width, 
-                int            height)
-{
-  int x, y, i, count;
-  int *d = dest;
-  unsigned char *p;
-
-  memset(dest, 0xff, height * width * 4);
-
-  for(y = 0; y < height; y++)
-    {
-      d = dest + (y * width);
-      /* RGB */
-      for(x = 0; x < width;)
-       if(*src < 0xc0)
-         {
-           x++;
-           p = (unsigned char *)d++;
-           *p = *src++;
-         }
-       else
-         {
-           count = *src++ & 0x3f;
-           for (i=0; i<count; i++)
-             {
-               p = (unsigned char *)d++;
-               *p = *src++;
-               x += count;
-             }
-         }
-
-      d = dest + (y * width);
-
-      /* RGB */
-      for(x = 0; x < width;)
-       if(*src < 0xc0)
-         {
-           x++;
-           p = (unsigned char *)d++; 
-           *(p+1) = *src++;
-         }
-       else
-         {
-           count = *src++ & 0x3f;
-           for (i=0; i<count; i++)
-             {
-               p = (unsigned char *)d++;
-               *(p+1) = *src++;
-             }
-           x += count;
-         }
-
-      d = dest + (y * width);
-
-      /* RGB */
-      for(x = 0; x < width;)
-       if(*src < 0xc0)
-         {
-           x++;
-           p = (unsigned char *)d++; 
-           *(p+2) = *src++ ;
-         }
-       else
-         {
-           count = *src++ & 0x3f;
-           for (i=0; i<count; i++)
-             {
-               p = (unsigned char *)d++;
-               *(p+2) = *src++;
-             }
-           x += count;
-         }
-
-    }
-}
-
-int* 
-load_pcx_file (const char *filename,
-              int        *width,
-              int        *height)
-{
-  int   *data;
-  int    fd, file_length;
-  pcx   *header;
-  struct stat st;
-
-       /* Open file */
-  if((fd = open(filename, O_RDONLY)) < 0)
-    return NULL;
-       
-  /* Test file */
-  if(pcx_is_suitable(fd))
-    return NULL;
-       
-  /* Get file size */
-  if (fstat(fd, &st))
-    return NULL;
-
-  file_length = st.st_size;
-       
-  /* mmap the pcx file into our header */
-  header = mmap(NULL, file_length, PROT_READ, MAP_SHARED, fd, 0);
-  if (header == MAP_FAILED)
-      return NULL;
-       
-  /* Get the width and height of the image */
-  *width = header->xmax - header->xmin + 1;
-  *height = header->ymax - header->ymin + 1;
-
-  /* Allocate enough room for the data and colourmap*/
-  data = malloc(*width * *height * 4);
-
-  if (!data) 
-    {
-      munmap(header, file_length);
-      return NULL;
-    }
-       
-  /* Decode the data */
-  pcx_raw_decode24(data, header->data, *width, *height);
-
-  /* Clean up */
-  munmap(header, file_length);
-  
-  close(fd);
-
-  return data;
-}
-
-
-/* -------------------------------------------------------------------- */
-
-Pixbuf*
-pixbuf_new(int width, int height)
-{
-  Pixbuf *pixb;
-
-  pixb = util_malloc0(sizeof(Pixbuf));
-
-  pixb->width           = width; 
-  pixb->height          = height; 
-  pixb->bytes_per_pixel = 4; 
-  pixb->channels        = 4;
-  pixb->bytes_per_line  = pixb->bytes_per_pixel * pixb->width;
-  pixb->data            = malloc(pixb->bytes_per_line * pixb->height);
-
-  memset(pixb->data, 0, pixb->bytes_per_line * pixb->height);
-
-  return pixb;
-}
-
-void
-pixbuf_unref(Pixbuf *pixb)
-{
-  pixb->refcnt--;
-
-  if (pixb->refcnt < 0)
-    {
-      free(pixb->data);
-      free(pixb);
-    }
-}
-
-void
-pixbuf_ref(Pixbuf *pixb)
-{
-  pixb->refcnt++;
-}
-
-Pixbuf*
-pixbuf_new_from_file(const char *filename)
-{
-  Pixbuf *pixb;
-
-  pixb = util_malloc0(sizeof(Pixbuf));
-
-  if (!strcasecmp(&filename[strlen(filename)-4], ".png"))
-    pixb->data =load_png_file(filename, &pixb->width, &pixb->height); 
-  else if (!strcasecmp(&filename[strlen(filename)-4], ".jpg")
-          || !strcasecmp(&filename[strlen(filename)-5], ".jpeg"))
-    pixb->data = load_jpg_file( filename, &pixb->width, &pixb->height); 
-  else if (!strcasecmp(&filename[strlen(filename)-4], ".pcx"))
-    pixb->data = load_pcx_file( filename, &pixb->width, &pixb->height); 
-
-  if (pixb->data == NULL)
-    {
-      free (pixb);
-      return NULL;
-    }
-
-  pixb->bytes_per_pixel = 4; 
-  pixb->channels        = 4;
-  pixb->bytes_per_line  = pixb->bytes_per_pixel * pixb->width;
-               
-  return pixb;
-}
-
-void
-pixbuf_set_pixel(Pixbuf *pixb, int x, int y, PixbufPixel *p)
-{
-  int *offset = pixb->data + ( y * pixb->width) + x;
-
-  /* ARGB_32 MSB */
-
-  // *offset = (p->r << 0) | (p->g << 8) | (p->b << 16) | (p->a << 24);
-  *offset = ( (p->r << 24) | (p->g << 16) | (p->b << 8) | (p->a) );
-
-  /*
-  printf("set %i,%i,%i,%i\n", p->r, p->g, p->b, p->a);
-  printf("Looks like %i %x\n", *offset, *offset);
-  */
-}
-
-void
-pixbuf_get_pixel(Pixbuf *pixb, int x, int y, PixbufPixel *p)
-{
-  int *offset = pixb->data + ( y * pixb->width) + x;
-
-  /* ARGB_32 MSB */
-
-  p->r = (*offset >> 24) & 0xff; 
-  p->g = (*offset >> 16) & 0xff;
-  p->b = (*offset >> 8) & 0xff;
-  p->a =  *offset & 0xff;
-
-}
-
-void                           /* XXX could be DEFINE */
-pixel_set_vals(PixbufPixel        *p, 
-              const unsigned char r,
-              const unsigned char g,
-              const unsigned char b,
-              const unsigned char a)
-{
-  p->r = r; p->g = g; p->b = b; p->a = a;
-}
-
-void
-pixbuf_copy(Pixbuf *src_pixb,
-           Pixbuf *dst_pixb,
-           int     srcx, 
-           int     srcy, 
-           int     srcw, 
-           int     srch,
-           int     dstx, 
-           int     dsty)
-{
-  int j, *sp, *dp;
-  
-  sp = src_pixb->data + (srcy * src_pixb->width) + srcx;
-  dp = dst_pixb->data + (dsty * dst_pixb->width) + dstx;
-
-  /* basic source clipping - needed by texture tiling code */
-
-  if (srcx + srcw > src_pixb->width)
-    srcw = src_pixb->width - srcx;
-
-  if (srcy + srch > src_pixb->height)
-    srch = src_pixb->height - srcy;
-
-  while (srch--)
-    {
-      j = srcw;
-      while (j--)
-       *dp++ = *sp++;
-      dp += (dst_pixb->width - srcw);
-      sp += (src_pixb->width - srcw);
-    }
-}
-
-void
-pixbuf_fill_rect(Pixbuf      *pixb,
-                int          x,
-                int          y,
-                int          width,
-                int          height,
-                PixbufPixel *p)
-{
-  int i, j;
-
-  if (width  < 0) width  = pixb->width;
-  if (height < 0) height = pixb->height;
-
-  for (i = x; i<width; i++)
-    for (j =y; j<height; j++)
-       pixbuf_set_pixel(pixb, i, j, p);
-}
-
-Pixbuf *
-pixbuf_scale_down(Pixbuf *pixb,
-                 int     new_width, 
-                 int     new_height)
-{
-  Pixbuf        *pixb_scaled;
-  int *xsample, *ysample, *dest, *src, *srcy;
-  int i, x, y,  r, g, b, a, nb_samples, xrange, yrange, rx, ry;
-
-  if ( new_width > pixb->width || new_height > pixb->height) 
-    return NULL;
-
-  pixb_scaled = pixbuf_new(new_width, new_height);
-
-  xsample = malloc( (new_width+1) * sizeof(int));
-  ysample = malloc( (new_height+1) * sizeof(int));
-
-  for ( i = 0; i <= new_width; i++ )
-    xsample[i] = i * pixb->width / new_width;
-
-  for ( i = 0; i <= new_height; i++ )
-    ysample[i] = i * pixb->height / new_height * pixb->width;
-
-  dest = pixb_scaled->data;
-
-  /* scan output image */
-  for ( y = 0; y < new_height; y++ ) 
-    {
-      yrange = ( ysample[y+1] - ysample[y] ) / pixb->width;
-      for ( x = 0; x < new_width; x++) 
-       {
-         xrange = xsample[x+1] - xsample[x];
-         srcy   = pixb->data + ( ysample[y] + xsample[x] );
-         
-         /* average R,G,B,A values on sub-rectangle of source image */
-         nb_samples = xrange * yrange;
-
-         if ( nb_samples > 1 ) 
-           {
-             r = 0; g = 0; b = 0; a = 0;
-             for ( ry = 0; ry < yrange; ry++ ) 
-               {
-                 src = srcy;
-                 for ( rx = 0; rx < xrange; rx++ ) 
-                   {
-                     /* average R,G,B,A values */
-                     r +=  *src & 0xff;
-                     g += ((*src) >> 8) & 0xff;
-                     b += ((*src) >> 16) & 0xff;
-                     a += ((*src) >> 24) & 0xff;
-
-                     src++;
-                   }
-
-                 srcy += pixb->width;
-               }
-
-             *dest++ = 
-               ((unsigned char)(r/nb_samples) << 0)  | 
-               ((unsigned char)(g/nb_samples) << 8)  | 
-               ((unsigned char)(b/nb_samples) << 16) | 
-               ((unsigned char)(a/nb_samples) << 24);
-           }
-         else 
-           {
-             *dest++ = *srcy++;
-           }
-       }
-    }
-
-  /* cleanup */
-  free( xsample );
-  free( ysample );
-
-  return pixb_scaled;
-}
-
-Pixbuf*
-pixbuf_clone(Pixbuf *pixb)
-{
-  Pixbuf *clone;
-
-  if (pixb == NULL)
-    return NULL;
-
-  clone = util_malloc0(sizeof(Pixbuf));
-
-  clone->width           = pixb->width;
-  clone->height          = pixb->height;
-  clone->bytes_per_pixel = pixb->bytes_per_pixel; 
-  clone->channels       = pixb->channels;
-  clone->bytes_per_line  = pixb->bytes_per_line;
-  clone->data            = malloc(pixb->bytes_per_line * pixb->height);
-
-  memcpy(clone->data, pixb->data, pixb->bytes_per_line * pixb->height);
-  
-  return clone;
-}
-
-Pixbuf*
-pixbuf_convolve(Pixbuf *pixb, 
-               int    *kernel, 
-               int     kernel_size, 
-               int     kernel_divisor) 
-{
-  int         padding, x, y, r, g, b, a, l, k;
-  PixbufPixel pixel;
-  Pixbuf     *clone_pixb;
-    
-  padding = ( kernel_size - 1 ) / 2; 
-  clone_pixb = pixbuf_clone(pixb);
-
-  for( y = padding; y < pixb->height - padding; y++ ) 
-    {
-      for( x = padding; x < pixb->width - padding; x++ ) 
-       {
-         r = b = g = a = 0;
-
-         for( l = 0; l < kernel_size; l++ ) 
-           {
-             for( k = 0; k < kernel_size; k++ ) 
-               {
-                 pixbuf_get_pixel(pixb, (x+k-padding), (y+l-padding), &pixel);
-                 
-                 r += pixel.r * kernel[k + l * kernel_size];
-                 g += pixel.g * kernel[k + l * kernel_size];
-                 b += pixel.b * kernel[k + l * kernel_size];
-                 a += pixel.a * kernel[k + l * kernel_size];
-               }
-           }
-
-         r = CLTR_CLAMP( r / kernel_divisor, 0xff);
-         g = CLTR_CLAMP( g / kernel_divisor, 0xff);
-         b = CLTR_CLAMP( b / kernel_divisor, 0xff);
-         a = CLTR_CLAMP( a / kernel_divisor, 0xff); 
-         
-         pixel_set_vals(&pixel, r, g, b, a); 
-         
-         pixbuf_set_pixel(clone_pixb, x, y, &pixel);
-         
-       }
-    }
-  
-  return clone_pixb;
-}
-
-Pixbuf*
-pixbuf_blur(Pixbuf *pixb)
-{ 
-  /*
-  int kernel[] = { 1, 1, 1,
-                  1, 0, 1, 
-                  1, 1, 1 };
-  */
-
-  int kernel[] = { 1, 1, 1,
-                  1, 1, 1,
-                  1, 1, 1 };
-
-
-  return pixbuf_convolve( pixb, kernel, 3, 9 );
-}
-
-Pixbuf*
-pixbuf_sharpen(Pixbuf *pixb)
-{ 
-  int kernel[] = {-1, -1, -1,
-                 -1, 9, -1, 
-                 -1, -1, -1 };
-
-  return pixbuf_convolve( pixb, kernel, 3, 1 );
-}
-
-
-#if 0
-
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%                                                                             %
-%                                                                             %
-%     C o n v o l v e I m a g e                                               %
-%                                                                             %
-%                                                                             %
-%                                                                             %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%  Method ConvolveImage applies a general image convolution kernel to an
-%  image returns the results.  ConvolveImage allocates the memory necessary for
-%  the new Image structure and returns a pointer to the new image.
-%
-%  The format of the ConvolveImage method is:
-%
-%      Image *ConvolveImage(Image *image,const unsigned int order,
-%        const double *kernel,ExceptionInfo *exception)
-%
-%  A description of each parameter follows:
-%
-%    o convolve_image: Method ConvolveImage returns a pointer to the image
-%      after it is convolved.  A null image is returned if there is a memory
-%      shortage.
-%
-%    o image: The address of a structure of type Image;  returned from
-%      ReadImage.
-%
-%    o order:  The number of columns and rows in the filter kernel.
-%
-%    o kernel:  An array of double representing the convolution kernel.
-%
-%    o exception: return any errors or warnings in this structure.
-%
-%
-*/
-MagickExport Image *ConvolveImage(Image *image,
-                                 const unsigned int order,
-                                 const double *kernel,
-                                 ExceptionInfo *exception)
-{
-#define ConvolveImageText  "  Convolving image...  "
-#define Cx(x) \
-  (x) < 0 ? (x)+image->columns : (x) >= image->columns ? (x)-image->columns : x
-#define Cy(y) \
-  (y) < 0 ? (y)+image->rows : (y) >= image->rows ? (y)-image->rows : y
-
-  double
-    blue,
-    green,
-    normalize,
-    opacity,
-    red;
-
-  Image
-    *convolve_image;
-
-  int
-    i,
-    width,
-    y;
-
-  PixelPacket
-    *p,
-    pixel;
-
-  register const double
-    *k;
-
-  register int
-    u,
-    v,
-    x;
-
-  register PixelPacket
-    *q,
-    *s;
-
-  /*
-    Initialize convolved image attributes.
-  */
-  assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
-  assert(exception != (ExceptionInfo *) NULL);
-  assert(exception->signature == MagickSignature);
-  width=order;
-  if ((width % 2) == 0)
-    ThrowImageException(OptionWarning,"Unable to convolve image",
-                       "kernel width must be an odd number");
-  if ((image->columns < width) || (image->rows < width))
-    ThrowImageException(OptionWarning,"Unable to convolve image",
-                       "image smaller than kernel width");
-  convolve_image=CloneImage(image,image->columns,image->rows,False,exception);
-  if (convolve_image == (Image *) NULL)
-    return((Image *) NULL);
-  convolve_image->storage_class=DirectClass;
-  /*
-    Convolve image.
-  */
-  normalize=0.0;
-  for (i=0; i < (width*width); i++)
-    normalize+=kernel[i];
-  for (y=0; y < (int) convolve_image->rows; y++)
-    {
-      p=(PixelPacket *) NULL;
-      q=SetImagePixels(convolve_image,0,y,convolve_image->columns,1);
-      if (q == (PixelPacket *) NULL)
-       break;
-      for (x=0; x < (int) convolve_image->columns; x++)
-       {
-         red=0.0;
-         green=0.0;
-         blue=0.0;
-         opacity=0.0;
-         k=kernel;
-         if ((x < (width/2)) || (x >= (int) (image->columns-width/2)) ||
-             (y < (width/2)) || (y >= (int) (image->rows-width/2)))
-           {
-             for (v=(-width/2); v <= (width/2); v++)
-               {
-                 for (u=(-width/2); u <= (width/2); u++)
-                   {
-                     pixel=GetOnePixel(image,Cx(x+u),Cy(y+v));
-                     red+=(*k)*pixel.red;
-                     green+=(*k)*pixel.green;
-                     blue+=(*k)*pixel.blue;
-                     opacity+=(*k)*pixel.opacity;
-                     k++;
-                   }
-               }
-           }
-         else
-           {
-             if (p == (PixelPacket *) NULL)
-               {
-                 p=GetImagePixels(image,0,y-width/2,image->columns,width);
-                 if (p == (PixelPacket *) NULL)
-                   break;
-               }
-             s=p+x;
-             for (v=(-width/2); v <= (width/2); v++)
-               {
-                 for (u=(-width/2); u <= (width/2); u++)
-                   {
-                     red+=(*k)*s[u].red;
-                     green+=(*k)*s[u].green;
-                     blue+=(*k)*s[u].blue;
-                     opacity+=(*k)*s[u].opacity;
-                     k++;
-                   }
-                 s+=image->columns;
-               }
-           }
-         if ((normalize != 0.0) && (normalize != 1.0))
-           {
-             red/=normalize;
-             green/=normalize;
-             blue/=normalize;
-             opacity/=normalize;
-           }
-         q->red=(Quantum) ((red < 0) ? 0 : (red > MaxRGB) ? MaxRGB : red+0.5);
-         q->green=(Quantum)
-           ((green < 0) ? 0 : (green > MaxRGB) ? MaxRGB : green+0.5);
-         q->blue=(Quantum) ((blue < 0) ? 0 : (blue > MaxRGB) ? MaxRGB : blue+0.5);
-         q->opacity=(Quantum)
-           ((opacity < 0) ? 0 : (opacity > MaxRGB) ? MaxRGB : opacity+0.5);
-         q++;
-       }
-      if (!SyncImagePixels(convolve_image))
-       break;
-      if (QuantumTick(y,convolve_image->rows))
-       MagickMonitor(ConvolveImageText,y,convolve_image->rows);
-    }
-  return(convolve_image);
-}
-
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%                                                                             %
-%                                                                             %
-%     G a u s s i a n B l u r I m a g e                                       %
-%                                                                             %
-%                                                                             %
-%                                                                             %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%  Method GaussianBlurImage creates a new image that is a copy of an existing
-%  one with the pixels blur.  It allocates the memory necessary for the
-%  new Image structure and returns a pointer to the new image.
-%
-%  The format of the BlurImage method is:
-%
-%      Image *GaussianBlurImage(Image *image,const double radius,
-%        const double sigma,ExceptionInfo *exception)
-%
-%  A description of each parameter follows:
-%
-%    o blur_image: Method GaussianBlurImage returns a pointer to the image
-%      after it is blur.  A null image is returned if there is a memory
-%      shortage.
-%
-%    o radius: the radius of the Gaussian, in pixels, not counting the center
-%      pixel.
-%
-%    o sigma: the standard deviation of the Gaussian, in pixels.
-%
-%    o exception: return any errors or warnings in this structure.
-%
-%
-*/
-MagickExport Image *GaussianBlurImage(Image *image,const double radius,
-                                     const double sigma,ExceptionInfo *exception)
-{
-  double
-    *kernel;
-
-  Image
-    *blur_image;
-
-  int
-    width;
-
-  register int
-    i,
-    u,
-    v;
-
-  assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
-  assert(exception != (ExceptionInfo *) NULL);
-  assert(exception->signature == MagickSignature);
-  width=GetOptimalKernelWidth2D(radius,sigma);
-  if ((image->columns < width) || (image->rows < width))
-    ThrowImageException(OptionWarning,"Unable to Gaussian blur image",
-                       "image is smaller than radius");
-  kernel=(double *) AcquireMemory(width*width*sizeof(double));
-  if (kernel == (double *) NULL)
-    ThrowImageException(ResourceLimitWarning,"Unable to Gaussian blur image",
-                       "Memory allocation failed");
-  i=0;
-  for (v=(-width/2); v <= (width/2); v++)
-    {
-      for (u=(-width/2); u <= (width/2); u++)
-       {
-         kernel[i]=exp((double) -(u*u+v*v)/(sigma*sigma));
-         i++;
-       }
-    }
-  blur_image=ConvolveImage(image,width,kernel,exception);
-  LiberateMemory((void **) &kernel);
-  return(blur_image);
-}
-
-/* GPE-gallery convolve code */
-
-static void 
-image_convolve( GdkPixbuf *pixbuf, 
-               int       *mask, 
-               int        mask_size, 
-               int        mask_divisor ) {
-
-  int x, y, k, l, b, rowstride, width, height, channels, padding, new_value;
-  int* temp_pixel;
-  guchar *temp_image, *image;
-
-  rowstride = gdk_pixbuf_get_rowstride( GDK_PIXBUF( pixbuf ) );
-  channels = gdk_pixbuf_get_n_channels( GDK_PIXBUF( pixbuf ) );
-
-  width = gdk_pixbuf_get_width( GDK_PIXBUF( pixbuf ) );
-  height = gdk_pixbuf_get_height( GDK_PIXBUF( pixbuf ) );
-
-  //    fprintf( stderr, "Rowstride: %d, width: %d, height: %d, channels: %d\n", rowstride, width, height, channels );
-
-    
-  padding = ( mask_size - 1 ) / 2; 
-
-  image = gdk_pixbuf_get_pixels( GDK_PIXBUF( pixbuf ) );
-  temp_image = (guchar*) malloc( width * height * channels * sizeof( guchar ) );
-  memcpy( temp_image, image, width * height * channels * sizeof( guchar ) ); 
-  temp_pixel =(int*)  malloc( channels * sizeof( int ) );
-  for( y = padding; y < height - padding; y++ ) {
-
-    for( x = padding; x < width - padding; x++ ) {
-        
-      for( b = 0; b < channels; b++ ) 
-       temp_pixel[b] = 0;
-
-      for( l = 0; l < mask_size; l++ ) {
-
-       for( k = 0; k < mask_size; k++ ) {
-
-         for( b = 0; b < channels; b++ ) 
-           temp_pixel[b] += temp_image[ ( y + l - padding ) * rowstride
-                                        + ( x + k - padding ) * channels + b ] * mask[ k + l *
-                                                                                       mask_size ];
-
-       }
-
-       }
-
-      for( b = 0; b < channels; b++ ) {
-
-       new_value = temp_pixel[b] / mask_divisor; 
-       image[ y * rowstride + x * channels +  b ] = ( new_value > 255 ? 255
-                                                      : new_value < 0 ? 0 : new_value ); 
-
-      }
-
-    }
-
-  }
-
-
-  free( temp_image );
-  free( temp_pixel );
-
-}
-
-void image_tools_blur( GdkPixbuf* pixbuf ) {
-
-  int mask[] = { 1, 1, 1,
-                1, 1, 1, 
-                1, 1, 1 };
-
-  image_convolve( pixbuf, mask, 3, 9 );
-
-}
-
-void image_tools_sharpen( GdkPixbuf* pixbuf ) {
-
-  int mask[] = {-1, -1, -1,
-               -1, 9, -1, 
-               -1, -1, -1 };
-
-  image_convolve( pixbuf, mask, 3, 1 );
-
-}
-
-#endif
diff --git a/clutter/pixbuf.h b/clutter/pixbuf.h
deleted file mode 100644 (file)
index 155d0b9..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef _HAVE_PIXBUF_H
-#define _HAVE_PIXBUF_H
-
-typedef struct Pixbuf Pixbuf;
-typedef struct PixbufPixel PixbufPixel;
-
-typedef enum PixbufFormat 
-{
-  PB_FMT_RGBA 
-} 
-PixbufFormat;
-
-struct PixbufPixel
-{
-  unsigned char r,g,b,a;
-};
-
-struct Pixbuf 
-{
-  int *data;
-  int  bytes_per_pixel;         /* bits per pixel = bpp << 3 */
-  int  channels;                /* 4 with alpha */
-  int  width, height;
-  int  bytes_per_line;          /* ( width * bpp ) */
-
-  int refcnt;                  /* starts at 0  */
-
-  void *meta;                  /* for jpeg meta text ? to a hash ? */
-
-  /* Possibles */
-
-  int rmask, gmask, bmask, amask;  /* Masks - good for packed formats > */
-  int has_alpha;                   /* Rather than channels ? */
-
-
-  /* PixbufFormat  format; like GL format      */
-  
-};
-
-Pixbuf*
-pixbuf_new_from_file(const char *filename);
-
-Pixbuf*
-pixbuf_new(int width, int height);
-
-void
-pixbuf_unref(Pixbuf *pixb);
-
-void
-pixbuf_ref(Pixbuf *pixb);
-
-void
-pixbuf_set_pixel(Pixbuf *pixb, int x, int y, PixbufPixel *p);
-
-void
-pixbuf_get_pixel(Pixbuf *pixbuf, int x, int y, PixbufPixel *p);
-
-void
-pixel_set_vals(PixbufPixel        *p, 
-              const unsigned char r,
-              const unsigned char g,
-              const unsigned char b,
-              const unsigned char a);
-
-void
-pixbuf_copy(Pixbuf *src_pixb,
-           Pixbuf *dst_pixb,
-           int     srcx, 
-           int     srcy, 
-           int     srcw, 
-           int     srch,
-           int     dstx, 
-           int     dsty);
-
-void
-pixbuf_fill_rect(Pixbuf      *pixb,
-                int          x,
-                int          y,
-                int          width,
-                int          height,
-                PixbufPixel *p);
-
-
-Pixbuf*
-pixbuf_scale_down(Pixbuf *pixb,
-                 int     new_width, 
-                 int     new_height);
-
-Pixbuf*
-pixbuf_clone(Pixbuf *pixb);
-
-Pixbuf*
-pixbuf_convolve(Pixbuf *pixb, 
-               int    *kernel, 
-               int     kernel_size, 
-               int     kernel_divisor) ;
-
-Pixbuf*
-pixbuf_blur(Pixbuf *pixb);
-
-Pixbuf*
-pixbuf_sharpen(Pixbuf *pixb);
-
-
-#endif
diff --git a/clutter/util.c b/clutter/util.c
deleted file mode 100644 (file)
index 67cc5eb..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#include "util.h"
-
-/* misc utility code */
-
-
-void*
-util_malloc0(int size)
-{
-  void *p;
-
-  p = malloc(size);
-  memset(p, 0, size);
-
-  return p;
-}
-
-int 
-util_next_p2 ( int a )
-{
-  int rval=1;
-  while(rval < a) 
-    rval <<= 1;
-
-  return rval;
-}
-
diff --git a/clutter/util.h b/clutter/util.h
deleted file mode 100644 (file)
index 67593ac..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _HAVE_UTIL_H
-#define _HAVE_UTIL_H
-
-#include <stdlib.h>
-#include <string.h>
-
-void*
-util_malloc0(int size);
-
-int 
-util_next_p2 ( int a );
-
-#endif
index c6688f3..97b6878 100644 (file)
@@ -1,11 +1,39 @@
 AC_PREREQ(2.53)
-AC_INIT([clutter], 0.0.1, [mallum@o-hand.com])
-AC_CONFIG_SRCDIR([clutter/cltr.h])
-
-AM_INIT_AUTOMAKE()
 
+# clutter package version number, (as distinct from shared library version)
+# An odd micro number indicates in-progress development, (eg. from CVS)
+# An even micro number indicates a released version.
+m4_define(clutter_version_major, 0)
+m4_define(clutter_version_minor, 0)
+m4_define(clutter_version_micro, 1)
+
+AC_INIT([clutter], 
+       clutter_version_major.clutter_version_minor.clutter_version_micro, 
+        [mallum@o-hand.com])
+AC_CONFIG_SRCDIR([clutter/clutter.h])
 AM_CONFIG_HEADER([config.h])
 
+AM_INIT_AUTOMAKE([1.7])
+
+CLUTTER_MAJORMINOR=clutter_version_major.clutter_version_minor
+AC_SUBST(CLUTTER_MAJORMINOR)
+
+# CURRENT, REVISION, AGE
+# - library source changed -> increment REVISION
+# - interfaces added/removed/changed -> increment CURRENT, REVISION = 0
+# - interfaces added -> increment AGE
+# - interfaces removed -> AGE = 0
+CLUTTER_LT_CURRENT=0
+CLUTTER_LT_REV=0
+CLUTTER_LT_AGE=0
+CLUTTER_LT_VERSION="$CLUTTER_LT_CURRENT:$CLUTTER_LT_REV:$CLUTTER_LT_AGE"
+CLUTTER_LT_LDFLAGS="-version-info $CLUTTER_LT_VERSION"
+
+AC_SUBST(CLUTTER_LT_VERSION)
+AC_SUBST(CLUTTER_LT_LDFLAGS)
+
+dnl ========================================================================
+
 # Checks for programs.
 AC_PROG_CC
 AC_PROG_LIBTOOL
@@ -22,11 +50,12 @@ AC_FUNC_MALLOC
 AC_FUNC_MMAP
 AC_CHECK_FUNCS([memset munmap strcasecmp strdup])
 
-dnl ------ X + GL -------------------------------------------------------------
 
-AC_PATH_XTRA
+dnl ========================================================================
+
+# FIXME: redo below
 
-# below is broken 
+AC_PATH_XTRA
 
 if test "x$have_x" = "xyes"; then
     GLX_LIBS="$X_LIBS -lX11 -lGL"
@@ -56,75 +85,109 @@ if test "x$have_x" = "xyes"; then
       AC_DEFINE([XTHREADS], [], [1])
     fi
 else
-    AC_MSG_ERROR([*** Cannot find X + GL****])
+    AC_MSG_ERROR([*** Cannot find X + GL ****])
 fi
 
-dnl ----- Pango, glib etc ---------------------------------------------------
+dnl ========================================================================
 
-pkg_modules="pangoft2 glib-2.0 gthread-2.0"
-PKG_CHECK_MODULES(CLTR, pangoft2 glib-2.0 gthread-2.0)
+pkg_modules="pangoft2 glib-2.0 >= 2.8 gthread-2.0 gdk-pixbuf-2.0"
+PKG_CHECK_MODULES(CLUTTER, [$pkg_modules])
 
-dnl ----- Gstreamer ---------------------------------------------------------
+dnl ========================================================================
 
-pkg_modules="gstreamer-0.8 gstreamer-interfaces-0.8 gthread-2.0 gstreamer-play-0.8 gstreamer-gconf-0.8"
-PKG_CHECK_MODULES(GST, [$pkg_modules])
-
-dnl ----- Gconf -------------------------------------------------------------
+GST_MAJORMINOR=0.10
 
-PKG_CHECK_MODULES(GCONF, gconf-2.0, HAVE_GCONF="yes", HAVE_GCONF="no")
+pkg_modules="gstreamer-$GST_MAJORMINOR gstreamer-plugins-base-$GST_MAJORMINOR"
+PKG_CHECK_MODULES(GST, [$pkg_modules])
 
-dnl ------ Check for PNG ---------------------------------------------------
+GST_LIBS="$GST_LIBS -lgstinterfaces-$GST_MAJORMINOR -lgstvideo-$GST_MAJORMINOR -lgstaudio-$GST_MAJORMINOR"
 
-AC_MSG_CHECKING(for libpng12)
+dnl ========================================================================
 
-if test x$PKG_CONFIG != xno && $PKG_CONFIG --exists libpng12; then 
-        AC_MSG_RESULT(yes)
-        PNG_LIBS=`$PKG_CONFIG --libs libpng12`
-       PNG_CFLAGS=`$PKG_CONFIG --cflags libpng12`
-else
-       AC_MSG_RESULT(no)
-        AC_CHECK_LIB([png], [png_create_read_struct], 
-                      [have_png="yes"], [have_png="no"])
-
-        if test x$have_png=xyes && test x$have_png_h=xyes; then 
-            PNG_LIBS="-lpng -lz"
-        else
-           AC_MSG_ERROR([*** Cannot find libpng12 ****])
-       fi
+if test "x$GCC" = "xyes"; then
+        GCC_FLAGS="-g -Wall"
 fi
 
-dnl ------ Check for JPEG ---------------------------------------------------
-
-AC_CHECK_LIB([jpeg], [jpeg_read_header], [have_jpg="yes"], [have_jpg="no"])
-
-if test x$have_jpg=xyes && test x$have_jpg_h=xyes; then 
-       JPEG_LIBS="-ljpeg"
-  else
-       AC_MSG_ERROR([*** Cannot find libjpeg ****])
+dnl ========================================================================
+
+GTK_DOC_CHECK([1.0])
+
+dnl ========================================================================
+
+AC_ARG_ENABLE(python,
+            [AC_HELP_STRING([--enable-python], [Compile with python bindings])],enable_python="$enableval",enable_python=no)
+
+if test "x$enable_python" = "xyes"; then
+   AC_PATH_PROG(PYTHON, python, no)
+   if test x$PYTHON = xno; then
+      AC_MSG_ERROR(Please install python)
+      fi
+      AC_MSG_CHECKING(Python compile flags)
+      changequote(<<, >>)dnl
+      PY_VER=`$PYTHON -c 'import distutils.sysconfig; print distutils.sysconfig.get_config_vars("VERSION")[0];'`
+      PY_LIB=`$PYTHON -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_lib(standard_lib=1);'`
+      PY_INC=`$PYTHON -c 'import distutils.sysconfig; print distutils.sysconfig.get_config_vars("INCLUDEPY")[0];'`
+      PY_PREFIX=`$PYTHON -c 'import sys; print sys.prefix'`
+      PY_EXEC_PREFIX=`$PYTHON -c 'import sys; print sys.exec_prefix'`
+      changequote([, ])dnl
+      if test -f $PY_INC/Python.h; then
+        PYTHON_LIBS="-L$PY_LIB/config -lpython$PY_VER -lpthread -lutil"
+                                      PYTHON_CFLAGS="-I$PY_INC"
+                                       AC_MSG_RESULT(ok)
+                                       else
+                                               AC_MSG_ERROR([Can't find Python.h])
+                                               fi
+        PKG_CHECK_MODULES(PYGTK, pygtk-2.0)
+       PYGTK_CODEGENDIR="`$PKG_CONFIG --variable=codegendir pygtk-2.0`"
+       PYGTK_DEFSDIR="`$PKG_CONFIG --variable=defsdir pygtk-2.0`"
+       AC_PATH_PROG(PYGTK_CODEGEN, pygtk-codegen-2.0, no)
+       if test x$PYGTK_CODEGEN = xno; then
+          AC_MSG_ERROR(Please install the application pygtk-codegen-2.0)
+          fi
+          AC_MSG_CHECKING(for pygtk codegendir)
+          AC_MSG_RESULT($PYGTK_CODEGENDIR)
+        AC_MSG_CHECKING(for pygtk defsdir)
+        AC_MSG_RESULT($PYGTK_DEFSDIR)
+
+       AC_DEFINE([ENABLE_PYTHON], [1], [Enable python bindings])
+else
+       PY_VER=""
+       PYTHON_CFLAGS=""
+       PYTHON_LIBS=""
+        PYGTK_CFLAGS=""
+        PYGTK_LIBS=""
+       PYGTK_CODEGENDIR=""
+       PYGTK_CODEGEN=""
+       PYGTK_DEFSDIR=""
 fi
+AC_SUBST(PY_VER)
+AC_SUBST(PYTHON_CFLAGS)
+AC_SUBST(PYTHON_LIBS)
+AC_SUBST(PYGTK_CFLAGS)
+AC_SUBST(PYGTK_LIBS)
+AC_SUBST(PYGTK_CODEGENDIR)
+AC_SUBST(PYGTK_DEFSDIR)
 
-dnl ----- GCC ---------------------------------------------------------------
+AM_CONDITIONAL(ENABLE_PYTHON, test x$enable_python = xyes)
 
-if test "x$GCC" = "xyes"; then
-        GCC_FLAGS="-g -Wall"
-fi
+dnl ========================================================================
 
 AC_SUBST(GCC_FLAGS)
-
 AC_SUBST(GST_CFLAGS)
 AC_SUBST(GST_LIBS)
 
-AC_SUBST(GCONF_CFLAGS)
-AC_SUBST(GCONF_LIBS)
-
-CLTR_CFLAGS="$GLX_CLAGS $CLTR_CFLAGS"
-CLTR_LIBS="$GLX_LIBS $PNG_LIBS $JPEG_LIBS $CLTR_LIBS"
+CLUTTER_CFLAGS="$GLX_CLAGS $CLUTTER_CFLAGS"
+CLUTTER_LIBS="$GLX_LIBS $CLUTTER_LIBS"
 
-AC_SUBST(CLTR_CFLAGS)
-AC_SUBST(CLTR_LIBS)
+AC_SUBST(CLUTTER_CFLAGS)
+AC_SUBST(CLUTTER_LIBS)
 
 AC_OUTPUT([Makefile
 clutter/Makefile
+bindings/Makefile
+bindings/python/Makefile
 examples/Makefile
-gst/Makefile
+doc/Makefile
+doc/reference/Makefile
+clutter.pc
 ])
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644 (file)
index 0000000..b68c774
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS=reference
diff --git a/doc/reference/ChangeLog b/doc/reference/ChangeLog
new file mode 100644 (file)
index 0000000..10e3285
--- /dev/null
@@ -0,0 +1,19 @@
+2006-05-26  Emmanuele Bassi  <ebassi@openedhand.com>
+
+       A clutter-0.0-sections.txt
+
+       * clutter-0.0-sections.txt: Add the -section file: every method
+       signature should go in this file in order to let gtk-doc pick
+       it up when building the template for it.
+
+2006-05-26  Emmanuele Bassi  <ebassi@openedhand.com>
+
+       A tmpl
+       A tmpl/*.sgml
+
+       * tmpl/*.sgml: Add gtk-doc templates.
+
+2006-05-26  Emmanuele Bassi  <ebassi@openedhand.com>
+
+       * *: Initial entry.
+
diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am
new file mode 100644 (file)
index 0000000..8e3111f
--- /dev/null
@@ -0,0 +1,78 @@
+## Process this file with automake to produce Makefile.in
+
+# We require automake 1.6 at least.
+AUTOMAKE_OPTIONS = 1.6
+
+# This is a blank Makefile.am for using gtk-doc.
+# Copy this to your project's API docs directory and modify the variables to
+# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
+# of using the various options.
+
+# The name of the module, e.g. 'glib'.
+DOC_MODULE=clutter-@CLUTTER_MAJORMINOR@
+
+# The top-level SGML file. You can change this if you want to.
+DOC_MAIN_SGML_FILE=clutter-docs.sgml
+
+# The directory containing the source code. Relative to $(srcdir).
+# gtk-doc will search all .c & .h files beneath here for inline comments
+# documenting the functions and macros.
+# e.g. DOC_SOURCE_DIR=../../../gtk
+DOC_SOURCE_DIR=../../clutter
+
+# Extra options to pass to gtkdoc-scangobj. Not normally needed.
+SCANGOBJ_OPTIONS=
+
+# Extra options to supply to gtkdoc-scan.
+# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" 
+SCAN_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkdb.
+# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
+MKDB_OPTIONS=--sgml-mode --output-format=xml
+
+# Extra options to supply to gtkdoc-mktmpl
+# e.g. MKTMPL_OPTIONS=--only-section-tmpl
+MKTMPL_OPTIONS=
+
+# Extra options to supply to gtkdoc-fixref. Not normally needed.
+# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
+FIXXREF_OPTIONS=
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
+# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
+HFILE_GLOB=$(top_srcdir)/clutter/*.h
+CFILE_GLOB=$(top_srcdir)/clutter/*.c
+
+# Header files to ignore when scanning.
+# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
+IGNORE_HFILES=clutter-private.h stamp-clutter-enum-types.h
+
+# Images to copy into HTML directory.
+# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
+HTML_IMAGES=
+
+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
+# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
+content_files=
+
+# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
+# These files must be listed here *and* in content_files
+# e.g. expand_content_files=running.sgml
+expand_content_files=
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+# Only needed if you are using gtkdoc-scangobj to dynamically query widget
+# signals and properties.
+# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
+# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
+INCLUDES=-I$(top_srcdir) $(CLUTTERR_CFLAGS)
+GTKDOC_LIBS=$(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la $(CLUTTER_LIBS)
+
+# This includes the standard gtk-doc make rules, copied by gtkdocize.
+include $(top_srcdir)/gtk-doc.make
+
+# Other files to distribute
+# e.g. EXTRA_DIST += version.xml.in
+#EXTRA_DIST += 
diff --git a/doc/reference/clutter-0.0-sections.txt b/doc/reference/clutter-0.0-sections.txt
new file mode 100644 (file)
index 0000000..487e8fc
--- /dev/null
@@ -0,0 +1,1689 @@
+<SECTION>
+<FILE>clutter-label</FILE>
+<TITLE>ClutterLabel</TITLE>
+ClutterLabel
+ClutterLabelClass
+clutter_label_new_with_text
+clutter_label_new
+clutter_label_set_text
+clutter_label_set_font
+clutter_label_set_color
+clutter_label_set_text_extents
+<SUBSECTION Standard>
+CLUTTER_LABEL
+CLUTTER_IS_LABEL
+CLUTTER_TYPE_LABEL
+CLUTTER_LABEL_CLASS
+CLUTTER_IS_LABEL_CLASS
+CLUTTER_LABEL_GET_CLASS
+<SUBSECTION Private>
+ClutterLabelPrivate
+clutter_label_get_type
+</SECTION>
+
+<SECTION>
+<FILE>clutter-element</FILE>
+<TITLE>ClutterElement</TITLE>
+CLUTTER_TYPE_GEOMETRY
+CLUTTER_TYPE_ELEMENT_BOX
+CLUTTER_ELEMENT_SET_FLAGS
+CLUTTER_ELEMENT_UNSET_FLAGS
+CLUTTER_ELEMENT_IS_MAPPED
+CLUTTER_ELEMENT_IS_REALIZED
+CLUTTER_ELEMENT_IS_VISIBLE
+ClutterElementBox
+ClutterGeometry
+ClutterElementTransform
+ClutterElementFlags
+clutter_element_box_get_type
+ClutterElement
+ClutterElementClass
+clutter_element_get_type
+clutter_element_show
+clutter_element_hide
+clutter_element_realize
+clutter_element_unrealize
+clutter_element_paint
+clutter_element_queue_redraw
+clutter_element_request_coords
+clutter_element_allocate_coords
+clutter_element_set_geometry
+clutter_element_get_geometry
+clutter_element_get_coords
+clutter_element_set_position
+clutter_element_set_size
+clutter_element_get_abs_position
+clutter_element_get_width
+clutter_element_get_height
+clutter_element_get_x
+clutter_element_get_y
+clutter_element_rotate_z
+clutter_element_rotate_x
+clutter_element_rotate_y
+clutter_element_set_opacity
+clutter_element_get_opacity
+clutter_element_set_name
+clutter_element_get_name
+clutter_element_get_id
+clutter_element_set_clip
+clutter_element_remove_clip
+clutter_element_set_parent
+clutter_element_get_parent
+clutter_element_raise
+clutter_element_lower
+clutter_element_raise_top
+clutter_element_lower_bottom
+<SUBSECTION Standard>
+CLUTTER_ELEMENT
+CLUTTER_IS_ELEMENT
+CLUTTER_TYPE_ELEMENT
+CLUTTER_ELEMENT_CLASS
+CLUTTER_IS_ELEMENT_CLASS
+CLUTTER_ELEMENT_GET_CLASS
+<SUBSECTION Private>
+clutter_geometry_get_type
+ClutterElementPrivate
+</SECTION>
+
+<SECTION>
+<FILE>clutter-group</FILE>
+ClutterGroupPrivate
+<TITLE>ClutterGroup</TITLE>
+ClutterGroup
+clutter_group_new
+clutter_group_add
+clutter_group_add_many_valist
+clutter_group_add_many
+clutter_group_remove
+clutter_group_show_all
+clutter_group_hide_all
+clutter_group_find_child_by_id
+clutter_group_raise
+clutter_group_lower
+<SUBSECTION Standard>
+CLUTTER_GROUP
+CLUTTER_IS_GROUP
+CLUTTER_TYPE_GROUP
+clutter_group_get_type
+CLUTTER_GROUP_CLASS
+CLUTTER_IS_GROUP_CLASS
+CLUTTER_GROUP_GET_CLASS
+</SECTION>
+
+<SECTION>
+<FILE>clutter-clone-texture</FILE>
+ClutterCloneTexturePrivate
+<TITLE>ClutterCloneTexture</TITLE>
+ClutterCloneTexture
+clutter_clone_texture_new
+<SUBSECTION Standard>
+CLUTTER_CLONE_TEXTURE
+CLUTTER_IS_CLONE_TEXTURE
+CLUTTER_TYPE_CLONE_TEXTURE
+clutter_clone_texture_get_type
+CLUTTER_CLONE_TEXTURE_CLASS
+CLUTTER_IS_CLONE_TEXTURE_CLASS
+CLUTTER_CLONE_TEXTURE_GET_CLASS
+</SECTION>
+
+<SECTION>
+<FILE>clutter-texture</FILE>
+ClutterTexturePrivate
+<TITLE>ClutterTexture</TITLE>
+ClutterTexture
+clutter_texture_new_from_pixbuf
+clutter_texture_new
+clutter_texture_set_pixbuf
+clutter_texture_get_pixbuf
+clutter_texture_get_base_size
+clutter_texture_bind_tile
+clutter_texture_get_n_tiles
+clutter_texture_get_x_tile_detail
+clutter_texture_get_y_tile_detail
+clutter_texture_has_generated_tiles
+clutter_texture_is_tiled
+<SUBSECTION Standard>
+CLUTTER_TEXTURE
+CLUTTER_IS_TEXTURE
+CLUTTER_TYPE_TEXTURE
+clutter_texture_get_type
+CLUTTER_TEXTURE_CLASS
+CLUTTER_IS_TEXTURE_CLASS
+CLUTTER_TEXTURE_GET_CLASS
+</SECTION>
+
+<SECTION>
+<FILE>clutter-stage</FILE>
+CLUTTER_STAGE_WIDTH
+CLUTTER_STAGE_HEIGHT
+ClutterStagePrivate
+<TITLE>ClutterStage</TITLE>
+ClutterStage
+clutter_stage_get_xwindow
+clutter_stage_set_color
+clutter_stage_get_color
+clutter_stage_pick
+<SUBSECTION Standard>
+CLUTTER_STAGE
+CLUTTER_IS_STAGE
+CLUTTER_TYPE_STAGE
+clutter_stage_get_type
+CLUTTER_STAGE_CLASS
+CLUTTER_IS_STAGE_CLASS
+CLUTTER_STAGE_GET_CLASS
+</SECTION>
+
+<SECTION>
+<FILE>clutter-rectangle</FILE>
+ClutterRectanglePrivate
+<TITLE>ClutterRectangle</TITLE>
+ClutterRectangle
+clutter_rectangle_new
+<SUBSECTION Standard>
+CLUTTER_RECTANGLE
+CLUTTER_IS_RECTANGLE
+CLUTTER_TYPE_RECTANGLE
+clutter_rectangle_get_type
+CLUTTER_RECTANGLE_CLASS
+CLUTTER_IS_RECTANGLE_CLASS
+CLUTTER_RECTANGLE_GET_CLASS
+</SECTION>
+
+<SECTION>
+<FILE>clutter-video-texture</FILE>
+ClutterVideoTexturePrivate
+CLUTTER_VIDEO_TEXTURE_ERROR
+ClutterVideoTextureError
+clutter_video_texture_error_quark
+ClutterVideoTextureAspectRatio
+<TITLE>ClutterVideoTexture</TITLE>
+ClutterVideoTexture
+clutter_video_texture_new
+clutter_video_texture_open
+clutter_video_texture_play
+clutter_video_texture_pause
+clutter_video_texture_can_direct_seek
+clutter_video_texture_seek_time
+clutter_video_texture_seek
+clutter_video_texture_stop
+clutter_video_texture_can_set_volume
+clutter_video_texture_set_volume
+clutter_video_texture_get_volume
+clutter_video_texture_get_current_time
+clutter_video_texture_get_stream_length
+clutter_video_texture_is_playing
+clutter_video_texture_is_seekable
+clutter_video_texture_get_position
+clutter_video_texture_set_aspect_ratio
+clutter_video_texture_get_aspect_ratio
+ClutterVideoTextureMetadataType
+clutter_video_texture_get_metadata
+<SUBSECTION Standard>
+CLUTTER_VIDEO_TEXTURE
+CLUTTER_IS_VIDEO_TEXTURE
+CLUTTER_TYPE_VIDEO_TEXTURE
+clutter_video_texture_get_type
+CLUTTER_VIDEO_TEXTURE_CLASS
+CLUTTER_IS_VIDEO_TEXTURE_CLASS
+CLUTTER_VIDEO_TEXTURE_GET_CLASS
+</SECTION>
+
+<SECTION>
+<FILE>clutter-timeline</FILE>
+ClutterTimelinePrivate
+<TITLE>ClutterTimeline</TITLE>
+ClutterTimeline
+clutter_timeline_new
+clutter_timeline_set_speed
+clutter_timeline_start
+clutter_timeline_pause
+clutter_timeline_stop
+clutter_timeline_set_loop
+clutter_timeline_rewind
+clutter_timeline_skip
+clutter_timeline_advance
+clutter_timeline_get_current_frame
+clutter_timeline_get_n_frames
+<SUBSECTION Standard>
+CLUTTER_TIMELINE
+CLUTTER_IS_TIMELINE
+CLUTTER_TYPE_TIMELINE
+clutter_timeline_get_type
+CLUTTER_TIMELINE_CLASS
+CLUTTER_IS_TIMELINE_CLASS
+CLUTTER_TIMELINE_GET_CLASS
+</SECTION>
+
+<SECTION>
+<FILE>clutter-util</FILE>
+clutter_util_next_p2
+clutter_util_can_create_texture
+</SECTION>
+
+<SECTION>
+<FILE>clutter-color</FILE>
+clutter_color_r
+clutter_color_g
+clutter_color_b
+clutter_color_a
+clutter_color_set_r
+clutter_color_set_g
+clutter_color_set_b
+clutter_color_set_a
+ClutterColor
+clutter_color_new
+clutter_color_set
+clutter_color_get
+</SECTION>
+
+<SECTION>
+<FILE>clutter-event</FILE>
+ClutterEventType
+ClutterKeyEvent
+ClutterButtonEvent
+ClutterMotionEvent
+ClutterInputDevice
+ClutterEvent
+clutter_key_event_type
+clutter_key_event_time
+clutter_key_event_state
+clutter_key_event_symbol
+clutter_key_event_code
+clutter_key_event_unicode
+clutter_keysym_to_unicode
+</SECTION>
+
+<SECTION>
+<FILE>clutter-main</FILE>
+CLUTTER_HAS_DEBUG_MESSGES
+CLUTTER_DBG
+CLUTTER_GLERR
+CLUTTER_MARK
+clutter_init
+clutter_main
+clutter_stage
+clutter_redraw
+clutter_xdisplay
+clutter_xscreen
+clutter_root_xwindow
+clutter_gl_context
+clutter_want_debug
+clutter_threads_enter
+clutter_threads_leave
+</SECTION>
+
+<SECTION>
+<FILE>clutter</FILE>
+</SECTION>
+
+<SECTION>
+<FILE>clutter-keysyms</FILE>
+CLUTTER_VoidSymbol
+CLUTTER_BackSpace
+CLUTTER_Tab
+CLUTTER_Linefeed
+CLUTTER_Clear
+CLUTTER_Return
+CLUTTER_Pause
+CLUTTER_Scroll_Lock
+CLUTTER_Sys_Req
+CLUTTER_Escape
+CLUTTER_Delete
+CLUTTER_Multi_key
+CLUTTER_Codeinput
+CLUTTER_SingleCandidate
+CLUTTER_MultipleCandidate
+CLUTTER_PreviousCandidate
+CLUTTER_Kanji
+CLUTTER_Muhenkan
+CLUTTER_Henkan_Mode
+CLUTTER_Henkan
+CLUTTER_Romaji
+CLUTTER_Hiragana
+CLUTTER_Katakana
+CLUTTER_Hiragana_Katakana
+CLUTTER_Zenkaku
+CLUTTER_Hankaku
+CLUTTER_Zenkaku_Hankaku
+CLUTTER_Touroku
+CLUTTER_Massyo
+CLUTTER_Kana_Lock
+CLUTTER_Kana_Shift
+CLUTTER_Eisu_Shift
+CLUTTER_Eisu_toggle
+CLUTTER_Kanji_Bangou
+CLUTTER_Zen_Koho
+CLUTTER_Mae_Koho
+CLUTTER_Home
+CLUTTER_Left
+CLUTTER_Up
+CLUTTER_Right
+CLUTTER_Down
+CLUTTER_Prior
+CLUTTER_Page_Up
+CLUTTER_Next
+CLUTTER_Page_Down
+CLUTTER_End
+CLUTTER_Begin
+CLUTTER_Select
+CLUTTER_Print
+CLUTTER_Execute
+CLUTTER_Insert
+CLUTTER_Undo
+CLUTTER_Redo
+CLUTTER_Menu
+CLUTTER_Find
+CLUTTER_Cancel
+CLUTTER_Help
+CLUTTER_Break
+CLUTTER_Mode_switch
+CLUTTER_script_switch
+CLUTTER_Num_Lock
+CLUTTER_KP_Space
+CLUTTER_KP_Tab
+CLUTTER_KP_Enter
+CLUTTER_KP_F1
+CLUTTER_KP_F2
+CLUTTER_KP_F3
+CLUTTER_KP_F4
+CLUTTER_KP_Home
+CLUTTER_KP_Left
+CLUTTER_KP_Up
+CLUTTER_KP_Right
+CLUTTER_KP_Down
+CLUTTER_KP_Prior
+CLUTTER_KP_Page_Up
+CLUTTER_KP_Next
+CLUTTER_KP_Page_Down
+CLUTTER_KP_End
+CLUTTER_KP_Begin
+CLUTTER_KP_Insert
+CLUTTER_KP_Delete
+CLUTTER_KP_Equal
+CLUTTER_KP_Multiply
+CLUTTER_KP_Add
+CLUTTER_KP_Separator
+CLUTTER_KP_Subtract
+CLUTTER_KP_Decimal
+CLUTTER_KP_Divide
+CLUTTER_KP_0
+CLUTTER_KP_1
+CLUTTER_KP_2
+CLUTTER_KP_3
+CLUTTER_KP_4
+CLUTTER_KP_5
+CLUTTER_KP_6
+CLUTTER_KP_7
+CLUTTER_KP_8
+CLUTTER_KP_9
+CLUTTER_F1
+CLUTTER_F2
+CLUTTER_F3
+CLUTTER_F4
+CLUTTER_F5
+CLUTTER_F6
+CLUTTER_F7
+CLUTTER_F8
+CLUTTER_F9
+CLUTTER_F10
+CLUTTER_F11
+CLUTTER_L1
+CLUTTER_F12
+CLUTTER_L2
+CLUTTER_F13
+CLUTTER_L3
+CLUTTER_F14
+CLUTTER_L4
+CLUTTER_F15
+CLUTTER_L5
+CLUTTER_F16
+CLUTTER_L6
+CLUTTER_F17
+CLUTTER_L7
+CLUTTER_F18
+CLUTTER_L8
+CLUTTER_F19
+CLUTTER_L9
+CLUTTER_F20
+CLUTTER_L10
+CLUTTER_F21
+CLUTTER_R1
+CLUTTER_F22
+CLUTTER_R2
+CLUTTER_F23
+CLUTTER_R3
+CLUTTER_F24
+CLUTTER_R4
+CLUTTER_F25
+CLUTTER_R5
+CLUTTER_F26
+CLUTTER_R6
+CLUTTER_F27
+CLUTTER_R7
+CLUTTER_F28
+CLUTTER_R8
+CLUTTER_F29
+CLUTTER_R9
+CLUTTER_F30
+CLUTTER_R10
+CLUTTER_F31
+CLUTTER_R11
+CLUTTER_F32
+CLUTTER_R12
+CLUTTER_F33
+CLUTTER_R13
+CLUTTER_F34
+CLUTTER_R14
+CLUTTER_F35
+CLUTTER_R15
+CLUTTER_Shift_L
+CLUTTER_Shift_R
+CLUTTER_Control_L
+CLUTTER_Control_R
+CLUTTER_Caps_Lock
+CLUTTER_Shift_Lock
+CLUTTER_Meta_L
+CLUTTER_Meta_R
+CLUTTER_Alt_L
+CLUTTER_Alt_R
+CLUTTER_Super_L
+CLUTTER_Super_R
+CLUTTER_Hyper_L
+CLUTTER_Hyper_R
+CLUTTER_ISO_Lock
+CLUTTER_ISO_Level2_Latch
+CLUTTER_ISO_Level3_Shift
+CLUTTER_ISO_Level3_Latch
+CLUTTER_ISO_Level3_Lock
+CLUTTER_ISO_Group_Shift
+CLUTTER_ISO_Group_Latch
+CLUTTER_ISO_Group_Lock
+CLUTTER_ISO_Next_Group
+CLUTTER_ISO_Next_Group_Lock
+CLUTTER_ISO_Prev_Group
+CLUTTER_ISO_Prev_Group_Lock
+CLUTTER_ISO_First_Group
+CLUTTER_ISO_First_Group_Lock
+CLUTTER_ISO_Last_Group
+CLUTTER_ISO_Last_Group_Lock
+CLUTTER_ISO_Left_Tab
+CLUTTER_ISO_Move_Line_Up
+CLUTTER_ISO_Move_Line_Down
+CLUTTER_ISO_Partial_Line_Up
+CLUTTER_ISO_Partial_Line_Down
+CLUTTER_ISO_Partial_Space_Left
+CLUTTER_ISO_Partial_Space_Right
+CLUTTER_ISO_Set_Margin_Left
+CLUTTER_ISO_Set_Margin_Right
+CLUTTER_ISO_Release_Margin_Left
+CLUTTER_ISO_Release_Margin_Right
+CLUTTER_ISO_Release_Both_Margins
+CLUTTER_ISO_Fast_Cursor_Left
+CLUTTER_ISO_Fast_Cursor_Right
+CLUTTER_ISO_Fast_Cursor_Up
+CLUTTER_ISO_Fast_Cursor_Down
+CLUTTER_ISO_Continuous_Underline
+CLUTTER_ISO_Discontinuous_Underline
+CLUTTER_ISO_Emphasize
+CLUTTER_ISO_Center_Object
+CLUTTER_ISO_Enter
+CLUTTER_dead_grave
+CLUTTER_dead_acute
+CLUTTER_dead_circumflex
+CLUTTER_dead_tilde
+CLUTTER_dead_macron
+CLUTTER_dead_breve
+CLUTTER_dead_abovedot
+CLUTTER_dead_diaeresis
+CLUTTER_dead_abovering
+CLUTTER_dead_doubleacute
+CLUTTER_dead_caron
+CLUTTER_dead_cedilla
+CLUTTER_dead_ogonek
+CLUTTER_dead_iota
+CLUTTER_dead_voiced_sound
+CLUTTER_dead_semivoiced_sound
+CLUTTER_dead_belowdot
+CLUTTER_dead_hook
+CLUTTER_dead_horn
+CLUTTER_First_Virtual_Screen
+CLUTTER_Prev_Virtual_Screen
+CLUTTER_Next_Virtual_Screen
+CLUTTER_Last_Virtual_Screen
+CLUTTER_Terminate_Server
+CLUTTER_AccessX_Enable
+CLUTTER_AccessX_Feedback_Enable
+CLUTTER_RepeatKeys_Enable
+CLUTTER_SlowKeys_Enable
+CLUTTER_BounceKeys_Enable
+CLUTTER_StickyKeys_Enable
+CLUTTER_MouseKeys_Enable
+CLUTTER_MouseKeys_Accel_Enable
+CLUTTER_Overlay1_Enable
+CLUTTER_Overlay2_Enable
+CLUTTER_AudibleBell_Enable
+CLUTTER_Pointer_Left
+CLUTTER_Pointer_Right
+CLUTTER_Pointer_Up
+CLUTTER_Pointer_Down
+CLUTTER_Pointer_UpLeft
+CLUTTER_Pointer_UpRight
+CLUTTER_Pointer_DownLeft
+CLUTTER_Pointer_DownRight
+CLUTTER_Pointer_Button_Dflt
+CLUTTER_Pointer_Button1
+CLUTTER_Pointer_Button2
+CLUTTER_Pointer_Button3
+CLUTTER_Pointer_Button4
+CLUTTER_Pointer_Button5
+CLUTTER_Pointer_DblClick_Dflt
+CLUTTER_Pointer_DblClick1
+CLUTTER_Pointer_DblClick2
+CLUTTER_Pointer_DblClick3
+CLUTTER_Pointer_DblClick4
+CLUTTER_Pointer_DblClick5
+CLUTTER_Pointer_Drag_Dflt
+CLUTTER_Pointer_Drag1
+CLUTTER_Pointer_Drag2
+CLUTTER_Pointer_Drag3
+CLUTTER_Pointer_Drag4
+CLUTTER_Pointer_Drag5
+CLUTTER_Pointer_EnableKeys
+CLUTTER_Pointer_Accelerate
+CLUTTER_Pointer_DfltBtnNext
+CLUTTER_Pointer_DfltBtnPrev
+CLUTTER_3270_Duplicate
+CLUTTER_3270_FieldMark
+CLUTTER_3270_Right2
+CLUTTER_3270_Left2
+CLUTTER_3270_BackTab
+CLUTTER_3270_EraseEOF
+CLUTTER_3270_EraseInput
+CLUTTER_3270_Reset
+CLUTTER_3270_Quit
+CLUTTER_3270_PA1
+CLUTTER_3270_PA2
+CLUTTER_3270_PA3
+CLUTTER_3270_Test
+CLUTTER_3270_Attn
+CLUTTER_3270_CursorBlink
+CLUTTER_3270_AltCursor
+CLUTTER_3270_KeyClick
+CLUTTER_3270_Jump
+CLUTTER_3270_Ident
+CLUTTER_3270_Rule
+CLUTTER_3270_Copy
+CLUTTER_3270_Play
+CLUTTER_3270_Setup
+CLUTTER_3270_Record
+CLUTTER_3270_ChangeScreen
+CLUTTER_3270_DeleteWord
+CLUTTER_3270_ExSelect
+CLUTTER_3270_CursorSelect
+CLUTTER_3270_PrintScreen
+CLUTTER_3270_Enter
+CLUTTER_space
+CLUTTER_exclam
+CLUTTER_quotedbl
+CLUTTER_numbersign
+CLUTTER_dollar
+CLUTTER_percent
+CLUTTER_ampersand
+CLUTTER_apostrophe
+CLUTTER_quoteright
+CLUTTER_parenleft
+CLUTTER_parenright
+CLUTTER_asterisk
+CLUTTER_plus
+CLUTTER_comma
+CLUTTER_minus
+CLUTTER_period
+CLUTTER_slash
+CLUTTER_0
+CLUTTER_1
+CLUTTER_2
+CLUTTER_3
+CLUTTER_4
+CLUTTER_5
+CLUTTER_6
+CLUTTER_7
+CLUTTER_8
+CLUTTER_9
+CLUTTER_colon
+CLUTTER_semicolon
+CLUTTER_less
+CLUTTER_equal
+CLUTTER_greater
+CLUTTER_question
+CLUTTER_at
+CLUTTER_A
+CLUTTER_B
+CLUTTER_C
+CLUTTER_D
+CLUTTER_E
+CLUTTER_F
+CLUTTER_G
+CLUTTER_H
+CLUTTER_I
+CLUTTER_J
+CLUTTER_K
+CLUTTER_L
+CLUTTER_M
+CLUTTER_N
+CLUTTER_O
+CLUTTER_P
+CLUTTER_Q
+CLUTTER_R
+CLUTTER_S
+CLUTTER_T
+CLUTTER_U
+CLUTTER_V
+CLUTTER_W
+CLUTTER_X
+CLUTTER_Y
+CLUTTER_Z
+CLUTTER_bracketleft
+CLUTTER_backslash
+CLUTTER_bracketright
+CLUTTER_asciicircum
+CLUTTER_underscore
+CLUTTER_grave
+CLUTTER_quoteleft
+CLUTTER_a
+CLUTTER_b
+CLUTTER_c
+CLUTTER_d
+CLUTTER_e
+CLUTTER_f
+CLUTTER_g
+CLUTTER_h
+CLUTTER_i
+CLUTTER_j
+CLUTTER_k
+CLUTTER_l
+CLUTTER_m
+CLUTTER_n
+CLUTTER_o
+CLUTTER_p
+CLUTTER_q
+CLUTTER_r
+CLUTTER_s
+CLUTTER_t
+CLUTTER_u
+CLUTTER_v
+CLUTTER_w
+CLUTTER_x
+CLUTTER_y
+CLUTTER_z
+CLUTTER_braceleft
+CLUTTER_bar
+CLUTTER_braceright
+CLUTTER_asciitilde
+CLUTTER_nobreakspace
+CLUTTER_exclamdown
+CLUTTER_cent
+CLUTTER_sterling
+CLUTTER_currency
+CLUTTER_yen
+CLUTTER_brokenbar
+CLUTTER_section
+CLUTTER_diaeresis
+CLUTTER_copyright
+CLUTTER_ordfeminine
+CLUTTER_guillemotleft
+CLUTTER_notsign
+CLUTTER_hyphen
+CLUTTER_registered
+CLUTTER_macron
+CLUTTER_degree
+CLUTTER_plusminus
+CLUTTER_twosuperior
+CLUTTER_threesuperior
+CLUTTER_acute
+CLUTTER_mu
+CLUTTER_paragraph
+CLUTTER_periodcentered
+CLUTTER_cedilla
+CLUTTER_onesuperior
+CLUTTER_masculine
+CLUTTER_guillemotright
+CLUTTER_onequarter
+CLUTTER_onehalf
+CLUTTER_threequarters
+CLUTTER_questiondown
+CLUTTER_Agrave
+CLUTTER_Aacute
+CLUTTER_Acircumflex
+CLUTTER_Atilde
+CLUTTER_Adiaeresis
+CLUTTER_Aring
+CLUTTER_AE
+CLUTTER_Ccedilla
+CLUTTER_Egrave
+CLUTTER_Eacute
+CLUTTER_Ecircumflex
+CLUTTER_Ediaeresis
+CLUTTER_Igrave
+CLUTTER_Iacute
+CLUTTER_Icircumflex
+CLUTTER_Idiaeresis
+CLUTTER_ETH
+CLUTTER_Eth
+CLUTTER_Ntilde
+CLUTTER_Ograve
+CLUTTER_Oacute
+CLUTTER_Ocircumflex
+CLUTTER_Otilde
+CLUTTER_Odiaeresis
+CLUTTER_multiply
+CLUTTER_Ooblique
+CLUTTER_Ugrave
+CLUTTER_Uacute
+CLUTTER_Ucircumflex
+CLUTTER_Udiaeresis
+CLUTTER_Yacute
+CLUTTER_THORN
+CLUTTER_Thorn
+CLUTTER_ssharp
+CLUTTER_agrave
+CLUTTER_aacute
+CLUTTER_acircumflex
+CLUTTER_atilde
+CLUTTER_adiaeresis
+CLUTTER_aring
+CLUTTER_ae
+CLUTTER_ccedilla
+CLUTTER_egrave
+CLUTTER_eacute
+CLUTTER_ecircumflex
+CLUTTER_ediaeresis
+CLUTTER_igrave
+CLUTTER_iacute
+CLUTTER_icircumflex
+CLUTTER_idiaeresis
+CLUTTER_eth
+CLUTTER_ntilde
+CLUTTER_ograve
+CLUTTER_oacute
+CLUTTER_ocircumflex
+CLUTTER_otilde
+CLUTTER_odiaeresis
+CLUTTER_division
+CLUTTER_oslash
+CLUTTER_ugrave
+CLUTTER_uacute
+CLUTTER_ucircumflex
+CLUTTER_udiaeresis
+CLUTTER_yacute
+CLUTTER_thorn
+CLUTTER_ydiaeresis
+CLUTTER_Aogonek
+CLUTTER_breve
+CLUTTER_Lstroke
+CLUTTER_Lcaron
+CLUTTER_Sacute
+CLUTTER_Scaron
+CLUTTER_Scedilla
+CLUTTER_Tcaron
+CLUTTER_Zacute
+CLUTTER_Zcaron
+CLUTTER_Zabovedot
+CLUTTER_aogonek
+CLUTTER_ogonek
+CLUTTER_lstroke
+CLUTTER_lcaron
+CLUTTER_sacute
+CLUTTER_caron
+CLUTTER_scaron
+CLUTTER_scedilla
+CLUTTER_tcaron
+CLUTTER_zacute
+CLUTTER_doubleacute
+CLUTTER_zcaron
+CLUTTER_zabovedot
+CLUTTER_Racute
+CLUTTER_Abreve
+CLUTTER_Lacute
+CLUTTER_Cacute
+CLUTTER_Ccaron
+CLUTTER_Eogonek
+CLUTTER_Ecaron
+CLUTTER_Dcaron
+CLUTTER_Dstroke
+CLUTTER_Nacute
+CLUTTER_Ncaron
+CLUTTER_Odoubleacute
+CLUTTER_Rcaron
+CLUTTER_Uring
+CLUTTER_Udoubleacute
+CLUTTER_Tcedilla
+CLUTTER_racute
+CLUTTER_abreve
+CLUTTER_lacute
+CLUTTER_cacute
+CLUTTER_ccaron
+CLUTTER_eogonek
+CLUTTER_ecaron
+CLUTTER_dcaron
+CLUTTER_dstroke
+CLUTTER_nacute
+CLUTTER_ncaron
+CLUTTER_odoubleacute
+CLUTTER_udoubleacute
+CLUTTER_rcaron
+CLUTTER_uring
+CLUTTER_tcedilla
+CLUTTER_abovedot
+CLUTTER_Hstroke
+CLUTTER_Hcircumflex
+CLUTTER_Iabovedot
+CLUTTER_Gbreve
+CLUTTER_Jcircumflex
+CLUTTER_hstroke
+CLUTTER_hcircumflex
+CLUTTER_idotless
+CLUTTER_gbreve
+CLUTTER_jcircumflex
+CLUTTER_Cabovedot
+CLUTTER_Ccircumflex
+CLUTTER_Gabovedot
+CLUTTER_Gcircumflex
+CLUTTER_Ubreve
+CLUTTER_Scircumflex
+CLUTTER_cabovedot
+CLUTTER_ccircumflex
+CLUTTER_gabovedot
+CLUTTER_gcircumflex
+CLUTTER_ubreve
+CLUTTER_scircumflex
+CLUTTER_kra
+CLUTTER_kappa
+CLUTTER_Rcedilla
+CLUTTER_Itilde
+CLUTTER_Lcedilla
+CLUTTER_Emacron
+CLUTTER_Gcedilla
+CLUTTER_Tslash
+CLUTTER_rcedilla
+CLUTTER_itilde
+CLUTTER_lcedilla
+CLUTTER_emacron
+CLUTTER_gcedilla
+CLUTTER_tslash
+CLUTTER_ENG
+CLUTTER_eng
+CLUTTER_Amacron
+CLUTTER_Iogonek
+CLUTTER_Eabovedot
+CLUTTER_Imacron
+CLUTTER_Ncedilla
+CLUTTER_Omacron
+CLUTTER_Kcedilla
+CLUTTER_Uogonek
+CLUTTER_Utilde
+CLUTTER_Umacron
+CLUTTER_amacron
+CLUTTER_iogonek
+CLUTTER_eabovedot
+CLUTTER_imacron
+CLUTTER_ncedilla
+CLUTTER_omacron
+CLUTTER_kcedilla
+CLUTTER_uogonek
+CLUTTER_utilde
+CLUTTER_umacron
+CLUTTER_OE
+CLUTTER_oe
+CLUTTER_Ydiaeresis
+CLUTTER_overline
+CLUTTER_kana_fullstop
+CLUTTER_kana_openingbracket
+CLUTTER_kana_closingbracket
+CLUTTER_kana_comma
+CLUTTER_kana_conjunctive
+CLUTTER_kana_middledot
+CLUTTER_kana_WO
+CLUTTER_kana_a
+CLUTTER_kana_i
+CLUTTER_kana_u
+CLUTTER_kana_e
+CLUTTER_kana_o
+CLUTTER_kana_ya
+CLUTTER_kana_yu
+CLUTTER_kana_yo
+CLUTTER_kana_tsu
+CLUTTER_kana_tu
+CLUTTER_prolongedsound
+CLUTTER_kana_A
+CLUTTER_kana_I
+CLUTTER_kana_U
+CLUTTER_kana_E
+CLUTTER_kana_O
+CLUTTER_kana_KA
+CLUTTER_kana_KI
+CLUTTER_kana_KU
+CLUTTER_kana_KE
+CLUTTER_kana_KO
+CLUTTER_kana_SA
+CLUTTER_kana_SHI
+CLUTTER_kana_SU
+CLUTTER_kana_SE
+CLUTTER_kana_SO
+CLUTTER_kana_TA
+CLUTTER_kana_CHI
+CLUTTER_kana_TI
+CLUTTER_kana_TSU
+CLUTTER_kana_TU
+CLUTTER_kana_TE
+CLUTTER_kana_TO
+CLUTTER_kana_NA
+CLUTTER_kana_NI
+CLUTTER_kana_NU
+CLUTTER_kana_NE
+CLUTTER_kana_NO
+CLUTTER_kana_HA
+CLUTTER_kana_HI
+CLUTTER_kana_FU
+CLUTTER_kana_HU
+CLUTTER_kana_HE
+CLUTTER_kana_HO
+CLUTTER_kana_MA
+CLUTTER_kana_MI
+CLUTTER_kana_MU
+CLUTTER_kana_ME
+CLUTTER_kana_MO
+CLUTTER_kana_YA
+CLUTTER_kana_YU
+CLUTTER_kana_YO
+CLUTTER_kana_RA
+CLUTTER_kana_RI
+CLUTTER_kana_RU
+CLUTTER_kana_RE
+CLUTTER_kana_RO
+CLUTTER_kana_WA
+CLUTTER_kana_N
+CLUTTER_voicedsound
+CLUTTER_semivoicedsound
+CLUTTER_kana_switch
+CLUTTER_Arabic_comma
+CLUTTER_Arabic_semicolon
+CLUTTER_Arabic_question_mark
+CLUTTER_Arabic_hamza
+CLUTTER_Arabic_maddaonalef
+CLUTTER_Arabic_hamzaonalef
+CLUTTER_Arabic_hamzaonwaw
+CLUTTER_Arabic_hamzaunderalef
+CLUTTER_Arabic_hamzaonyeh
+CLUTTER_Arabic_alef
+CLUTTER_Arabic_beh
+CLUTTER_Arabic_tehmarbuta
+CLUTTER_Arabic_teh
+CLUTTER_Arabic_theh
+CLUTTER_Arabic_jeem
+CLUTTER_Arabic_hah
+CLUTTER_Arabic_khah
+CLUTTER_Arabic_dal
+CLUTTER_Arabic_thal
+CLUTTER_Arabic_ra
+CLUTTER_Arabic_zain
+CLUTTER_Arabic_seen
+CLUTTER_Arabic_sheen
+CLUTTER_Arabic_sad
+CLUTTER_Arabic_dad
+CLUTTER_Arabic_tah
+CLUTTER_Arabic_zah
+CLUTTER_Arabic_ain
+CLUTTER_Arabic_ghain
+CLUTTER_Arabic_tatweel
+CLUTTER_Arabic_feh
+CLUTTER_Arabic_qaf
+CLUTTER_Arabic_kaf
+CLUTTER_Arabic_lam
+CLUTTER_Arabic_meem
+CLUTTER_Arabic_noon
+CLUTTER_Arabic_ha
+CLUTTER_Arabic_heh
+CLUTTER_Arabic_waw
+CLUTTER_Arabic_alefmaksura
+CLUTTER_Arabic_yeh
+CLUTTER_Arabic_fathatan
+CLUTTER_Arabic_dammatan
+CLUTTER_Arabic_kasratan
+CLUTTER_Arabic_fatha
+CLUTTER_Arabic_damma
+CLUTTER_Arabic_kasra
+CLUTTER_Arabic_shadda
+CLUTTER_Arabic_sukun
+CLUTTER_Arabic_switch
+CLUTTER_Serbian_dje
+CLUTTER_Macedonia_gje
+CLUTTER_Cyrillic_io
+CLUTTER_Ukrainian_ie
+CLUTTER_Ukranian_je
+CLUTTER_Macedonia_dse
+CLUTTER_Ukrainian_i
+CLUTTER_Ukranian_i
+CLUTTER_Ukrainian_yi
+CLUTTER_Ukranian_yi
+CLUTTER_Cyrillic_je
+CLUTTER_Serbian_je
+CLUTTER_Cyrillic_lje
+CLUTTER_Serbian_lje
+CLUTTER_Cyrillic_nje
+CLUTTER_Serbian_nje
+CLUTTER_Serbian_tshe
+CLUTTER_Macedonia_kje
+CLUTTER_Ukrainian_ghe_with_upturn
+CLUTTER_Byelorussian_shortu
+CLUTTER_Cyrillic_dzhe
+CLUTTER_Serbian_dze
+CLUTTER_numerosign
+CLUTTER_Serbian_DJE
+CLUTTER_Macedonia_GJE
+CLUTTER_Cyrillic_IO
+CLUTTER_Ukrainian_IE
+CLUTTER_Ukranian_JE
+CLUTTER_Macedonia_DSE
+CLUTTER_Ukrainian_I
+CLUTTER_Ukranian_I
+CLUTTER_Ukrainian_YI
+CLUTTER_Ukranian_YI
+CLUTTER_Cyrillic_JE
+CLUTTER_Serbian_JE
+CLUTTER_Cyrillic_LJE
+CLUTTER_Serbian_LJE
+CLUTTER_Cyrillic_NJE
+CLUTTER_Serbian_NJE
+CLUTTER_Serbian_TSHE
+CLUTTER_Macedonia_KJE
+CLUTTER_Ukrainian_GHE_WITH_UPTURN
+CLUTTER_Byelorussian_SHORTU
+CLUTTER_Cyrillic_DZHE
+CLUTTER_Serbian_DZE
+CLUTTER_Cyrillic_yu
+CLUTTER_Cyrillic_a
+CLUTTER_Cyrillic_be
+CLUTTER_Cyrillic_tse
+CLUTTER_Cyrillic_de
+CLUTTER_Cyrillic_ie
+CLUTTER_Cyrillic_ef
+CLUTTER_Cyrillic_ghe
+CLUTTER_Cyrillic_ha
+CLUTTER_Cyrillic_i
+CLUTTER_Cyrillic_shorti
+CLUTTER_Cyrillic_ka
+CLUTTER_Cyrillic_el
+CLUTTER_Cyrillic_em
+CLUTTER_Cyrillic_en
+CLUTTER_Cyrillic_o
+CLUTTER_Cyrillic_pe
+CLUTTER_Cyrillic_ya
+CLUTTER_Cyrillic_er
+CLUTTER_Cyrillic_es
+CLUTTER_Cyrillic_te
+CLUTTER_Cyrillic_u
+CLUTTER_Cyrillic_zhe
+CLUTTER_Cyrillic_ve
+CLUTTER_Cyrillic_softsign
+CLUTTER_Cyrillic_yeru
+CLUTTER_Cyrillic_ze
+CLUTTER_Cyrillic_sha
+CLUTTER_Cyrillic_e
+CLUTTER_Cyrillic_shcha
+CLUTTER_Cyrillic_che
+CLUTTER_Cyrillic_hardsign
+CLUTTER_Cyrillic_YU
+CLUTTER_Cyrillic_A
+CLUTTER_Cyrillic_BE
+CLUTTER_Cyrillic_TSE
+CLUTTER_Cyrillic_DE
+CLUTTER_Cyrillic_IE
+CLUTTER_Cyrillic_EF
+CLUTTER_Cyrillic_GHE
+CLUTTER_Cyrillic_HA
+CLUTTER_Cyrillic_I
+CLUTTER_Cyrillic_SHORTI
+CLUTTER_Cyrillic_KA
+CLUTTER_Cyrillic_EL
+CLUTTER_Cyrillic_EM
+CLUTTER_Cyrillic_EN
+CLUTTER_Cyrillic_O
+CLUTTER_Cyrillic_PE
+CLUTTER_Cyrillic_YA
+CLUTTER_Cyrillic_ER
+CLUTTER_Cyrillic_ES
+CLUTTER_Cyrillic_TE
+CLUTTER_Cyrillic_U
+CLUTTER_Cyrillic_ZHE
+CLUTTER_Cyrillic_VE
+CLUTTER_Cyrillic_SOFTSIGN
+CLUTTER_Cyrillic_YERU
+CLUTTER_Cyrillic_ZE
+CLUTTER_Cyrillic_SHA
+CLUTTER_Cyrillic_E
+CLUTTER_Cyrillic_SHCHA
+CLUTTER_Cyrillic_CHE
+CLUTTER_Cyrillic_HARDSIGN
+CLUTTER_Greek_ALPHAaccent
+CLUTTER_Greek_EPSILONaccent
+CLUTTER_Greek_ETAaccent
+CLUTTER_Greek_IOTAaccent
+CLUTTER_Greek_IOTAdieresis
+CLUTTER_Greek_IOTAdiaeresis
+CLUTTER_Greek_OMICRONaccent
+CLUTTER_Greek_UPSILONaccent
+CLUTTER_Greek_UPSILONdieresis
+CLUTTER_Greek_OMEGAaccent
+CLUTTER_Greek_accentdieresis
+CLUTTER_Greek_horizbar
+CLUTTER_Greek_alphaaccent
+CLUTTER_Greek_epsilonaccent
+CLUTTER_Greek_etaaccent
+CLUTTER_Greek_iotaaccent
+CLUTTER_Greek_iotadieresis
+CLUTTER_Greek_iotaaccentdieresis
+CLUTTER_Greek_omicronaccent
+CLUTTER_Greek_upsilonaccent
+CLUTTER_Greek_upsilondieresis
+CLUTTER_Greek_upsilonaccentdieresis
+CLUTTER_Greek_omegaaccent
+CLUTTER_Greek_ALPHA
+CLUTTER_Greek_BETA
+CLUTTER_Greek_GAMMA
+CLUTTER_Greek_DELTA
+CLUTTER_Greek_EPSILON
+CLUTTER_Greek_ZETA
+CLUTTER_Greek_ETA
+CLUTTER_Greek_THETA
+CLUTTER_Greek_IOTA
+CLUTTER_Greek_KAPPA
+CLUTTER_Greek_LAMDA
+CLUTTER_Greek_LAMBDA
+CLUTTER_Greek_MU
+CLUTTER_Greek_NU
+CLUTTER_Greek_XI
+CLUTTER_Greek_OMICRON
+CLUTTER_Greek_PI
+CLUTTER_Greek_RHO
+CLUTTER_Greek_SIGMA
+CLUTTER_Greek_TAU
+CLUTTER_Greek_UPSILON
+CLUTTER_Greek_PHI
+CLUTTER_Greek_CHI
+CLUTTER_Greek_PSI
+CLUTTER_Greek_OMEGA
+CLUTTER_Greek_alpha
+CLUTTER_Greek_beta
+CLUTTER_Greek_gamma
+CLUTTER_Greek_delta
+CLUTTER_Greek_epsilon
+CLUTTER_Greek_zeta
+CLUTTER_Greek_eta
+CLUTTER_Greek_theta
+CLUTTER_Greek_iota
+CLUTTER_Greek_kappa
+CLUTTER_Greek_lamda
+CLUTTER_Greek_lambda
+CLUTTER_Greek_mu
+CLUTTER_Greek_nu
+CLUTTER_Greek_xi
+CLUTTER_Greek_omicron
+CLUTTER_Greek_pi
+CLUTTER_Greek_rho
+CLUTTER_Greek_sigma
+CLUTTER_Greek_finalsmallsigma
+CLUTTER_Greek_tau
+CLUTTER_Greek_upsilon
+CLUTTER_Greek_phi
+CLUTTER_Greek_chi
+CLUTTER_Greek_psi
+CLUTTER_Greek_omega
+CLUTTER_Greek_switch
+CLUTTER_leftradical
+CLUTTER_topleftradical
+CLUTTER_horizconnector
+CLUTTER_topintegral
+CLUTTER_botintegral
+CLUTTER_vertconnector
+CLUTTER_topleftsqbracket
+CLUTTER_botleftsqbracket
+CLUTTER_toprightsqbracket
+CLUTTER_botrightsqbracket
+CLUTTER_topleftparens
+CLUTTER_botleftparens
+CLUTTER_toprightparens
+CLUTTER_botrightparens
+CLUTTER_leftmiddlecurlybrace
+CLUTTER_rightmiddlecurlybrace
+CLUTTER_topleftsummation
+CLUTTER_botleftsummation
+CLUTTER_topvertsummationconnector
+CLUTTER_botvertsummationconnector
+CLUTTER_toprightsummation
+CLUTTER_botrightsummation
+CLUTTER_rightmiddlesummation
+CLUTTER_lessthanequal
+CLUTTER_notequal
+CLUTTER_greaterthanequal
+CLUTTER_integral
+CLUTTER_therefore
+CLUTTER_variation
+CLUTTER_infinity
+CLUTTER_nabla
+CLUTTER_approximate
+CLUTTER_similarequal
+CLUTTER_ifonlyif
+CLUTTER_implies
+CLUTTER_identical
+CLUTTER_radical
+CLUTTER_includedin
+CLUTTER_includes
+CLUTTER_intersection
+CLUTTER_union
+CLUTTER_logicaland
+CLUTTER_logicalor
+CLUTTER_partialderivative
+CLUTTER_function
+CLUTTER_leftarrow
+CLUTTER_uparrow
+CLUTTER_rightarrow
+CLUTTER_downarrow
+CLUTTER_blank
+CLUTTER_soliddiamond
+CLUTTER_checkerboard
+CLUTTER_ht
+CLUTTER_ff
+CLUTTER_cr
+CLUTTER_lf
+CLUTTER_nl
+CLUTTER_vt
+CLUTTER_lowrightcorner
+CLUTTER_uprightcorner
+CLUTTER_upleftcorner
+CLUTTER_lowleftcorner
+CLUTTER_crossinglines
+CLUTTER_horizlinescan1
+CLUTTER_horizlinescan3
+CLUTTER_horizlinescan5
+CLUTTER_horizlinescan7
+CLUTTER_horizlinescan9
+CLUTTER_leftt
+CLUTTER_rightt
+CLUTTER_bott
+CLUTTER_topt
+CLUTTER_vertbar
+CLUTTER_emspace
+CLUTTER_enspace
+CLUTTER_em3space
+CLUTTER_em4space
+CLUTTER_digitspace
+CLUTTER_punctspace
+CLUTTER_thinspace
+CLUTTER_hairspace
+CLUTTER_emdash
+CLUTTER_endash
+CLUTTER_signifblank
+CLUTTER_ellipsis
+CLUTTER_doubbaselinedot
+CLUTTER_onethird
+CLUTTER_twothirds
+CLUTTER_onefifth
+CLUTTER_twofifths
+CLUTTER_threefifths
+CLUTTER_fourfifths
+CLUTTER_onesixth
+CLUTTER_fivesixths
+CLUTTER_careof
+CLUTTER_figdash
+CLUTTER_leftanglebracket
+CLUTTER_decimalpoint
+CLUTTER_rightanglebracket
+CLUTTER_marker
+CLUTTER_oneeighth
+CLUTTER_threeeighths
+CLUTTER_fiveeighths
+CLUTTER_seveneighths
+CLUTTER_trademark
+CLUTTER_signaturemark
+CLUTTER_trademarkincircle
+CLUTTER_leftopentriangle
+CLUTTER_rightopentriangle
+CLUTTER_emopencircle
+CLUTTER_emopenrectangle
+CLUTTER_leftsinglequotemark
+CLUTTER_rightsinglequotemark
+CLUTTER_leftdoublequotemark
+CLUTTER_rightdoublequotemark
+CLUTTER_prescription
+CLUTTER_minutes
+CLUTTER_seconds
+CLUTTER_latincross
+CLUTTER_hexagram
+CLUTTER_filledrectbullet
+CLUTTER_filledlefttribullet
+CLUTTER_filledrighttribullet
+CLUTTER_emfilledcircle
+CLUTTER_emfilledrect
+CLUTTER_enopencircbullet
+CLUTTER_enopensquarebullet
+CLUTTER_openrectbullet
+CLUTTER_opentribulletup
+CLUTTER_opentribulletdown
+CLUTTER_openstar
+CLUTTER_enfilledcircbullet
+CLUTTER_enfilledsqbullet
+CLUTTER_filledtribulletup
+CLUTTER_filledtribulletdown
+CLUTTER_leftpointer
+CLUTTER_rightpointer
+CLUTTER_club
+CLUTTER_diamond
+CLUTTER_heart
+CLUTTER_maltesecross
+CLUTTER_dagger
+CLUTTER_doubledagger
+CLUTTER_checkmark
+CLUTTER_ballotcross
+CLUTTER_musicalsharp
+CLUTTER_musicalflat
+CLUTTER_malesymbol
+CLUTTER_femalesymbol
+CLUTTER_telephone
+CLUTTER_telephonerecorder
+CLUTTER_phonographcopyright
+CLUTTER_caret
+CLUTTER_singlelowquotemark
+CLUTTER_doublelowquotemark
+CLUTTER_cursor
+CLUTTER_leftcaret
+CLUTTER_rightcaret
+CLUTTER_downcaret
+CLUTTER_upcaret
+CLUTTER_overbar
+CLUTTER_downtack
+CLUTTER_upshoe
+CLUTTER_downstile
+CLUTTER_underbar
+CLUTTER_jot
+CLUTTER_quad
+CLUTTER_uptack
+CLUTTER_circle
+CLUTTER_upstile
+CLUTTER_downshoe
+CLUTTER_rightshoe
+CLUTTER_leftshoe
+CLUTTER_lefttack
+CLUTTER_righttack
+CLUTTER_hebrew_doublelowline
+CLUTTER_hebrew_aleph
+CLUTTER_hebrew_bet
+CLUTTER_hebrew_beth
+CLUTTER_hebrew_gimel
+CLUTTER_hebrew_gimmel
+CLUTTER_hebrew_dalet
+CLUTTER_hebrew_daleth
+CLUTTER_hebrew_he
+CLUTTER_hebrew_waw
+CLUTTER_hebrew_zain
+CLUTTER_hebrew_zayin
+CLUTTER_hebrew_chet
+CLUTTER_hebrew_het
+CLUTTER_hebrew_tet
+CLUTTER_hebrew_teth
+CLUTTER_hebrew_yod
+CLUTTER_hebrew_finalkaph
+CLUTTER_hebrew_kaph
+CLUTTER_hebrew_lamed
+CLUTTER_hebrew_finalmem
+CLUTTER_hebrew_mem
+CLUTTER_hebrew_finalnun
+CLUTTER_hebrew_nun
+CLUTTER_hebrew_samech
+CLUTTER_hebrew_samekh
+CLUTTER_hebrew_ayin
+CLUTTER_hebrew_finalpe
+CLUTTER_hebrew_pe
+CLUTTER_hebrew_finalzade
+CLUTTER_hebrew_finalzadi
+CLUTTER_hebrew_zade
+CLUTTER_hebrew_zadi
+CLUTTER_hebrew_qoph
+CLUTTER_hebrew_kuf
+CLUTTER_hebrew_resh
+CLUTTER_hebrew_shin
+CLUTTER_hebrew_taw
+CLUTTER_hebrew_taf
+CLUTTER_Hebrew_switch
+CLUTTER_Thai_kokai
+CLUTTER_Thai_khokhai
+CLUTTER_Thai_khokhuat
+CLUTTER_Thai_khokhwai
+CLUTTER_Thai_khokhon
+CLUTTER_Thai_khorakhang
+CLUTTER_Thai_ngongu
+CLUTTER_Thai_chochan
+CLUTTER_Thai_choching
+CLUTTER_Thai_chochang
+CLUTTER_Thai_soso
+CLUTTER_Thai_chochoe
+CLUTTER_Thai_yoying
+CLUTTER_Thai_dochada
+CLUTTER_Thai_topatak
+CLUTTER_Thai_thothan
+CLUTTER_Thai_thonangmontho
+CLUTTER_Thai_thophuthao
+CLUTTER_Thai_nonen
+CLUTTER_Thai_dodek
+CLUTTER_Thai_totao
+CLUTTER_Thai_thothung
+CLUTTER_Thai_thothahan
+CLUTTER_Thai_thothong
+CLUTTER_Thai_nonu
+CLUTTER_Thai_bobaimai
+CLUTTER_Thai_popla
+CLUTTER_Thai_phophung
+CLUTTER_Thai_fofa
+CLUTTER_Thai_phophan
+CLUTTER_Thai_fofan
+CLUTTER_Thai_phosamphao
+CLUTTER_Thai_moma
+CLUTTER_Thai_yoyak
+CLUTTER_Thai_rorua
+CLUTTER_Thai_ru
+CLUTTER_Thai_loling
+CLUTTER_Thai_lu
+CLUTTER_Thai_wowaen
+CLUTTER_Thai_sosala
+CLUTTER_Thai_sorusi
+CLUTTER_Thai_sosua
+CLUTTER_Thai_hohip
+CLUTTER_Thai_lochula
+CLUTTER_Thai_oang
+CLUTTER_Thai_honokhuk
+CLUTTER_Thai_paiyannoi
+CLUTTER_Thai_saraa
+CLUTTER_Thai_maihanakat
+CLUTTER_Thai_saraaa
+CLUTTER_Thai_saraam
+CLUTTER_Thai_sarai
+CLUTTER_Thai_saraii
+CLUTTER_Thai_saraue
+CLUTTER_Thai_sarauee
+CLUTTER_Thai_sarau
+CLUTTER_Thai_sarauu
+CLUTTER_Thai_phinthu
+CLUTTER_Thai_maihanakat_maitho
+CLUTTER_Thai_baht
+CLUTTER_Thai_sarae
+CLUTTER_Thai_saraae
+CLUTTER_Thai_sarao
+CLUTTER_Thai_saraaimaimuan
+CLUTTER_Thai_saraaimaimalai
+CLUTTER_Thai_lakkhangyao
+CLUTTER_Thai_maiyamok
+CLUTTER_Thai_maitaikhu
+CLUTTER_Thai_maiek
+CLUTTER_Thai_maitho
+CLUTTER_Thai_maitri
+CLUTTER_Thai_maichattawa
+CLUTTER_Thai_thanthakhat
+CLUTTER_Thai_nikhahit
+CLUTTER_Thai_leksun
+CLUTTER_Thai_leknung
+CLUTTER_Thai_leksong
+CLUTTER_Thai_leksam
+CLUTTER_Thai_leksi
+CLUTTER_Thai_lekha
+CLUTTER_Thai_lekhok
+CLUTTER_Thai_lekchet
+CLUTTER_Thai_lekpaet
+CLUTTER_Thai_lekkao
+CLUTTER_Hangul
+CLUTTER_Hangul_Start
+CLUTTER_Hangul_End
+CLUTTER_Hangul_Hanja
+CLUTTER_Hangul_Jamo
+CLUTTER_Hangul_Romaja
+CLUTTER_Hangul_Codeinput
+CLUTTER_Hangul_Jeonja
+CLUTTER_Hangul_Banja
+CLUTTER_Hangul_PreHanja
+CLUTTER_Hangul_PostHanja
+CLUTTER_Hangul_SingleCandidate
+CLUTTER_Hangul_MultipleCandidate
+CLUTTER_Hangul_PreviousCandidate
+CLUTTER_Hangul_Special
+CLUTTER_Hangul_switch
+CLUTTER_Hangul_Kiyeog
+CLUTTER_Hangul_SsangKiyeog
+CLUTTER_Hangul_KiyeogSios
+CLUTTER_Hangul_Nieun
+CLUTTER_Hangul_NieunJieuj
+CLUTTER_Hangul_NieunHieuh
+CLUTTER_Hangul_Dikeud
+CLUTTER_Hangul_SsangDikeud
+CLUTTER_Hangul_Rieul
+CLUTTER_Hangul_RieulKiyeog
+CLUTTER_Hangul_RieulMieum
+CLUTTER_Hangul_RieulPieub
+CLUTTER_Hangul_RieulSios
+CLUTTER_Hangul_RieulTieut
+CLUTTER_Hangul_RieulPhieuf
+CLUTTER_Hangul_RieulHieuh
+CLUTTER_Hangul_Mieum
+CLUTTER_Hangul_Pieub
+CLUTTER_Hangul_SsangPieub
+CLUTTER_Hangul_PieubSios
+CLUTTER_Hangul_Sios
+CLUTTER_Hangul_SsangSios
+CLUTTER_Hangul_Ieung
+CLUTTER_Hangul_Jieuj
+CLUTTER_Hangul_SsangJieuj
+CLUTTER_Hangul_Cieuc
+CLUTTER_Hangul_Khieuq
+CLUTTER_Hangul_Tieut
+CLUTTER_Hangul_Phieuf
+CLUTTER_Hangul_Hieuh
+CLUTTER_Hangul_A
+CLUTTER_Hangul_AE
+CLUTTER_Hangul_YA
+CLUTTER_Hangul_YAE
+CLUTTER_Hangul_EO
+CLUTTER_Hangul_E
+CLUTTER_Hangul_YEO
+CLUTTER_Hangul_YE
+CLUTTER_Hangul_O
+CLUTTER_Hangul_WA
+CLUTTER_Hangul_WAE
+CLUTTER_Hangul_OE
+CLUTTER_Hangul_YO
+CLUTTER_Hangul_U
+CLUTTER_Hangul_WEO
+CLUTTER_Hangul_WE
+CLUTTER_Hangul_WI
+CLUTTER_Hangul_YU
+CLUTTER_Hangul_EU
+CLUTTER_Hangul_YI
+CLUTTER_Hangul_I
+CLUTTER_Hangul_J_Kiyeog
+CLUTTER_Hangul_J_SsangKiyeog
+CLUTTER_Hangul_J_KiyeogSios
+CLUTTER_Hangul_J_Nieun
+CLUTTER_Hangul_J_NieunJieuj
+CLUTTER_Hangul_J_NieunHieuh
+CLUTTER_Hangul_J_Dikeud
+CLUTTER_Hangul_J_Rieul
+CLUTTER_Hangul_J_RieulKiyeog
+CLUTTER_Hangul_J_RieulMieum
+CLUTTER_Hangul_J_RieulPieub
+CLUTTER_Hangul_J_RieulSios
+CLUTTER_Hangul_J_RieulTieut
+CLUTTER_Hangul_J_RieulPhieuf
+CLUTTER_Hangul_J_RieulHieuh
+CLUTTER_Hangul_J_Mieum
+CLUTTER_Hangul_J_Pieub
+CLUTTER_Hangul_J_PieubSios
+CLUTTER_Hangul_J_Sios
+CLUTTER_Hangul_J_SsangSios
+CLUTTER_Hangul_J_Ieung
+CLUTTER_Hangul_J_Jieuj
+CLUTTER_Hangul_J_Cieuc
+CLUTTER_Hangul_J_Khieuq
+CLUTTER_Hangul_J_Tieut
+CLUTTER_Hangul_J_Phieuf
+CLUTTER_Hangul_J_Hieuh
+CLUTTER_Hangul_RieulYeorinHieuh
+CLUTTER_Hangul_SunkyeongeumMieum
+CLUTTER_Hangul_SunkyeongeumPieub
+CLUTTER_Hangul_PanSios
+CLUTTER_Hangul_KkogjiDalrinIeung
+CLUTTER_Hangul_SunkyeongeumPhieuf
+CLUTTER_Hangul_YeorinHieuh
+CLUTTER_Hangul_AraeA
+CLUTTER_Hangul_AraeAE
+CLUTTER_Hangul_J_PanSios
+CLUTTER_Hangul_J_KkogjiDalrinIeung
+CLUTTER_Hangul_J_YeorinHieuh
+CLUTTER_Korean_Won
+CLUTTER_EcuSign
+CLUTTER_ColonSign
+CLUTTER_CruzeiroSign
+CLUTTER_FFrancSign
+CLUTTER_LiraSign
+CLUTTER_MillSign
+CLUTTER_NairaSign
+CLUTTER_PesetaSign
+CLUTTER_RupeeSign
+CLUTTER_WonSign
+CLUTTER_NewSheqelSign
+CLUTTER_DongSign
+CLUTTER_EuroSign
+</SECTION>
+
+<SECTION>
+<FILE>clutter-marshal</FILE>
+clutter_marshal_VOID__INT64_INT64_FLOAT_BOOLEAN
+clutter_marshal_VOID__STRING_BOOLEAN_BOOLEAN
+clutter_marshal_VOID__INT_INT
+</SECTION>
+
+<SECTION>
+<FILE>clutter-enum-types</FILE>
+CLUTTER_TYPE_EVENT_TYPE
+clutter_event_type_get_type
+CLUTTER_TYPE_ELEMENT_TRANSFORM
+clutter_element_transform_get_type
+CLUTTER_TYPE_ELEMENT_FLAGS
+clutter_element_flags_get_type
+CLUTTER_TYPE_VIDEO_TEXTURE_ERROR
+clutter_video_texture_error_get_type
+CLUTTER_TYPE_VIDEO_TEXTURE_ASPECT_RATIO
+clutter_video_texture_aspect_ratio_get_type
+CLUTTER_TYPE_VIDEO_TEXTURE_METADATA_TYPE
+clutter_video_texture_metadata_type_get_type
+</SECTION>
+
+<SECTION>
+<FILE>stamp-clutter-enum-types</FILE>
+</SECTION>
+
diff --git a/doc/reference/clutter.types b/doc/reference/clutter.types
new file mode 100644 (file)
index 0000000..44a606c
--- /dev/null
@@ -0,0 +1,11 @@
+#include <clutter/clutter.h>
+
+clutter_element_get_type
+clutter_group_get_type
+clutter_stage_get_type
+clutter_rectangle_get_type
+clutter_texture_get_type
+clutter_video_texture_get_type
+clutter_clone_texture_get_type
+clutter_label_get_type
+clutter_timeline_get_type
\ No newline at end of file
diff --git a/doc/reference/tmpl/clutter-0.0-unused.sgml b/doc/reference/tmpl/clutter-0.0-unused.sgml
new file mode 100644 (file)
index 0000000..8f7b8b8
--- /dev/null
@@ -0,0 +1,12 @@
+<!-- ##### STRUCT ClutterElementPrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT ClutterLabelPrivate ##### -->
+<para>
+
+</para>
+
+
diff --git a/doc/reference/tmpl/clutter-clone-texture.sgml b/doc/reference/tmpl/clutter-clone-texture.sgml
new file mode 100644 (file)
index 0000000..bd02605
--- /dev/null
@@ -0,0 +1,42 @@
+<!-- ##### SECTION Title ##### -->
+ClutterCloneTexture
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT ClutterCloneTexturePrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT ClutterCloneTexture ##### -->
+<para>
+
+</para>
+
+@parent: 
+@priv: 
+
+<!-- ##### FUNCTION clutter_clone_texture_new ##### -->
+<para>
+
+</para>
+
+@texture: 
+@Returns: 
+
+
diff --git a/doc/reference/tmpl/clutter-color.sgml b/doc/reference/tmpl/clutter-color.sgml
new file mode 100644 (file)
index 0000000..84abd7d
--- /dev/null
@@ -0,0 +1,129 @@
+<!-- ##### SECTION Title ##### -->
+clutter-color
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### MACRO clutter_color_r ##### -->
+<para>
+
+</para>
+
+@col: 
+
+
+<!-- ##### MACRO clutter_color_g ##### -->
+<para>
+
+</para>
+
+@col: 
+
+
+<!-- ##### MACRO clutter_color_b ##### -->
+<para>
+
+</para>
+
+@col: 
+
+
+<!-- ##### MACRO clutter_color_a ##### -->
+<para>
+
+</para>
+
+@col: 
+
+
+<!-- ##### MACRO clutter_color_set_r ##### -->
+<para>
+
+</para>
+
+@col: 
+@r: 
+
+
+<!-- ##### MACRO clutter_color_set_g ##### -->
+<para>
+
+</para>
+
+@col: 
+@g: 
+
+
+<!-- ##### MACRO clutter_color_set_b ##### -->
+<para>
+
+</para>
+
+@col: 
+@b: 
+
+
+<!-- ##### MACRO clutter_color_set_a ##### -->
+<para>
+
+</para>
+
+@col: 
+@a: 
+
+
+<!-- ##### TYPEDEF ClutterColor ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION clutter_color_new ##### -->
+<para>
+
+</para>
+
+@r: 
+@g: 
+@b: 
+@a: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_color_set ##### -->
+<para>
+
+</para>
+
+@color: 
+@r: 
+@g: 
+@b: 
+@a: 
+
+
+<!-- ##### FUNCTION clutter_color_get ##### -->
+<para>
+
+</para>
+
+@color: 
+@r: 
+@g: 
+@b: 
+@a: 
+
+
diff --git a/doc/reference/tmpl/clutter-element.sgml b/doc/reference/tmpl/clutter-element.sgml
new file mode 100644 (file)
index 0000000..779d565
--- /dev/null
@@ -0,0 +1,466 @@
+<!-- ##### SECTION Title ##### -->
+ClutterElement
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### MACRO CLUTTER_TYPE_GEOMETRY ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_TYPE_ELEMENT_BOX ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ELEMENT_SET_FLAGS ##### -->
+<para>
+
+</para>
+
+@e: 
+@f: 
+
+
+<!-- ##### MACRO CLUTTER_ELEMENT_UNSET_FLAGS ##### -->
+<para>
+
+</para>
+
+@e: 
+@f: 
+
+
+<!-- ##### MACRO CLUTTER_ELEMENT_IS_MAPPED ##### -->
+<para>
+
+</para>
+
+@e: 
+
+
+<!-- ##### MACRO CLUTTER_ELEMENT_IS_REALIZED ##### -->
+<para>
+
+</para>
+
+@e: 
+
+
+<!-- ##### MACRO CLUTTER_ELEMENT_IS_VISIBLE ##### -->
+<para>
+
+</para>
+
+@e: 
+
+
+<!-- ##### STRUCT ClutterElementBox ##### -->
+<para>
+
+</para>
+
+@x1: 
+@y1: 
+@x2: 
+@y2: 
+
+<!-- ##### STRUCT ClutterGeometry ##### -->
+<para>
+
+</para>
+
+@x: 
+@y: 
+@width: 
+@height: 
+
+<!-- ##### ENUM ClutterElementTransform ##### -->
+<para>
+
+</para>
+
+@CLUTTER_ELEMENT_MIRROR_X: 
+@CLUTTER_ELEMENT_MIRROR_Y: 
+
+<!-- ##### ENUM ClutterElementFlags ##### -->
+<para>
+
+</para>
+
+@CLUTTER_ELEMENT_MAPPED: 
+@CLUTTER_ELEMENT_REALIZED: 
+
+<!-- ##### FUNCTION clutter_element_box_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### STRUCT ClutterElement ##### -->
+<para>
+
+</para>
+
+@parent: 
+@flags: 
+
+<!-- ##### STRUCT ClutterElementClass ##### -->
+<para>
+
+</para>
+
+@parent_class: 
+@show: 
+@hide: 
+@realize: 
+@unrealize: 
+@paint: 
+@request_coords: 
+@allocate_coords: 
+@set_depth: 
+@get_depth: 
+@show_all: 
+@hide_all: 
+@queue_redraw: 
+
+<!-- ##### FUNCTION clutter_element_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_element_show ##### -->
+<para>
+
+</para>
+
+@self: 
+
+
+<!-- ##### FUNCTION clutter_element_hide ##### -->
+<para>
+
+</para>
+
+@self: 
+
+
+<!-- ##### FUNCTION clutter_element_realize ##### -->
+<para>
+
+</para>
+
+@self: 
+
+
+<!-- ##### FUNCTION clutter_element_unrealize ##### -->
+<para>
+
+</para>
+
+@self: 
+
+
+<!-- ##### FUNCTION clutter_element_paint ##### -->
+<para>
+
+</para>
+
+@self: 
+
+
+<!-- ##### FUNCTION clutter_element_queue_redraw ##### -->
+<para>
+
+</para>
+
+@self: 
+
+
+<!-- ##### FUNCTION clutter_element_request_coords ##### -->
+<para>
+
+</para>
+
+@self: 
+@box: 
+
+
+<!-- ##### FUNCTION clutter_element_allocate_coords ##### -->
+<para>
+
+</para>
+
+@self: 
+@box: 
+
+
+<!-- ##### FUNCTION clutter_element_set_geometry ##### -->
+<para>
+
+</para>
+
+@self: 
+@geom: 
+
+
+<!-- ##### FUNCTION clutter_element_get_geometry ##### -->
+<para>
+
+</para>
+
+@self: 
+@geom: 
+
+
+<!-- ##### FUNCTION clutter_element_get_coords ##### -->
+<para>
+
+</para>
+
+@self: 
+@x1: 
+@y1: 
+@x2: 
+@y2: 
+
+
+<!-- ##### FUNCTION clutter_element_set_position ##### -->
+<para>
+
+</para>
+
+@self: 
+@x: 
+@y: 
+
+
+<!-- ##### FUNCTION clutter_element_set_size ##### -->
+<para>
+
+</para>
+
+@self: 
+@width: 
+@height: 
+
+
+<!-- ##### FUNCTION clutter_element_get_abs_position ##### -->
+<para>
+
+</para>
+
+@self: 
+@x: 
+@y: 
+
+
+<!-- ##### FUNCTION clutter_element_get_width ##### -->
+<para>
+
+</para>
+
+@self: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_element_get_height ##### -->
+<para>
+
+</para>
+
+@self: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_element_get_x ##### -->
+<para>
+
+</para>
+
+@self: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_element_get_y ##### -->
+<para>
+
+</para>
+
+@self: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_element_rotate_z ##### -->
+<para>
+
+</para>
+
+@self: 
+@angle: 
+@x: 
+@y: 
+
+
+<!-- ##### FUNCTION clutter_element_rotate_x ##### -->
+<para>
+
+</para>
+
+@self: 
+@angle: 
+@y: 
+@z: 
+
+
+<!-- ##### FUNCTION clutter_element_rotate_y ##### -->
+<para>
+
+</para>
+
+@self: 
+@angle: 
+@x: 
+@z: 
+
+
+<!-- ##### FUNCTION clutter_element_set_opacity ##### -->
+<para>
+
+</para>
+
+@self: 
+@opacity: 
+
+
+<!-- ##### FUNCTION clutter_element_get_opacity ##### -->
+<para>
+
+</para>
+
+@self: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_element_set_name ##### -->
+<para>
+
+</para>
+
+@self: 
+@id: 
+
+
+<!-- ##### FUNCTION clutter_element_get_name ##### -->
+<para>
+
+</para>
+
+@self: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_element_get_id ##### -->
+<para>
+
+</para>
+
+@self: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_element_set_clip ##### -->
+<para>
+
+</para>
+
+@self: 
+@xoff: 
+@yoff: 
+@width: 
+@height: 
+
+
+<!-- ##### FUNCTION clutter_element_remove_clip ##### -->
+<para>
+
+</para>
+
+@self: 
+
+
+<!-- ##### FUNCTION clutter_element_set_parent ##### -->
+<para>
+
+</para>
+
+@self: 
+@parent: 
+
+
+<!-- ##### FUNCTION clutter_element_get_parent ##### -->
+<para>
+
+</para>
+
+@self: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_element_raise ##### -->
+<para>
+
+</para>
+
+@self: 
+@below: 
+
+
+<!-- ##### FUNCTION clutter_element_lower ##### -->
+<para>
+
+</para>
+
+@self: 
+@above: 
+
+
+<!-- ##### FUNCTION clutter_element_raise_top ##### -->
+<para>
+
+</para>
+
+@self: 
+
+
+<!-- ##### FUNCTION clutter_element_lower_bottom ##### -->
+<para>
+
+</para>
+
+@self: 
+
+
diff --git a/doc/reference/tmpl/clutter-enum-types.sgml b/doc/reference/tmpl/clutter-enum-types.sgml
new file mode 100644 (file)
index 0000000..649e106
--- /dev/null
@@ -0,0 +1,109 @@
+<!-- ##### SECTION Title ##### -->
+clutter-enum-types
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### MACRO CLUTTER_TYPE_EVENT_TYPE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### FUNCTION clutter_event_type_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### MACRO CLUTTER_TYPE_ELEMENT_TRANSFORM ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### FUNCTION clutter_element_transform_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### MACRO CLUTTER_TYPE_ELEMENT_FLAGS ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### FUNCTION clutter_element_flags_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### MACRO CLUTTER_TYPE_VIDEO_TEXTURE_ERROR ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### FUNCTION clutter_video_texture_error_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### MACRO CLUTTER_TYPE_VIDEO_TEXTURE_ASPECT_RATIO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### FUNCTION clutter_video_texture_aspect_ratio_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### MACRO CLUTTER_TYPE_VIDEO_TEXTURE_METADATA_TYPE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### FUNCTION clutter_video_texture_metadata_type_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
diff --git a/doc/reference/tmpl/clutter-event.sgml b/doc/reference/tmpl/clutter-event.sgml
new file mode 100644 (file)
index 0000000..debc0a6
--- /dev/null
@@ -0,0 +1,144 @@
+<!-- ##### SECTION Title ##### -->
+clutter-event
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### ENUM ClutterEventType ##### -->
+<para>
+
+</para>
+
+@CLUTTER_KEY_PRESS: 
+@CLUTTER_KEY_RELEASE: 
+@CLUTTER_MOTION: 
+@CLUTTER_BUTTON_PRESS: 
+@CLUTTER_2BUTTON_PRESS: 
+@CLUTTER_BUTTON_RELEASE: 
+
+<!-- ##### STRUCT ClutterKeyEvent ##### -->
+<para>
+
+</para>
+
+@type: 
+@time: 
+@modifier_state: 
+@keyval: 
+@hardware_keycode: 
+
+<!-- ##### STRUCT ClutterButtonEvent ##### -->
+<para>
+
+</para>
+
+@type: 
+@time: 
+@x: 
+@y: 
+@modifier_state: 
+@button: 
+@axes: 
+@device: 
+
+<!-- ##### STRUCT ClutterMotionEvent ##### -->
+<para>
+
+</para>
+
+@type: 
+@time: 
+@x: 
+@y: 
+@modifier_state: 
+@axes: 
+@device: 
+
+<!-- ##### STRUCT ClutterInputDevice ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### UNION ClutterEvent ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION clutter_key_event_type ##### -->
+<para>
+
+</para>
+
+@keyev: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_key_event_time ##### -->
+<para>
+
+</para>
+
+@keyev: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_key_event_state ##### -->
+<para>
+
+</para>
+
+@keyev: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_key_event_symbol ##### -->
+<para>
+
+</para>
+
+@keyev: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_key_event_code ##### -->
+<para>
+
+</para>
+
+@keyev: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_key_event_unicode ##### -->
+<para>
+
+</para>
+
+@keyev: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_keysym_to_unicode ##### -->
+<para>
+
+</para>
+
+@keyval: 
+@Returns: 
+
+
diff --git a/doc/reference/tmpl/clutter-group.sgml b/doc/reference/tmpl/clutter-group.sgml
new file mode 100644 (file)
index 0000000..71b1d49
--- /dev/null
@@ -0,0 +1,124 @@
+<!-- ##### SECTION Title ##### -->
+ClutterGroup
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT ClutterGroupPrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT ClutterGroup ##### -->
+<para>
+
+</para>
+
+@parent: 
+
+<!-- ##### FUNCTION clutter_group_new ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_group_add ##### -->
+<para>
+
+</para>
+
+@group: 
+@element: 
+
+
+<!-- ##### FUNCTION clutter_group_add_many_valist ##### -->
+<para>
+
+</para>
+
+@group: 
+@first_element: 
+@args: 
+
+
+<!-- ##### FUNCTION clutter_group_add_many ##### -->
+<para>
+
+</para>
+
+@group: 
+@first_element: 
+@Varargs: 
+
+
+<!-- ##### FUNCTION clutter_group_remove ##### -->
+<para>
+
+</para>
+
+@group: 
+@element: 
+
+
+<!-- ##### FUNCTION clutter_group_show_all ##### -->
+<para>
+
+</para>
+
+@self: 
+
+
+<!-- ##### FUNCTION clutter_group_hide_all ##### -->
+<para>
+
+</para>
+
+@self: 
+
+
+<!-- ##### FUNCTION clutter_group_find_child_by_id ##### -->
+<para>
+
+</para>
+
+@self: 
+@id: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_group_raise ##### -->
+<para>
+
+</para>
+
+@self: 
+@element: 
+@sibling: 
+
+
+<!-- ##### FUNCTION clutter_group_lower ##### -->
+<para>
+
+</para>
+
+@self: 
+@element: 
+@sibling: 
+
+
diff --git a/doc/reference/tmpl/clutter-keysyms.sgml b/doc/reference/tmpl/clutter-keysyms.sgml
new file mode 100644 (file)
index 0000000..454fab6
--- /dev/null
@@ -0,0 +1,9399 @@
+<!-- ##### SECTION Title ##### -->
+clutter-keysyms
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### MACRO CLUTTER_VoidSymbol ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_BackSpace ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Tab ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Linefeed ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Clear ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Return ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pause ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Scroll_Lock ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Sys_Req ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Escape ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Delete ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Multi_key ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Codeinput ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_SingleCandidate ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_MultipleCandidate ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_PreviousCandidate ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Kanji ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Muhenkan ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Henkan_Mode ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Henkan ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Romaji ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hiragana ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Katakana ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hiragana_Katakana ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Zenkaku ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hankaku ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Zenkaku_Hankaku ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Touroku ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Massyo ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Kana_Lock ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Kana_Shift ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Eisu_Shift ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Eisu_toggle ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Kanji_Bangou ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Zen_Koho ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Mae_Koho ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Home ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Left ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Up ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Right ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Down ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Prior ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Page_Up ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Next ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Page_Down ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_End ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Begin ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Select ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Print ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Execute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Insert ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Undo ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Redo ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Menu ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Find ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cancel ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Help ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Break ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Mode_switch ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_script_switch ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Num_Lock ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Space ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Tab ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Enter ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_F1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_F2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_F3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_F4 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Home ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Left ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Up ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Right ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Down ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Prior ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Page_Up ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Next ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Page_Down ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_End ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Begin ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Insert ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Delete ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Equal ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Multiply ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Add ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Separator ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Subtract ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Decimal ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_Divide ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_0 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_4 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_5 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_6 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_7 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_8 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_KP_9 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F4 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F5 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F6 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F7 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F8 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F9 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F10 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F11 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_L1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F12 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_L2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F13 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_L3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F14 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_L4 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F15 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_L5 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F16 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_L6 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F17 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_L7 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F18 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_L8 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F19 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_L9 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F20 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_L10 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F21 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_R1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F22 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_R2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F23 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_R3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F24 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_R4 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F25 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_R5 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F26 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_R6 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F27 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_R7 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F28 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_R8 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F29 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_R9 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F30 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_R10 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F31 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_R11 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F32 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_R12 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F33 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_R13 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F34 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_R14 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F35 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_R15 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Shift_L ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Shift_R ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Control_L ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Control_R ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Caps_Lock ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Shift_Lock ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Meta_L ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Meta_R ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Alt_L ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Alt_R ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Super_L ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Super_R ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hyper_L ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hyper_R ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Lock ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Level2_Latch ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Level3_Shift ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Level3_Latch ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Level3_Lock ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Group_Shift ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Group_Latch ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Group_Lock ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Next_Group ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Next_Group_Lock ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Prev_Group ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Prev_Group_Lock ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_First_Group ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_First_Group_Lock ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Last_Group ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Last_Group_Lock ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Left_Tab ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Move_Line_Up ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Move_Line_Down ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Partial_Line_Up ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Partial_Line_Down ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Partial_Space_Left ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Partial_Space_Right ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Set_Margin_Left ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Set_Margin_Right ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Release_Margin_Left ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Release_Margin_Right ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Release_Both_Margins ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Fast_Cursor_Left ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Fast_Cursor_Right ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Fast_Cursor_Up ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Fast_Cursor_Down ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Continuous_Underline ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Discontinuous_Underline ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Emphasize ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Center_Object ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ISO_Enter ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_grave ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_acute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_circumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_tilde ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_macron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_breve ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_abovedot ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_diaeresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_abovering ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_doubleacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_caron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_cedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_ogonek ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_iota ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_voiced_sound ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_semivoiced_sound ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_belowdot ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_hook ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dead_horn ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_First_Virtual_Screen ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Prev_Virtual_Screen ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Next_Virtual_Screen ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Last_Virtual_Screen ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Terminate_Server ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_AccessX_Enable ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_AccessX_Feedback_Enable ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_RepeatKeys_Enable ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_SlowKeys_Enable ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_BounceKeys_Enable ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_StickyKeys_Enable ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_MouseKeys_Enable ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_MouseKeys_Accel_Enable ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Overlay1_Enable ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Overlay2_Enable ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_AudibleBell_Enable ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Left ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Right ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Up ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Down ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_UpLeft ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_UpRight ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_DownLeft ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_DownRight ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Button_Dflt ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Button1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Button2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Button3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Button4 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Button5 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_DblClick_Dflt ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_DblClick1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_DblClick2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_DblClick3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_DblClick4 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_DblClick5 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Drag_Dflt ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Drag1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Drag2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Drag3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Drag4 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Drag5 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_EnableKeys ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_Accelerate ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_DfltBtnNext ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Pointer_DfltBtnPrev ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_Duplicate ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_FieldMark ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_Right2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_Left2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_BackTab ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_EraseEOF ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_EraseInput ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_Reset ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_Quit ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_PA1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_PA2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_PA3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_Test ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_Attn ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_CursorBlink ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_AltCursor ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_KeyClick ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_Jump ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_Ident ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_Rule ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_Copy ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_Play ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_Setup ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_Record ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_ChangeScreen ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_DeleteWord ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_ExSelect ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_CursorSelect ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_PrintScreen ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3270_Enter ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_space ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_exclam ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_quotedbl ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_numbersign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dollar ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_percent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ampersand ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_apostrophe ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_quoteright ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_parenleft ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_parenright ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_asterisk ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_plus ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_comma ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_minus ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_period ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_slash ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_0 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_4 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_5 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_6 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_7 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_8 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_9 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_colon ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_semicolon ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_less ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_equal ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_greater ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_question ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_at ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_A ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_B ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_C ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_D ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_E ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_F ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_G ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_H ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_I ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_J ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_K ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_L ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_M ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_N ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_O ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_P ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Q ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_R ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_S ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_T ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_U ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_V ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_W ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_X ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Y ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Z ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_bracketleft ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_backslash ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_bracketright ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_asciicircum ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_underscore ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_grave ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_quoteleft ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_a ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_b ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_c ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_d ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_e ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_f ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_g ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_h ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_i ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_j ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_k ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_l ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_m ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_n ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_o ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_p ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_q ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_r ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_s ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_t ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_u ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_v ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_w ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_x ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_y ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_z ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_braceleft ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_bar ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_braceright ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_asciitilde ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_nobreakspace ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_exclamdown ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_cent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_sterling ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_currency ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_yen ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_brokenbar ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_section ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_diaeresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_copyright ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ordfeminine ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_guillemotleft ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_notsign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hyphen ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_registered ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_macron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_degree ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_plusminus ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_twosuperior ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_threesuperior ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_acute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_mu ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_paragraph ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_periodcentered ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_cedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_onesuperior ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_masculine ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_guillemotright ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_onequarter ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_onehalf ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_threequarters ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_questiondown ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Agrave ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Aacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Acircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Atilde ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Adiaeresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Aring ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_AE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ccedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Egrave ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Eacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ecircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ediaeresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Igrave ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Iacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Icircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Idiaeresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ETH ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Eth ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ntilde ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ograve ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Oacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ocircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Otilde ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Odiaeresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_multiply ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ooblique ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ugrave ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Uacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ucircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Udiaeresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Yacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_THORN ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thorn ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ssharp ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_agrave ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_aacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_acircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_atilde ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_adiaeresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_aring ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ae ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ccedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_egrave ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_eacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ecircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ediaeresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_igrave ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_iacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_icircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_idiaeresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_eth ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ntilde ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ograve ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_oacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ocircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_otilde ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_odiaeresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_division ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_oslash ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ugrave ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_uacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ucircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_udiaeresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_yacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_thorn ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ydiaeresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Aogonek ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_breve ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Lstroke ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Lcaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Sacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Scaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Scedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Tcaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Zacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Zcaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Zabovedot ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_aogonek ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ogonek ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_lstroke ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_lcaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_sacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_caron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_scaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_scedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_tcaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_zacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_doubleacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_zcaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_zabovedot ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Racute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Abreve ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Lacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ccaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Eogonek ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ecaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Dcaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Dstroke ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Nacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ncaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Odoubleacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Rcaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Uring ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Udoubleacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Tcedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_racute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_abreve ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_lacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_cacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ccaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_eogonek ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ecaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dcaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dstroke ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_nacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ncaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_odoubleacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_udoubleacute ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_rcaron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_uring ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_tcedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_abovedot ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hstroke ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hcircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Iabovedot ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Gbreve ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Jcircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hstroke ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hcircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_idotless ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_gbreve ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_jcircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cabovedot ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ccircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Gabovedot ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Gcircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ubreve ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Scircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_cabovedot ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ccircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_gabovedot ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_gcircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ubreve ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_scircumflex ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kra ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kappa ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Rcedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Itilde ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Lcedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Emacron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Gcedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Tslash ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_rcedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_itilde ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_lcedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_emacron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_gcedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_tslash ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ENG ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_eng ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Amacron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Iogonek ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Eabovedot ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Imacron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ncedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Omacron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Kcedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Uogonek ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Utilde ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Umacron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_amacron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_iogonek ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_eabovedot ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_imacron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ncedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_omacron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kcedilla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_uogonek ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_utilde ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_umacron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_OE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_oe ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ydiaeresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_overline ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_fullstop ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_openingbracket ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_closingbracket ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_comma ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_conjunctive ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_middledot ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_WO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_a ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_i ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_u ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_e ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_o ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_ya ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_yu ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_yo ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_tsu ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_tu ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_prolongedsound ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_A ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_I ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_U ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_E ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_O ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_KA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_KI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_KU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_KE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_KO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_SA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_SHI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_SU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_SE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_SO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_TA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_CHI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_TI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_TSU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_TU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_TE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_TO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_NA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_NI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_NU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_NE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_NO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_HA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_HI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_FU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_HU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_HE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_HO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_MA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_MI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_MU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_ME ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_MO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_YA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_YU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_YO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_RA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_RI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_RU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_RE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_RO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_WA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_N ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_voicedsound ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_semivoicedsound ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_kana_switch ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_comma ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_semicolon ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_question_mark ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_hamza ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_maddaonalef ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_hamzaonalef ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_hamzaonwaw ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_hamzaunderalef ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_hamzaonyeh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_alef ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_beh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_tehmarbuta ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_teh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_theh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_jeem ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_hah ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_khah ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_dal ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_thal ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_ra ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_zain ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_seen ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_sheen ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_sad ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_dad ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_tah ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_zah ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_ain ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_ghain ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_tatweel ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_feh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_qaf ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_kaf ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_lam ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_meem ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_noon ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_ha ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_heh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_waw ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_alefmaksura ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_yeh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_fathatan ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_dammatan ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_kasratan ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_fatha ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_damma ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_kasra ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_shadda ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_sukun ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Arabic_switch ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Serbian_dje ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Macedonia_gje ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_io ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ukrainian_ie ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ukranian_je ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Macedonia_dse ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ukrainian_i ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ukranian_i ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ukrainian_yi ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ukranian_yi ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_je ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Serbian_je ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_lje ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Serbian_lje ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_nje ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Serbian_nje ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Serbian_tshe ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Macedonia_kje ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ukrainian_ghe_with_upturn ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Byelorussian_shortu ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_dzhe ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Serbian_dze ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_numerosign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Serbian_DJE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Macedonia_GJE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_IO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ukrainian_IE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ukranian_JE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Macedonia_DSE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ukrainian_I ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ukranian_I ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ukrainian_YI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ukranian_YI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_JE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Serbian_JE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_LJE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Serbian_LJE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_NJE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Serbian_NJE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Serbian_TSHE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Macedonia_KJE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Ukrainian_GHE_WITH_UPTURN ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Byelorussian_SHORTU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_DZHE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Serbian_DZE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_yu ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_a ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_be ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_tse ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_de ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_ie ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_ef ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_ghe ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_ha ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_i ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_shorti ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_ka ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_el ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_em ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_en ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_o ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_pe ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_ya ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_er ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_es ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_te ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_u ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_zhe ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_ve ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_softsign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_yeru ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_ze ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_sha ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_e ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_shcha ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_che ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_hardsign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_YU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_A ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_BE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_TSE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_DE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_IE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_EF ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_GHE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_HA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_I ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_SHORTI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_KA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_EL ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_EM ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_EN ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_O ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_PE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_YA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_ER ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_ES ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_TE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_U ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_ZHE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_VE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_SOFTSIGN ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_YERU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_ZE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_SHA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_E ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_SHCHA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_CHE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Cyrillic_HARDSIGN ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_ALPHAaccent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_EPSILONaccent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_ETAaccent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_IOTAaccent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_IOTAdieresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_IOTAdiaeresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_OMICRONaccent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_UPSILONaccent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_UPSILONdieresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_OMEGAaccent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_accentdieresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_horizbar ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_alphaaccent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_epsilonaccent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_etaaccent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_iotaaccent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_iotadieresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_iotaaccentdieresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_omicronaccent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_upsilonaccent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_upsilondieresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_upsilonaccentdieresis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_omegaaccent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_ALPHA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_BETA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_GAMMA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_DELTA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_EPSILON ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_ZETA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_ETA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_THETA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_IOTA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_KAPPA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_LAMDA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_LAMBDA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_MU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_NU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_XI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_OMICRON ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_PI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_RHO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_SIGMA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_TAU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_UPSILON ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_PHI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_CHI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_PSI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_OMEGA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_alpha ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_beta ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_gamma ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_delta ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_epsilon ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_zeta ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_eta ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_theta ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_iota ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_kappa ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_lamda ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_lambda ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_mu ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_nu ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_xi ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_omicron ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_pi ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_rho ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_sigma ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_finalsmallsigma ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_tau ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_upsilon ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_phi ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_chi ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_psi ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_omega ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Greek_switch ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_leftradical ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_topleftradical ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_horizconnector ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_topintegral ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_botintegral ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_vertconnector ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_topleftsqbracket ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_botleftsqbracket ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_toprightsqbracket ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_botrightsqbracket ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_topleftparens ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_botleftparens ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_toprightparens ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_botrightparens ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_leftmiddlecurlybrace ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_rightmiddlecurlybrace ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_topleftsummation ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_botleftsummation ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_topvertsummationconnector ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_botvertsummationconnector ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_toprightsummation ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_botrightsummation ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_rightmiddlesummation ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_lessthanequal ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_notequal ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_greaterthanequal ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_integral ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_therefore ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_variation ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_infinity ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_nabla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_approximate ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_similarequal ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ifonlyif ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_implies ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_identical ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_radical ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_includedin ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_includes ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_intersection ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_union ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_logicaland ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_logicalor ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_partialderivative ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_function ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_leftarrow ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_uparrow ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_rightarrow ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_downarrow ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_blank ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_soliddiamond ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_checkerboard ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ht ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ff ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_cr ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_lf ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_nl ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_vt ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_lowrightcorner ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_uprightcorner ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_upleftcorner ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_lowleftcorner ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_crossinglines ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_horizlinescan1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_horizlinescan3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_horizlinescan5 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_horizlinescan7 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_horizlinescan9 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_leftt ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_rightt ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_bott ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_topt ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_vertbar ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_emspace ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_enspace ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_em3space ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_em4space ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_digitspace ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_punctspace ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_thinspace ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hairspace ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_emdash ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_endash ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_signifblank ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ellipsis ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_doubbaselinedot ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_onethird ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_twothirds ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_onefifth ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_twofifths ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_threefifths ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_fourfifths ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_onesixth ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_fivesixths ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_careof ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_figdash ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_leftanglebracket ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_decimalpoint ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_rightanglebracket ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_marker ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_oneeighth ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_threeeighths ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_fiveeighths ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_seveneighths ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_trademark ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_signaturemark ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_trademarkincircle ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_leftopentriangle ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_rightopentriangle ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_emopencircle ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_emopenrectangle ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_leftsinglequotemark ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_rightsinglequotemark ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_leftdoublequotemark ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_rightdoublequotemark ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_prescription ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_minutes ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_seconds ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_latincross ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hexagram ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_filledrectbullet ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_filledlefttribullet ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_filledrighttribullet ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_emfilledcircle ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_emfilledrect ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_enopencircbullet ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_enopensquarebullet ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_openrectbullet ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_opentribulletup ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_opentribulletdown ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_openstar ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_enfilledcircbullet ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_enfilledsqbullet ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_filledtribulletup ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_filledtribulletdown ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_leftpointer ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_rightpointer ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_club ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_diamond ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_heart ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_maltesecross ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_dagger ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_doubledagger ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_checkmark ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ballotcross ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_musicalsharp ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_musicalflat ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_malesymbol ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_femalesymbol ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_telephone ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_telephonerecorder ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_phonographcopyright ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_caret ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_singlelowquotemark ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_doublelowquotemark ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_cursor ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_leftcaret ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_rightcaret ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_downcaret ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_upcaret ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_overbar ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_downtack ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_upshoe ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_downstile ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_underbar ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_jot ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_quad ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_uptack ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_circle ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_upstile ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_downshoe ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_rightshoe ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_leftshoe ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_lefttack ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_righttack ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_doublelowline ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_aleph ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_bet ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_beth ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_gimel ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_gimmel ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_dalet ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_daleth ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_he ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_waw ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_zain ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_zayin ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_chet ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_het ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_tet ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_teth ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_yod ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_finalkaph ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_kaph ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_lamed ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_finalmem ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_mem ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_finalnun ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_nun ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_samech ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_samekh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_ayin ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_finalpe ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_pe ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_finalzade ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_finalzadi ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_zade ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_zadi ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_qoph ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_kuf ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_resh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_shin ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_taw ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_hebrew_taf ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hebrew_switch ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_kokai ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_khokhai ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_khokhuat ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_khokhwai ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_khokhon ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_khorakhang ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_ngongu ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_chochan ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_choching ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_chochang ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_soso ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_chochoe ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_yoying ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_dochada ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_topatak ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_thothan ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_thonangmontho ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_thophuthao ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_nonen ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_dodek ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_totao ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_thothung ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_thothahan ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_thothong ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_nonu ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_bobaimai ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_popla ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_phophung ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_fofa ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_phophan ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_fofan ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_phosamphao ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_moma ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_yoyak ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_rorua ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_ru ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_loling ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_lu ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_wowaen ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_sosala ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_sorusi ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_sosua ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_hohip ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_lochula ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_oang ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_honokhuk ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_paiyannoi ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_saraa ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_maihanakat ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_saraaa ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_saraam ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_sarai ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_saraii ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_saraue ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_sarauee ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_sarau ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_sarauu ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_phinthu ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_maihanakat_maitho ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_baht ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_sarae ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_saraae ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_sarao ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_saraaimaimuan ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_saraaimaimalai ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_lakkhangyao ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_maiyamok ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_maitaikhu ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_maiek ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_maitho ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_maitri ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_maichattawa ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_thanthakhat ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_nikhahit ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_leksun ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_leknung ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_leksong ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_leksam ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_leksi ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_lekha ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_lekhok ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_lekchet ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_lekpaet ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Thai_lekkao ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Start ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_End ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Hanja ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Jamo ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Romaja ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Codeinput ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Jeonja ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Banja ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_PreHanja ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_PostHanja ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_SingleCandidate ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_MultipleCandidate ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_PreviousCandidate ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Special ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_switch ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Kiyeog ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_SsangKiyeog ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_KiyeogSios ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Nieun ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_NieunJieuj ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_NieunHieuh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Dikeud ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_SsangDikeud ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Rieul ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_RieulKiyeog ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_RieulMieum ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_RieulPieub ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_RieulSios ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_RieulTieut ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_RieulPhieuf ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_RieulHieuh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Mieum ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Pieub ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_SsangPieub ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_PieubSios ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Sios ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_SsangSios ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Ieung ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Jieuj ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_SsangJieuj ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Cieuc ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Khieuq ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Tieut ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Phieuf ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_Hieuh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_A ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_AE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_YA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_YAE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_EO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_E ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_YEO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_YE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_O ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_WA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_WAE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_OE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_YO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_U ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_WEO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_WE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_WI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_YU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_EU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_YI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_I ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_Kiyeog ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_SsangKiyeog ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_KiyeogSios ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_Nieun ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_NieunJieuj ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_NieunHieuh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_Dikeud ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_Rieul ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_RieulKiyeog ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_RieulMieum ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_RieulPieub ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_RieulSios ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_RieulTieut ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_RieulPhieuf ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_RieulHieuh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_Mieum ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_Pieub ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_PieubSios ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_Sios ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_SsangSios ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_Ieung ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_Jieuj ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_Cieuc ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_Khieuq ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_Tieut ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_Phieuf ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_Hieuh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_RieulYeorinHieuh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_SunkyeongeumMieum ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_SunkyeongeumPieub ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_PanSios ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_KkogjiDalrinIeung ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_SunkyeongeumPhieuf ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_YeorinHieuh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_AraeA ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_AraeAE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_PanSios ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_KkogjiDalrinIeung ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Hangul_J_YeorinHieuh ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_Korean_Won ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_EcuSign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_ColonSign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_CruzeiroSign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_FFrancSign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_LiraSign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_MillSign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_NairaSign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_PesetaSign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_RupeeSign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_WonSign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_NewSheqelSign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_DongSign ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_EuroSign ##### -->
+<para>
+
+</para>
+
+
+
diff --git a/doc/reference/tmpl/clutter-label.sgml b/doc/reference/tmpl/clutter-label.sgml
new file mode 100644 (file)
index 0000000..453ffb4
--- /dev/null
@@ -0,0 +1,87 @@
+<!-- ##### SECTION Title ##### -->
+ClutterLabel
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT ClutterLabel ##### -->
+<para>
+
+</para>
+
+@parent: 
+
+<!-- ##### STRUCT ClutterLabelClass ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION clutter_label_new_with_text ##### -->
+<para>
+
+</para>
+
+@font_desc: 
+@text: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_label_new ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_label_set_text ##### -->
+<para>
+
+</para>
+
+@label: 
+@text: 
+
+
+<!-- ##### FUNCTION clutter_label_set_font ##### -->
+<para>
+
+</para>
+
+@label: 
+@desc: 
+
+
+<!-- ##### FUNCTION clutter_label_set_color ##### -->
+<para>
+
+</para>
+
+@label: 
+@pixel: 
+
+
+<!-- ##### FUNCTION clutter_label_set_text_extents ##### -->
+<para>
+
+</para>
+
+@label: 
+@width: 
+@height: 
+
+
diff --git a/doc/reference/tmpl/clutter-main.sgml b/doc/reference/tmpl/clutter-main.sgml
new file mode 100644 (file)
index 0000000..38ad5c6
--- /dev/null
@@ -0,0 +1,138 @@
+<!-- ##### SECTION Title ##### -->
+clutter-main
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### MACRO CLUTTER_HAS_DEBUG_MESSGES ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_DBG ##### -->
+<para>
+
+</para>
+
+@x: 
+@a...:
+@a...:
+@a...:
+@a...: 
+
+
+<!-- ##### MACRO CLUTTER_GLERR ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_MARK ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### FUNCTION clutter_init ##### -->
+<para>
+
+</para>
+
+@argc: 
+@argv: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_main ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### FUNCTION clutter_stage ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_redraw ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### FUNCTION clutter_xdisplay ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_xscreen ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_root_xwindow ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_gl_context ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_want_debug ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_threads_enter ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### FUNCTION clutter_threads_leave ##### -->
+<para>
+
+</para>
+
+
+
diff --git a/doc/reference/tmpl/clutter-marshal.sgml b/doc/reference/tmpl/clutter-marshal.sgml
new file mode 100644 (file)
index 0000000..f71bab8
--- /dev/null
@@ -0,0 +1,58 @@
+<!-- ##### SECTION Title ##### -->
+clutter-marshal
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### FUNCTION clutter_marshal_VOID__INT64_INT64_FLOAT_BOOLEAN ##### -->
+<para>
+
+</para>
+
+@closure: 
+@return_value: 
+@n_param_values: 
+@param_values: 
+@invocation_hint: 
+@marshal_data: 
+
+
+<!-- ##### FUNCTION clutter_marshal_VOID__STRING_BOOLEAN_BOOLEAN ##### -->
+<para>
+
+</para>
+
+@closure: 
+@return_value: 
+@n_param_values: 
+@param_values: 
+@invocation_hint: 
+@marshal_data: 
+
+
+<!-- ##### FUNCTION clutter_marshal_VOID__INT_INT ##### -->
+<para>
+
+</para>
+
+@closure: 
+@return_value: 
+@n_param_values: 
+@param_values: 
+@invocation_hint: 
+@marshal_data: 
+
+
diff --git a/doc/reference/tmpl/clutter-rectangle.sgml b/doc/reference/tmpl/clutter-rectangle.sgml
new file mode 100644 (file)
index 0000000..29e7205
--- /dev/null
@@ -0,0 +1,42 @@
+<!-- ##### SECTION Title ##### -->
+ClutterRectangle
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT ClutterRectanglePrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT ClutterRectangle ##### -->
+<para>
+
+</para>
+
+@parent: 
+@priv: 
+
+<!-- ##### FUNCTION clutter_rectangle_new ##### -->
+<para>
+
+</para>
+
+@col: 
+@Returns: 
+
+
diff --git a/doc/reference/tmpl/clutter-stage.sgml b/doc/reference/tmpl/clutter-stage.sgml
new file mode 100644 (file)
index 0000000..58ce359
--- /dev/null
@@ -0,0 +1,85 @@
+<!-- ##### SECTION Title ##### -->
+ClutterStage
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### MACRO CLUTTER_STAGE_WIDTH ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO CLUTTER_STAGE_HEIGHT ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### TYPEDEF ClutterStagePrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT ClutterStage ##### -->
+<para>
+
+</para>
+
+@parent: 
+@priv: 
+
+<!-- ##### FUNCTION clutter_stage_get_xwindow ##### -->
+<para>
+
+</para>
+
+@stage: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_stage_set_color ##### -->
+<para>
+
+</para>
+
+@stage: 
+@color: 
+
+
+<!-- ##### FUNCTION clutter_stage_get_color ##### -->
+<para>
+
+</para>
+
+@stage: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_stage_pick ##### -->
+<para>
+
+</para>
+
+@stage: 
+@x: 
+@y: 
+@Returns: 
+
+
diff --git a/doc/reference/tmpl/clutter-texture.sgml b/doc/reference/tmpl/clutter-texture.sgml
new file mode 100644 (file)
index 0000000..f3056b6
--- /dev/null
@@ -0,0 +1,139 @@
+<!-- ##### SECTION Title ##### -->
+ClutterTexture
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### TYPEDEF ClutterTexturePrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT ClutterTexture ##### -->
+<para>
+
+</para>
+
+@parent: 
+@priv: 
+
+<!-- ##### FUNCTION clutter_texture_new_from_pixbuf ##### -->
+<para>
+
+</para>
+
+@pixbuf: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_texture_new ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_texture_set_pixbuf ##### -->
+<para>
+
+</para>
+
+@texture: 
+@pixbuf: 
+
+
+<!-- ##### FUNCTION clutter_texture_get_pixbuf ##### -->
+<para>
+
+</para>
+
+@texture: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_texture_get_base_size ##### -->
+<para>
+
+</para>
+
+@texture: 
+@width: 
+@height: 
+
+
+<!-- ##### FUNCTION clutter_texture_bind_tile ##### -->
+<para>
+
+</para>
+
+@texture: 
+@index: 
+
+
+<!-- ##### FUNCTION clutter_texture_get_n_tiles ##### -->
+<para>
+
+</para>
+
+@texture: 
+@n_x_tiles: 
+@n_y_tiles: 
+
+
+<!-- ##### FUNCTION clutter_texture_get_x_tile_detail ##### -->
+<para>
+
+</para>
+
+@texture: 
+@x_index: 
+@pos: 
+@size: 
+@waste: 
+
+
+<!-- ##### FUNCTION clutter_texture_get_y_tile_detail ##### -->
+<para>
+
+</para>
+
+@texture: 
+@y_index: 
+@pos: 
+@size: 
+@waste: 
+
+
+<!-- ##### FUNCTION clutter_texture_has_generated_tiles ##### -->
+<para>
+
+</para>
+
+@texture: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_texture_is_tiled ##### -->
+<para>
+
+</para>
+
+@texture: 
+@Returns: 
+
+
diff --git a/doc/reference/tmpl/clutter-timeline.sgml b/doc/reference/tmpl/clutter-timeline.sgml
new file mode 100644 (file)
index 0000000..4cb93a1
--- /dev/null
@@ -0,0 +1,129 @@
+<!-- ##### SECTION Title ##### -->
+ClutterTimeline
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### TYPEDEF ClutterTimelinePrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT ClutterTimeline ##### -->
+<para>
+
+</para>
+
+@parent: 
+@priv: 
+
+<!-- ##### FUNCTION clutter_timeline_new ##### -->
+<para>
+
+</para>
+
+@nframes: 
+@fps: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_timeline_set_speed ##### -->
+<para>
+
+</para>
+
+@timeline: 
+@fps: 
+
+
+<!-- ##### FUNCTION clutter_timeline_start ##### -->
+<para>
+
+</para>
+
+@timeline: 
+
+
+<!-- ##### FUNCTION clutter_timeline_pause ##### -->
+<para>
+
+</para>
+
+@timeline: 
+
+
+<!-- ##### FUNCTION clutter_timeline_stop ##### -->
+<para>
+
+</para>
+
+@timeline: 
+
+
+<!-- ##### FUNCTION clutter_timeline_set_loop ##### -->
+<para>
+
+</para>
+
+@timeline: 
+@loop: 
+
+
+<!-- ##### FUNCTION clutter_timeline_rewind ##### -->
+<para>
+
+</para>
+
+@timeline: 
+
+
+<!-- ##### FUNCTION clutter_timeline_skip ##### -->
+<para>
+
+</para>
+
+@timeline: 
+@nframes: 
+
+
+<!-- ##### FUNCTION clutter_timeline_advance ##### -->
+<para>
+
+</para>
+
+@timeline: 
+@frame_num: 
+
+
+<!-- ##### FUNCTION clutter_timeline_get_current_frame ##### -->
+<para>
+
+</para>
+
+@timeline: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_timeline_get_n_frames ##### -->
+<para>
+
+</para>
+
+@timeline: 
+@Returns: 
+
+
diff --git a/doc/reference/tmpl/clutter-util.sgml b/doc/reference/tmpl/clutter-util.sgml
new file mode 100644 (file)
index 0000000..6ba39f0
--- /dev/null
@@ -0,0 +1,38 @@
+<!-- ##### SECTION Title ##### -->
+clutter-util
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### FUNCTION clutter_util_next_p2 ##### -->
+<para>
+
+</para>
+
+@a: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_util_can_create_texture ##### -->
+<para>
+
+</para>
+
+@width: 
+@height: 
+@Returns: 
+
+
diff --git a/doc/reference/tmpl/clutter-video-texture.sgml b/doc/reference/tmpl/clutter-video-texture.sgml
new file mode 100644 (file)
index 0000000..1053bee
--- /dev/null
@@ -0,0 +1,286 @@
+<!-- ##### SECTION Title ##### -->
+ClutterVideoTexture
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### TYPEDEF ClutterVideoTexturePrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO CLUTTER_VIDEO_TEXTURE_ERROR ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### ENUM ClutterVideoTextureError ##### -->
+<para>
+
+</para>
+
+@CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_PLUGIN: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_NO_PLUGIN_FOR_FILE: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_VIDEO_PLUGIN: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_BUSY: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_BROKEN_FILE: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_FILE_GENERIC: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_FILE_PERMISSION: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_FILE_ENCRYPTED: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_FILE_NOT_FOUND: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_DVD_ENCRYPTED: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_INVALID_DEVICE: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_UNKNOWN_HOST: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_NETWORK_UNREACHABLE: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_CONNECTION_REFUSED: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_UNVALID_LOCATION: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_GENERIC: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_CODEC_NOT_HANDLED: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_ONLY: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_CANNOT_CAPTURE: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_READ_ERROR: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_PLUGIN_LOAD: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_STILL_IMAGE: 
+@CLUTTER_VIDEO_TEXTURE_ERROR_EMPTY_FILE: 
+
+<!-- ##### FUNCTION clutter_video_texture_error_quark ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### ENUM ClutterVideoTextureAspectRatio ##### -->
+<para>
+
+</para>
+
+@CLUTTER_VIDEO_TEXTURE_AUTO: 
+@CLUTTER_VIDEO_TEXTURE_SQUARE: 
+@CLUTTER_VIDEO_TEXTURE_FOURBYTHREE: 
+@CLUTTER_VIDEO_TEXTURE_ANAMORPHIC: 
+@CLUTTER_VIDEO_TEXTURE_DVB: 
+
+<!-- ##### STRUCT ClutterVideoTexture ##### -->
+<para>
+
+</para>
+
+@parent: 
+@priv: 
+
+<!-- ##### FUNCTION clutter_video_texture_new ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_open ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+@mrl: 
+@subtitle_uri: 
+@error: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_play ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+@error: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_pause ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_can_direct_seek ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_seek_time ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+@time: 
+@gerror: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_seek ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+@position: 
+@error: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_stop ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_can_set_volume ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_set_volume ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+@volume: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_get_volume ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_get_current_time ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_get_stream_length ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_is_playing ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_is_seekable ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_get_position ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_set_aspect_ratio ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+@ratio: 
+
+
+<!-- ##### FUNCTION clutter_video_texture_get_aspect_ratio ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+@Returns: 
+
+
+<!-- ##### ENUM ClutterVideoTextureMetadataType ##### -->
+<para>
+
+</para>
+
+@CLUTTER_INFO_TITLE: 
+@CLUTTER_INFO_ARTIST: 
+@CLUTTER_INFO_YEAR: 
+@CLUTTER_INFO_ALBUM: 
+@CLUTTER_INFO_DURATION: 
+@CLUTTER_INFO_TRACK_NUMBER: 
+@CLUTTER_INFO_HAS_VIDEO: 
+@CLUTTER_INFO_DIMENSION_X: 
+@CLUTTER_INFO_DIMENSION_Y: 
+@CLUTTER_INFO_VIDEO_BITRATE: 
+@CLUTTER_INFO_VIDEO_CODEC: 
+@CLUTTER_INFO_FPS: 
+@CLUTTER_INFO_HAS_AUDIO: 
+@CLUTTER_INFO_AUDIO_BITRATE: 
+@CLUTTER_INFO_AUDIO_CODEC: 
+
+<!-- ##### FUNCTION clutter_video_texture_get_metadata ##### -->
+<para>
+
+</para>
+
+@video_texture: 
+@type: 
+@value: 
+
+
diff --git a/doc/reference/tmpl/clutter.sgml b/doc/reference/tmpl/clutter.sgml
new file mode 100644 (file)
index 0000000..b93d913
--- /dev/null
@@ -0,0 +1,19 @@
+<!-- ##### SECTION Title ##### -->
+clutter
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
index 5aa71c0..2d63565 100644 (file)
@@ -1,35 +1,45 @@
-noinst_PROGRAMS = scratch photos player select
+noinst_PROGRAMS = test test-video video-cube test-text super-oh
 
-scratch_SOURCES = scratch.c
-scratch_CFLAGS = $(CLTR_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
-scratch_LDFLAGS = \
-    $(CLTR_LIBS) \
+INCLUDES = -I$(top_srcdir)/clutter
+
+test_SOURCES = test.c
+test_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
+test_LDFLAGS = \
+    $(CLUTTER_LIBS) \
     $(GST_LIBS)   \
     $(GCONF_LIBS) \
-    $(top_builddir)/clutter/libclutter.la 
+    $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la 
 
-photos_SOURCES = photos.c
-photos_CFLAGS = $(CLTR_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
-photos_LDFLAGS = \
-    $(CLTR_LIBS) \
+test_video_SOURCES = test-video.c
+test_video_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
+test_video_LDFLAGS = \
+    $(CLUTTER_LIBS) \
     $(GST_LIBS)   \
     $(GCONF_LIBS) \
-    $(top_builddir)/clutter/libclutter.la 
+    $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la 
 
-player_SOURCES = player.c
-player_CFLAGS = $(CLTR_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
-player_LDFLAGS =    \
-    $(CLTR_LIBS)    \
+video_cube_SOURCES = video-cube.c
+video_cube_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
+video_cube_LDFLAGS = \
+    $(CLUTTER_LIBS) \
     $(GST_LIBS)   \
     $(GCONF_LIBS) \
-    $(top_builddir)/clutter/libclutter.la 
+    $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la 
 
-select_SOURCES = select.c
-select_CFLAGS = $(CLTR_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
-select_LDFLAGS =    \
-    $(CLTR_LIBS)    \
+test_text_SOURCES = test-text.c
+test_text_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
+test_text_LDFLAGS = \
+    $(CLUTTER_LIBS) \
     $(GST_LIBS)   \
     $(GCONF_LIBS) \
-    $(top_builddir)/clutter/libclutter.la 
+    $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la 
 
+super_oh_SOURCES = super-oh.c
+super_oh_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
+super_oh_LDFLAGS = \
+    $(CLUTTER_LIBS) \
+    $(GST_LIBS)   \
+    $(GCONF_LIBS) \
+    $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la 
 
+EXTRA_DIST = redhand.png clutter-logo-800x600.png
\ No newline at end of file
index 93bae5a..7a81de9 100644 (file)
Binary files a/examples/clutter-logo-800x600.png and b/examples/clutter-logo-800x600.png differ
diff --git a/examples/photos.c b/examples/photos.c
deleted file mode 100644 (file)
index 6553c3b..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-#include <clutter/cltr.h>
-
-gchar *ImgPath = NULL;
-
-int 
-usage(char *progname)
-{
-  fprintf(stderr, "Usage ... check source for now\n");
-  exit(-1);
-}
-
-gpointer
-photo_grid_populate(gpointer data) 
-{
-  CltrPhotoGrid    *grid = (CltrPhotoGrid *)data;
-  GDir             *dir;
-  GError           *error;
-  const gchar      *entry = NULL;
-  gchar            *fullpath = NULL;
-  int               n_pixb = 0, i =0;
-  ClutterFont      *font = NULL;
-  PixbufPixel       font_col = { 255, 0, 0, 255 };
-
-  font = font_new("Sans Bold 96");
-
-  if ((dir = g_dir_open (ImgPath, 0, &error)) == NULL)
-    {
-      /* handle this much better */
-      fprintf(stderr, "failed to open '%s'\n", ImgPath);
-      return NULL;
-    }
-
-  while ((entry = g_dir_read_name (dir)) != NULL)
-    {
-      if (!strcasecmp(&entry[strlen(entry)-4], ".png")
-         || !strcasecmp(&entry[strlen(entry)-4], ".jpg")
-         || !strcasecmp(&entry[strlen(entry)-5], ".jpeg"))
-       n_pixb++;
-    }
-
-  g_dir_rewind (dir);
-
-  while ((entry = g_dir_read_name (dir)) != NULL)
-    {
-      Pixbuf *pixb = NULL; 
-      fullpath = g_strconcat(ImgPath, "/", entry, NULL);
-      pixb = pixbuf_new_from_file(fullpath);
-
-      if (pixb)
-       {
-         CltrPhotoGridCell *cell;
-         gchar              buf[24];
-         Pixbuf            *tmp_pixb;
-
-         cell = cltr_photo_grid_cell_new(grid, pixb);
-
-         /*
-         g_snprintf(&buf[0], 24, "%i", i);
-         font_draw(font, cltr_photo_grid_cell_pixbuf(cell), 
-                   buf, 10, 10, &font_col);
-         */
-         g_mutex_lock(cltr_photo_grid_mutex(grid));
-
-         if (!cltr_photo_grid_get_active_cell(grid))
-           cltr_photo_grid_set_active_cell(grid,
-                                           cltr_photo_grid_get_first_cell(grid));
-
-         cltr_photo_grid_append_cell(grid, cell);
-
-         g_mutex_unlock(cltr_photo_grid_mutex(grid));
-
-         i++;
-       }
-
-      g_free(fullpath);
-    }
-
-  g_dir_close (dir);
-
-  g_mutex_lock(cltr_photo_grid_mutex(grid));
-
-  cltr_photo_grid_set_populated(grid, TRUE);
-
-  g_mutex_unlock(cltr_photo_grid_mutex(grid));
-
-  cltr_widget_queue_paint(CLTR_WIDGET(grid));
-
-  return NULL;
-}
-
-int
-main(int argc, char **argv)
-{
-  CltrWidget *win = NULL, *grid = NULL;
-  gchar      *img_path = NULL;
-  gboolean    want_fullscreen = FALSE;
-  gint        i, cols = 3;
-
-  GThread    *loader_thread; 
-
-  cltr_init(&argc, &argv);
-
-  if (argc < 2)
-    usage(argv[0]);
-
-  for (i = 1; i < argc; i++) 
-    {
-      if (!strcmp ("--image-path", argv[i]) || !strcmp ("-i", argv[i])) 
-       {
-         if (++i>=argc) usage (argv[0]);
-         ImgPath = argv[i];
-         continue;
-       }
-      if (!strcmp ("--cols", argv[i]) || !strcmp ("-c", argv[i])) 
-       {
-         if (++i>=argc) usage (argv[0]);
-         cols = atoi(argv[i]);
-         continue;
-       }
-      if (!strcmp ("-fs", argv[i]) || !strcmp ("--fullscreen", argv[i])) 
-       {
-         want_fullscreen = TRUE;
-         continue;
-       }
-      if (!strcmp("--help", argv[i]) || !strcmp("-h", argv[i])) 
-       {
-         usage(argv[0]);
-       }
-
-      usage(argv[0]);
-    }
-
-  win = cltr_window_new(800, 600);
-
-  if (want_fullscreen)
-    cltr_window_set_fullscreen(CLTR_WINDOW(win));
-
-  grid = cltr_photo_grid_new(800, 600, cols, cols, ImgPath);
-
-  cltr_window_focus_widget(CLTR_WINDOW(win), grid);
-
-  cltr_widget_add_child(win, grid, 0, 0);
-
-  cltr_widget_show_all(win);
-
-  /* grid->state = CLTR_PHOTO_GRID_STATE_BROWSE; */
-
-  loader_thread = g_thread_create (photo_grid_populate,
-                                  (gpointer)grid,
-                                  TRUE,
-                                  NULL);
-
-
-  cltr_main_loop();
-
-  return 0;
-}
diff --git a/examples/player.c b/examples/player.c
deleted file mode 100644 (file)
index c8c9f72..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-#include <clutter/cltr.h>
-
-int Paused = 0;
-
-void
-handle_xevent(CltrWidget *win, XEvent *xev, void *cookie)
-{
-  KeySym          kc;
-  CltrVideo      *video = CLTR_VIDEO(cookie);
-
-  if (xev->type == KeyPress)
-    {
-      XKeyEvent *xkeyev = &xev->xkey;
-
-      kc = XKeycodeToKeysym(xkeyev->display, xkeyev->keycode, 0);
-
-      switch (kc)
-       {
-       case XK_Return:
-         if (Paused)
-           cltr_video_play (video, NULL);
-         else
-           cltr_video_pause (video);
-         Paused ^= 1;
-
-         break;
-       }
-    }
-
-}
-
-int
-main (int argc, char *argv[])
-{
-  CltrWidget *win, *video, *label;
-  CltrFont   *font;
-  PixbufPixel col = { 0x66, 0x00, 0x00, 0x99 };
-
-  cltr_init (&argc, &argv);
-
-  if (argc != 2) {
-    g_print ("usage: %s <video filename>\n", argv[0]);
-    exit (-1);
-  }
-
-  font = font_new("Baubau 72");
-
-  win = cltr_window_new(800, 600);
-
-  video = cltr_video_new(800, 600);
-
-  cltr_video_set_source(CLTR_VIDEO(video), argv[1]);
-
-  cltr_widget_add_child(win, video, 0, 0);  
-
-  label = cltr_label_new("Clutter", font, &col);
-
-  cltr_widget_add_child(win, label, 10, 400);  
-
-  cltr_window_on_xevent(CLTR_WINDOW(win), handle_xevent, video);
-
-  cltr_widget_show_all(win);
-
-  cltr_video_play(CLTR_VIDEO(video), NULL);
-
-  cltr_main_loop();
-
-  exit (0);
-}
diff --git a/examples/rects.py b/examples/rects.py
new file mode 100755 (executable)
index 0000000..4663e40
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+import clutter
+
+stage = clutter.stage()
+stage.set_size(800,600)
+
+for i in range(1, 10):
+    rect = clutter.Rectangle(0x0000ff33)
+    rect.set_position((800 - (80 * i)) / 2, (600 - (60 * i)) / 2)
+    rect.set_size(80 * i,60 * i)
+    stage.add(rect)
+    rect.show()
+
+stage.show()
+
+clutter.main()
diff --git a/examples/redhand.png b/examples/redhand.png
new file mode 100644 (file)
index 0000000..c07d8ac
Binary files /dev/null and b/examples/redhand.png differ
diff --git a/examples/scratch.c b/examples/scratch.c
deleted file mode 100644 (file)
index 6e564ef..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-#include <clutter/cltr.h>
-
-int 
-usage(char *progname)
-{
-  fprintf(stderr, "Usage ... check source for now\n");
-  exit(-1);
-}
-
-int
-main(int argc, char **argv)
-{
-  int         i;
-  CltrWidget *win = NULL, *grid = NULL, *test = NULL, *test2 = NULL, *list;
-  CltrFont   *font = NULL;
-  PixbufPixel col = { 0xff, 0, 0, 0xff };
-
-  gchar      *img_path = NULL;
-  gboolean    want_fullscreen = FALSE;
-  gint        cols = 3;
-
-  cltr_init(&argc, &argv);
-
-  for (i = 1; i < argc; i++) 
-    {
-      if (!strcmp ("--image-path", argv[i]) || !strcmp ("-i", argv[i])) 
-       {
-         if (++i>=argc) usage (argv[0]);
-         img_path = argv[i];
-         continue;
-       }
-      if (!strcmp ("--cols", argv[i]) || !strcmp ("-c", argv[i])) 
-       {
-         if (++i>=argc) usage (argv[0]);
-         cols = atoi(argv[i]);
-         continue;
-       }
-      if (!strcmp ("-fs", argv[i]) || !strcmp ("--fullscreen", argv[i])) 
-       {
-         want_fullscreen = TRUE;
-         continue;
-       }
-      if (!strcmp("--help", argv[i]) || !strcmp("-h", argv[i])) 
-       {
-         usage(argv[0]);
-       }
-
-      usage(argv[0]);
-    }
-
-  win = cltr_window_new(800, 600);
-
-  if (want_fullscreen)
-    cltr_window_set_fullscreen(CLTR_WINDOW(win));
-
-  font = font_new("Sans Bold 11");
-
-  test = cltr_button_new_with_label("ButtonBoooo\nd sfdsfdsfsss\nsjhsjhsjhs", font, &col);
-
-  test2 = cltr_button_new_with_label("One Two", font, &col);
-
-  cltr_widget_add_child(win, test, 300, 100);
-
-  cltr_widget_add_child(win, test2, 100, 100);
-
-  cltr_window_focus_widget(CLTR_WINDOW(win), test2);
-
-  cltr_widget_set_focus_next(test, test2, CLTR_EAST);
-  cltr_widget_set_focus_next(test, test2, CLTR_WEST);
-  cltr_widget_set_focus_next(test2, test, CLTR_EAST);
-  cltr_widget_set_focus_next(test2, test, CLTR_WEST);
-
-  /*
-  test = cltr_scratch_new(300, 100);
-  test2 = cltr_scratch_new(150, 150);
-
-  cltr_widget_add_child(win, test, 400, 240);
-  */
-
-
-
-  /*
-  cltr_widget_add_child(win, test, 320, 240);
-  cltr_widget_add_child(win, test2, 400, 300);
-  */
-
-
-  cltr_window_focus_widget(CLTR_WINDOW(win), test);
-
-
-  cltr_widget_show_all(win);
-
-  cltr_main_loop();
-
-  return 0;
-}
diff --git a/examples/select.c b/examples/select.c
deleted file mode 100644 (file)
index 1697bdc..0000000
+++ /dev/null
@@ -1,657 +0,0 @@
-#include <clutter/cltr.h>
-
-typedef struct ItemEntry ItemEntry;
-typedef struct VideoCtrls VideoCtrls;
-
-typedef struct DemoApp
-{
-  CltrAnimator *anim;
-  CltrWidget   *list;
-  CltrWidget   *video;
-  CltrWidget   *win;
-
-
-  GList        *items;
-
-  /* video stuff */
-  gboolean      paused;
-  VideoCtrls   *video_ctrls;
-
-  gboolean ignore_next_xevent_hack;
-
-} DemoApp;
-
-struct ItemEntry
-{
-  gchar        *nice_name;
-  gchar        *path;
-  gchar        *uri;
-  gint64        stoptime;
-  CltrListCell *cell;
-};
-
-enum {
-  VIDEO_PLAY_BTN = 0,
-  VIDEO_STOP_BTN,
-  VIDEO_REWND_BTN,
-  VIDEO_FFWD_BTN,
-  VIDEO_VOLUP_BTN,
-  VIDEO_VOLDOWN_BTN,
-  VIDEO_BEGIN_BTN,
-  N_VIDEO_BTNS
-};
-
-struct VideoCtrls
-{
-  ClutterFont *font;
-
-
-  CltrWidget *container;
-  CltrWidget *buttons[N_VIDEO_BTNS];
-};
-
-static void
-zoom_out_complete (CltrAnimator *anim, void *userdata);
-
-static void
-zoom_video_out(DemoApp *app);
-
-void
-handle_xevent(CltrWidget *win, XEvent *xev, void *cookie);
-
-int 
-usage(char *progname)
-{
-  fprintf(stderr, "Usage ... check source for now\n");
-  exit(-1);
-}
-
-/* video control buttons */
-
-void
-video_ctrl_hide(DemoApp *app)
-{
-  cltr_widget_hide(app->video_ctrls->container);
-
-  cltr_window_focus_widget(CLTR_WINDOW(app->win), app->video);
-
-  app->ignore_next_xevent_hack = TRUE; /* urg */
-  cltr_window_on_xevent(CLTR_WINDOW(app->win), handle_xevent, app);
-}
-
-void
-video_ctrl_stop_cb(CltrButton *button, void *cookie)
-{
-  DemoApp        *app = (DemoApp*)cookie;
-
-  cltr_widget_hide(app->video_ctrls->container);
-
-  cltr_window_focus_widget(CLTR_WINDOW(app->win), app->list);
-
-  zoom_video_out(app);
-}
-
-void
-video_ctrl_play_cb(CltrButton *button, void *cookie)
-{
-  DemoApp        *app = (DemoApp*)cookie;
-  VideoCtrls     *v   = app->video_ctrls;
-
-  PixbufPixel col = { 0xff, 0xff, 0xff, 0xff };
-
-  if (app->paused)
-    {
-      cltr_video_play (CLTR_VIDEO(app->video), NULL);
-
-      cltr_button_set_label(CLTR_BUTTON(v->buttons[VIDEO_PLAY_BTN]),
-                           "PAUSE", v->font, &col);
-
-      app->paused = FALSE;
-
-      video_ctrl_hide(app);
-    }
-  else
-    {
-      cltr_button_set_label(CLTR_BUTTON(v->buttons[VIDEO_PLAY_BTN]),
-                           "PLAY", v->font, &col);
-
-      cltr_video_pause (CLTR_VIDEO(app->video));
-
-      app->paused = TRUE;
-
-      cltr_widget_queue_paint(v->buttons[VIDEO_PLAY_BTN]);
-    }
-}
-
-void
-video_ctrl_seek_begin_cb(CltrButton *button, void *cookie)
-{
-  DemoApp        *app = (DemoApp*)cookie;
-
-  video_ctrl_hide(app);
-
-  cltr_video_seek (CLTR_VIDEO(app->video), 0.0, NULL);
-}
-
-void
-init_video_ctrl(DemoApp *app)
-{
-  VideoCtrls *v;
-  int         width, height, x =0, y = 0;
-  PixbufPixel col = { 0xff, 0xff, 0xff, 0xff };
-
-  v = app->video_ctrls = g_malloc0(sizeof(VideoCtrls));
-
-  v->font = font_new ("Sans Bold 20");
-
-  font_get_pixel_size (v->font, "1234567890", &width, &height); 
-
-  height += 6;
-
-  v->container = cltr_overlay_new(width, height * 3 /*N_VIDEO_BTNS*/);
-
-  v->buttons[VIDEO_PLAY_BTN] = cltr_button_new(width, height-1);
-
-  cltr_button_set_label(CLTR_BUTTON(v->buttons[VIDEO_PLAY_BTN]),
-                       "PAUSE", v->font, &col);
-
-  cltr_button_on_activate(CLTR_BUTTON(v->buttons[VIDEO_PLAY_BTN]),
-                         video_ctrl_play_cb, (void *)app);
-
-  cltr_widget_add_child(v->container, 
-                       v->buttons[VIDEO_PLAY_BTN],
-                       x, y);
-  y += height;
-
-  v->buttons[VIDEO_STOP_BTN] =  cltr_button_new(width, height-1); 
-
-  cltr_button_set_label(CLTR_BUTTON(v->buttons[VIDEO_STOP_BTN]),
-                       "STOP", 
-                       v->font, &col);
-
-  cltr_button_on_activate(CLTR_BUTTON(v->buttons[VIDEO_STOP_BTN]),
-                         video_ctrl_stop_cb, (void *)app);
-
-  cltr_widget_add_child(v->container, 
-                       v->buttons[VIDEO_STOP_BTN],
-                       x, y);
-  y += height;
-
-
-  v->buttons[VIDEO_REWND_BTN] =  cltr_button_new(width, height-1);
-
-  cltr_button_set_label(CLTR_BUTTON(v->buttons[VIDEO_REWND_BTN]),
-                       "BEGIN", 
-                       v->font, &col);
-
-  cltr_button_on_activate(CLTR_BUTTON(v->buttons[VIDEO_REWND_BTN]),
-                         video_ctrl_seek_begin_cb, (void *)app);
-
-  cltr_widget_add_child(v->container, 
-                       v->buttons[VIDEO_REWND_BTN],
-                       x, y);
-
-  y += height;
-
-  /*
-  v->buttons[VIDEO_FFWD_BTN] =  cltr_button_new(width, height-1);
-
-  cltr_button_set_label(CLTR_BUTTON(v->buttons[VIDEO_FFWD_BTN]),
-                       "FFWD", 
-                       v->font, &col);
-
-  cltr_widget_add_child(v->container, 
-                       v->buttons[VIDEO_FFWD_BTN],
-                       x, y);
-
-  y += height;
-
-  */
-  cltr_widget_add_child(app->video, v->container, 100, 100);
-
-  /* focus - URG !*/
-
-  cltr_widget_set_focus_next(v->buttons[VIDEO_PLAY_BTN], 
-                            v->buttons[VIDEO_STOP_BTN], 
-                            CLTR_SOUTH);
-
-  cltr_widget_set_focus_next(v->buttons[VIDEO_STOP_BTN], 
-                            v->buttons[VIDEO_PLAY_BTN], 
-                            CLTR_NORTH);
-
-  cltr_widget_set_focus_next(v->buttons[VIDEO_STOP_BTN], 
-                            v->buttons[VIDEO_REWND_BTN], 
-                            CLTR_SOUTH);
-
-  cltr_widget_set_focus_next(v->buttons[VIDEO_REWND_BTN], 
-                            v->buttons[VIDEO_STOP_BTN], 
-                            CLTR_NORTH);
-
-  cltr_widget_set_focus_next(v->buttons[VIDEO_REWND_BTN], 
-                            v->buttons[VIDEO_PLAY_BTN], 
-                            CLTR_SOUTH);
-
-}
-
-void
-show_video_ctrl(DemoApp *app)
-{
-  cltr_widget_show_all(app->video_ctrls->container);
-}
-
-
-
-/* ********************* */
-
-gboolean
-populate(DemoApp *app, char *path)
-{
-  GDir             *dir;
-  GError           *error;
-  const gchar      *entry = NULL;
-  int               n_pixb = 0, i =0;
-  CltrList         *list = CLTR_LIST(app->list);
-  Pixbuf           *default_thumb_pixb = NULL;
-
-  default_thumb_pixb = pixbuf_new_from_file("clutter-logo-800x600.png");
-
-  if (!default_thumb_pixb)
-    g_error( "failed to open clutter-logo-800x600.png\n");
-
-  if ((dir = g_dir_open (path, 0, &error)) == NULL)
-    {
-      /* handle this much better */
-      g_error( "failed to open '%s'\n", path);
-      return FALSE;
-    }
-
-  g_printf("One sec.");
-
-  while ((entry = g_dir_read_name (dir)) != NULL)
-    {
-      Pixbuf       *pixb = NULL;
-      gint          i = 0;
-      ItemEntry    *new_item;
-      char         *img_path;
-      char         *seek_path, *seek_data = NULL;
-      gint64        seek_time = 0;
-
-      /* Eeek! */
-      if (!(g_str_has_suffix (entry, ".mpg") ||
-           g_str_has_suffix (entry, ".MPG") ||
-           g_str_has_suffix (entry, ".mpg4") ||
-           g_str_has_suffix (entry, ".MPG4") ||
-           g_str_has_suffix (entry, ".avi") ||
-           g_str_has_suffix (entry, ".mov") ||
-           g_str_has_suffix (entry, ".MOV") ||
-           g_str_has_suffix (entry, ".ogg") ||
-           g_str_has_suffix (entry, ".OGG") ||
-           g_str_has_suffix (entry, ".AVI")))
-       {
-         continue;
-       }
-
-      new_item = g_malloc0(sizeof(ItemEntry));
-
-      new_item->nice_name = g_strdup(entry);
-
-      i = strlen(new_item->nice_name) - 1;
-      while (i-- && new_item->nice_name[i] != '.') ;
-      if (i > 0) 
-       new_item->nice_name[i] = '\0';
-
-      seek_path  = g_strconcat(path, "/", new_item->nice_name, ".seek", NULL);
-
-      if (g_file_get_contents (seek_path, &seek_data, NULL, NULL))
-       {
-         seek_time = atol(seek_data);
-       }
-
-      img_path = g_strconcat(path, "/", new_item->nice_name, ".png", NULL);
-
-      pixb = pixbuf_new_from_file(img_path);
-
-      if (!pixb) 
-       pixb = default_thumb_pixb;
-
-      new_item->cell = cltr_list_cell_new(list, pixb, new_item->nice_name);
-
-      cltr_list_append_cell(list, new_item->cell);
-
-      new_item->uri = g_strconcat("file://", path, "/", entry, NULL);
-      new_item->path = g_strdup(path);
-
-      new_item->stoptime = seek_time;
-
-      app->items = g_list_append(app->items, new_item);
-
-      g_free(img_path);
-
-      g_printf(".");
-    }
-
-  g_dir_close (dir);
-
-  g_printf("\n");
-
-  return TRUE;
-}
-
-ItemEntry*
-cell_to_item(DemoApp *app, CltrListCell *cell)
-{
-  GList *item = NULL;
-
-  item = g_list_first(app->items);
-
-  while (item)
-    {
-      ItemEntry *entry = item->data;
-
-      if (entry->cell == cell)
-       return entry;
-
-      item = g_list_next(item);
-    }
-
-  return NULL;
-}
-
-
-void
-zoom_video_out(DemoApp *app)
-{
-  ItemEntry    *item;
-  char          filename[1024];
-  Pixbuf       *spixb, *dpixb;
-  int           dstx, dsty, dstw, dsth;
-  PixbufPixel   col = { 0, 0, 0, 0xff };
-  int           x1, y1, x2, y2;
-  FILE         *fp;
-
-  cltr_video_pause (CLTR_VIDEO(app->video));
-  
-  item = cell_to_item(app, cltr_list_get_active_cell(CLTR_LIST(app->list)));
-  
-  item->stoptime = cltr_video_get_time (CLTR_VIDEO(app->video));
-  
-  snprintf(filename, 1024, "%s/%s.png", item->path, item->nice_name);
-  
-  spixb = cltr_video_get_pixbuf (CLTR_VIDEO(app->video));
-  
-  /* fixup pixbuf so scaled like video 
-   *
-   */
-  
-  /* XXX wrongly assume width > height */
-  
-  dstw = spixb->width;
-  
-  dsth = (spixb->width * cltr_widget_height(app->win)) 
-    / cltr_widget_width(app->win) ;
-  
-  printf("dsth %i, spixb h %i\n", dsth, spixb->height);
-  
-  dsty = (dsth - spixb->height)/2; dstx = 0;
-  
-  dpixb = pixbuf_new(dstw, dsth);
-  pixbuf_fill_rect(dpixb, 0, 0, -1, -1, &col);
-  pixbuf_copy(spixb, dpixb, 0, 0, 
-             spixb->width, spixb->height, dstx, dsty);
-  
-  cltr_list_cell_set_pixbuf(cltr_list_get_active_cell(app->list),
-                           dpixb);
-
-  pixbuf_write_png(dpixb, filename);
-  
-  /* reset the viewing pixbuf */
-  
-  pixbuf_unref(dpixb);
-
-  /* write out the seektime too  */
-
-  snprintf(filename, 1024, "%s/%s.seek", item->path, item->nice_name);
-  
-  fp = fopen(filename, "w");
-
-  if (fp)
-    {
-      fprintf(fp, "%li", item->stoptime);
-      fclose(fp);
-    }
-
-  cltr_list_get_active_cell_video_box_co_ords(CLTR_LIST(app->list), 
-                                             &x1, &y1, &x2, &y2);
-  
-  cltr_video_stop (CLTR_VIDEO(app->video));
-  
-  /* zoom out, XXX old anim needs freeing */
-  
-  app->anim = cltr_animator_zoom_new(app->list,
-                                    x1, y1, x2, y2,
-                                    0,0,800,600);
-  
-  printf("got return, seek time %li, %i, %i \n", 
-        cltr_video_get_time (CLTR_VIDEO(app->video)),
-        x1, y1);
-  
-  cltr_widget_show(app->list);
-  
-  cltr_animator_run(app->anim, zoom_out_complete, app);
-  
-  return;
-}
-
-void
-init_show_controls(DemoApp *app)
-{
-  /*
-  app->anim = cltr_animator_move_new(app->video_ctrls->container,
-                                    -100, 200, 
-                                    100, 200);
-
-  cltr_widget_show_all(app->video_ctrls->container);
-  
-  cltr_animator_run(app->anim, NULL, app);
-  */
-
-  cltr_widget_show_all(app->video_ctrls->container);
-  cltr_window_focus_widget(CLTR_WINDOW(app->win), 
-                          app->video_ctrls->buttons[VIDEO_PLAY_BTN]);
-  cltr_window_on_xevent(CLTR_WINDOW(app->win), NULL, NULL);
-}
-
-void
-handle_xevent(CltrWidget *win, XEvent *xev, void *cookie)
-{
-  KeySym          kc;
-  DemoApp        *app = (DemoApp*)cookie;
-
-  /* 
-   * XXX really need to think about not queuing xevents in
-   *     the current queue or something :/
-  */
-  if (app->ignore_next_xevent_hack)
-    {
-      app->ignore_next_xevent_hack = FALSE;
-      return;
-    }
-
-  if (xev->type == KeyPress)
-    {
-      XKeyEvent *xkeyev = &xev->xkey;
-
-      kc = XKeycodeToKeysym(xkeyev->display, xkeyev->keycode, 0);
-
-      switch (kc)
-       {
-       case XK_Return:
-         {
-           init_show_controls(app);
-           /* zoom_video_out(app); */
-         }
-         break;
-       }
-    }
-
-}
-
-static void
-zoom_out_complete (CltrAnimator *anim, void *userdata)
-{
-  DemoApp *app = (DemoApp*)userdata;
-
-  cltr_window_on_xevent(CLTR_WINDOW(app->win), NULL, NULL);
-
-
-
-  cltr_widget_hide(app->video);
-
-  cltr_widget_queue_paint(app->win);
-}
-
-void
-zoom_in_complete (CltrAnimator *anim, void *userdata)
-{
-  DemoApp      *app = (DemoApp*)userdata;
-  ItemEntry    *item;
-
-  /* cltr_animator_reset(anim); */
-
-  item = cell_to_item(app, cltr_list_get_active_cell(app->list));
-
-  app->paused = FALSE;
-
-  cltr_video_set_source(CLTR_VIDEO(app->video), item->uri);
-
-  if (item->stoptime)
-    {
-      printf("*** seeking to %li\n", item->stoptime);
-      cltr_video_seek_time (CLTR_VIDEO(app->video), item->stoptime, NULL);
-    }
-
-  cltr_video_play(CLTR_VIDEO(app->video), NULL);
-
-  if (item->stoptime)
-    {
-      printf("*** seeking to %li\n", item->stoptime);
-      cltr_video_seek_time (CLTR_VIDEO(app->video), item->stoptime, NULL);
-    }
-
-
-  cltr_widget_show(app->video);
-
-  cltr_widget_hide(CLTR_WIDGET(app->list));
-
-
-
-  cltr_window_on_xevent(CLTR_WINDOW(app->win), handle_xevent, app);
-}
-
-void
-cell_activated (CltrList     *list, 
-               CltrListCell *cell,
-               void         *userdata)
-{
-  DemoApp      *app = (DemoApp*)userdata;
-  int           x1, y1, x2, y2;
-  static        have_added_child = 0; /* HACK */
-
-  cltr_list_get_active_cell_video_box_co_ords(CLTR_LIST(list), 
-                                             &x1, &y1, &x2, &y2);
-
-  if (app->video == NULL) 
-    {
-      /*
-      app->video = cltr_video_new(x2-x1, y2-y1);
-      cltr_widget_add_child(app->win, app->video, x1, y1);
-      */
-      app->video = cltr_video_new(800, 600);
-      cltr_widget_add_child(app->win, app->video, 0, 0);
-
-      init_video_ctrl(app);
-    }
-
-  app->anim = cltr_animator_zoom_new(CLTR_WIDGET(list),
-                                    0,0,800,600,
-                                    x1, y1, x2, y2);
-  have_added_child = 1;
-
-  cltr_animator_run(app->anim, zoom_in_complete, app);
-}
-
-int
-main(int argc, char **argv)
-{
-  int         i;
-  CltrWidget *win = NULL, *list = NULL;
-  CltrFont   *font = NULL;
-  PixbufPixel col = { 0xff, 0, 0, 0xff };
-
-  gchar      *movie_path = NULL;
-  gboolean    want_fullscreen = FALSE;
-  gint        cols = 3;
-
-  DemoApp *app;
-
-  cltr_init(&argc, &argv);
-
-  for (i = 1; i < argc; i++) 
-    {
-      if (!strcmp ("--movie-path", argv[i]) || !strcmp ("-i", argv[i])) 
-       {
-         if (++i>=argc) usage (argv[0]);
-         movie_path = argv[i];
-         continue;
-       }
-      if (!strcmp ("--cols", argv[i]) || !strcmp ("-c", argv[i])) 
-       {
-         if (++i>=argc) usage (argv[0]);
-         cols = atoi(argv[i]);
-         continue;
-       }
-      if (!strcmp ("-fs", argv[i]) || !strcmp ("--fullscreen", argv[i])) 
-       {
-         want_fullscreen = TRUE;
-         continue;
-       }
-      if (!strcmp("--help", argv[i]) || !strcmp("-h", argv[i])) 
-       {
-         usage(argv[0]);
-       }
-
-      usage(argv[0]);
-    }
-
-  if (!movie_path)
-    {
-      g_error("usage: %s -i <movies path>", argv[0]);
-      exit(-1);
-    }
-
-  app = g_malloc0(sizeof(DemoApp));
-
-  app->win = cltr_window_new(800, 600);
-
-  if (want_fullscreen)
-    cltr_window_set_fullscreen(CLTR_WINDOW(app->win));
-
-
-
-  app->list = cltr_list_new(800, 600, 800, 600/5);
-  
-  if (!populate(app, movie_path))
-      exit(-1);
-
-  cltr_widget_add_child(app->win, app->list, 0, 0);
-
-  cltr_window_focus_widget(CLTR_WINDOW(app->win), app->list);
-
-  cltr_widget_show_all(app->win);
-
-
-  cltr_list_on_activate_cell(CLTR_LIST(app->list), 
-                            cell_activated, (gpointer)app);
-
-  cltr_main_loop();
-}
diff --git a/examples/super-oh.c b/examples/super-oh.c
new file mode 100644 (file)
index 0000000..4937e91
--- /dev/null
@@ -0,0 +1,158 @@
+#include <clutter/clutter.h>
+#include <math.h>
+
+#define TRAILS 0
+#define NHANDS  6
+#define WINWIDTH   800
+#define WINHEIGHT  800
+#define RADIUS     250
+
+typedef struct SuperOH
+{
+  ClutterElement *hand[NHANDS], *bgtex;
+  ClutterGroup   *group;
+  GdkPixbuf      *bgpixb;
+
+} SuperOH; 
+
+/* input handler */
+void 
+input_cb (ClutterStage *stage, 
+         ClutterEvent *event,
+         gpointer      data)
+{
+  SuperOH *oh = (SuperOH *)data;
+
+  if (event->type == CLUTTER_BUTTON_PRESS)
+    {
+      ClutterElement *e;
+
+      e = clutter_stage_pick (stage, 
+                             clutter_button_event_x(event),
+                             clutter_button_event_y(event));
+
+      if (e)
+       clutter_element_hide(e);
+    }
+}
+
+
+/* Timeline handler */
+void
+frame_cb (ClutterTimeline *timeline, 
+         gint             frame_num, 
+         gpointer         data)
+{
+  SuperOH *oh = (SuperOH *)data;
+  gint     i;
+
+#if TRAILS
+  oh->bgpixb = clutter_stage_snapshot (CLUTTER_STAGE(clutter_stage()),
+                                      0, 0, WINWIDTH, WINHEIGHT);
+  clutter_texture_set_pixbuf(CLUTTER_TEXTURE(oh->bgtex), oh->bgpixb);
+  g_object_unref(G_OBJECT(oh->bgpixb));
+#endif
+
+  /* Rotate everything clockwise about stage center*/
+  clutter_element_rotate_z (CLUTTER_ELEMENT(oh->group),
+                           frame_num,
+                           WINWIDTH/2,
+                           WINHEIGHT/2);
+  for (i = 0; i < NHANDS; i++)
+    {
+      /* rotate each hand around there centers */
+      clutter_element_rotate_z (oh->hand[i],
+                               - 6.0 * frame_num,
+                               clutter_element_get_width (oh->hand[i])/2,
+                               clutter_element_get_height (oh->hand[i])/2);
+    }
+
+  /*
+  clutter_element_rotate_x (CLUTTER_ELEMENT(oh->group),
+                           75.0,
+                           WINHEIGHT/2, 0);
+  */
+}
+
+int
+main (int argc, char *argv[])
+{
+  ClutterTimeline *timeline;
+  GdkPixbuf       *pixbuf;
+  SuperOH         *oh;
+  gint             i;
+
+  clutter_init (&argc, &argv);
+
+  pixbuf = gdk_pixbuf_new_from_file ("redhand.png", NULL);
+
+  if (!pixbuf)
+    g_error("pixbuf load failed");
+
+  /* Set our stage (window) size */
+  clutter_element_set_size (CLUTTER_ELEMENT(clutter_stage()),
+                           WINWIDTH, WINHEIGHT);
+
+  /* and its background color */
+  clutter_stage_set_color (CLUTTER_STAGE(clutter_stage()), 0x61648cff);
+
+  oh = g_new(SuperOH, 1);
+
+#if TRAILS
+  oh->bgtex = clutter_texture_new();
+  clutter_element_set_size (oh->bgtex, WINWIDTH, WINHEIGHT);
+  clutter_element_set_opacity (oh->bgtex, 0x99);
+  clutter_group_add (clutter_stage(), oh->bgtex);
+#endif
+
+  /* create a new group to hold multiple elements in a group */
+  oh->group = clutter_group_new();
+  
+  for (i = 0; i < NHANDS; i++)
+    {
+      gint x, y, w, h;
+
+      /* Create a texture from pixbuf, then clone in to same resources */
+      if (i == 0)
+       oh->hand[i] = clutter_texture_new_from_pixbuf (pixbuf);
+     else
+       oh->hand[i] = clutter_clone_texture_new (CLUTTER_TEXTURE(oh->hand[0]));
+
+      /* Place around a circle */
+      w = clutter_element_get_width (oh->hand[0]);
+      h = clutter_element_get_height (oh->hand[0]);
+
+      x = WINWIDTH/2  + RADIUS * cos (i * M_PI / (NHANDS/2)) - w/2;
+      y = WINHEIGHT/2 + RADIUS * sin (i * M_PI / (NHANDS/2)) - h/2;
+
+      clutter_element_set_position (oh->hand[i], x, y);
+
+      /* Add to our group group */
+      clutter_group_add (oh->group, oh->hand[i]);
+    }
+
+  /* Add the group to the stage */
+  clutter_group_add (clutter_stage(), CLUTTER_ELEMENT(oh->group));
+
+  /* Show everying ( and map window ) */
+  clutter_group_show_all (oh->group);
+  clutter_group_show_all (clutter_stage());
+
+  g_signal_connect (clutter_stage(), "input-event",
+                   G_CALLBACK (input_cb), 
+                   oh);
+
+  /* Create a timeline to manage animation */
+  timeline = clutter_timeline_new (360, 60); /* num frames, fps */
+  g_object_set(timeline, "loop", TRUE, 0);   /* have it loop */
+
+  /* fire a callback for frame change */
+  g_signal_connect(timeline, "new-frame",  G_CALLBACK (frame_cb), oh);
+
+  /* and start it */
+  clutter_timeline_start (timeline);
+
+  clutter_main();
+
+  return 0;
+}
diff --git a/examples/test-text.c b/examples/test-text.c
new file mode 100644 (file)
index 0000000..b97bae0
--- /dev/null
@@ -0,0 +1,31 @@
+#include <clutter/clutter.h>
+
+int
+main (int argc, char *argv[])
+{
+  ClutterElement *label;
+  gchar          *text;
+  gsize           size;
+
+  clutter_init (&argc, &argv);
+
+  if (!g_file_get_contents ("test-text.c", &text, &size, NULL)) 
+    g_error("g_file_get_contents() of test-text.c failed");
+
+  clutter_element_set_size (CLUTTER_ELEMENT(clutter_stage()), 800, 600);
+  clutter_stage_set_color (CLUTTER_STAGE(clutter_stage()), 0x00000000);
+
+  label = clutter_label_new_with_text("Mono 8", text);
+
+  /* clutter_label_set_text_extents (CLUTTER_LABEL(label), 200, 0); */
+
+  clutter_label_set_color (CLUTTER_LABEL(label), 0xffffffff);
+
+  clutter_group_add(clutter_stage(), label);
+
+  clutter_group_show_all(clutter_stage());
+
+  clutter_main();
+
+  return 0;
+}
diff --git a/examples/test-video.c b/examples/test-video.c
new file mode 100644 (file)
index 0000000..ac05295
--- /dev/null
@@ -0,0 +1,175 @@
+#include <clutter/clutter.h>
+
+ClutterElement *rect; /* um... */
+
+gboolean 
+foo (gpointer data)
+{
+  static int i = 0;
+
+  clutter_element_set_opacity (CLUTTER_ELEMENT(data), i);
+
+  i += 10;
+
+  if (i>255) i = 0;
+
+  return TRUE;
+}
+
+void input_cb (ClutterStage *stage, 
+              ClutterEvent *event,
+              gpointer      user_data)
+{
+  ClutterVideoTexture *vtex = CLUTTER_VIDEO_TEXTURE(user_data);
+  static gint paused = 0;
+
+  if (event->type == CLUTTER_KEY_RELEASE)
+    {
+      if (paused)
+       {
+         clutter_video_texture_play (vtex, NULL);
+         paused = 0;
+       }
+      else
+       {
+         clutter_video_texture_pause (vtex);
+         paused = 1;
+       }
+    }
+}
+
+void
+size_change (ClutterTexture *texture, 
+            gint            width,
+            gint            height,
+            gpointer        user_data)
+{
+  ClutterGeometry stage_geom;
+  gint            vid_width, vid_height, new_y, new_height;
+
+  clutter_element_get_geometry (CLUTTER_ELEMENT(clutter_stage()), 
+                               &stage_geom);
+
+  clutter_texture_get_base_size (texture, &vid_width, &vid_height);
+
+  printf("*** vid : %ix%i stage %ix%i ***\n", 
+        vid_width, vid_height, stage_geom.width, stage_geom.height);
+
+
+  new_height = ( vid_height * stage_geom.width ) / vid_width;
+  new_y      = (stage_geom.height - new_height) / 2;
+
+  clutter_element_set_position (CLUTTER_ELEMENT(texture), 0, new_y);
+
+  clutter_element_set_size (CLUTTER_ELEMENT(texture),
+                           stage_geom.width,
+                           new_height);
+
+  clutter_element_set_opacity (CLUTTER_ELEMENT(texture), 50);
+
+  printf("*** Pos set to +%i+%i , %ix%i ***\n", 
+        0, new_y, stage_geom.width, new_height);
+}
+
+void 
+tick (ClutterVideoTexture *cvt, 
+      gint64              current_time, 
+      gint64              stream_length,
+      float               current_position, 
+      gboolean            seekable,
+      gpointer            userdata)
+{
+  gint          w, h;
+  gchar         buf[256];
+  ClutterLabel *label = CLUTTER_LABEL(userdata);
+
+  g_snprintf(buf, 256, "%lli/%lli secs", 
+            current_time / 1000,
+            stream_length / 1000); 
+
+  clutter_label_set_text (label, buf);
+  clutter_texture_get_base_size (CLUTTER_TEXTURE(label), &w, &h);
+  clutter_element_set_size(rect, w+10, h+10);
+}
+
+int
+main (int argc, char *argv[])
+{
+  ClutterElement        *label, *vtexture, *ctexture; 
+  GError                *err = NULL;
+
+  if (argc < 2)
+    g_error("%s <video file>", argv[0]);
+
+  clutter_init (&argc, &argv);
+
+  vtexture = clutter_video_texture_new ();
+
+  /* Broken..
+  g_object_set(vtexture, "repeat-x", TRUE, NULL);
+  g_object_set(vtexture, "repeat-y", TRUE, NULL);
+  */
+
+  printf("tiled okey\n");
+
+  if (vtexture == NULL || err != NULL)
+    {
+      g_error("failed to create vtexture, err: %s", err->message);
+    }
+
+  label = clutter_label_new_with_text ("Sans Bold 24", "Loading...");
+
+  clutter_element_set_position(label, 10, 10);
+
+  rect = clutter_rectangle_new (0xdededfaa);
+  clutter_element_set_size(rect, 0, 0);
+  clutter_element_set_position(rect, 5, 5);
+
+  ctexture = clutter_clone_texture_new (CLUTTER_TEXTURE(vtexture));
+
+  clutter_element_set_size (ctexture, 640, 50);
+  clutter_element_set_position (ctexture, 0, 430);
+
+  /*
+  clutter_element_set_clip (CLUTTER_ELEMENT(clutter_stage()), 
+                           0, 0, 100, 100);
+  */
+
+  clutter_video_texture_open(CLUTTER_VIDEO_TEXTURE(vtexture), 
+                            argv[1],
+                            NULL,
+                            NULL);
+
+  clutter_group_add(clutter_stage(), vtexture);
+  clutter_group_add(clutter_stage(), rect);
+  clutter_group_add(clutter_stage(), label);
+  clutter_group_add(clutter_stage(), ctexture);
+
+  clutter_stage_set_color (CLUTTER_STAGE(clutter_stage()), 0xFFFFFF00); 
+
+  g_signal_connect (clutter_stage(), "input-event",
+                   G_CALLBACK (input_cb), 
+                   vtexture);
+
+  clutter_group_show_all(clutter_stage());
+
+
+  if (!clutter_video_texture_play(CLUTTER_VIDEO_TEXTURE(vtexture), NULL))
+      g_error("failed to play vtexture");
+
+  g_signal_connect (vtexture, "tick",
+                   G_CALLBACK (tick), 
+                   label);
+
+  g_object_set (G_OBJECT(vtexture), "sync-size", FALSE, NULL);
+
+  g_signal_connect (CLUTTER_TEXTURE(vtexture), 
+                   "size-change",
+                   G_CALLBACK (size_change), NULL);
+
+  /* g_timeout_add (100, foo, vtexture); */
+
+  clutter_main();
+
+  return 0;
+}
diff --git a/examples/test.c b/examples/test.c
new file mode 100644 (file)
index 0000000..c7d4985
--- /dev/null
@@ -0,0 +1,108 @@
+#include <clutter/clutter.h>
+
+guint8 opacity = 255;
+
+gboolean 
+timeout_cb (gpointer data)
+{
+  ClutterElement *element;
+
+  element = CLUTTER_ELEMENT(data);
+
+  if (opacity > 0)
+    {
+      clutter_element_set_opacity (element, opacity);
+      opacity -= 2;
+    }
+  else opacity = 0xff;
+
+  return TRUE;
+}
+
+gboolean 
+timeout_text_cb (gpointer data)
+{
+  ClutterLabel *label;
+  gchar buf[32];
+
+  label = CLUTTER_LABEL(data);
+
+  g_snprintf(buf, 32, "--> %i <--", opacity);
+
+  if (opacity > 0)
+    {
+      clutter_label_set_text(label, buf);
+      clutter_element_set_opacity (CLUTTER_ELEMENT(label), opacity);
+      opacity -= 2;
+    }
+  else opacity = 0xff;
+
+
+
+  return TRUE;
+}
+
+void
+frame_cb (ClutterTimeline *timeline, 
+         gint             frame_num, 
+         gpointer         data)
+{
+  ClutterLabel *label;
+  gchar buf[32];
+
+  label = CLUTTER_LABEL(data);
+
+  opacity = frame_num/2;
+
+  g_snprintf(buf, 32, "--> %i <--", frame_num);
+
+  clutter_label_set_text (label, buf);
+  clutter_element_set_opacity (CLUTTER_ELEMENT(label), opacity); 
+
+  clutter_element_rotate_z (CLUTTER_ELEMENT(label),
+                           frame_num,
+                           clutter_element_get_width (CLUTTER_ELEMENT(label))/2,
+                           clutter_element_get_height (CLUTTER_ELEMENT(label))/2);
+}
+
+int
+main (int argc, char *argv[])
+{
+  ClutterElement *texture, *label;
+  ClutterTimeline *timeline;
+  GdkPixbuf      *pixbuf;
+
+  clutter_init (&argc, &argv);
+
+  pixbuf = gdk_pixbuf_new_from_file ("clutter-logo-800x600.png", NULL);
+
+  if (!pixbuf)
+    g_error("pixbuf load failed");
+
+  texture = clutter_texture_new_from_pixbuf (pixbuf);
+
+  printf("***********foo***********\n");
+
+  label = clutter_label_new_with_text("Sans Bold 72", "Clutter\nOpened\nHand");
+
+  printf("***********foo***********\n");
+
+  clutter_element_set_opacity (CLUTTER_ELEMENT(label), 0x99);
+  clutter_element_set_position (CLUTTER_ELEMENT(label), 100, 200);
+
+  clutter_group_add(clutter_stage(), texture);
+  clutter_group_add(clutter_stage(), label);
+
+  clutter_element_set_size (CLUTTER_ELEMENT(clutter_stage()), 800, 600);
+
+  clutter_group_show_all(clutter_stage());
+
+  timeline = clutter_timeline_new (360, 200);
+  g_object_set(timeline, "loop", TRUE, 0);
+  g_signal_connect(timeline, "new-frame", frame_cb, label);
+  clutter_timeline_start (timeline);
+
+  clutter_main();
+
+  return 0;
+}
diff --git a/examples/video-cube.c b/examples/video-cube.c
new file mode 100644 (file)
index 0000000..e186e7d
--- /dev/null
@@ -0,0 +1,275 @@
+/* HACK HACK. HACK.  
+ * This is just a quick hack to see if a 3D type video cube
+ * would be possible with clutter. It needs many hacks cleaning.
+ */
+
+#include <clutter/clutter.h>
+#include <glib-object.h>
+
+#include <math.h>              /* for M_PI */
+
+#define WINWIDTH 800
+#define WINHEIGHT 600
+
+/* lazy globals */
+static float xrot, yrot, zrot;
+
+/* Avoid needing GLUT perspective call */
+static void
+frustum (GLfloat left,
+        GLfloat right,
+        GLfloat bottom,
+        GLfloat top,
+        GLfloat nearval,
+        GLfloat farval)
+{
+  GLfloat x, y, a, b, c, d;
+  GLfloat m[16];
+
+  x = (2.0 * nearval) / (right - left);
+  y = (2.0 * nearval) / (top - bottom);
+  a = (right + left) / (right - left);
+  b = (top + bottom) / (top - bottom);
+  c = -(farval + nearval) / ( farval - nearval);
+  d = -(2.0 * farval * nearval) / (farval - nearval);
+
+#define M(row,col)  m[col*4+row]
+  M(0,0) = x;     M(0,1) = 0.0F;  M(0,2) = a;      M(0,3) = 0.0F;
+  M(1,0) = 0.0F;  M(1,1) = y;     M(1,2) = b;      M(1,3) = 0.0F;
+  M(2,0) = 0.0F;  M(2,1) = 0.0F;  M(2,2) = c;      M(2,3) = d;
+  M(3,0) = 0.0F;  M(3,1) = 0.0F;  M(3,2) = -1.0F;  M(3,3) = 0.0F;
+#undef M
+
+  glMultMatrixf (m);
+}
+
+static void
+perspective (GLfloat fovy,
+            GLfloat aspect,
+            GLfloat zNear,
+            GLfloat zFar)
+{
+  GLfloat xmin, xmax, ymin, ymax;
+
+  ymax = zNear * tan (fovy * M_PI / 360.0);
+  ymin = -ymax;
+  xmin = ymin * aspect;
+  xmax = ymax * aspect;
+
+  frustum (xmin, xmax, ymin, ymax, zNear, zFar);
+}
+
+
+/* video texture subclass */
+
+#define CLUTTER_TYPE_VIDEO_TEXTURE_CUBE clutter_video_texture_cube_get_type()
+
+#define CLUTTER_VIDEO_TEXTURE_CUBE(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+  CLUTTER_TYPE_VIDEO_TEXTURE_CUBE, ClutterVideoTextureCube))
+
+#define CLUTTER_VIDEO_TEXTURE_CUBE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), \
+  CLUTTER_TYPE_VIDEO_TEXTURE_CUBE, ClutterVideoTextureCubeClass))
+
+#define CLUTTER_IS_VIDEO_TEXTURE_CUBE(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+  CLUTTER_TYPE_VIDEO_TEXTURE_CUBE))
+
+#define CLUTTER_IS_VIDEO_TEXTURE_CUBE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+  CLUTTER_TYPE_VIDEO_TEXTURE_CUBE))
+
+#define CLUTTER_VIDEO_TEXTURE_CUBE_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+  CLUTTER_TYPE_VIDEO_TEXTURE_CUBE, ClutterVideoTextureCubeClass))
+
+typedef struct ClutterVideoTextureCubePrivate ClutterVideoTextureCubePrivate ;
+
+typedef struct ClutterVideoTextureCube
+{
+  ClutterVideoTexture             parent;
+  ClutterVideoTextureCubePrivate *priv;
+
+} 
+ClutterVideoTextureCube;
+
+typedef struct ClutterVideoTextureCubeClass 
+{
+  ClutterVideoTextureClass parent_class;
+} 
+ClutterVideoTextureCubeClass;
+
+GType clutter_video_texture_cube_get_type (void);
+
+G_DEFINE_TYPE (ClutterVideoTextureCube, clutter_video_texture_cube, CLUTTER_TYPE_VIDEO_TEXTURE);
+
+
+static void
+clutter_video_texture_cube_paint (ClutterElement *self)
+{
+  if (clutter_texture_get_pixbuf (CLUTTER_TEXTURE(self)) == NULL)
+    return;
+
+  if (!CLUTTER_ELEMENT_IS_REALIZED (CLUTTER_ELEMENT(self)))
+      clutter_element_realize (CLUTTER_ELEMENT(self));
+
+  if (!clutter_texture_has_generated_tiles (CLUTTER_TEXTURE(self)))
+    return;
+
+  /* HACK: sets up a 3D tranform matrix other than regular 2D one */
+  /* FIXME: figure out how to nicely combine both within clutter */
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+
+  perspective (45.0f, 
+              (GLfloat)WINWIDTH/(GLfloat)WINHEIGHT, 
+              0.1f,
+              100.0f);
+
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+
+  /* back camera out a little */
+  glTranslatef(0.0f,0.0f,-3.0f);
+
+  glEnable(GL_DEPTH_TEST);
+  glEnable(GL_TEXTURE_2D);
+
+  glShadeModel(GL_SMOOTH);
+  glClearDepth(1.0f);
+  glDepthFunc(GL_LEQUAL);
+  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+
+  glRotatef(xrot,1.0f,0.0f,0.0f);
+  glRotatef(yrot,0.0f,1.0f,0.0f);
+  glRotatef(zrot,0.0f,0.0f,1.0f);
+
+  /* HACK: Cheat as just bind to first tiled as squared   */
+  clutter_texture_bind_tile (CLUTTER_TEXTURE(self), 0);
+
+  glBegin(GL_QUADS);
+  // Front Face
+  glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
+  glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
+  glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
+  glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
+  // Back Face
+  glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
+  glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
+  glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
+  glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
+  // Top Face
+  glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
+  glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
+  glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
+  glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
+  // Bottom Face
+  glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
+  glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
+  glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
+  glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
+  // Right face
+  glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
+  glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
+  glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
+  glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
+  // Left Face
+  glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
+  glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
+  glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
+  glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
+  glEnd();
+
+
+  /* HACK: reset to regular transform */
+#if 0
+  glMatrixMode (GL_PROJECTION);
+  glLoadIdentity ();
+  glOrtho (0, WINWIDTH, WINHEIGHT, 0, -1, 1);
+  glMatrixMode (GL_MODELVIEW);
+  glLoadIdentity ();
+#endif
+
+  /* rotate */
+  xrot+=1.0f;
+  yrot+=1.0f;
+  zrot+=1.0f;
+}
+
+static void
+clutter_video_texture_cube_class_init (ClutterVideoTextureCubeClass *klass)
+{
+  GObjectClass        *gobject_class;
+  ClutterElementClass *element_class;
+
+  gobject_class = (GObjectClass*)klass;
+  element_class = (ClutterElementClass*)klass;
+
+  element_class->paint = clutter_video_texture_cube_paint;
+}
+
+static void
+clutter_video_texture_cube_init (ClutterVideoTextureCube *self)
+{
+
+}
+
+ClutterElement*
+clutter_video_texture_cube_new (GError **err)
+{
+  return CLUTTER_ELEMENT(g_object_new (CLUTTER_TYPE_VIDEO_TEXTURE_CUBE, 
+                                      /* "tiled", FALSE, */
+                                      NULL));
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  ClutterElement      *label, *texture, *vtexture; 
+  GdkPixbuf           *pixbuf;
+  GError              *err = NULL;
+
+  if (argc < 2)
+    g_error("%s <video file>", argv[0]);
+
+  clutter_init (&argc, &argv);
+
+  pixbuf = gdk_pixbuf_new_from_file ("clutter-logo-800x600.png", NULL);
+
+  if (!pixbuf)
+    g_error("pixbuf load failed");
+
+  clutter_element_set_size (CLUTTER_ELEMENT(clutter_stage()), 
+                           WINWIDTH, WINHEIGHT);
+
+  texture = clutter_texture_new_from_pixbuf (pixbuf);
+
+  vtexture = clutter_video_texture_cube_new (&err);
+
+  if (vtexture == NULL || err != NULL)
+    {
+      g_error("failed to create vtexture, err: %s", err->message);
+    }
+
+  clutter_video_texture_open(CLUTTER_VIDEO_TEXTURE(vtexture), 
+                            argv[1],
+                            NULL,
+                            NULL);
+
+  clutter_group_add(clutter_stage(), texture);
+
+  clutter_group_add(clutter_stage(), vtexture);
+  
+  clutter_group_show_all(clutter_stage());
+
+  if (!clutter_video_texture_play(CLUTTER_VIDEO_TEXTURE(vtexture), NULL))
+      g_error("failed to play vtexture");
+
+  clutter_main();
+
+  return 0;
+}
+
+
index f8cea26..d02099a 100644 (file)
@@ -1,20 +1,17 @@
-# see http://cvs.sourceforge.net/viewcvs.py/wechselspieler/wechselspieler/plugins/Makefile.am?rev=1.6&view=auto
-
-lib_LTLIBRARIES = libcltrimagesink.la
+lib_LTLIBRARIES = libclutterimagesink.la
 
 # HACK HACK HACK HACK for now
-libdir= /usr/lib/gstreamer-0.8/
+libdir= /usr/lib/gstreamer-0.10/
 
-INCLUDES=@GST_CFLAGS@ $(CLTR_CFLAGS)
+INCLUDES=@GST_CFLAGS@ $(CLUTTER_CFLAGS)
 
 LIBS=@GST_LIBS@
 
-
-libcltrimagesink_la_SOURCES = cltrimagesink.c 
-libcltrimagesink_la_INCLUDES = $(CLTR_CFLAGS)
-libcltrimagesink_LIBDIR = ${libdir}/gst
-libcltrimagesink_la_LIBADD = @CLTR_LIBS@
-libcltrimagesink_la_LDFLAGS = -module -avoid-version
+libclutterimagesink_la_SOURCES = clutterimagesink.c 
+libclutterimagesink_la_INCLUDES = $(CLUTTER_CFLAGS)
+libclutterimagesink_LIBDIR = ${libdir}/gst
+libclutterimagesink_la_LIBADD = @CLUTTER_LIBS@
+libclutterimagesink_la_LDFLAGS = -module -avoid-version
 
 noinst_HEADERS = \
-    cltrimagesink.h
\ No newline at end of file
+    clutterimagesink.h
\ No newline at end of file
diff --git a/gst/cltrimagesink.h b/gst/cltrimagesink.h
deleted file mode 100644 (file)
index a31f32d..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef __GST_CLTRIMAGESINK_H__
-#define __GST_CLTRIMAGESINK_H__
-
-#include <gst/video/videosink.h>
-#include <clutter/cltr.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_CLTRIMAGESINK \
-  (gst_cltrimagesink_get_type())
-#define GST_CLTRIMAGESINK(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_CLTRIMAGESINK, GstCltrimageSink))
-#define GST_CLTRIMAGESINK_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_CLTRIMAGESINK, GstCltrimageSink))
-#define GST_IS_CLTRIMAGESINK(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_CLTRIMAGESINK))
-#define GST_IS_CLTRIMAGESINK_CLASS(obj) \
-  (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_CLTRIMAGESINK))
-
-typedef struct _GstCltrimageSink GstCltrimageSink;
-typedef struct _GstCltrimageSinkClass GstCltrimageSinkClass;
-
-struct _GstCltrimageSink 
-{
-  /* Our element stuff */
-  GstVideoSink videosink;
-  
-  CltrTexture *texture;
-  
-  int pixel_width, pixel_height;
-
-  gdouble framerate;
-  GMutex *x_lock;
-  
-  GstClockTime time;
-  
-  GMutex *pool_lock;
-  GSList *image_pool;
-
-  GstCaps     *caps;
-  GAsyncQueue *queue; 
-
-};
-
-struct _GstCltrimageSinkClass {
-  GstVideoSinkClass parent_class;
-
-  /* signals */
-  void (*handoff)     (GstElement *element, GstBuffer *buf, GstPad *pad);
-  void (*bufferalloc) (GstElement *element, GstBuffer *buf, GstPad *pad);
-};
-
-GType gst_cltrimagesink_get_type(void); /* XXX needed ? */
-
-
-G_END_DECLS
-
-#endif /* __GST_CLTRIMAGESINK_H__ */
similarity index 100%
rename from gst/cltrimagesink.c
rename to gst/clutterimagesink.
diff --git a/gst/clutterimagesink.c b/gst/clutterimagesink.c
new file mode 100644 (file)
index 0000000..c839f65
--- /dev/null
@@ -0,0 +1,1386 @@
+/*
+ * Clutter GST VideoSink 
+ *
+ * Heavily based on code XImageSink with following copyright;
+ * Copyright (C) <2005> Julien Moutte <julien@moutte.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Our interfaces */
+#include <gst/interfaces/navigation.h>
+
+/* Object header */
+#include "clutterimagesink.h"
+
+/* Debugging category */
+#include <gst/gstinfo.h>
+
+/* Clutter */
+#include <clutter/clutter.h>
+
+GST_DEBUG_CATEGORY_EXTERN (gst_debug_clutterimagesink);
+#define GST_CAT_DEFAULT gst_debug_clutterimagesink
+
+#define DBG(x, a...) \
+ g_printerr ( __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a)
+
+static void 
+gst_clutterimagesink_clutterimage_destroy (GstClutterImageSink *clutterimagesink,
+                                          GstClutterImageBuffer *clutterimage);
+
+/* ElementFactory information */
+static GstElementDetails gst_clutterimagesink_details =
+GST_ELEMENT_DETAILS ("Video sink",
+                    "Sink/Video",
+                    "Clutter videosink",
+                    "Matthew Allum <mallum@o-hand.com>");
+
+static GstStaticPadTemplate gst_clutterimagesink_sink_template_factory =
+GST_STATIC_PAD_TEMPLATE ("sink",
+           GST_PAD_SINK,
+           GST_PAD_ALWAYS,
+           GST_STATIC_CAPS ("video/x-raw-rgb, "
+                            "framerate = (fraction) [ 0, MAX ], "
+                            "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
+                        );
+enum
+{
+  PROP_0,
+  PROP_VIDEO_TEXTURE,
+  PROP_PIXEL_ASPECT_RATIO,
+  PROP_FORCE_ASPECT_RATIO
+};
+
+static GstVideoSinkClass *parent_class = NULL;
+
+
+#define GST_TYPE_CLUTTERIMAGE_BUFFER (gst_clutterimage_buffer_get_type())
+
+#define GST_IS_CLUTTERIMAGE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CLUTTERIMAGE_BUFFER))
+#define GST_CLUTTERIMAGE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CLUTTERIMAGE_BUFFER, GstClutterImageBuffer))
+#define GST_CLUTTERIMAGE_BUFFER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_CLUTTERIMAGE_BUFFER, GstClutterImageBufferClass))
+
+static void
+gst_clutterimage_buffer_finalize (GstClutterImageBuffer *clutterimage)
+{
+  GstClutterImageSink *clutterimagesink = NULL;
+  gboolean                     recycled = FALSE;
+
+  g_return_if_fail (clutterimage != NULL);
+
+  clutterimagesink = clutterimage->clutterimagesink;
+
+  if (!clutterimagesink) 
+    {
+      GST_WARNING_OBJECT (clutterimagesink, "no sink found");
+      goto beach;
+    }
+
+  /* If our geometry changed we can't reuse that image. */
+  if ((clutterimage->width != GST_VIDEO_SINK_WIDTH (clutterimagesink)) 
+      || (clutterimage->height != GST_VIDEO_SINK_HEIGHT (clutterimagesink))) 
+    {
+      gst_clutterimagesink_clutterimage_destroy (clutterimagesink, 
+                                                clutterimage);
+    } 
+  else 
+    {
+      /* In that case we can reuse the image and add it to our image pool. */
+      GST_LOG_OBJECT (clutterimagesink, "recycling image %p in pool", 
+                     clutterimage);
+
+      /* need to increment the refcount again to recycle */
+      gst_buffer_ref (GST_BUFFER (clutterimage));
+      g_mutex_lock (clutterimagesink->pool_lock);
+      clutterimagesink->buffer_pool 
+       = g_slist_prepend (clutterimagesink->buffer_pool, clutterimage);
+      g_mutex_unlock (clutterimagesink->pool_lock);
+      recycled = TRUE;
+    }
+  
+ beach:
+  return;
+}
+
+static void
+gst_clutterimage_buffer_free (GstClutterImageBuffer *clutterimage)
+{
+  /* make sure it is not recycled */
+  clutterimage->width  = -1;
+  clutterimage->height = -1;
+  gst_buffer_unref (GST_BUFFER (clutterimage));
+}
+
+static void
+gst_clutterimage_buffer_init (GstClutterImageBuffer *clutterimage_buffer, 
+                             gpointer               g_class)
+{
+  ;
+}
+
+static void
+gst_clutterimage_buffer_class_init (gpointer g_class, gpointer class_data)
+{
+  GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
+
+  mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
+      gst_clutterimage_buffer_finalize;
+}
+
+GType
+gst_clutterimage_buffer_get_type (void)
+{
+  static GType _gst_clutterimage_buffer_type;
+
+  if (G_UNLIKELY (_gst_clutterimage_buffer_type == 0)) 
+    {
+      static const GTypeInfo clutterimage_buffer_info = 
+       {
+         sizeof (GstBufferClass),
+         NULL,
+         NULL,
+         gst_clutterimage_buffer_class_init,
+         NULL,
+         NULL,
+         sizeof (GstClutterImageBuffer),
+         0,
+         (GInstanceInitFunc) gst_clutterimage_buffer_init,
+         NULL
+       };
+      
+      _gst_clutterimage_buffer_type 
+       = g_type_register_static (GST_TYPE_BUFFER,
+                                 "GstClutterImageBuffer", 
+                                 &clutterimage_buffer_info, 0);
+    }
+  return _gst_clutterimage_buffer_type;
+}
+
+static GstClutterImageBuffer *
+gst_clutterimagesink_clutterimage_new (GstClutterImageSink *clutterimagesink, 
+                                      GstCaps             *caps)
+{
+  GstClutterImageBuffer *clutterimage = NULL;
+  GstStructure          *structure = NULL;
+  gboolean               succeeded = FALSE;
+
+  g_return_val_if_fail (GST_IS_CLUTTERIMAGESINK (clutterimagesink), NULL);
+
+  clutterimage = (GstClutterImageBuffer*)gst_mini_object_new (GST_TYPE_CLUTTERIMAGE_BUFFER);
+
+  structure = gst_caps_get_structure (caps, 0);
+
+  if (!gst_structure_get_int (structure, "width", &clutterimage->width) ||
+      !gst_structure_get_int (structure, "height", &clutterimage->height)) 
+    GST_WARNING ("failed getting geometry from caps %" GST_PTR_FORMAT, caps);
+
+  GST_DEBUG_OBJECT (clutterimagesink, 
+                   "creating image %p (%dx%d)", 
+                   clutterimage,
+                   clutterimage->width, clutterimage->height);
+
+  g_mutex_lock (clutterimagesink->x_lock);
+
+  clutterimage->clutterimage = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 
+                                              TRUE, 
+                                              8,
+                                              clutterimage->width,
+                                              clutterimage->height);
+
+  if (!clutterimage->clutterimage) 
+    {
+      GST_ELEMENT_ERROR (clutterimagesink, RESOURCE, WRITE, (NULL),
+                        ("could not XCreateImage a %dx%d image"));
+      goto beach;
+    }
+
+  succeeded = TRUE;
+
+  GST_BUFFER_DATA (clutterimage) = (guchar *) gdk_pixbuf_get_pixels (clutterimage->clutterimage);
+  GST_BUFFER_SIZE (clutterimage) = gdk_pixbuf_get_rowstride (clutterimage->clutterimage) * clutterimage->height;
+  
+  /* Keep a ref to our sink */
+  clutterimage->clutterimagesink = gst_object_ref (clutterimagesink);
+
+beach:
+  g_mutex_unlock (clutterimagesink->x_lock);
+  
+  if (!succeeded) {
+    gst_clutterimage_buffer_free (clutterimage);
+    clutterimage = NULL;
+  }
+
+  return clutterimage;
+}
+
+static void
+gst_clutterimagesink_clutterimage_destroy (GstClutterImageSink   *clutterimagesink,
+                                          GstClutterImageBuffer *clutterimage)
+{
+  g_return_if_fail (clutterimage != NULL);
+  g_return_if_fail (GST_IS_CLUTTERIMAGESINK (clutterimagesink));
+
+  /* If the destroyed image is the current one we destroy our reference too */
+  if (clutterimagesink->cur_image == clutterimage) 
+    clutterimagesink->cur_image = NULL;
+
+  /* We might have some buffers destroyed after changing state to NULL */
+  if (!clutterimagesink->context)
+    goto beach;
+
+
+  g_mutex_lock (clutterimagesink->x_lock);
+
+  if (clutterimage->clutterimage) 
+    g_object_unref (clutterimage->clutterimage);
+
+  g_mutex_unlock (clutterimagesink->x_lock);
+
+beach:
+  if (clutterimage->clutterimagesink) 
+    {
+      /* Release the ref to our sink */
+      clutterimage->clutterimagesink = NULL;
+      gst_object_unref (clutterimagesink);
+    }
+
+  return;
+}
+
+static void
+gst_clutterimagesink_clutterimage_put (GstClutterImageSink   *clutterimagesink,
+                                      GstClutterImageBuffer *clutterimage)
+{
+  GstVideoRectangle src, dst, result;
+
+  g_return_if_fail (GST_IS_CLUTTERIMAGESINK (clutterimagesink));
+
+  /* We take the flow_lock. If expose is in there we don't want to run
+     concurrently from the data flow thread */
+  g_mutex_lock (clutterimagesink->flow_lock);
+
+  /* Store a reference to the last image we put, lose the previous one */
+  if (clutterimage && clutterimagesink->cur_image != clutterimage) 
+    {
+      if (clutterimagesink->cur_image) 
+       {
+         GST_LOG_OBJECT (clutterimagesink, 
+                         "unreffing %p", 
+                         clutterimagesink->cur_image);
+         gst_buffer_unref (clutterimagesink->cur_image);
+       }
+      
+      GST_LOG_OBJECT (clutterimagesink, 
+                     "reffing %p as our current image", 
+                     clutterimage);
+      
+      clutterimagesink->cur_image 
+       = GST_CLUTTERIMAGE_BUFFER (gst_buffer_ref (clutterimage));
+    }
+
+  /* Expose sends a NULL image, we take the latest frame */
+  if (!clutterimage) 
+    {
+      if (clutterimagesink->cur_image) 
+       {
+         clutterimage = clutterimagesink->cur_image;
+       } 
+      else 
+       {
+         g_mutex_unlock (clutterimagesink->flow_lock);
+         return;
+       }
+    }
+
+  /* FIXME: figure this out */
+  src.w = clutterimage->width;
+  src.h = clutterimage->height;
+  dst.w = clutterimage->width;
+  dst.h = clutterimage->height;
+
+  gst_video_sink_center_rect (src, dst, &result, FALSE);
+  
+  g_mutex_lock (clutterimagesink->x_lock);
+  
+  if (clutterimagesink->video_texture)
+    {
+      guchar *pixels;
+      guint   x,y, off, stride, total;
+
+      /* gstreamer does not seem to want to give us data in 
+       * LITTLE_ENDIAN which GL textures really need so we
+       * have to byteswap.
+       *
+       * Setting pixel_format to GL_BGR does not seem to help 
+       * either - maybe something pixbufs are doing something
+       * funky also.
+       *
+       * FIXME:
+       * Ultimatly the whole thing can be optimised. ( avoid
+       * pixbufs completely with just int data? ). need to just 
+       * figure out best way.
+      */
+      
+      pixels = gdk_pixbuf_get_pixels (clutterimage->clutterimage);
+      stride = gdk_pixbuf_get_rowstride (clutterimage->clutterimage);
+
+      /* Swap endianess - FIXME: count down + faster, safer */
+      for (y=0; y < gdk_pixbuf_get_height(clutterimage->clutterimage); y++)
+       {
+         off = (y * stride);
+         for (x=0; x < stride; x += 4)
+           { 
+             pixels[off+x+2] ^= pixels[off+x];
+             pixels[off+x]   ^= pixels[off+x+2];
+             pixels[off+x+2] ^= pixels[off+x];
+
+             pixels[off+x+4] ^= 0; /* double fix alpha */
+           }
+       }
+
+      
+
+      clutter_texture_set_pixbuf (CLUTTER_TEXTURE(clutterimagesink->video_texture),
+                                 clutterimage->clutterimage);
+    }
+
+  g_mutex_unlock (clutterimagesink->x_lock);
+
+  g_mutex_unlock (clutterimagesink->flow_lock);
+}
+
+/* This function calculates the pixel aspect ratio based on the properties
+ * in the context structure and stores it there. */
+static void
+gst_clutterimagesink_calculate_pixel_aspect_ratio (GstClutterContext *context)
+{
+  gint par[][2] = {
+    {1, 1},                     /* regular screen */
+    {16, 15},                   /* PAL TV */
+    {11, 10},                   /* 525 line Rec.601 video */
+    {54, 59},                   /* 625 line Rec.601 video */
+    {64, 45},                   /* 1280x1024 on 16:9 display */
+    {5, 3},                     /* 1280x1024 on 4:3 display */
+    {4, 3}                      /*  800x600 on 16:9 display */
+  };
+
+  gint    i;
+  gint    index;
+  gdouble ratio;
+  gdouble delta;
+
+#define DELTA(idx) (ABS (ratio - ((gdouble) par[idx][0] / par[idx][1])))
+
+  /* first calculate the "real" ratio based on the X values;
+   * which is the "physical" w/h divided by the w/h in pixels of the display */
+  ratio = (gdouble) (context->widthmm * context->height)
+                     / (context->heightmm * context->width);
+
+  GST_DEBUG ("calculated pixel aspect ratio: %f", ratio);
+
+  /* now find the one from par[][2] with the lowest delta to the real one */
+  delta = DELTA (0);
+  index = 0;
+  
+  for (i = 1; i < sizeof (par) / (sizeof (gint) * 2); ++i) 
+    {
+      gdouble this_delta = DELTA (i);
+      
+      if (this_delta < delta) {
+       index = i;
+       delta = this_delta;
+      }
+    }
+
+  GST_DEBUG ("Decided on index %d (%d/%d)", 
+            index,  par[index][0], par[index][1]);
+
+  g_free (context->par);
+
+  context->par = g_new0 (GValue, 1);
+
+  g_value_init (context->par, GST_TYPE_FRACTION);
+
+  gst_value_set_fraction (context->par, par[index][0], par[index][1]);
+
+  GST_DEBUG ("set context PAR to %d/%d",
+            gst_value_get_fraction_numerator (context->par),
+            gst_value_get_fraction_denominator (context->par));
+}
+
+static GstClutterContext *
+gst_clutterimagesink_context_get (GstClutterImageSink * clutterimagesink)
+{
+  GstClutterContext    *context = NULL;
+  XPixmapFormatValues *px_formats = NULL;
+  gint                 nb_formats = 0, i;
+
+  g_return_val_if_fail (GST_IS_CLUTTERIMAGESINK (clutterimagesink), NULL);
+
+  context = g_new0 (GstClutterContext, 1);
+
+  g_mutex_lock (clutterimagesink->x_lock);
+
+  /* FIXME: pull from clutter context */
+  context->disp = XOpenDisplay (clutterimagesink->display_name);
+
+  if (!context->disp) 
+    {
+      g_mutex_unlock (clutterimagesink->x_lock);
+      g_free (context);
+      GST_ELEMENT_ERROR (clutterimagesink, RESOURCE, WRITE, (NULL),
+                        ("Could not open display"));
+      return NULL;
+    }
+
+  context->screen     = DefaultScreenOfDisplay (context->disp);
+  context->screen_num = DefaultScreen (context->disp);
+  context->width    = DisplayWidth (context->disp, context->screen_num);
+  context->height   = DisplayHeight (context->disp, context->screen_num);
+  context->widthmm  = DisplayWidthMM (context->disp, context->screen_num);
+  context->heightmm = DisplayHeightMM (context->disp, context->screen_num);
+
+  DBG("X reports %dx%d pixels and %d mm x %d mm",
+      context->width, context->height, 
+      context->widthmm, context->heightmm);
+
+  gst_clutterimagesink_calculate_pixel_aspect_ratio (context);
+
+  XCloseDisplay (context->disp);
+
+  /* update object's par with calculated one if not set yet */
+  if (!clutterimagesink->par) 
+    {
+      clutterimagesink->par = g_new0 (GValue, 1);
+      gst_value_init_and_copy (clutterimagesink->par, context->par);
+      GST_DEBUG_OBJECT (clutterimagesink, "set calculated PAR on object's PAR");
+    }
+
+  context->caps = gst_caps_new_simple ("video/x-raw-rgb",
+      "bpp", G_TYPE_INT, 32,
+      "depth", G_TYPE_INT, 24,
+      "endianness", G_TYPE_INT, G_BIG_ENDIAN, 
+       "red_mask", G_TYPE_INT,   0xff00 /* >> 8 for 24bpp */, 
+      "green_mask", G_TYPE_INT, 0xff0000,
+      "blue_mask", G_TYPE_INT,  0xff000000,
+      "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
+      "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
+      "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
+
+  if (clutterimagesink->par) 
+    {
+      int nom, den;
+      
+      nom = gst_value_get_fraction_numerator (clutterimagesink->par);
+      den = gst_value_get_fraction_denominator (clutterimagesink->par);
+      gst_caps_set_simple (context->caps, 
+                          "pixel-aspect-ratio",
+                          GST_TYPE_FRACTION, nom, den, NULL);
+    }
+
+  g_mutex_unlock (clutterimagesink->x_lock);
+
+  return context;
+}
+
+static void
+gst_clutterimagesink_context_clear (GstClutterImageSink *clutterimagesink)
+{
+  g_return_if_fail (GST_IS_CLUTTERIMAGESINK (clutterimagesink));
+  g_return_if_fail (clutterimagesink->context != NULL);
+
+  gst_caps_unref (clutterimagesink->context->caps);
+  g_free (clutterimagesink->context->par);
+  g_free (clutterimagesink->par);
+  clutterimagesink->par = NULL;
+
+  g_mutex_lock (clutterimagesink->x_lock);
+
+  XCloseDisplay (clutterimagesink->context->disp);
+
+  g_mutex_unlock (clutterimagesink->x_lock);
+
+  g_free (clutterimagesink->context);
+
+  clutterimagesink->context = NULL;
+}
+
+static void
+gst_clutterimagesink_bufferpool_clear (GstClutterImageSink *clutterimagesink)
+{
+
+  g_mutex_lock (clutterimagesink->pool_lock);
+
+  while (clutterimagesink->buffer_pool) 
+    {
+      GstClutterImageBuffer *clutterimage;
+
+      clutterimage = clutterimagesink->buffer_pool->data;
+
+      clutterimagesink->buffer_pool 
+       = g_slist_delete_link (clutterimagesink->buffer_pool,
+                              clutterimagesink->buffer_pool);
+
+      gst_clutterimage_buffer_free (clutterimage);
+    }
+
+  g_mutex_unlock (clutterimagesink->pool_lock);
+}
+
+/* Element stuff */
+
+static GstCaps *
+gst_clutterimagesink_getcaps (GstBaseSink * bsink)
+{
+  GstClutterImageSink *clutterimagesink;
+  GstCaps             *caps;
+  int                  i;
+
+  clutterimagesink = GST_CLUTTERIMAGESINK (bsink);
+
+  if (clutterimagesink->context)
+    return gst_caps_ref (clutterimagesink->context->caps);
+
+  /* get a template copy and add the pixel aspect ratio */
+  caps =
+    gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SINK (clutterimagesink)->sinkpad));
+
+  for (i = 0; i < gst_caps_get_size (caps); ++i) 
+    {
+      GstStructure *structure = gst_caps_get_structure (caps, i);
+
+      if (clutterimagesink->par) 
+       {
+         int nom, den;
+
+         nom = gst_value_get_fraction_numerator (clutterimagesink->par);
+         den = gst_value_get_fraction_denominator (clutterimagesink->par);
+         gst_structure_set (structure, "pixel-aspect-ratio",
+                            GST_TYPE_FRACTION, nom, den, NULL);
+       }
+    }
+  
+  return caps;
+}
+
+static gboolean
+gst_clutterimagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
+{
+  GstClutterImageSink *clutterimagesink;
+  gboolean             ret = TRUE;
+  GstStructure        *structure;
+  GstCaps             *intersection;
+  const GValue        *par;
+  gint                 new_width, new_height;
+  const GValue        *fps;
+
+  clutterimagesink = GST_CLUTTERIMAGESINK (bsink);
+
+  if (!clutterimagesink->context)
+    return FALSE;
+
+  GST_DEBUG_OBJECT (clutterimagesink,
+                   "sinkconnect possible caps %" GST_PTR_FORMAT " with given caps %"
+                   GST_PTR_FORMAT, clutterimagesink->context->caps, caps);
+
+  /* We intersect those caps with our template to make sure they are correct */
+  intersection = gst_caps_intersect (clutterimagesink->context->caps, caps);
+
+  GST_DEBUG_OBJECT (clutterimagesink, "intersection returned %" GST_PTR_FORMAT,
+                   intersection);
+
+  if (gst_caps_is_empty (intersection)) 
+    return FALSE;
+
+  gst_caps_unref (intersection);
+
+  structure = gst_caps_get_structure (caps, 0);
+
+  ret &= gst_structure_get_int (structure, "width", &new_width);
+  ret &= gst_structure_get_int (structure, "height", &new_height);
+  fps = gst_structure_get_value (structure, "framerate");
+  ret &= (fps != NULL);
+
+  if (!ret) return FALSE;
+
+  /* if the caps contain pixel-aspect-ratio, they have to match ours,
+   * otherwise linking should fail */
+  par = gst_structure_get_value (structure, "pixel-aspect-ratio");
+
+  if (par) 
+    {
+      if (clutterimagesink->par) 
+       {
+         if (gst_value_compare (par, 
+                                clutterimagesink->par) != GST_VALUE_EQUAL) 
+           {
+             goto wrong_aspect;
+           }
+       } 
+      else if (clutterimagesink->context->par) 
+       {
+         if (gst_value_compare (par, 
+                                clutterimagesink->context->par) != GST_VALUE_EQUAL) 
+           {
+             goto wrong_aspect;
+           }
+       }
+    }
+
+  GST_VIDEO_SINK_WIDTH (clutterimagesink)  = new_width;
+  GST_VIDEO_SINK_HEIGHT (clutterimagesink) = new_height;
+
+  clutterimagesink->fps_n = gst_value_get_fraction_numerator (fps);
+  clutterimagesink->fps_d = gst_value_get_fraction_denominator (fps);
+
+  /* Creating our window and our image */
+  g_assert (GST_VIDEO_SINK_WIDTH (clutterimagesink) > 0);
+  g_assert (GST_VIDEO_SINK_HEIGHT (clutterimagesink) > 0);
+
+  /* If our clutterimage has changed we destroy it, next chain 
+     iteration will create a new one */
+  if ((clutterimagesink->clutterimage) &&
+      ((GST_VIDEO_SINK_WIDTH (clutterimagesink) != clutterimagesink->clutterimage->width) ||
+       (GST_VIDEO_SINK_HEIGHT (clutterimagesink) != clutterimagesink->clutterimage->height))) 
+    {
+      GST_DEBUG_OBJECT (clutterimagesink, 
+                       "our image is not usable anymore, unref %p",
+                       clutterimagesink->clutterimage);
+      gst_buffer_unref (GST_BUFFER (clutterimagesink->clutterimage));
+      clutterimagesink->clutterimage = NULL;
+    }
+
+  return TRUE;
+
+wrong_aspect:
+  {
+    GST_INFO_OBJECT (clutterimagesink, "pixel aspect ratio does not match");
+    return FALSE;
+  }
+}
+
+static GstStateChangeReturn
+gst_clutterimagesink_change_state (GstElement    *element, 
+                                  GstStateChange transition)
+{
+  GstClutterImageSink *clutterimagesink;
+  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+
+  clutterimagesink = GST_CLUTTERIMAGESINK (element);
+
+  switch (transition) 
+    {
+    case GST_STATE_CHANGE_NULL_TO_READY:
+      clutterimagesink->running = TRUE;
+      /* Initializing the Context */
+      if (!clutterimagesink->context)
+        clutterimagesink->context 
+         = gst_clutterimagesink_context_get (clutterimagesink);
+      if (!clutterimagesink->context) 
+       {
+         ret = GST_STATE_CHANGE_FAILURE;
+         goto beach;
+       }
+      break;
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+      break;
+    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+      break;
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+  if (ret == GST_STATE_CHANGE_FAILURE)
+    return ret;
+
+  switch (transition) {
+    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+      break;
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+      clutterimagesink->fps_n = 0;
+      clutterimagesink->fps_d = 1;
+      GST_VIDEO_SINK_WIDTH (clutterimagesink)  = 0;
+      GST_VIDEO_SINK_HEIGHT (clutterimagesink) = 0;
+      break;
+    case GST_STATE_CHANGE_READY_TO_NULL:
+      clutterimagesink->running = FALSE;
+      if (clutterimagesink->clutterimage) 
+       {
+         gst_buffer_unref (clutterimagesink->clutterimage);
+         clutterimagesink->clutterimage = NULL;
+       }
+      if (clutterimagesink->cur_image) 
+       {
+         gst_buffer_unref (clutterimagesink->cur_image);
+         clutterimagesink->cur_image = NULL;
+       }
+      if (clutterimagesink->buffer_pool)
+        gst_clutterimagesink_bufferpool_clear (clutterimagesink);
+
+      if (clutterimagesink->context) 
+       {
+         gst_clutterimagesink_context_clear (clutterimagesink);
+         clutterimagesink->context = NULL;
+       }
+      break;
+    default:
+      break;
+  }
+beach:
+  return ret;
+}
+
+static void
+gst_clutterimagesink_get_times (GstBaseSink  *bsink, 
+                               GstBuffer    *buf,
+                               GstClockTime *start, 
+                               GstClockTime *end)
+{
+  GstClutterImageSink *clutterimagesink;
+
+  clutterimagesink = GST_CLUTTERIMAGESINK (bsink);
+
+  if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) 
+    {
+      *start = GST_BUFFER_TIMESTAMP (buf);
+      if (GST_BUFFER_DURATION_IS_VALID (buf)) 
+       {
+         *end = *start + GST_BUFFER_DURATION (buf);
+       } 
+      else 
+       {
+         if (clutterimagesink->fps_n > 0) {
+           *end = *start + (GST_SECOND * clutterimagesink->fps_d) 
+                               / clutterimagesink->fps_n;
+         }
+       }
+    }
+}
+
+static GstFlowReturn
+gst_clutterimagesink_show_frame (GstBaseSink *bsink, GstBuffer *buf)
+{
+  GstClutterImageSink *clutterimagesink;
+
+  g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
+
+  clutterimagesink = GST_CLUTTERIMAGESINK (bsink);
+
+  /* If this buffer has been allocated using our buffer management we simply
+     put the clutterimage which is in the PRIVATE pointer */
+  if (GST_IS_CLUTTERIMAGE_BUFFER (buf)) 
+    {
+      GST_LOG_OBJECT (clutterimagesink, 
+                     "buffer from our pool, writing directly");
+      
+      gst_clutterimagesink_clutterimage_put (clutterimagesink, 
+                                            GST_CLUTTERIMAGE_BUFFER (buf));
+    } 
+  else 
+    {
+      /* Else we have to copy the data into our private image, */
+      /* if we have one... */
+      GST_LOG_OBJECT (clutterimagesink, "normal buffer, copying from it");
+
+      if (!clutterimagesink->clutterimage) 
+       {
+         GST_DEBUG_OBJECT (clutterimagesink, "creating our clutterimage");
+
+         clutterimagesink->clutterimage 
+           = gst_clutterimagesink_clutterimage_new (clutterimagesink,
+                                                    GST_BUFFER_CAPS (buf));
+         if (!clutterimagesink->clutterimage)
+           goto no_clutterimage;
+       }
+      
+      memcpy (GST_BUFFER_DATA (clutterimagesink->clutterimage), 
+             GST_BUFFER_DATA (buf),
+             MIN (GST_BUFFER_SIZE (buf), 
+                  clutterimagesink->clutterimage->size));
+      
+      gst_clutterimagesink_clutterimage_put (clutterimagesink, 
+                                            clutterimagesink->clutterimage);
+    }
+
+  return GST_FLOW_OK;
+  
+  /* ERRORS */
+ no_clutterimage:
+  {
+    /* No image available. That's very bad ! */
+    GST_DEBUG ("could not create image");
+
+    GST_ELEMENT_ERROR (clutterimagesink, CORE, NEGOTIATION, (NULL),
+     ("Failed creating an ClutterImage in clutterimagesink chain function."));
+    return GST_FLOW_ERROR;
+  }
+}
+
+/* Buffer management */
+
+static GstFlowReturn
+gst_clutterimagesink_buffer_alloc (GstBaseSink *bsink, 
+                                  guint64      offset, 
+                                  guint        size,
+                                  GstCaps     *caps, 
+                                  GstBuffer  **buf)
+{
+  GstClutterImageSink   *clutterimagesink;
+  GstClutterImageBuffer *clutterimage = NULL;
+  GstStructure          *structure = NULL;
+  GstCaps               *desired_caps = NULL;
+  GstFlowReturn          ret = GST_FLOW_OK;
+  gboolean               rev_nego = FALSE;
+  gint                   width, height;
+
+  clutterimagesink = GST_CLUTTERIMAGESINK (bsink);
+
+  GST_LOG_OBJECT (clutterimagesink,
+      "a buffer of %d bytes was requested with caps %" GST_PTR_FORMAT
+      " and offset %" G_GUINT64_FORMAT, size, caps, offset);
+
+  desired_caps = gst_caps_copy (caps);
+
+  structure = gst_caps_get_structure (desired_caps, 0);
+
+  if (gst_structure_get_int (structure, "width", &width) &&
+      gst_structure_get_int (structure, "height", &height)) 
+    {
+      GstVideoRectangle dst, src, result;
+      
+      src.w = width;
+      src.h = height;
+      
+      /* We take the flow_lock because the window might go away */
+      g_mutex_lock (clutterimagesink->flow_lock);
+
+      /* What is our geometry */
+#if 0
+    gst_clutterimagesink_xwindow_update_geometry (clutterimagesink, clutterimagesink->xwindow);
+    dst.w = clutterimagesink->xwindow->width;
+    dst.h = clutterimagesink->xwindow->height;
+#endif
+
+    g_mutex_unlock (clutterimagesink->flow_lock);
+    
+    if (clutterimagesink->keep_aspect) 
+      {
+       GST_LOG_OBJECT (clutterimagesink, 
+                       "enforcing aspect ratio in reverse caps "
+                       "negotiation");
+       gst_video_sink_center_rect (src, dst, &result, TRUE);
+      } 
+    else 
+      {
+       GST_LOG_OBJECT (clutterimagesink, 
+                       "trying to resize to window geometry "
+                       "ignoring aspect ratio");
+       result.x = result.y = 0;
+       result.w = dst.w;
+       result.h = dst.h;
+      }
+
+    /* We would like another geometry */
+    if (width != result.w || height != result.h) 
+      {
+       int     nom, den;
+       GstPad *peer;
+
+       peer = gst_pad_get_peer (GST_VIDEO_SINK_PAD (clutterimagesink));
+
+      if (!GST_IS_PAD (peer)) 
+        goto alloc;
+
+      GST_DEBUG ("we would love to receive a %dx%d video", result.w, result.h);
+
+      gst_structure_set (structure, "width", G_TYPE_INT, result.w, NULL);
+      gst_structure_set (structure, "height", G_TYPE_INT, result.h, NULL);
+
+      /* PAR property overrides the X calculated one */
+      if (clutterimagesink->par) 
+       {
+         nom = gst_value_get_fraction_numerator (clutterimagesink->par);
+         den = gst_value_get_fraction_denominator (clutterimagesink->par);
+         gst_structure_set (structure, "pixel-aspect-ratio",
+                            GST_TYPE_FRACTION, nom, den, NULL);
+       } 
+      else if (clutterimagesink->context->par) 
+       {
+         nom = gst_value_get_fraction_numerator (clutterimagesink->context->par);
+         den = gst_value_get_fraction_denominator (clutterimagesink->context->par);
+         gst_structure_set (structure, "pixel-aspect-ratio",
+                            GST_TYPE_FRACTION, nom, den, NULL);
+       }
+
+      if (gst_pad_accept_caps (peer, desired_caps)) 
+       {
+         gint bpp;
+
+         bpp      = size / height / width;
+         rev_nego = TRUE;
+         width    = result.w;
+         height   = result.h;
+         size     = bpp * width * height;
+
+         GST_DEBUG ("peed pad accepts our desired caps %" GST_PTR_FORMAT
+                    " buffer size is now %d bytes", desired_caps, size);
+       } 
+      else 
+       {
+         GST_DEBUG ("peer pad does not accept our desired caps %" GST_PTR_FORMAT,
+                    desired_caps);
+         rev_nego = FALSE;
+         width  = GST_VIDEO_SINK_WIDTH (clutterimagesink);
+         height = GST_VIDEO_SINK_HEIGHT (clutterimagesink);
+      }
+      gst_object_unref (peer);
+      }
+    }
+  
+ alloc:
+  /* Inspect our buffer pool */
+  g_mutex_lock (clutterimagesink->pool_lock);
+  while (clutterimagesink->buffer_pool) 
+    {
+      clutterimage = (GstClutterImageBuffer *) clutterimagesink->buffer_pool->data;
+
+      if (clutterimage) 
+       {
+         /* Removing from the pool */
+         clutterimagesink->buffer_pool 
+           = g_slist_delete_link (clutterimagesink->buffer_pool,
+                                  clutterimagesink->buffer_pool);
+
+         /* If the clutterimage is invalid for our need, destroy */
+         if ((clutterimage->width != width) 
+             || (clutterimage->height != height)) 
+           {
+             gst_clutterimage_buffer_free (clutterimage);
+             clutterimage = NULL;
+           } 
+         else 
+           {
+             /* We found a suitable clutterimage */
+             break;
+           }
+       }
+    }
+  g_mutex_unlock (clutterimagesink->pool_lock);
+
+  /* We haven't found anything, creating a new one */
+  if (!clutterimage) 
+    {
+      if (rev_nego)
+       clutterimage = gst_clutterimagesink_clutterimage_new (clutterimagesink,
+                                                             desired_caps);
+      else 
+       clutterimage = gst_clutterimagesink_clutterimage_new (clutterimagesink,
+                                                             caps);
+    }
+
+  /* Now we should have a clutterimage, set appropriate caps on it */
+  if (clutterimage) 
+    {
+      if (rev_nego) 
+       gst_buffer_set_caps (GST_BUFFER (clutterimage), desired_caps);
+      else 
+       gst_buffer_set_caps (GST_BUFFER (clutterimage), caps);
+    }
+
+  gst_caps_unref (desired_caps);
+  
+  *buf = GST_BUFFER (clutterimage);
+  
+  return ret;
+}
+
+/* Interfaces stuff - probably non working clutter */
+
+static gboolean
+gst_clutterimagesink_interface_supported (GstImplementsInterface *iface, 
+                                         GType                   type)
+{
+  g_assert (type == GST_TYPE_NAVIGATION);
+  return TRUE;
+}
+
+static void
+gst_clutterimagesink_interface_init (GstImplementsInterfaceClass *klass)
+{
+  klass->supported = gst_clutterimagesink_interface_supported;
+}
+
+static void
+gst_clutterimagesink_navigation_send_event (GstNavigation *navigation,
+                                           GstStructure  *structure)
+{
+  GstClutterImageSink *clutterimagesink = GST_CLUTTERIMAGESINK (navigation);
+  GstEvent            *event;
+  gint                 x_offset, y_offset;
+  gdouble              x, y;
+  GstPad              *pad = NULL;
+
+  event = gst_event_new_navigation (structure);
+
+  /* We are not converting the pointer coordinates as there's no hardware
+     scaling done here. The only possible scaling is done by videoscale and
+     videoscale will have to catch those events and tranform the coordinates
+     to match the applied scaling. So here we just add the offset if the image
+     is centered in the window.  */
+
+  /* We take the flow_lock while we look at the window */
+  g_mutex_lock (clutterimagesink->flow_lock);
+
+  x_offset = 0;
+  y_offset = 0;
+
+  g_mutex_unlock (clutterimagesink->flow_lock);
+
+  if (gst_structure_get_double (structure, "pointer_x", &x)) 
+    {
+      x -= x_offset / 2;
+      gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL);
+    }
+
+  if (gst_structure_get_double (structure, "pointer_y", &y)) 
+    {
+      y -= y_offset / 2;
+      gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
+    }
+
+  pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (clutterimagesink));
+
+  if (GST_IS_PAD (pad) && GST_IS_EVENT (event)) {
+    gst_pad_send_event (pad, event);
+    
+    gst_object_unref (pad);
+  }
+}
+
+static void
+gst_clutterimagesink_navigation_init (GstNavigationInterface *iface)
+{
+  iface->send_event = gst_clutterimagesink_navigation_send_event;
+}
+
+
+/* =========================================== */
+/*                                             */
+/*              Init & Class init              */
+/*                                             */
+/* =========================================== */
+
+static void
+gst_clutterimagesink_set_property (GObject      *object, 
+                                  guint         prop_id,
+                                  const GValue *value, 
+                                  GParamSpec   *pspec)
+{
+  GstClutterImageSink *clutterimagesink;
+
+  g_return_if_fail (GST_IS_CLUTTERIMAGESINK (object));
+
+  clutterimagesink = GST_CLUTTERIMAGESINK (object);
+
+  switch (prop_id) 
+    {
+    case PROP_VIDEO_TEXTURE:
+      clutterimagesink->video_texture = g_value_get_pointer (value);
+      break;
+    case PROP_FORCE_ASPECT_RATIO:
+      clutterimagesink->keep_aspect = g_value_get_boolean (value);
+      break;
+    case PROP_PIXEL_ASPECT_RATIO:
+      {
+       GValue *tmp;
+       
+       tmp = g_new0 (GValue, 1);
+       g_value_init (tmp, GST_TYPE_FRACTION);
+       
+       if (!g_value_transform (value, tmp)) 
+         {
+           GST_WARNING_OBJECT (clutterimagesink,
+                               "Could not transform string to aspect ratio");
+           g_free (tmp);
+         } 
+       else 
+         {
+           GST_DEBUG_OBJECT (clutterimagesink, "set PAR to %d/%d",
+                             gst_value_get_fraction_numerator (tmp),
+                             gst_value_get_fraction_denominator (tmp));
+           g_free (clutterimagesink->par);
+           clutterimagesink->par = tmp;
+         }
+      }
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gst_clutterimagesink_get_property (GObject    *object, 
+                                  guint       prop_id,
+                                  GValue     *value, 
+                                  GParamSpec *pspec)
+{
+  GstClutterImageSink *clutterimagesink;
+
+  g_return_if_fail (GST_IS_CLUTTERIMAGESINK (object));
+
+  clutterimagesink = GST_CLUTTERIMAGESINK (object);
+
+  switch (prop_id) 
+    {
+    case PROP_VIDEO_TEXTURE:
+      g_value_set_pointer (value, clutterimagesink->video_texture);
+      break;
+    case PROP_FORCE_ASPECT_RATIO:
+      g_value_set_boolean (value, clutterimagesink->keep_aspect);
+      break;
+    case PROP_PIXEL_ASPECT_RATIO:
+      if (clutterimagesink->par)
+        g_value_transform (clutterimagesink->par, value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gst_clutterimagesink_finalize (GObject * object)
+{
+  GstClutterImageSink *clutterimagesink;
+
+  clutterimagesink = GST_CLUTTERIMAGESINK (object);
+
+  if (clutterimagesink->display_name) 
+    {
+      g_free (clutterimagesink->display_name);
+      clutterimagesink->display_name = NULL;
+    }
+
+  if (clutterimagesink->par) 
+    {
+      g_free (clutterimagesink->par);
+      clutterimagesink->par = NULL;
+    }
+
+  if (clutterimagesink->x_lock) 
+    {
+      g_mutex_free (clutterimagesink->x_lock);
+      clutterimagesink->x_lock = NULL;
+    }
+
+  if (clutterimagesink->flow_lock) 
+    {
+      g_mutex_free (clutterimagesink->flow_lock);
+      clutterimagesink->flow_lock = NULL;
+    }
+
+  if (clutterimagesink->pool_lock) 
+    {
+      g_mutex_free (clutterimagesink->pool_lock);
+      clutterimagesink->pool_lock = NULL;
+    }
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_clutterimagesink_init (GstClutterImageSink * clutterimagesink)
+{
+  clutterimagesink->display_name = NULL;
+  clutterimagesink->context  = NULL;
+  clutterimagesink->clutterimage = NULL;
+  clutterimagesink->cur_image = NULL;
+
+  clutterimagesink->event_thread = NULL;
+  clutterimagesink->running = FALSE;
+
+  clutterimagesink->fps_n = 0;
+  clutterimagesink->fps_d = 1;
+
+  clutterimagesink->x_lock    = g_mutex_new ();
+  clutterimagesink->flow_lock = g_mutex_new ();
+
+  clutterimagesink->par       = NULL;
+
+  clutterimagesink->pool_lock = g_mutex_new ();
+  clutterimagesink->buffer_pool = NULL;
+
+  clutterimagesink->keep_aspect = FALSE;
+}
+
+static void
+gst_clutterimagesink_base_init (gpointer g_class)
+{
+  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+
+  gst_element_class_set_details (element_class, &gst_clutterimagesink_details);
+
+  gst_element_class_add_pad_template (element_class,
+    gst_static_pad_template_get (&gst_clutterimagesink_sink_template_factory));
+}
+
+static void
+gst_clutterimagesink_class_init (GstClutterImageSinkClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+  GstBaseSinkClass *gstbasesink_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+  gstbasesink_class = (GstBaseSinkClass *) klass;
+
+  parent_class = g_type_class_ref (GST_TYPE_VIDEO_SINK);
+
+  gobject_class->finalize = gst_clutterimagesink_finalize;
+  gobject_class->set_property = gst_clutterimagesink_set_property;
+  gobject_class->get_property = gst_clutterimagesink_get_property;
+
+  g_object_class_install_property (gobject_class, PROP_VIDEO_TEXTURE,
+                                  g_param_spec_pointer ("video-texture", 
+                                                       "Video-Texture", 
+                                                       "Video Texture",
+                                                       G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO,
+                                  g_param_spec_boolean ("force-aspect-ratio",
+                                                        "Force aspect ratio",
+            "When enabled, reverse caps negotiation (scaling) will respect "
+                                                   "original aspect ratio", 
+                                                        FALSE, 
+                                                        G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_PIXEL_ASPECT_RATIO,
+                                  g_param_spec_string ("pixel-aspect-ratio", 
+                                                       "Pixel Aspect Ratio",
+                                                       "The pixel aspect ratio of the device", 
+                                                       "1/1", 
+                                                       G_PARAM_READWRITE));
+
+  gstelement_class->change_state = gst_clutterimagesink_change_state;
+
+  gstbasesink_class->get_caps 
+    = GST_DEBUG_FUNCPTR (gst_clutterimagesink_getcaps);
+
+  gstbasesink_class->set_caps 
+    = GST_DEBUG_FUNCPTR (gst_clutterimagesink_setcaps);
+
+  gstbasesink_class->buffer_alloc =
+      GST_DEBUG_FUNCPTR (gst_clutterimagesink_buffer_alloc);
+
+  gstbasesink_class->get_times 
+    = GST_DEBUG_FUNCPTR (gst_clutterimagesink_get_times);
+
+  gstbasesink_class->preroll 
+    = GST_DEBUG_FUNCPTR (gst_clutterimagesink_show_frame);
+
+  gstbasesink_class->render 
+    = GST_DEBUG_FUNCPTR (gst_clutterimagesink_show_frame);
+}
+
+/* ============================================================= */
+/*                                                               */
+/*                       Public Methods                          */
+/*                                                               */
+/* ============================================================= */
+
+/* =========================================== */
+/*                                             */
+/*          Object typing & Creation           */
+/*                                             */
+/* =========================================== */
+
+GType
+gst_clutterimagesink_get_type (void)
+{
+  static GType clutterimagesink_type = 0;
+
+  if (!clutterimagesink_type) {
+    static const GTypeInfo clutterimagesink_info = {
+      sizeof (GstClutterImageSinkClass),
+      gst_clutterimagesink_base_init,
+      NULL,
+      (GClassInitFunc) gst_clutterimagesink_class_init,
+      NULL,
+      NULL,
+      sizeof (GstClutterImageSink),
+      0,
+      (GInstanceInitFunc) gst_clutterimagesink_init,
+    };
+    static const GInterfaceInfo iface_info = {
+      (GInterfaceInitFunc) gst_clutterimagesink_interface_init,
+      NULL,
+      NULL,
+    };
+    static const GInterfaceInfo navigation_info = {
+      (GInterfaceInitFunc) gst_clutterimagesink_navigation_init,
+      NULL,
+      NULL,
+    };
+    clutterimagesink_type 
+      = g_type_register_static (GST_TYPE_VIDEO_SINK,
+                               "GstClutterImageSink", 
+                               &clutterimagesink_info, 0);
+
+    g_type_add_interface_static (clutterimagesink_type, 
+                                GST_TYPE_IMPLEMENTS_INTERFACE,
+                                &iface_info);
+
+    g_type_add_interface_static (clutterimagesink_type, 
+                                GST_TYPE_NAVIGATION,
+                                &navigation_info);
+  }
+  
+  return clutterimagesink_type;
+}
+
+GST_DEBUG_CATEGORY (gst_debug_clutterimagesink);
+
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+  if (!gst_element_register (plugin, "clutterimagesink",
+          GST_RANK_SECONDARY, GST_TYPE_CLUTTERIMAGESINK))
+    return FALSE;
+
+  GST_DEBUG_CATEGORY_INIT (gst_debug_clutterimagesink, "clutterimagesink", 0,
+      "clutterimagesink element");
+
+  return TRUE;
+}
+
+#define GST_LICENSE "LGPL"
+#define GST_PACKAGE "GStreamer"
+#define GST_ORIGIN  "http://o-hand.com"
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+    GST_VERSION_MINOR,
+    "clutterimagesink",
+    "Clutter Video Sink",
+    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)
diff --git a/gst/clutterimagesink.h b/gst/clutterimagesink.h
new file mode 100644 (file)
index 0000000..3efbf29
--- /dev/null
@@ -0,0 +1,122 @@
+/* GStreamer
+ * Copyright (C) <2005> Julien Moutte <julien@moutte.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_CLUTTERIMAGESINK_H__
+#define __GST_CLUTTERIMAGESINK_H__
+
+#include <gst/video/gstvideosink.h>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include <clutter/clutter.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include <string.h>
+#include <math.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_CLUTTERIMAGESINK \
+  (gst_clutterimagesink_get_type())
+#define GST_CLUTTERIMAGESINK(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_CLUTTERIMAGESINK, GstClutterImageSink))
+#define GST_CLUTTERIMAGESINK_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_CLUTTERIMAGESINK, GstClutterImageSink))
+#define GST_IS_CLUTTERIMAGESINK(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_CLUTTERIMAGESINK))
+#define GST_IS_CLUTTERIMAGESINK_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_CLUTTERIMAGESINK))
+
+typedef struct _GstClutterContext GstClutterContext;
+typedef struct _GstXWindow GstXWindow;
+
+typedef struct _GstClutterImageBuffer GstClutterImageBuffer;
+typedef struct _GstClutterImageBufferClass GstClutterImageBufferClass;
+
+typedef struct _GstClutterImageSink GstClutterImageSink;
+typedef struct _GstClutterImageSinkClass GstClutterImageSinkClass;
+
+struct _GstClutterContext 
+{
+  Display *disp;
+  Screen  *screen;
+  gint     screen_num;
+  gint width, height;
+  gint widthmm, heightmm;
+  GValue *par;                  /* calculated pixel aspect ratio */
+  GstCaps *caps;
+};
+
+struct _GstClutterImageBuffer 
+{
+  GstBuffer buffer;
+
+  /* Reference to the clutterimagesink we belong to */
+  GstClutterImageSink *clutterimagesink;
+
+  GdkPixbuf *clutterimage;     /* FIXME: Rename */
+
+  gint width, height;
+  size_t size;
+};
+
+struct _GstClutterImageSink 
+{
+  /* Our element stuff */
+  GstVideoSink videosink;
+
+  char *display_name;
+
+  GstClutterContext     *context;
+  GstClutterImageBuffer *clutterimage;
+  GstClutterImageBuffer *cur_image;
+  
+  GThread               *event_thread;
+  gboolean running;
+
+  /* Framerate numerator and denominator */
+  gint                   fps_n;
+  gint                   fps_d;
+
+  /* object-set pixel aspect ratio */
+  GValue                 *par;
+
+  GMutex                 *x_lock; /* FIXME: rename */
+  GMutex                 *flow_lock;
+  
+  GMutex                 *pool_lock;
+  GSList                 *buffer_pool;
+
+  ClutterVideoTexture    *video_texture;
+
+  gboolean                synchronous;
+  gboolean                keep_aspect;
+};
+
+struct _GstClutterImageSinkClass {
+  GstVideoSinkClass parent_class;
+};
+
+GType gst_clutterimagesink_get_type(void);
+
+G_END_DECLS
+
+#endif /* __GST_CLUTTERIMAGESINK_H__ */