Merge gobject-branch into trunk

This commit is contained in:
Matthew Allum 2006-05-29 08:59:36 +00:00
parent c936f265b0
commit 342ea125f1
123 changed files with 30673 additions and 8360 deletions

504
COPYING Normal file
View File

@ -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.
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.
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.
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.
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.
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.
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.
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.
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
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!

990
ChangeLog
View File

@ -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> 2005-05-27 mallum,,, <mallum@openedhand.com>
* clutter/cltr-animator.c: (cltr_animator_zoom_new), * clutter/cltr-animator.c: (cltr_animator_zoom_new),

View File

@ -1 +1,20 @@
SUBDIRS=clutter gst examples 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

14
README
View File

@ -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

39
TODO Normal file
View File

@ -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 ?

View File

@ -1,3 +1,4 @@
#! /bin/sh #! /bin/sh
gtkdocize || exit 1
autoreconf -v --install || exit 1 autoreconf -v --install || exit 1
./configure --enable-maintainer-mode "$@" ./configure --enable-maintainer-mode "$@"

55
bindings/ChangeLog Normal file
View File

@ -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.

5
bindings/Makefile.am Normal file
View File

@ -0,0 +1,5 @@
SUBDIRS =
if ENABLE_PYTHON
SUBDIRS += python
endif

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

View File

@ -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);
}

11
clutter.pc.in Normal file
View File

@ -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

View File

@ -1,46 +1,101 @@
source_h = pixbuf.h util.h fonts.h \ MARSHALFILES = clutter-marshal.c clutter-marshal.h
cltr.h \ ENUMFILES = clutter-enum-types.c clutter-enum-types.h
cltr-private.h \ GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0`
cltr-glu.h \ GLIB_MKENUMS=`pkg-config --variable=glib_mkenums glib-2.0`
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 \ BUILT_SOURCES = $(MARSHALFILES) $(ENUMFILES)
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) 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
lib_LTLIBRARIES = libclutter.la clutter-marshal.h: clutter-marshal.list
libclutter_la_SOURCES = $(source_c) $(source_h) ( $(GLIB_GENMARSHAL) --prefix=clutter_marshal $(srcdir)/clutter-marshal.list --header > clutter-marshal.h )
libclutter_la_LIBADD = @CLTR_LIBS@ $(GST_LIBS) $(GCONF_LIBS)
# http://sources.redhat.com/autobook/autobook/autobook_91.html#SEC91 clutter-marshal.c: clutter-marshal.h
# current : revision : age ( $(GLIB_GENMARSHAL) --prefix=clutter_marshal $(srcdir)/clutter-marshal.list --body --header > clutter-marshal.c )
libclutter_la_LDFLAGS = -version-info 0:0:0 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)
clutterheadersdir = $(includedir)/clutter clutter-enum-types.c: clutter-enum-types.h
clutterheaders_DATA = $(source_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

View File

@ -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);
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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];
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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();
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

61
clutter/clutter-color.c Normal file
View File

@ -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);
}

64
clutter/clutter-color.h Normal file
View File

@ -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

1285
clutter/clutter-element.c Normal file

File diff suppressed because it is too large Load Diff

261
clutter/clutter-element.h Normal file
View File

@ -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

990
clutter/clutter-event.c Normal file
View File

@ -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;
}

126
clutter/clutter-event.h Normal file
View File

@ -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

481
clutter/clutter-group.c Normal file
View File

@ -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);
}

130
clutter/clutter-group.h Normal file
View File

@ -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

1374
clutter/clutter-keysyms.h Normal file

File diff suppressed because it is too large Load Diff

419
clutter/clutter-label.c Normal file
View File

@ -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));
}

104
clutter/clutter-label.h Normal file
View File

@ -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

403
clutter/clutter-main.c Normal file
View File

@ -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;
}

96
clutter/clutter-main.h Normal file
View File

@ -0,0 +1,96 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
*
* Copyright (C) 2006 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, 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

View File

@ -0,0 +1,4 @@
VOID:INT64,INT64,FLOAT,BOOLEAN
VOID:STRING,BOOLEAN,BOOLEAN
VOID:INT,INT

65
clutter/clutter-private.h Normal file
View File

@ -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

185
clutter/clutter-rectangle.c Normal file
View File

@ -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);
}

View File

@ -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

620
clutter/clutter-stage.c Normal file
View File

@ -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;
}

110
clutter/clutter-stage.h Normal file
View File

@ -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

1216
clutter/clutter-texture.c Normal file

File diff suppressed because it is too large Load Diff

127
clutter/clutter-texture.h Normal file
View File

@ -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

482
clutter/clutter-timeline.c Normal file
View File

@ -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);
}

112
clutter/clutter-timeline.h Normal file
View File

@ -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

55
clutter/clutter-util.c Normal file
View File

@ -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

41
clutter/clutter-util.h Normal file
View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

20
clutter/clutter.h Normal file
View File

@ -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

View File

@ -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);
}
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -1,11 +1,39 @@
AC_PREREQ(2.53) 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_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. # Checks for programs.
AC_PROG_CC AC_PROG_CC
AC_PROG_LIBTOOL AC_PROG_LIBTOOL
@ -22,12 +50,13 @@ AC_FUNC_MALLOC
AC_FUNC_MMAP AC_FUNC_MMAP
AC_CHECK_FUNCS([memset munmap strcasecmp strdup]) AC_CHECK_FUNCS([memset munmap strcasecmp strdup])
dnl ------ X + GL -------------------------------------------------------------
dnl ========================================================================
# FIXME: redo below
AC_PATH_XTRA AC_PATH_XTRA
# below is broken
if test "x$have_x" = "xyes"; then if test "x$have_x" = "xyes"; then
GLX_LIBS="$X_LIBS -lX11 -lGL" GLX_LIBS="$X_LIBS -lX11 -lGL"
GLX_CFLAGS="$X_CFLAGS" GLX_CFLAGS="$X_CFLAGS"
@ -59,72 +88,106 @@ else
AC_MSG_ERROR([*** Cannot find X + GL ****]) AC_MSG_ERROR([*** Cannot find X + GL ****])
fi fi
dnl ----- Pango, glib etc --------------------------------------------------- dnl ========================================================================
pkg_modules="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(CLTR, pangoft2 glib-2.0 gthread-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" GST_MAJORMINOR=0.10
pkg_modules="gstreamer-$GST_MAJORMINOR gstreamer-plugins-base-$GST_MAJORMINOR"
PKG_CHECK_MODULES(GST, [$pkg_modules]) PKG_CHECK_MODULES(GST, [$pkg_modules])
dnl ----- Gconf ------------------------------------------------------------- GST_LIBS="$GST_LIBS -lgstinterfaces-$GST_MAJORMINOR -lgstvideo-$GST_MAJORMINOR -lgstaudio-$GST_MAJORMINOR"
PKG_CHECK_MODULES(GCONF, gconf-2.0, HAVE_GCONF="yes", HAVE_GCONF="no") dnl ========================================================================
dnl ------ Check for PNG ---------------------------------------------------
AC_MSG_CHECKING(for libpng12)
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
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 ****])
fi
dnl ----- GCC ---------------------------------------------------------------
if test "x$GCC" = "xyes"; then if test "x$GCC" = "xyes"; then
GCC_FLAGS="-g -Wall" GCC_FLAGS="-g -Wall"
fi fi
AC_SUBST(GCC_FLAGS) 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)
AM_CONDITIONAL(ENABLE_PYTHON, test x$enable_python = xyes)
dnl ========================================================================
AC_SUBST(GCC_FLAGS)
AC_SUBST(GST_CFLAGS) AC_SUBST(GST_CFLAGS)
AC_SUBST(GST_LIBS) AC_SUBST(GST_LIBS)
AC_SUBST(GCONF_CFLAGS) CLUTTER_CFLAGS="$GLX_CLAGS $CLUTTER_CFLAGS"
AC_SUBST(GCONF_LIBS) CLUTTER_LIBS="$GLX_LIBS $CLUTTER_LIBS"
CLTR_CFLAGS="$GLX_CLAGS $CLTR_CFLAGS" AC_SUBST(CLUTTER_CFLAGS)
CLTR_LIBS="$GLX_LIBS $PNG_LIBS $JPEG_LIBS $CLTR_LIBS" AC_SUBST(CLUTTER_LIBS)
AC_SUBST(CLTR_CFLAGS)
AC_SUBST(CLTR_LIBS)
AC_OUTPUT([Makefile AC_OUTPUT([Makefile
clutter/Makefile clutter/Makefile
bindings/Makefile
bindings/python/Makefile
examples/Makefile examples/Makefile
gst/Makefile doc/Makefile
doc/reference/Makefile
clutter.pc
]) ])

1
doc/Makefile.am Normal file
View File

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

19
doc/reference/ChangeLog Normal file
View File

@ -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.

78
doc/reference/Makefile.am Normal file
View File

@ -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 +=

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -0,0 +1,12 @@
<!-- ##### STRUCT ClutterElementPrivate ##### -->
<para>
</para>
<!-- ##### STRUCT ClutterLabelPrivate ##### -->
<para>
</para>

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

File diff suppressed because it is too large Load Diff

View File

@ -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:

View File

@ -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>

View File

@ -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:

View File

@ -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:

View File

@ -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:

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