diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..b1e3f5a26 --- /dev/null +++ b/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + 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. + + + Copyright (C) + + This library is free software; you can redistribute it 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. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/ChangeLog b/ChangeLog index aab1f431b..cb87c31d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,993 @@ +2006-05-29 Matthew Allum + + * 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 + + * 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 + + * 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 + + 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 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 header. + +2006-05-25 Matthew Allum + + * 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 + + * clutter.pc.in: + Fix prefix snafu via Ross. + +2006-05-24 Matthew Allum + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + reviewed by: + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * TODO: + Update + * clutter/clutter-element.h: + * clutter/clutter-rectangle.h: + Minor formatting cleanups + +2006-05-02 Matthew Allum + + * clutter/Makefile.am: + * clutter/clutter-timeline.c: + * clutter/clutter-timeline.h: + Add initial timeline implementation + +2006-05-02 Matthew Allum + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * clutter/clutter-marshal.list: + Add missing. + +2006-04-17 Matthew Allum + + * 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 + + * TODO: + * doc/clutter.types: + * doc/reference/Makefile.am: + Move gtk-doc gubbins to doc/reference + +2006-04-16 Matthew Allum + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + reviewed by: + + * 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 + + * 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,,, * clutter/cltr-animator.c: (cltr_animator_zoom_new), diff --git a/Makefile.am b/Makefile.am index 5a09d1b6d..5f19271de 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1 +1,20 @@ -SUBDIRS=clutter gst examples \ No newline at end of file +SUBDIRS=clutter bindings doc examples + +pcfiles = clutter-@CLUTTER_MAJORMINOR@.pc + +%-@CLUTTER_MAJORMINOR@.pc: %.pc + cp $< $@ + +pkgconfig_DATA = $(pcfiles) +pkgconfigdir = $(libdir)/pkgconfig + +EXTRA_DIST = clutter.pc.in + +CLEANFILES = $(pcfiles) + +DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = aclocal.m4 compile config.guess config.sub \ + configure depcomp install-sh ltmain.sh \ + Makefile.in missing config.h.in \ No newline at end of file diff --git a/README b/README index e69de29bb..54d37132f 100644 --- a/README +++ b/README @@ -0,0 +1,14 @@ + + +What it will do: + + - Give a nice easy GObject based API for creating fast, mainly 2D + single window stylalised applications such as media box UI's, + presentaions, kiosk style apps etc. + + - If you've ever used Director, thats the kind of functionality, + clutter aims for. + +What it wont do: + + - Provide a general interface to all openGL functionality diff --git a/TODO b/TODO new file mode 100644 index 000000000..c557c3d51 --- /dev/null +++ b/TODO @@ -0,0 +1,39 @@ +TODO +==== + +- Element + o depth and z positioning ? + o can glscale -1 for mirroring / flipping, or just use rotation ? + +- Stage + o Events - mouse + +- Texture + o display lists ? + +- Rect + o rounded + o gradients ( or add to elements ? ) + o general polygon handler ? + +- Video Texture + o complete API from bacon-video-widget *Mostly done* + o Work with pixel aspect and use this info to size element correctly ? + o mostly rewrite or check with orig author for LGPL. + +- Group + o apply tranforms to group of elements + o scissor to clip + o sizing ? how does set/get_geometry affect ? + o stacking orders with 'depth' value. + +- GST + o Fix FIXME's + o Remove and use fake sinc instead + +- Audio api for sound effects etc + +- Document, Document, Document! + o fix GTK Doc set up with index, grouping etc + +- Glitz integration ? \ No newline at end of file diff --git a/bootstrap-autotools.sh b/autogen.sh similarity index 81% rename from bootstrap-autotools.sh rename to autogen.sh index b1376df5a..aecfb84ce 100755 --- a/bootstrap-autotools.sh +++ b/autogen.sh @@ -1,3 +1,4 @@ #! /bin/sh +gtkdocize || exit 1 autoreconf -v --install || exit 1 ./configure --enable-maintainer-mode "$@" diff --git a/bindings/ChangeLog b/bindings/ChangeLog new file mode 100644 index 000000000..22062c5ef --- /dev/null +++ b/bindings/ChangeLog @@ -0,0 +1,55 @@ +2006-05-27 Emmanuele Bassi + + * 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 + + 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 + + * python/clutter-base.defs: + * python/clutter-base-types.defs: + * python/clutter.override: Fix ClutterGeometry bindings; + implement ClutterElementBox bindings. + + * python/Makefile.am: Use variables instead of hard-coded + file names. + diff --git a/bindings/Makefile.am b/bindings/Makefile.am new file mode 100644 index 000000000..0f4745056 --- /dev/null +++ b/bindings/Makefile.am @@ -0,0 +1,5 @@ +SUBDIRS = + +if ENABLE_PYTHON +SUBDIRS += python +endif diff --git a/bindings/python/Makefile.am b/bindings/python/Makefile.am new file mode 100644 index 000000000..13437663f --- /dev/null +++ b/bindings/python/Makefile.am @@ -0,0 +1,91 @@ +AUTOMAKE_OPTIONS = 1.7 + +CLEANFILES = +EXTRA_DIST = + +CLUTTER_DEFS = clutter-base.defs +CLUTTER_TYPES_DEFS = clutter-base-types.defs + +CREATEDEFS = $(PYTHON) createdefs.py + +CLUTTER_OVERRIDES = clutter.override + +CLEANFILES += \ + clutter.defs \ + clutter-types.defs + +EXTRA_DIST += \ + $(CLUTTER_DEFS) \ + $(CLUTTER_TYPES_DEFS) \ + $(CLUTTER_OVERRIDES) + +clutter.defs: $(CLUTTER_DEFS) + @echo "*** Creating clutter.defs" && \ + echo ";; -*- scheme -*-" > gen-cdefs && \ + echo ";; THIS FILE IS AUTOGENERATED" >> gen-cdefs && \ + for p in $(CLUTTER_DEFS); do \ + echo "(include \"$$p\")" >> gen-cdefs; \ + done && \ + (cmp -s gen-cdefs clutter.defs || cp gen-cdefs clutter.defs) && \ + rm -f gen-cdefs +clutter.defs: Makefile + +clutter-types.defs: $(CLUTTER_TYPES_DEFS) + @echo "*** Creating clutter-types.defs" && \ + echo ";; -*- scheme -*-" > gen-ctdefs && \ + echo ";; THIS FILE IS AUTOGENERATED" >> gen-ctdefs && \ + for p in $(CLUTTER_TYPES_DEFS); do \ + echo "(include \"$$p\")" >> gen-ctdefs; \ + done && \ + (cmp -s gen-ctdefs clutter-types.defs || cp gen-ctdefs clutter-types.defs) && \ + rm -f gen-ctdefs +clutter-types.defs: Makefile + +clutter-pyglue.c: clutter.defs clutter-types.defs $(CLUTTER_OVERRIDES) + $(PYGTK_CODEGEN) \ + --register $(PYGTK_DEFSDIR)/gdk-types.defs \ + --register $(PYGTK_DEFSDIR)/gtk-types.defs \ + --register $(PYGTK_DEFSDIR)/pango-types.defs \ + --register clutter-types.defs \ + --override $(CLUTTER_OVERRIDES) \ + --prefix clutter \ + clutter.defs > gen-$@ && \ + (cmp -s $@ gen-$@ || cp gen-$@ $@) && \ + rm -f gen-$@ + +CLEANFILES += clutter-pyglue.c + +pythondir = $(libdir)/python${PY_VER}/site-packages +python_LTLIBRARIES = clutter.la + +INCLUDES = $(PYTHON_CFLAGS) $(PYGTK_CFLAGS) -I$(top_srcdir) $(CLUTTER_CFLAGS) + +clutter_la_DEPENDENCIES = cluttermodule.c clutter-pyglue.c +clutter_la_SOURCES = clutter-pyglue.c cluttermodule.c +clutter_la_LIBADD = $(PYTHON_LIBS) $(PYGTK_LIBS) \ + $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la +clutter_la_LDFLAGS = -module avoid-version -export-symbols-regex initclutter + +# Run this to update the API and then copy then newly generated +# definitions into clutter-base.defs and clutter-base-types.defs; +# it's manual, as my might do some name mangling for static +# methods. +update-defs: + $(PYTHON) $(PYGTK_CODEGENDIR)/h2def.py -v \ + $(top_srcdir)/clutter/clutter-keysyms.h \ + $(top_srcdir)/clutter/clutter-timeline.h \ + $(top_srcdir)/clutter/clutter-main.h \ + $(top_srcdir)/clutter/clutter-event.h \ + $(top_srcdir)/clutter/clutter-element.h \ + $(top_srcdir)/clutter/clutter-rectangle.h \ + $(top_srcdir)/clutter/clutter-texture.h \ + $(top_srcdir)/clutter/clutter-color.h \ + $(top_srcdir)/clutter/clutter-clone-texture.h \ + $(top_srcdir)/clutter/clutter-video-texture.h \ + $(top_srcdir)/clutter/clutter-label.h \ + $(top_srcdir)/clutter/clutter-group.h \ + $(top_srcdir)/clutter/clutter-stage.h \ + $(top_srcdir)/clutter/clutter-enum-types.h \ + > gen-cdefs && \ + (cmp -s gen-cdefs clutter-api.def || cp gen-cdefs clutter-api.def) && \ + rm -f gen-cdefs diff --git a/bindings/python/clutter-base-types.defs b/bindings/python/clutter-base-types.defs new file mode 100644 index 000000000..94e408dfb --- /dev/null +++ b/bindings/python/clutter-base-types.defs @@ -0,0 +1,207 @@ +;; -*- scheme -*- +;; +;; Try and keep everything sorted +;; + +;; Boxed types + +(define-boxed ElementBox + (in-module "Clutter") + (c-name "ClutterElementBox") + (gtype-id "CLUTTER_TYPE_ELEMENT_BOX") + (fields + '("gint" "x1") + '("gint" "y1") + '("gint" "x2") + '("gint" "y2") + ) +) + +(define-boxed Geometry + (in-module "Clutter") + (c-name "ClutterGeometry") + (gtype-id "CLUTTER_TYPE_GEOMETRY") + (fields + '("gint" "x") + '("gint" "y") + '("gint" "width") + '("gint" "height") + ) +) + +;; Enumerations and flags ... + +(define-flags ElementTransform + (in-module "Clutter") + (c-name "ClutterElementTransform") + (gtype-id "CLUTTER_TYPE_ELEMENT_TRANSFORM") + (values + '("x" "CLUTTER_ELEMENT_MIRROR_X") + '("y" "CLUTTER_ELEMENT_MIRROR_Y") + ) +) + +(define-flags ElementFlags + (in-module "Clutter") + (c-name "ClutterElementFlags") + (gtype-id "CLUTTER_TYPE_ELEMENT_FLAGS") + (values + '("mapped" "CLUTTER_ELEMENT_MAPPED") + '("realized" "CLUTTER_ELEMENT_REALIZED") + ) +) + +(define-enum EventType + (in-module "Clutter") + (c-name "ClutterEventType") + (gtype-id "CLUTTER_TYPE_EVENT_TYPE") + (values + '("key-press" "CLUTTER_KEY_PRESS") + '("key-release" "CLUTTER_KEY_RELEASE") + '("motion" "CLUTTER_MOTION") + '("button-press" "CLUTTER_BUTTON_PRESS") + '("2button-press" "CLUTTER_2BUTTON_PRESS") + '("button-release" "CLUTTER_BUTTON_RELEASE") + ) +) + +(define-enum VideoTextureAspectRatio + (in-module "Clutter") + (c-name "ClutterVideoTextureAspectRatio") + (gtype-id "CLUTTER_TYPE_VIDEO_TEXTURE_ASPECT_RATIO") + (values + '("auto" "CLUTTER_VIDEO_TEXTURE_AUTO") + '("square" "CLUTTER_VIDEO_TEXTURE_SQUARE") + '("fourbythree" "CLUTTER_VIDEO_TEXTURE_FOURBYTHREE") + '("anamorphic" "CLUTTER_VIDEO_TEXTURE_ANAMORPHIC") + '("dvb" "CLUTTER_VIDEO_TEXTURE_DVB") + ) +) + +(define-enum VideoTextureError + (in-module "Clutter") + (c-name "ClutterVideoTextureError") + (gtype-id "CLUTTER_TYPE_VIDEO_TEXTURE_ERROR") + (values + '("audio-plugin" "CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_PLUGIN") + '("no-plugin-for-file" "CLUTTER_VIDEO_TEXTURE_ERROR_NO_PLUGIN_FOR_FILE") + '("video-plugin" "CLUTTER_VIDEO_TEXTURE_ERROR_VIDEO_PLUGIN") + '("audio-busy" "CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_BUSY") + '("broken-file" "CLUTTER_VIDEO_TEXTURE_ERROR_BROKEN_FILE") + '("file-generic" "CLUTTER_VIDEO_TEXTURE_ERROR_FILE_GENERIC") + '("file-permission" "CLUTTER_VIDEO_TEXTURE_ERROR_FILE_PERMISSION") + '("file-encrypted" "CLUTTER_VIDEO_TEXTURE_ERROR_FILE_ENCRYPTED") + '("file-not-found" "CLUTTER_VIDEO_TEXTURE_ERROR_FILE_NOT_FOUND") + '("dvd-encrypted" "CLUTTER_VIDEO_TEXTURE_ERROR_DVD_ENCRYPTED") + '("invalid-device" "CLUTTER_VIDEO_TEXTURE_ERROR_INVALID_DEVICE") + '("unknown-host" "CLUTTER_VIDEO_TEXTURE_ERROR_UNKNOWN_HOST") + '("network-unreachable" "CLUTTER_VIDEO_TEXTURE_ERROR_NETWORK_UNREACHABLE") + '("connection-refused" "CLUTTER_VIDEO_TEXTURE_ERROR_CONNECTION_REFUSED") + '("unvalid-location" "CLUTTER_VIDEO_TEXTURE_ERROR_UNVALID_LOCATION") + '("generic" "CLUTTER_VIDEO_TEXTURE_ERROR_GENERIC") + '("codec-not-handled" "CLUTTER_VIDEO_TEXTURE_ERROR_CODEC_NOT_HANDLED") + '("audio-only" "CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_ONLY") + '("cannot-capture" "CLUTTER_VIDEO_TEXTURE_ERROR_CANNOT_CAPTURE") + '("read-error" "CLUTTER_VIDEO_TEXTURE_ERROR_READ_ERROR") + '("plugin-load" "CLUTTER_VIDEO_TEXTURE_ERROR_PLUGIN_LOAD") + '("still-image" "CLUTTER_VIDEO_TEXTURE_ERROR_STILL_IMAGE") + '("empty-file" "CLUTTER_VIDEO_TEXTURE_ERROR_EMPTY_FILE") + ) +) + +(define-enum VideoTextureMetadataType + (in-module "Clutter") + (c-name "ClutterVideoTextureMetadataType") + (gtype-id "CLUTTER_TYPE_VIDEO_TEXTURE_METADATA_TYPE") + (values + '("title" "CLUTTER_INFO_TITLE") + '("artist" "CLUTTER_INFO_ARTIST") + '("year" "CLUTTER_INFO_YEAR") + '("album" "CLUTTER_INFO_ALBUM") + '("duration" "CLUTTER_INFO_DURATION") + '("track-number" "CLUTTER_INFO_TRACK_NUMBER") + '("has-video" "CLUTTER_INFO_HAS_VIDEO") + '("dimension-x" "CLUTTER_INFO_DIMENSION_X") + '("dimension-y" "CLUTTER_INFO_DIMENSION_Y") + '("video-bitrate" "CLUTTER_INFO_VIDEO_BITRATE") + '("video-codec" "CLUTTER_INFO_VIDEO_CODEC") + '("fps" "CLUTTER_INFO_FPS") + '("has-audio" "CLUTTER_INFO_HAS_AUDIO") + '("audio-bitrate" "CLUTTER_INFO_AUDIO_BITRATE") + '("audio-codec" "CLUTTER_INFO_AUDIO_CODEC") + ) +) + +;; Objects + +(define-object Element + (in-module "Clutter") + (parent "GObject") + (c-name "ClutterElement") + (gtype-id "CLUTTER_TYPE_ELEMENT") +) + +(define-object CloneTexture + (in-module "Clutter") + (parent "ClutterElement") + (c-name "ClutterCloneTexture") + (gtype-id "CLUTTER_TYPE_CLONE_TEXTURE") +) + +(define-object Group + (in-module "Clutter") + (parent "ClutterElement") + (c-name "ClutterGroup") + (gtype-id "CLUTTER_TYPE_GROUP") +) + +(define-object Rectangle + (in-module "Clutter") + (parent "ClutterElement") + (c-name "ClutterRectangle") + (gtype-id "CLUTTER_TYPE_RECTANGLE") +) + +(define-object Stage + (in-module "Clutter") + (parent "ClutterGroup") + (c-name "ClutterStage") + (gtype-id "CLUTTER_TYPE_STAGE") +) + +(define-object Texture + (in-module "Clutter") + (parent "ClutterElement") + (c-name "ClutterTexture") + (gtype-id "CLUTTER_TYPE_TEXTURE") +) + +(define-object Label + (in-module "Clutter") + (parent "ClutterTexture") + (c-name "ClutterLabel") + (gtype-id "CLUTTER_TYPE_LABEL") +) + +(define-object Timeline + (in-module "Clutter") + (parent "GObject") + (c-name "ClutterTimeline") + (gtype-id "CLUTTER_TYPE_TIMELINE") +) + +(define-object VideoTexture + (in-module "Clutter") + (parent "ClutterTexture") + (c-name "ClutterVideoTexture") + (gtype-id "CLUTTER_TYPE_VIDEO_TEXTURE") +) + +;; Pointers + + + +;; Unsupported + + + diff --git a/bindings/python/clutter-base.defs b/bindings/python/clutter-base.defs new file mode 100644 index 000000000..79f5bfbb4 --- /dev/null +++ b/bindings/python/clutter-base.defs @@ -0,0 +1,1073 @@ +;; -*- scheme -*- + +(include "clutter-base-types.defs") + +;; From ../../clutter/clutter-keysyms.h + + + +;; From ../../clutter/clutter-timeline.h + +(define-function clutter_timeline_get_type + (c-name "clutter_timeline_get_type") + (return-type "GType") +) + +(define-function clutter_timeline_new + (c-name "clutter_timeline_new") + (is-constructor-of "ClutterTimeline") + (return-type "ClutterTimeline*") + (properties + '("frames" (argname "frames")) + '("fps" (argsname "fps")) + ) +) + +(define-method set_speed + (of-object "ClutterTimeline") + (c-name "clutter_timeline_set_speed") + (return-type "none") + (parameters + '("guint" "fps") + ) +) + +(define-method start + (of-object "ClutterTimeline") + (c-name "clutter_timeline_start") + (return-type "none") +) + +(define-method pause + (of-object "ClutterTimeline") + (c-name "clutter_timeline_pause") + (return-type "none") +) + +(define-method stop + (of-object "ClutterTimeline") + (c-name "clutter_timeline_stop") + (return-type "none") +) + +(define-method set_loop + (of-object "ClutterTimeline") + (c-name "clutter_timeline_set_loop") + (return-type "none") + (parameters + '("gboolean" "loop") + ) +) + +(define-method rewind + (of-object "ClutterTimeline") + (c-name "clutter_timeline_rewind") + (return-type "none") +) + +(define-method skip + (of-object "ClutterTimeline") + (c-name "clutter_timeline_skip") + (return-type "none") + (parameters + '("guint" "nframes") + ) +) + +(define-method advance + (of-object "ClutterTimeline") + (c-name "clutter_timeline_advance") + (return-type "none") + (parameters + '("guint" "frame_num") + ) +) + +(define-method get_current_frame + (of-object "ClutterTimeline") + (c-name "clutter_timeline_get_current_frame") + (return-type "gint") +) + +(define-method get_n_frames + (of-object "ClutterTimeline") + (c-name "clutter_timeline_get_n_frames") + (return-type "guint") +) + + + +;; From ../../clutter/clutter-main.h + +(define-function clutter_init + (c-name "clutter_init") + (return-type "int") + (parameters + '("int*" "argc") + '("char***" "argv") + ) +) + +(define-function main + (c-name "clutter_main") + (return-type "none") +) + +(define-function stage + (c-name "clutter_stage") + (return-type "ClutterGroup*") +) + +(define-function redraw + (c-name "clutter_redraw") + (return-type "none") + (parameters + ) +) + +(define-function xdisplay + (c-name "clutter_xdisplay") + (return-type "Display*") +) + +(define-function xscreen + (c-name "clutter_xscreen") + (return-type "int") +) + +(define-function root_xwindow + (c-name "clutter_root_xwindow") + (return-type "Window") +) + +(define-function gl_context + (c-name "clutter_gl_context") + (return-type "GLXContext") +) + +(define-function want_debug + (c-name "clutter_want_debug") + (return-type "gboolean") +) + +(define-function threads_enter + (c-name "clutter_threads_enter") + (return-type "none") +) + +(define-function threads_leave + (c-name "clutter_threads_leave") + (return-type "none") +) + + + +;; From ../../clutter/clutter-event.h + +(define-method type + (of-object "ClutterKeyEvent") + (c-name "clutter_key_event_type") + (return-type "ClutterEventType") +) + +(define-method time + (of-object "ClutterKeyEvent") + (c-name "clutter_key_event_time") + (return-type "guint32") +) + +(define-method state + (of-object "ClutterKeyEvent") + (c-name "clutter_key_event_state") + (return-type "guint") +) + +(define-method symbol + (of-object "ClutterKeyEvent") + (c-name "clutter_key_event_symbol") + (return-type "guint") +) + +(define-method code + (of-object "ClutterKeyEvent") + (c-name "clutter_key_event_code") + (return-type "guint16") +) + +(define-method unicode + (of-object "ClutterKeyEvent") + (c-name "clutter_key_event_unicode") + (return-type "guint32") +) + +(define-function clutter_keysym_to_unicode + (c-name "clutter_keysym_to_unicode") + (return-type "guint32") + (parameters + '("guint" "keyval") + ) +) + + + +;; From ../../clutter/clutter-element.h + +(define-function clutter_geometry_get_type + (c-name "clutter_geometry_get_type") + (return-type "GType") +) + +(define-function geometry_new + (c-name "clutter_geometry_new") + (is-constructor-of "ClutterGeometry") + (return-type "ClutterGeometry") +) + +(define-function clutter_element_box_get_type + (c-name "clutter_element_box_get_type") + (return-type "GType") +) + +(define-function element_box_new + (c-name "clutter_element_box_new") + (is-constructor-of "ClutterElementBox") + (return-type "ClutterElementBox") +) + +(define-function clutter_element_get_type + (c-name "clutter_element_get_type") + (return-type "GType") +) + +(define-method show + (of-object "ClutterElement") + (c-name "clutter_element_show") + (return-type "none") +) + +(define-method hide + (of-object "ClutterElement") + (c-name "clutter_element_hide") + (return-type "none") +) + +(define-method realize + (of-object "ClutterElement") + (c-name "clutter_element_realize") + (return-type "none") +) + +(define-method unrealize + (of-object "ClutterElement") + (c-name "clutter_element_unrealize") + (return-type "none") +) + +(define-method paint + (of-object "ClutterElement") + (c-name "clutter_element_paint") + (return-type "none") +) + +(define-method queue_redraw + (of-object "ClutterElement") + (c-name "clutter_element_queue_redraw") + (return-type "none") +) + +(define-method request_coords + (of-object "ClutterElement") + (c-name "clutter_element_request_coords") + (return-type "none") + (parameters + '("ClutterElementBox*" "box") + ) +) + +(define-method allocate_coords + (of-object "ClutterElement") + (c-name "clutter_element_allocate_coords") + (return-type "none") + (parameters + '("ClutterElementBox*" "box") + ) +) + +(define-method set_geometry + (of-object "ClutterElement") + (c-name "clutter_element_set_geometry") + (return-type "none") + (parameters + '("ClutterGeometry*" "geom") + ) +) + +(define-method get_geometry + (of-object "ClutterElement") + (c-name "clutter_element_get_geometry") + (return-type "none") + (parameters + '("ClutterGeometry*" "geom") + ) +) + +(define-method get_coords + (of-object "ClutterElement") + (c-name "clutter_element_get_coords") + (return-type "none") + (parameters + '("gint*" "x1") + '("gint*" "y1") + '("gint*" "x2") + '("gint*" "y2") + ) +) + +(define-method set_position + (of-object "ClutterElement") + (c-name "clutter_element_set_position") + (return-type "none") + (parameters + '("gint" "x") + '("gint" "y") + ) +) + +(define-method set_size + (of-object "ClutterElement") + (c-name "clutter_element_set_size") + (return-type "none") + (parameters + '("gint" "width") + '("gint" "height") + ) +) + +(define-method get_abs_position + (of-object "ClutterElement") + (c-name "clutter_element_get_abs_position") + (return-type "none") + (parameters + '("gint*" "x") + '("gint*" "y") + ) +) + +(define-method get_width + (of-object "ClutterElement") + (c-name "clutter_element_get_width") + (return-type "guint") +) + +(define-method get_height + (of-object "ClutterElement") + (c-name "clutter_element_get_height") + (return-type "guint") +) + +(define-method get_x + (of-object "ClutterElement") + (c-name "clutter_element_get_x") + (return-type "gint") +) + +(define-method get_y + (of-object "ClutterElement") + (c-name "clutter_element_get_y") + (return-type "gint") +) + +(define-method rotate_z + (of-object "ClutterElement") + (c-name "clutter_element_rotate_z") + (return-type "none") + (parameters + '("gfloat" "angle") + '("gint" "x") + '("gint" "y") + ) +) + +(define-method rotate_x + (of-object "ClutterElement") + (c-name "clutter_element_rotate_x") + (return-type "none") + (parameters + '("gfloat" "angle") + '("gint" "y") + '("gint" "z") + ) +) + +(define-method rotate_y + (of-object "ClutterElement") + (c-name "clutter_element_rotate_y") + (return-type "none") + (parameters + '("gfloat" "angle") + '("gint" "x") + '("gint" "z") + ) +) + +(define-method set_opacity + (of-object "ClutterElement") + (c-name "clutter_element_set_opacity") + (return-type "none") + (parameters + '("guint8" "opacity") + ) +) + +(define-method get_opacity + (of-object "ClutterElement") + (c-name "clutter_element_get_opacity") + (return-type "guint8") +) + +(define-method set_name + (of-object "ClutterElement") + (c-name "clutter_element_set_name") + (return-type "none") + (parameters + '("const-gchar*" "id") + ) +) + +(define-method get_name + (of-object "ClutterElement") + (c-name "clutter_element_get_name") + (return-type "const-gchar*") +) + +(define-method get_id + (of-object "ClutterElement") + (c-name "clutter_element_get_id") + (return-type "guint32") +) + +(define-method set_clip + (of-object "ClutterElement") + (c-name "clutter_element_set_clip") + (return-type "none") + (parameters + '("gint" "xoff") + '("gint" "yoff") + '("gint" "width") + '("gint" "height") + ) +) + +(define-method remove_clip + (of-object "ClutterElement") + (c-name "clutter_element_remove_clip") + (return-type "none") +) + +(define-method set_parent + (of-object "ClutterElement") + (c-name "clutter_element_set_parent") + (return-type "none") + (parameters + '("ClutterElement*" "parent") + ) +) + +(define-method get_parent + (of-object "ClutterElement") + (c-name "clutter_element_get_parent") + (return-type "ClutterElement*") +) + +(define-method raise + (of-object "ClutterElement") + (c-name "clutter_element_raise") + (return-type "none") + (parameters + '("ClutterElement*" "below") + ) +) + +(define-method lower + (of-object "ClutterElement") + (c-name "clutter_element_lower") + (return-type "none") + (parameters + '("ClutterElement*" "above") + ) +) + +(define-method raise_top + (of-object "ClutterElement") + (c-name "clutter_element_raise_top") + (return-type "none") +) + +(define-method lower_bottom + (of-object "ClutterElement") + (c-name "clutter_element_lower_bottom") + (return-type "none") +) + + + +;; From ../../clutter/clutter-rectangle.h + +(define-function clutter_rectangle_get_type + (c-name "clutter_rectangle_get_type") + (return-type "GType") +) + +(define-function clutter_rectangle_new + (c-name "clutter_rectangle_new") + (is-constructor-of "ClutterRectangle") + (return-type "ClutterElement*") + (properties + '("color" (argname "col")) + ) +) + + + +;; From ../../clutter/clutter-texture.h + +(define-function clutter_texture_get_type + (c-name "clutter_texture_get_type") + (return-type "GType") +) + +(define-function clutter_texture_new_from_pixbuf + (c-name "clutter_texture_new_from_pixbuf") + (return-type "ClutterElement*") + (parameters + '("GdkPixbuf*" "pixbuf") + ) +) + +(define-function clutter_texture_new + (c-name "clutter_texture_new") + (is-constructor-of "ClutterTexture") + (return-type "ClutterElement*") +) + +(define-method set_pixbuf + (of-object "ClutterTexture") + (c-name "clutter_texture_set_pixbuf") + (return-type "none") + (parameters + '("GdkPixbuf*" "pixbuf") + ) +) + +(define-method get_pixbuf + (of-object "ClutterTexture") + (c-name "clutter_texture_get_pixbuf") + (return-type "GdkPixbuf*") +) + +(define-method get_base_size + (of-object "ClutterTexture") + (c-name "clutter_texture_get_base_size") + (return-type "none") + (parameters + '("gint*" "width") + '("gint*" "height") + ) +) + +(define-method bind_tile + (of-object "ClutterTexture") + (c-name "clutter_texture_bind_tile") + (return-type "none") + (parameters + '("gint" "index") + ) +) + +(define-method get_n_tiles + (of-object "ClutterTexture") + (c-name "clutter_texture_get_n_tiles") + (return-type "none") + (parameters + '("gint*" "n_x_tiles") + '("gint*" "n_y_tiles") + ) +) + +(define-method get_x_tile_detail + (of-object "ClutterTexture") + (c-name "clutter_texture_get_x_tile_detail") + (return-type "none") + (parameters + '("gint" "x_index") + '("gint*" "pos") + '("gint*" "size") + '("gint*" "waste") + ) +) + +(define-method get_y_tile_detail + (of-object "ClutterTexture") + (c-name "clutter_texture_get_y_tile_detail") + (return-type "none") + (parameters + '("gint" "y_index") + '("gint*" "pos") + '("gint*" "size") + '("gint*" "waste") + ) +) + +(define-method has_generated_tiles + (of-object "ClutterTexture") + (c-name "clutter_texture_has_generated_tiles") + (return-type "gboolean") +) + +(define-method is_tiled + (of-object "ClutterTexture") + (c-name "clutter_texture_is_tiled") + (return-type "gboolean") +) + + + +;; From ../../clutter/clutter-color.h + +(define-function clutter_color_new + (c-name "clutter_color_new") + (return-type "ClutterColor") + (parameters + '("guint8" "r") + '("guint8" "g") + '("guint8" "b") + '("guint8" "a") + ) +) + +(define-method set + (of-object "ClutterColor") + (c-name "clutter_color_set") + (return-type "none") + (parameters + '("guint8" "r") + '("guint8" "g") + '("guint8" "b") + '("guint8" "a") + ) +) + +(define-method get + (of-object "ClutterColor") + (c-name "clutter_color_get") + (return-type "none") + (parameters + '("guint8*" "r") + '("guint8*" "g") + '("guint8*" "b") + '("guint8*" "a") + ) +) + + + +;; From ../../clutter/clutter-clone-texture.h + +(define-function clutter_clone_texture_get_type + (c-name "clutter_clone_texture_get_type") + (return-type "GType") +) + +(define-function clutter_clone_texture_new + (c-name "clutter_clone_texture_new") + (is-constructor-of "ClutterCloneTexture") + (return-type "ClutterElement*") + (properties + '("parent-texture" (argname "texture")) + ) +) + + + +;; From ../../clutter/clutter-video-texture.h + +(define-function clutter_video_texture_error_quark + (c-name "clutter_video_texture_error_quark") + (return-type "GQuark") +) + +(define-function clutter_video_texture_get_type + (c-name "clutter_video_texture_get_type") + (return-type "GType") +) + +(define-function clutter_video_texture_new + (c-name "clutter_video_texture_new") + (is-constructor-of "ClutterVideoTexture") + (return-type "ClutterElement*") +) + +(define-method open + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_open") + (return-type "gboolean") + (parameters + '("const-gchar*" "mrl") + '("const-gchar*" "subtitle_uri") + '("GError**" "error") + ) +) + +(define-method play + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_play") + (return-type "gboolean") + (parameters + '("GError**" "error") + ) +) + +(define-method pause + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_pause") + (return-type "none") +) + +(define-method can_direct_seek + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_can_direct_seek") + (return-type "gboolean") +) + +(define-method seek_time + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_seek_time") + (return-type "gboolean") + (parameters + '("gint64" "time") + '("GError**" "gerror") + ) +) + +(define-method seek + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_seek") + (return-type "gboolean") + (parameters + '("float" "position") + '("GError**" "error") + ) +) + +(define-method stop + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_stop") + (return-type "none") +) + +(define-method can_set_volume + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_can_set_volume") + (return-type "gboolean") +) + +(define-method set_volume + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_set_volume") + (return-type "none") + (parameters + '("int" "volume") + ) +) + +(define-method get_volume + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_get_volume") + (return-type "int") +) + +(define-method get_current_time + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_get_current_time") + (return-type "gint64") +) + +(define-method get_stream_length + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_get_stream_length") + (return-type "gint64") +) + +(define-method is_playing + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_is_playing") + (return-type "gboolean") +) + +(define-method is_seekable + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_is_seekable") + (return-type "gboolean") +) + +(define-method get_position + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_get_position") + (return-type "float") +) + +(define-method set_aspect_ratio + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_set_aspect_ratio") + (return-type "none") + (parameters + '("ClutterVideoTextureAspectRatio" "ratio") + ) +) + +(define-method get_aspect_ratio + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_get_aspect_ratio") + (return-type "ClutterVideoTextureAspectRatio") +) + +(define-method get_metadata + (of-object "ClutterVideoTexture") + (c-name "clutter_video_texture_get_metadata") + (return-type "none") + (parameters + '("ClutterVideoTextureMetadataType" "type") + '("GValue*" "value") + ) +) + + + +;; From ../../clutter/clutter-label.h + +(define-function clutter_label_get_type + (c-name "clutter_label_get_type") + (return-type "GType") +) + +(define-function clutter_label_new_with_text + (c-name "clutter_label_new_with_text") + (return-type "ClutterElement*") + (parameters + '("const-gchar*" "font_desc") + '("const-gchar*" "text") + ) +) + +(define-function clutter_label_new + (c-name "clutter_label_new") + (is-constructor-of "ClutterLabel") + (return-type "ClutterElement*") +) + +(define-method set_text + (of-object "ClutterLabel") + (c-name "clutter_label_set_text") + (return-type "none") + (parameters + '("const-gchar*" "text") + ) +) + +(define-method set_font + (of-object "ClutterLabel") + (c-name "clutter_label_set_font") + (return-type "none") + (parameters + '("const-gchar*" "desc") + ) +) + +(define-method set_color + (of-object "ClutterLabel") + (c-name "clutter_label_set_color") + (return-type "none") + (parameters + '("guint32" "pixel") + ) +) + +(define-method set_text_extents + (of-object "ClutterLabel") + (c-name "clutter_label_set_text_extents") + (return-type "none") + (parameters + '("gint" "width") + '("gint" "height") + ) +) + + + +;; From ../../clutter/clutter-group.h + +(define-function clutter_group_get_type + (c-name "clutter_group_get_type") + (return-type "GType") +) + +(define-function clutter_group_new + (c-name "clutter_group_new") + (is-constructor-of "ClutterGroup") + (return-type "ClutterGroup*") +) + +(define-method add + (of-object "ClutterGroup") + (c-name "clutter_group_add") + (return-type "none") + (parameters + '("ClutterElement*" "element") + ) +) + +(define-method add_many_valist + (of-object "ClutterGroup") + (c-name "clutter_group_add_many_valist") + (return-type "none") + (parameters + '("ClutterElement*" "first_element") + '("va_list" "args") + ) +) + +(define-method add_many + (of-object "ClutterGroup") + (c-name "clutter_group_add_many") + (return-type "none") + (parameters + '("ClutterElement*" "first_element") + ) + (varargs #t) +) + +(define-method remove + (of-object "ClutterGroup") + (c-name "clutter_group_remove") + (return-type "none") + (parameters + '("ClutterElement*" "element") + ) +) + +(define-method show_all + (of-object "ClutterGroup") + (c-name "clutter_group_show_all") + (return-type "none") +) + +(define-method hide_all + (of-object "ClutterGroup") + (c-name "clutter_group_hide_all") + (return-type "none") +) + +(define-method find_child_by_id + (of-object "ClutterGroup") + (c-name "clutter_group_find_child_by_id") + (return-type "ClutterElement*") + (parameters + '("guint" "id") + ) +) + +(define-method raise + (of-object "ClutterGroup") + (c-name "clutter_group_raise") + (return-type "none") + (parameters + '("ClutterElement*" "element") + '("ClutterElement*" "sibling") + ) +) + +(define-method lower + (of-object "ClutterGroup") + (c-name "clutter_group_lower") + (return-type "none") + (parameters + '("ClutterElement*" "element") + '("ClutterElement*" "sibling") + ) +) + + + +;; From ../../clutter/clutter-stage.h + +(define-function clutter_stage_get_type + (c-name "clutter_stage_get_type") + (return-type "GType") +) + +(define-method get_xwindow + (of-object "ClutterStage") + (c-name "clutter_stage_get_xwindow") + (return-type "Window") +) + +(define-method set_color + (of-object "ClutterStage") + (c-name "clutter_stage_set_color") + (return-type "none") + (parameters + '("ClutterColor" "color") + ) +) + +(define-method get_color + (of-object "ClutterStage") + (c-name "clutter_stage_get_color") + (return-type "ClutterColor") +) + +(define-method pick + (of-object "ClutterStage") + (c-name "clutter_stage_pick") + (return-type "ClutterElement*") + (parameters + '("gint" "x") + '("gint" "y") + ) +) + + + +;; From ../../clutter/clutter-enum-types.h + +(define-function clutter_event_type_get_type + (c-name "clutter_event_type_get_type") + (return-type "GType") +) + +(define-function clutter_element_transform_get_type + (c-name "clutter_element_transform_get_type") + (return-type "GType") +) + +(define-function clutter_element_flags_get_type + (c-name "clutter_element_flags_get_type") + (return-type "GType") +) + +(define-function clutter_video_texture_error_get_type + (c-name "clutter_video_texture_error_get_type") + (return-type "GType") +) + +(define-function clutter_video_texture_aspect_ratio_get_type + (c-name "clutter_video_texture_aspect_ratio_get_type") + (return-type "GType") +) + +(define-function clutter_video_texture_metadata_type_get_type + (c-name "clutter_video_texture_metadata_type_get_type") + (return-type "GType") +) + + diff --git a/bindings/python/clutter.override b/bindings/python/clutter.override new file mode 100644 index 000000000..19a96d783 --- /dev/null +++ b/bindings/python/clutter.override @@ -0,0 +1,500 @@ +/* -*- C -*- */ +%% +headers +#define NO_IMPORT_PYGOBJECT +#include "pygobject.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +%% +modulename clutter +%% +import gobject.GObject as PyGObject_Type +import gtk.gdk.Pixbuf as PyGdkPixbuf_Type +%% +ignore + clutter_video_texture_error_quark + clutter_group_add_many_valist + clutter_stage_get_xwindow + clutter_init + clutter_xdisplay + clutter_root_xwindow + clutter_gl_context +%% +ignore-glob + *_get_type +%% +override clutter_geometry_new kwargs +static int +_wrap_clutter_geometry_new (PyGBoxed *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "x", "y", "width", "height", NULL }; + ClutterGeometry geom = { 0, 0, 0, 0 }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|iiii:ClutterGeometry.__init__", + kwlist, + &(geom.x), &(geom.y), + &(geom.width), &(geom.height))) + return -1; + + self->boxed = g_boxed_copy (CLUTTER_TYPE_GEOMETRY, &geom); + self->free_on_dealloc = TRUE; + self->gtype = CLUTTER_TYPE_GEOMETRY; + + return 0; +} +%% +override-slot ClutterGeometry.tp_as_sequence +static int +_wrap_clutter_geometry_length (PyGBoxed *self) +{ + return 4; +} +static PyObject * +_wrap_clutter_geometry_getitem(PyGBoxed *self, int pos) +{ + ClutterGeometry *geom; + + if (pos < 0) + pos += 4; + + if (pos < 0 || pos >= 4) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + + return NULL; + } + + geom = pyg_boxed_get (self, ClutterGeometry); + switch (pos) { + case 0: return PyInt_FromLong (geom->x); + case 1: return PyInt_FromLong (geom->y); + case 2: return PyInt_FromLong (geom->width); + case 3: return PyInt_FromLong (geom->height); + default: + g_assert_not_reached(); + return NULL; + } +} +static int +_wrap_clutter_geometry_setitem (PyGBoxed *self, int pos, PyObject *value) +{ + ClutterGeometry *geom; + gint val; + + if (pos < 0) + pos += 4; + + if (pos < 0 || pos >= 4) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + + return -1; + } + + geom = pyg_boxed_get (self, ClutterGeometry); + val = PyInt_AsLong (value); + if (PyErr_Occurred ()) + return -1; + + switch(pos) { + case 0: geom->x = val; break; + case 1: geom->y = val; break; + case 2: geom->width = val; break; + case 3: geom->height = val; break; + default: + g_assert_not_reached(); + return -1; + } + + return 0; +} +static PySequenceMethods _wrap_clutter_geometry_tp_as_sequence = { + (inquiry) _wrap_clutter_geometry_length, + (binaryfunc) 0, + (intargfunc) 0, + (intargfunc) _wrap_clutter_geometry_getitem, + (intintargfunc) 0, + (intobjargproc) _wrap_clutter_geometry_setitem, + (intintobjargproc) 0 +}; +%% +override-attr ClutterGeometry.x +static int +_wrap_clutter_geomtry__set_x (PyGBoxed *self, PyObject *value, void *closure) +{ + gint val; + + val = PyInt_AsLong (value); + if (PyErr_Occurred ()) + return -1; + + pyg_boxed_get (self, ClutterGeometry)->x = val; + + return 0; +} +%% +override-attr ClutterGeometry.y +static int +_wrap_clutter_geometry__set_y (PyGBoxed *self, PyObject *value, void *closure) +{ + gint val; + + val = PyInt_AsLong (value); + if (PyErr_Occurred ()) + return -1; + + pyg_boxed_get (self, ClutterGeometry)->y = val; + + return 0; +} +%% +override-attr ClutterGeometry.width +static int +_wrap_clutter_geometry__set_width (PyGBoxed *self, PyObject *value, void *closure) +{ + gint val; + + val = PyInt_AsLong (value); + if (PyErr_Occurred ()) + return -1; + + pyg_boxed_get(self, ClutterGeometry)->width = val; + + return 0; +} +%% +override-attr ClutterGeometry.height +static int +_wrap_clutter_geometry__set_height (PyGBoxed *self, PyObject *value, void *closure) +{ + gint val; + + val = PyInt_AsLong (value); + if (PyErr_Occurred ()) + return -1; + + pyg_boxed_get (self, ClutterGeometry)->height = val; + + return 0; +} +%% +override clutter_element_box_new kwargs +static int +_wrap_clutter_element_box_new (PyGBoxed *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "x1", "y1", "x2", "y2", NULL }; + ClutterElementBox box = { 0, 0, 0, 0 }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|iiii:ClutterElementBox.__init__", + kwlist, + &(box.x1), &(box.y1), + &(box.x2), &(box.y2))) + return -1; + + self->boxed = g_boxed_copy (CLUTTER_TYPE_ELEMENT_BOX, &box); + self->free_on_dealloc = TRUE; + self->gtype = CLUTTER_TYPE_ELEMENT_BOX; + + return 0; +} +%% +override-slot ClutterElementBox.tp_as_sequence +static int +_wrap_clutter_element_box_length (PyGBoxed *self) +{ + return 4; +} +static PyObject * +_wrap_clutter_element_box_getitem(PyGBoxed *self, int pos) +{ + ClutterElementBox *box; + + if (pos < 0) + pos += 4; + + if (pos < 0 || pos >= 4) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + + return NULL; + } + + box = pyg_boxed_get (self, ClutterElementBox); + switch (pos) { + case 0: return PyInt_FromLong (box->x1); + case 1: return PyInt_FromLong (box->y1); + case 2: return PyInt_FromLong (box->x2); + case 3: return PyInt_FromLong (box->y2); + default: + g_assert_not_reached(); + return NULL; + } +} +static int +_wrap_clutter_element_box_setitem (PyGBoxed *self, int pos, PyObject *value) +{ + ClutterElementBox *box; + gint val; + + if (pos < 0) + pos += 4; + + if (pos < 0 || pos >= 4) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + + return -1; + } + + box = pyg_boxed_get (self, ClutterElementBox); + val = PyInt_AsLong (value); + if (PyErr_Occurred ()) + return -1; + + switch(pos) { + case 0: box->x1 = val; break; + case 1: box->y1 = val; break; + case 2: box->x2 = val; break; + case 3: box->y2 = val; break; + default: + g_assert_not_reached(); + return -1; + } + + return 0; +} +static PySequenceMethods _wrap_clutter_element_box_tp_as_sequence = { + (inquiry) _wrap_clutter_element_box_length, + (binaryfunc) 0, + (intargfunc) 0, + (intargfunc) _wrap_clutter_element_box_getitem, + (intintargfunc) 0, + (intobjargproc) _wrap_clutter_element_box_setitem, + (intintobjargproc) 0 +}; +%% +override-attr ClutterElementBox.x1 +static int +_wrap_clutter_element_box__set_x1 (PyGBoxed *self, PyObject *value, void *closure) +{ + gint val; + + val = PyInt_AsLong (value); + if (PyErr_Occurred ()) + return -1; + + pyg_boxed_get (self, ClutterElementBox)->x1 = val; + + return 0; +} +%% +override-attr ClutterElementBox.y1 +static int +_wrap_clutter_element_box__set_y1 (PyGBoxed *self, PyObject *value, void *closure) +{ + gint val; + + val = PyInt_AsLong (value); + if (PyErr_Occurred ()) + return -1; + + pyg_boxed_get (self, ClutterElementBox)->y1 = val; + + return 0; +} +%% +override-attr ClutterElementBox.x2 +static int +_wrap_clutter_element_box__set_x2 (PyGBoxed *self, PyObject *value, void *closure) +{ + gint val; + + val = PyInt_AsLong (value); + if (PyErr_Occurred ()) + return -1; + + pyg_boxed_get(self, ClutterElementBox)->x2 = val; + + return 0; +} +%% +override-attr ClutterElementBox.y2 +static int +_wrap_clutter_element_box__set_y2 (PyGBoxed *self, PyObject *value, void *closure) +{ + gint val; + + val = PyInt_AsLong (value); + if (PyErr_Occurred ()) + return -1; + + pyg_boxed_get (self, ClutterElementBox)->y2 = val; + + return 0; +} +%% +override clutter_element_get_coords +static PyObject * +_wrap_clutter_element_get_coords (PyGObject *self) +{ + gint x1, y1; + gint x2, y2; + + clutter_element_get_coords (CLUTTER_ELEMENT (self->obj), + &x1, &y1, + &x2, &y2); + return Py_BuildValue("(iiii)", x1, y1, x2, y2); +} +%% +override clutter_element_get_abs_position +static PyObject * +_wrap_clutter_element_get_abs_position (PyGObject *self) +{ + gint pos_x, pos_y; + + clutter_element_get_abs_position (CLUTTER_ELEMENT (self->obj), + &pos_x, + &pos_y); + return Py_BuildValue("(ii)", pos_x, pos_y); +} +%% +override clutter_texture_get_base_size +static PyObject * +_wrap_clutter_texture_get_base_size (PyGObject *self) +{ + gint width, height; + + clutter_texture_get_base_size (CLUTTER_TEXTURE (self->obj), + &width, + &height); + return Py_BuildValue ("(ii)", width, height); +} +%% +override clutter_texture_get_n_tiles +static PyObject * +_wrap_clutter_texture_get_n_tiles (PyGObject *self) +{ + gint n_x_tiles, n_y_tiles; + + clutter_texture_get_n_tiles (CLUTTER_TEXTURE (self->obj), + &n_x_tiles, + &n_y_tiles); + return Py_BuildValue ("(ii)", n_x_tiles, n_y_tiles); +} +%% +override clutter_texture_get_x_tile_detail kwargs +static PyObject * +_wrap_clutter_texture_get_x_tile_detail (PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "x_index", NULL }; + gint x_index; + gint pos, size, waste; + + if (!PyArg_ParseTupleAndKeywords (args, kwargs, + "i:ClutterTexture.get_x_tile_detail", + kwlist, &x_index)) + return NULL; + + clutter_texture_get_x_tile_detail (CLUTTER_TEXTURE (self->obj), + x_index, + &pos, &size, &waste); + return Py_BuildValue ("(iii)", pos, size, waste); +} +%% +override clutter_texture_get_y_tile_detail kwargs +static PyObject * +_wrap_clutter_texture_get_y_tile_detail (PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "y_index", NULL }; + gint y_index; + gint pos, size, waste; + + if (!PyArg_ParseTupleAndKeywords (args, kwargs, + "i:ClutterTexture.get_y_tile_detail", + kwlist, &y_index)) + return NULL; + + clutter_texture_get_y_tile_detail (CLUTTER_TEXTURE (self->obj), + y_index, + &pos, &size, &waste); + return Py_BuildValue ("(iii)", pos, size, waste); +} +%% +override clutter_group_add_many +static PyObject * +_wrap_clutter_group_add_many (PyGObject *self, + PyObject *args) +{ + ClutterGroup *group; + int i, len; + + if ((len = PyTuple_Size(args)) < 1) { + PyErr_SetString(PyExc_TypeError, + "requires at least one argument"); + return NULL; + } + + group = CLUTTER_GROUP (self->obj); + + for (i = 0; i < len; i++) { + PyGObject *pyelement; + ClutterElement *element; + + pyelement = (PyGObject *) PyTuple_GetItem (args, i); + if (!pygobject_check (pyelement, &PyClutterElement_Type)) { + PyErr_SetString (PyExc_TypeError, + "Expected a ClutterElement"); + return NULL; + } + + element = CLUTTER_ELEMENT (pyelement->obj); + + clutter_group_add (group, element); + } + + Py_INCREF (Py_None); + return Py_None; +} +%% +override clutter_main noargs +static PyObject * +_wrap_clutter_main (PyObject *self) +{ + pyg_begin_allow_threads; + clutter_main (); + pyg_end_allow_threads; + + if (PyErr_Occurred ()) + return NULL; + Py_INCREF (Py_None); + return Py_None; +} +%% +override clutter_threads_enter noargs +static PyObject * +_wrap_clutter_threads_enter (PyObject *self) +{ + /* must allow threads while acquiring lock, or no other python + * code will execute while we wait! */ + pyg_begin_allow_threads; + clutter_threads_enter (); + pyg_end_allow_threads; + + Py_INCREF(Py_None); + return Py_None; +} diff --git a/bindings/python/cluttermodule.c b/bindings/python/cluttermodule.c new file mode 100644 index 000000000..6d11647c4 --- /dev/null +++ b/bindings/python/cluttermodule.c @@ -0,0 +1,26 @@ +#include +/* #include */ + +void clutter_register_classes (PyObject *d); +extern PyMethodDef clutter_functions[]; + +DL_EXPORT (void) +initclutter (void) +{ + PyObject *m, *d; + + init_pygobject (); + /* init_pygtk(); */ + + m = Py_InitModule ("clutter", clutter_functions); + d = PyModule_GetDict (m); + + clutter_register_classes (d); + + if (PyErr_Occurred ()) + { + Py_FatalError ("can't initialise module clutter"); + } + else + clutter_init(NULL, NULL); +} diff --git a/clutter.pc.in b/clutter.pc.in new file mode 100644 index 000000000..8ba3c1b50 --- /dev/null +++ b/clutter.pc.in @@ -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 diff --git a/clutter/Makefile.am b/clutter/Makefile.am index 5cdba8953..b1caab12a 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -1,46 +1,101 @@ -source_h = pixbuf.h util.h fonts.h \ - cltr.h \ - cltr-private.h \ - cltr-glu.h \ - cltr-animator.h \ - cltr-events.h \ - cltr-texture.h \ - cltr-widget.h \ - cltr-window.h \ - cltr-photo-grid.h \ - cltr-video.h \ - cltr-list.h \ - cltr-overlay.h \ - cltr-label.h \ - cltr-button.h \ - cltr-scratch.h +MARSHALFILES = clutter-marshal.c clutter-marshal.h +ENUMFILES = clutter-enum-types.c clutter-enum-types.h +GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0` +GLIB_MKENUMS=`pkg-config --variable=glib_mkenums glib-2.0` -source_c = pixbuf.c util.c fonts.c \ - cltr-core.c \ - cltr-glu.c \ - cltr-animator.c \ - cltr-texture.c \ - cltr-widget.c \ - cltr-events.c \ - cltr-window.c \ - cltr-photo-grid.c \ - cltr-video.c \ - cltr-list.c \ - cltr-overlay.c \ - cltr-label.c \ - cltr-button.c \ - cltr-scratch.c +BUILT_SOURCES = $(MARSHALFILES) $(ENUMFILES) -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 -libclutter_la_SOURCES = $(source_c) $(source_h) -libclutter_la_LIBADD = @CLTR_LIBS@ $(GST_LIBS) $(GCONF_LIBS) +clutter-marshal.h: clutter-marshal.list + ( $(GLIB_GENMARSHAL) --prefix=clutter_marshal $(srcdir)/clutter-marshal.list --header > clutter-marshal.h ) -# http://sources.redhat.com/autobook/autobook/autobook_91.html#SEC91 -# current : revision : age +clutter-marshal.c: clutter-marshal.h + ( $(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 -clutterheaders_DATA = $(source_h) +clutter-enum-types.c: clutter-enum-types.h + $(GLIB_MKENUMS) \ + --fhead "#include \n" \ + --fhead "#include \"clutter-enum-types.h\"\n" \ + --fprod "\n/* enumerations from \"@filename@\" */" \ + --fprod "\n#include \"@filename@\"" \ + --vhead "static const G@Type@Value _@enum_name@_values[] = {" \ + --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \ + --vtail " { 0, NULL, NULL }\n};\n\n" \ + --vtail "GType\n@enum_name@_get_type (void)\n{\n" \ + --vtail " static GType type = 0;\n\n" \ + --vtail " if (!type)\n" \ + --vtail " type = g_@type@_register_static (\"@EnumName@\", _@enum_name@_values);\n\n" \ + --vtail " return type;\n}\n\n" \ + $(source_h) >> xgen-cetc \ + && cp xgen-cetc clutter-enum-types.c \ + && rm -f xgen-cetc + +CLEANFILES = $(BUILT_SOURCES) stamp-clutter-enum-types.h + +source_c = clutter-main.c \ + clutter-util.c \ + clutter-event.c \ + clutter-color.c \ + clutter-timeline.c \ + clutter-group.c \ + clutter-stage.c \ + clutter-rectangle.c \ + clutter-texture.c \ + clutter-clone-texture.c \ + clutter-video-texture.c \ + clutter-label.c \ + clutter-element.c \ + clutter-enum-types.c + +source_h_priv = clutter-private.h + +libclutter_@CLUTTER_MAJORMINOR@_la_SOURCES = $(MARSHALFILES) \ + $(source_c) \ + $(source_h) \ + $(source_h_priv) + +INCLUDES = @GCC_FLAGS@ @CLUTTER_CFLAGS@ $(GST_CFLAGS) + +lib_LTLIBRARIES = libclutter-@CLUTTER_MAJORMINOR@.la + +libclutter_@CLUTTER_MAJORMINOR@_la_LIBADD = @CLUTTER_LIBS@ $(GST_LIBS) +libclutter_@CLUTTER_MAJORMINOR@_la_LDFLAGS = @CLUTTER_LT_LDFLAGS@ + +clutterheadersdir = $(includedir)/clutter-@CLUTTER_MAJORMINOR@/clutter +clutterheaders_DATA = $(source_h) \ + clutter-marshal.h \ + clutter-enum-types.h \ + clutter.h + +EXTRA_DIST = clutter-marshal.list diff --git a/clutter/cltr-animator.c b/clutter/cltr-animator.c deleted file mode 100644 index a47277015..000000000 --- a/clutter/cltr-animator.c +++ /dev/null @@ -1,302 +0,0 @@ -#include "cltr-animator.h" -#include "cltr-private.h" - - -struct CltrAnimator -{ - CltrWidget *widget; - - CltrAnimatorType type; - - gint fps; - int n_steps, step; - - CltrAnimatorFinishFunc anim_finish_cb; - gpointer *anim_finish_data; - - WidgetPaintMethod wrapped_paint_func; - - int zoom_end_x1, zoom_end_y1, zoom_end_x2, zoom_end_y2; - int zoom_start_x1, zoom_start_y1, zoom_start_x2, zoom_start_y2; - - int move_start_x1, move_start_y1, move_end_x1, move_end_y1; -}; - - -static void -cltr_animator_wrapped_paint(CltrWidget *widget); - -CltrAnimator* -cltr_animator_zoom_new(CltrWidget *widget, - int src_x1, - int src_y1, - int src_x2, - int src_y2, - int dst_x1, - int dst_y1, - int dst_x2, - int dst_y2) -{ - CltrAnimator *anim = g_malloc0(sizeof(CltrAnimator)); - - anim->type = CltrAnimatorZoom; - - anim->zoom_end_x1 = dst_x1; - anim->zoom_end_x2 = dst_x2; - anim->zoom_end_y1 = dst_y1; - anim->zoom_end_y2 = dst_y2; - - anim->zoom_start_x1 = src_x1; - anim->zoom_start_x2 = src_x2; - anim->zoom_start_y1 = src_y1; - anim->zoom_start_y2 = src_y2; - - anim->wrapped_paint_func = widget->paint; - - anim->widget = widget; - widget->anim = anim; - - anim->n_steps = 10; - anim->step = 0; - anim->fps = 50; - - return anim; -} - -CltrAnimator* -cltr_animator_move_new(CltrWidget *widget, - int src_x1, - int src_y1, - int dst_x1, - int dst_y1) -{ - CltrAnimator *anim = g_malloc0(sizeof(CltrAnimator)); - - anim->type = CltrAnimatorMove; - - anim->move_start_x1 = src_x1; - anim->move_start_y1 = src_y1; - anim->move_end_x1 = dst_x1; - anim->move_end_y1 = dst_y1; - - anim->wrapped_paint_func = widget->paint; - - anim->widget = widget; - widget->anim = anim; - - anim->n_steps = 10; - anim->step = 0; - anim->fps = 50; - - return anim; -} - - -CltrAnimator* -cltr_animator_fullzoom_new(CltrWidget *widget, - int x1, - int y1, - int x2, - int y2) -{ - CltrAnimator *anim = g_malloc0(sizeof(CltrAnimator)); - - anim->type = CltrAnimatorFullZoom; - - anim->zoom_end_x1 = x1; - anim->zoom_end_x2 = x2; - anim->zoom_end_y1 = y1; - anim->zoom_end_y2 = y2; - - anim->zoom_start_x1 = cltr_widget_abs_x(widget); - anim->zoom_start_x2 = cltr_widget_abs_x2(widget); - anim->zoom_start_y1 = cltr_widget_abs_y(widget); - anim->zoom_start_y2 = cltr_widget_abs_y2(widget); - - anim->wrapped_paint_func = widget->paint; - - anim->widget = widget; - widget->anim = anim; - - anim->n_steps = 10; - anim->step = 0; - anim->fps = 50; - - return anim; -} - - -CltrAnimator* -cltr_animator_new(CltrWidget *widget) -{ - return NULL; -} - -void -cltr_animator_set_args(CltrAnimator *anim) -{ - -} - -static void -cltr_animator_wrapped_move_paint(CltrWidget *widget) -{ - CltrAnimator *anim = widget->anim; - int orig_x, orig_y; - - float f = (float)anim->step/anim->n_steps; - - orig_x = widget->x; - orig_y = widget->y; - - widget->x = anim->move_start_x1 + ( (anim->move_end_x1 - anim->move_start_x1) * f ); - widget->x = anim->move_start_y1 + ( (anim->move_end_y1 - anim->move_start_y1) * f ); - - anim->wrapped_paint_func(widget); - - widget->x = orig_x; - widget->y = orig_y; -} - -static void -cltr_animator_wrapped_zoom_paint(CltrWidget *widget) -{ - CltrAnimator *anim = widget->anim; - float tx = 0.0, ty = 0.0; - float x1, x2, y1, y2; - - /* zoom here */ - - float f = (float)anim->step/anim->n_steps; - - int end_width = anim->zoom_end_x2 - anim->zoom_end_x1; - int start_width = anim->zoom_start_x2 - anim->zoom_start_x1; - - int end_height = anim->zoom_end_y2 - anim->zoom_end_y1; - int start_height = anim->zoom_start_y2 - anim->zoom_start_y1; - - float max_zoom_x = (float)start_width/end_width; - float max_zoom_y = (float)start_height/end_height; - - float trans_y = ((float)anim->zoom_end_y1); - - CLTR_MARK(); - - glPushMatrix(); - - CLTR_DBG("f is %f ( %i/%i ) max_zoom x: %f y: %f, zooming to %f, %f", - f, anim->step, anim->n_steps, max_zoom_x, max_zoom_y, - (f * max_zoom_x), (f * max_zoom_y)); - -#if 0 - glTranslatef (0.0 /* - (float)(anim->zoom_start_x1) * ( (max_zoom_x * f) )*/, - - trans_y * f * max_zoom_y, - 0.0); - - if ((f * max_zoom_x) > 1.0 && (f * max_zoom_y) > 1.0) - { - glScalef ((f * max_zoom_x), (f * max_zoom_y), 0.0); - } -#endif - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - /* glOrtho (0, widget->width, widget->height, 0, -1, 1); */ - - - - /* 800 -> 80, 800-80 = 720/n_steps = x , cur = 80 + x * (n_steps - steps) */ - - x2 = anim->zoom_end_x2 + ( ( ((float)anim->zoom_start_x2 - anim->zoom_end_x2)/ (float)anim->n_steps) * (anim->n_steps - anim->step) ); - - x1 = anim->zoom_end_x1 + ( ( ((float)anim->zoom_start_x1 - anim->zoom_end_x1)/ (float)anim->n_steps) * (anim->n_steps - anim->step) ); - - y1 = anim->zoom_end_y1 + ( ( ((float)anim->zoom_start_y1 - anim->zoom_end_y1)/ (float)anim->n_steps) * (anim->n_steps - anim->step) ); - - y2 = anim->zoom_end_y2 + ( ( ((float)anim->zoom_start_y2 - anim->zoom_end_y2)/ (float)anim->n_steps) * (anim->n_steps - anim->step) ); - - /* - glOrtho( anim->zoom_end_x1, x2-1, - anim->zoom_end_y2-1, anim->zoom_end_y1, - -1, 1); - */ - - glOrtho( x1, x2-1, y2-1, y1, - -1, 1); - - glMatrixMode (GL_MODELVIEW); - glLoadIdentity (); - - anim->wrapped_paint_func(widget); - - glPopMatrix(); - - /* reset here */ -} - -/* Hack, we need somehow to reset the viewport - * XXX Hook this into anim->widget hide() - * XXX Call this every time for every render ? -*/ -void -cltr_animator_reset(CltrAnimator *anim) -{ - ClutterMainContext *ctx = CLTR_CONTEXT(); - - clrt_window_set_gl_viewport(ctx->window); -} - - -static gboolean -cltr_animator_timeout_cb(gpointer data) -{ - CltrAnimator *anim = (CltrAnimator *)data; - - CLTR_MARK(); - - anim->step++; - - if (anim->step > anim->n_steps) - { - if (anim->anim_finish_cb) - anim->anim_finish_cb(anim, anim->anim_finish_data); - - anim->widget->paint = anim->wrapped_paint_func; - - return FALSE; - } - - cltr_widget_queue_paint(anim->widget); - - return TRUE; -} - -void -cltr_animator_run(CltrAnimator *anim, - CltrAnimatorFinishFunc finish_callback, - gpointer *finish_data) -{ - anim->anim_finish_cb = finish_callback; - anim->anim_finish_data = finish_data; - - - switch (anim->type) - { - case CltrAnimatorZoom: - anim->widget->paint = cltr_animator_wrapped_zoom_paint; - break; - case CltrAnimatorFullZoom: - /* anim->widget->paint = cltr_animator_wrapped_fullzoom_paint; */ - break; - case CltrAnimatorMove: - anim->widget->paint = cltr_animator_wrapped_move_paint; - break; - } - - anim->step = 0; - - g_timeout_add(FPS_TO_TIMEOUT(anim->fps), - cltr_animator_timeout_cb, anim); -} - diff --git a/clutter/cltr-animator.h b/clutter/cltr-animator.h deleted file mode 100644 index d0014cdc1..000000000 --- a/clutter/cltr-animator.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef _HAVE_CLTR_ANIMATOR_H -#define _HAVE_CLTR_ANIMATOR_H - -#include "cltr.h" - -typedef struct CltrAnimator CltrAnimator; - -typedef enum CltrAnimatorType -{ - CltrAnimatorZoom, - CltrAnimatorFullZoom, - CltrAnimatorMove -} -CltrAnimatorType; - -typedef void (*CltrAnimatorFinishFunc) (CltrAnimator *anim, void *userdata) ; - -CltrAnimator* -cltr_animator_zoom_new(CltrWidget *widget, - int src_x1, - int src_y1, - int src_x2, - int src_y2, - int dst_x1, - int dst_y1, - int dst_x2, - int dst_y2); - -CltrAnimator* -cltr_animator_fullzoom_new(CltrWidget *widget, - int x1, - int y1, - int x2, - int y2); - -/* HACK */ -void -cltr_animator_reset(CltrAnimator *anim); - -void -cltr_animator_run(CltrAnimator *anim, - CltrAnimatorFinishFunc finish_callback, - gpointer *finish_data); - -#endif diff --git a/clutter/cltr-button.c b/clutter/cltr-button.c deleted file mode 100644 index c353b2a77..000000000 --- a/clutter/cltr-button.c +++ /dev/null @@ -1,296 +0,0 @@ -#include "cltr-button.h" -#include "cltr-private.h" - -struct CltrButton -{ - CltrWidget widget; - CltrLabel *label; - Pixmap *pixb; - CltrTexture *texture; - - CltrButtonActivate activate_cb; - void *activate_cb_data; - - - CltrButtonState state; /* may be better in widget ? */ -}; - -#define BUTTON_BORDER 1 -#define BUTTON_PAD 5 - -static void -cltr_button_show(CltrWidget *widget); - -static gboolean -cltr_button_handle_xevent (CltrWidget *widget, XEvent *xev); - -static void -cltr_button_paint(CltrWidget *widget); - -static void -cltr_button_focus(CltrWidget *widget); - -static void -cltr_button_unfocus(CltrWidget *widget); - - -CltrWidget* -cltr_button_new(int width, int height) -{ - CltrButton *button; - - button = g_malloc0(sizeof(CltrButton)); - - button->widget.width = width; - button->widget.height = height; - - button->widget.show = cltr_button_show; - button->widget.paint = cltr_button_paint; - button->widget.focus_in = cltr_button_focus; - button->widget.focus_out = cltr_button_unfocus; - button->widget.xevent_handler = cltr_button_handle_xevent; - - return CLTR_WIDGET(button); -} - -void -cltr_button_on_activate(CltrButton *button, - CltrButtonActivate callback, - void *userdata) -{ - button->activate_cb = callback; - button->activate_cb_data = userdata; -} - -CltrWidget* -cltr_button_new_with_label(const char *label, - CltrFont *font, - PixbufPixel *col) -{ - CltrButton *button = NULL; - - button = CLTR_BUTTON(cltr_button_new(-1, -1)); - - button->label = CLTR_LABEL(cltr_label_new(label, font, col)); - - button->widget.width = cltr_widget_width((CltrWidget*)button->label) + (2 * ( BUTTON_BORDER + BUTTON_PAD)); - button->widget.height = cltr_widget_height((CltrWidget*)button->label) + ( 2 * ( BUTTON_BORDER + BUTTON_PAD)); - - CLTR_DBG("width: %i, height %i", - cltr_widget_width((CltrWidget*)button->label), - cltr_widget_height((CltrWidget*)button->label)); - - cltr_widget_add_child(CLTR_WIDGET(button), - CLTR_WIDGET(button->label), - ( BUTTON_BORDER + BUTTON_PAD), - ( BUTTON_BORDER + BUTTON_PAD)); - - return CLTR_WIDGET(button); -} - -void -cltr_button_set_label(CltrButton *button, - const char *text, - CltrFont *font, - PixbufPixel *col) -{ - int x, y; - - if (button->label) - { - cltr_label_set_text(button->label, text); - } - else - { - button->label = CLTR_LABEL(cltr_label_new(text, font, col)); - - x = (cltr_widget_width(CLTR_WIDGET(button)) - cltr_widget_width(CLTR_WIDGET(button->label)))/2; - - y = (cltr_widget_height(CLTR_WIDGET(button)) - cltr_widget_height(CLTR_WIDGET(button->label)))/2; - - cltr_widget_add_child(CLTR_WIDGET(button), - CLTR_WIDGET(button->label), - x, y); - } -} - -CltrWidget* -cltr_button_new_with_pixbuf(Pixbuf *pixb) -{ - CltrButton *button = NULL; - - button = CLTR_BUTTON(cltr_button_new(-1, -1)); - - return CLTR_WIDGET(button); -} - -static void -cltr_button_show(CltrWidget *widget) -{ - -} - -static void -cltr_button_focus(CltrWidget *widget) -{ - CltrButton *button = CLTR_BUTTON(widget); - - if (button->state != CltrButtonStateFocused) - { - button->state = CltrButtonStateFocused; - cltr_widget_queue_paint(widget); - } -} - -static void -cltr_button_unfocus(CltrWidget *widget) -{ - CltrButton *button = CLTR_BUTTON(widget); - - if (button->state != CltrButtonStateInactive) - { - button->state = CltrButtonStateInactive; - - cltr_widget_queue_paint(CLTR_WIDGET(button)); - } -} - -static void -cltr_button_handle_xkeyevent(CltrButton *button, XKeyEvent *xkeyev) -{ - KeySym kc; - CltrButtonState old_state; - CltrWidget *next_focus = NULL; - - old_state = button->state; - - kc = XKeycodeToKeysym(xkeyev->display, xkeyev->keycode, 0); - - switch (kc) - { - case XK_Left: - case XK_KP_Left: - if (xkeyev->type != KeyPress) - break; - next_focus = cltr_widget_get_focus_next(CLTR_WIDGET(button), CLTR_WEST); - break; - case XK_Up: - case XK_KP_Up: - if (xkeyev->type != KeyPress) - break; - - next_focus = cltr_widget_get_focus_next(CLTR_WIDGET(button), CLTR_NORTH); - break; - case XK_Right: - case XK_KP_Right: - if (xkeyev->type != KeyPress) - break; - - next_focus = cltr_widget_get_focus_next(CLTR_WIDGET(button), CLTR_EAST); - break; - case XK_Down: - case XK_KP_Down: - if (xkeyev->type != KeyPress) - break; - - next_focus = cltr_widget_get_focus_next(CLTR_WIDGET(button), CLTR_SOUTH); - break; - case XK_Return: - if (xkeyev->type == KeyPress) - { - if (button->state != CltrButtonStateActive) - button->state = CltrButtonStateActive; - CLTR_DBG("press"); - - if (button->activate_cb) - button->activate_cb(CLTR_WIDGET(button), button->activate_cb_data); - - } - else /* KeyRelease */ - { - CLTR_DBG("release"); - if (button->state != CltrButtonStateFocused) - button->state = CltrButtonStateFocused; - - /* What to do about key repeats ? */ - - } - break; - default: - /* ??? */ - break; - } - - if (button->state != old_state) - { - CLTR_DBG("queueing paint"); - cltr_widget_queue_paint(CLTR_WIDGET(button)); - } - - if (next_focus) - { - /* Evil - need to centralise focus management */ - ClutterMainContext *ctx = CLTR_CONTEXT(); - cltr_window_focus_widget(CLTR_WIDGET(ctx->window), next_focus); - } -} - - -static gboolean -cltr_button_handle_xevent (CltrWidget *widget, XEvent *xev) -{ - CltrButton *button = CLTR_BUTTON(widget); - - switch (xev->type) - { - case KeyPress: - case KeyRelease: - CLTR_DBG("KeyPress"); - cltr_button_handle_xkeyevent(button, &xev->xkey); - break; - } - - return TRUE; -} - - -static void -cltr_button_paint(CltrWidget *widget) -{ - PixbufPixel bgcol = { 0xe7, 0xe7, 0xe7, 0xff }; - PixbufPixel boxcol = { 0xd7, 0xd7, 0xd7, 0xff }; - PixbufPixel hlfontcol = { 0xe6, 0x99, 0x99, 0xff }; - - CltrButton *button = CLTR_BUTTON(widget); - - CLTR_MARK(); - - glPushMatrix(); - - glEnable(GL_BLEND); - - switch (button->state) - { - case CltrButtonStateFocused: - cltr_glu_set_color(&hlfontcol); - break; - case CltrButtonStateActive: - glColor4f(1.0, 1.0, 1.0, 1.0); - break; - default: - cltr_glu_set_color(&bgcol); - } - - cltr_glu_rounded_rect(cltr_widget_abs_x(widget), - cltr_widget_abs_y(widget), - cltr_widget_abs_x2(widget), - cltr_widget_abs_y2(widget), - 1, 2, - NULL); - - glDisable(GL_BLEND); - - glPopMatrix(); -} - - diff --git a/clutter/cltr-button.h b/clutter/cltr-button.h deleted file mode 100644 index c07ea7906..000000000 --- a/clutter/cltr-button.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _HAVE_CLTR_BUTTON_H -#define _HAVE_CLTR_BUTTON_H - -#include "cltr.h" - -typedef struct CltrButton CltrButton; - -typedef enum CltrButtonState -{ - CltrButtonStateDisabled, - CltrButtonStateInactive, - CltrButtonStateFocused, - CltrButtonStateActive, - } -CltrButtonState; - -typedef void (*CltrButtonActivate) (CltrWidget *widget, void *userdata) ; - -#define CLTR_BUTTON(w) ((CltrButton*)(w)) - -CltrWidget* -cltr_button_new(int width, int height); - -void -cltr_button_on_activate(CltrButton *button, - CltrButtonActivate callback, - void* userdata); - -void -cltr_button_set_label(CltrButton *button, - const char *text, - CltrFont *font, - PixbufPixel *col); - -#endif diff --git a/clutter/cltr-core.c b/clutter/cltr-core.c deleted file mode 100644 index d4294cbbf..000000000 --- a/clutter/cltr-core.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "cltr-core.h" -#include "cltr-private.h" - -int -cltr_init(int *argc, char ***argv) -{ - -#define GLX_SAMPLE_BUFFERS_ARB 100000 -#define GLX_SAMPLES_ARB 100001 - - - int gl_attributes[] = - { - GLX_RGBA, - GLX_DOUBLEBUFFER, - GLX_STENCIL_SIZE, 1, - GLX_DEPTH_SIZE, 24, - - /* - GLX_SAMPLE_BUFFERS_ARB, 1, - GLX_SAMPLES_ARB, 0, - - */ - /* - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - */ - 0 - }; - - XVisualInfo *vinfo; - - gst_init (argc, argv); - - if (!g_thread_supported ()) - g_thread_init (NULL); - - /* XInitThreads (); */ - - if ((CltrCntx.xdpy = XOpenDisplay(getenv("DISPLAY"))) == NULL) - { - return 0; - } - - CltrCntx.xscreen = DefaultScreen(CltrCntx.xdpy); - CltrCntx.xwin_root = RootWindow(CltrCntx.xdpy, CltrCntx.xscreen); - - CLTR_DBG("EXT : %s", glXQueryExtensionsString( CltrCntx.xdpy, - CltrCntx.xscreen)); - - - if ((vinfo = glXChooseVisual(CltrCntx.xdpy, - CltrCntx.xscreen, - gl_attributes)) == NULL) - { - fprintf(stderr, "Unable to find visual\n"); - return 0; - } - - CltrCntx.gl_context = glXCreateContext(CltrCntx.xdpy, vinfo, 0, True); - - pixel_set_vals(&CltrCntx.colors[CLTR_COL_BG], 0xff, 0xff, 0xff, 0xff ); - pixel_set_vals(&CltrCntx.colors[CLTR_COL_BDR],0xff, 0xff, 0xff, 0xff ); - pixel_set_vals(&CltrCntx.colors[CLTR_COL_FG], 0xff, 0xff, 0xff, 0xff ); - - cltr_events_init(); - - return 1; -} - -int -cltr_display_width(void) -{ - ClutterMainContext *ctx = CLTR_CONTEXT(); - - return DisplayWidth(ctx->xdpy, ctx->xscreen); -} - -int -cltr_display_height(void) -{ - ClutterMainContext *ctx = CLTR_CONTEXT(); - - return DisplayHeight(ctx->xdpy, ctx->xscreen); -} - -PixbufPixel* -cltr_core_get_color(CltrNamedColor col) -{ - ClutterMainContext *ctx = CLTR_CONTEXT(); - - return &ctx->colors[col]; -} diff --git a/clutter/cltr-core.h b/clutter/cltr-core.h deleted file mode 100644 index 9175b039f..000000000 --- a/clutter/cltr-core.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _HAVE_CLTR_CORE_H -#define _HAVE_CLTR_CORE_H - -#include "cltr.h" - -int -cltr_init(int *argc, char ***argv); - -int -cltr_display_height(void); - -int -cltr_display_width(void); - -#endif diff --git a/clutter/cltr-events.c b/clutter/cltr-events.c deleted file mode 100644 index 8f9557bd1..000000000 --- a/clutter/cltr-events.c +++ /dev/null @@ -1,183 +0,0 @@ -#include - -#include "cltr-events.h" -#include "cltr-private.h" - -typedef void (*CltrXEventFunc) (XEvent *xev, gpointer user_data); - -typedef struct -{ - GSource source; - Display *display; - GPollFD event_poll_fd; -} -CltrXEventSource; - -static gboolean -x_event_prepare (GSource *source, - gint *timeout) -{ - Display *display = ((CltrXEventSource*)source)->display; - - *timeout = -1; - - return XPending (display); -} - -static gboolean -x_event_check (GSource *source) -{ - CltrXEventSource *display_source = (CltrXEventSource*)source; - gboolean retval; - - if (display_source->event_poll_fd.revents & G_IO_IN) - retval = XPending (display_source->display); - else - retval = FALSE; - - return retval; -} - -static gboolean -x_event_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data) -{ - Display *display = ((CltrXEventSource*)source)->display; - CltrXEventFunc event_func = (CltrXEventFunc) callback; - - XEvent xev; - - if (XPending (display)) - { - XNextEvent (display, &xev); - - if (event_func) - (*event_func) (&xev, user_data); - } - - return TRUE; -} - -static const GSourceFuncs x_event_funcs = { - x_event_prepare, - x_event_check, - x_event_dispatch, - NULL -}; - -void -cltr_dispatch_expose(XExposeEvent *xexpev) -{ - // cltr_photo_grid_redraw(Grid); -} - -void -cltr_dispatch_x_event (XEvent *xevent, - gpointer data) -{ - /* Should actually forward on to focussed widget */ - - ClutterMainContext *ctx = CLTR_CONTEXT(); - - cltr_widget_handle_xevent(ctx->window, xevent); - -#if 0 - switch (xevent->type) - { - case MapNotify: - CLTR_DBG("Map Notify Event"); - break; - case Expose: - CLTR_DBG("Expose"); /* TODO COMPRESS */ - cltr_dispatch_expose(&xevent->xexpose); - break; - case KeyPress: - CLTR_DBG("KeyPress"); - cltr_dispatch_keypress(&xevent->xkey); - break; - } -#endif -} - -void -cltr_events_init() -{ - GMainContext *gmain_context; - int connection_number; - GSource *source; - CltrXEventSource *display_source; - - ClutterMainContext *ctx = CLTR_CONTEXT(); - - /* g_main loop stuff */ - - gmain_context = g_main_context_default (); - - g_main_context_ref (gmain_context); - - connection_number = ConnectionNumber (CltrCntx.xdpy); - - source = g_source_new ((GSourceFuncs *)&x_event_funcs, - sizeof (CltrXEventSource)); - - display_source = (CltrXEventSource *)source; - - display_source->event_poll_fd.fd = connection_number; - display_source->event_poll_fd.events = G_IO_IN; - display_source->display = CltrCntx.xdpy; - - g_source_add_poll (source, &display_source->event_poll_fd); - g_source_set_can_recurse (source, TRUE); - - g_source_set_callback (source, - (GSourceFunc) cltr_dispatch_x_event, - NULL /* no userdata */, NULL); - - g_source_attach (source, gmain_context); - g_source_unref (source); - - ctx->internal_event_q = g_async_queue_new(); -} - -void -cltr_main_loop() -{ - ClutterMainContext *ctx = CLTR_CONTEXT(); - - /* - GMainLoop *loop; - - loop = g_main_loop_new (g_main_context_default (), FALSE); - - g_main_loop_run (loop); - */ - - while (TRUE) - { - if (g_async_queue_length (ctx->internal_event_q)) - { - CltrWindow *win = CLTR_WINDOW(ctx->window); - - /* Empty the queue */ - while (g_async_queue_try_pop(ctx->internal_event_q) != NULL) ; - - /* Repaint everything visible from window down - URG. - * GL workings make it difficult to paint single part with - * layering etc.. - * Is this really bad ? time will tell... - */ - cltr_widget_paint(CLTR_WIDGET(win)); - - /* pre paint in window paint method */ - cltr_window_post_paint(win); - - /* Swap Buffers */ - glXSwapBuffers(ctx->xdpy, cltr_window_xwin(win)); - } - - /* while (g_main_context_pending(g_main_context_default ())) */ - g_main_context_iteration (g_main_context_default (), TRUE); - - } -} diff --git a/clutter/cltr-events.h b/clutter/cltr-events.h deleted file mode 100644 index 48180e9b1..000000000 --- a/clutter/cltr-events.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _HAVE_CLTR_EVENT_H -#define _HAVE_CLTR_EVENT_H - -#include "cltr.h" - - - -void -cltr_main_loop(); - -void -cltr_dispatch_x_event (XEvent *xevent, - gpointer data); - -void -cltr_events_init(); - -#endif diff --git a/clutter/cltr-glu.c b/clutter/cltr-glu.c deleted file mode 100644 index e658570e8..000000000 --- a/clutter/cltr-glu.c +++ /dev/null @@ -1,156 +0,0 @@ -#include "cltr-glu.h" -#include "cltr-private.h" - -/* Clutter GL Utility routines */ - -#define PI 3.1415926535897932384626433832795 - -void -cltr_glu_set_color(PixbufPixel *p) -{ - glColor4ub(p->r, p->b, p->g, p->a); -} - -void -cltr_glu_rounded_rect(int x1, - int y1, - int x2, - int y2, - int line_width, - int radius, - PixbufPixel *col) -{ - double ang = 0; - int width = x2-x1, height = y2-y1; - float cX = x1+radius, cY = y1+radius; - - if (col) - cltr_glu_set_color(col); - - glLineWidth(line_width); - - glBegin(GL_LINES); - glVertex2f(x1, y1 + radius); - glVertex2f(x1, y1 + height - radius); /* Left Line */ - - glVertex2f(x1 + radius, y1); - glVertex2f(x1 + width - radius, y1); /* Top Line */ - - glVertex2f(x1 + width, y1 + radius); - glVertex2f(x1 + width, y1 + height - radius); /* Right Line */ - - glVertex2f(x1 + radius, y1 + height); - glVertex2f(x1 + width - radius, y1 + height); /* Bottom Line */ - glEnd(); - - /* corners */ - - glBegin(GL_LINE_STRIP); - - /* Top Left */ - for(ang = PI; ang <= (1.5*PI); ang = ang + 0.05) - { - glVertex2d(radius* cos(ang) + cX, radius * sin(ang) + cY); - } - - glEnd(); - - /* Top Right */ - - cX = x1 + width-radius; - - glBegin(GL_LINE_STRIP); - - for(ang = (1.5*PI); ang <= (2 * PI); ang = ang + 0.05) - { - glVertex2d(radius* cos(ang) + cX, radius * sin(ang) + cY); - } - - glEnd(); - - glBegin(GL_LINE_STRIP); - - cY = y1 + height-radius; - - /* Bottom Right */ - - for(ang = 0; ang <= (0.5*PI); ang = ang + 0.05) - { - glVertex2d(radius* cos(ang) + cX, radius * sin(ang) + cY); - } - - glEnd(); - - glBegin(GL_LINE_STRIP); - - cX = x1 + radius; - - /* Bottom Left */ - - for(ang = (0.5*PI); ang <= PI; ang = ang + 0.05) - { - glVertex2d(radius* cos(ang) + cX, radius * sin(ang) + cY); - - } - glEnd(); - -} - -void -cltr_glu_rounded_rect_filled(int x1, - int y1, - int x2, - int y2, - int radius, - PixbufPixel *col) -{ - double i = 0; - double gap = 0.05; - float cX = x1 + radius, cY = y1 + radius; - - if (col) - cltr_glu_set_color(col); - - glBegin(GL_POLYGON); - - /* Left Line */ - glVertex2f(x1, y2 - radius); - glVertex2f(x1, y1 + radius); - - /* Top Left */ - for(i = PI; i <= (1.5*PI); i += gap) - glVertex2d(radius* cos(i) + cX, radius * sin(i) + cY); - - /* Top Line */ - glVertex2f(x1 + radius, y1); - glVertex2f(x2 - radius, y1); - - cX = x2 - radius; - - /* Top Right */ - for(i = (1.5*PI); i <= (2 * PI); i += gap) - glVertex2d(radius* cos(i) + cX, radius * sin(i) + cY); - - glVertex2f(x2, y1 + radius); - - /* Right Line */ - glVertex2f(x2, y2 - radius); - - cY = y2 - radius; - - /* Bottom Right */ - for(i = 0; i <= (0.5*PI); i+=gap) - glVertex2d(radius* cos(i) + cX, radius * sin(i) + cY); - - /* Bottom Line */ - glVertex2f(x1 + radius, y2); - glVertex2f(x2 - radius, y2); - - /* Bottom Left */ - cX = x1 + radius; - for(i = (0.5*PI); i <= PI; i += gap) - glVertex2d(radius* cos(i) + cX, radius * sin(i) + cY); - - glEnd(); -} - diff --git a/clutter/cltr-glu.h b/clutter/cltr-glu.h deleted file mode 100644 index 3d5de1570..000000000 --- a/clutter/cltr-glu.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _HAVE_CLTR_GLU_H -#define _HAVE_CLTR_GLU_H - -#include "cltr.h" - -void -cltr_glu_set_color(PixbufPixel *p); - -void -cltr_glu_rounded_rect(int x1, - int y1, - int x2, - int y2, - int line_width, - int radius, - PixbufPixel *col); - -void -cltr_glu_rounded_rect_filled(int x1, - int y1, - int x2, - int y2, - int radius, - PixbufPixel *col); - -#endif diff --git a/clutter/cltr-label.c b/clutter/cltr-label.c deleted file mode 100644 index df1e3baa1..000000000 --- a/clutter/cltr-label.c +++ /dev/null @@ -1,165 +0,0 @@ -#include "cltr-label.h" -#include "cltr-private.h" - -struct CltrLabel -{ - CltrWidget widget; - - char *text; - Pixbuf *pixb; - PixbufPixel col; - CltrFont *font; - CltrTexture *texture; -}; - -static void -cltr_label_show(CltrWidget *widget); - -static gboolean -cltr_label_handle_xevent (CltrWidget *widget, XEvent *xev); - -static void -cltr_label_paint(CltrWidget *widget); - - -CltrWidget* -cltr_label_new(const char *text, - CltrFont *font, - PixbufPixel *col) -{ - CltrLabel *label; - int width,height; - - label = g_malloc0(sizeof(CltrLabel)); - - font_get_pixel_size (font, text, &width, &height); - - if (width && height) - { - PixbufPixel bg = { 0x00, 0x00, 0x00, 0x00 }; - - label->text = strdup(text); - label->pixb = pixbuf_new(width, height); - - pixbuf_fill_rect(label->pixb, 0, 0, -1, -1, &bg); - - font_draw(font, - label->pixb, - label->text, - 0, - 0, - col); - - label->texture = cltr_texture_new(label->pixb); - } - - label->font = font; /* XXX Ref The font XXX*/ - - memcpy(&label->col, col, sizeof(PixbufPixel)); - - label->widget.width = width; - label->widget.height = height; - - label->widget.show = cltr_label_show; - label->widget.paint = cltr_label_paint; - - label->widget.xevent_handler = cltr_label_handle_xevent; - - return CLTR_WIDGET(label); -} - -void -cltr_label_set_text(CltrLabel *label, char *text) -{ - int width,height; - - if (label->texture) - cltr_texture_unref(label->texture); - - if (label->pixb) - cltr_texture_unref(label->pixb); - - if (label->text) - free(label->text); - - font_get_pixel_size (label->font, text, &width, &height); - - if (width && height) - { - PixbufPixel bg = { 0x00, 0x00, 0x00, 0x00 }; - PixbufPixel col = { 0xff, 0xff, 0xff, 0xff }; - - label->widget.width = width; - label->widget.height = height; - - CLTR_DBG("** setting label to %s ***", text); - - label->text = strdup(text); - label->pixb = pixbuf_new(width, height); - - pixbuf_fill_rect(label->pixb, 0, 0, -1, -1, &bg); - - font_draw(label->font, - label->pixb, - label->text, - 0, - 0, - &label->col); - - label->texture = cltr_texture_new(label->pixb); - - } - -} - -const char* -cltr_label_get_text(CltrLabel *label) -{ - return label->text; -} - -static void -cltr_label_show(CltrWidget *widget) -{ - ; -} - -static gboolean -cltr_label_handle_xevent (CltrWidget *widget, XEvent *xev) -{ - ; -} - -static void -cltr_label_paint(CltrWidget *widget) -{ - CltrLabel *label = CLTR_LABEL(widget); - - CLTR_MARK(); - - if (label->text) - { - - glPushMatrix(); - - glEnable(GL_TEXTURE_2D); - - glEnable(GL_BLEND); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - /* glColor4f(1.0, 1.0, 1.0, 1.0); */ - - cltr_texture_render_to_gl_quad(label->texture, - cltr_widget_abs_x(widget), - cltr_widget_abs_y(widget), - cltr_widget_abs_x2(widget), - cltr_widget_abs_y2(widget)); - - glDisable(GL_BLEND); - - glDisable(GL_TEXTURE_2D); - - glPopMatrix(); - } -} diff --git a/clutter/cltr-label.h b/clutter/cltr-label.h deleted file mode 100644 index d66ba4946..000000000 --- a/clutter/cltr-label.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _HAVE_CLTR_LABEL_H -#define _HAVE_CLTR_LABEL_H - -#include "cltr.h" - -typedef struct CltrLabel CltrLabel; - -#define CLTR_LABEL(w) ((CltrLabel*)(w)) - -CltrWidget* -cltr_label_new(const char *text, - CltrFont *font, - PixbufPixel *col); - -void -cltr_label_set_text(CltrLabel *label, char *text); - -#endif diff --git a/clutter/cltr-list.c b/clutter/cltr-list.c deleted file mode 100644 index 6bbd5334c..000000000 --- a/clutter/cltr-list.c +++ /dev/null @@ -1,514 +0,0 @@ -#include "cltr-list.h" -#include "cltr-private.h" - -#define ANIM_FPS 50 -#define FPS_TO_TIMEOUT(t) (1000/(t)) - -struct CltrListCell -{ - CltrRect rect; - - Pixbuf *thumb_pixb; - CltrTexture *thumb_texture; - - Pixbuf *text_pixb; - CltrTexture *text_texture; - -}; - -struct CltrList -{ - CltrWidget widget; - GList *cells, *active_cell; - int active_cell_y; - int cell_height; - int cell_width; - - int n_cells; - - CltrListCellActivate cell_activate_cb; - gpointer cell_activate_data; - - CltrListState state; - int scroll_dir; - -}; - -#define PAD 10 - -static void -cltr_list_show(CltrWidget *widget); - -static gboolean -cltr_list_handle_xevent (CltrWidget *widget, XEvent *xev); - -static void -cltr_list_paint(CltrWidget *widget); - -static float -distfunc(CltrList *list, int d) -{ - int maxdist = list->widget.height; - - d = (maxdist-ABS(d)) ; - return ( exp( (float)d/maxdist * 0.8 ) / exp(0.8) ) ; -} - -CltrListCell* -cltr_list_cell_new(CltrList *list, - Pixbuf *thumb_pixb, - char *text) -{ - CltrListCell *cell = NULL; - ClutterFont *font; - PixbufPixel pixel = { 0, 0, 0, 0 }, font_pixel = { 255, 255, 255, 255}; - - font = font_new ("Sans Bold 24"); - - cell = g_malloc0(sizeof(CltrListCell)); - - cell->thumb_pixb = thumb_pixb; - pixbuf_ref(cell->thumb_pixb); - cell->thumb_texture = cltr_texture_new(cell->thumb_pixb); - - cell->text_pixb = pixbuf_new(list->cell_width - (list->cell_width/4), - (list->cell_height/2) - (2*PAD)); - - pixbuf_fill_rect(cell->text_pixb, 0, 0, -1, -1, &pixel); - font_draw(font, cell->text_pixb, text, 0, 0, &font_pixel); - cell->text_texture = cltr_texture_new(cell->text_pixb); - - return cell; -} - -void -cltr_list_cell_set_pixbuf(CltrListCell *cell, - Pixbuf *thumb_pixb) -{ - cltr_texture_unref(cell->thumb_texture); - - cell->thumb_pixb = thumb_pixb; - - cell->thumb_texture = cltr_texture_new(cell->thumb_pixb); - -} - -CltrWidget* -cltr_list_new(int width, - int height, - int cell_width, - int cell_height) -{ - CltrList *list; - - list = g_malloc0(sizeof(CltrList)); - - list->widget.width = width; - list->widget.height = height; - - list->widget.show = cltr_list_show; - list->widget.paint = cltr_list_paint; - - list->cell_height = cell_height; /* maximum */ - list->cell_width = cell_width; /* maximum */ - - list->widget.xevent_handler = cltr_list_handle_xevent; - - return CLTR_WIDGET(list); -} - -void -cltr_list_append_cell(CltrList *list, CltrListCell *cell) -{ - list->cells = g_list_append(list->cells, cell); - - if (!list->active_cell) - list->active_cell = g_list_first(list->cells); - - list->n_cells++; -} - -static void -video_box_co_ords(CltrList *list, - CltrListCell *cell, - int *x1, int *y1, int *x2, int *y2) -{ - CltrWidget *widget = CLTR_WIDGET(list); - int vw, vh; - - vh = cltr_rect_y2(cell->rect) - cltr_rect_y1(cell->rect); - vh -= (PAD*2); - vw = ( widget->width * vh ) / widget->height; - - *x1 = cltr_rect_x1(cell->rect) + PAD; *x2 = *x1 + vw; - *y1 = cltr_rect_y1(cell->rect) + PAD; *y2 = *y1 + vh; -} - -/* - * This is messy hack as cells arn't real widgets :( - * - */ -gboolean -cltr_list_get_active_cell_video_box_co_ords(CltrList *list, - int *x1, - int *y1, - int *x2, - int *y2) -{ - if (list->active_cell) - { - CltrListCell *cell = list->active_cell->data; - - video_box_co_ords(list, cell, x1, y1, x2, y2); - - return TRUE; - } - return FALSE; -} - -static void -cltr_list_show(CltrWidget *widget) -{ - CltrList *list = CLTR_LIST(widget); - CltrListCell *cell = NULL; - - if (list->active_cell_y == 0) - { - list->active_cell_y = (widget->height / 2) - (list->cell_height/2); - - list->active_cell = g_list_first(list->cells); - - cell = list->active_cell->data; - - cell->rect.y = list->active_cell_y; - } - - list->state = CLTR_LIST_STATE_BROWSE; - - cltr_list_update_layout(list); - - cltr_widget_queue_paint(widget); -} - -void -cltr_list_on_activate_cell(CltrList *list, - CltrListCellActivate callback, - gpointer *userdata) -{ - list->cell_activate_cb = callback; - list->cell_activate_data = userdata; -} - -CltrListCell* -cltr_list_get_active_cell(CltrList *list) -{ - if (list->active_cell) - return list->active_cell->data; - - return NULL; -} - -static gboolean -cltr_list_handle_xevent (CltrWidget *widget, XEvent *xev) -{ - CltrList *list = CLTR_LIST(widget); - - switch (xev->type) - { - case KeyPress: - { - KeySym kc; - - kc = XKeycodeToKeysym(xev->xkey.display, xev->xkey.keycode, 0); - - switch (kc) - { - case XK_Up: - case XK_KP_Up: - cltr_list_scroll_up(list); - break; - case XK_Down: - case XK_KP_Down: - cltr_list_scroll_down(list); - break; - case XK_Return: - if (list->cell_activate_cb && list->active_cell) - list->cell_activate_cb(list, - list->active_cell->data, - list->cell_activate_data); - break; - case XK_Left: - case XK_KP_Left: - case XK_Right: - case XK_KP_Right: - default: - CLTR_DBG("unhandled keysym"); - } - } - break; - } - - return TRUE; -} - -static void -cltr_list_animate(CltrList *list) -{ - GList *cell_item = NULL; - CltrListCell *next_active = NULL, *cell_top = NULL; - - cell_top = (CltrListCell *)g_list_nth_data(list->cells, 0); - int i = 0; - - for (;;) - { - if (list->state == CLTR_LIST_STATE_SCROLL_UP) - { - cell_item = g_list_previous(list->active_cell); - - if (!cell_item) - { - list->state = CLTR_LIST_STATE_BROWSE; - return; - } - - next_active = (CltrListCell *)cell_item->data; - - if (next_active->rect.y < list->active_cell_y) - { - cell_top->rect.y += 1; - } - else - { - list->active_cell = cell_item; - list->state = CLTR_LIST_STATE_BROWSE; - return; - } - } - else if (list->state == CLTR_LIST_STATE_SCROLL_DOWN) - { - cell_item = g_list_next(list->active_cell); - - if (!cell_item) - { - list->state = CLTR_LIST_STATE_BROWSE; - return; - } - - next_active = (CltrListCell *)cell_item->data; - - if (next_active->rect.y > list->active_cell_y) - { - cell_top->rect.y -= 1; - } - else - { - list->active_cell = cell_item; - list->state = CLTR_LIST_STATE_BROWSE; - return; - } - } - - if (++i > 10) - return; - - cltr_list_update_layout(list); - } -} - -gboolean -cltr_list_timeout_cb(gpointer data) -{ - CltrList *list = (CltrList *)data; - - cltr_list_animate(list); - - cltr_widget_queue_paint(CLTR_WIDGET(list)); - - switch(list->state) - { - case CLTR_LIST_STATE_SCROLL_UP: - case CLTR_LIST_STATE_SCROLL_DOWN: - return TRUE; - case CLTR_LIST_STATE_LOADING: - case CLTR_LIST_STATE_LOAD_COMPLETE: - case CLTR_LIST_STATE_BROWSE: - default: - return FALSE; - } -} - -static void -cltr_list_update_layout(CltrList *list) -{ - GList *cell_item = NULL; - CltrListCell *cell = NULL; - int last; - - cell_item = g_list_first(list->cells); - cell = (CltrListCell *)cell_item->data; - - last = cell->rect.y; - - while (cell_item) - { - float scale = 0.0; - - cell = (CltrListCell *)cell_item->data; - - cell->rect.y = last; - - if (cell->rect.y + cell->rect.height >= 0) - { - scale = distfunc(list, cell->rect.y - list->active_cell_y); - - cell->rect.width = list->cell_width * scale; - cell->rect.height = list->cell_height * scale; - - cell->rect.x = (list->widget.width - cell->rect.width) / 2; - } - - last = cell->rect.y + cell->rect.height; - - cell_item = g_list_next(cell_item); - } - -} - -static void -cltr_list_paint(CltrWidget *widget) -{ - GList *cell_item = NULL; - CltrList *list = CLTR_LIST(widget); - CltrListCell *cell = NULL; - int last; - - PixbufPixel col = { 0xff, 0, 0, 0xff }; - PixbufPixel bgcol = { 0xe7, 0xe7, 0xe7, 0xff }; - PixbufPixel boxcol = { 0xd7, 0xd7, 0xd7, 0xff }; - PixbufPixel hlfontcol = { 0xe6, 0x99, 0x99, 0xff }; - - CLTR_MARK(); - - cell_item = g_list_first(list->cells); - cell = (CltrListCell *)cell_item->data; - last = cell->rect.y; - - glPushMatrix(); - - cltr_glu_set_color(&bgcol); - - glRecti(0, 0, widget->width, widget->height); - - glEnable(GL_TEXTURE_2D); - - glEnable(GL_BLEND); - - cltr_list_update_layout(list); - - while (cell_item) - { - float scale = 0.0; - - col.r = 0xff; col.g = 0; col.b = 0; col.a = 0xff; - - cell = (CltrListCell *)cell_item->data; - - last = cell->rect.y + cell->rect.height; - - scale = distfunc(list, cell->rect.y - list->active_cell_y); - - if (last > 0 && cell->rect.y < list->widget.width) /* crappy clip */ - { - glDisable(GL_TEXTURE_2D); - - if (cell_item == list->active_cell && list->state == CLTR_LIST_STATE_BROWSE) - col.b = 0xff; - else - col.b = 0x00; - - cltr_glu_set_color(&boxcol); - - cltr_glu_rounded_rect_filled(cltr_rect_x1(cell->rect), - cltr_rect_y1(cell->rect) + (5.0 * scale), - cltr_rect_x2(cell->rect), - cltr_rect_y2(cell->rect) - (5.0 * scale), - 10, - &boxcol); - - col.r = 0xff; col.g = 0xff; col.b = 0xff; col.a = 0xff; - - /* - cltr_glu_rounded_rect(cltr_rect_x1(cell->rect) + 10, - cltr_rect_y1(cell->rect) + 12, - cltr_rect_x2(cell->rect) - 10, - cltr_rect_y2(cell->rect) - 12, - 10, - &col); - */ - - glEnable(GL_TEXTURE_2D); - - glEnable(GL_BLEND); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - - { - /* Video Box */ - - int vx1, vx2, vy1, vy2; - - video_box_co_ords(list, cell, &vx1, &vy1, &vx2, &vy2); - - cltr_texture_render_to_gl_quad(cell->thumb_texture, - vx1, vy1, vx2, vy2); - - /* Text */ - - if (cell_item == list->active_cell - && list->state == CLTR_LIST_STATE_BROWSE) - cltr_glu_set_color(&hlfontcol); - else - glColor4f(0.4, 0.4, 0.4, 1.0); - - cltr_texture_render_to_gl_quad(cell->text_texture, - vx2 + PAD, - vy1, - cltr_rect_x2(cell->rect) - (2*PAD), - vy1 + (list->cell_height/2) - (2*PAD)); - - } - - glDisable(GL_BLEND); - - } - - cell_item = g_list_next(cell_item); - } - - glDisable(GL_BLEND); - - glDisable(GL_TEXTURE_2D); - - glPopMatrix(); -} - - -void -cltr_list_scroll_down(CltrList *list) -{ - list->state = CLTR_LIST_STATE_SCROLL_DOWN; - - g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS), - cltr_list_timeout_cb, list); -} - -void -cltr_list_scroll_up(CltrList *list) -{ - list->state = CLTR_LIST_STATE_SCROLL_UP; - - g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS), - cltr_list_timeout_cb, list); -} diff --git a/clutter/cltr-list.h b/clutter/cltr-list.h deleted file mode 100644 index ec2d6e0bb..000000000 --- a/clutter/cltr-list.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef _HAVE_CLTR_LIST_H -#define _HAVE_CLTR_LIST_H - -#include "cltr.h" - -typedef struct CltrList CltrList; - -typedef struct CltrListCell CltrListCell; - -#define CLTR_LIST(w) ((CltrList*)(w)) - -typedef void (*CltrListCellActivate) (CltrList *list, - CltrListCell *cell, - void *userdata) ; - -typedef enum CltrListState -{ - CLTR_LIST_STATE_LOADING , - CLTR_LIST_STATE_LOAD_COMPLETE , - CLTR_LIST_STATE_BROWSE , - CLTR_LIST_STATE_SCROLL_UP , - CLTR_LIST_STATE_SCROLL_DOWN -} -CltrListState; - -CltrListCell* -cltr_list_cell_new(CltrList *list, - Pixbuf *thump_pixb, - char *text); - -void -cltr_list_cell_set_pixbuf(CltrListCell *cell, - Pixbuf *thump_pixb); - -void -cltr_list_append_cell(CltrList *list, CltrListCell *cell); - -CltrWidget* -cltr_list_new(int width, - int height, - int cell_width, - int cell_height); - -CltrListCell* -cltr_list_get_active_cell(CltrList *list); - -void -cltr_list_on_activate_cell(CltrList *list, - CltrListCellActivate callback, - gpointer *userdata); - -gboolean -cltr_list_get_active_cell_video_box_co_ords(CltrList *list, - int *x1, - int *y1, - int *x2, - int *y2); - -void -cltr_list_scroll_down(CltrList *list); - -void -cltr_list_scroll_up(CltrList *list); - - -#endif diff --git a/clutter/cltr-overlay.c b/clutter/cltr-overlay.c deleted file mode 100644 index b68103e1c..000000000 --- a/clutter/cltr-overlay.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "cltr-overlay.h" -#include "cltr-private.h" - -struct CltrOverlay -{ - CltrWidget widget; -}; - -static void -cltr_overlay_show(CltrWidget *widget); - -static gboolean -cltr_overlay_handle_xevent (CltrWidget *widget, XEvent *xev); - -static void -cltr_overlay_paint(CltrWidget *widget); - - -CltrWidget* -cltr_overlay_new(int width, int height) -{ - CltrOverlay *overlay; - - overlay = g_malloc0(sizeof(CltrOverlay)); - - overlay->widget.width = width; - overlay->widget.height = height; - - overlay->widget.show = cltr_overlay_show; - overlay->widget.paint = cltr_overlay_paint; - - overlay->widget.xevent_handler = cltr_overlay_handle_xevent; - - return CLTR_WIDGET(overlay); -} - -static void -cltr_overlay_show(CltrWidget *widget) -{ - -} - -static gboolean -cltr_overlay_handle_xevent (CltrWidget *widget, XEvent *xev) -{ - - return FALSE; -} - -static void -cltr_overlay_paint(CltrWidget *widget) -{ - glEnable(GL_BLEND); - - glColor4f(0.5, 0.5, 0.5, 0.5); - - cltr_glu_rounded_rect_filled(widget->x, - widget->y, - widget->x + widget->width, - widget->y + widget->height, - widget->width/30, - NULL); - - glDisable(GL_BLEND); - -} diff --git a/clutter/cltr-overlay.h b/clutter/cltr-overlay.h deleted file mode 100644 index 2d6d1a3e4..000000000 --- a/clutter/cltr-overlay.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _HAVE_CLTR_OVERLAY_H -#define _HAVE_CLTR_OVERLAY_H - -#include "cltr.h" - -typedef struct CltrOverlay CltrOverlay; - -#define CLTR_OVERLAY(w) ((CltrOverlay*)(w)) - -CltrWidget* -cltr_overlay_new(int width, int height); - - -#endif diff --git a/clutter/cltr-photo-grid.c b/clutter/cltr-photo-grid.c deleted file mode 100644 index fa6a43519..000000000 --- a/clutter/cltr-photo-grid.c +++ /dev/null @@ -1,855 +0,0 @@ -#include "cltr-photo-grid.h" -#include "cltr-private.h" - -struct CltrPhotoGridCell -{ - Pixbuf *pixb; - float angle; - CltrTexture *texture; - gint anim_step; - - CltrPhotoGridCellState state; -}; - -struct CltrPhotoGrid -{ - CltrWidget widget; - - gchar *img_path; - - int n_rows; - int n_cols; - int row_offset; /* where is the first visible row. */ - - int cell_width; - int cell_height; - - GList *cells_tail; - GList *cell_active; - - gboolean is_populated; - - /* animation / zoom etc stuff */ - - /* current anim frame position */ - int anim_fps, anim_n_steps, anim_step; - - /* start / end points for animations */ - float zoom_min, zoom_max, zoom_step; - float view_min_x, view_max_x, view_min_y, view_max_y; - float scroll_dist; - - /* Values calucated from above for setting up the GL tranforms and 'view' */ - float paint_trans_x, paint_trans_y, paint_zoom; - int paint_start_y; - - GList *paint_cell_item; - - GMutex *mutex; - - CltrPhotoGridState state; -}; - -static void -cltr_photo_grid_paint(CltrWidget *widget); - -static gboolean -cltr_photo_grid_handle_xevent (CltrWidget *widget, XEvent *xev); - -static void -cltr_photo_grid_show(CltrWidget *widget); - -static void -cltr_photo_grid_update_visual_state(CltrPhotoGrid *grid); - - -GMutex* -cltr_photo_grid_mutex(CltrPhotoGrid *grid) -{ - return grid->mutex; -} - -void -cltr_photo_grid_set_populated(CltrPhotoGrid *grid, gboolean populated) -{ - grid->is_populated = populated; -} - -static void -cltr_photo_grid_handle_xkeyevent(CltrPhotoGrid *grid, XKeyEvent *xkeyev) -{ - KeySym kc; - - kc = XKeycodeToKeysym(xkeyev->display, xkeyev->keycode, 0); - - switch (kc) - { - case XK_Left: - case XK_KP_Left: - cltr_photo_grid_navigate(grid, CLTR_WEST); - break; - case XK_Up: - case XK_KP_Up: - cltr_photo_grid_navigate(grid, CLTR_NORTH); - break; - case XK_Right: - case XK_KP_Right: - cltr_photo_grid_navigate(grid, CLTR_EAST); - break; - case XK_Down: - case XK_KP_Down: - cltr_photo_grid_navigate(grid, CLTR_SOUTH); - break; - case XK_Return: - cltr_photo_grid_activate_cell(grid); - break; - default: - CLTR_DBG("unhandled keysym"); - } -} - -static gboolean -cltr_photo_grid_handle_xevent (CltrWidget *widget, XEvent *xev) -{ - CltrPhotoGrid* grid = CLTR_PHOTO_GRID(widget); - - switch (xev->type) - { - case KeyPress: - CLTR_DBG("KeyPress"); - cltr_photo_grid_handle_xkeyevent(grid, &xev->xkey); - break; - } - - return TRUE; -} - - -CltrPhotoGridCell* -cltr_photo_grid_cell_new(CltrPhotoGrid *grid, - Pixbuf *pixb) -{ - CltrPhotoGridCell *cell = NULL; - int maxw = grid->widget.width, maxh = grid->widget.height; - int neww = 0, newh = 0; - - cell = g_malloc0(sizeof(CltrPhotoGridCell)); - - if (pixb->width > pixb->height) /* landscape */ - { - if (pixb->width > maxw) - { - neww = maxw; - newh = (neww * pixb->height) / pixb->width; - } - } - else /* portrait */ - { - if (pixb->height > maxh) - { - newh = maxh; - neww = (newh * pixb->width) / pixb->height; - } - } - - if (neww || newh) - { - cell->pixb = pixbuf_scale_down(pixb, neww, newh); - pixbuf_unref(pixb); - } - else cell->pixb = pixb; - - cell->texture = cltr_texture_new(cell->pixb); - - cell->angle = 6.0 - (rand()%12); - - cell->anim_step = 15; - cell->state = CLTR_PHOTO_GRID_CELL_STATE_APPEARING; - - return cell; -} - -Pixbuf* -cltr_photo_grid_cell_pixbuf(CltrPhotoGridCell *cell) -{ - return cell->pixb; -} - -CltrPhotoGridCell* -cltr_photo_grid_get_active_cell(CltrPhotoGrid *grid) -{ - if (grid->cell_active) - return grid->cell_active->data; - else - return NULL; -} - -void -cltr_photo_grid_set_active_cell(CltrPhotoGrid *grid, CltrPhotoGridCell *cell) -{ - GList *cell_item = NULL; - - cell_item = g_list_find(g_list_first(grid->cells_tail), (gconstpointer)cell); - - if (cell_item) - grid->cell_active = cell_item; -} - -CltrPhotoGridCell* -cltr_photo_grid_get_first_cell(CltrPhotoGrid *grid) -{ - GList *cell_item = NULL; - - cell_item = g_list_first(grid->cells_tail); - - if (cell_item) - return cell_item->data; - return NULL; -} - -void -cltr_photo_grid_append_cell(CltrPhotoGrid *grid, - CltrPhotoGridCell *cell) -{ - grid->cells_tail = g_list_append(grid->cells_tail, cell); -} - -/* relative */ -static void -ctrl_photo_grid_cell_to_coords(CltrPhotoGrid *grid, - GList *cell, - int *x, - int *y) -{ - int idx; - - idx = g_list_position(grid->cells_tail, cell); - - *y = idx / grid->n_cols; - *x = idx % grid->n_cols; - - CLTR_DBG("idx: %i x: %i, y: %i", idx, *x , *y); -} - -static void -ctrl_photo_grid_get_zoomed_coords(CltrPhotoGrid *grid, - int x, - int y, - float *tx, - float *ty) -{ - /* - * figure out translate co-ords for the cell at x,y to get translated - * so its centered for glScale to zoom in on it. - */ - - *tx = (float)grid->cell_width * (grid->zoom_max) * x * -1.0; - *ty = (float)grid->cell_height * (grid->zoom_max) * y * -1.0; -} - -static gboolean -cell_is_offscreen(CltrPhotoGrid *grid, - GList *cell, - CltrDirection *where) -{ - int idx; - - idx = g_list_position(grid->cells_tail, cell); - - CLTR_DBG("idx %i, rows*cols %i", idx, grid->n_cols * grid->n_rows); - - if (idx < (grid->row_offset * grid->n_cols)) - { - if (where) *where = CLTR_NORTH; - return TRUE; /* scroll up */ - } - - if (idx >= ((grid->row_offset * grid->n_cols)+(grid->n_cols * grid->n_rows))) - { - if (where) *where = CLTR_SOUTH; - return TRUE; /* scroll down */ - } - - return FALSE; -} - -gboolean -cltr_photo_grid_idle_cb(gpointer data) -{ - CltrPhotoGrid *grid = (CltrPhotoGrid *)data; - - cltr_photo_grid_update_visual_state(grid); - - cltr_widget_queue_paint(CLTR_WIDGET(grid)); - - if (!grid->is_populated) - return TRUE; - - switch(grid->state) - { - case CLTR_PHOTO_GRID_STATE_ZOOM_IN: - case CLTR_PHOTO_GRID_STATE_ZOOM_OUT: - case CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE: - case CLTR_PHOTO_GRID_STATE_SCROLLED_MOVE: - return TRUE; - case CLTR_PHOTO_GRID_STATE_ZOOMED: - case CLTR_PHOTO_GRID_STATE_BROWSE: - default: - return FALSE; /* no need for rapid updates now */ - } -} - - -void -cltr_photo_grid_navigate(CltrPhotoGrid *grid, - CltrDirection direction) -{ - GList *cell_orig = grid->cell_active; - - switch (direction) - { - case CLTR_SOUTH: - if (g_list_nth(grid->cell_active, grid->n_cols)) - grid->cell_active = g_list_nth(grid->cell_active, grid->n_cols); - break; - case CLTR_NORTH: - if (g_list_nth_prev(grid->cell_active, grid->n_cols)) - grid->cell_active = g_list_nth_prev(grid->cell_active, grid->n_cols); - break; - case CLTR_EAST: - if (g_list_next(grid->cell_active)) - grid->cell_active = g_list_next(grid->cell_active); - break; - case CLTR_WEST: - if (g_list_previous(grid->cell_active)) - grid->cell_active = g_list_previous(grid->cell_active); - break; - } - - if (cell_orig != grid->cell_active) /* we've moved */ - { - int x, y; - float zoom = grid->zoom_min; - CltrDirection where; - - if (cell_is_offscreen(grid, grid->cell_active, &where)) - { - GList *cell_item = NULL; - - cell_item = g_list_nth(grid->cells_tail, - grid->n_cols * grid->row_offset); - - if (grid->state != CLTR_PHOTO_GRID_STATE_ZOOMED) - grid->state = CLTR_PHOTO_GRID_STATE_SCROLLED_MOVE; - - /* scroll */ - if (where == CLTR_NORTH) - { /* up */ - grid->scroll_dist = grid->cell_height; - grid->row_offset--; - } - else - { - grid->scroll_dist = - grid->cell_height; - grid->row_offset++; - } - - if (grid->state != CLTR_PHOTO_GRID_STATE_ZOOMED) - g_timeout_add(FPS_TO_TIMEOUT(grid->anim_fps), - cltr_photo_grid_idle_cb, grid); - } - - if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED) - { - grid->state = CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE; - - grid->view_min_x = grid->view_max_x; - grid->view_min_y = grid->view_max_y ; - grid->anim_step = 0; - zoom = grid->zoom_max; - - g_timeout_add(FPS_TO_TIMEOUT(grid->anim_fps), - cltr_photo_grid_idle_cb, grid); - } - - ctrl_photo_grid_cell_to_coords(grid, grid->cell_active, &x, &y); - - ctrl_photo_grid_get_zoomed_coords(grid, x, y, - &grid->view_max_x, - &grid->view_max_y); - - CLTR_DBG("x: %f, y: %f", grid->view_max_x , grid->view_max_y); - - cltr_widget_queue_paint(CLTR_WIDGET(grid)); - } -} - -void /* bleh badly named */ -cltr_photo_grid_activate_cell(CltrPhotoGrid *grid) -{ - if (grid->state == CLTR_PHOTO_GRID_STATE_BROWSE) - { - grid->state = CLTR_PHOTO_GRID_STATE_ZOOM_IN; - - - g_timeout_add(FPS_TO_TIMEOUT(grid->anim_fps), - cltr_photo_grid_idle_cb, grid); - } - else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED) - { - grid->state = CLTR_PHOTO_GRID_STATE_ZOOM_OUT; - /* reset - zoomed moving will have reset */ - - grid->view_min_x = 0.0; - grid->view_min_y = 0.0; /*- (grid->row_offset * grid->cell_height);*/ - - g_timeout_add(FPS_TO_TIMEOUT(grid->anim_fps), - cltr_photo_grid_idle_cb, grid); - } -} - - -static void -cltr_photo_grid_update_visual_state(CltrPhotoGrid *grid) -{ - int view_x_diff = grid->view_max_x - grid->view_min_x; - int view_y_diff = grid->view_max_y - grid->view_min_y; - int zoom_diff = grid->zoom_max - grid->zoom_min; - int row_offset_h = grid->row_offset * grid->cell_height; - - /* Default states ( zoomed out ) */ - grid->paint_zoom = grid->zoom_min; - grid->paint_trans_x = grid->view_min_x; - grid->paint_trans_y = grid->view_min_y - row_offset_h; - grid->paint_start_y = row_offset_h; - grid->paint_cell_item = g_list_nth(grid->cells_tail, - grid->n_cols * grid->row_offset); - - if (grid->state != CLTR_PHOTO_GRID_STATE_BROWSE) - { - float scroll_min_y_offset = (float)(row_offset_h); - - /* Assume zoomed in */ - grid->paint_zoom = grid->zoom_max; - grid->paint_trans_x = grid->view_max_x; - grid->paint_trans_y = grid->view_max_y; - - if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOM_IN) - { - grid->anim_step++; - - /* Are we zoomed all the way in > */ - if (grid->anim_step >= grid->anim_n_steps) - { - grid->state = CLTR_PHOTO_GRID_STATE_ZOOMED; - grid->anim_step = 0; - } - else - { - float f = (float)grid->anim_step/grid->anim_n_steps; - - scroll_min_y_offset *= grid->zoom_max; - - grid->paint_zoom = grid->zoom_min + (zoom_diff * f); - grid->paint_trans_x = view_x_diff * f; - grid->paint_trans_y = (view_y_diff + scroll_min_y_offset) * f; - - grid->paint_start_y = 0; - } - } - else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOM_OUT) - { - grid->anim_step++; - - if (grid->anim_step >= grid->anim_n_steps) - { - grid->paint_zoom = grid->zoom_min; - grid->anim_step = 0; - grid->paint_trans_x = grid->view_min_x; - grid->paint_trans_y = grid->view_min_y - scroll_min_y_offset; - grid->state = CLTR_PHOTO_GRID_STATE_BROWSE; - } - else - { - float f = (float)(grid->anim_n_steps - grid->anim_step ) - / grid->anim_n_steps; - - scroll_min_y_offset *= grid->zoom_max; - - grid->paint_zoom = grid->zoom_min + (zoom_diff * f); - grid->paint_trans_x = view_x_diff * f; - grid->paint_trans_y = (view_y_diff + scroll_min_y_offset) * f; - grid->paint_start_y = 0; - - } - } - else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE) - { - grid->anim_step++; - - if (grid->anim_step >= grid->anim_n_steps) - { - grid->state = CLTR_PHOTO_GRID_STATE_ZOOMED; - grid->anim_step = 0; - } - else - { - float f = (float)grid->anim_step/grid->anim_n_steps; - - grid->paint_trans_x = grid->view_min_x + (view_x_diff * f); - grid->paint_trans_y = grid->view_min_y + (view_y_diff * f); - } - } - else if (grid->state == CLTR_PHOTO_GRID_STATE_SCROLLED_MOVE) - { - grid->paint_zoom = grid->zoom_min; - grid->paint_trans_x = grid->view_min_x; - grid->paint_trans_y = grid->view_min_y - row_offset_h; - grid->anim_step++; - - if (grid->anim_step >= (grid->anim_n_steps/4)) - { - grid->state = CLTR_PHOTO_GRID_STATE_BROWSE; - grid->anim_step = 0; - grid->paint_zoom = grid->zoom_min; - } - else - { - float f = (float)grid->anim_step / (grid->anim_n_steps/4); - - grid->paint_trans_y += (grid->scroll_dist * f); - - if (grid->scroll_dist > 0) /* up */ - { - grid->paint_start_y = (grid->row_offset-1) * grid->cell_height; - } - else /* down */ - { - grid->paint_cell_item = g_list_nth(grid->cells_tail, - grid->n_cols * (grid->row_offset-1)); - } - } - } - } -} - -static void -cltr_photo_grid_paint(CltrWidget *widget) -{ - int x = 0, y = 0, rows = 0, cols = 0, i =0; - GList *cell_item; - - CltrPhotoGrid *grid = (CltrPhotoGrid *)widget; - - rows = grid->n_rows+1; - - CLTR_MARK(); - - glPushMatrix(); - - if (grid->cells_tail == NULL) - { - glColor3ub(0xc2, 0xc3, 0xc1); - glRecti(0, 0, widget->width, widget->height); - - glPopMatrix(); - return; - } - - /* - * Using GL_POLYGON_SMOOTH with 'regular' alpha blends causes ugly seems - * in the textures and texture tile borders. We therefore do this 'saturate' - * trick painting front -> back. - * - * see http://blog.metawrap.com/blog/PermaLink.aspx?guid=db82f92e-9fc8-4635-b3e5-e37a1ca6ee0a - * for more info - * - * Note bg must be glClearColor( 0.0, 0.0, 0.0, 0.0 ) to work. - * Is there a better way.? - * - multisample ? - */ - - if (!grid->paint_cell_item) - cltr_photo_grid_update_visual_state(grid); - - glEnable(GL_BLEND); - - glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); /* needed */ - - glEnable(GL_POLYGON_SMOOTH); - - glDisable(GL_LIGHTING); - glDisable(GL_DEPTH_TEST); - - glBlendFunc(GL_SRC_ALPHA_SATURATE,GL_ONE); - - glColor4f(1.0, 1.0, 1.0, 1.0); - - /* values from cltr_photo_grid_update_visual_state() */ - - cell_item = grid->paint_cell_item; - y = grid->paint_start_y; - - glTranslatef (grid->paint_trans_x, grid->paint_trans_y, 0.0); - glScalef (grid->paint_zoom, grid->paint_zoom, 0.0); - - while (rows--) - { - cols = grid->n_cols; - x = 0; - while (cols--) - { - CltrPhotoGridCell *cell = (CltrPhotoGridCell *)cell_item->data; - Pixbuf *pixb = NULL; - int x1, x2, y1, y2, thumb_w, thumb_h; - int ns_border, ew_border, selected_offset = 0; - - pixb = cell->pixb; - - thumb_w = (pixb->width / grid->n_cols); - thumb_h = (pixb->height / grid->n_rows); - - if (cell->state == CLTR_PHOTO_GRID_CELL_STATE_APPEARING) - { - cell->anim_step -= 4; - - if (cell->anim_step <= 0) - { - cell->state = CLTR_PHOTO_GRID_CELL_STATE_STATIC; - } - else - { - thumb_w = thumb_w + cell->anim_step; - thumb_h = thumb_h + cell->anim_step; - } - /* set color here for developing effect - * only fully develop when all picts loaded ? - * blur texture too ? - */ - /* glColor4f(1.0, 1.0, 1.0, 0.5); */ - - cell->anim_step = 0; - } - - if (cell_item == grid->cell_active - && grid->state == CLTR_PHOTO_GRID_STATE_BROWSE) - selected_offset = 2; - - ew_border = thumb_w/8; - ns_border = (thumb_h/8) + 4; - - thumb_w -= (2 * ew_border); - thumb_h -= (2 * ns_border); - - x1 = x + ((grid->cell_width - thumb_w)/2); - y1 = y + ((grid->cell_height - thumb_h)/2); - - x2 = x1 + thumb_w; - y2 = y1 + thumb_h; - - glPushMatrix(); - - /* Translate origin to rotation point ( photo center ) */ - glTranslatef( x1 + ((x2-x1)/2), y1 + ((y2-y1)/2), 0.0); - - if (cell->state != CLTR_PHOTO_GRID_CELL_STATE_APPEARING) - /* Rotate around Z axis */ - glRotatef ( cell->angle, 0.0, 0.0, 1.0); - - glEnable(GL_TEXTURE_2D); - - g_mutex_lock(grid->mutex); - - cltr_texture_render_to_gl_quad(cell->texture, - -(thumb_w/2) - selected_offset, - -(thumb_h/2) - selected_offset, - (thumb_w/2) - selected_offset, - (thumb_h/2) - selected_offset); - - g_mutex_unlock(grid->mutex); - - glDisable(GL_TEXTURE_2D); - - - if (cell_item == grid->cell_active - && grid->state == CLTR_PHOTO_GRID_STATE_BROWSE) - glColor4f(1.0, 1.0, 1.0, 1.0); - else - glColor4f(0.9, 0.95, 0.95, 1.0); - - glColor4f(1.0, 1.0, 1.0, 1.0); - - /* Draw with origin in center of photo */ - - - glRecti(-(thumb_w/2)-6 - selected_offset, - -(thumb_h/2)-6 - selected_offset, - (thumb_w/2)+6 - selected_offset, - (thumb_h/2)+ns_border - selected_offset); - - - /* - cltr_glu_rounded_rect(-(thumb_w/2)-4, -(thumb_h/2)-4, - (thumb_w/2)+4, (thumb_h/2)+ns_border, - thumb_w/30, - NULL); - */ - - - /* Nice colors */ - /* glColor4ub(0x3c, 0xbb, 0x15, 0xff); */ - /* glColor4ub(0x99, 0x99, 0xff, 0xff); */ - /* glColor4ub(0x99, 0x99, 0x99, 0xff); */ - - /* shadow */ - - glColor4ub(0x99, 0x99, 0x99, 0xff); - glRecti(-(thumb_w/2)-6+2, -(thumb_h/2)-6+2, - (thumb_w/2)+6+2, (thumb_h/2)+ns_border+2); - - - /* - glColor4f(0.1, 0.1, 0.1, 0.3); - - - cltr_glu_rounded_rect(-(thumb_w/2)-4 + 1, -(thumb_h/2)-4 + 1, - (thumb_w/2)+4 + 1, (thumb_h/2)+ns_border +1, - thumb_w/30, - NULL); - */ - - - glColor4f(1.0, 1.0, 1.0, 1.0); - - glEnable(GL_TEXTURE_2D); - - glPopMatrix(); - - cell_item = g_list_next(cell_item); - - if (!cell_item) - goto finish; - - x += grid->cell_width; - i++; - } - - y += grid->cell_height; - } - - finish: - - glPopMatrix(); - - /* finally paint background */ - - glDisable(GL_TEXTURE_2D); - - glColor3ub(0xc2, 0xc3, 0xc1); - - glRecti(0, 0, widget->width, widget->height); - - /* reset */ - - glDisable(GL_POLYGON_SMOOTH); - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); -} - -static void -cltr_photo_grid_show(CltrWidget *widget) -{ - CltrPhotoGrid *grid = CLTR_PHOTO_GRID(widget); - - /* - GThread *loader_thread; - - loader_thread = g_thread_create (cltr_photo_grid_populate, - (gpointer)grid, - TRUE, - NULL); - */ - - grid->state = CLTR_PHOTO_GRID_STATE_BROWSE; - - if (!grid->is_populated) - g_timeout_add(FPS_TO_TIMEOUT(20), - cltr_photo_grid_idle_cb, grid); - - cltr_widget_queue_paint(widget); -} - -void -cltr_photo_grid_set_fps(CltrPhotoGrid *grid, int fps) -{ - grid->anim_fps = fps; -} - -int -cltr_photo_grid_get_fps(CltrPhotoGrid *grid) -{ - return grid->anim_fps; -} - -void -cltr_photo_grid_set_anim_steps(CltrPhotoGrid *grid, int steps) -{ - grid->anim_n_steps = steps; -} - -int -cltr_photo_grid_get_anim_steps(CltrPhotoGrid *grid) -{ - return grid->anim_n_steps; -} - - - -CltrWidget* -cltr_photo_grid_new(int width, - int height, - int n_cols, - int n_rows, - const gchar *img_path) -{ - CltrPhotoGrid *grid = NULL; - - grid = g_malloc0(sizeof(CltrPhotoGrid)); - - grid->widget.width = width; - grid->widget.height = height; - - grid->widget.show = cltr_photo_grid_show; - grid->widget.paint = cltr_photo_grid_paint; - - grid->widget.xevent_handler = cltr_photo_grid_handle_xevent; - - grid->img_path = strdup(img_path); - grid->n_cols = n_cols; - grid->n_rows = n_rows; - - grid->cell_width = grid->widget.width / n_cols; - grid->cell_height = grid->widget.height / n_rows; - - grid->state = CLTR_PHOTO_GRID_STATE_BROWSE; - grid->is_populated = FALSE; - - grid->anim_fps = 50; - - grid->anim_n_steps = 10; /* value needs to be calced dep on rows */ - grid->anim_step = 0; - - /* Default 'browse view' */ - grid->zoom_min = 1.0; - grid->view_min_x = (grid->widget.width - (grid->zoom_min * grid->widget.width))/2.0; - grid->view_min_y = 0.0; - - /* Assmes cols == rows */ - grid->zoom_max = (float) (n_rows * 1.0); - - grid->row_offset = 0; - - grid->mutex = g_mutex_new(); - - return CLTR_WIDGET(grid); -} diff --git a/clutter/cltr-photo-grid.h b/clutter/cltr-photo-grid.h deleted file mode 100644 index e26498f6f..000000000 --- a/clutter/cltr-photo-grid.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef _HAVE_CLTR_PHOTO_GRID_H -#define _HAVE_CLTR_PHOTO_GRID_H - -#include "cltr.h" - -typedef struct CltrPhotoGrid CltrPhotoGrid; - -typedef struct CltrPhotoGridCell CltrPhotoGridCell; - -#define CLTR_PHOTO_GRID(w) (CltrPhotoGrid*)(w) - -typedef enum CltrPhotoGridState -{ - CLTR_PHOTO_GRID_STATE_BROWSE , - CLTR_PHOTO_GRID_STATE_ZOOM_IN , - CLTR_PHOTO_GRID_STATE_ZOOMED , - CLTR_PHOTO_GRID_STATE_ZOOM_OUT , - CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE , - CLTR_PHOTO_GRID_STATE_SCROLLED_MOVE , -} -CltrPhotoGridState; - -typedef enum CltrPhotoGridCellState -{ - CLTR_PHOTO_GRID_CELL_STATE_APPEARING, - CLTR_PHOTO_GRID_CELL_STATE_STATIC, -} -CltrPhotoGridCellState; - -GMutex* -cltr_photo_grid_mutex(CltrPhotoGrid *grid); - -void -cltr_photo_grid_set_populated(CltrPhotoGrid *grid, gboolean populated); - -CltrPhotoGridCell* -cltr_photo_grid_cell_new(CltrPhotoGrid *grid, - Pixbuf *pixb); - -Pixbuf* -cltr_photo_grid_cell_pixbuf(CltrPhotoGridCell *cell); - -CltrPhotoGridCell* -cltr_photo_grid_get_active_cell(CltrPhotoGrid *grid); - -void -cltr_photo_grid_set_active_cell(CltrPhotoGrid *grid, CltrPhotoGridCell *cell); - -CltrPhotoGridCell* -cltr_photo_grid_get_first_cell(CltrPhotoGrid *grid); - - -void -cltr_photo_grid_append_cell(CltrPhotoGrid *grid, - CltrPhotoGridCell *cell); - -void -cltr_photo_grid_navigate(CltrPhotoGrid *grid, - CltrDirection direction) ; - -void /* bleh badly named */ -cltr_photo_grid_activate_cell(CltrPhotoGrid *grid); - -gpointer -cltr_photo_grid_populate(gpointer data) ; - -void -cltr_photo_grid_redraw(CltrPhotoGrid *grid); - -CltrWidget* -cltr_photo_grid_new(int width, - int height, - int n_cols, - int n_rows, - const gchar *img_path); - - -#endif diff --git a/clutter/cltr-private.h b/clutter/cltr-private.h deleted file mode 100644 index e7247b407..000000000 --- a/clutter/cltr-private.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef _HAVE_CLTR_PRIVATE_H -#define _HAVE_CLTR_PRIVATE_H - -#include "cltr.h" - -#define CLTR_WANT_DEBUG 1 - -#if (CLTR_WANT_DEBUG) - -#define CLTR_DBG(x, a...) \ - g_printerr ( __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a) - -#define CLTR_GLERR() \ - { \ - GLenum err = glGetError (); /* Roundtrip */ \ - if (err != GL_NO_ERROR) \ - { \ - g_printerr (__FILE__ ": GL Error: %x [at %s:%d]\n", \ - err, __func__, __LINE__); \ - } \ - } - -#else - -#define CLTR_DBG(x, a...) do {} while (0) -#define CLTR_GLERR() do {} while (0) - -#endif - -#define CLTR_MARK() CLTR_DBG("mark") - -typedef void (*WidgetPaintMethod) (CltrWidget *widget ) ; -typedef void (*WidgetShowMethod) (CltrWidget *widget ) ; -typedef void (*WidgetDestroyMethod) (CltrWidget *widget) ; -typedef void (*WidgetFocusMethod) (CltrWidget *widget) ; -typedef void (*WidgetUnfocusMethod) (CltrWidget *widget) ; -typedef gboolean (*WidgetXEventHandler) (CltrWidget *widget, XEvent *xev) ; - -struct CltrWidget -{ - int type; - int x,y,width,height; - CltrWidget *parent; - - gboolean visible; - - GList *children; - int refcnt; - - /* focus */ - - CltrWidget *focus_next_north, *focus_next_south, - *focus_next_west, *focus_next_east; - - /* methods */ - - WidgetPaintMethod paint; - WidgetShowMethod show; - WidgetDestroyMethod destroy; - WidgetFocusMethod focus_in; - WidgetUnfocusMethod focus_out; - WidgetXEventHandler xevent_handler; - - /* Anim ref */ - - CltrAnimator *anim; -}; - -typedef struct ClutterMainContext ClutterMainContext; - -struct ClutterMainContext -{ - Display *xdpy; - Window xwin_root; - int xscreen; - GC xgc; - - GLXContext gl_context; - - CltrWidget *window; - GAsyncQueue *internal_event_q; - - PixbufPixel colors[CLTR_N_COLS]; -}; - -ClutterMainContext CltrCntx; - -#define CLTR_CONTEXT() &CltrCntx - -#define FPS_TO_TIMEOUT(t) (1000/(t)) - -#endif diff --git a/clutter/cltr-scratch.c b/clutter/cltr-scratch.c deleted file mode 100644 index 2b611b06f..000000000 --- a/clutter/cltr-scratch.c +++ /dev/null @@ -1,154 +0,0 @@ -#include "cltr-scratch.h" -#include "cltr-private.h" - -struct CltrScratch -{ - CltrWidget widget; - - Pixbuf *pixb; - CltrTexture *tex; -}; - -static void -cltr_scratch_show(CltrWidget *widget); - -static gboolean -cltr_scratch_handle_xevent (CltrWidget *widget, XEvent *xev); - -static void -cltr_scratch_paint(CltrWidget *widget); - - -CltrWidget* -cltr_scratch_new(int width, int height) -{ - CltrScratch *scratch; - ClutterFont *font; - PixbufPixel pixel = { 255, 255, 255, 100 }; - - scratch = g_malloc0(sizeof(CltrScratch)); - - scratch->widget.width = width; - scratch->widget.height = height; - - scratch->widget.show = cltr_scratch_show; - scratch->widget.paint = cltr_scratch_paint; - - scratch->widget.xevent_handler = cltr_scratch_handle_xevent; - - scratch->pixb = pixbuf_new(width, height); - - pixel_set_vals(&pixel, 0, 0, 0, 255); - - pixbuf_fill_rect(scratch->pixb, 0, 0, width, height, &pixel); - - font = font_new ("Sans Bold 72"); - - pixel_set_vals(&pixel, 255, 255, 255, 255); - - font_draw(font, scratch->pixb, "Hello", 0, 0, &pixel); - - scratch->tex = cltr_texture_new(scratch->pixb); - - return CLTR_WIDGET(scratch); -} - -static void -cltr_scratch_show(CltrWidget *widget) -{ - cltr_widget_queue_paint(widget); -} - -static gboolean -cltr_scratch_handle_xevent (CltrWidget *widget, XEvent *xev) -{ - - return TRUE; -} - -static void -cltr_scratch_paint_old(CltrWidget *widget) -{ - CltrScratch *scratch = CLTR_SCRATCH(widget); - - int times = 100, num = 0; - int spost = 0; - float alphainc = 0.9f / times; - float alpha = 0.1f; - - glPushMatrix(); - - glEnable(GL_TEXTURE_2D); - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - - glBlendFunc(GL_SRC_ALPHA,GL_ONE); - glEnable(GL_BLEND); - - - /* - glEnable(GL_BLEND); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - */ - - for (num = 0;num < times;num++) - { - glColor4f(1.0f, 1.0f, 1.0f, alpha); - cltr_texture_render_to_gl_quad(scratch->tex, - widget->x - spost, - widget->y - spost, - widget->x + widget->width + spost, - widget->y + widget->height + spost); - spost += 2; - alpha = alpha - alphainc; - } - - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - - cltr_texture_render_to_gl_quad(scratch->tex, - widget->x, - widget->y, - widget->x + widget->width , - widget->y + widget->height); - - - glDisable(GL_BLEND); - - glPopMatrix(); -} - - -static void -cltr_scratch_paint(CltrWidget *widget) -{ - CltrScratch *scratch = CLTR_SCRATCH(widget); - - glPushMatrix(); - - CLTR_MARK(); - - glEnable(GL_BLEND); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glColor4ub(100, 200, 50, 100); - - glRecti(widget->x, widget->y, - widget->x + widget->width, - widget->y + widget->height); - - glEnable(GL_TEXTURE_2D); - - cltr_texture_render_to_gl_quad(scratch->tex, - widget->x, - widget->y, - widget->x + widget->width , - widget->y + widget->height); - - glDisable(GL_TEXTURE_2D); - - glDisable(GL_BLEND); - - glPopMatrix(); -} diff --git a/clutter/cltr-scratch.h b/clutter/cltr-scratch.h deleted file mode 100644 index f9b6de993..000000000 --- a/clutter/cltr-scratch.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _HAVE_CLTR_SCRATCH_H -#define _HAVE_CLTR_SCRATCH_H - -#include "cltr.h" - -typedef struct CltrScratch CltrScratch; - -#define CLTR_SCRATCH(w) ((CltrScratch*)(w)) - -CltrWidget* -cltr_scratch_new(int width, int height); - - -#endif diff --git a/clutter/cltr-texture.c b/clutter/cltr-texture.c deleted file mode 100644 index 1c5177f67..000000000 --- a/clutter/cltr-texture.c +++ /dev/null @@ -1,536 +0,0 @@ -#include "cltr-texture.h" -#include "cltr-private.h" - -/* - IDEAS or less memory - - + texture compression - made no difference ? - - + mipmaps - make zoom faster ? ( vs memory ) - - + check max texture size *DONE* - - + how much texture mem available ? - */ - - - -static int -next_p2 ( int a ) -{ - int rval=1; - while(rval < a) - rval <<= 1; - - return rval; -} - -void -cltr_texture_render_to_gl_quad(CltrTexture *texture, - int x1, - int y1, - int x2, - int y2) -{ - int qx1 = 0, qx2 = 0, qy1 = 0, qy2 = 0; - int qwidth = 0, qheight = 0; - int x, y, i =0, lastx = 0, lasty = 0; - float tx, ty; - - qwidth = x2-x1; - qheight = y2-y1; - - if (texture->tiles == NULL) - cltr_texture_realize(texture); - - if (!texture->tiled) - { - glBindTexture(GL_TEXTURE_2D, texture->tiles[0]); - - tx = (float) texture->pixb->width / texture->width; - ty = (float) texture->pixb->height / texture->height; - - qx1 = x1; - qx2 = x2; - - qy1 = y1; - qy2 = y2; - - glBegin (GL_QUADS); - glTexCoord2f (tx, ty); glVertex2i (qx2, qy2); - glTexCoord2f (0, ty); glVertex2i (qx1, qy2); - glTexCoord2f (0, 0); glVertex2i (qx1, qy1); - glTexCoord2f (tx, 0); glVertex2i (qx2, qy1); - glEnd (); - - return; - } - - for (x=0; x < texture->n_x_tiles; x++) - { - lasty = 0; - - for (y=0; y < texture->n_y_tiles; y++) - { - int actual_w, actual_h; - - glBindTexture(GL_TEXTURE_2D, texture->tiles[i]); - - actual_w = texture->tile_x_size[x] - texture->tile_x_waste[x]; - actual_h = texture->tile_y_size[y] - texture->tile_y_waste[y]; - - tx = (float) actual_w / texture->tile_x_size[x]; - ty = (float) actual_h / texture->tile_y_size[y]; - - qx1 = x1 + lastx; - qx2 = qx1 + ((qwidth * actual_w ) / texture->width ); - - qy1 = y1 + lasty; - qy2 = qy1 + ((qheight * actual_h) / texture->height ); - - glBegin (GL_QUADS); - glTexCoord2f (tx, ty); glVertex2i (qx2, qy2); - glTexCoord2f (0, ty); glVertex2i (qx1, qy2); - glTexCoord2f (0, 0); glVertex2i (qx1, qy1); - glTexCoord2f (tx, 0); glVertex2i (qx2, qy1); - glEnd (); - - lasty += qy2 - qy1; - - i++; - } - lastx += qx2 - qx1; - } -} - - -/* Code below based heavily from luminocity - copyright Owen Taylor */ - -/* MAX_WASTE: The maximum dimension of blank area we'll accept - * in a pixmap. Bigger values use less textures, smaller - * values less texture memory. The current value of - * 256 means that the smallest texture we'll split to - * save texture memory is 513x512. (That will be split into - * a 512x512 and, if overlap is 32, a 64x512 texture) - */ -#define MAX_WASTE 64 - -/* - * OVERLAP: when we divide the full-resolution image into - * tiles to deal with hardware limitations, we overlap - * tiles by this much. This means that we can scale - * down by up to OVERLAP before we start getting - * seems. - */ - -#define OVERLAP 0 /* 32 */ - -static gboolean -can_create (int width, int height) -{ - GLint new_width; - - glTexImage2D (GL_PROXY_TEXTURE_2D, 0, GL_RGBA, - width, height, 0 /* border */, - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); - - glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, - GL_TEXTURE_WIDTH, &new_width); - - return new_width != 0; -} - - -static int -tile_dimension (int to_fill, - int start_size, - int *positions, - int *sizes, - int *waste) - -{ - int pos = 0; - int n_tiles = 0; - int size = start_size; - - while (TRUE) - { - if (positions) - positions[n_tiles] = pos; - if (sizes) - sizes[n_tiles] = size; - if (waste) - waste[n_tiles] = 0; - - n_tiles++; - - if (to_fill <= size) - { - if (waste) - waste[n_tiles-1] = size - to_fill; - break; - } - else - { - - to_fill -= (size - OVERLAP); - pos += size - OVERLAP; - while (size >= 2 * to_fill || size - to_fill > MAX_WASTE) - size /= 2; - } - - - } - - return n_tiles; -} - -static void -init_tiles (CltrTexture *texture) -{ - int x_pot = next_p2 (texture->width); - int y_pot = next_p2 (texture->height); - - while (!(can_create (x_pot, y_pot) && - (x_pot - texture->width < MAX_WASTE) && - (y_pot - texture->height < MAX_WASTE))) - { - if (x_pot > y_pot) - x_pot /= 2; - else - y_pot /= 2; - } - - texture->n_x_tiles = tile_dimension (texture->width, x_pot, - NULL, NULL, NULL); - - texture->tile_x_position = g_new (int, texture->n_x_tiles); - texture->tile_x_size = g_new (int, texture->n_x_tiles); - texture->tile_x_waste = g_new (int, texture->n_x_tiles); - - tile_dimension (texture->width, x_pot, - texture->tile_x_position, - texture->tile_x_size, - texture->tile_x_waste); - - texture->n_y_tiles = tile_dimension (texture->height, y_pot, - NULL, NULL, NULL); - - texture->tile_y_position = g_new (int, texture->n_y_tiles); - texture->tile_y_size = g_new (int, texture->n_y_tiles); - texture->tile_y_waste = g_new (int, texture->n_y_tiles); - - tile_dimension (texture->height, y_pot, - texture->tile_y_position, - texture->tile_y_size, - texture->tile_y_waste); - - -#if 0 - /* debug info */ - { - int i; - - g_print("n_x_tiles %i, n_y_tiles %i\n", - texture->n_x_tiles, texture->n_y_tiles); - - g_print ("Tiled %d x %d texture as [", texture->width, texture->height); - for (i = 0; i < texture->n_x_tiles; i++) - { - if (i != 0) - g_print (","); - g_print ("%d(%d)", texture->tile_x_size[i], texture->tile_x_position[i]); - } - g_print ("]x["); - for (i = 0; i < texture->n_y_tiles; i++) - { - if (i != 0) - g_print (","); - g_print ("%d(%d)", texture->tile_y_size[i], texture->tile_y_position[i]); - } - g_print ("]\n"); - } -#endif - -} - -/* End borrowed luminocity code */ - -void -cltr_texture_unrealize(CltrTexture *texture) -{ - if (texture->tiles == NULL) - return; - - if (!texture->tiled) - glDeleteTextures(1, texture->tiles); - else - glDeleteTextures(texture->n_x_tiles * texture->n_y_tiles, texture->tiles); - - g_free(texture->tiles); - - texture->tiles = NULL; - -} - -void -cltr_texture_realize(CltrTexture *texture) -{ - int x, y, i = 0; - - if (!texture->tiled) - { - if (!texture->tiles) - { - texture->tiles = g_new (GLuint, 1); - glGenTextures (1, texture->tiles); - } - - glBindTexture(GL_TEXTURE_2D, texture->tiles[0]); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - /* glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); */ - - glTexImage2D(GL_TEXTURE_2D, 0, /*GL_COMPRESSED_RGBA_ARB*/ GL_RGBA, - texture->width, - texture->height, - 0, GL_RGBA, - GL_UNSIGNED_INT_8_8_8_8, - NULL); - - CLTR_GLERR(); - - cltr_texture_sync_pixbuf(texture); - - return; - } - - if (!texture->tiles) - { - texture->tiles = g_new (GLuint, texture->n_x_tiles * texture->n_y_tiles); - glGenTextures (texture->n_x_tiles * texture->n_y_tiles, texture->tiles); - } - - for (x=0; x < texture->n_x_tiles; x++) - for (y=0; y < texture->n_y_tiles; y++) - { - Pixbuf *pixtmp; - int src_h, src_w; - - src_w = texture->tile_x_size[x]; - src_h = texture->tile_y_size[y]; - - /* - CLTR_DBG("%i+%i, %ix%i to %ix%i, waste %ix%i", - texture->tile_x_position[x], - texture->tile_y_position[y], - texture->tile_x_size[x], - texture->tile_y_size[y], - texture->width, - texture->height, - texture->tile_x_waste[x], - texture->tile_y_waste[y]); - */ - - /* Only break the pixbuf up if we have multiple tiles */ - /* if (texture->n_x_tiles > 1 && texture->n_y_tiles >1) */ - { - pixtmp = pixbuf_new(texture->tile_x_size[x], - texture->tile_y_size[y]); - - pixbuf_copy(texture->pixb, - pixtmp, - texture->tile_x_position[x], - texture->tile_y_position[y], - texture->tile_x_size[x], - texture->tile_y_size[y], - 0,0); - } - /* else pixtmp = texture->pixb; */ - - - glBindTexture(GL_TEXTURE_2D, texture->tiles[i]); - - CLTR_GLERR(); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); -glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - /* glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); */ - - /* glPixelStorei (GL_UNPACK_ALIGNMENT, 4); */ - /* glPixelStorei (GL_UNPACK_ROW_LENGTH, texture->tile_x_size[x]); */ - - glTexImage2D(GL_TEXTURE_2D, 0, /*GL_COMPRESSED_RGBA_ARB*/ GL_RGBA, - pixtmp->width, - pixtmp->height, - 0, GL_RGBA, - GL_UNSIGNED_INT_8_8_8_8, - /* GL_UNSIGNED_BYTE, */ - pixtmp->data); - - CLTR_GLERR(); - - CLTR_DBG("pixtmp is %ix%i texture %ix%i\n", - pixtmp->width, pixtmp->height, - texture->width, texture->height); - - pixbuf_unref(pixtmp); - - i++; - - } - -} - -CltrTexture* -cltr_texture_new(Pixbuf *pixb) -{ - CltrTexture *texture; - - CLTR_MARK(); - - texture = g_malloc0(sizeof(CltrTexture)); - - texture->width = pixb->width; - texture->height = pixb->height; - texture->tiled = TRUE; - - /* maybe we should copy the pixbuf - a change to refed one would explode */ - texture->pixb = pixb; - texture->mutex = g_mutex_new(); - - pixbuf_ref(pixb); - - init_tiles (texture); - - cltr_texture_ref(texture); - - return texture; -} - -void -cltr_texture_ref(CltrTexture *texture) -{ - texture->refcnt++; -} - -void -cltr_texture_unref(CltrTexture *texture) -{ - texture->refcnt--; - - if (texture->refcnt <= 0) - { - cltr_texture_unrealize(texture); - if (texture->pixb) - pixbuf_unref(texture->pixb); - g_free(texture); - } -} - -CltrTexture* -cltr_texture_no_tile_new(Pixbuf *pixb) -{ - CltrTexture *texture; - - CLTR_MARK(); - - texture = g_malloc0(sizeof(CltrTexture)); - - texture->tiled = FALSE; - texture->width = next_p2(pixb->width); - texture->height = next_p2(pixb->height); - - if (!can_create (texture->width, texture->height)) - { - free(texture); - return NULL; - } - - texture->pixb = pixb; - texture->mutex = g_mutex_new(); - - pixbuf_ref(pixb); - cltr_texture_ref(texture); - - return texture; -} - - -Pixbuf* -cltr_texture_get_pixbuf(CltrTexture* texture) -{ - return texture->pixb; -} - -void -cltr_texture_lock(CltrTexture* texture) -{ - g_mutex_lock(texture->mutex); -} - -void -cltr_texture_unlock(CltrTexture* texture) -{ - g_mutex_unlock(texture->mutex); -} - -void -cltr_texture_sync_pixbuf(CltrTexture* texture) -{ - if (texture->tiled) - { - cltr_texture_realize(texture); - } - else - { - if (!texture->tiles) - cltr_texture_realize(texture); - - glBindTexture(GL_TEXTURE_2D, texture->tiles[0]); - - glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, - texture->pixb->width, - texture->pixb->height, - GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, - texture->pixb->data); - } -} - - -/* - * This is a nasty hack to work round me not figuring out - * how to get RGBA data out of gstreamer in a format clutters - * GL setup can handle :( - * - * The good side is it probably speeds video playback up by - * avoiding copys of frame data. - */ -void -cltr_texture_force_rgb_data(CltrTexture *texture, - int width, - int height, - int *data) -{ - if (texture->tiled) - return; - - if (!texture->tiles) - cltr_texture_realize(texture); - - glBindTexture(GL_TEXTURE_2D, texture->tiles[0]); - - glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, - width, - height, - GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, - data); - - CLTR_GLERR(); -} diff --git a/clutter/cltr-texture.h b/clutter/cltr-texture.h deleted file mode 100644 index 70a638043..000000000 --- a/clutter/cltr-texture.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef _HAVE_CLTR_TEX_H -#define _HAVE_CLTR_TEX_H - -#include "cltr.h" - - - -struct CltrTexture -{ - Pixbuf *pixb; - - int width, height; - - gboolean tiled; - - int n_x_tiles, n_y_tiles; - int *tile_x_position, *tile_x_size, *tile_x_waste; - int *tile_y_position, *tile_y_size, *tile_y_waste; - - GLuint *tiles; - - GMutex *mutex; - - gint refcnt; -}; - - -CltrTexture* -cltr_texture_new(Pixbuf *pixb); - -void -cltr_texture_ref(CltrTexture *texture); - -void -cltr_texture_unref(CltrTexture *texture); - -CltrTexture* -cltr_texture_no_tile_new(Pixbuf *pixb); - -void -cltr_texture_unrealize(CltrTexture *texture); - -void -cltr_texture_realize(CltrTexture *texture); - -void -cltr_texture_render_to_gl_quad(CltrTexture *texture, - int x1, - int y1, - int x2, - int y2); - -Pixbuf* -cltr_texture_get_pixbuf(CltrTexture* texture); - -void -cltr_texture_lock(CltrTexture* texture); - -void -cltr_texture_unlock(CltrTexture* texture); - -void -cltr_texture_sync_pixbuf(CltrTexture* texture); - -void -cltr_texture_force_rgb_data(CltrTexture *texture, - int width, - int height, - int *data); - - -#endif diff --git a/clutter/cltr-video.c b/clutter/cltr-video.c deleted file mode 100644 index 869ccf774..000000000 --- a/clutter/cltr-video.c +++ /dev/null @@ -1,923 +0,0 @@ -#include "cltr-video.h" -#include "cltr-private.h" - -/* This is all very much based on the totem gst bacon video widget */ - -struct CltrVideo -{ - CltrWidget widget; - - GstElement *play, *data_src, *video_sink, *audio_sink, *vis_element; - - GAsyncQueue *queue; - - gint video_width, video_height; - gdouble video_fps; - CltrTexture *frame_texture; - - gboolean has_video, has_audio; - - gint64 stream_length; - gint64 current_time_nanos; - gint64 current_time; - float current_position; - - guint update_id; - gchar *last_error_message; - gchar *mrl; -}; - - -static void -cltr_video_show(CltrWidget *widget); - -static gboolean -cltr_video_handle_xevent (CltrWidget *widget, XEvent *xev); - -static void -cltr_video_paint(CltrWidget *widget); - -static void -parse_stream_info (CltrVideo *video); - -static gboolean -cb_iterate (CltrVideo *video); - -static void -reset_error_msg (CltrVideo *video); - -static gboolean -cltr_video_idler (CltrVideo *video); - - -static gint64 length = 0; /* to go */ - -static void -cltr_video_print_tag (const GstTagList *list, - const gchar *tag, - gpointer unused) -{ - gint i, count; - - count = gst_tag_list_get_tag_size (list, tag); - - for (i = 0; i < count; i++) { - gchar *str; - - if (gst_tag_get_type (tag) == G_TYPE_STRING) { - if (!gst_tag_list_get_string_index (list, tag, i, &str)) - g_assert_not_reached (); - } else { - str = - g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i)); - } - - if (i == 0) { - g_print ("%15s: %s\n", gst_tag_get_nick (tag), str); - } else { - g_print (" : %s\n", str); - } - - g_free (str); - } -} - -static void -got_eos (GstPlay* play, CltrVideo *video) -{ - CLTR_DBG ("End Of Stream\n"); - - CltrVideoSignal *signal; - - signal = g_new0 (CltrVideoSignal, 1); - - signal->signal_id = CLTR_VIDEO_ASYNC_EOS; - - g_async_queue_push (video->queue, signal); - - gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY); -} - -static void -got_stream_length (GstElement *play, - gint64 length_nanos, - CltrVideo *video) -{ - video->stream_length = (gint64) length_nanos / GST_MSECOND; - - CLTR_MARK(); - /* fire off some callback here ? */ - - CLTR_DBG("length: %li", video->stream_length); -} - -static void -got_time_tick (GstElement *play, - gint64 time_nanos, - CltrVideo *video) -{ - CLTR_MARK(); - - video->current_time_nanos = time_nanos; - - video->current_time = (gint64) time_nanos / GST_MSECOND; - - if (video->stream_length == 0) - video->current_position = 0; - else - { - video->current_position = (float) video->current_time / video->stream_length; - } - - CLTR_DBG("current pos is %f\n", video->current_position); - - /* fire off callback here */ -} - - -static void -got_found_tag (GstPlay *play, - GstElement *source, - GstTagList *tag_list, - CltrVideo *video) -{ - CltrVideoSignal *signal; - - CLTR_MARK(); - - signal = g_new0 (CltrVideoSignal, 1); - signal->signal_id = CLTR_VIDEO_ASYNC_FOUND_TAG; - signal->signal_data.found_tag.source = source; - signal->signal_data.found_tag.tag_list = gst_tag_list_copy (tag_list); - - g_async_queue_push (video->queue, signal); - - /* gst_tag_list_foreach (tag_list, cltr_video_print_tag, NULL); */ -} - -static void -got_state_change (GstElement *play, - GstElementState old_state, - GstElementState new_state, - CltrVideo *video) -{ - if (old_state == GST_STATE_PLAYING) - { - if (video->update_id != 0) - { - g_source_remove (video->update_id); - video->update_id = 0; - } - - g_idle_remove_by_data (video); - - - } - else if (new_state == GST_STATE_PLAYING) - { - if (video->update_id != 0) - g_source_remove (video->update_id); - - video->update_id = g_timeout_add (200, (GSourceFunc) cb_iterate, video); - - g_idle_add((GSourceFunc) cltr_video_idler, video); - } - - if (old_state <= GST_STATE_READY && new_state >= GST_STATE_PAUSED) - { - parse_stream_info (video); - } - else if (new_state <= GST_STATE_READY && old_state >= GST_STATE_PAUSED) - { - video->has_video = FALSE; - video->has_audio = FALSE; - - /* blank the texture */ - - /* while (g_async_queue_try_pop (video->queue)) ; */ - - /* - if (bvw->priv->tagcache) - { - gst_tag_list_free (bvw->priv->tagcache); - bvw->priv->tagcache = NULL; - } - */ - - video->video_width = 0; - video->video_height = 0; - } -} - - -static void -got_redirect (GstElement *play, - const gchar *new_location, - CltrVideo *bvw) -{ - CLTR_MARK(); - - /* - bvw->priv->got_redirect = TRUE; - - signal = g_new0 (BVWSignal, 1); - signal->signal_id = ASYNC_REDIRECT; - signal->signal_data.redirect.new_location = g_strdup (new_location); - - g_async_queue_push (bvw->priv->queue, signal); - - g_idle_add ((GSourceFunc) bacon_video_widget_signal_idler, bvw); - */ -} - - -static void -stream_info_set (GObject *obj, - GParamSpec *pspec, - CltrVideo *video) -{ - - parse_stream_info (video); - - /* - signal = g_new0 (BVWSignal, 1); - signal->signal_id = ASYNC_NOTIFY_STREAMINFO; - - g_async_queue_push (bvw->priv->queue, signal); - - g_idle_add ((GSourceFunc) bacon_video_widget_signal_idler, bvw); - */ -} - -static void -got_source (GObject *play, - GParamSpec *pspec, - CltrVideo *video) -{ - GObject *source = NULL; - GObjectClass *klass; - - CLTR_MARK(); - - /* - if (bvw->priv->tagcache) { - gst_tag_list_free (bvw->priv->tagcache); - bvw->priv->tagcache = NULL; - } - - if (!bvw->priv->media_device) - return; - - g_object_get (play, "source", &source, NULL); - if (!source) - return; - - klass = G_OBJECT_GET_CLASS (source); - if (!g_object_class_find_property (klass, "device")) - return; - - g_object_set (source, "device", bvw->priv->media_device, NULL); - */ -} - - -static void -got_buffering (GstElement *play, - gint percentage, - CltrVideo *video) -{ - CLTR_DBG("Buffering with %i", percentage); - -#if 0 - BVWSignal *signal; - - g_return_if_fail (bvw != NULL); - g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw)); - - signal = g_new0 (BVWSignal, 1); - signal->signal_id = ASYNC_BUFFERING; - signal->signal_data.buffering.percent = percentage; - - g_async_queue_push (bvw->priv->queue, signal); - - g_idle_add ((GSourceFunc) bacon_video_widget_signal_idler, bvw); -#endif -} - -static void -reset_error_msg (CltrVideo *video) -{ - if (video->last_error_message) - { - g_free (video->last_error_message); - video->last_error_message = NULL; - } -} - - -static void -got_error (GstElement *play, - GstElement *orig, - GError *error, - gchar *debug, - CltrVideo *video) -{ - - /* - XXX TODO cpy the error message to asyc queueu - - */ - - CLTR_MARK(); - -#if 0 - /* since we're opening, we will never enter the mainloop - * until we return, so setting an idle handler doesn't - * help... Anyway, let's prepare a message. */ - if (GST_STATE (play) != GST_STATE_PLAYING) { - g_free (bvw->priv->last_error_message); - bvw->priv->last_error_message = g_strdup (error->message); - return; - } - - signal = g_new0 (BVWSignal, 1); - signal->signal_id = ASYNC_ERROR; - signal->signal_data.error.element = orig; - signal->signal_data.error.error = g_error_copy (error); - if (debug) - signal->signal_data.error.debug_message = g_strdup (debug); - - g_async_queue_push (bvw->priv->queue, signal); - - g_idle_add ((GSourceFunc) bacon_video_widget_signal_idler, bvw); -#endif -} - - -static void -caps_set (GObject *obj, - GParamSpec *pspec, - CltrVideo *video) -{ - GstPad *pad = GST_PAD (obj); - GstStructure *s; - - if (!GST_PAD_CAPS (pad)) - return; - - s = gst_caps_get_structure (GST_PAD_CAPS (pad), 0); - - if (s) - { - /* const GValue *par; */ - - if (!(gst_structure_get_double (s, "framerate", &video->video_fps) && - gst_structure_get_int (s, "width", &video->video_width) && - gst_structure_get_int (s, "height", &video->video_height))) - return; - - /* - if ((par = gst_structure_get_value (s, "pixel-aspect-ratio"))) - { - gint num = gst_value_get_fraction_numerator (par), - den = gst_value_get_fraction_denominator (par); - - if (num > den) - bvw->priv->video_width *= (gfloat) num / den; - else - bvw->priv->video_height *= (gfloat) den / num; - } - - got_video_size (bvw->priv->play, bvw->priv->video_width, - bvw->priv->video_height, bvw); - - */ - } -} - - -static void -parse_stream_info (CltrVideo *video) -{ - GList *streaminfo = NULL; - GstPad *videopad = NULL; - - g_object_get (G_OBJECT (video->play), "stream-info", &streaminfo, NULL); - - streaminfo = g_list_copy (streaminfo); - - g_list_foreach (streaminfo, (GFunc) g_object_ref, NULL); - - for ( ; streaminfo != NULL; streaminfo = streaminfo->next) - { - GObject *info = streaminfo->data; - gint type; - GParamSpec *pspec; - GEnumValue *val; - - if (!info) - continue; - - g_object_get (info, "type", &type, NULL); - - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (info), "type"); - - val = g_enum_get_value (G_PARAM_SPEC_ENUM (pspec)->enum_class, type); - - if (strstr (val->value_name, "AUDIO")) - { - if (!video->has_audio) { - video->has_audio = TRUE; - /*if (!bvw->priv->media_has_video && - bvw->priv->show_vfx && bvw->priv->vis_element) { - videopad = gst_element_get_pad (bvw->priv->vis_element, "src"); - }*/ - } - } - else if (strstr (val->value_name, "VIDEO")) - { - video->has_video = TRUE; - if (!videopad) - g_object_get (info, "object", &videopad, NULL); - - } - } - - if (videopad) - { - GstPad *real = (GstPad *) GST_PAD_REALIZE (videopad); - - /* handle explicit caps as well - they're set later */ - if (((GstRealPad *) real)->link != NULL && GST_PAD_CAPS (real)) - caps_set (G_OBJECT (real), NULL, video); - - g_signal_connect (real, "notify::caps", G_CALLBACK (caps_set), video); - - } - /* - else if (bvw->priv->show_vfx && bvw->priv->vis_element) - { - fixate_visualization (NULL, NULL, bvw); - } - */ - - g_list_foreach (streaminfo, (GFunc) g_object_unref, NULL); - g_list_free (streaminfo); -} - -static gboolean -cb_iterate (CltrVideo *video) -{ - GstFormat fmt = GST_FORMAT_TIME; - gint64 value; - - CLTR_MARK(); - - /* check length/pos of stream */ - if (gst_element_query (GST_ELEMENT (video->play), - GST_QUERY_TOTAL, &fmt, &value) - && GST_CLOCK_TIME_IS_VALID (value) - && value / GST_MSECOND != video->stream_length) - { - got_stream_length (GST_ELEMENT (video->play), value, video); - } - - if (gst_element_query (GST_ELEMENT (video->play), - GST_QUERY_POSITION, &fmt, &value)) - { - got_time_tick (GST_ELEMENT (video->play), value, video); - } - - return TRUE; -} - -CltrWidget* -cltr_video_new(int width, int height) -{ - CltrVideo *video; - GError *error = NULL; - - video = g_malloc0(sizeof(CltrVideo)); - - video->widget.width = width; - video->widget.height = height; - - video->widget.show = cltr_video_show; - video->widget.paint = cltr_video_paint; - - video->widget.xevent_handler = cltr_video_handle_xevent; - - /* Creating the GstPlay object */ - - video->play = gst_element_factory_make ("playbin", "play"); - if (!video->play) { - g_error ("Could not make playbin element"); - /* XXX Error */ - return NULL; - } - - video->audio_sink = gst_gconf_get_default_audio_sink (); - - if (!GST_IS_ELEMENT (video->audio_sink)) - g_error ("Could not get default audio sink from GConf"); - - video->video_sink = gst_element_factory_make ("cltrimagesink", "cltr-output"); - - if (!GST_IS_ELEMENT (video->video_sink)) - g_error ("Could not get clutter video sink"); - -#if 0 - sig1 = g_signal_connect (video_sink, "error", G_CALLBACK (out_error), err); - sig2 = g_signal_connect (audio_sink, "error", G_CALLBACK (out_error), err); - if (gst_element_set_state (video_sink, - GST_STATE_READY) != GST_STATE_SUCCESS || - gst_element_set_state (audio_sink, - GST_STATE_READY) != GST_STATE_SUCCESS) { - if (err && !*err) { - g_set_error (err, 0, 0, - "Failed to intialize %s output; check your configuration", - GST_STATE (video_sink) == GST_STATE_NULL ? - "video" : "audio"); - } - gst_object_unref (GST_OBJECT (video_sink)); - gst_object_unref (GST_OBJECT (audio_sink)); - g_object_unref (G_OBJECT (bvw)); - return NULL; - } - /* somehow, alsa hangs? */ - gst_element_set_state (video->audio_sink, GST_STATE_NULL); - g_signal_handler_disconnect (video->video_sink, sig1); - g_signal_handler_disconnect (video->audio_sink, sig2); -#endif - g_object_set (G_OBJECT (video->play), "video-sink", - video->video_sink, NULL); - g_object_set (G_OBJECT (video->play), "audio-sink", - video->audio_sink, NULL); - - /* Needed ? */ -#if 0 - g_signal_connect (GST_PAD_REALIZE (gst_element_get_pad (audio_sink, "sink")), - "fixate", G_CALLBACK (cb_audio_fixate), (gpointer) bvw); -#endif - - g_signal_connect (G_OBJECT (video->play), "eos", - G_CALLBACK (got_eos), (gpointer) video); - - g_signal_connect (G_OBJECT (video->play), "state-change", - G_CALLBACK (got_state_change), (gpointer) video); - - g_signal_connect (G_OBJECT (video->play), "found_tag", - G_CALLBACK (got_found_tag), (gpointer) video); - - g_signal_connect (G_OBJECT (video->play), "error", - G_CALLBACK (got_error), (gpointer) video); - - g_signal_connect (G_OBJECT (video->play), "buffering", - G_CALLBACK (got_buffering), (gpointer) video); - - g_signal_connect (G_OBJECT (video->play), "notify::source", - G_CALLBACK (got_source), (gpointer) video); - - g_signal_connect (G_OBJECT (video->play), "notify::stream-info", - G_CALLBACK (stream_info_set), (gpointer) video); - - /* what does this do ? - g_signal_connect (G_OBJECT (video->play), "group-switch", - G_CALLBACK (group_switch), (gpointer) video); - */ - - g_signal_connect (G_OBJECT (video->play), "got-redirect", - G_CALLBACK (got_redirect), (gpointer) video); - - - video->queue = g_async_queue_new (); - - gst_element_set(video->video_sink, "queue", video->queue, NULL); - - - return CLTR_WIDGET(video); -} - -gboolean -cltr_video_play ( CltrVideo *video, GError ** error) -{ - gboolean ret; - - reset_error_msg (video); - - ret = (gst_element_set_state (GST_ELEMENT (video->play), - GST_STATE_PLAYING) == GST_STATE_SUCCESS); - if (!ret) - { - g_set_error (error, 0, 0, "%s", video->last_error_message ? - video->last_error_message : "Failed to play; reason unknown"); - } - - return ret; -} - -gint64 -cltr_video_get_time (CltrVideo *video) -{ - CLTR_DBG("current pos is %f\n", video->current_position); - - return video->current_time; -} - -gboolean -cltr_video_seek (CltrVideo *video, float position, GError **gerror) -{ - gint64 seek_time, length_nanos; - - /* Resetting last_error_message to NULL */ - if (video->last_error_message) - { - g_free (video->last_error_message); - video->last_error_message = NULL; - } - - length_nanos = (gint64) (video->stream_length * GST_MSECOND); - seek_time = (gint64) (length_nanos * position); - - gst_element_seek (video->play, GST_SEEK_METHOD_SET | - GST_SEEK_FLAG_FLUSH | GST_FORMAT_TIME, - seek_time); - - return TRUE; -} - -gboolean -cltr_video_seek_time (CltrVideo *video, gint64 time, GError **gerror) -{ - if (video->last_error_message) - { - g_free (video->last_error_message); - video->last_error_message = NULL; - } - - gst_element_seek (video->play, GST_SEEK_METHOD_SET | - GST_SEEK_FLAG_FLUSH | GST_FORMAT_TIME, - time * GST_MSECOND); - - return TRUE; -} - -void -cltr_video_stop ( CltrVideo *video) -{ - gst_element_set_state (GST_ELEMENT (video->play), GST_STATE_READY); -} - -void -cltr_video_close ( CltrVideo *video) -{ - gst_element_set_state (GST_ELEMENT (video->play), GST_STATE_READY); - - /* XX close callback here */ -} - -void -cltr_video_pause ( CltrVideo *video) -{ - gst_element_set_state (GST_ELEMENT (video->play), GST_STATE_PAUSED); -} - - -gboolean -cltr_video_can_set_volume ( CltrVideo *video ) -{ - return TRUE; -} - -void -cltr_video_set_volume ( CltrVideo *video, int volume) -{ - if (cltr_video_can_set_volume (video) != FALSE) - { - volume = CLAMP (volume, 0, 100); - g_object_set (G_OBJECT (video->play), "volume", - (gdouble) (1. * volume / 100), NULL); - } -} - -int -cltr_video_get_volume ( CltrVideo *video) -{ - gdouble vol; - - g_object_get (G_OBJECT (video->play), "volume", &vol, NULL); - - return (gint) (vol * 100 + 0.5); -} - -Pixbuf* -cltr_video_get_pixbuf (CltrVideo *video) -{ - Pixbuf *pixb = NULL; - - /* if (video->frame_texture) */ - { - cltr_texture_lock(video->frame_texture); - - pixb = pixbuf_clone(cltr_texture_get_pixbuf(video->frame_texture)); - - cltr_texture_unlock(video->frame_texture); - } - - return pixb; -} - -static gboolean -cltr_video_idler (CltrVideo *video) -{ - gint queue_length; - CltrVideoSignal *signal; - - signal = g_async_queue_try_pop (video->queue); - - if (!signal) - return TRUE; - - switch (signal->signal_id) - { - case CLTR_VIDEO_ASYNC_TEXTURE: - { - Pixbuf *pixb = NULL; - - video->frame_texture = signal->signal_data.texture.ref; - - cltr_texture_lock(video->frame_texture); - - if (cltr_texture_get_pixbuf(video->frame_texture)) - cltr_texture_sync_pixbuf(video->frame_texture); - - cltr_texture_unlock(video->frame_texture); - - cltr_widget_queue_paint(CLTR_WIDGET(video)); - } - break; - case CLTR_VIDEO_ASYNC_VIDEO_SIZE: - video->video_width = signal->signal_data.video_size.width; - video->video_height = signal->signal_data.video_size.height; - break; - case CLTR_VIDEO_ASYNC_ERROR: - break; - case CLTR_VIDEO_ASYNC_FOUND_TAG: - break; - case CLTR_VIDEO_ASYNC_NOTIFY_STREAMINFO: - break; - case CLTR_VIDEO_ASYNC_EOS: - break; - case CLTR_VIDEO_ASYNC_BUFFERING: - break; - case CLTR_VIDEO_ASYNC_REDIRECT: - break; - } - - g_free (signal); - - return TRUE; -} - -gboolean -cltr_video_set_source(CltrVideo *video, char *mrl) -{ - gboolean ret; - - if (video->mrl && !strcmp (video->mrl, mrl)) - return TRUE; - - if (video->mrl) - g_free (video->mrl); - - video->mrl = g_strdup (mrl); - - gst_element_set_state (GST_ELEMENT (video->play), GST_STATE_READY); - - reset_error_msg (video); - - /* video->got_redirect = FALSE; */ - video->has_video = FALSE; - video->stream_length = 0; - - /* Dont handle subtitles as yet - if (g_strrstr (video->mrl, "#subtitle:")) - { - gchar **uris; - - uris = g_strsplit (video->mrl, "#subtitle:", 2); - g_object_set (G_OBJECT (video->play), "uri", - uris[0], "suburi", uris[1], NULL); - g_strfreev (uris); - } - else - { - g_object_set (G_OBJECT (video->play), "uri", - video->mrl, "suburi", subtitle_uri, NULL); - } - */ - - g_object_set (G_OBJECT (video->play), "uri", - video->mrl, "suburi", NULL, NULL); - - ret = (gst_element_set_state (video->play, - GST_STATE_PAUSED) == GST_STATE_SUCCESS); - - - if (!ret /* && !video->got_redirect */) - { - - /* - g_set_error (error, 0, 0, "%s", video->last_error_message ? - video->last_error_message : "Failed to open; reason unknown"); - */ - - g_free (video->mrl); - video->mrl = NULL; - - return FALSE; - } - - /* - if (ret) - g_signal_emit (bvw, bvw_table_signals[SIGNAL_CHANNELS_CHANGE], 0); - */ - - return ret; -} - - - -static void -cltr_video_show(CltrWidget *widget) -{ - return; -} - -static void -cltr_video_hide(CltrWidget *widget) -{ - return; -} - -static gboolean -cltr_video_handle_xevent (CltrWidget *widget, XEvent *xev) -{ - CLTR_DBG("X Event"); - - return False; -} - -static void -cltr_video_paint(CltrWidget *widget) -{ - CltrVideo *video = CLTR_VIDEO(widget); - - glPushMatrix(); - - if (video->frame_texture - && video->video_height - && video->video_width) - { - int dis_x = 0, dis_y = 0, dis_height = 0, dis_width = 0; - - if (video->video_width > video->video_height) - { - dis_width = widget->width; - dis_height = ( video->video_height * widget->width ) - / video->video_width; - dis_y = (widget->height - dis_height)/2; - dis_x = 0; - } - - glEnable(GL_TEXTURE_2D); - - /* - glEnable(GL_BLEND); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - */ - - glColor4f(1.0, 1.0, 1.0, 1.0); - - cltr_texture_lock(video->frame_texture); - - cltr_texture_render_to_gl_quad(video->frame_texture, - widget->x + dis_x, - widget->y + dis_y, - widget->x + dis_x + dis_width, - widget->y + dis_y + dis_height); - - cltr_texture_unlock(video->frame_texture); - - glDisable(GL_TEXTURE_2D); - - glDisable(GL_BLEND); - - // glColor4f(1.0, 1.0, 1.0, 0.5); - - // glRecti(100, 100, 600, 600); - } - - glPopMatrix(); -} diff --git a/clutter/cltr-video.h b/clutter/cltr-video.h deleted file mode 100644 index 49754ef04..000000000 --- a/clutter/cltr-video.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef _HAVE_CLTR_VIDEO_H -#define _HAVE_CLTR_VIDEO_H - -#include "cltr.h" - -#include -#include - -typedef struct CltrVideo CltrVideo; - -/* Signals - cltrimagesink needs to deliver texture signals :/ */ - -enum { - CLTR_VIDEO_ASYNC_TEXTURE, - CLTR_VIDEO_ASYNC_VIDEO_SIZE, - CLTR_VIDEO_ASYNC_ERROR, - CLTR_VIDEO_ASYNC_FOUND_TAG, - CLTR_VIDEO_ASYNC_NOTIFY_STREAMINFO, - CLTR_VIDEO_ASYNC_EOS, - CLTR_VIDEO_ASYNC_BUFFERING, - CLTR_VIDEO_ASYNC_REDIRECT -}; - -typedef struct CltrVideoSignal -{ - gint signal_id; - union - { - struct - { - gint width; - gint height; - } video_size; - struct - { - GstElement *element; - GError *error; - char *debug_message; - } error; - struct - { - GstElement *source; - GstTagList *tag_list; - } found_tag; - struct - { - gint percent; - } buffering; - struct - { - gchar *new_location; - } redirect; - struct - { - CltrTexture *ref; - } texture; - } signal_data; -} -CltrVideoSignal; - -#define CLTR_VIDEO(w) ((CltrVideo*)(w)) - -CltrWidget* -cltr_video_new(int width, int height); - -gboolean -cltr_video_set_source(CltrVideo *video, char *location); - -gboolean -cltr_video_play ( CltrVideo *video, GError ** Error); - -gint64 -cltr_video_get_time (CltrVideo *video); - -gboolean -cltr_video_seek (CltrVideo *video, float position, GError **gerror); - -gboolean -cltr_video_seek_time (CltrVideo *video, gint64 time, GError **gerror); - -void -cltr_video_stop ( CltrVideo *video); - -void -cltr_video_close ( CltrVideo *video); - -void -cltr_video_pause ( CltrVideo *video); - -gboolean -cltr_video_can_set_volume ( CltrVideo *video ); - -void -cltr_video_set_volume ( CltrVideo *video, int volume); - -int -cltr_video_get_volume ( CltrVideo *video); - -Pixbuf* -cltr_video_get_pixbuf (CltrVideo *video); - - -#endif diff --git a/clutter/cltr-widget.c b/clutter/cltr-widget.c deleted file mode 100644 index 908bbb56b..000000000 --- a/clutter/cltr-widget.c +++ /dev/null @@ -1,250 +0,0 @@ -#include "cltr-widget.h" -#include "cltr-private.h" - -CltrWidget* -cltr_widget_new(void) -{ - CltrWidget *w = NULL; - - w = g_malloc0(sizeof(CltrWidget)); - - return w; -} - -int -cltr_widget_abs_x(CltrWidget *widget) -{ - int x = widget->x; - - /* XXX we really need to identify top level window - * this assummes its positioned at 0,0 - but really - * it could be anywhere and need to account for this. - */ - - while ((widget = widget->parent) != NULL) - x += widget->x; - - return x; -} - -int -cltr_widget_abs_y(CltrWidget *widget) -{ - int y = widget->y; - - while ((widget = widget->parent) != NULL) - y += widget->y; - - return y; -} - -int -cltr_widget_abs_x2(CltrWidget *widget) -{ - return cltr_widget_abs_x(widget) + cltr_widget_width(widget); -} - -int -cltr_widget_abs_y2(CltrWidget *widget) -{ - return cltr_widget_abs_y(widget) + cltr_widget_height(widget); -} - - -int -cltr_widget_width(CltrWidget *widget) -{ - return widget->width; -} - -int -cltr_widget_height(CltrWidget *widget) -{ - return widget->height; -} - - -void -cltr_widget_show(CltrWidget *widget) -{ - widget->visible = TRUE; - - if (widget->show) - { - widget->show(widget); - } -} - -void -cltr_widget_unref(CltrWidget *widget) -{ - widget->refcnt--; - - if (widget->refcnt < 0 && widget->destroy) - { - widget->destroy(widget); - } -} - - -/* XXX Focus hacks; - * - * Should not call directly but via cltr_window_focus_widget() - * - * need to sort this out. -*/ -void -cltr_widget_focus(CltrWidget *widget) -{ - if (widget->focus_in) - { - widget->focus_in(widget); - } -} - -void -cltr_widget_unfocus(CltrWidget *widget) -{ - if (widget->focus_out) - { - widget->focus_out(widget); - } -} - -void -cltr_widget_set_focus_next(CltrWidget *widget, - CltrWidget *widget_to_focus, - CltrDirection direction) -{ - switch (direction) - { - case CLTR_NORTH: - widget->focus_next_north = widget_to_focus; - break; - case CLTR_SOUTH: - widget->focus_next_south = widget_to_focus; - break; - case CLTR_EAST: - widget->focus_next_east = widget_to_focus; - break; - case CLTR_WEST: - widget->focus_next_west = widget_to_focus; - break; - } -} - -CltrWidget* -cltr_widget_get_focus_next(CltrWidget *widget, - CltrDirection direction) -{ - switch (direction) - { - case CLTR_NORTH: - return widget->focus_next_north; - case CLTR_SOUTH: - return widget->focus_next_south; - case CLTR_EAST: - return widget->focus_next_east; - case CLTR_WEST: - return widget->focus_next_west; - } - - return NULL; -} - - -void -cltr_widget_show_all(CltrWidget *widget) -{ - GList *widget_item = widget->children;; - - if (widget_item) - { - do - { - CltrWidget *child = CLTR_WIDGET(widget_item->data); - - cltr_widget_show(child); - - cltr_widget_show_all(child); - } - while ((widget_item = g_list_next(widget_item)) != NULL); - } - - cltr_widget_show(widget); -} - -void -cltr_widget_add_child(CltrWidget *widget, CltrWidget *child, int x, int y) -{ - - widget->children = g_list_append(widget->children, child); - - child->parent = widget; - child->x = x; - child->y = y; - -} - -void -cltr_widget_remove_child(CltrWidget *widget, CltrWidget *child) -{ - widget->children = g_list_remove(widget->children, child); - - child->parent = NULL; - child->x = 0; - child->y = 0; -} - - -void -cltr_widget_hide(CltrWidget *widget) -{ - widget->visible = FALSE; -} - -void -cltr_widget_paint(CltrWidget *widget) -{ - if (widget->visible) - { - GList *child_item = widget->children;; - - if (widget->paint) - widget->paint(widget); - - /* Recurse down */ - if (child_item) - { - do - { - CltrWidget *child = CLTR_WIDGET(child_item->data); - - if (child->visible) - cltr_widget_paint(child); - - } - while ((child_item = g_list_next(child_item)) != NULL); - } - } -} - -void -cltr_widget_queue_paint(CltrWidget *widget) -{ - ClutterMainContext *ctx = CLTR_CONTEXT(); - - g_async_queue_push (ctx->internal_event_q, (gpointer)widget); -} - -gboolean -cltr_widget_handle_xevent(CltrWidget *widget, XEvent *xev) -{ - if (!widget->visible) - return FALSE; - - if (widget && widget->xevent_handler) - return widget->xevent_handler(widget, xev); - - return FALSE; -} diff --git a/clutter/cltr-widget.h b/clutter/cltr-widget.h deleted file mode 100644 index ca106e095..000000000 --- a/clutter/cltr-widget.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef _HAVE_CLTR_WIDGET_H -#define _HAVE_CLTR_WIDGET_H - -#include "cltr.h" - -#define CLTR_WIDGET(w) ((CltrWidget*)(w)) - -CltrWidget* -cltr_widget_new(void); - -int -cltr_widget_width(CltrWidget *widget); - -int -cltr_widget_height(CltrWidget *widget); - -int -cltr_widget_abs_x(CltrWidget *widget); - -int -cltr_widget_abs_y(CltrWidget *widget); - -int -cltr_widget_abs_x2(CltrWidget *widget); - -int -cltr_widget_abs_y2(CltrWidget *widget); - - -/* These are hacky see notes in .c */ -void -cltr_widget_focus(CltrWidget *widget); - -void -cltr_widget_unfocus(CltrWidget *widget); - -/* ******************************* */ - -void -cltr_widget_set_focus_next(CltrWidget *widget, - CltrWidget *widget_to_focus, - CltrDirection direction); - -CltrWidget* -cltr_widget_get_focus_next(CltrWidget *widget, - CltrDirection direction); - -void -cltr_widget_show(CltrWidget *widget); - -void -cltr_widget_paint(CltrWidget *widget); - -void -cltr_widget_unref(CltrWidget *widget); - -gboolean -cltr_widget_handle_xevent(CltrWidget *widget, XEvent *xev); - -void -cltr_widget_show_all(CltrWidget *widget); - -void -cltr_widget_queue_paint(CltrWidget *widget); - -void -cltr_widget_add_child(CltrWidget *widget, CltrWidget *child, int x, int y); - -void -cltr_widget_remove_child(CltrWidget *widget, CltrWidget *child); - -#endif diff --git a/clutter/cltr-window.c b/clutter/cltr-window.c deleted file mode 100644 index 33beb836d..000000000 --- a/clutter/cltr-window.c +++ /dev/null @@ -1,257 +0,0 @@ -#include "cltr-window.h" -#include "cltr-private.h" - -static gboolean -cltr_window_handle_xevent (CltrWidget *widget, XEvent *xev); - -static void -cltr_window_show(CltrWidget *widget); - -static void -cltr_window_paint(CltrWidget *widget); - -struct CltrWindow -{ - CltrWidget widget; - Window xwin; - CltrWidget *focused_child; - - CltrCallback *pre_paint_hook, *post_paint_hook; - - CltrXEventCallback xevent_cb; - gpointer *xevent_cb_data; - - CltrCallback post_paint_cb; - gpointer *post_paint_cb_data; - - CltrCallback pre_paint_cb; - gpointer *pre_paint_cb_data; -}; - -void -clrt_window_set_gl_viewport(CltrWindow *win) -{ - CltrWidget *widget = CLTR_WIDGET(win); - - glViewport (0, 0, widget->width, widget->height); - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); - glOrtho (0, widget->width, widget->height, 0, -1, 1); /* 2d */ - glMatrixMode (GL_MODELVIEW); - glLoadIdentity (); -} - -CltrWidget* -cltr_window_new(int width, int height) -{ - ClutterMainContext *ctx = CLTR_CONTEXT(); - CltrWindow *win; - - win = util_malloc0(sizeof(CltrWindow)); - - win->widget.width = width; - win->widget.height = height; - win->widget.show = cltr_window_show; - win->widget.paint = cltr_window_paint; - win->widget.xevent_handler = cltr_window_handle_xevent; - - win->xwin = XCreateSimpleWindow(CltrCntx.xdpy, - CltrCntx.xwin_root, - 0, 0, - width, height, - 0, 0, WhitePixel(CltrCntx.xdpy, - CltrCntx.xscreen)); - - XSelectInput(CltrCntx.xdpy, win->xwin, - StructureNotifyMask|ExposureMask| - KeyPressMask|KeyReleaseMask|PropertyChangeMask); - - glXMakeCurrent(CltrCntx.xdpy, win->xwin, CltrCntx.gl_context); - - /* All likely better somewhere else */ - - ctx->window = CLTR_WIDGET(win); - - clrt_window_set_gl_viewport(win); - - return CLTR_WIDGET(win); -} - -static void -cltr_window_show(CltrWidget *widget) -{ - ClutterMainContext *ctx = CLTR_CONTEXT(); - CltrWindow *win = CLTR_WINDOW(widget); - - /* XXX set focused call */ - if (widget->children) - { - if (win->focused_child == NULL) - win->focused_child = g_list_nth_data(widget->children, 0); - } - - XMapWindow(ctx->xdpy, win->xwin); -} - -static void -cltr_window_paint(CltrWidget *widget) -{ - CltrWindow *win = CLTR_WINDOW(widget); - - clrt_window_set_gl_viewport(win); - - glClear(GL_COLOR_BUFFER_BIT); - - glDisable(GL_LIGHTING); - glDisable(GL_DEPTH_TEST); - - glClearColor( 0.0, 0.0, 0.0, 0.0 ); /* needed for saturate to work */ - - if (win->pre_paint_cb) - win->pre_paint_cb(widget, win->pre_paint_cb_data); -} - -static void -cltr_window_handle_xconfigure(CltrWindow *win, XConfigureEvent *cxev) -{ - /* - widget.width = cxev->width; - widget.height = cxev->height; - */ - -} - -static gboolean -cltr_window_handle_xevent (CltrWidget *widget, XEvent *xev) -{ - CltrWindow *win = CLTR_WINDOW(widget); - - /* XXX handle exposes here too */ - - if (xev->type == Expose) - { - cltr_widget_queue_paint(widget); - } - - /* - case ConfigureNotify: - wm_handle_configure_request(w, &ev.xconfigure); break; - */ - - if (xev->type == KeyPress) - { - if (XKeycodeToKeysym(xev->xkey.display, - xev->xkey.keycode, 0) == XK_Escape) - exit(0); - } - - /* XXX Very basic - assumes we are only interested in mouse clicks */ - if (win->focused_child) - cltr_widget_handle_xevent(win->focused_child, xev); - - if (win->xevent_cb) - (win->xevent_cb)(widget, xev, win->xevent_cb_data); - - return FALSE; -} - -/* window only methods */ - -void -cltr_window_post_paint(CltrWindow *win) -{ - if (win->post_paint_cb) - win->post_paint_cb(CLTR_WIDGET(win), win->post_paint_cb_data); -} - -/* naming is a little odd */ -void -cltr_window_set_paint_funcs(CltrWindow *win, - CltrCallback pre_paint, - gpointer pre_userdata, - CltrCallback post_paint, - gpointer post_userdata) -{ - win->post_paint_cb = post_paint; - win->post_paint_cb_data = post_userdata; - win->pre_paint_cb = pre_paint; - win->pre_paint_cb_data = pre_userdata; -} - - -Window -cltr_window_xwin(CltrWindow *win) -{ - return win->xwin; -} - -void -cltr_window_hide_cursor(CltrWindow *win) -{ - ClutterMainContext *ctx = CLTR_CONTEXT(); - XColor col; - Pixmap pix; - Cursor curs; - - pix = XCreatePixmap (ctx->xdpy, win->xwin, 1, 1, 1); - - memset (&col, 0, sizeof (col)); - - curs = XCreatePixmapCursor (ctx->xdpy, pix, pix, &col, &col, 1, 1); - - XFreePixmap (ctx->xdpy, pix); - - XDefineCursor(ctx->xdpy, win->xwin, curs); -} - -void -cltr_window_set_fullscreen(CltrWindow *win) -{ - ClutterMainContext *ctx = CLTR_CONTEXT(); - - Atom atom_WINDOW_STATE, atom_WINDOW_STATE_FULLSCREEN; - - atom_WINDOW_STATE - = XInternAtom(ctx->xdpy, "_NET_WM_STATE", False); - atom_WINDOW_STATE_FULLSCREEN - = XInternAtom(ctx->xdpy, "_NET_WM_STATE_FULLSCREEN",False); - - XChangeProperty(ctx->xdpy, win->xwin, - atom_WINDOW_STATE, XA_ATOM, 32, - PropModeReplace, - (unsigned char *)&atom_WINDOW_STATE_FULLSCREEN, 1); - - /* - XF86VidModeSwitchToMode (GLWin.dpy, GLWin.screen, &GLWin.deskMode); - XF86VidModeSetViewPort (GLWin.dpy, GLWin.screen, 0, 0); - */ - - cltr_window_hide_cursor(win); -} - - -void -cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget) -{ - /* XXX Should check widget is an actual child of the window */ - - /* ClutterMainContext *ctx = CLTR_CONTEXT(); */ - - if (win->focused_child) - cltr_widget_unfocus(win->focused_child); - - cltr_widget_focus(widget); - - win->focused_child = widget; -} - -void -cltr_window_on_xevent(CltrWindow *win, - CltrXEventCallback callback, - void *userdata) -{ - win->xevent_cb = callback; - win->xevent_cb_data = userdata; -} - - diff --git a/clutter/cltr-window.h b/clutter/cltr-window.h deleted file mode 100644 index b0a3c68cd..000000000 --- a/clutter/cltr-window.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _HAVE_CLTR_WINDOW_H -#define _HAVE_CLTR_WINDOW_H - -#include "cltr.h" - -typedef struct CltrWindow CltrWindow; - -#define CLTR_WINDOW(w) ((CltrWindow*)(w)) - -CltrWidget* -cltr_window_new(int width, int height); - -void -cltr_window_add_widget(CltrWindow *win, CltrWidget *widget, int x, int y); - -/* win only methods */ - -Window -cltr_window_xwin(CltrWindow *win); - -void -cltr_window_hide_cursor(CltrWindow *win); - -void -cltr_window_set_fullscreen(CltrWindow *win); - -void -cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget); - -void -cltr_window_on_xevent(CltrWindow *win, - CltrXEventCallback callback, - void *userdata); -void -cltr_window_post_paint(CltrWindow *win); - - -#endif diff --git a/clutter/cltr.h b/clutter/cltr.h deleted file mode 100644 index 134bad4d0..000000000 --- a/clutter/cltr.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef _HAVE_CLTR_H -#define _HAVE_CLTR_H - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include - -#include - -#include "pixbuf.h" -#include "fonts.h" - -typedef enum CltrDirection -{ - CLTR_NORTH, - CLTR_SOUTH, - CLTR_EAST, - CLTR_WEST -} -CltrDirection; - -typedef enum CltrNamedColor -{ - CLTR_COL_BG = 0, - CLTR_COL_BDR, - CLTR_COL_FG, - CLTR_N_COLS -} -CltrNamedColor; - -typedef struct CltrRect -{ - int x, y, width, height; -} -CltrRect; - -typedef struct CltrTexture CltrTexture; - -#define cltr_rect_x1(r) ((r).x) -#define cltr_rect_y1(r) ((r).y) -#define cltr_rect_x2(r) ((r).x + (r).width) -#define cltr_rect_y2(r) ((r).y + (r).height) - -typedef struct CltrWidget CltrWidget; - - - -typedef void (*CltrCallback) (CltrWidget *widget, void *userdata) ; - -typedef void (*CltrXEventCallback) (CltrWidget *widget, - XEvent *xev, - void *userdata) ; - - -/* texture stuff */ - -/* ******************* */ - -#include "cltr-core.h" -#include "cltr-glu.h" -#include "cltr-texture.h" -#include "cltr-events.h" -#include "cltr-widget.h" -#include "cltr-animator.h" -#include "cltr-window.h" -#include "cltr-overlay.h" -#include "cltr-label.h" -#include "cltr-button.h" -#include "cltr-photo-grid.h" -#include "cltr-list.h" -#include "cltr-video.h" - -#endif diff --git a/clutter/clutter-clone-texture.c b/clutter/clutter-clone-texture.c new file mode 100644 index 000000000..d54f64843 --- /dev/null +++ b/clutter/clutter-clone-texture.c @@ -0,0 +1,306 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "clutter-clone-texture.h" +#include "clutter-main.h" +#include "clutter-util.h" +#include "clutter-enum-types.h" +#include "clutter-private.h" /* for DBG */ + +enum +{ + PROP_0, + PROP_PARENT_TEXTURE +}; + +G_DEFINE_TYPE (ClutterCloneTexture, + clutter_clone_texture, + CLUTTER_TYPE_ELEMENT); + +#define CLUTTER_CLONE_TEXTURE_GET_PRIVATE(obj) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_CLONE_TEXTURE, ClutterCloneTexturePrivate)) + +struct _ClutterCloneTexturePrivate +{ + ClutterTexture *parent_texture; +}; + +static void +clone_texture_render_to_gl_quad (ClutterCloneTexture *ctexture, + int x1, + int y1, + int x2, + int y2) +{ + gint qx1 = 0, qx2 = 0, qy1 = 0, qy2 = 0; + gint qwidth = 0, qheight = 0; + gint x, y, i =0, lastx = 0, lasty = 0; + gint n_x_tiles, n_y_tiles; + gint pwidth, pheight; + float tx, ty; + + ClutterCloneTexturePrivate *priv = ctexture->priv; + ClutterElement *parent_element = CLUTTER_ELEMENT (priv->parent_texture); + + priv = ctexture->priv; + + qwidth = x2 - x1; + qheight = y2 - y1; + + if (!CLUTTER_ELEMENT_IS_REALIZED (parent_element)) + clutter_element_realize (parent_element); + + /* Only paint if parent is in a state to do so */ + if (!clutter_texture_has_generated_tiles (priv->parent_texture)) + return; + + clutter_texture_get_base_size (priv->parent_texture, &pwidth, &pheight); + + if (!clutter_texture_is_tiled (priv->parent_texture)) + { + clutter_texture_bind_tile (priv->parent_texture, 0); + + tx = (float) pwidth / clutter_util_next_p2 (pwidth); + ty = (float) pheight / clutter_util_next_p2 (pheight); + + qx1 = x1; qx2 = x2; + qy1 = y1; qy2 = y2; + + glBegin (GL_QUADS); + glTexCoord2f (tx, ty); glVertex2i (qx2, qy2); + glTexCoord2f (0, ty); glVertex2i (qx1, qy2); + glTexCoord2f (0, 0); glVertex2i (qx1, qy1); + glTexCoord2f (tx, 0); glVertex2i (qx2, qy1); + glEnd (); + + return; + } + + clutter_texture_get_n_tiles (priv->parent_texture, &n_x_tiles, &n_y_tiles); + + for (x=0; x < n_x_tiles; x++) + { + lasty = 0; + + for (y=0; y < n_y_tiles; y++) + { + gint actual_w, actual_h; + gint xpos, ypos, xsize, ysize, ywaste, xwaste; + + clutter_texture_bind_tile (priv->parent_texture, i); + + clutter_texture_get_x_tile_detail (priv->parent_texture, + x, &xpos, &xsize, &xwaste); + + clutter_texture_get_y_tile_detail (priv->parent_texture, + y, &ypos, &ysize, &ywaste); + + actual_w = xsize - xwaste; + actual_h = ysize - ywaste; + + tx = (float) actual_w / xsize; + ty = (float) actual_h / ysize; + + qx1 = x1 + lastx; + qx2 = qx1 + ((qwidth * actual_w ) / pwidth ); + + qy1 = y1 + lasty; + qy2 = qy1 + ((qheight * actual_h) / pheight ); + + glBegin (GL_QUADS); + glTexCoord2f (tx, ty); glVertex2i (qx2, qy2); + glTexCoord2f (0, ty); glVertex2i (qx1, qy2); + glTexCoord2f (0, 0); glVertex2i (qx1, qy1); + glTexCoord2f (tx, 0); glVertex2i (qx2, qy1); + glEnd (); + + lasty += qy2 - qy1; + + i++; + } + lastx += qx2 - qx1; + } +} + +static void +clutter_clone_texture_paint (ClutterElement *self) +{ + ClutterCloneTexturePrivate *priv; + ClutterElement *parent_texture; + gint x1, y1, x2, y2; + + priv = CLUTTER_CLONE_TEXTURE (self)->priv; + + /* parent texture may have been hidden, there for need to make sure its + * realised with resources available. + */ + parent_texture = CLUTTER_ELEMENT (priv->parent_texture); + if (!CLUTTER_ELEMENT_IS_REALIZED (parent_texture)) + clutter_element_realize (parent_texture); + + glEnable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glColor4ub(255, 255, 255, clutter_element_get_opacity(self)); + + clutter_element_get_coords (self, &x1, &y1, &x2, &y2); + clone_texture_render_to_gl_quad (CLUTTER_CLONE_TEXTURE(self), + x1, y1, x2, y2); + + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); +} + +static void +set_parent_texture (ClutterCloneTexture *ctexture, + ClutterTexture *texture) +{ + ClutterCloneTexturePrivate *priv = ctexture->priv; + + if (priv->parent_texture) + { + g_object_unref (priv->parent_texture); + priv->parent_texture = NULL; + } + + if (texture) + priv->parent_texture = g_object_ref (texture); +} + +static void +clutter_clone_texture_dispose (GObject *object) +{ + ClutterCloneTexture *self = CLUTTER_CLONE_TEXTURE(object); + ClutterCloneTexturePrivate *priv = self->priv; + + if (priv->parent_texture) + g_object_unref (priv->parent_texture); + + priv->parent_texture = NULL; + + G_OBJECT_CLASS (clutter_clone_texture_parent_class)->dispose (object); +} + +static void +clutter_clone_texture_finalize (GObject *object) +{ + G_OBJECT_CLASS (clutter_clone_texture_parent_class)->finalize (object); +} + +static void +clutter_clone_texture_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ClutterCloneTexture *ctexture = CLUTTER_CLONE_TEXTURE (object); + + switch (prop_id) + { + case PROP_PARENT_TEXTURE: + set_parent_texture (ctexture, g_value_get_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +clutter_clone_texture_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ClutterCloneTexture *ctexture = CLUTTER_CLONE_TEXTURE (object); + + switch (prop_id) + { + case PROP_PARENT_TEXTURE: + g_value_set_object (value, ctexture->priv->parent_texture); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +clutter_clone_texture_class_init (ClutterCloneTextureClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterElementClass *element_class = CLUTTER_ELEMENT_CLASS (klass); + + element_class->paint = clutter_clone_texture_paint; + + gobject_class->finalize = clutter_clone_texture_finalize; + gobject_class->dispose = clutter_clone_texture_dispose; + gobject_class->set_property = clutter_clone_texture_set_property; + gobject_class->get_property = clutter_clone_texture_get_property; + + g_object_class_install_property (gobject_class, + PROP_PARENT_TEXTURE, + g_param_spec_object ("parent-texture", + "Parent Texture", + "The parent texture to clone", + CLUTTER_TYPE_TEXTURE, + (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE))); + + g_type_class_add_private (gobject_class, sizeof (ClutterCloneTexturePrivate)); +} + +static void +clutter_clone_texture_init (ClutterCloneTexture *self) +{ + ClutterCloneTexturePrivate *priv; + + self->priv = priv = CLUTTER_CLONE_TEXTURE_GET_PRIVATE (self); + priv->parent_texture = NULL; +} + +/** + * clutter_clone_texture_new: + * @texture: a #ClutterTexture + * + * FIXME + * + * Return value: the newly created #ClutterCloneTexture + */ +ClutterElement * +clutter_clone_texture_new (ClutterTexture *texture) +{ + gint width, height; + + g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), NULL); + + clutter_texture_get_base_size (texture, &width, &height); + + return g_object_new (CLUTTER_TYPE_CLONE_TEXTURE, + "parent-texture", texture, + "width", width, + "height", height, + NULL); +} diff --git a/clutter/clutter-clone-texture.h b/clutter/clutter-clone-texture.h new file mode 100644 index 000000000..85a1fdd75 --- /dev/null +++ b/clutter/clutter-clone-texture.h @@ -0,0 +1,85 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, 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 +#include +#include + +G_BEGIN_DECLS + +#define CLUTTER_TYPE_CLONE_TEXTURE (clutter_clone_texture_get_type ()) + +#define CLUTTER_CLONE_TEXTURE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + CLUTTER_TYPE_CLONE_TEXTURE, ClutterCloneTexture)) + +#define CLUTTER_CLONE_TEXTURE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + CLUTTER_TYPE_CLONE_TEXTURE, ClutterCloneTextureClass)) + +#define CLUTTER_IS_CLONE_TEXTURE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + CLUTTER_TYPE_CLONE_TEXTURE)) + +#define CLUTTER_IS_CLONE_TEXTURE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + CLUTTER_TYPE_CLONE_TEXTURE)) + +#define CLUTTER_CLONE_TEXTURE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + CLUTTER_TYPE_CLONE_TEXTURE, ClutterCloneTextureClass)) + +typedef struct _ClutterCloneTexture ClutterCloneTexture; +typedef struct _ClutterCloneTexturePrivate ClutterCloneTexturePrivate; +typedef struct _ClutterCloneTextureClass ClutterCloneTextureClass; + +struct _ClutterCloneTexture +{ + ClutterElement parent; + + /*< priv >*/ + ClutterCloneTexturePrivate *priv; +}; + +struct _ClutterCloneTextureClass +{ + ClutterElementClass parent_class; + + /* padding for future expansion */ + void (*_clutter_clone_1) (void); + void (*_clutter_clone_2) (void); + void (*_clutter_clone_3) (void); + void (*_clutter_clone_4) (void); +}; + +GType clutter_clone_texture_get_type (void); +ClutterElement *clutter_clone_texture_new (ClutterTexture *texture); + +G_END_DECLS + +#endif diff --git a/clutter/clutter-color.c b/clutter/clutter-color.c new file mode 100644 index 000000000..f2bc38e5b --- /dev/null +++ b/clutter/clutter-color.c @@ -0,0 +1,61 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "clutter-color.h" + +ClutterColor +clutter_color_new (guint8 r, guint8 g, guint8 b, guint8 a) +{ + return ( r | g << 8 | b << 16 | a << 24 ); +} + +void +clutter_color_set (ClutterColor *color, + guint8 r, + guint8 g, + guint8 b, + guint8 a) +{ + *color = ( r | g << 8 | b << 16 | a << 24 ); +} + +void +clutter_color_get (ClutterColor color, + guint8 *r, + guint8 *g, + guint8 *b, + guint8 *a) +{ + if (r) + *r = clutter_color_r(color); + if (g) + *g = clutter_color_g(color); + if (b) + *b = clutter_color_b(color); + if (a) + *a = clutter_color_a(color); +} + + diff --git a/clutter/clutter-color.h b/clutter/clutter-color.h new file mode 100644 index 000000000..eab24a430 --- /dev/null +++ b/clutter/clutter-color.h @@ -0,0 +1,64 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, 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 + +G_BEGIN_DECLS + +#define clutter_color_r(col) ((col) >> 24) +#define clutter_color_g(col) (((col) >> 16) & 0xff) +#define clutter_color_b(col) (((col) >> 8) & 0xff) +#define clutter_color_a(col) ((col) & 0xff) + +#define clutter_color_set_r(col,r) ((col) &= (r)) +#define clutter_color_set_g(col,g) ((col) &= (g << 8)) +#define clutter_color_set_b(col,b) ((col) &= (b << 16)) +#define clutter_color_set_a(col,a) ((col) &= (a << 24)) + +typedef guint32 ClutterColor; + +ClutterColor +clutter_color_new (guint8 r, guint8 g, guint8 b, guint8 a); + +void +clutter_color_set (ClutterColor *color, + guint8 r, + guint8 g, + guint8 b, + guint8 a); + +void +clutter_color_get (ClutterColor color, + guint8 *r, + guint8 *g, + guint8 *b, + guint8 *a); + +G_END_DECLS + +#endif diff --git a/clutter/clutter-element.c b/clutter/clutter-element.c new file mode 100644 index 000000000..c8be3ea27 --- /dev/null +++ b/clutter/clutter-element.c @@ -0,0 +1,1285 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:clutter-elementy + * @short_description: Base abstract class for all visual stage elements. + * + * #ClutterElement is an blah blah + */ + +#include "config.h" + +#include "clutter-element.h" +#include "clutter-main.h" +#include "clutter-private.h" + +G_DEFINE_ABSTRACT_TYPE (ClutterElement, clutter_element, G_TYPE_OBJECT); + +static guint32 __id = 0; + +#define CLUTTER_ELEMENT_GET_PRIVATE(obj) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_ELEMENT, ClutterElementPrivate)) + +struct _ClutterElementPrivate +{ + ClutterElementBox coords; + + ClutterGeometry clip; + gboolean has_clip; + + ClutterElementTransform mirror_transform; + gfloat rxang, ryang, rzang; /* Rotation foo. */ + gint rzx, rzy, rxy, rxz, ryx, ryz; + gint z; /* to element box ? */ + + guint8 opacity; + ClutterElement *parent_element; + gchar *name; + guint32 id; /* Unique ID */ +}; + +enum +{ + PROP_0, + PROP_X, + PROP_Y, + PROP_WIDTH, + PROP_HEIGHT, + /* PROP_CLIP FIXME: add */ + PROP_OPACITY, + PROP_NAME, +}; + +extern ClutterMainContext ClutterCntx; + +static gboolean +redraw_update_idle (gpointer data) +{ + ClutterMainContext *ctx = CLUTTER_CONTEXT(); + + clutter_threads_enter(); + + if (ctx->update_idle) + { + g_source_remove (ctx->update_idle); + ctx->update_idle = 0; + } + + clutter_threads_leave(); + + clutter_redraw (); + + return FALSE; +} + +/** + * clutter_element_show + * @self: A #ClutterElement + * + * Flags a clutter element to be displayed. An element not shown will not + * appear on the display. + **/ +void +clutter_element_show (ClutterElement *self) +{ + ClutterElementClass *klass; + + if (CLUTTER_ELEMENT_IS_VISIBLE (self)) + return; + + if (!CLUTTER_ELEMENT_IS_REALIZED (self)) + clutter_element_realize(self); + + CLUTTER_ELEMENT_SET_FLAGS (self, CLUTTER_ELEMENT_MAPPED); + + klass = CLUTTER_ELEMENT_GET_CLASS (self); + + if (klass->show) + (klass->show) (self); + + if (CLUTTER_ELEMENT_IS_VISIBLE (self)) + clutter_element_queue_redraw (self); +} + +/** + * clutter_element_hide + * @self: A #ClutterElement + * + * Flags a clutter element to be hidden. An element not shown will not + * appear on the display. + **/ +void +clutter_element_hide (ClutterElement *self) +{ + ClutterElementClass *klass; + + if (!CLUTTER_ELEMENT_IS_VISIBLE (self)) + return; + + CLUTTER_ELEMENT_UNSET_FLAGS (self, CLUTTER_ELEMENT_MAPPED); + + klass = CLUTTER_ELEMENT_GET_CLASS (self); + + if (klass->hide) + (klass->hide) (self); + + clutter_element_queue_redraw (self); +} + +/** + * clutter_element_realize + * @self: A #ClutterElement + * + * Creates any underlying graphics resources needed by the element to be + * displayed. + **/ +void +clutter_element_realize (ClutterElement *self) +{ + ClutterElementClass *klass; + + if (CLUTTER_ELEMENT_IS_REALIZED (self)) + return; + + CLUTTER_ELEMENT_SET_FLAGS (self, CLUTTER_ELEMENT_REALIZED); + + klass = CLUTTER_ELEMENT_GET_CLASS (self); + + if (klass->realize) + (klass->realize) (self); +} + +/** + * clutter_element_realize + * @self: A #ClutterElement + * + * Frees up any underlying graphics resources needed by the element to be + * displayed. + **/ +void +clutter_element_unrealize (ClutterElement *self) +{ + ClutterElementClass *klass; + + if (!CLUTTER_ELEMENT_IS_REALIZED (self)) + return; + + CLUTTER_ELEMENT_UNSET_FLAGS (self, CLUTTER_ELEMENT_REALIZED); + + klass = CLUTTER_ELEMENT_GET_CLASS (self); + + if (klass->unrealize) + (klass->unrealize) (self); +} + +/** + * clutter_element_paint: + * @self: A #ClutterElement + * + * Renders the element to display. + * + * This function should not be called directly by applications instead + * #clutter_element_queue_redraw should be used to queue paints. + **/ +void +clutter_element_paint (ClutterElement *self) +{ + ClutterElementClass *klass; + + if (!CLUTTER_ELEMENT_IS_REALIZED (self)) + { + CLUTTER_DBG("@@@ Attempting realize via paint() @@@"); + clutter_element_realize(self); + + if (!CLUTTER_ELEMENT_IS_REALIZED (self)) + { + CLUTTER_DBG("*** Attempt failed, aborting paint ***"); + return; + } + } + + klass = CLUTTER_ELEMENT_GET_CLASS (self); + + if (self->priv->has_clip) + { + ClutterGeometry *clip = &self->priv->clip; + gint absx, absy; + + clutter_element_get_abs_position (self, &absx, &absy); + + CLUTTER_DBG("clip +%i+%i, %ix%i\n", + absx + clip->x, + clutter_element_get_height(CLUTTER_ELEMENT(clutter_stage())) + - (absy + clip->y) - clip->height, + clip->width, + clip->height); + + glEnable (GL_SCISSOR_TEST); + + glScissor (absx + clip->x, + clutter_element_get_height(CLUTTER_ELEMENT(clutter_stage())) + - (absy + clip->y) - clip->height, + clip->width, + clip->height); + } + + glPushMatrix(); + + glLoadName (clutter_element_get_id (self)); + + /* FIXME: Less clunky */ + + if (self->priv->rzang) + { + glTranslatef ( (float)(self->priv->coords.x1) + self->priv->rzx, + (float)(self->priv->coords.y1) + self->priv->rzy, + 0.0); + + glRotatef (self->priv->rzang, 0.0f, 0.0f, 1.0f); + + glTranslatef ( (-1.0 * self->priv->coords.x1) - self->priv->rzx, + (-1.0 * self->priv->coords.y1) - self->priv->rzy, + 0.0 ); + } + + if (self->priv->ryang) + { + glTranslatef ( (float)(self->priv->coords.x1) + self->priv->ryx, + 0.0, + (float)(self->priv->z) + self->priv->ryz); + + glRotatef (self->priv->ryang, 0.0f, 1.0f, 0.0f); + + glTranslatef ( (float)(-1.0 * self->priv->coords.x1) - self->priv->ryx, + 0.0, + (float)(-1.0 * self->priv->z) - self->priv->ryz); + } + + if (self->priv->rxang) + { + glTranslatef ( 0.0, + (float)(self->priv->coords.x1) + self->priv->rxy, + (float)(self->priv->z) + self->priv->rxz); + + glRotatef (self->priv->rxang, 1.0f, 0.0f, 0.0f); + + glTranslatef ( 0.0, + (float)(-1.0 * self->priv->coords.x1) - self->priv->rxy, + (float)(-1.0 * self->priv->z) - self->priv->rxz); + } + + + + if (klass->paint) + (klass->paint) (self); + + glPopMatrix(); + + if (self->priv->has_clip) + glDisable (GL_SCISSOR_TEST); +} + +/** + * clutter_element_request_coords: + * @self: A #ClutterElement + * @box: A #ClutterElementBox with requested new co-ordinates. + * + * Requests new co-ordinates for the #ClutterElement ralative to any parent. + * + * This function should not be called directly by applications instead + * the various position/geometry methods should be used. + **/ +void +clutter_element_request_coords (ClutterElement *self, + ClutterElementBox *box) +{ + ClutterElementClass *klass; + + klass = CLUTTER_ELEMENT_GET_CLASS (self); + + /* FIXME: Kludgy see allocate co-ords */ + if (klass->request_coords) + klass->request_coords(self, box); + + self->priv->coords.x1 = box->x1; + self->priv->coords.y1 = box->y1; + self->priv->coords.x2 = box->x2; + self->priv->coords.y2 = box->y2; + + /* TODO: Fire a signal ? Could be usage for WM resizing stage */ + + if (CLUTTER_ELEMENT_IS_VISIBLE (self)) + clutter_element_queue_redraw (self); +} + +/** + * clutter_element_allocate_coords: + * @self: A #ClutterElement + * @box: A location to store the elements #ClutterElementBox co-ordinates + * + * Requests the allocated co-ordinates for the #ClutterElement ralative + * to any parent. + * + * This function should not be called directly by applications instead + * the various position/geometry methods should be used. + **/ +void +clutter_element_allocate_coords (ClutterElement *self, + ClutterElementBox *box) +{ + ClutterElementClass *klass; + + klass = CLUTTER_ELEMENT_GET_CLASS (self); + + box->x1 = self->priv->coords.x1; + box->y1 = self->priv->coords.y1; + box->x2 = self->priv->coords.x2; + box->y2 = self->priv->coords.y2; + + if (klass->request_coords) + { + /* FIXME: This is kind of a cludge - we pass out *private* + * co-ords down to any subclasses so they can modify + * we then resync any changes. Needed for group class. + * Need to figure out nicer way. + */ + klass->allocate_coords(self, box); + + self->priv->coords.x1 = box->x1; + self->priv->coords.y1 = box->y1; + self->priv->coords.x2 = box->x2; + self->priv->coords.y2 = box->y2; + } +} + +static void +clutter_element_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + + ClutterElement *element; + ClutterElementPrivate *priv; + + element = CLUTTER_ELEMENT(object); + priv = element->priv; + + switch (prop_id) + { + case PROP_X: + clutter_element_set_position (element, + g_value_get_int (value), + clutter_element_get_y (element)); + break; + case PROP_Y: + clutter_element_set_position (element, + clutter_element_get_x (element), + g_value_get_int (value)); + break; + case PROP_WIDTH: + clutter_element_set_size (element, + g_value_get_int (value), + clutter_element_get_height (element)); + break; + case PROP_HEIGHT: + clutter_element_set_size (element, + clutter_element_get_width (element), + g_value_get_int (value)); + break; + case PROP_OPACITY: + clutter_element_set_opacity (element, g_value_get_uchar (value)); + break; + case PROP_NAME: + clutter_element_set_name (element, g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +clutter_element_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ClutterElement *element; + ClutterElementPrivate *priv; + + element = CLUTTER_ELEMENT(object); + priv = element->priv; + + switch (prop_id) + { + case PROP_X: + g_value_set_int (value, clutter_element_get_x (element)); + break; + case PROP_Y: + g_value_set_int (value, clutter_element_get_y (element)); + break; + case PROP_WIDTH: + g_value_set_int (value, clutter_element_get_width (element)); + break; + case PROP_HEIGHT: + g_value_set_int (value, clutter_element_get_height (element)); + break; + case PROP_OPACITY: + g_value_set_uchar (value, priv->opacity); + break; + case PROP_NAME: + g_value_set_string (value, priv->name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +clutter_element_dispose (GObject *object) +{ + ClutterElement *self = CLUTTER_ELEMENT(object); + + if (self->priv->parent_element) + { + clutter_group_remove (CLUTTER_GROUP(self->priv->parent_element), self); + } + + G_OBJECT_CLASS (clutter_element_parent_class)->dispose (object); +} + +static void +clutter_element_finalize (GObject *object) +{ + G_OBJECT_CLASS (clutter_element_parent_class)->finalize (object); +} + +static void +clutter_element_class_init (ClutterElementClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = clutter_element_set_property; + object_class->get_property = clutter_element_get_property; + object_class->dispose = clutter_element_dispose; + object_class->finalize = clutter_element_finalize; + + g_type_class_add_private (klass, sizeof (ClutterElementPrivate)); + + g_object_class_install_property + (object_class, PROP_X, + g_param_spec_int ("x", + "X co-ord", + "X co-ord of element", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_Y, + g_param_spec_int ("y", + "Y co-ord", + "Y co-ord of element", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_WIDTH, + g_param_spec_int ("width", + "Width", + "Width of element in pixels", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_HEIGHT, + g_param_spec_int ("height", + "Height", + "Height of element in pixels", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_OPACITY, + g_param_spec_uchar ("opacity", + "Opacity", + "Opacity of element", + 0, + 0xff, + 0xff, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + + /* FIXME: add - as boxed ? + * g_object_class_install_property + * (gobject_class, PROP_CLIP, + * g_param_spec_pointer ("clip", + * "Clip", + * "Clip", + * G_PARAM_READWRITE)); + */ +} + +static void +clutter_element_init (ClutterElement *self) +{ + self->priv = CLUTTER_ELEMENT_GET_PRIVATE (self); + + self->priv->parent_element = NULL; + self->priv->has_clip = FALSE; + self->priv->opacity = 0xff; + self->priv->id = __id++; + + clutter_element_set_position (self, 0, 0); + clutter_element_set_size (self, 0, 0); +} + +/** + * clutter_element_queue_redraw: + * @self: A #ClutterElement + * + * Queues up a redraw of an element and any children. The redraw occurs + * once the main loop becomes idle (after the current batch of events + * has been processed, roughly). + * + * Applications rarely need to call this as redraws are handled automatically + * by modification functions. + */ +void +clutter_element_queue_redraw (ClutterElement *self) +{ + ClutterMainContext *ctx = CLUTTER_CONTEXT(); + + clutter_threads_enter(); + + if (!ctx->update_idle) + { + ctx->update_idle = g_idle_add_full (-100 , /* very high priority */ + redraw_update_idle, + NULL, NULL); + } + + clutter_threads_leave(); +} + +/** + * clutter_element_set_geometry: + * @self: A #ClutterElement + * @geom: A #ClutterGeometry + * + * Sets the elements geometry in pixels relative to any parent element. + */ +void +clutter_element_set_geometry (ClutterElement *self, + ClutterGeometry *geom) +{ + ClutterElementBox box; + + box.x1 = geom->x; + box.y1 = geom->y; + box.x2 = geom->x + geom->width; + box.y2 = geom->y + geom->height; + + clutter_element_request_coords (self, &box); +} + +/** + * clutter_element_get_geometry: + * @self: A #ClutterElement + * @geom: A location to store elements #ClutterGeometry + * + * Gets the elements geometry in pixels relative to any parent element. + */ +void +clutter_element_get_geometry (ClutterElement *self, + ClutterGeometry *geom) +{ + ClutterElementBox box; + + g_return_if_fail (CLUTTER_IS_ELEMENT (self)); + + clutter_element_allocate_coords (self, &box); + + geom->x = box.x1; + geom->y = box.y1; + geom->width = box.x2 - box.x1; + geom->height = box.y2 - box.y1; +} + +/** + * clutter_element_get_coords: + * @self: A #ClutterElement + * @x1: A location to store elements left position if non NULL. + * @y1: A location to store elements top position if non NULL. + * @x2: A location to store elements right position if non NULL. + * @y2: A location to store elements bottom position if non NULL. + * + * Gets the elements bounding rectangle co-ordinates in pixels + * relative to any parent element. + */ +void +clutter_element_get_coords (ClutterElement *self, + gint *x1, + gint *y1, + gint *x2, + gint *y2) +{ + ClutterElementBox box; + + g_return_if_fail (CLUTTER_IS_ELEMENT (self)); + + clutter_element_allocate_coords (self, &box); + + if (x1) *x1 = box.x1; + if (y1) *y1 = box.y1; + if (x2) *x2 = box.x2; + if (y2) *y2 = box.y2; +} + +/** + * clutter_element_set_position + * @self: A #ClutterElement + * @x: New left position of element in pixels. + * @y: New top position of element in pixels. + * + * Sets the elements position in pixels relative to any + * parent element. + */ +void +clutter_element_set_position (ClutterElement *self, + gint x, + gint y) +{ + ClutterElementBox box; + + g_return_if_fail (CLUTTER_IS_ELEMENT (self)); + + clutter_element_allocate_coords (self, &box); + + box.x2 += (x - box.x1); + box.y2 += (y - box.y1); + + box.x1 = x; + box.y1 = y; + + clutter_element_request_coords (self, &box); +} + +/** + * clutter_element_set_size + * @self: A #ClutterElement + * @width: New width of element in pixels + * @height: New height of element in pixels + * + * Sets the elements position in pixels relative to any + * parent element. + */ +void +clutter_element_set_size (ClutterElement *self, + gint width, + gint height) +{ + ClutterElementBox box; + + g_return_if_fail (CLUTTER_IS_ELEMENT (self)); + + clutter_element_allocate_coords (self, &box); + + box.x2 = box.x1 + width; + box.y2 = box.y1 + height; + + clutter_element_request_coords (self, &box); +} + +/** + * clutter_element_set_position + * @self: A #ClutterElement + * @x: Location to store x position if non NULL. + * @y: Location to store y position if non NULL. + * + * Gets the absolute position of an element in pixels relative + * to the stage. + */ +void +clutter_element_get_abs_position (ClutterElement *self, + gint *x, + gint *y) +{ + ClutterElementBox box; + ClutterElement *parent; + gint px = 0, py = 0; + + g_return_if_fail (CLUTTER_IS_ELEMENT (self)); + + clutter_element_allocate_coords (self, &box); + + parent = self->priv->parent_element; + + /* FIXME: must be nicer way to get 0,0 for stage ? */ + if (parent && !CLUTTER_IS_STAGE (parent)) + clutter_element_get_abs_position (parent, &px, &py); + + if (x) + *x = px + box.x1; + + if (y) + *y = py + box.y1; +} + +/** + * clutter_element_get_width + * @self: A #ClutterElement + * + * Retrieves the elements width. + * + * Return value: The element width in pixels + **/ +guint +clutter_element_get_width (ClutterElement *self) +{ + ClutterElementBox box; + + g_return_val_if_fail (CLUTTER_IS_ELEMENT (self), 0); + + clutter_element_allocate_coords (self, &box); + + return box.x2 - box.x1; +} + +/** + * clutter_element_get_height + * @self: A #ClutterElement + * + * Retrieves the elements height. + * + * Return value: The element height in pixels + **/ +guint +clutter_element_get_height (ClutterElement *self) +{ + ClutterElementBox box; + + g_return_val_if_fail (CLUTTER_IS_ELEMENT (self), 0); + + clutter_element_allocate_coords (self, &box); + + return box.y2 - box.y1; +} + +/** + * clutter_element_get_x + * @self: A #ClutterElement + * + * Retrieves the elements x position relative to any parent. + * + * Return value: The element x position in pixels + **/ +gint +clutter_element_get_x (ClutterElement *self) +{ + ClutterElementBox box; + + g_return_val_if_fail (CLUTTER_IS_ELEMENT (self), 0); + + clutter_element_allocate_coords (self, &box); + + return box.x1; +} + +/** + * clutter_element_get_y: + * @self: A #ClutterElement + * + * Retrieves the elements y position relative to any parent. + * + * Return value: The element y position in pixels + **/ +gint +clutter_element_get_y (ClutterElement *self) +{ + ClutterElementBox box; + + g_return_val_if_fail (CLUTTER_IS_ELEMENT (self), 0); + + clutter_element_allocate_coords (self, &box); + + return box.y1; +} + +/** + * clutter_element_set_opacity: + * @self: A #ClutterElement + * @opacity: New opacity value for element. + * + * Sets the elements opacity, with zero being completely transparent. + */ +void +clutter_element_set_opacity (ClutterElement *self, + guint8 opacity) +{ + g_return_if_fail (CLUTTER_IS_ELEMENT (self)); + + self->priv->opacity = opacity; + + if (CLUTTER_ELEMENT_IS_VISIBLE (self)) + clutter_element_queue_redraw (self); +} + +/** + * clutter_element_get_opacity: + * @self: A #ClutterElement + * + * Retrieves the elements opacity. + * + * Return value: The element opacity value. + */ +guint8 +clutter_element_get_opacity (ClutterElement *self) +{ + ClutterElement *parent; + + g_return_val_if_fail (CLUTTER_IS_ELEMENT (self), 0); + + parent = self->priv->parent_element; + + /* FIXME: need to factor in the actual elements opacity with parents */ + if (parent && clutter_element_get_opacity (parent) != 0xff) + return clutter_element_get_opacity(parent); + + return self->priv->opacity; +} + +/** + * clutter_element_set_name: + * @self: A #ClutterElement + * @id: Textual tag to apply to element + * + * Sets a textual tag to the element. + */ +void +clutter_element_set_name (ClutterElement *self, + const gchar *name) +{ + g_return_if_fail (CLUTTER_IS_ELEMENT (self)); + + if (name || name[0] != '\0') + { + g_free (self->priv->name); + + self->priv->name = g_strdup(name); + } +} + +/** + * clutter_element_get_name: + * @self: A #ClutterElement + * + * Return value: pointer to textual tag for the element. The + * returned string is owned by the element and should not + * be modified or freed. + */ +const gchar* +clutter_element_get_name (ClutterElement *self) +{ + g_return_val_if_fail (CLUTTER_IS_ELEMENT (self), NULL); + + return self->priv->name; +} + +/** + * clutter_element_get_id: + * @self: A #ClutterElement + * + * FIXME + * + * Return value: Globally unique value for object instance. + */ +guint32 +clutter_element_get_id (ClutterElement *self) +{ + g_return_val_if_fail (CLUTTER_IS_ELEMENT (self), 0); + + return self->priv->id; +} + +static void +depth_sorter_foreach (ClutterElement *element, gpointer user_data) +{ + ClutterElement *element_to_sort = CLUTTER_ELEMENT(user_data); + + if (element_to_sort->priv->z > element->priv->z) + clutter_element_raise (element_to_sort, element); +} + +/** + * clutter_element_set_depth: + * @self: a #ClutterElement + * @depth: FIXME + * + * FIXME + */ +void +clutter_element_set_depth (ClutterElement *self, + gint depth) +{ + /* Sets Z value. Note probably need to sort via stacking order + * so rendering correct with alpha values. + */ + self->priv->z = depth; + + if (self->priv->parent_element) + { + /* Fix stacking ordering so rendering correct */ + + clutter_element_lower_bottom (self); + + clutter_group_foreach (CLUTTER_GROUP(self->priv->parent_element), + depth_sorter_foreach, + (gpointer)self); + } +} + +/** + * clutter_element_get_depth: + * @self: a #ClutterElement + * + * Retrieves the depth of @self. + * + * Return value: the depth of a #ClutterElement + */ +gint +clutter_element_get_depth (ClutterElement *self) +{ + g_return_val_if_fail (CLUTTER_IS_ELEMENT (self), -1); + + return self->priv->z; +} + +/** + * clutter_element_rotate_z: + * @self: A #ClutterElement + * @angle: Angle of rotation + * @x: X co-ord to rotate element around ( relative to element position ) + * @y: Y co-ord to rotate element around ( relative to element position ) + * + * Rotates element around the Z axis. + */ +void +clutter_element_rotate_z (ClutterElement *self, + gfloat angle, + gint x, + gint y) +{ + g_return_if_fail (CLUTTER_IS_ELEMENT (self)); + + self->priv->rzang = angle; + self->priv->rzx = x; + self->priv->rzy = y; + + if (CLUTTER_ELEMENT_IS_VISIBLE (self)) + clutter_element_queue_redraw (self); +} + +/** + * clutter_element_rotate_x: + * @self: A #ClutterElement + * @angle: Angle of rotation + * @y: Y co-ord to rotate element around ( relative to element position ) + * @z: Z co-ord to rotate element around ( relative to element position ) + * + * Rotates element around the X axis. + */ +void +clutter_element_rotate_x (ClutterElement *self, + gfloat angle, + gint y, + gint z) +{ + g_return_if_fail (CLUTTER_IS_ELEMENT (self)); + + self->priv->rxang = angle; + self->priv->rxy = y; + self->priv->rxz = z; + + if (CLUTTER_ELEMENT_IS_VISIBLE (self)) + clutter_element_queue_redraw (self); +} + +/** + * clutter_element_rotate_y: + * @self: A #ClutterElement + * @angle: Angle of rotation + * @x: X co-ord to rotate element around ( relative to element position ) + * @z: Z co-ord to rotate element around ( relative to element position ) + * + * Rotates element around the X axis. + */ +void +clutter_element_rotate_y (ClutterElement *self, + gfloat angle, + gint x, + gint z) +{ + g_return_if_fail (CLUTTER_IS_ELEMENT (self)); + + self->priv->ryang = angle; + self->priv->ryx = x; + self->priv->ryz = z; + + if (CLUTTER_ELEMENT_IS_VISIBLE (self)) + clutter_element_queue_redraw (self); +} + +/** + * clutter_element_mirror: + * @self: a #ClutterElement + * @transform: a #ClutterElementTransform + * + * FIXME + */ +void +clutter_element_mirror (ClutterElement *self, + ClutterElementTransform transform) +{ + g_return_if_fail (CLUTTER_IS_ELEMENT (self)); + + self->priv->mirror_transform = transform; +} + +/** + * clutter_element_set_clip: + * @self: A #ClutterElement + * @xoff: FIXME + * @yoff: FIXME + * @width: FIXME + * @height: FIXME + * + * Sets clip area for @self. + */ +void +clutter_element_set_clip (ClutterElement *self, + gint xoff, + gint yoff, + gint width, + gint height) +{ + ClutterGeometry *clip; + + g_return_if_fail (CLUTTER_IS_ELEMENT (self)); + + clip = &self->priv->clip; + + clip->x = xoff; + clip->y = yoff; + clip->width = width; + clip->height = height; + + self->priv->has_clip = TRUE; +} + +/** + * clutter_element_remove_clip + * @self: A #ClutterElement + * + * Removes clip area from @self. + */ +void +clutter_element_remove_clip (ClutterElement *self) +{ + g_return_if_fail (CLUTTER_IS_ELEMENT (self)); + + self->priv->has_clip = FALSE; +} + +/** + * clutter_element_set_parent: + * @self: A #ClutterElement + * @parent: A new #ClutterElement parent or NULL + * + * This function should not be used by applications. + */ +void +clutter_element_set_parent (ClutterElement *self, + ClutterElement *parent) +{ + g_return_if_fail (CLUTTER_IS_ELEMENT (self)); + g_return_if_fail ((parent == NULL) || CLUTTER_IS_ELEMENT (parent)); + + if (self->priv->parent_element == parent) + return; + + if (self->priv->parent_element && self->priv->parent_element != parent) + g_object_unref (self->priv->parent_element); + + self->priv->parent_element = parent; + + if (self->priv->parent_element) + g_object_ref (self->priv->parent_element); +} + +/** + * clutter_element_get_parent: + * @self: A #ClutterElement + * + * Return Value: The #ClutterElement parent or NULL + */ +ClutterElement* +clutter_element_get_parent (ClutterElement *self) +{ + return self->priv->parent_element; +} + +/** + * clutter_element_raise: + * @self: A #ClutterElement + * @below: A #ClutterElement to raise above. + * + * Both elements must have the same parent. + */ +void +clutter_element_raise (ClutterElement *self, ClutterElement *below) +{ + g_return_if_fail (clutter_element_get_parent (self) != NULL); + g_return_if_fail + (clutter_element_get_parent (self) != clutter_element_get_parent (below)); + + clutter_group_raise (CLUTTER_GROUP(clutter_element_get_parent (self)), + self, + below); +} + +/** + * clutter_element_lower: + * @self: A #ClutterElement + * @above: A #ClutterElement to lower below + * + * Both elements must have the same parent. + */ +void +clutter_element_lower (ClutterElement *self, ClutterElement *above) +{ + g_return_if_fail (CLUTTER_IS_ELEMENT(self)); + g_return_if_fail (clutter_element_get_parent (self) != NULL); + + /* FIXME: fix Z ordering ? */ + if (above != NULL) + { + g_return_if_fail + (clutter_element_get_parent (self) + != clutter_element_get_parent (above)); + } + + /* FIXME: group_lower should be an overidable method ? */ + clutter_group_lower (CLUTTER_GROUP(clutter_element_get_parent (self)), + self, + above); +} + +/** + * clutter_element_rise_top: + * @self: A #ClutterElement + * + * Rises @self to the top. + */ +void +clutter_element_raise_top (ClutterElement *self) +{ + clutter_element_raise (self, NULL); +} + +/** + * clutter_element_lower_bottom: + * @self: A #ClutterElement + * + * Lowers @self to the bottom. + */ +void +clutter_element_lower_bottom (ClutterElement *self) +{ + clutter_element_lower (self, NULL); +} + +/* + * ClutterGemoetry + */ + +static ClutterGeometry* +clutter_geometry_copy (const ClutterGeometry *geometry) +{ + ClutterGeometry *result = g_new (ClutterGeometry, 1); + + *result = *geometry; + + return result; +} + +GType +clutter_geometry_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = g_boxed_type_register_static ( + g_intern_static_string ("ClutterGeometry"), + (GBoxedCopyFunc) clutter_geometry_copy, + (GBoxedFreeFunc) g_free); + + return our_type; +} + +/* + * ClutterElementBox + */ +static ClutterElementBox * +clutter_element_box_copy (const ClutterElementBox *box) +{ + ClutterElementBox *result = g_new (ClutterElementBox, 1); + + *result = *box; + + return result; +} + +GType +clutter_element_box_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = g_boxed_type_register_static ( + g_intern_static_string ("ClutterElementBox"), + (GBoxedCopyFunc) clutter_element_box_copy, + (GBoxedFreeFunc) g_free); + return our_type; +} diff --git a/clutter/clutter-element.h b/clutter/clutter-element.h new file mode 100644 index 000000000..355e84d68 --- /dev/null +++ b/clutter/clutter-element.h @@ -0,0 +1,261 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, 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 + +G_BEGIN_DECLS + +#define CLUTTER_TYPE_GEOMETRY (clutter_geometry_get_type ()) +#define CLUTTER_TYPE_ELEMENT_BOX (clutter_element_box_get_type ()) + +#define CLUTTER_TYPE_ELEMENT clutter_element_get_type() + +#define CLUTTER_ELEMENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ELEMENT, ClutterElement)) +#define CLUTTER_ELEMENT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ELEMENT, ClutterElementClass)) +#define CLUTTER_IS_ELEMENT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ELEMENT)) +#define CLUTTER_IS_ELEMENT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ELEMENT)) +#define CLUTTER_ELEMENT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ELEMENT, ClutterElementClass)) + +#define CLUTTER_ELEMENT_SET_FLAGS(e,f) ((e)->flags |= (f)) +#define CLUTTER_ELEMENT_UNSET_FLAGS(e,f) ((e)->flags &= ~(f)) + +#define CLUTTER_ELEMENT_IS_MAPPED(e) ((e)->flags & CLUTTER_ELEMENT_MAPPED) +#define CLUTTER_ELEMENT_IS_REALIZED(e) ((e)->flags & CLUTTER_ELEMENT_REALIZED) +#define CLUTTER_ELEMENT_IS_VISIBLE(e) \ + (CLUTTER_ELEMENT_IS_MAPPED(e) && CLUTTER_ELEMENT_IS_REALIZED(e)) + +typedef struct _ClutterElement ClutterElement; +typedef struct _ClutterElementClass ClutterElementClass; +typedef struct _ClutterElementBox ClutterElementBox; +typedef struct _ClutterElementPrivate ClutterElementPrivate; +typedef struct _ClutterGeometry ClutterGeometry; + +typedef void (*ClutterCallback) (ClutterElement *element, gpointer data); + +struct _ClutterGeometry +{ + gint x; + gint y; + guint width; + guint height; +}; + +GType clutter_geometry_get_type (void) G_GNUC_CONST; + +typedef enum +{ + CLUTTER_ELEMENT_MIRROR_X = 1 << 1, + CLUTTER_ELEMENT_MIRROR_Y = 1 << 2 +} ClutterElementTransform; + +typedef enum +{ + CLUTTER_ELEMENT_MAPPED = 1 << 1, + CLUTTER_ELEMENT_REALIZED = 1 << 2 +} ClutterElementFlags; + +struct _ClutterElementBox { gint x1, y1, x2, y2; }; + +GType clutter_element_box_get_type (void) G_GNUC_CONST; + +struct _ClutterElement +{ + /*< public >*/ + GObject parent; + guint32 flags; + + /*< private >*/ + ClutterElementPrivate *priv; +}; + +struct _ClutterElementClass +{ + GObjectClass parent_class; + + void (* show) (ClutterElement *element); + void (* hide) (ClutterElement *element); + void (* realize) (ClutterElement *element); + void (* unrealize) (ClutterElement *element); + void (* paint) (ClutterElement *element); + void (* request_coords) (ClutterElement *element, + ClutterElementBox *box); + void (* allocate_coords) (ClutterElement *element, + ClutterElementBox *box); + void (* set_depth) (ClutterElement *element, + gint depth); + gint (* get_depth) (ClutterElement *element); + + /* to go ? */ + void (* show_all) (ClutterElement *element); + void (* hide_all) (ClutterElement *element); + void (* queue_redraw) (ClutterElement *element); +}; + +GType clutter_element_get_type (void); + +void +clutter_element_show (ClutterElement *self); + +void +clutter_element_hide (ClutterElement *self); + +void +clutter_element_realize (ClutterElement *self); + +void +clutter_element_unrealize (ClutterElement *self); + +void +clutter_element_paint (ClutterElement *self); + +void +clutter_element_queue_redraw (ClutterElement *self); + +void +clutter_element_request_coords (ClutterElement *self, + ClutterElementBox *box); + +void +clutter_element_allocate_coords (ClutterElement *self, + ClutterElementBox *box); + +void +clutter_element_set_geometry (ClutterElement *self, + ClutterGeometry *geom); + +void +clutter_element_get_geometry (ClutterElement *self, + ClutterGeometry *geom); + +void +clutter_element_get_coords (ClutterElement *self, + gint *x1, + gint *y1, + gint *x2, + gint *y2); + +void +clutter_element_set_position (ClutterElement *self, + gint x, + gint y); + +void +clutter_element_set_size (ClutterElement *self, + gint width, + gint height); + +void +clutter_element_get_abs_position (ClutterElement *self, + gint *x, + gint *y); + +guint +clutter_element_get_width (ClutterElement *self); + +guint +clutter_element_get_height (ClutterElement *self); + +gint +clutter_element_get_x (ClutterElement *self); + +gint +clutter_element_get_y (ClutterElement *self); + +void +clutter_element_rotate_z (ClutterElement *self, + gfloat angle, + gint x, + gint y); + +void +clutter_element_rotate_x (ClutterElement *self, + gfloat angle, + gint y, + gint z); + +void +clutter_element_rotate_y (ClutterElement *self, + gfloat angle, + gint x, + gint z); + +void +clutter_element_set_opacity (ClutterElement *self, + guint8 opacity); + +guint8 +clutter_element_get_opacity (ClutterElement *self); + +void +clutter_element_set_name (ClutterElement *self, + const gchar *id); + +const gchar* +clutter_element_get_name (ClutterElement *self); + +guint32 +clutter_element_get_id (ClutterElement *self); + +void +clutter_element_set_clip (ClutterElement *self, + gint xoff, + gint yoff, + gint width, + gint height); + +void +clutter_element_remove_clip (ClutterElement *self); + +void +clutter_element_set_parent (ClutterElement *self, ClutterElement *parent); + +ClutterElement* +clutter_element_get_parent (ClutterElement *self); + +void +clutter_element_raise (ClutterElement *self, ClutterElement *below); + +void +clutter_element_lower (ClutterElement *self, ClutterElement *above); + +void +clutter_element_raise_top (ClutterElement *self); + +void +clutter_element_lower_bottom (ClutterElement *self); + +G_END_DECLS + +#endif diff --git a/clutter/clutter-event.c b/clutter/clutter-event.c new file mode 100644 index 000000000..e55263090 --- /dev/null +++ b/clutter/clutter-event.c @@ -0,0 +1,990 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#include "clutter-event.h" + +#include +#include + +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 for the ksysym<->Unicode + * mapping functions, from the xterm sources. + */ +static struct { + unsigned short keysym; + unsigned short ucs; +} clutter_keysym_to_unicode_tab[] = { + { 0x01a1, 0x0104 }, /* Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */ + { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */ + { 0x01a3, 0x0141 }, /* Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE */ + { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ + { 0x01a6, 0x015a }, /* Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE */ + { 0x01a9, 0x0160 }, /* Scaron Š LATIN CAPITAL LETTER S WITH CARON */ + { 0x01aa, 0x015e }, /* Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA */ + { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ + { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ + { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ + { 0x01af, 0x017b }, /* Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE */ + { 0x01b1, 0x0105 }, /* aogonek ą LATIN SMALL LETTER A WITH OGONEK */ + { 0x01b2, 0x02db }, /* ogonek ˛ OGONEK */ + { 0x01b3, 0x0142 }, /* lstroke ł LATIN SMALL LETTER L WITH STROKE */ + { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ + { 0x01b6, 0x015b }, /* sacute ś LATIN SMALL LETTER S WITH ACUTE */ + { 0x01b7, 0x02c7 }, /* caron ˇ CARON */ + { 0x01b9, 0x0161 }, /* scaron š LATIN SMALL LETTER S WITH CARON */ + { 0x01ba, 0x015f }, /* scedilla ş LATIN SMALL LETTER S WITH CEDILLA */ + { 0x01bb, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */ + { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ + { 0x01bd, 0x02dd }, /* doubleacute ˝ DOUBLE ACUTE ACCENT */ + { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ + { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ + { 0x01c0, 0x0154 }, /* Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE */ + { 0x01c3, 0x0102 }, /* Abreve Ă LATIN CAPITAL LETTER A WITH BREVE */ + { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ + { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ + { 0x01c8, 0x010c }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */ + { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ + { 0x01cc, 0x011a }, /* Ecaron Ě LATIN CAPITAL LETTER E WITH CARON */ + { 0x01cf, 0x010e }, /* Dcaron Ď LATIN CAPITAL LETTER D WITH CARON */ + { 0x01d0, 0x0110 }, /* Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE */ + { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ + { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ + { 0x01d5, 0x0150 }, /* Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ + { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ + { 0x01d9, 0x016e }, /* Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE */ + { 0x01db, 0x0170 }, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ + { 0x01de, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */ + { 0x01e0, 0x0155 }, /* racute ŕ LATIN SMALL LETTER R WITH ACUTE */ + { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ + { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ + { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ + { 0x01e8, 0x010d }, /* ccaron č LATIN SMALL LETTER C WITH CARON */ + { 0x01ea, 0x0119 }, /* eogonek ę LATIN SMALL LETTER E WITH OGONEK */ + { 0x01ec, 0x011b }, /* ecaron ě LATIN SMALL LETTER E WITH CARON */ + { 0x01ef, 0x010f }, /* dcaron ď LATIN SMALL LETTER D WITH CARON */ + { 0x01f0, 0x0111 }, /* dstroke đ LATIN SMALL LETTER D WITH STROKE */ + { 0x01f1, 0x0144 }, /* nacute ń LATIN SMALL LETTER N WITH ACUTE */ + { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ + { 0x01f5, 0x0151 }, /* odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE */ + { 0x01f8, 0x0159 }, /* rcaron ř LATIN SMALL LETTER R WITH CARON */ + { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ + { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ + { 0x01fe, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */ + { 0x01ff, 0x02d9 }, /* abovedot ˙ DOT ABOVE */ + { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ + { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ + { 0x02a9, 0x0130 }, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */ + { 0x02ab, 0x011e }, /* Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE */ + { 0x02ac, 0x0134 }, /* Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ + { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ + { 0x02b6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ + { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */ + { 0x02bb, 0x011f }, /* gbreve ğ LATIN SMALL LETTER G WITH BREVE */ + { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ + { 0x02c5, 0x010a }, /* Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE */ + { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ + { 0x02d5, 0x0120 }, /* Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE */ + { 0x02d8, 0x011c }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ + { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ + { 0x02de, 0x015c }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ + { 0x02e5, 0x010b }, /* cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE */ + { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ + { 0x02f5, 0x0121 }, /* gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE */ + { 0x02f8, 0x011d }, /* gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX */ + { 0x02fd, 0x016d }, /* ubreve ŭ LATIN SMALL LETTER U WITH BREVE */ + { 0x02fe, 0x015d }, /* scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX */ + { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */ + { 0x03a3, 0x0156 }, /* Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA */ + { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ + { 0x03a6, 0x013b }, /* Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA */ + { 0x03aa, 0x0112 }, /* Emacron Ē LATIN CAPITAL LETTER E WITH MACRON */ + { 0x03ab, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */ + { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ + { 0x03b3, 0x0157 }, /* rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA */ + { 0x03b5, 0x0129 }, /* itilde ĩ LATIN SMALL LETTER I WITH TILDE */ + { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ + { 0x03ba, 0x0113 }, /* emacron ē LATIN SMALL LETTER E WITH MACRON */ + { 0x03bb, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */ + { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ + { 0x03bd, 0x014a }, /* ENG Ŋ LATIN CAPITAL LETTER ENG */ + { 0x03bf, 0x014b }, /* eng ŋ LATIN SMALL LETTER ENG */ + { 0x03c0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */ + { 0x03c7, 0x012e }, /* Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK */ + { 0x03cc, 0x0116 }, /* Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE */ + { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ + { 0x03d1, 0x0145 }, /* Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA */ + { 0x03d2, 0x014c }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */ + { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ + { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ + { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ + { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ + { 0x03e0, 0x0101 }, /* amacron ā LATIN SMALL LETTER A WITH MACRON */ + { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ + { 0x03ec, 0x0117 }, /* eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE */ + { 0x03ef, 0x012b }, /* imacron ī LATIN SMALL LETTER I WITH MACRON */ + { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ + { 0x03f2, 0x014d }, /* omacron ō LATIN SMALL LETTER O WITH MACRON */ + { 0x03f3, 0x0137 }, /* kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA */ + { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ + { 0x03fd, 0x0169 }, /* utilde ũ LATIN SMALL LETTER U WITH TILDE */ + { 0x03fe, 0x016b }, /* umacron ū LATIN SMALL LETTER U WITH MACRON */ + { 0x047e, 0x203e }, /* overline ‾ OVERLINE */ + { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ + { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */ + { 0x04a3, 0x300d }, /* kana_closingbracket 」 RIGHT CORNER BRACKET */ + { 0x04a4, 0x3001 }, /* kana_comma 、 IDEOGRAPHIC COMMA */ + { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ + { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */ + { 0x04a7, 0x30a1 }, /* kana_a ァ KATAKANA LETTER SMALL A */ + { 0x04a8, 0x30a3 }, /* kana_i ィ KATAKANA LETTER SMALL I */ + { 0x04a9, 0x30a5 }, /* kana_u ゥ KATAKANA LETTER SMALL U */ + { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */ + { 0x04ab, 0x30a9 }, /* kana_o ォ KATAKANA LETTER SMALL O */ + { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */ + { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */ + { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */ + { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ + { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ + { 0x04b1, 0x30a2 }, /* kana_A ア KATAKANA LETTER A */ + { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */ + { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */ + { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */ + { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */ + { 0x04b6, 0x30ab }, /* kana_KA カ KATAKANA LETTER KA */ + { 0x04b7, 0x30ad }, /* kana_KI キ KATAKANA LETTER KI */ + { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */ + { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */ + { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */ + { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */ + { 0x04bc, 0x30b7 }, /* kana_SHI シ KATAKANA LETTER SI */ + { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */ + { 0x04be, 0x30bb }, /* kana_SE セ KATAKANA LETTER SE */ + { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */ + { 0x04c0, 0x30bf }, /* kana_TA タ KATAKANA LETTER TA */ + { 0x04c1, 0x30c1 }, /* kana_CHI チ KATAKANA LETTER TI */ + { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */ + { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */ + { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */ + { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */ + { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */ + { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */ + { 0x04c8, 0x30cd }, /* kana_NE ネ KATAKANA LETTER NE */ + { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */ + { 0x04ca, 0x30cf }, /* kana_HA ハ KATAKANA LETTER HA */ + { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */ + { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */ + { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */ + { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */ + { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */ + { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */ + { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */ + { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */ + { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */ + { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */ + { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */ + { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */ + { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */ + { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */ + { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */ + { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */ + { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */ + { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */ + { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */ + { 0x04de, 0x309b }, /* voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK */ + { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ + { 0x05ac, 0x060c }, /* Arabic_comma ، ARABIC COMMA */ + { 0x05bb, 0x061b }, /* Arabic_semicolon ؛ ARABIC SEMICOLON */ + { 0x05bf, 0x061f }, /* Arabic_question_mark ؟ ARABIC QUESTION MARK */ + { 0x05c1, 0x0621 }, /* Arabic_hamza ء ARABIC LETTER HAMZA */ + { 0x05c2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */ + { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */ + { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ + { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */ + { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ + { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */ + { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */ + { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA */ + { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */ + { 0x05cb, 0x062b }, /* Arabic_theh ث ARABIC LETTER THEH */ + { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */ + { 0x05cd, 0x062d }, /* Arabic_hah ح ARABIC LETTER HAH */ + { 0x05ce, 0x062e }, /* Arabic_khah خ ARABIC LETTER KHAH */ + { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */ + { 0x05d0, 0x0630 }, /* Arabic_thal ذ ARABIC LETTER THAL */ + { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */ + { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */ + { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */ + { 0x05d4, 0x0634 }, /* Arabic_sheen ش ARABIC LETTER SHEEN */ + { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */ + { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */ + { 0x05d7, 0x0637 }, /* Arabic_tah ط ARABIC LETTER TAH */ + { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */ + { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */ + { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */ + { 0x05e0, 0x0640 }, /* Arabic_tatweel ـ ARABIC TATWEEL */ + { 0x05e1, 0x0641 }, /* Arabic_feh ف ARABIC LETTER FEH */ + { 0x05e2, 0x0642 }, /* Arabic_qaf ق ARABIC LETTER QAF */ + { 0x05e3, 0x0643 }, /* Arabic_kaf ك ARABIC LETTER KAF */ + { 0x05e4, 0x0644 }, /* Arabic_lam ل ARABIC LETTER LAM */ + { 0x05e5, 0x0645 }, /* Arabic_meem م ARABIC LETTER MEEM */ + { 0x05e6, 0x0646 }, /* Arabic_noon ن ARABIC LETTER NOON */ + { 0x05e7, 0x0647 }, /* Arabic_ha ه ARABIC LETTER HEH */ + { 0x05e8, 0x0648 }, /* Arabic_waw و ARABIC LETTER WAW */ + { 0x05e9, 0x0649 }, /* Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA */ + { 0x05ea, 0x064a }, /* Arabic_yeh ي ARABIC LETTER YEH */ + { 0x05eb, 0x064b }, /* Arabic_fathatan ً ARABIC FATHATAN */ + { 0x05ec, 0x064c }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */ + { 0x05ed, 0x064d }, /* Arabic_kasratan ٍ ARABIC KASRATAN */ + { 0x05ee, 0x064e }, /* Arabic_fatha َ ARABIC FATHA */ + { 0x05ef, 0x064f }, /* Arabic_damma ُ ARABIC DAMMA */ + { 0x05f0, 0x0650 }, /* Arabic_kasra ِ ARABIC KASRA */ + { 0x05f1, 0x0651 }, /* Arabic_shadda ّ ARABIC SHADDA */ + { 0x05f2, 0x0652 }, /* Arabic_sukun ْ ARABIC SUKUN */ + { 0x06a1, 0x0452 }, /* Serbian_dje ђ CYRILLIC SMALL LETTER DJE */ + { 0x06a2, 0x0453 }, /* Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE */ + { 0x06a3, 0x0451 }, /* Cyrillic_io ё CYRILLIC SMALL LETTER IO */ + { 0x06a4, 0x0454 }, /* Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE */ + { 0x06a5, 0x0455 }, /* Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE */ + { 0x06a6, 0x0456 }, /* Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x06a7, 0x0457 }, /* Ukrainian_yi ї CYRILLIC SMALL LETTER YI */ + { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ + { 0x06a9, 0x0459 }, /* Cyrillic_lje љ CYRILLIC SMALL LETTER LJE */ + { 0x06aa, 0x045a }, /* Cyrillic_nje њ CYRILLIC SMALL LETTER NJE */ + { 0x06ab, 0x045b }, /* Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE */ + { 0x06ac, 0x045c }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */ + { 0x06ad, 0x0491 }, /* Ukrainian_ghe_with_upturn ґ CYRILLIC SMALL LETTER GHE WITH UPTURN */ + { 0x06ae, 0x045e }, /* Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U */ + { 0x06af, 0x045f }, /* Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE */ + { 0x06b0, 0x2116 }, /* numerosign № NUMERO SIGN */ + { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ + { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ + { 0x06b3, 0x0401 }, /* Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO */ + { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ + { 0x06b5, 0x0405 }, /* Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE */ + { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ + { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ + { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ + { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ + { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ + { 0x06bc, 0x040c }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */ + { 0x06bd, 0x0490 }, /* Ukrainian_GHE_WITH_UPTURN Ґ CYRILLIC CAPITAL LETTER GHE WITH UPTURN */ + { 0x06be, 0x040e }, /* Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U */ + { 0x06bf, 0x040f }, /* Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE */ + { 0x06c0, 0x044e }, /* Cyrillic_yu ю CYRILLIC SMALL LETTER YU */ + { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ + { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ + { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ + { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ + { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ + { 0x06c6, 0x0444 }, /* Cyrillic_ef ф CYRILLIC SMALL LETTER EF */ + { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ + { 0x06c8, 0x0445 }, /* Cyrillic_ha х CYRILLIC SMALL LETTER HA */ + { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ + { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ + { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ + { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ + { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ + { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ + { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ + { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ + { 0x06d1, 0x044f }, /* Cyrillic_ya я CYRILLIC SMALL LETTER YA */ + { 0x06d2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */ + { 0x06d3, 0x0441 }, /* Cyrillic_es с CYRILLIC SMALL LETTER ES */ + { 0x06d4, 0x0442 }, /* Cyrillic_te т CYRILLIC SMALL LETTER TE */ + { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ + { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ + { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ + { 0x06d8, 0x044c }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */ + { 0x06d9, 0x044b }, /* Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU */ + { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ + { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ + { 0x06dc, 0x044d }, /* Cyrillic_e э CYRILLIC SMALL LETTER E */ + { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ + { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ + { 0x06df, 0x044a }, /* Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN */ + { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ + { 0x06e1, 0x0410 }, /* Cyrillic_A А CYRILLIC CAPITAL LETTER A */ + { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ + { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ + { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ + { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ + { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ + { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ + { 0x06e8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */ + { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ + { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ + { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ + { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ + { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */ + { 0x06ee, 0x041d }, /* Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN */ + { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ + { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ + { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ + { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */ + { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ + { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ + { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ + { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ + { 0x06f7, 0x0412 }, /* Cyrillic_VE В CYRILLIC CAPITAL LETTER VE */ + { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ + { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ + { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ + { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ + { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */ + { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ + { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ + { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ + { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ + { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ + { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ + { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ + { 0x07a5, 0x03aa }, /* Greek_IOTAdieresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ + { 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */ + { 0x07a8, 0x038e }, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */ + { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ + { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS */ + { 0x07ae, 0x0385 }, /* Greek_accentdieresis ΅ GREEK DIALYTIKA TONOS */ + { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */ + { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ + { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */ + { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ + { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ + { 0x07b5, 0x03ca }, /* Greek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ + { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ + { 0x07b7, 0x03cc }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */ + { 0x07b8, 0x03cd }, /* Greek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS */ + { 0x07b9, 0x03cb }, /* Greek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ + { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ + { 0x07bb, 0x03ce }, /* Greek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS */ + { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ + { 0x07c2, 0x0392 }, /* Greek_BETA Β GREEK CAPITAL LETTER BETA */ + { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ + { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ + { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ + { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ + { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ + { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ + { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ + { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ + { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */ + { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */ + { 0x07cd, 0x039d }, /* Greek_NU Ν GREEK CAPITAL LETTER NU */ + { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ + { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ + { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */ + { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ + { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ + { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ + { 0x07d5, 0x03a5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */ + { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ + { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ + { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ + { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ + { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ + { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */ + { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ + { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */ + { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ + { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ + { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */ + { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */ + { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */ + { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ + { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */ + { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */ + { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */ + { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */ + { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ + { 0x07f0, 0x03c0 }, /* Greek_pi π GREEK SMALL LETTER PI */ + { 0x07f1, 0x03c1 }, /* Greek_rho ρ GREEK SMALL LETTER RHO */ + { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ + { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA */ + { 0x07f4, 0x03c4 }, /* Greek_tau τ GREEK SMALL LETTER TAU */ + { 0x07f5, 0x03c5 }, /* Greek_upsilon υ GREEK SMALL LETTER UPSILON */ + { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */ + { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */ + { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */ + { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ +/* 0x08a1 leftradical ? ??? */ +/* 0x08a2 topleftradical ? ??? */ +/* 0x08a3 horizconnector ? ??? */ + { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */ + { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ + { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ +/* 0x08a7 topleftsqbracket ? ??? */ +/* 0x08a8 botleftsqbracket ? ??? */ +/* 0x08a9 toprightsqbracket ? ??? */ +/* 0x08aa botrightsqbracket ? ??? */ +/* 0x08ab topleftparens ? ??? */ +/* 0x08ac botleftparens ? ??? */ +/* 0x08ad toprightparens ? ??? */ +/* 0x08ae botrightparens ? ??? */ +/* 0x08af leftmiddlecurlybrace ? ??? */ +/* 0x08b0 rightmiddlecurlybrace ? ??? */ +/* 0x08b1 topleftsummation ? ??? */ +/* 0x08b2 botleftsummation ? ??? */ +/* 0x08b3 topvertsummationconnector ? ??? */ +/* 0x08b4 botvertsummationconnector ? ??? */ +/* 0x08b5 toprightsummation ? ??? */ +/* 0x08b6 botrightsummation ? ??? */ +/* 0x08b7 rightmiddlesummation ? ??? */ + { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ + { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */ + { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ + { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */ + { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */ + { 0x08c1, 0x221d }, /* variation ∝ PROPORTIONAL TO */ + { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */ + { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */ + { 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */ +/* 0x08c9 similarequal ? ??? */ + { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ + { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ + { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */ + { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */ + { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */ + { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */ + { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */ + { 0x08dd, 0x222a }, /* union ∪ UNION */ + { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */ + { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */ + { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ + { 0x08f6, 0x0192 }, /* function ƒ LATIN SMALL LETTER F WITH HOOK */ + { 0x08fb, 0x2190 }, /* leftarrow ← LEFTWARDS ARROW */ + { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */ + { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */ + { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */ + { 0x09df, 0x2422 }, /* blank ␢ BLANK SYMBOL */ + { 0x09e0, 0x25c6 }, /* soliddiamond ◆ BLACK DIAMOND */ + { 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */ + { 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */ + { 0x09e3, 0x240c }, /* ff ␌ SYMBOL FOR FORM FEED */ + { 0x09e4, 0x240d }, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */ + { 0x09e5, 0x240a }, /* lf ␊ SYMBOL FOR LINE FEED */ + { 0x09e8, 0x2424 }, /* nl ␤ SYMBOL FOR NEWLINE */ + { 0x09e9, 0x240b }, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */ + { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ + { 0x09eb, 0x2510 }, /* uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */ + { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ + { 0x09ed, 0x2514 }, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */ + { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ +/* 0x09ef horizlinescan1 ? ??? */ +/* 0x09f0 horizlinescan3 ? ??? */ + { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ +/* 0x09f2 horizlinescan7 ? ??? */ +/* 0x09f3 horizlinescan9 ? ??? */ + { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ + { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ + { 0x09f6, 0x2534 }, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ + { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ + { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ + { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */ + { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */ + { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */ + { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */ + { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */ + { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */ + { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */ + { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */ + { 0x0aa9, 0x2014 }, /* emdash — EM DASH */ + { 0x0aaa, 0x2013 }, /* endash – EN DASH */ +/* 0x0aac signifblank ? ??? */ + { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */ +/* 0x0aaf doubbaselinedot ? ??? */ + { 0x0ab0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */ + { 0x0ab1, 0x2154 }, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */ + { 0x0ab2, 0x2155 }, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */ + { 0x0ab3, 0x2156 }, /* twofifths ⅖ VULGAR FRACTION TWO FIFTHS */ + { 0x0ab4, 0x2157 }, /* threefifths ⅗ VULGAR FRACTION THREE FIFTHS */ + { 0x0ab5, 0x2158 }, /* fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS */ + { 0x0ab6, 0x2159 }, /* onesixth ⅙ VULGAR FRACTION ONE SIXTH */ + { 0x0ab7, 0x215a }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */ + { 0x0ab8, 0x2105 }, /* careof ℅ CARE OF */ + { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */ + { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */ + { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */ + { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */ +/* 0x0abf marker ? ??? */ + { 0x0ac3, 0x215b }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */ + { 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */ + { 0x0ac5, 0x215d }, /* fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS */ + { 0x0ac6, 0x215e }, /* seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS */ + { 0x0ac9, 0x2122 }, /* trademark ™ TRADE MARK SIGN */ + { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */ +/* 0x0acb trademarkincircle ? ??? */ + { 0x0acc, 0x25c1 }, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */ + { 0x0acd, 0x25b7 }, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */ + { 0x0ace, 0x25cb }, /* emopencircle ○ WHITE CIRCLE */ + { 0x0acf, 0x25a1 }, /* emopenrectangle □ WHITE SQUARE */ + { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ + { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ + { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ + { 0x0ad3, 0x201d }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */ + { 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */ + { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */ + { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */ + { 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */ +/* 0x0ada hexagram ? ??? */ + { 0x0adb, 0x25ac }, /* filledrectbullet ▬ BLACK RECTANGLE */ + { 0x0adc, 0x25c0 }, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */ + { 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */ + { 0x0ade, 0x25cf }, /* emfilledcircle ● BLACK CIRCLE */ + { 0x0adf, 0x25a0 }, /* emfilledrect ■ BLACK SQUARE */ + { 0x0ae0, 0x25e6 }, /* enopencircbullet ◦ WHITE BULLET */ + { 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */ + { 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */ + { 0x0ae3, 0x25b3 }, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */ + { 0x0ae4, 0x25bd }, /* opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE */ + { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */ + { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */ + { 0x0ae7, 0x25aa }, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */ + { 0x0ae8, 0x25b2 }, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */ + { 0x0ae9, 0x25bc }, /* filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE */ + { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ + { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ + { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */ + { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */ + { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */ + { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */ + { 0x0af1, 0x2020 }, /* dagger † DAGGER */ + { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */ + { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */ + { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */ + { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */ + { 0x0af6, 0x266d }, /* musicalflat ♭ MUSIC FLAT SIGN */ + { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */ + { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */ + { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */ + { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */ + { 0x0afb, 0x2117 }, /* phonographcopyright ℗ SOUND RECORDING COPYRIGHT */ + { 0x0afc, 0x2038 }, /* caret ‸ CARET */ + { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ + { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ +/* 0x0aff cursor ? ??? */ + { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */ + { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */ + { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */ + { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */ + { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */ + { 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */ + { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */ + { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */ + { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */ + { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */ + { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */ + { 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */ + { 0x0bcf, 0x25cb }, /* circle ○ WHITE CIRCLE */ + { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */ + { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */ + { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */ + { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */ + { 0x0bdc, 0x22a3 }, /* lefttack ⊣ LEFT TACK */ + { 0x0bfc, 0x22a2 }, /* righttack ⊢ RIGHT TACK */ + { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ + { 0x0ce0, 0x05d0 }, /* hebrew_aleph א HEBREW LETTER ALEF */ + { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */ + { 0x0ce2, 0x05d2 }, /* hebrew_gimel ג HEBREW LETTER GIMEL */ + { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */ + { 0x0ce4, 0x05d4 }, /* hebrew_he ה HEBREW LETTER HE */ + { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */ + { 0x0ce6, 0x05d6 }, /* hebrew_zain ז HEBREW LETTER ZAYIN */ + { 0x0ce7, 0x05d7 }, /* hebrew_chet ח HEBREW LETTER HET */ + { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */ + { 0x0ce9, 0x05d9 }, /* hebrew_yod י HEBREW LETTER YOD */ + { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ + { 0x0ceb, 0x05db }, /* hebrew_kaph כ HEBREW LETTER KAF */ + { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */ + { 0x0ced, 0x05dd }, /* hebrew_finalmem ם HEBREW LETTER FINAL MEM */ + { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */ + { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ + { 0x0cf0, 0x05e0 }, /* hebrew_nun נ HEBREW LETTER NUN */ + { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */ + { 0x0cf2, 0x05e2 }, /* hebrew_ayin ע HEBREW LETTER AYIN */ + { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ף HEBREW LETTER FINAL PE */ + { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */ + { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ץ HEBREW LETTER FINAL TSADI */ + { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */ + { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */ + { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */ + { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */ + { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */ + { 0x0da1, 0x0e01 }, /* Thai_kokai ก THAI CHARACTER KO KAI */ + { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ + { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ + { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ + { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ + { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ + { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ + { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ + { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ + { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ + { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */ + { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ + { 0x0dad, 0x0e0d }, /* Thai_yoying ญ THAI CHARACTER YO YING */ + { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ + { 0x0daf, 0x0e0f }, /* Thai_topatak ฏ THAI CHARACTER TO PATAK */ + { 0x0db0, 0x0e10 }, /* Thai_thothan ฐ THAI CHARACTER THO THAN */ + { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ + { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ + { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */ + { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */ + { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */ + { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ + { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ + { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */ + { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */ + { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ + { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */ + { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ + { 0x0dbd, 0x0e1d }, /* Thai_fofa ฝ THAI CHARACTER FO FA */ + { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ + { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ + { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */ + { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */ + { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */ + { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */ + { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */ + { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */ + { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */ + { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ + { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */ + { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ + { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */ + { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */ + { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ + { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */ + { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ + { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ + { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */ + { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ + { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */ + { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */ + { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */ + { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */ + { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */ + { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ + { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */ + { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */ + { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ + { 0x0dde, 0x0e3e }, /* Thai_maihanakat_maitho ฾ ??? */ + { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ + { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */ + { 0x0de1, 0x0e41 }, /* Thai_saraae แ THAI CHARACTER SARA AE */ + { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */ + { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ + { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ + { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ + { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ + { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ + { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */ + { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */ + { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ + { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ + { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ + { 0x0ded, 0x0e4d }, /* Thai_nikhahit ํ THAI CHARACTER NIKHAHIT */ + { 0x0df0, 0x0e50 }, /* Thai_leksun ๐ THAI DIGIT ZERO */ + { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */ + { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */ + { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */ + { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */ + { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */ + { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */ + { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ + { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ + { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */ + { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ + { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ + { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ + { 0x0ea4, 0x3134 }, /* Hangul_Nieun ㄴ HANGUL LETTER NIEUN */ + { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ + { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */ + { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT */ + { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ + { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ + { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ + { 0x0eab, 0x313b }, /* Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM */ + { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ + { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ + { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ + { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH */ + { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH */ + { 0x0eb1, 0x3141 }, /* Hangul_Mieum ㅁ HANGUL LETTER MIEUM */ + { 0x0eb2, 0x3142 }, /* Hangul_Pieub ㅂ HANGUL LETTER PIEUP */ + { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP */ + { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS */ + { 0x0eb5, 0x3145 }, /* Hangul_Sios ㅅ HANGUL LETTER SIOS */ + { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS */ + { 0x0eb7, 0x3147 }, /* Hangul_Ieung ㅇ HANGUL LETTER IEUNG */ + { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ㅈ HANGUL LETTER CIEUC */ + { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC */ + { 0x0eba, 0x314a }, /* Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH */ + { 0x0ebb, 0x314b }, /* Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH */ + { 0x0ebc, 0x314c }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */ + { 0x0ebd, 0x314d }, /* Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH */ + { 0x0ebe, 0x314e }, /* Hangul_Hieuh ㅎ HANGUL LETTER HIEUH */ + { 0x0ebf, 0x314f }, /* Hangul_A ㅏ HANGUL LETTER A */ + { 0x0ec0, 0x3150 }, /* Hangul_AE ㅐ HANGUL LETTER AE */ + { 0x0ec1, 0x3151 }, /* Hangul_YA ㅑ HANGUL LETTER YA */ + { 0x0ec2, 0x3152 }, /* Hangul_YAE ㅒ HANGUL LETTER YAE */ + { 0x0ec3, 0x3153 }, /* Hangul_EO ㅓ HANGUL LETTER EO */ + { 0x0ec4, 0x3154 }, /* Hangul_E ㅔ HANGUL LETTER E */ + { 0x0ec5, 0x3155 }, /* Hangul_YEO ㅕ HANGUL LETTER YEO */ + { 0x0ec6, 0x3156 }, /* Hangul_YE ㅖ HANGUL LETTER YE */ + { 0x0ec7, 0x3157 }, /* Hangul_O ㅗ HANGUL LETTER O */ + { 0x0ec8, 0x3158 }, /* Hangul_WA ㅘ HANGUL LETTER WA */ + { 0x0ec9, 0x3159 }, /* Hangul_WAE ㅙ HANGUL LETTER WAE */ + { 0x0eca, 0x315a }, /* Hangul_OE ㅚ HANGUL LETTER OE */ + { 0x0ecb, 0x315b }, /* Hangul_YO ㅛ HANGUL LETTER YO */ + { 0x0ecc, 0x315c }, /* Hangul_U ㅜ HANGUL LETTER U */ + { 0x0ecd, 0x315d }, /* Hangul_WEO ㅝ HANGUL LETTER WEO */ + { 0x0ece, 0x315e }, /* Hangul_WE ㅞ HANGUL LETTER WE */ + { 0x0ecf, 0x315f }, /* Hangul_WI ㅟ HANGUL LETTER WI */ + { 0x0ed0, 0x3160 }, /* Hangul_YU ㅠ HANGUL LETTER YU */ + { 0x0ed1, 0x3161 }, /* Hangul_EU ㅡ HANGUL LETTER EU */ + { 0x0ed2, 0x3162 }, /* Hangul_YI ㅢ HANGUL LETTER YI */ + { 0x0ed3, 0x3163 }, /* Hangul_I ㅣ HANGUL LETTER I */ + { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ + { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ + { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ + { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ + { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ + { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */ + { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ + { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ + { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ + { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ + { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ + { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ + { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ + { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ + { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ + { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ + { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ + { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ + { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ + { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ + { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ + { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ + { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ + { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ + { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ + { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */ + { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ + { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH */ + { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */ + { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */ + { 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */ +/* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */ + { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ + { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ + { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */ + { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ + { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ +/* 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ??? */ + { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ + { 0x0eff, 0x20a9 }, /* Korean_Won ₩ WON SIGN */ + { 0x13bc, 0x0152 }, /* OE Œ LATIN CAPITAL LIGATURE OE */ + { 0x13bd, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */ + { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ + { 0x20a0, 0x20a0 }, /* EcuSign ₠ EURO-CURRENCY SIGN */ + { 0x20a1, 0x20a1 }, /* ColonSign ₡ COLON SIGN */ + { 0x20a2, 0x20a2 }, /* CruzeiroSign ₢ CRUZEIRO SIGN */ + { 0x20a3, 0x20a3 }, /* FFrancSign ₣ FRENCH FRANC SIGN */ + { 0x20a4, 0x20a4 }, /* LiraSign ₤ LIRA SIGN */ + { 0x20a5, 0x20a5 }, /* MillSign ₥ MILL SIGN */ + { 0x20a6, 0x20a6 }, /* NairaSign ₦ NAIRA SIGN */ + { 0x20a7, 0x20a7 }, /* PesetaSign ₧ PESETA SIGN */ + { 0x20a8, 0x20a8 }, /* RupeeSign ₨ RUPEE SIGN */ + { 0x20a9, 0x20a9 }, /* WonSign ₩ WON SIGN */ + { 0x20aa, 0x20aa }, /* NewSheqelSign ₪ NEW SHEQEL SIGN */ + { 0x20ab, 0x20ab }, /* DongSign ₫ DONG SIGN */ + { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */ + + + /* Following items added to GTK, not in the xterm table */ + + /* Numeric keypad */ + + { 0xFF80 /* Space */, ' ' }, + { 0xFFAA /* Multiply */, '*' }, + { 0xFFAB /* Add */, '+' }, + { 0xFFAC /* Separator */, ',' }, + { 0xFFAD /* Subtract */, '-' }, + { 0xFFAE /* Decimal */, '.' }, + { 0xFFAF /* Divide */, '/' }, + { 0xFFB0 /* 0 */, '0' }, + { 0xFFB1 /* 1 */, '1' }, + { 0xFFB2 /* 2 */, '2' }, + { 0xFFB3 /* 3 */, '3' }, + { 0xFFB4 /* 4 */, '4' }, + { 0xFFB5 /* 5 */, '5' }, + { 0xFFB6 /* 6 */, '6' }, + { 0xFFB7 /* 7 */, '7' }, + { 0xFFB8 /* 8 */, '8' }, + { 0xFFB9 /* 9 */, '9' }, + { 0xFFBD /* Equal */, '=' }, + + /* End numeric keypad */ +}; + +/** + * clutter_keysym_to_unicode: + * @keyval: a clutter key symbol + * + * Convert from a GDK key symbol to the corresponding ISO10646 (Unicode) + * character. + * + * Return value: the corresponding unicode character, or 0 if there + * is no corresponding character. + **/ +guint32 +clutter_keysym_to_unicode (guint keyval) +{ + int min = 0; + int max = G_N_ELEMENTS (clutter_keysym_to_unicode_tab) - 1; + int mid; + + /* First check for Latin-1 characters (1:1 mapping) */ + if ((keyval >= 0x0020 && keyval <= 0x007e) || + (keyval >= 0x00a0 && keyval <= 0x00ff)) + return keyval; + + /* Also check for directly encoded 24-bit UCS characters: + */ + if ((keyval & 0xff000000) == 0x01000000) + return keyval & 0x00ffffff; + + /* binary search in table */ + while (max >= min) { + mid = (min + max) / 2; + if (clutter_keysym_to_unicode_tab[mid].keysym < keyval) + min = mid + 1; + else if (clutter_keysym_to_unicode_tab[mid].keysym > keyval) + max = mid - 1; + else { + /* found it */ + return clutter_keysym_to_unicode_tab[mid].ucs; + } + } + + /* No matching Unicode value found */ + return 0; +} + diff --git a/clutter/clutter-event.h b/clutter/clutter-event.h new file mode 100644 index 000000000..7e0d7daaf --- /dev/null +++ b/clutter/clutter-event.h @@ -0,0 +1,126 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, 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 + +G_BEGIN_DECLS + + +enum +{ + /* Map to xlibs masks */ + CLUTTER_BUTTON1_MASK = (1<<8), + CLUTTER_BUTTON2_MASK = (1<<9), + CLUTTER_BUTTON3_MASK = (1<<10), + CLUTTER_BUTTON4_MASK = (1<<11), + CLUTTER_BUTTON5_MASK = (1<<12) +}; + +typedef enum +{ + CLUTTER_KEY_PRESS, + CLUTTER_KEY_RELEASE, + CLUTTER_MOTION, + CLUTTER_BUTTON_PRESS, + CLUTTER_2BUTTON_PRESS, /* Double click */ + CLUTTER_BUTTON_RELEASE +} ClutterEventType; + +typedef union _ClutterEvent ClutterEvent; + +typedef struct _ClutterKeyEvent ClutterKeyEvent; +typedef struct _ClutterButtonEvent ClutterButtonEvent; +typedef struct _ClutterMotionEvent ClutterMotionEvent; + +typedef struct _ClutterInputDevice ClutterInputDevice; + +struct _ClutterKeyEvent +{ + ClutterEventType type; + guint32 time; + guint modifier_state; + guint keyval; + guint16 hardware_keycode; +}; + +struct _ClutterButtonEvent +{ + ClutterEventType type; + guint32 time; + gint x; + gint y; + guint32 modifier_state; + guint32 button; + gdouble *axes; /* Future use */ + ClutterInputDevice *device; /* Future use */ +}; + +struct _ClutterMotionEvent +{ + ClutterEventType type; + guint32 time; + gint x; + gint y; + guint32 modifier_state; + gdouble *axes; /* Future use */ + ClutterInputDevice *device; /* Future use */ +}; + +union _ClutterEvent +{ + ClutterEventType type; + + ClutterKeyEvent key_event; + ClutterButtonEvent button_event; + ClutterMotionEvent motion_event; +}; + +ClutterEventType +clutter_key_event_type (ClutterKeyEvent *keyev); + +guint32 +clutter_key_event_time (ClutterKeyEvent *keyev); + +guint +clutter_key_event_state (ClutterKeyEvent *keyev); + +guint +clutter_key_event_symbol (ClutterKeyEvent *keyev); + +guint16 +clutter_key_event_code (ClutterKeyEvent *keyev); + +guint32 +clutter_key_event_unicode (ClutterKeyEvent *keyev); + +guint32 +clutter_keysym_to_unicode (guint keyval); + +G_END_DECLS + +#endif diff --git a/clutter/clutter-group.c b/clutter/clutter-group.c new file mode 100644 index 000000000..5fc3dbca4 --- /dev/null +++ b/clutter/clutter-group.c @@ -0,0 +1,481 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" +#include + +#include "clutter-group.h" +#include "clutter-main.h" + +G_DEFINE_TYPE (ClutterGroup, clutter_group, CLUTTER_TYPE_ELEMENT); + +#define CLUTTER_GROUP_GET_PRIVATE(obj) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_GROUP, ClutterGroupPrivate)) + +struct _ClutterGroupPrivate +{ + GList *children; +}; + +static void +clutter_group_paint (ClutterElement *element) +{ + ClutterGroup *self = CLUTTER_GROUP(element); + GList *child_item; + + child_item = self->priv->children; + + glPushMatrix(); + + /* Translate if parent ( i.e not stage window ). + */ + if (clutter_element_get_parent(element) != NULL) + { + ClutterGeometry geom; + + clutter_element_get_geometry (element, &geom); + + if (geom.x != 0 && geom.y != 0) + glTranslatef(geom.x, geom.y, 0.0); + + } + + if (child_item) + { + do + { + ClutterElement *child = CLUTTER_ELEMENT(child_item->data); + + if (CLUTTER_ELEMENT_IS_MAPPED (child)) + { + clutter_element_paint(child); + } + } + while ((child_item = g_list_next(child_item)) != NULL); + } + + glPopMatrix(); +} + +static void +clutter_group_request_coords (ClutterElement *self, + ClutterElementBox *box) +{ + /* FIXME: what to do here ? + * o clip if smaller ? + * o scale each element ? + */ +} + +static void +clutter_group_allocate_coords (ClutterElement *self, + ClutterElementBox *box) +{ + ClutterGroupPrivate *priv; + GList *child_item; + + priv = CLUTTER_GROUP(self)->priv; + + child_item = priv->children; + + if (child_item) + { + do + { + ClutterElement *child = CLUTTER_ELEMENT(child_item->data); + + if (CLUTTER_ELEMENT_IS_VISIBLE (child)) + { + ClutterElementBox cbox; + + clutter_element_allocate_coords (child, &cbox); + + /* + if (box->x1 == 0 || cbox.x1 < box->x1) + box->x1 = cbox.x1; + + if (box->y1 == 0 || cbox.y1 < box->y1) + box->y1 = cbox.y1; + */ + + if (box->x2 == 0 || cbox.x2 > box->x2) + box->x2 = cbox.x2; + + if (box->y2 == 0 || cbox.y2 < box->y2) + box->y2 = cbox.y2; + } + } + while ((child_item = g_list_next(child_item)) != NULL); + } +} + +static void +clutter_group_dispose (GObject *object) +{ + ClutterGroup *self = CLUTTER_GROUP(object); + + if (self->priv) + { + /* FIXME: Do we need to actually free anything here ? + * Children ref us so this wont get called till + * they are all removed. + */ + } + + G_OBJECT_CLASS (clutter_group_parent_class)->dispose (object); +} + + +static void +clutter_group_finalize (GObject *object) +{ + G_OBJECT_CLASS (clutter_group_parent_class)->finalize (object); +} + +static void +clutter_group_class_init (ClutterGroupClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + ClutterElementClass *element_class = CLUTTER_ELEMENT_CLASS (klass); + + element_class->paint = clutter_group_paint; + /* + element_class->show = clutter_group_show_all; + element_class->hide = clutter_group_hide_all; + */ + element_class->request_coords = clutter_group_request_coords; + element_class->allocate_coords = clutter_group_allocate_coords; + + /* GObject */ + object_class->finalize = clutter_group_finalize; + object_class->dispose = clutter_group_dispose; + + g_type_class_add_private (object_class, sizeof (ClutterGroupPrivate)); +} + +static void +clutter_group_init (ClutterGroup *self) +{ + self->priv = CLUTTER_GROUP_GET_PRIVATE (self); +} + +/** + * clutter_group_new: + * + * Create a new #ClutterGroup instance. + * + * returns a new #ClutterGroup + **/ +ClutterGroup* +clutter_group_new (void) +{ + return g_object_new (CLUTTER_TYPE_GROUP, NULL); +} + +/** + * clutter_group_get_children: + * @self: A #ClutterGroup + * + * Get a list containing all elements contained in the group. + * + * Return value: A GList containing child #ClutterElements. + **/ +GList* +clutter_group_get_children (ClutterGroup *self) +{ + g_return_val_if_fail (CLUTTER_IS_GROUP (self), NULL); + + return g_list_copy(self->priv->children); +} + +/** + * clutter_group_forall: + * @self: A #ClutterGroup + * @callback: a callback + * @user_data: callback user data + * + * Invokes callback on each child of the group. + **/ +void +clutter_group_foreach (ClutterGroup *self, + ClutterCallback callback, + gpointer user_data) +{ + ClutterElement *child; + GList *children; + + g_return_if_fail (CLUTTER_IS_GROUP (self)); + g_return_if_fail (callback != NULL); + + children = self->priv->children; + + while (children) + { + child = children->data; + + (*callback) (child, user_data); + + children = g_list_next(children); + } +} + +/** + * clutter_group_show_all: + * @self: A #ClutterGroup + * + * Show all child elements of the group. Note, does not recurse. + **/ +void +clutter_group_show_all (ClutterGroup *self) +{ + g_return_if_fail (CLUTTER_IS_GROUP (self)); + + clutter_element_show(CLUTTER_ELEMENT(self)); + + g_list_foreach (self->priv->children, + (GFunc)clutter_element_show, + NULL); +} + +/** + * clutter_group_hide_all: + * @self: A #ClutterGroup + * + * Hide all child elements of the group. Note, does not recurse. + **/ +void +clutter_group_hide_all (ClutterGroup *self) +{ + g_return_if_fail (CLUTTER_IS_GROUP (self)); + + clutter_element_hide(CLUTTER_ELEMENT(self)); + + g_list_foreach (self->priv->children, + (GFunc)clutter_element_hide, + NULL); +} + +/** + * clutter_group_add: + * @self: A #ClutterGroup + * @element: A #ClutterElement + * + * Add a new child #ClutterElement to the #ClutterGroup. + **/ +void +clutter_group_add (ClutterGroup *self, ClutterElement *element) +{ + g_return_if_fail (CLUTTER_IS_GROUP (self)); + g_return_if_fail (CLUTTER_IS_ELEMENT (element)); + + self->priv->children = g_list_append (self->priv->children, element); + /* below refs */ + clutter_element_set_parent (element, CLUTTER_ELEMENT(self)); + + /* FIXME: Force Sort any Z ordering, or set to 0 ? */ + if (clutter_element_get_depth (element) != 0) + clutter_element_set_depth (element, clutter_element_get_depth (element)); +} + +/** + * clutter_group_add_manyv: + * @self: a #ClutterGroup + * @first_element: the #ClutterElement element to add to the group + * @args: the elements to be added + * + * Similar to clutter_group_add_many() but using a va_list. Use this + * function inside bindings. + */ +void +clutter_group_add_many_valist (ClutterGroup *group, + ClutterElement *first_element, + va_list args) +{ + ClutterElement *element; + + g_return_if_fail (CLUTTER_IS_GROUP (group)); + g_return_if_fail (CLUTTER_IS_ELEMENT (first_element)); + + element = first_element; + while (element) + { + clutter_group_add (group, element); + element = va_arg (args, ClutterElement *); + } +} + +/** + * clutter_group_add_many: + * @self: A #ClutterGroup + * @first_element: the #ClutterElement element to add to the group + * @Varargs: additional elements to add to the group + * + * Adds a NULL-terminated list of elements to a group. This function is + * equivalent to calling clutter_group_add() for each member of the list. + */ +void +clutter_group_add_many (ClutterGroup *self, + ClutterElement *first_element, + ...) +{ + va_list args; + + va_start (args, first_element); + clutter_group_add_many_valist (self, first_element, args); + va_end (args); +} + +/** + * clutter_group_remove + * @self: A #ClutterGroup + * @element: A #ClutterElement + * + * Remove a child #ClutterElement from the #ClutterGroup. + **/ +void +clutter_group_remove (ClutterGroup *self, ClutterElement *element) +{ + g_return_if_fail (CLUTTER_IS_GROUP (self)); + g_return_if_fail (CLUTTER_IS_ELEMENT (element)); + + /* FIXME: Check we actually are a child ? */ + self->priv->children = g_list_remove (self->priv->children, element); + clutter_element_set_parent (element, NULL); +} + +/** + * clutter_group_remove_all: + * @self: A #ClutterGroup + * + * Remove all child #ClutterElement from the #ClutterGroup. + **/ +void +clutter_group_remove_all (ClutterGroup *self) +{ + GList *child_item; + + g_return_if_fail (CLUTTER_IS_GROUP (self)); + + child_item = self->priv->children; + + if (child_item) + { + do + { + clutter_group_remove (self, CLUTTER_ELEMENT(child_item->data)); + } + while ((child_item = g_list_next(child_item)) != NULL); + } +} + +/** + * clutter_group_find_child_by_id: + * @self: A #ClutterGroup + * @id: A unique #Clutterelement ID + * + * Finds a child element of a group by its unique ID. Search recurses + * into any child groups. + **/ +ClutterElement* +clutter_group_find_child_by_id (ClutterGroup *self, guint id) +{ + ClutterElement *element = NULL, *inner_element; + GList *child_item; + + g_return_val_if_fail (CLUTTER_IS_GROUP (self), NULL); + + if (clutter_element_get_id (CLUTTER_ELEMENT(self)) == id) + return CLUTTER_ELEMENT(self); + + child_item = self->priv->children; + + if (child_item) + { + do + { + inner_element = (ClutterElement*)child_item->data; + + if (clutter_element_get_id (inner_element) == id) + return inner_element; + + if (CLUTTER_IS_GROUP(inner_element)) + { + element = + clutter_group_find_child_by_id (CLUTTER_GROUP(inner_element), + id); + if (element) + return element; + } + + } + while ((child_item = g_list_next(child_item)) != NULL); + } + + return element; +} + +void +clutter_group_raise (ClutterGroup *self, + ClutterElement *element, + ClutterElement *sibling) +{ + ClutterGroupPrivate *priv; + gint pos; + + g_return_if_fail (element != sibling); + + priv = self->priv; + + pos = g_list_index (priv->children, element) + 1; + + priv->children = g_list_remove (priv->children, element); + + if (sibling == NULL) + priv->children = g_list_append (priv->children, element); + else + priv->children = g_list_insert (priv->children, element, pos); +} + +void +clutter_group_lower (ClutterGroup *self, + ClutterElement *element, + ClutterElement *sibling) +{ + ClutterGroupPrivate *priv; + gint pos; + + g_return_if_fail (element != sibling); + + priv = self->priv; + + pos = g_list_index (priv->children, element) - 1; + + priv->children = g_list_remove (priv->children, element); + + if (sibling == NULL) + priv->children = g_list_prepend (priv->children, element); + else + priv->children = g_list_insert (priv->children, element, pos); +} diff --git a/clutter/clutter-group.h b/clutter/clutter-group.h new file mode 100644 index 000000000..25dd7d632 --- /dev/null +++ b/clutter/clutter-group.h @@ -0,0 +1,130 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, 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 +#include + +G_BEGIN_DECLS + +#define CLUTTER_TYPE_GROUP clutter_group_get_type() + +#define CLUTTER_GROUP(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + CLUTTER_TYPE_GROUP, ClutterGroup)) + +#define CLUTTER_GROUP_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + CLUTTER_TYPE_GROUP, ClutterGroupClass)) + +#define CLUTTER_IS_GROUP(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + CLUTTER_TYPE_GROUP)) + +#define CLUTTER_IS_GROUP_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + CLUTTER_TYPE_GROUP)) + +#define CLUTTER_GROUP_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + CLUTTER_TYPE_GROUP, ClutterGroupClass)) + +typedef struct _ClutterGroupPrivate ClutterGroupPrivate; +typedef struct _ClutterGroup ClutterGroup; +typedef struct _ClutterGroupClass ClutterGroupClass; + +struct _ClutterGroup +{ + ClutterElement parent; + + /*< private >*/ + ClutterGroupPrivate *priv; +}; + +struct _ClutterGroupClass +{ + /*< private >*/ + ClutterElementClass parent_class; + + void (*_clutter_group_1) (void); + void (*_clutter_group_2) (void); + void (*_clutter_group_3) (void); + void (*_clutter_group_4) (void); + void (*_clutter_group_5) (void); + void (*_clutter_group_6) (void); +}; + +GType clutter_group_get_type (void); + +ClutterGroup *clutter_group_new (void); + +GList* +clutter_group_get_children (ClutterGroup *self); + +void +clutter_group_foreach (ClutterGroup *self, + ClutterCallback callback, + gpointer user_data); + +void +clutter_group_add (ClutterGroup *group, ClutterElement *element); + +void +clutter_group_add_many_valist (ClutterGroup *group, + ClutterElement *first_element, + va_list args); + +void +clutter_group_add_many (ClutterGroup *group, + ClutterElement *first_element, + ...) G_GNUC_NULL_TERMINATED; + +void +clutter_group_remove (ClutterGroup *group, ClutterElement *element); + +void +clutter_group_show_all (ClutterGroup *self); + +void +clutter_group_hide_all (ClutterGroup *self); + +ClutterElement* +clutter_group_find_child_by_id (ClutterGroup *self, guint id); + +void +clutter_group_raise (ClutterGroup *self, + ClutterElement *element, + ClutterElement *sibling); + +void +clutter_group_lower (ClutterGroup *self, + ClutterElement *element, + ClutterElement *sibling); + +G_END_DECLS + +#endif diff --git a/clutter/clutter-keysyms.h b/clutter/clutter-keysyms.h new file mode 100644 index 000000000..b5b0d9d3a --- /dev/null +++ b/clutter/clutter-keysyms.h @@ -0,0 +1,1374 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __CLUTTER_KEYSYMS_H__ +#define __CLUTTER_KEYSYMS_H__ + +/* This file based on GDK's gdkkeysyms.h which in turn + * I think is from xlibs keysymdef.h +*/ + +#define CLUTTER_VoidSymbol 0xFFFFFF +#define CLUTTER_BackSpace 0xFF08 +#define CLUTTER_Tab 0xFF09 +#define CLUTTER_Linefeed 0xFF0A +#define CLUTTER_Clear 0xFF0B +#define CLUTTER_Return 0xFF0D +#define CLUTTER_Pause 0xFF13 +#define CLUTTER_Scroll_Lock 0xFF14 +#define CLUTTER_Sys_Req 0xFF15 +#define CLUTTER_Escape 0xFF1B +#define CLUTTER_Delete 0xFFFF +#define CLUTTER_Multi_key 0xFF20 +#define CLUTTER_Codeinput 0xFF37 +#define CLUTTER_SingleCandidate 0xFF3C +#define CLUTTER_MultipleCandidate 0xFF3D +#define CLUTTER_PreviousCandidate 0xFF3E +#define CLUTTER_Kanji 0xFF21 +#define CLUTTER_Muhenkan 0xFF22 +#define CLUTTER_Henkan_Mode 0xFF23 +#define CLUTTER_Henkan 0xFF23 +#define CLUTTER_Romaji 0xFF24 +#define CLUTTER_Hiragana 0xFF25 +#define CLUTTER_Katakana 0xFF26 +#define CLUTTER_Hiragana_Katakana 0xFF27 +#define CLUTTER_Zenkaku 0xFF28 +#define CLUTTER_Hankaku 0xFF29 +#define CLUTTER_Zenkaku_Hankaku 0xFF2A +#define CLUTTER_Touroku 0xFF2B +#define CLUTTER_Massyo 0xFF2C +#define CLUTTER_Kana_Lock 0xFF2D +#define CLUTTER_Kana_Shift 0xFF2E +#define CLUTTER_Eisu_Shift 0xFF2F +#define CLUTTER_Eisu_toggle 0xFF30 +#define CLUTTER_Kanji_Bangou 0xFF37 +#define CLUTTER_Zen_Koho 0xFF3D +#define CLUTTER_Mae_Koho 0xFF3E +#define CLUTTER_Home 0xFF50 +#define CLUTTER_Left 0xFF51 +#define CLUTTER_Up 0xFF52 +#define CLUTTER_Right 0xFF53 +#define CLUTTER_Down 0xFF54 +#define CLUTTER_Prior 0xFF55 +#define CLUTTER_Page_Up 0xFF55 +#define CLUTTER_Next 0xFF56 +#define CLUTTER_Page_Down 0xFF56 +#define CLUTTER_End 0xFF57 +#define CLUTTER_Begin 0xFF58 +#define CLUTTER_Select 0xFF60 +#define CLUTTER_Print 0xFF61 +#define CLUTTER_Execute 0xFF62 +#define CLUTTER_Insert 0xFF63 +#define CLUTTER_Undo 0xFF65 +#define CLUTTER_Redo 0xFF66 +#define CLUTTER_Menu 0xFF67 +#define CLUTTER_Find 0xFF68 +#define CLUTTER_Cancel 0xFF69 +#define CLUTTER_Help 0xFF6A +#define CLUTTER_Break 0xFF6B +#define CLUTTER_Mode_switch 0xFF7E +#define CLUTTER_script_switch 0xFF7E +#define CLUTTER_Num_Lock 0xFF7F +#define CLUTTER_KP_Space 0xFF80 +#define CLUTTER_KP_Tab 0xFF89 +#define CLUTTER_KP_Enter 0xFF8D +#define CLUTTER_KP_F1 0xFF91 +#define CLUTTER_KP_F2 0xFF92 +#define CLUTTER_KP_F3 0xFF93 +#define CLUTTER_KP_F4 0xFF94 +#define CLUTTER_KP_Home 0xFF95 +#define CLUTTER_KP_Left 0xFF96 +#define CLUTTER_KP_Up 0xFF97 +#define CLUTTER_KP_Right 0xFF98 +#define CLUTTER_KP_Down 0xFF99 +#define CLUTTER_KP_Prior 0xFF9A +#define CLUTTER_KP_Page_Up 0xFF9A +#define CLUTTER_KP_Next 0xFF9B +#define CLUTTER_KP_Page_Down 0xFF9B +#define CLUTTER_KP_End 0xFF9C +#define CLUTTER_KP_Begin 0xFF9D +#define CLUTTER_KP_Insert 0xFF9E +#define CLUTTER_KP_Delete 0xFF9F +#define CLUTTER_KP_Equal 0xFFBD +#define CLUTTER_KP_Multiply 0xFFAA +#define CLUTTER_KP_Add 0xFFAB +#define CLUTTER_KP_Separator 0xFFAC +#define CLUTTER_KP_Subtract 0xFFAD +#define CLUTTER_KP_Decimal 0xFFAE +#define CLUTTER_KP_Divide 0xFFAF +#define CLUTTER_KP_0 0xFFB0 +#define CLUTTER_KP_1 0xFFB1 +#define CLUTTER_KP_2 0xFFB2 +#define CLUTTER_KP_3 0xFFB3 +#define CLUTTER_KP_4 0xFFB4 +#define CLUTTER_KP_5 0xFFB5 +#define CLUTTER_KP_6 0xFFB6 +#define CLUTTER_KP_7 0xFFB7 +#define CLUTTER_KP_8 0xFFB8 +#define CLUTTER_KP_9 0xFFB9 +#define CLUTTER_F1 0xFFBE +#define CLUTTER_F2 0xFFBF +#define CLUTTER_F3 0xFFC0 +#define CLUTTER_F4 0xFFC1 +#define CLUTTER_F5 0xFFC2 +#define CLUTTER_F6 0xFFC3 +#define CLUTTER_F7 0xFFC4 +#define CLUTTER_F8 0xFFC5 +#define CLUTTER_F9 0xFFC6 +#define CLUTTER_F10 0xFFC7 +#define CLUTTER_F11 0xFFC8 +#define CLUTTER_L1 0xFFC8 +#define CLUTTER_F12 0xFFC9 +#define CLUTTER_L2 0xFFC9 +#define CLUTTER_F13 0xFFCA +#define CLUTTER_L3 0xFFCA +#define CLUTTER_F14 0xFFCB +#define CLUTTER_L4 0xFFCB +#define CLUTTER_F15 0xFFCC +#define CLUTTER_L5 0xFFCC +#define CLUTTER_F16 0xFFCD +#define CLUTTER_L6 0xFFCD +#define CLUTTER_F17 0xFFCE +#define CLUTTER_L7 0xFFCE +#define CLUTTER_F18 0xFFCF +#define CLUTTER_L8 0xFFCF +#define CLUTTER_F19 0xFFD0 +#define CLUTTER_L9 0xFFD0 +#define CLUTTER_F20 0xFFD1 +#define CLUTTER_L10 0xFFD1 +#define CLUTTER_F21 0xFFD2 +#define CLUTTER_R1 0xFFD2 +#define CLUTTER_F22 0xFFD3 +#define CLUTTER_R2 0xFFD3 +#define CLUTTER_F23 0xFFD4 +#define CLUTTER_R3 0xFFD4 +#define CLUTTER_F24 0xFFD5 +#define CLUTTER_R4 0xFFD5 +#define CLUTTER_F25 0xFFD6 +#define CLUTTER_R5 0xFFD6 +#define CLUTTER_F26 0xFFD7 +#define CLUTTER_R6 0xFFD7 +#define CLUTTER_F27 0xFFD8 +#define CLUTTER_R7 0xFFD8 +#define CLUTTER_F28 0xFFD9 +#define CLUTTER_R8 0xFFD9 +#define CLUTTER_F29 0xFFDA +#define CLUTTER_R9 0xFFDA +#define CLUTTER_F30 0xFFDB +#define CLUTTER_R10 0xFFDB +#define CLUTTER_F31 0xFFDC +#define CLUTTER_R11 0xFFDC +#define CLUTTER_F32 0xFFDD +#define CLUTTER_R12 0xFFDD +#define CLUTTER_F33 0xFFDE +#define CLUTTER_R13 0xFFDE +#define CLUTTER_F34 0xFFDF +#define CLUTTER_R14 0xFFDF +#define CLUTTER_F35 0xFFE0 +#define CLUTTER_R15 0xFFE0 +#define CLUTTER_Shift_L 0xFFE1 +#define CLUTTER_Shift_R 0xFFE2 +#define CLUTTER_Control_L 0xFFE3 +#define CLUTTER_Control_R 0xFFE4 +#define CLUTTER_Caps_Lock 0xFFE5 +#define CLUTTER_Shift_Lock 0xFFE6 +#define CLUTTER_Meta_L 0xFFE7 +#define CLUTTER_Meta_R 0xFFE8 +#define CLUTTER_Alt_L 0xFFE9 +#define CLUTTER_Alt_R 0xFFEA +#define CLUTTER_Super_L 0xFFEB +#define CLUTTER_Super_R 0xFFEC +#define CLUTTER_Hyper_L 0xFFED +#define CLUTTER_Hyper_R 0xFFEE +#define CLUTTER_ISO_Lock 0xFE01 +#define CLUTTER_ISO_Level2_Latch 0xFE02 +#define CLUTTER_ISO_Level3_Shift 0xFE03 +#define CLUTTER_ISO_Level3_Latch 0xFE04 +#define CLUTTER_ISO_Level3_Lock 0xFE05 +#define CLUTTER_ISO_Group_Shift 0xFF7E +#define CLUTTER_ISO_Group_Latch 0xFE06 +#define CLUTTER_ISO_Group_Lock 0xFE07 +#define CLUTTER_ISO_Next_Group 0xFE08 +#define CLUTTER_ISO_Next_Group_Lock 0xFE09 +#define CLUTTER_ISO_Prev_Group 0xFE0A +#define CLUTTER_ISO_Prev_Group_Lock 0xFE0B +#define CLUTTER_ISO_First_Group 0xFE0C +#define CLUTTER_ISO_First_Group_Lock 0xFE0D +#define CLUTTER_ISO_Last_Group 0xFE0E +#define CLUTTER_ISO_Last_Group_Lock 0xFE0F +#define CLUTTER_ISO_Left_Tab 0xFE20 +#define CLUTTER_ISO_Move_Line_Up 0xFE21 +#define CLUTTER_ISO_Move_Line_Down 0xFE22 +#define CLUTTER_ISO_Partial_Line_Up 0xFE23 +#define CLUTTER_ISO_Partial_Line_Down 0xFE24 +#define CLUTTER_ISO_Partial_Space_Left 0xFE25 +#define CLUTTER_ISO_Partial_Space_Right 0xFE26 +#define CLUTTER_ISO_Set_Margin_Left 0xFE27 +#define CLUTTER_ISO_Set_Margin_Right 0xFE28 +#define CLUTTER_ISO_Release_Margin_Left 0xFE29 +#define CLUTTER_ISO_Release_Margin_Right 0xFE2A +#define CLUTTER_ISO_Release_Both_Margins 0xFE2B +#define CLUTTER_ISO_Fast_Cursor_Left 0xFE2C +#define CLUTTER_ISO_Fast_Cursor_Right 0xFE2D +#define CLUTTER_ISO_Fast_Cursor_Up 0xFE2E +#define CLUTTER_ISO_Fast_Cursor_Down 0xFE2F +#define CLUTTER_ISO_Continuous_Underline 0xFE30 +#define CLUTTER_ISO_Discontinuous_Underline 0xFE31 +#define CLUTTER_ISO_Emphasize 0xFE32 +#define CLUTTER_ISO_Center_Object 0xFE33 +#define CLUTTER_ISO_Enter 0xFE34 +#define CLUTTER_dead_grave 0xFE50 +#define CLUTTER_dead_acute 0xFE51 +#define CLUTTER_dead_circumflex 0xFE52 +#define CLUTTER_dead_tilde 0xFE53 +#define CLUTTER_dead_macron 0xFE54 +#define CLUTTER_dead_breve 0xFE55 +#define CLUTTER_dead_abovedot 0xFE56 +#define CLUTTER_dead_diaeresis 0xFE57 +#define CLUTTER_dead_abovering 0xFE58 +#define CLUTTER_dead_doubleacute 0xFE59 +#define CLUTTER_dead_caron 0xFE5A +#define CLUTTER_dead_cedilla 0xFE5B +#define CLUTTER_dead_ogonek 0xFE5C +#define CLUTTER_dead_iota 0xFE5D +#define CLUTTER_dead_voiced_sound 0xFE5E +#define CLUTTER_dead_semivoiced_sound 0xFE5F +#define CLUTTER_dead_belowdot 0xFE60 +#define CLUTTER_dead_hook 0xFE61 +#define CLUTTER_dead_horn 0xFE62 +#define CLUTTER_First_Virtual_Screen 0xFED0 +#define CLUTTER_Prev_Virtual_Screen 0xFED1 +#define CLUTTER_Next_Virtual_Screen 0xFED2 +#define CLUTTER_Last_Virtual_Screen 0xFED4 +#define CLUTTER_Terminate_Server 0xFED5 +#define CLUTTER_AccessX_Enable 0xFE70 +#define CLUTTER_AccessX_Feedback_Enable 0xFE71 +#define CLUTTER_RepeatKeys_Enable 0xFE72 +#define CLUTTER_SlowKeys_Enable 0xFE73 +#define CLUTTER_BounceKeys_Enable 0xFE74 +#define CLUTTER_StickyKeys_Enable 0xFE75 +#define CLUTTER_MouseKeys_Enable 0xFE76 +#define CLUTTER_MouseKeys_Accel_Enable 0xFE77 +#define CLUTTER_Overlay1_Enable 0xFE78 +#define CLUTTER_Overlay2_Enable 0xFE79 +#define CLUTTER_AudibleBell_Enable 0xFE7A +#define CLUTTER_Pointer_Left 0xFEE0 +#define CLUTTER_Pointer_Right 0xFEE1 +#define CLUTTER_Pointer_Up 0xFEE2 +#define CLUTTER_Pointer_Down 0xFEE3 +#define CLUTTER_Pointer_UpLeft 0xFEE4 +#define CLUTTER_Pointer_UpRight 0xFEE5 +#define CLUTTER_Pointer_DownLeft 0xFEE6 +#define CLUTTER_Pointer_DownRight 0xFEE7 +#define CLUTTER_Pointer_Button_Dflt 0xFEE8 +#define CLUTTER_Pointer_Button1 0xFEE9 +#define CLUTTER_Pointer_Button2 0xFEEA +#define CLUTTER_Pointer_Button3 0xFEEB +#define CLUTTER_Pointer_Button4 0xFEEC +#define CLUTTER_Pointer_Button5 0xFEED +#define CLUTTER_Pointer_DblClick_Dflt 0xFEEE +#define CLUTTER_Pointer_DblClick1 0xFEEF +#define CLUTTER_Pointer_DblClick2 0xFEF0 +#define CLUTTER_Pointer_DblClick3 0xFEF1 +#define CLUTTER_Pointer_DblClick4 0xFEF2 +#define CLUTTER_Pointer_DblClick5 0xFEF3 +#define CLUTTER_Pointer_Drag_Dflt 0xFEF4 +#define CLUTTER_Pointer_Drag1 0xFEF5 +#define CLUTTER_Pointer_Drag2 0xFEF6 +#define CLUTTER_Pointer_Drag3 0xFEF7 +#define CLUTTER_Pointer_Drag4 0xFEF8 +#define CLUTTER_Pointer_Drag5 0xFEFD +#define CLUTTER_Pointer_EnableKeys 0xFEF9 +#define CLUTTER_Pointer_Accelerate 0xFEFA +#define CLUTTER_Pointer_DfltBtnNext 0xFEFB +#define CLUTTER_Pointer_DfltBtnPrev 0xFEFC +#define CLUTTER_3270_Duplicate 0xFD01 +#define CLUTTER_3270_FieldMark 0xFD02 +#define CLUTTER_3270_Right2 0xFD03 +#define CLUTTER_3270_Left2 0xFD04 +#define CLUTTER_3270_BackTab 0xFD05 +#define CLUTTER_3270_EraseEOF 0xFD06 +#define CLUTTER_3270_EraseInput 0xFD07 +#define CLUTTER_3270_Reset 0xFD08 +#define CLUTTER_3270_Quit 0xFD09 +#define CLUTTER_3270_PA1 0xFD0A +#define CLUTTER_3270_PA2 0xFD0B +#define CLUTTER_3270_PA3 0xFD0C +#define CLUTTER_3270_Test 0xFD0D +#define CLUTTER_3270_Attn 0xFD0E +#define CLUTTER_3270_CursorBlink 0xFD0F +#define CLUTTER_3270_AltCursor 0xFD10 +#define CLUTTER_3270_KeyClick 0xFD11 +#define CLUTTER_3270_Jump 0xFD12 +#define CLUTTER_3270_Ident 0xFD13 +#define CLUTTER_3270_Rule 0xFD14 +#define CLUTTER_3270_Copy 0xFD15 +#define CLUTTER_3270_Play 0xFD16 +#define CLUTTER_3270_Setup 0xFD17 +#define CLUTTER_3270_Record 0xFD18 +#define CLUTTER_3270_ChangeScreen 0xFD19 +#define CLUTTER_3270_DeleteWord 0xFD1A +#define CLUTTER_3270_ExSelect 0xFD1B +#define CLUTTER_3270_CursorSelect 0xFD1C +#define CLUTTER_3270_PrintScreen 0xFD1D +#define CLUTTER_3270_Enter 0xFD1E +#define CLUTTER_space 0x020 +#define CLUTTER_exclam 0x021 +#define CLUTTER_quotedbl 0x022 +#define CLUTTER_numbersign 0x023 +#define CLUTTER_dollar 0x024 +#define CLUTTER_percent 0x025 +#define CLUTTER_ampersand 0x026 +#define CLUTTER_apostrophe 0x027 +#define CLUTTER_quoteright 0x027 +#define CLUTTER_parenleft 0x028 +#define CLUTTER_parenright 0x029 +#define CLUTTER_asterisk 0x02a +#define CLUTTER_plus 0x02b +#define CLUTTER_comma 0x02c +#define CLUTTER_minus 0x02d +#define CLUTTER_period 0x02e +#define CLUTTER_slash 0x02f +#define CLUTTER_0 0x030 +#define CLUTTER_1 0x031 +#define CLUTTER_2 0x032 +#define CLUTTER_3 0x033 +#define CLUTTER_4 0x034 +#define CLUTTER_5 0x035 +#define CLUTTER_6 0x036 +#define CLUTTER_7 0x037 +#define CLUTTER_8 0x038 +#define CLUTTER_9 0x039 +#define CLUTTER_colon 0x03a +#define CLUTTER_semicolon 0x03b +#define CLUTTER_less 0x03c +#define CLUTTER_equal 0x03d +#define CLUTTER_greater 0x03e +#define CLUTTER_question 0x03f +#define CLUTTER_at 0x040 +#define CLUTTER_A 0x041 +#define CLUTTER_B 0x042 +#define CLUTTER_C 0x043 +#define CLUTTER_D 0x044 +#define CLUTTER_E 0x045 +#define CLUTTER_F 0x046 +#define CLUTTER_G 0x047 +#define CLUTTER_H 0x048 +#define CLUTTER_I 0x049 +#define CLUTTER_J 0x04a +#define CLUTTER_K 0x04b +#define CLUTTER_L 0x04c +#define CLUTTER_M 0x04d +#define CLUTTER_N 0x04e +#define CLUTTER_O 0x04f +#define CLUTTER_P 0x050 +#define CLUTTER_Q 0x051 +#define CLUTTER_R 0x052 +#define CLUTTER_S 0x053 +#define CLUTTER_T 0x054 +#define CLUTTER_U 0x055 +#define CLUTTER_V 0x056 +#define CLUTTER_W 0x057 +#define CLUTTER_X 0x058 +#define CLUTTER_Y 0x059 +#define CLUTTER_Z 0x05a +#define CLUTTER_bracketleft 0x05b +#define CLUTTER_backslash 0x05c +#define CLUTTER_bracketright 0x05d +#define CLUTTER_asciicircum 0x05e +#define CLUTTER_underscore 0x05f +#define CLUTTER_grave 0x060 +#define CLUTTER_quoteleft 0x060 +#define CLUTTER_a 0x061 +#define CLUTTER_b 0x062 +#define CLUTTER_c 0x063 +#define CLUTTER_d 0x064 +#define CLUTTER_e 0x065 +#define CLUTTER_f 0x066 +#define CLUTTER_g 0x067 +#define CLUTTER_h 0x068 +#define CLUTTER_i 0x069 +#define CLUTTER_j 0x06a +#define CLUTTER_k 0x06b +#define CLUTTER_l 0x06c +#define CLUTTER_m 0x06d +#define CLUTTER_n 0x06e +#define CLUTTER_o 0x06f +#define CLUTTER_p 0x070 +#define CLUTTER_q 0x071 +#define CLUTTER_r 0x072 +#define CLUTTER_s 0x073 +#define CLUTTER_t 0x074 +#define CLUTTER_u 0x075 +#define CLUTTER_v 0x076 +#define CLUTTER_w 0x077 +#define CLUTTER_x 0x078 +#define CLUTTER_y 0x079 +#define CLUTTER_z 0x07a +#define CLUTTER_braceleft 0x07b +#define CLUTTER_bar 0x07c +#define CLUTTER_braceright 0x07d +#define CLUTTER_asciitilde 0x07e +#define CLUTTER_nobreakspace 0x0a0 +#define CLUTTER_exclamdown 0x0a1 +#define CLUTTER_cent 0x0a2 +#define CLUTTER_sterling 0x0a3 +#define CLUTTER_currency 0x0a4 +#define CLUTTER_yen 0x0a5 +#define CLUTTER_brokenbar 0x0a6 +#define CLUTTER_section 0x0a7 +#define CLUTTER_diaeresis 0x0a8 +#define CLUTTER_copyright 0x0a9 +#define CLUTTER_ordfeminine 0x0aa +#define CLUTTER_guillemotleft 0x0ab +#define CLUTTER_notsign 0x0ac +#define CLUTTER_hyphen 0x0ad +#define CLUTTER_registered 0x0ae +#define CLUTTER_macron 0x0af +#define CLUTTER_degree 0x0b0 +#define CLUTTER_plusminus 0x0b1 +#define CLUTTER_twosuperior 0x0b2 +#define CLUTTER_threesuperior 0x0b3 +#define CLUTTER_acute 0x0b4 +#define CLUTTER_mu 0x0b5 +#define CLUTTER_paragraph 0x0b6 +#define CLUTTER_periodcentered 0x0b7 +#define CLUTTER_cedilla 0x0b8 +#define CLUTTER_onesuperior 0x0b9 +#define CLUTTER_masculine 0x0ba +#define CLUTTER_guillemotright 0x0bb +#define CLUTTER_onequarter 0x0bc +#define CLUTTER_onehalf 0x0bd +#define CLUTTER_threequarters 0x0be +#define CLUTTER_questiondown 0x0bf +#define CLUTTER_Agrave 0x0c0 +#define CLUTTER_Aacute 0x0c1 +#define CLUTTER_Acircumflex 0x0c2 +#define CLUTTER_Atilde 0x0c3 +#define CLUTTER_Adiaeresis 0x0c4 +#define CLUTTER_Aring 0x0c5 +#define CLUTTER_AE 0x0c6 +#define CLUTTER_Ccedilla 0x0c7 +#define CLUTTER_Egrave 0x0c8 +#define CLUTTER_Eacute 0x0c9 +#define CLUTTER_Ecircumflex 0x0ca +#define CLUTTER_Ediaeresis 0x0cb +#define CLUTTER_Igrave 0x0cc +#define CLUTTER_Iacute 0x0cd +#define CLUTTER_Icircumflex 0x0ce +#define CLUTTER_Idiaeresis 0x0cf +#define CLUTTER_ETH 0x0d0 +#define CLUTTER_Eth 0x0d0 +#define CLUTTER_Ntilde 0x0d1 +#define CLUTTER_Ograve 0x0d2 +#define CLUTTER_Oacute 0x0d3 +#define CLUTTER_Ocircumflex 0x0d4 +#define CLUTTER_Otilde 0x0d5 +#define CLUTTER_Odiaeresis 0x0d6 +#define CLUTTER_multiply 0x0d7 +#define CLUTTER_Ooblique 0x0d8 +#define CLUTTER_Ugrave 0x0d9 +#define CLUTTER_Uacute 0x0da +#define CLUTTER_Ucircumflex 0x0db +#define CLUTTER_Udiaeresis 0x0dc +#define CLUTTER_Yacute 0x0dd +#define CLUTTER_THORN 0x0de +#define CLUTTER_Thorn 0x0de +#define CLUTTER_ssharp 0x0df +#define CLUTTER_agrave 0x0e0 +#define CLUTTER_aacute 0x0e1 +#define CLUTTER_acircumflex 0x0e2 +#define CLUTTER_atilde 0x0e3 +#define CLUTTER_adiaeresis 0x0e4 +#define CLUTTER_aring 0x0e5 +#define CLUTTER_ae 0x0e6 +#define CLUTTER_ccedilla 0x0e7 +#define CLUTTER_egrave 0x0e8 +#define CLUTTER_eacute 0x0e9 +#define CLUTTER_ecircumflex 0x0ea +#define CLUTTER_ediaeresis 0x0eb +#define CLUTTER_igrave 0x0ec +#define CLUTTER_iacute 0x0ed +#define CLUTTER_icircumflex 0x0ee +#define CLUTTER_idiaeresis 0x0ef +#define CLUTTER_eth 0x0f0 +#define CLUTTER_ntilde 0x0f1 +#define CLUTTER_ograve 0x0f2 +#define CLUTTER_oacute 0x0f3 +#define CLUTTER_ocircumflex 0x0f4 +#define CLUTTER_otilde 0x0f5 +#define CLUTTER_odiaeresis 0x0f6 +#define CLUTTER_division 0x0f7 +#define CLUTTER_oslash 0x0f8 +#define CLUTTER_ugrave 0x0f9 +#define CLUTTER_uacute 0x0fa +#define CLUTTER_ucircumflex 0x0fb +#define CLUTTER_udiaeresis 0x0fc +#define CLUTTER_yacute 0x0fd +#define CLUTTER_thorn 0x0fe +#define CLUTTER_ydiaeresis 0x0ff +#define CLUTTER_Aogonek 0x1a1 +#define CLUTTER_breve 0x1a2 +#define CLUTTER_Lstroke 0x1a3 +#define CLUTTER_Lcaron 0x1a5 +#define CLUTTER_Sacute 0x1a6 +#define CLUTTER_Scaron 0x1a9 +#define CLUTTER_Scedilla 0x1aa +#define CLUTTER_Tcaron 0x1ab +#define CLUTTER_Zacute 0x1ac +#define CLUTTER_Zcaron 0x1ae +#define CLUTTER_Zabovedot 0x1af +#define CLUTTER_aogonek 0x1b1 +#define CLUTTER_ogonek 0x1b2 +#define CLUTTER_lstroke 0x1b3 +#define CLUTTER_lcaron 0x1b5 +#define CLUTTER_sacute 0x1b6 +#define CLUTTER_caron 0x1b7 +#define CLUTTER_scaron 0x1b9 +#define CLUTTER_scedilla 0x1ba +#define CLUTTER_tcaron 0x1bb +#define CLUTTER_zacute 0x1bc +#define CLUTTER_doubleacute 0x1bd +#define CLUTTER_zcaron 0x1be +#define CLUTTER_zabovedot 0x1bf +#define CLUTTER_Racute 0x1c0 +#define CLUTTER_Abreve 0x1c3 +#define CLUTTER_Lacute 0x1c5 +#define CLUTTER_Cacute 0x1c6 +#define CLUTTER_Ccaron 0x1c8 +#define CLUTTER_Eogonek 0x1ca +#define CLUTTER_Ecaron 0x1cc +#define CLUTTER_Dcaron 0x1cf +#define CLUTTER_Dstroke 0x1d0 +#define CLUTTER_Nacute 0x1d1 +#define CLUTTER_Ncaron 0x1d2 +#define CLUTTER_Odoubleacute 0x1d5 +#define CLUTTER_Rcaron 0x1d8 +#define CLUTTER_Uring 0x1d9 +#define CLUTTER_Udoubleacute 0x1db +#define CLUTTER_Tcedilla 0x1de +#define CLUTTER_racute 0x1e0 +#define CLUTTER_abreve 0x1e3 +#define CLUTTER_lacute 0x1e5 +#define CLUTTER_cacute 0x1e6 +#define CLUTTER_ccaron 0x1e8 +#define CLUTTER_eogonek 0x1ea +#define CLUTTER_ecaron 0x1ec +#define CLUTTER_dcaron 0x1ef +#define CLUTTER_dstroke 0x1f0 +#define CLUTTER_nacute 0x1f1 +#define CLUTTER_ncaron 0x1f2 +#define CLUTTER_odoubleacute 0x1f5 +#define CLUTTER_udoubleacute 0x1fb +#define CLUTTER_rcaron 0x1f8 +#define CLUTTER_uring 0x1f9 +#define CLUTTER_tcedilla 0x1fe +#define CLUTTER_abovedot 0x1ff +#define CLUTTER_Hstroke 0x2a1 +#define CLUTTER_Hcircumflex 0x2a6 +#define CLUTTER_Iabovedot 0x2a9 +#define CLUTTER_Gbreve 0x2ab +#define CLUTTER_Jcircumflex 0x2ac +#define CLUTTER_hstroke 0x2b1 +#define CLUTTER_hcircumflex 0x2b6 +#define CLUTTER_idotless 0x2b9 +#define CLUTTER_gbreve 0x2bb +#define CLUTTER_jcircumflex 0x2bc +#define CLUTTER_Cabovedot 0x2c5 +#define CLUTTER_Ccircumflex 0x2c6 +#define CLUTTER_Gabovedot 0x2d5 +#define CLUTTER_Gcircumflex 0x2d8 +#define CLUTTER_Ubreve 0x2dd +#define CLUTTER_Scircumflex 0x2de +#define CLUTTER_cabovedot 0x2e5 +#define CLUTTER_ccircumflex 0x2e6 +#define CLUTTER_gabovedot 0x2f5 +#define CLUTTER_gcircumflex 0x2f8 +#define CLUTTER_ubreve 0x2fd +#define CLUTTER_scircumflex 0x2fe +#define CLUTTER_kra 0x3a2 +#define CLUTTER_kappa 0x3a2 +#define CLUTTER_Rcedilla 0x3a3 +#define CLUTTER_Itilde 0x3a5 +#define CLUTTER_Lcedilla 0x3a6 +#define CLUTTER_Emacron 0x3aa +#define CLUTTER_Gcedilla 0x3ab +#define CLUTTER_Tslash 0x3ac +#define CLUTTER_rcedilla 0x3b3 +#define CLUTTER_itilde 0x3b5 +#define CLUTTER_lcedilla 0x3b6 +#define CLUTTER_emacron 0x3ba +#define CLUTTER_gcedilla 0x3bb +#define CLUTTER_tslash 0x3bc +#define CLUTTER_ENG 0x3bd +#define CLUTTER_eng 0x3bf +#define CLUTTER_Amacron 0x3c0 +#define CLUTTER_Iogonek 0x3c7 +#define CLUTTER_Eabovedot 0x3cc +#define CLUTTER_Imacron 0x3cf +#define CLUTTER_Ncedilla 0x3d1 +#define CLUTTER_Omacron 0x3d2 +#define CLUTTER_Kcedilla 0x3d3 +#define CLUTTER_Uogonek 0x3d9 +#define CLUTTER_Utilde 0x3dd +#define CLUTTER_Umacron 0x3de +#define CLUTTER_amacron 0x3e0 +#define CLUTTER_iogonek 0x3e7 +#define CLUTTER_eabovedot 0x3ec +#define CLUTTER_imacron 0x3ef +#define CLUTTER_ncedilla 0x3f1 +#define CLUTTER_omacron 0x3f2 +#define CLUTTER_kcedilla 0x3f3 +#define CLUTTER_uogonek 0x3f9 +#define CLUTTER_utilde 0x3fd +#define CLUTTER_umacron 0x3fe +#define CLUTTER_OE 0x13bc +#define CLUTTER_oe 0x13bd +#define CLUTTER_Ydiaeresis 0x13be +#define CLUTTER_overline 0x47e +#define CLUTTER_kana_fullstop 0x4a1 +#define CLUTTER_kana_openingbracket 0x4a2 +#define CLUTTER_kana_closingbracket 0x4a3 +#define CLUTTER_kana_comma 0x4a4 +#define CLUTTER_kana_conjunctive 0x4a5 +#define CLUTTER_kana_middledot 0x4a5 +#define CLUTTER_kana_WO 0x4a6 +#define CLUTTER_kana_a 0x4a7 +#define CLUTTER_kana_i 0x4a8 +#define CLUTTER_kana_u 0x4a9 +#define CLUTTER_kana_e 0x4aa +#define CLUTTER_kana_o 0x4ab +#define CLUTTER_kana_ya 0x4ac +#define CLUTTER_kana_yu 0x4ad +#define CLUTTER_kana_yo 0x4ae +#define CLUTTER_kana_tsu 0x4af +#define CLUTTER_kana_tu 0x4af +#define CLUTTER_prolongedsound 0x4b0 +#define CLUTTER_kana_A 0x4b1 +#define CLUTTER_kana_I 0x4b2 +#define CLUTTER_kana_U 0x4b3 +#define CLUTTER_kana_E 0x4b4 +#define CLUTTER_kana_O 0x4b5 +#define CLUTTER_kana_KA 0x4b6 +#define CLUTTER_kana_KI 0x4b7 +#define CLUTTER_kana_KU 0x4b8 +#define CLUTTER_kana_KE 0x4b9 +#define CLUTTER_kana_KO 0x4ba +#define CLUTTER_kana_SA 0x4bb +#define CLUTTER_kana_SHI 0x4bc +#define CLUTTER_kana_SU 0x4bd +#define CLUTTER_kana_SE 0x4be +#define CLUTTER_kana_SO 0x4bf +#define CLUTTER_kana_TA 0x4c0 +#define CLUTTER_kana_CHI 0x4c1 +#define CLUTTER_kana_TI 0x4c1 +#define CLUTTER_kana_TSU 0x4c2 +#define CLUTTER_kana_TU 0x4c2 +#define CLUTTER_kana_TE 0x4c3 +#define CLUTTER_kana_TO 0x4c4 +#define CLUTTER_kana_NA 0x4c5 +#define CLUTTER_kana_NI 0x4c6 +#define CLUTTER_kana_NU 0x4c7 +#define CLUTTER_kana_NE 0x4c8 +#define CLUTTER_kana_NO 0x4c9 +#define CLUTTER_kana_HA 0x4ca +#define CLUTTER_kana_HI 0x4cb +#define CLUTTER_kana_FU 0x4cc +#define CLUTTER_kana_HU 0x4cc +#define CLUTTER_kana_HE 0x4cd +#define CLUTTER_kana_HO 0x4ce +#define CLUTTER_kana_MA 0x4cf +#define CLUTTER_kana_MI 0x4d0 +#define CLUTTER_kana_MU 0x4d1 +#define CLUTTER_kana_ME 0x4d2 +#define CLUTTER_kana_MO 0x4d3 +#define CLUTTER_kana_YA 0x4d4 +#define CLUTTER_kana_YU 0x4d5 +#define CLUTTER_kana_YO 0x4d6 +#define CLUTTER_kana_RA 0x4d7 +#define CLUTTER_kana_RI 0x4d8 +#define CLUTTER_kana_RU 0x4d9 +#define CLUTTER_kana_RE 0x4da +#define CLUTTER_kana_RO 0x4db +#define CLUTTER_kana_WA 0x4dc +#define CLUTTER_kana_N 0x4dd +#define CLUTTER_voicedsound 0x4de +#define CLUTTER_semivoicedsound 0x4df +#define CLUTTER_kana_switch 0xFF7E +#define CLUTTER_Arabic_comma 0x5ac +#define CLUTTER_Arabic_semicolon 0x5bb +#define CLUTTER_Arabic_question_mark 0x5bf +#define CLUTTER_Arabic_hamza 0x5c1 +#define CLUTTER_Arabic_maddaonalef 0x5c2 +#define CLUTTER_Arabic_hamzaonalef 0x5c3 +#define CLUTTER_Arabic_hamzaonwaw 0x5c4 +#define CLUTTER_Arabic_hamzaunderalef 0x5c5 +#define CLUTTER_Arabic_hamzaonyeh 0x5c6 +#define CLUTTER_Arabic_alef 0x5c7 +#define CLUTTER_Arabic_beh 0x5c8 +#define CLUTTER_Arabic_tehmarbuta 0x5c9 +#define CLUTTER_Arabic_teh 0x5ca +#define CLUTTER_Arabic_theh 0x5cb +#define CLUTTER_Arabic_jeem 0x5cc +#define CLUTTER_Arabic_hah 0x5cd +#define CLUTTER_Arabic_khah 0x5ce +#define CLUTTER_Arabic_dal 0x5cf +#define CLUTTER_Arabic_thal 0x5d0 +#define CLUTTER_Arabic_ra 0x5d1 +#define CLUTTER_Arabic_zain 0x5d2 +#define CLUTTER_Arabic_seen 0x5d3 +#define CLUTTER_Arabic_sheen 0x5d4 +#define CLUTTER_Arabic_sad 0x5d5 +#define CLUTTER_Arabic_dad 0x5d6 +#define CLUTTER_Arabic_tah 0x5d7 +#define CLUTTER_Arabic_zah 0x5d8 +#define CLUTTER_Arabic_ain 0x5d9 +#define CLUTTER_Arabic_ghain 0x5da +#define CLUTTER_Arabic_tatweel 0x5e0 +#define CLUTTER_Arabic_feh 0x5e1 +#define CLUTTER_Arabic_qaf 0x5e2 +#define CLUTTER_Arabic_kaf 0x5e3 +#define CLUTTER_Arabic_lam 0x5e4 +#define CLUTTER_Arabic_meem 0x5e5 +#define CLUTTER_Arabic_noon 0x5e6 +#define CLUTTER_Arabic_ha 0x5e7 +#define CLUTTER_Arabic_heh 0x5e7 +#define CLUTTER_Arabic_waw 0x5e8 +#define CLUTTER_Arabic_alefmaksura 0x5e9 +#define CLUTTER_Arabic_yeh 0x5ea +#define CLUTTER_Arabic_fathatan 0x5eb +#define CLUTTER_Arabic_dammatan 0x5ec +#define CLUTTER_Arabic_kasratan 0x5ed +#define CLUTTER_Arabic_fatha 0x5ee +#define CLUTTER_Arabic_damma 0x5ef +#define CLUTTER_Arabic_kasra 0x5f0 +#define CLUTTER_Arabic_shadda 0x5f1 +#define CLUTTER_Arabic_sukun 0x5f2 +#define CLUTTER_Arabic_switch 0xFF7E +#define CLUTTER_Serbian_dje 0x6a1 +#define CLUTTER_Macedonia_gje 0x6a2 +#define CLUTTER_Cyrillic_io 0x6a3 +#define CLUTTER_Ukrainian_ie 0x6a4 +#define CLUTTER_Ukranian_je 0x6a4 +#define CLUTTER_Macedonia_dse 0x6a5 +#define CLUTTER_Ukrainian_i 0x6a6 +#define CLUTTER_Ukranian_i 0x6a6 +#define CLUTTER_Ukrainian_yi 0x6a7 +#define CLUTTER_Ukranian_yi 0x6a7 +#define CLUTTER_Cyrillic_je 0x6a8 +#define CLUTTER_Serbian_je 0x6a8 +#define CLUTTER_Cyrillic_lje 0x6a9 +#define CLUTTER_Serbian_lje 0x6a9 +#define CLUTTER_Cyrillic_nje 0x6aa +#define CLUTTER_Serbian_nje 0x6aa +#define CLUTTER_Serbian_tshe 0x6ab +#define CLUTTER_Macedonia_kje 0x6ac +#define CLUTTER_Ukrainian_ghe_with_upturn 0x6ad +#define CLUTTER_Byelorussian_shortu 0x6ae +#define CLUTTER_Cyrillic_dzhe 0x6af +#define CLUTTER_Serbian_dze 0x6af +#define CLUTTER_numerosign 0x6b0 +#define CLUTTER_Serbian_DJE 0x6b1 +#define CLUTTER_Macedonia_GJE 0x6b2 +#define CLUTTER_Cyrillic_IO 0x6b3 +#define CLUTTER_Ukrainian_IE 0x6b4 +#define CLUTTER_Ukranian_JE 0x6b4 +#define CLUTTER_Macedonia_DSE 0x6b5 +#define CLUTTER_Ukrainian_I 0x6b6 +#define CLUTTER_Ukranian_I 0x6b6 +#define CLUTTER_Ukrainian_YI 0x6b7 +#define CLUTTER_Ukranian_YI 0x6b7 +#define CLUTTER_Cyrillic_JE 0x6b8 +#define CLUTTER_Serbian_JE 0x6b8 +#define CLUTTER_Cyrillic_LJE 0x6b9 +#define CLUTTER_Serbian_LJE 0x6b9 +#define CLUTTER_Cyrillic_NJE 0x6ba +#define CLUTTER_Serbian_NJE 0x6ba +#define CLUTTER_Serbian_TSHE 0x6bb +#define CLUTTER_Macedonia_KJE 0x6bc +#define CLUTTER_Ukrainian_GHE_WITH_UPTURN 0x6bd +#define CLUTTER_Byelorussian_SHORTU 0x6be +#define CLUTTER_Cyrillic_DZHE 0x6bf +#define CLUTTER_Serbian_DZE 0x6bf +#define CLUTTER_Cyrillic_yu 0x6c0 +#define CLUTTER_Cyrillic_a 0x6c1 +#define CLUTTER_Cyrillic_be 0x6c2 +#define CLUTTER_Cyrillic_tse 0x6c3 +#define CLUTTER_Cyrillic_de 0x6c4 +#define CLUTTER_Cyrillic_ie 0x6c5 +#define CLUTTER_Cyrillic_ef 0x6c6 +#define CLUTTER_Cyrillic_ghe 0x6c7 +#define CLUTTER_Cyrillic_ha 0x6c8 +#define CLUTTER_Cyrillic_i 0x6c9 +#define CLUTTER_Cyrillic_shorti 0x6ca +#define CLUTTER_Cyrillic_ka 0x6cb +#define CLUTTER_Cyrillic_el 0x6cc +#define CLUTTER_Cyrillic_em 0x6cd +#define CLUTTER_Cyrillic_en 0x6ce +#define CLUTTER_Cyrillic_o 0x6cf +#define CLUTTER_Cyrillic_pe 0x6d0 +#define CLUTTER_Cyrillic_ya 0x6d1 +#define CLUTTER_Cyrillic_er 0x6d2 +#define CLUTTER_Cyrillic_es 0x6d3 +#define CLUTTER_Cyrillic_te 0x6d4 +#define CLUTTER_Cyrillic_u 0x6d5 +#define CLUTTER_Cyrillic_zhe 0x6d6 +#define CLUTTER_Cyrillic_ve 0x6d7 +#define CLUTTER_Cyrillic_softsign 0x6d8 +#define CLUTTER_Cyrillic_yeru 0x6d9 +#define CLUTTER_Cyrillic_ze 0x6da +#define CLUTTER_Cyrillic_sha 0x6db +#define CLUTTER_Cyrillic_e 0x6dc +#define CLUTTER_Cyrillic_shcha 0x6dd +#define CLUTTER_Cyrillic_che 0x6de +#define CLUTTER_Cyrillic_hardsign 0x6df +#define CLUTTER_Cyrillic_YU 0x6e0 +#define CLUTTER_Cyrillic_A 0x6e1 +#define CLUTTER_Cyrillic_BE 0x6e2 +#define CLUTTER_Cyrillic_TSE 0x6e3 +#define CLUTTER_Cyrillic_DE 0x6e4 +#define CLUTTER_Cyrillic_IE 0x6e5 +#define CLUTTER_Cyrillic_EF 0x6e6 +#define CLUTTER_Cyrillic_GHE 0x6e7 +#define CLUTTER_Cyrillic_HA 0x6e8 +#define CLUTTER_Cyrillic_I 0x6e9 +#define CLUTTER_Cyrillic_SHORTI 0x6ea +#define CLUTTER_Cyrillic_KA 0x6eb +#define CLUTTER_Cyrillic_EL 0x6ec +#define CLUTTER_Cyrillic_EM 0x6ed +#define CLUTTER_Cyrillic_EN 0x6ee +#define CLUTTER_Cyrillic_O 0x6ef +#define CLUTTER_Cyrillic_PE 0x6f0 +#define CLUTTER_Cyrillic_YA 0x6f1 +#define CLUTTER_Cyrillic_ER 0x6f2 +#define CLUTTER_Cyrillic_ES 0x6f3 +#define CLUTTER_Cyrillic_TE 0x6f4 +#define CLUTTER_Cyrillic_U 0x6f5 +#define CLUTTER_Cyrillic_ZHE 0x6f6 +#define CLUTTER_Cyrillic_VE 0x6f7 +#define CLUTTER_Cyrillic_SOFTSIGN 0x6f8 +#define CLUTTER_Cyrillic_YERU 0x6f9 +#define CLUTTER_Cyrillic_ZE 0x6fa +#define CLUTTER_Cyrillic_SHA 0x6fb +#define CLUTTER_Cyrillic_E 0x6fc +#define CLUTTER_Cyrillic_SHCHA 0x6fd +#define CLUTTER_Cyrillic_CHE 0x6fe +#define CLUTTER_Cyrillic_HARDSIGN 0x6ff +#define CLUTTER_Greek_ALPHAaccent 0x7a1 +#define CLUTTER_Greek_EPSILONaccent 0x7a2 +#define CLUTTER_Greek_ETAaccent 0x7a3 +#define CLUTTER_Greek_IOTAaccent 0x7a4 +#define CLUTTER_Greek_IOTAdieresis 0x7a5 +#define CLUTTER_Greek_IOTAdiaeresis CLUTTER_Greek_IOTAdieresis +#define CLUTTER_Greek_OMICRONaccent 0x7a7 +#define CLUTTER_Greek_UPSILONaccent 0x7a8 +#define CLUTTER_Greek_UPSILONdieresis 0x7a9 +#define CLUTTER_Greek_OMEGAaccent 0x7ab +#define CLUTTER_Greek_accentdieresis 0x7ae +#define CLUTTER_Greek_horizbar 0x7af +#define CLUTTER_Greek_alphaaccent 0x7b1 +#define CLUTTER_Greek_epsilonaccent 0x7b2 +#define CLUTTER_Greek_etaaccent 0x7b3 +#define CLUTTER_Greek_iotaaccent 0x7b4 +#define CLUTTER_Greek_iotadieresis 0x7b5 +#define CLUTTER_Greek_iotaaccentdieresis 0x7b6 +#define CLUTTER_Greek_omicronaccent 0x7b7 +#define CLUTTER_Greek_upsilonaccent 0x7b8 +#define CLUTTER_Greek_upsilondieresis 0x7b9 +#define CLUTTER_Greek_upsilonaccentdieresis 0x7ba +#define CLUTTER_Greek_omegaaccent 0x7bb +#define CLUTTER_Greek_ALPHA 0x7c1 +#define CLUTTER_Greek_BETA 0x7c2 +#define CLUTTER_Greek_GAMMA 0x7c3 +#define CLUTTER_Greek_DELTA 0x7c4 +#define CLUTTER_Greek_EPSILON 0x7c5 +#define CLUTTER_Greek_ZETA 0x7c6 +#define CLUTTER_Greek_ETA 0x7c7 +#define CLUTTER_Greek_THETA 0x7c8 +#define CLUTTER_Greek_IOTA 0x7c9 +#define CLUTTER_Greek_KAPPA 0x7ca +#define CLUTTER_Greek_LAMDA 0x7cb +#define CLUTTER_Greek_LAMBDA 0x7cb +#define CLUTTER_Greek_MU 0x7cc +#define CLUTTER_Greek_NU 0x7cd +#define CLUTTER_Greek_XI 0x7ce +#define CLUTTER_Greek_OMICRON 0x7cf +#define CLUTTER_Greek_PI 0x7d0 +#define CLUTTER_Greek_RHO 0x7d1 +#define CLUTTER_Greek_SIGMA 0x7d2 +#define CLUTTER_Greek_TAU 0x7d4 +#define CLUTTER_Greek_UPSILON 0x7d5 +#define CLUTTER_Greek_PHI 0x7d6 +#define CLUTTER_Greek_CHI 0x7d7 +#define CLUTTER_Greek_PSI 0x7d8 +#define CLUTTER_Greek_OMEGA 0x7d9 +#define CLUTTER_Greek_alpha 0x7e1 +#define CLUTTER_Greek_beta 0x7e2 +#define CLUTTER_Greek_gamma 0x7e3 +#define CLUTTER_Greek_delta 0x7e4 +#define CLUTTER_Greek_epsilon 0x7e5 +#define CLUTTER_Greek_zeta 0x7e6 +#define CLUTTER_Greek_eta 0x7e7 +#define CLUTTER_Greek_theta 0x7e8 +#define CLUTTER_Greek_iota 0x7e9 +#define CLUTTER_Greek_kappa 0x7ea +#define CLUTTER_Greek_lamda 0x7eb +#define CLUTTER_Greek_lambda 0x7eb +#define CLUTTER_Greek_mu 0x7ec +#define CLUTTER_Greek_nu 0x7ed +#define CLUTTER_Greek_xi 0x7ee +#define CLUTTER_Greek_omicron 0x7ef +#define CLUTTER_Greek_pi 0x7f0 +#define CLUTTER_Greek_rho 0x7f1 +#define CLUTTER_Greek_sigma 0x7f2 +#define CLUTTER_Greek_finalsmallsigma 0x7f3 +#define CLUTTER_Greek_tau 0x7f4 +#define CLUTTER_Greek_upsilon 0x7f5 +#define CLUTTER_Greek_phi 0x7f6 +#define CLUTTER_Greek_chi 0x7f7 +#define CLUTTER_Greek_psi 0x7f8 +#define CLUTTER_Greek_omega 0x7f9 +#define CLUTTER_Greek_switch 0xFF7E +#define CLUTTER_leftradical 0x8a1 +#define CLUTTER_topleftradical 0x8a2 +#define CLUTTER_horizconnector 0x8a3 +#define CLUTTER_topintegral 0x8a4 +#define CLUTTER_botintegral 0x8a5 +#define CLUTTER_vertconnector 0x8a6 +#define CLUTTER_topleftsqbracket 0x8a7 +#define CLUTTER_botleftsqbracket 0x8a8 +#define CLUTTER_toprightsqbracket 0x8a9 +#define CLUTTER_botrightsqbracket 0x8aa +#define CLUTTER_topleftparens 0x8ab +#define CLUTTER_botleftparens 0x8ac +#define CLUTTER_toprightparens 0x8ad +#define CLUTTER_botrightparens 0x8ae +#define CLUTTER_leftmiddlecurlybrace 0x8af +#define CLUTTER_rightmiddlecurlybrace 0x8b0 +#define CLUTTER_topleftsummation 0x8b1 +#define CLUTTER_botleftsummation 0x8b2 +#define CLUTTER_topvertsummationconnector 0x8b3 +#define CLUTTER_botvertsummationconnector 0x8b4 +#define CLUTTER_toprightsummation 0x8b5 +#define CLUTTER_botrightsummation 0x8b6 +#define CLUTTER_rightmiddlesummation 0x8b7 +#define CLUTTER_lessthanequal 0x8bc +#define CLUTTER_notequal 0x8bd +#define CLUTTER_greaterthanequal 0x8be +#define CLUTTER_integral 0x8bf +#define CLUTTER_therefore 0x8c0 +#define CLUTTER_variation 0x8c1 +#define CLUTTER_infinity 0x8c2 +#define CLUTTER_nabla 0x8c5 +#define CLUTTER_approximate 0x8c8 +#define CLUTTER_similarequal 0x8c9 +#define CLUTTER_ifonlyif 0x8cd +#define CLUTTER_implies 0x8ce +#define CLUTTER_identical 0x8cf +#define CLUTTER_radical 0x8d6 +#define CLUTTER_includedin 0x8da +#define CLUTTER_includes 0x8db +#define CLUTTER_intersection 0x8dc +#define CLUTTER_union 0x8dd +#define CLUTTER_logicaland 0x8de +#define CLUTTER_logicalor 0x8df +#define CLUTTER_partialderivative 0x8ef +#define CLUTTER_function 0x8f6 +#define CLUTTER_leftarrow 0x8fb +#define CLUTTER_uparrow 0x8fc +#define CLUTTER_rightarrow 0x8fd +#define CLUTTER_downarrow 0x8fe +#define CLUTTER_blank 0x9df +#define CLUTTER_soliddiamond 0x9e0 +#define CLUTTER_checkerboard 0x9e1 +#define CLUTTER_ht 0x9e2 +#define CLUTTER_ff 0x9e3 +#define CLUTTER_cr 0x9e4 +#define CLUTTER_lf 0x9e5 +#define CLUTTER_nl 0x9e8 +#define CLUTTER_vt 0x9e9 +#define CLUTTER_lowrightcorner 0x9ea +#define CLUTTER_uprightcorner 0x9eb +#define CLUTTER_upleftcorner 0x9ec +#define CLUTTER_lowleftcorner 0x9ed +#define CLUTTER_crossinglines 0x9ee +#define CLUTTER_horizlinescan1 0x9ef +#define CLUTTER_horizlinescan3 0x9f0 +#define CLUTTER_horizlinescan5 0x9f1 +#define CLUTTER_horizlinescan7 0x9f2 +#define CLUTTER_horizlinescan9 0x9f3 +#define CLUTTER_leftt 0x9f4 +#define CLUTTER_rightt 0x9f5 +#define CLUTTER_bott 0x9f6 +#define CLUTTER_topt 0x9f7 +#define CLUTTER_vertbar 0x9f8 +#define CLUTTER_emspace 0xaa1 +#define CLUTTER_enspace 0xaa2 +#define CLUTTER_em3space 0xaa3 +#define CLUTTER_em4space 0xaa4 +#define CLUTTER_digitspace 0xaa5 +#define CLUTTER_punctspace 0xaa6 +#define CLUTTER_thinspace 0xaa7 +#define CLUTTER_hairspace 0xaa8 +#define CLUTTER_emdash 0xaa9 +#define CLUTTER_endash 0xaaa +#define CLUTTER_signifblank 0xaac +#define CLUTTER_ellipsis 0xaae +#define CLUTTER_doubbaselinedot 0xaaf +#define CLUTTER_onethird 0xab0 +#define CLUTTER_twothirds 0xab1 +#define CLUTTER_onefifth 0xab2 +#define CLUTTER_twofifths 0xab3 +#define CLUTTER_threefifths 0xab4 +#define CLUTTER_fourfifths 0xab5 +#define CLUTTER_onesixth 0xab6 +#define CLUTTER_fivesixths 0xab7 +#define CLUTTER_careof 0xab8 +#define CLUTTER_figdash 0xabb +#define CLUTTER_leftanglebracket 0xabc +#define CLUTTER_decimalpoint 0xabd +#define CLUTTER_rightanglebracket 0xabe +#define CLUTTER_marker 0xabf +#define CLUTTER_oneeighth 0xac3 +#define CLUTTER_threeeighths 0xac4 +#define CLUTTER_fiveeighths 0xac5 +#define CLUTTER_seveneighths 0xac6 +#define CLUTTER_trademark 0xac9 +#define CLUTTER_signaturemark 0xaca +#define CLUTTER_trademarkincircle 0xacb +#define CLUTTER_leftopentriangle 0xacc +#define CLUTTER_rightopentriangle 0xacd +#define CLUTTER_emopencircle 0xace +#define CLUTTER_emopenrectangle 0xacf +#define CLUTTER_leftsinglequotemark 0xad0 +#define CLUTTER_rightsinglequotemark 0xad1 +#define CLUTTER_leftdoublequotemark 0xad2 +#define CLUTTER_rightdoublequotemark 0xad3 +#define CLUTTER_prescription 0xad4 +#define CLUTTER_minutes 0xad6 +#define CLUTTER_seconds 0xad7 +#define CLUTTER_latincross 0xad9 +#define CLUTTER_hexagram 0xada +#define CLUTTER_filledrectbullet 0xadb +#define CLUTTER_filledlefttribullet 0xadc +#define CLUTTER_filledrighttribullet 0xadd +#define CLUTTER_emfilledcircle 0xade +#define CLUTTER_emfilledrect 0xadf +#define CLUTTER_enopencircbullet 0xae0 +#define CLUTTER_enopensquarebullet 0xae1 +#define CLUTTER_openrectbullet 0xae2 +#define CLUTTER_opentribulletup 0xae3 +#define CLUTTER_opentribulletdown 0xae4 +#define CLUTTER_openstar 0xae5 +#define CLUTTER_enfilledcircbullet 0xae6 +#define CLUTTER_enfilledsqbullet 0xae7 +#define CLUTTER_filledtribulletup 0xae8 +#define CLUTTER_filledtribulletdown 0xae9 +#define CLUTTER_leftpointer 0xaea +#define CLUTTER_rightpointer 0xaeb +#define CLUTTER_club 0xaec +#define CLUTTER_diamond 0xaed +#define CLUTTER_heart 0xaee +#define CLUTTER_maltesecross 0xaf0 +#define CLUTTER_dagger 0xaf1 +#define CLUTTER_doubledagger 0xaf2 +#define CLUTTER_checkmark 0xaf3 +#define CLUTTER_ballotcross 0xaf4 +#define CLUTTER_musicalsharp 0xaf5 +#define CLUTTER_musicalflat 0xaf6 +#define CLUTTER_malesymbol 0xaf7 +#define CLUTTER_femalesymbol 0xaf8 +#define CLUTTER_telephone 0xaf9 +#define CLUTTER_telephonerecorder 0xafa +#define CLUTTER_phonographcopyright 0xafb +#define CLUTTER_caret 0xafc +#define CLUTTER_singlelowquotemark 0xafd +#define CLUTTER_doublelowquotemark 0xafe +#define CLUTTER_cursor 0xaff +#define CLUTTER_leftcaret 0xba3 +#define CLUTTER_rightcaret 0xba6 +#define CLUTTER_downcaret 0xba8 +#define CLUTTER_upcaret 0xba9 +#define CLUTTER_overbar 0xbc0 +#define CLUTTER_downtack 0xbc2 +#define CLUTTER_upshoe 0xbc3 +#define CLUTTER_downstile 0xbc4 +#define CLUTTER_underbar 0xbc6 +#define CLUTTER_jot 0xbca +#define CLUTTER_quad 0xbcc +#define CLUTTER_uptack 0xbce +#define CLUTTER_circle 0xbcf +#define CLUTTER_upstile 0xbd3 +#define CLUTTER_downshoe 0xbd6 +#define CLUTTER_rightshoe 0xbd8 +#define CLUTTER_leftshoe 0xbda +#define CLUTTER_lefttack 0xbdc +#define CLUTTER_righttack 0xbfc +#define CLUTTER_hebrew_doublelowline 0xcdf +#define CLUTTER_hebrew_aleph 0xce0 +#define CLUTTER_hebrew_bet 0xce1 +#define CLUTTER_hebrew_beth 0xce1 +#define CLUTTER_hebrew_gimel 0xce2 +#define CLUTTER_hebrew_gimmel 0xce2 +#define CLUTTER_hebrew_dalet 0xce3 +#define CLUTTER_hebrew_daleth 0xce3 +#define CLUTTER_hebrew_he 0xce4 +#define CLUTTER_hebrew_waw 0xce5 +#define CLUTTER_hebrew_zain 0xce6 +#define CLUTTER_hebrew_zayin 0xce6 +#define CLUTTER_hebrew_chet 0xce7 +#define CLUTTER_hebrew_het 0xce7 +#define CLUTTER_hebrew_tet 0xce8 +#define CLUTTER_hebrew_teth 0xce8 +#define CLUTTER_hebrew_yod 0xce9 +#define CLUTTER_hebrew_finalkaph 0xcea +#define CLUTTER_hebrew_kaph 0xceb +#define CLUTTER_hebrew_lamed 0xcec +#define CLUTTER_hebrew_finalmem 0xced +#define CLUTTER_hebrew_mem 0xcee +#define CLUTTER_hebrew_finalnun 0xcef +#define CLUTTER_hebrew_nun 0xcf0 +#define CLUTTER_hebrew_samech 0xcf1 +#define CLUTTER_hebrew_samekh 0xcf1 +#define CLUTTER_hebrew_ayin 0xcf2 +#define CLUTTER_hebrew_finalpe 0xcf3 +#define CLUTTER_hebrew_pe 0xcf4 +#define CLUTTER_hebrew_finalzade 0xcf5 +#define CLUTTER_hebrew_finalzadi 0xcf5 +#define CLUTTER_hebrew_zade 0xcf6 +#define CLUTTER_hebrew_zadi 0xcf6 +#define CLUTTER_hebrew_qoph 0xcf7 +#define CLUTTER_hebrew_kuf 0xcf7 +#define CLUTTER_hebrew_resh 0xcf8 +#define CLUTTER_hebrew_shin 0xcf9 +#define CLUTTER_hebrew_taw 0xcfa +#define CLUTTER_hebrew_taf 0xcfa +#define CLUTTER_Hebrew_switch 0xFF7E +#define CLUTTER_Thai_kokai 0xda1 +#define CLUTTER_Thai_khokhai 0xda2 +#define CLUTTER_Thai_khokhuat 0xda3 +#define CLUTTER_Thai_khokhwai 0xda4 +#define CLUTTER_Thai_khokhon 0xda5 +#define CLUTTER_Thai_khorakhang 0xda6 +#define CLUTTER_Thai_ngongu 0xda7 +#define CLUTTER_Thai_chochan 0xda8 +#define CLUTTER_Thai_choching 0xda9 +#define CLUTTER_Thai_chochang 0xdaa +#define CLUTTER_Thai_soso 0xdab +#define CLUTTER_Thai_chochoe 0xdac +#define CLUTTER_Thai_yoying 0xdad +#define CLUTTER_Thai_dochada 0xdae +#define CLUTTER_Thai_topatak 0xdaf +#define CLUTTER_Thai_thothan 0xdb0 +#define CLUTTER_Thai_thonangmontho 0xdb1 +#define CLUTTER_Thai_thophuthao 0xdb2 +#define CLUTTER_Thai_nonen 0xdb3 +#define CLUTTER_Thai_dodek 0xdb4 +#define CLUTTER_Thai_totao 0xdb5 +#define CLUTTER_Thai_thothung 0xdb6 +#define CLUTTER_Thai_thothahan 0xdb7 +#define CLUTTER_Thai_thothong 0xdb8 +#define CLUTTER_Thai_nonu 0xdb9 +#define CLUTTER_Thai_bobaimai 0xdba +#define CLUTTER_Thai_popla 0xdbb +#define CLUTTER_Thai_phophung 0xdbc +#define CLUTTER_Thai_fofa 0xdbd +#define CLUTTER_Thai_phophan 0xdbe +#define CLUTTER_Thai_fofan 0xdbf +#define CLUTTER_Thai_phosamphao 0xdc0 +#define CLUTTER_Thai_moma 0xdc1 +#define CLUTTER_Thai_yoyak 0xdc2 +#define CLUTTER_Thai_rorua 0xdc3 +#define CLUTTER_Thai_ru 0xdc4 +#define CLUTTER_Thai_loling 0xdc5 +#define CLUTTER_Thai_lu 0xdc6 +#define CLUTTER_Thai_wowaen 0xdc7 +#define CLUTTER_Thai_sosala 0xdc8 +#define CLUTTER_Thai_sorusi 0xdc9 +#define CLUTTER_Thai_sosua 0xdca +#define CLUTTER_Thai_hohip 0xdcb +#define CLUTTER_Thai_lochula 0xdcc +#define CLUTTER_Thai_oang 0xdcd +#define CLUTTER_Thai_honokhuk 0xdce +#define CLUTTER_Thai_paiyannoi 0xdcf +#define CLUTTER_Thai_saraa 0xdd0 +#define CLUTTER_Thai_maihanakat 0xdd1 +#define CLUTTER_Thai_saraaa 0xdd2 +#define CLUTTER_Thai_saraam 0xdd3 +#define CLUTTER_Thai_sarai 0xdd4 +#define CLUTTER_Thai_saraii 0xdd5 +#define CLUTTER_Thai_saraue 0xdd6 +#define CLUTTER_Thai_sarauee 0xdd7 +#define CLUTTER_Thai_sarau 0xdd8 +#define CLUTTER_Thai_sarauu 0xdd9 +#define CLUTTER_Thai_phinthu 0xdda +#define CLUTTER_Thai_maihanakat_maitho 0xdde +#define CLUTTER_Thai_baht 0xddf +#define CLUTTER_Thai_sarae 0xde0 +#define CLUTTER_Thai_saraae 0xde1 +#define CLUTTER_Thai_sarao 0xde2 +#define CLUTTER_Thai_saraaimaimuan 0xde3 +#define CLUTTER_Thai_saraaimaimalai 0xde4 +#define CLUTTER_Thai_lakkhangyao 0xde5 +#define CLUTTER_Thai_maiyamok 0xde6 +#define CLUTTER_Thai_maitaikhu 0xde7 +#define CLUTTER_Thai_maiek 0xde8 +#define CLUTTER_Thai_maitho 0xde9 +#define CLUTTER_Thai_maitri 0xdea +#define CLUTTER_Thai_maichattawa 0xdeb +#define CLUTTER_Thai_thanthakhat 0xdec +#define CLUTTER_Thai_nikhahit 0xded +#define CLUTTER_Thai_leksun 0xdf0 +#define CLUTTER_Thai_leknung 0xdf1 +#define CLUTTER_Thai_leksong 0xdf2 +#define CLUTTER_Thai_leksam 0xdf3 +#define CLUTTER_Thai_leksi 0xdf4 +#define CLUTTER_Thai_lekha 0xdf5 +#define CLUTTER_Thai_lekhok 0xdf6 +#define CLUTTER_Thai_lekchet 0xdf7 +#define CLUTTER_Thai_lekpaet 0xdf8 +#define CLUTTER_Thai_lekkao 0xdf9 +#define CLUTTER_Hangul 0xff31 +#define CLUTTER_Hangul_Start 0xff32 +#define CLUTTER_Hangul_End 0xff33 +#define CLUTTER_Hangul_Hanja 0xff34 +#define CLUTTER_Hangul_Jamo 0xff35 +#define CLUTTER_Hangul_Romaja 0xff36 +#define CLUTTER_Hangul_Codeinput 0xff37 +#define CLUTTER_Hangul_Jeonja 0xff38 +#define CLUTTER_Hangul_Banja 0xff39 +#define CLUTTER_Hangul_PreHanja 0xff3a +#define CLUTTER_Hangul_PostHanja 0xff3b +#define CLUTTER_Hangul_SingleCandidate 0xff3c +#define CLUTTER_Hangul_MultipleCandidate 0xff3d +#define CLUTTER_Hangul_PreviousCandidate 0xff3e +#define CLUTTER_Hangul_Special 0xff3f +#define CLUTTER_Hangul_switch 0xFF7E +#define CLUTTER_Hangul_Kiyeog 0xea1 +#define CLUTTER_Hangul_SsangKiyeog 0xea2 +#define CLUTTER_Hangul_KiyeogSios 0xea3 +#define CLUTTER_Hangul_Nieun 0xea4 +#define CLUTTER_Hangul_NieunJieuj 0xea5 +#define CLUTTER_Hangul_NieunHieuh 0xea6 +#define CLUTTER_Hangul_Dikeud 0xea7 +#define CLUTTER_Hangul_SsangDikeud 0xea8 +#define CLUTTER_Hangul_Rieul 0xea9 +#define CLUTTER_Hangul_RieulKiyeog 0xeaa +#define CLUTTER_Hangul_RieulMieum 0xeab +#define CLUTTER_Hangul_RieulPieub 0xeac +#define CLUTTER_Hangul_RieulSios 0xead +#define CLUTTER_Hangul_RieulTieut 0xeae +#define CLUTTER_Hangul_RieulPhieuf 0xeaf +#define CLUTTER_Hangul_RieulHieuh 0xeb0 +#define CLUTTER_Hangul_Mieum 0xeb1 +#define CLUTTER_Hangul_Pieub 0xeb2 +#define CLUTTER_Hangul_SsangPieub 0xeb3 +#define CLUTTER_Hangul_PieubSios 0xeb4 +#define CLUTTER_Hangul_Sios 0xeb5 +#define CLUTTER_Hangul_SsangSios 0xeb6 +#define CLUTTER_Hangul_Ieung 0xeb7 +#define CLUTTER_Hangul_Jieuj 0xeb8 +#define CLUTTER_Hangul_SsangJieuj 0xeb9 +#define CLUTTER_Hangul_Cieuc 0xeba +#define CLUTTER_Hangul_Khieuq 0xebb +#define CLUTTER_Hangul_Tieut 0xebc +#define CLUTTER_Hangul_Phieuf 0xebd +#define CLUTTER_Hangul_Hieuh 0xebe +#define CLUTTER_Hangul_A 0xebf +#define CLUTTER_Hangul_AE 0xec0 +#define CLUTTER_Hangul_YA 0xec1 +#define CLUTTER_Hangul_YAE 0xec2 +#define CLUTTER_Hangul_EO 0xec3 +#define CLUTTER_Hangul_E 0xec4 +#define CLUTTER_Hangul_YEO 0xec5 +#define CLUTTER_Hangul_YE 0xec6 +#define CLUTTER_Hangul_O 0xec7 +#define CLUTTER_Hangul_WA 0xec8 +#define CLUTTER_Hangul_WAE 0xec9 +#define CLUTTER_Hangul_OE 0xeca +#define CLUTTER_Hangul_YO 0xecb +#define CLUTTER_Hangul_U 0xecc +#define CLUTTER_Hangul_WEO 0xecd +#define CLUTTER_Hangul_WE 0xece +#define CLUTTER_Hangul_WI 0xecf +#define CLUTTER_Hangul_YU 0xed0 +#define CLUTTER_Hangul_EU 0xed1 +#define CLUTTER_Hangul_YI 0xed2 +#define CLUTTER_Hangul_I 0xed3 +#define CLUTTER_Hangul_J_Kiyeog 0xed4 +#define CLUTTER_Hangul_J_SsangKiyeog 0xed5 +#define CLUTTER_Hangul_J_KiyeogSios 0xed6 +#define CLUTTER_Hangul_J_Nieun 0xed7 +#define CLUTTER_Hangul_J_NieunJieuj 0xed8 +#define CLUTTER_Hangul_J_NieunHieuh 0xed9 +#define CLUTTER_Hangul_J_Dikeud 0xeda +#define CLUTTER_Hangul_J_Rieul 0xedb +#define CLUTTER_Hangul_J_RieulKiyeog 0xedc +#define CLUTTER_Hangul_J_RieulMieum 0xedd +#define CLUTTER_Hangul_J_RieulPieub 0xede +#define CLUTTER_Hangul_J_RieulSios 0xedf +#define CLUTTER_Hangul_J_RieulTieut 0xee0 +#define CLUTTER_Hangul_J_RieulPhieuf 0xee1 +#define CLUTTER_Hangul_J_RieulHieuh 0xee2 +#define CLUTTER_Hangul_J_Mieum 0xee3 +#define CLUTTER_Hangul_J_Pieub 0xee4 +#define CLUTTER_Hangul_J_PieubSios 0xee5 +#define CLUTTER_Hangul_J_Sios 0xee6 +#define CLUTTER_Hangul_J_SsangSios 0xee7 +#define CLUTTER_Hangul_J_Ieung 0xee8 +#define CLUTTER_Hangul_J_Jieuj 0xee9 +#define CLUTTER_Hangul_J_Cieuc 0xeea +#define CLUTTER_Hangul_J_Khieuq 0xeeb +#define CLUTTER_Hangul_J_Tieut 0xeec +#define CLUTTER_Hangul_J_Phieuf 0xeed +#define CLUTTER_Hangul_J_Hieuh 0xeee +#define CLUTTER_Hangul_RieulYeorinHieuh 0xeef +#define CLUTTER_Hangul_SunkyeongeumMieum 0xef0 +#define CLUTTER_Hangul_SunkyeongeumPieub 0xef1 +#define CLUTTER_Hangul_PanSios 0xef2 +#define CLUTTER_Hangul_KkogjiDalrinIeung 0xef3 +#define CLUTTER_Hangul_SunkyeongeumPhieuf 0xef4 +#define CLUTTER_Hangul_YeorinHieuh 0xef5 +#define CLUTTER_Hangul_AraeA 0xef6 +#define CLUTTER_Hangul_AraeAE 0xef7 +#define CLUTTER_Hangul_J_PanSios 0xef8 +#define CLUTTER_Hangul_J_KkogjiDalrinIeung 0xef9 +#define CLUTTER_Hangul_J_YeorinHieuh 0xefa +#define CLUTTER_Korean_Won 0xeff +#define CLUTTER_EcuSign 0x20a0 +#define CLUTTER_ColonSign 0x20a1 +#define CLUTTER_CruzeiroSign 0x20a2 +#define CLUTTER_FFrancSign 0x20a3 +#define CLUTTER_LiraSign 0x20a4 +#define CLUTTER_MillSign 0x20a5 +#define CLUTTER_NairaSign 0x20a6 +#define CLUTTER_PesetaSign 0x20a7 +#define CLUTTER_RupeeSign 0x20a8 +#define CLUTTER_WonSign 0x20a9 +#define CLUTTER_NewSheqelSign 0x20aa +#define CLUTTER_DongSign 0x20ab +#define CLUTTER_EuroSign 0x20ac + +#endif /* __CLUTTER_KEYSYMS_H__ */ diff --git a/clutter/clutter-label.c b/clutter/clutter-label.c new file mode 100644 index 000000000..b8fe7f548 --- /dev/null +++ b/clutter/clutter-label.c @@ -0,0 +1,419 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, 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 + +G_DEFINE_TYPE (ClutterLabel, clutter_label, CLUTTER_TYPE_TEXTURE); + +enum +{ + PROP_0, + PROP_FONT, + PROP_TEXT, + PROP_COL +}; + +#define CLUTTER_LABEL_GET_PRIVATE(obj) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_LABEL, ClutterLabelPrivate)) + +struct _ClutterLabelPrivate +{ + PangoLayout *layout; + PangoContext *context; + PangoFontDescription *desc; + guint32 fgcol; + gchar *text; + gchar *font; + gint extents_width, extents_height; +}; + +static void +clutter_label_make_pixbuf (ClutterLabel *label) +{ + gint bx, by, w, h; + FT_Bitmap ft_bitmap; + guint8 const *ps; + guint8 *pd; + ClutterLabelPrivate *priv; + ClutterTexture *texture; + GdkPixbuf *pixbuf; + + priv = label->priv; + + texture = CLUTTER_TEXTURE(label); + + if (priv->layout == NULL || priv->desc == NULL || priv->text == NULL) + { + CLUTTER_DBG("*** FAIL: layout: %p , desc: %p, text %p ***", + priv->layout, priv->desc, priv->text); + return; + } + + pango_layout_set_font_description (priv->layout, priv->desc); + pango_layout_set_text (priv->layout, priv->text, -1); + + if (priv->extents_width != 0) + { + CLUTTER_DBG("forcing width to '%i'", priv->extents_width); + pango_layout_set_width (priv->layout, PANGO_SCALE * priv->extents_width); + pango_layout_set_wrap (priv->layout, PANGO_WRAP_WORD); + } + + pango_layout_get_pixel_size (priv->layout, + &w, + &h); + + if (w == 0 || h == 0) + return; + + ft_bitmap.rows = h; + ft_bitmap.width = w; + ft_bitmap.pitch = (w+3) & ~3; + ft_bitmap.buffer = g_malloc0 (ft_bitmap.rows * ft_bitmap.pitch); + ft_bitmap.num_grays = 256; + ft_bitmap.pixel_mode = ft_pixel_mode_grays; + ft_bitmap.palette_mode = 0; + ft_bitmap.palette = NULL; + + pango_ft2_render_layout (&ft_bitmap, priv->layout, 0, 0); + + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, + TRUE, + 8, + ft_bitmap.width, + ft_bitmap.rows); + + for (by = 0; by < ft_bitmap.rows; by++) + { + pd = gdk_pixbuf_get_pixels (pixbuf) + + by * gdk_pixbuf_get_rowstride (pixbuf); + ps = ft_bitmap.buffer + by * ft_bitmap.pitch; + + for (bx = 0; bx < ft_bitmap.width; bx++) + { + *pd++ = clutter_color_r(priv->fgcol); + *pd++ = clutter_color_g(priv->fgcol); + *pd++ = clutter_color_b(priv->fgcol); + *pd++ = *ps++; + } + } + + g_free (ft_bitmap.buffer); + + CLUTTER_DBG("Calling set_pixbuf with text : '%s' , pixb %ix%i", + priv->text, w, h); + clutter_texture_set_pixbuf (CLUTTER_TEXTURE (label), pixbuf); + + /* Texture has the ref now */ + g_object_unref (pixbuf); +} + +static void +clutter_label_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ClutterLabel *label; + ClutterLabelPrivate *priv; + + label = CLUTTER_LABEL(object); + priv = label->priv; + + switch (prop_id) + { + case PROP_FONT: + clutter_label_set_font (label, g_value_get_string(value)); + break; + case PROP_TEXT: + clutter_label_set_text (label, g_value_get_string(value)); + break; + case PROP_COL: + clutter_label_set_color (label, g_value_get_uint(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +clutter_label_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ClutterLabel *label; + ClutterLabelPrivate *priv; + + label = CLUTTER_LABEL(object); + priv = label->priv; + + switch (prop_id) + { + case PROP_FONT: + g_value_set_string (value, priv->font); + break; + case PROP_TEXT: + g_value_set_string (value, priv->text); + break; + case PROP_COL: + g_value_set_uint (value, priv->fgcol); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static void +clutter_label_dispose (GObject *object) +{ + ClutterLabel *self = CLUTTER_LABEL(object); + ClutterLabelPrivate *priv; + + priv = self->priv; + + if (priv) + { + if (priv->layout) + { + g_object_unref (priv->layout); + priv->layout = NULL; + } + if (priv->desc) + { + pango_font_description_free (priv->desc); + priv->desc = NULL; + } + + if (priv->text) + { + g_free (priv->text); + priv->text = NULL; + } + + if (priv->font) + { + g_free (priv->font); + priv->font = NULL; + } + + if (priv->context) + { + g_object_unref (priv->context); + priv->context = NULL; + } + } + + G_OBJECT_CLASS (clutter_label_parent_class)->dispose (object); +} + +static void +clutter_label_finalize (GObject *object) +{ + G_OBJECT_CLASS (clutter_label_parent_class)->finalize (object); +} + +static void +clutter_label_class_init (ClutterLabelClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterElementClass *element_class = CLUTTER_ELEMENT_CLASS (klass); + ClutterTextureClass *texture_class = CLUTTER_TEXTURE_CLASS (klass); + ClutterElementClass *parent_class = CLUTTER_ELEMENT_CLASS (clutter_label_parent_class); + + element_class->paint = parent_class->paint; + element_class->realize = parent_class->realize; + element_class->unrealize = parent_class->unrealize; + element_class->show = parent_class->show; + element_class->hide = parent_class->hide; + + gobject_class->finalize = clutter_label_finalize; + gobject_class->dispose = clutter_label_dispose; + gobject_class->set_property = clutter_label_set_property; + gobject_class->get_property = clutter_label_get_property; + + g_object_class_install_property + (gobject_class, PROP_FONT, + g_param_spec_string ("font", + "Font", + "Pango font description", + "sans 10", + G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, PROP_TEXT, + g_param_spec_string ("text", + "Text", + "Text to render", + "", + G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, PROP_COL, + g_param_spec_uint ("color", + "Font Colour", + "Font Colour specified as 8 byte RGBA value", + 0, + 0xffffffff, + 0x000000ff, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + + g_type_class_add_private (gobject_class, sizeof (ClutterLabelPrivate)); +} + +static void +clutter_label_init (ClutterLabel *self) +{ + ClutterLabelPrivate *priv; + PangoFT2FontMap *font_map; + + self->priv = priv = CLUTTER_LABEL_GET_PRIVATE (self); + + font_map = PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ()); + + pango_ft2_font_map_set_resolution (font_map, 96.0, 96.0); + + priv->context = pango_ft2_font_map_create_context (font_map); + + priv->layout = pango_layout_new (priv->context); + + /* See http://bugzilla.gnome.org/show_bug.cgi?id=143542 ?? + pango_ft2_font_map_substitute_changed (font_map); + g_object_unref (font_map); + */ +} + +ClutterElement* +clutter_label_new_with_text (const gchar *font_desc, const gchar *text) +{ + ClutterLabel *label; + + label = g_object_new (CLUTTER_TYPE_LABEL, + "font", font_desc, + "text", text, + NULL); + + return CLUTTER_ELEMENT(label); +} + +ClutterElement* +clutter_label_new (void) +{ + return CLUTTER_ELEMENT(g_object_new (CLUTTER_TYPE_LABEL, NULL)); +} + +void +clutter_label_set_text (ClutterLabel *label, const gchar *text) +{ + ClutterLabelPrivate *priv; + + g_return_if_fail (CLUTTER_IS_LABEL (label)); + + priv = label->priv; + + if (priv->text) + g_free (priv->text); + + priv->text = g_strdup(text); + + clutter_label_make_pixbuf (label); + + if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT(label))) + clutter_element_queue_redraw (CLUTTER_ELEMENT(label)); +} + +void +clutter_label_set_font (ClutterLabel *label, const gchar *desc) +{ + ClutterLabelPrivate *priv; + + g_return_if_fail (CLUTTER_IS_LABEL (label)); + + priv = label->priv; + + if (priv->desc) + pango_font_description_free (priv->desc); + + if (priv->font) + g_free(priv->font); + + priv->font = g_strdup(desc); + + priv->desc = pango_font_description_from_string (desc); + + if (label->priv->text && label->priv->text[0] != '\0') + { + clutter_label_make_pixbuf (label); + + if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT(label))) + clutter_element_queue_redraw (CLUTTER_ELEMENT(label)); + } +} + +void +clutter_label_set_text_extents (ClutterLabel *label, + gint width, + gint height) +{ + /* FIXME: height extents is broken.... + */ + + label->priv->extents_width = width; + label->priv->extents_height = height; + + clutter_label_make_pixbuf (label); + + if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT(label))) + clutter_element_queue_redraw (CLUTTER_ELEMENT(label)); +} + +void +clutter_label_set_color (ClutterLabel *label, ClutterColor pixel) +{ + ClutterLabelPrivate *priv; + + priv = label->priv; + + priv->fgcol = pixel; + + clutter_element_set_opacity(CLUTTER_ELEMENT(label), priv->fgcol & 0xff); + + clutter_label_make_pixbuf (label); + + if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT(label))) + clutter_element_queue_redraw (CLUTTER_ELEMENT(label)); +} + + diff --git a/clutter/clutter-label.h b/clutter/clutter-label.h new file mode 100644 index 000000000..356e3c0ba --- /dev/null +++ b/clutter/clutter-label.h @@ -0,0 +1,104 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, 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 +#include +#include + +G_BEGIN_DECLS + +#define CLUTTER_TYPE_LABEL clutter_label_get_type() + +#define CLUTTER_LABEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + CLUTTER_TYPE_LABEL, ClutterLabel)) + +#define CLUTTER_LABEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + CLUTTER_TYPE_LABEL, ClutterLabelClass)) + +#define CLUTTER_IS_LABEL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + CLUTTER_TYPE_LABEL)) + +#define CLUTTER_IS_LABEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + CLUTTER_TYPE_LABEL)) + +#define CLUTTER_LABEL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + CLUTTER_TYPE_LABEL, ClutterLabelClass)) + +typedef struct _ClutterLabel ClutterLabel; +typedef struct _ClutterLabelPrivate ClutterLabelPrivate ; +typedef struct _ClutterLabelClass ClutterLabelClass; + +struct _ClutterLabel +{ + ClutterTexture parent; + + /*< private >*/ + ClutterLabelPrivate *priv; +}; + +struct _ClutterLabelClass +{ + /*< private >*/ + ClutterTextureClass parent_class; + + void (*_clutter_label_1) (void); + void (*_clutter_label_2) (void); + void (*_clutter_label_3) (void); + void (*_clutter_label_4) (void); +}; + +GType clutter_label_get_type (void); + +ClutterElement* +clutter_label_new_with_text (const gchar *font_desc, const gchar *text); + +ClutterElement* +clutter_label_new (void); + +void +clutter_label_set_text (ClutterLabel *label, const gchar *text); + +void +clutter_label_set_font (ClutterLabel *label, const gchar *desc); + +void +clutter_label_set_color (ClutterLabel *label, guint32 pixel); + +void +clutter_label_set_text_extents (ClutterLabel *label, + gint width, + gint height); + +G_END_DECLS + +#endif diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c new file mode 100644 index 000000000..2b792878f --- /dev/null +++ b/clutter/clutter-main.c @@ -0,0 +1,403 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, 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 /* for gst_init() */ + +typedef struct +{ + GSource source; + Display *display; + GPollFD event_poll_fd; +} +ClutterXEventSource; + +ClutterMainContext ClutterCntx; + +#define GLX_SAMPLE_BUFFERS_ARB 100000 +#define GLX_SAMPLES_ARB 100001 + +typedef void (*ClutterXEventFunc) (XEvent *xev, gpointer user_data); + +static gboolean __clutter_has_debug = FALSE; +static gboolean __clutter_has_fps = FALSE; + +static gboolean +x_event_prepare (GSource *source, + gint *timeout) +{ + Display *display = ((ClutterXEventSource*)source)->display; + + *timeout = -1; + + return XPending (display); +} + +static gboolean +x_event_check (GSource *source) +{ + ClutterXEventSource *display_source = (ClutterXEventSource*)source; + gboolean retval; + + if (display_source->event_poll_fd.revents & G_IO_IN) + retval = XPending (display_source->display); + else + retval = FALSE; + + return retval; +} + +static gboolean +x_event_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + Display *display = ((ClutterXEventSource*)source)->display; + ClutterXEventFunc event_func = (ClutterXEventFunc) callback; + + XEvent xev; + + if (XPending (display)) + { + XNextEvent (display, &xev); + + if (event_func) + (*event_func) (&xev, user_data); + } + + return TRUE; +} + +static const GSourceFuncs x_event_funcs = { + x_event_prepare, + x_event_check, + x_event_dispatch, + NULL +}; + +static void +translate_key_event (ClutterKeyEvent *event, + XEvent *xevent) +{ + event->type = xevent->xany.type + == KeyPress ? CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE; + event->time = xevent->xkey.time; + event->modifier_state = xevent->xkey.state; /* FIXME: handle modifiers */ + event->hardware_keycode = xevent->xkey.keycode; + event->keyval = XKeycodeToKeysym(xevent->xkey.display, + xevent->xkey.keycode, + 0 ); /* FIXME: index with modifiers */ +} + +static void +translate_button_event (ClutterButtonEvent *event, + XEvent *xevent) +{ + /* FIXME: catch double click */ + CLUTTER_DBG("button event at %ix%i", xevent->xbutton.x, xevent->xbutton.y); + + event->type = xevent->xany.type + == ButtonPress ? CLUTTER_BUTTON_PRESS : CLUTTER_BUTTON_RELEASE; + event->time = xevent->xbutton.time; + event->x = xevent->xbutton.x; + event->y = xevent->xbutton.y; + event->modifier_state = xevent->xbutton.state; /* includes button masks */ + event->button = xevent->xbutton.button; +} + +static void +translate_motion_event (ClutterMotionEvent *event, + XEvent *xevent) +{ + event->type = CLUTTER_MOTION; + event->time = xevent->xbutton.time; + event->x = xevent->xmotion.x; + event->y = xevent->xmotion.y; + event->modifier_state = xevent->xmotion.state; +} + +void +clutter_dispatch_x_event (XEvent *xevent, + gpointer data) +{ + ClutterMainContext *ctx = CLUTTER_CONTEXT(); + ClutterEvent event; + + switch (xevent->type) + { + case Expose: + { + XEvent foo_xev; + + /* Cheap compress */ + while (XCheckTypedWindowEvent(ctx->xdpy, + xevent->xexpose.window, + Expose, + &foo_xev)); + + /* FIXME: need to make stage an 'element' so can que + * a paint direct from there rather than hack here... + */ + clutter_element_queue_redraw (CLUTTER_ELEMENT(clutter_stage())); + } + break; + case KeyPress: + case KeyRelease: + translate_key_event ((ClutterKeyEvent*)&event, xevent); + g_signal_emit_by_name (clutter_stage(), "input-event", &event); + break; + case ButtonPress: + case ButtonRelease: + translate_button_event ((ClutterButtonEvent*)&event, xevent); + g_signal_emit_by_name (clutter_stage(), "input-event", &event); + break; + case MotionNotify: + translate_motion_event ((ClutterMotionEvent*)&event, xevent); + g_signal_emit_by_name (clutter_stage(), "input-event", &event); + break; + } +} + +static void +events_init() +{ + GMainContext *gmain_context; + int connection_number; + GSource *source; + ClutterXEventSource *display_source; + + gmain_context = g_main_context_default (); + + g_main_context_ref (gmain_context); + + connection_number = ConnectionNumber (ClutterCntx.xdpy); + + source = g_source_new ((GSourceFuncs *)&x_event_funcs, + sizeof (ClutterXEventSource)); + + display_source = (ClutterXEventSource *)source; + + display_source->event_poll_fd.fd = connection_number; + display_source->event_poll_fd.events = G_IO_IN; + display_source->display = ClutterCntx.xdpy; + + g_source_add_poll (source, &display_source->event_poll_fd); + g_source_set_can_recurse (source, TRUE); + + g_source_set_callback (source, + (GSourceFunc) clutter_dispatch_x_event, + NULL /* no userdata */, NULL); + + g_source_attach (source, gmain_context); + g_source_unref (source); +} + +static gboolean +clutter_want_fps(void) +{ + return __clutter_has_fps; +} + +void +clutter_redraw () +{ + ClutterMainContext *ctx = CLUTTER_CONTEXT(); + ClutterStage *stage = CLUTTER_STAGE(clutter_stage()); + ClutterColor stage_color; + + static GTimer *timer = NULL; + static guint timer_n_frames = 0; + + CLUTTER_DBG("@@@ Redraw enter @@@"); + + clutter_threads_enter(); + + if (clutter_want_fps()) + { + if (!timer) + timer = g_timer_new(); + } + + stage_color = clutter_stage_get_color (stage); + + glClearColor( ( (float)clutter_color_r(stage_color) / 0xff ) * 1.0, + ( (float)clutter_color_g(stage_color) / 0xff ) * 1.0, + ( (float)clutter_color_b(stage_color) / 0xff ) * 1.0, + 0.0 ); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + + clutter_element_paint(CLUTTER_ELEMENT(stage)); + + glXSwapBuffers(ctx->xdpy, clutter_stage_get_xwindow (stage)); + + if (clutter_want_fps()) + { + timer_n_frames++; + + if (g_timer_elapsed (timer, NULL) >= 1.0) + { + g_print ("*** FPS: %i ***\n", timer_n_frames); + timer_n_frames = 0; + g_timer_start (timer); + } + } + + clutter_threads_leave(); + + CLUTTER_DBG("@@@ Redraw leave @@@"); +} + + +void +clutter_main() +{ + GMainLoop *loop; + + loop = g_main_loop_new (g_main_context_default (), TRUE); + + g_main_loop_run (loop); +} + +void +clutter_threads_enter(void) +{ + g_mutex_lock(ClutterCntx.gl_lock); +} + +void +clutter_threads_leave(void) +{ + g_mutex_unlock(ClutterCntx.gl_lock); +} + +ClutterGroup* +clutter_stage(void) +{ + return CLUTTER_GROUP(ClutterCntx.stage); +} + +Display* +clutter_xdisplay(void) +{ + return ClutterCntx.xdpy; +} + +int +clutter_xscreen(void) +{ + return ClutterCntx.xscreen; +} + +Window +clutter_root_xwindow(void) +{ + return ClutterCntx.xwin_root; +} + +gboolean +clutter_want_debug(void) +{ + return __clutter_has_debug; +} + +GLXContext +clutter_gl_context(void) +{ + return ClutterCntx.gl_context; +} + +int +clutter_init(int *argc, char ***argv) +{ + XVisualInfo *vinfo; + + int gl_attributes[] = + { + GLX_RGBA, + GLX_DOUBLEBUFFER, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + /* GLX_DEPTH_SIZE, 1, */ + /* GLX_DEPTH_SIZE, 32, */ + 0 + }; + + if (getenv("CLUTTER_DEBUG")) + __clutter_has_debug = TRUE; + + if (getenv("CLUTTER_SHOW_FPS")) + __clutter_has_fps = TRUE; + + g_type_init(); + + if (!g_thread_supported ()) + g_thread_init (NULL); + + XInitThreads(); + + gst_init (argc, argv); + + if ((ClutterCntx.xdpy = XOpenDisplay(getenv("DISPLAY"))) == NULL) + { + g_warning("Unable to connect to X DISPLAY."); + return -1; + } + + ClutterCntx.xscreen = DefaultScreen(ClutterCntx.xdpy); + ClutterCntx.xwin_root = RootWindow(ClutterCntx.xdpy, ClutterCntx.xscreen); + + if ((vinfo = glXChooseVisual(ClutterCntx.xdpy, + ClutterCntx.xscreen, + gl_attributes)) == NULL) + { + g_warning("Unable to find suitable GL visual."); + return -2; + } + + ClutterCntx.gl_context = glXCreateContext(ClutterCntx.xdpy, vinfo, 0, True); + + ClutterCntx.font_map = PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ()); + + pango_ft2_font_map_set_resolution (ClutterCntx.font_map, 96.0, 96.0); + + ClutterCntx.gl_lock = g_mutex_new (); + + ClutterCntx.stage = g_object_new (CLUTTER_TYPE_STAGE, NULL); + + g_return_val_if_fail (ClutterCntx.stage != NULL, -3); + + clutter_element_realize(CLUTTER_ELEMENT(ClutterCntx.stage)); + + events_init(); + + return 1; +} + diff --git a/clutter/clutter-main.h b/clutter/clutter-main.h new file mode 100644 index 000000000..1c493d358 --- /dev/null +++ b/clutter/clutter-main.h @@ -0,0 +1,96 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, 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 +#include + +#include + +#include +#include + +#define CLUTTER_HAS_DEBUG_MESSGES 1 + +#if (CLUTTER_HAS_DEBUG_MESSGES) + +#define CLUTTER_DBG(x, a...) \ + if (clutter_want_debug()) \ + { g_printerr ( __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a); } + +#define CLUTTER_GLERR() \ + if (clutter_want_debug()) \ + { \ + GLenum err = glGetError (); /* Roundtrip */ \ + if (err != GL_NO_ERROR) \ + { \ + g_printerr (__FILE__ ": GL Error: %x [at %s:%d]\n", \ + err, __func__, __LINE__); \ + } \ + } +#else +#define CLUTTER_DBG(x, a...) do {} while (0) +#define CLUTTER_GLERR() do {} while (0) +#endif /* CLUTTER_HAS_DEBUG */ + +#define CLUTTER_MARK() CLUTTER_DBG("mark") + +int +clutter_init (int *argc, char ***argv); + +void +clutter_main(void); + +ClutterGroup* +clutter_stage(void); + +void +clutter_redraw (); + +Display* +clutter_xdisplay (void); + +int +clutter_xscreen (void); + +Window +clutter_root_xwindow (void); + +GLXContext +clutter_gl_context (void); + +gboolean +clutter_want_debug (void); + +void +clutter_threads_enter (void); + +void +clutter_threads_leave (void); + + +#endif diff --git a/clutter/clutter-marshal.list b/clutter/clutter-marshal.list new file mode 100644 index 000000000..435c9acee --- /dev/null +++ b/clutter/clutter-marshal.list @@ -0,0 +1,4 @@ +VOID:INT64,INT64,FLOAT,BOOLEAN +VOID:STRING,BOOLEAN,BOOLEAN +VOID:INT,INT + diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h new file mode 100644 index 000000000..5ebea0b01 --- /dev/null +++ b/clutter/clutter-private.h @@ -0,0 +1,65 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, 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 + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include + + +typedef struct ClutterMainContext +{ + Display *xdpy; + Window xwin_root; + int xscreen; + GC xgc; + PangoFT2FontMap *font_map; + GLXContext gl_context; + GMutex *gl_lock; + guint update_idle; + ClutterStage *stage; +} +ClutterMainContext; + +#define CLUTTER_CONTEXT() &ClutterCntx + +#endif diff --git a/clutter/clutter-rectangle.c b/clutter/clutter-rectangle.c new file mode 100644 index 000000000..47207dd26 --- /dev/null +++ b/clutter/clutter-rectangle.c @@ -0,0 +1,185 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, 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 +#include + +G_DEFINE_TYPE (ClutterRectangle, clutter_rectangle, CLUTTER_TYPE_ELEMENT); + +enum +{ + PROP_0, + PROP_COL + + /* FIXME: Add gradient, rounded corner props etc */ +}; + +#define CLUTTER_RECTANGLE_GET_PRIVATE(obj) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_RECTANGLE, ClutterRectanglePrivate)) + +struct _ClutterRectanglePrivate +{ + guint32 col; +}; + +static void +clutter_rectangle_paint (ClutterElement *self) +{ + ClutterRectangle *rectangle = CLUTTER_RECTANGLE(self); + ClutterRectanglePrivate *priv; + ClutterGeometry geom; + + rectangle = CLUTTER_RECTANGLE(self); + priv = rectangle->priv; + + glPushMatrix(); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + clutter_element_get_geometry (self, &geom); + + glColor4ub(clutter_color_r(priv->col), + clutter_color_g(priv->col), + clutter_color_b(priv->col), + clutter_element_get_opacity(self)); + + glRecti (geom.x, + geom.y, + geom.x + geom.width, + geom.y + geom.height); + + glDisable(GL_BLEND); + + glPopMatrix(); +} + +static void +clutter_rectangle_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ClutterRectangle *rectangle; + ClutterRectanglePrivate *priv; + + rectangle = CLUTTER_RECTANGLE(object); + priv = rectangle->priv; + + switch (prop_id) + { + case PROP_COL: + priv->col = g_value_get_uint(value); + clutter_element_set_opacity(CLUTTER_ELEMENT(rectangle), + priv->col & 0xff); + /* FIXME: queue paint */ + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +clutter_rectangle_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ClutterRectangle *rectangle; + ClutterRectanglePrivate *priv; + + rectangle = CLUTTER_RECTANGLE(object); + priv = rectangle->priv; + + switch (prop_id) + { + case PROP_COL: + g_value_set_uint (value, priv->col); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static void +clutter_rectangle_finalize (GObject *object) +{ + G_OBJECT_CLASS (clutter_rectangle_parent_class)->finalize (object); +} + +static void +clutter_rectangle_dispose (GObject *object) +{ + G_OBJECT_CLASS (clutter_rectangle_parent_class)->dispose (object); +} + + +static void +clutter_rectangle_class_init (ClutterRectangleClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterElementClass *element_class = CLUTTER_ELEMENT_CLASS (klass); + + element_class->paint = clutter_rectangle_paint; + + gobject_class->finalize = clutter_rectangle_finalize; + gobject_class->dispose = clutter_rectangle_dispose; + gobject_class->set_property = clutter_rectangle_set_property; + gobject_class->get_property = clutter_rectangle_get_property; + + g_object_class_install_property + (gobject_class, PROP_COL, + g_param_spec_uint ("color", + "Rectangle Colour", + "Rectangle Colour specified as 8 byte RGBA value", + 0, + 0xffffffff, + 0xff, + G_PARAM_READWRITE)); + + g_type_class_add_private (gobject_class, sizeof (ClutterRectanglePrivate)); +} + +static void +clutter_rectangle_init (ClutterRectangle *self) +{ + self->priv = CLUTTER_RECTANGLE_GET_PRIVATE (self); +} + +ClutterElement* +clutter_rectangle_new (guint32 colour) +{ + return g_object_new (CLUTTER_TYPE_RECTANGLE, + "color", colour, + NULL); +} + diff --git a/clutter/clutter-rectangle.h b/clutter/clutter-rectangle.h new file mode 100644 index 000000000..c13a91ea5 --- /dev/null +++ b/clutter/clutter-rectangle.h @@ -0,0 +1,80 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, 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 +#include + +G_BEGIN_DECLS + +#define CLUTTER_TYPE_RECTANGLE clutter_rectangle_get_type() + +#define CLUTTER_RECTANGLE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + CLUTTER_TYPE_RECTANGLE, ClutterRectangle)) + +#define CLUTTER_RECTANGLE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + CLUTTER_TYPE_RECTANGLE, ClutterRectangleClass)) + +#define CLUTTER_IS_RECTANGLE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + CLUTTER_TYPE_RECTANGLE)) + +#define CLUTTER_IS_RECTANGLE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + CLUTTER_TYPE_RECTANGLE)) + +#define CLUTTER_RECTANGLE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + CLUTTER_TYPE_RECTANGLE, ClutterRectangleClass)) + +typedef struct _ClutterRectanglePrivate ClutterRectanglePrivate; +typedef struct _ClutterRectangle ClutterRectangle; +typedef struct _ClutterRectangleClass ClutterRectangleClass; + +struct _ClutterRectangle +{ + ClutterElement parent; + + /*< priv >*/ + ClutterRectanglePrivate *priv; +}; + +struct _ClutterRectangleClass +{ + ClutterElementClass parent_class; +}; + +GType clutter_rectangle_get_type (void); + +ClutterElement* +clutter_rectangle_new (guint32 col); + +G_END_DECLS + +#endif diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c new file mode 100644 index 000000000..fd2e7b4a1 --- /dev/null +++ b/clutter/clutter-stage.c @@ -0,0 +1,620 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, 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 +#include + +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 + * + * 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 + +#include +#include +#include + +#include + +#include +#include + +G_BEGIN_DECLS + +#define CLUTTER_TYPE_STAGE clutter_stage_get_type() + +#define CLUTTER_STAGE_WIDTH() \ + clutter_element_get_width(CLUTTER_ELEMENT(clutter_stage())) + +#define CLUTTER_STAGE_HEIGHT() \ + clutter_element_get_height(CLUTTER_ELEMENT(clutter_stage())) + + +#define CLUTTER_STAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + CLUTTER_TYPE_STAGE, ClutterStage)) + +#define CLUTTER_STAGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + CLUTTER_TYPE_STAGE, ClutterStageClass)) + +#define CLUTTER_IS_STAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + CLUTTER_TYPE_STAGE)) + +#define CLUTTER_IS_STAGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + CLUTTER_TYPE_STAGE)) + +#define CLUTTER_STAGE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + CLUTTER_TYPE_STAGE, ClutterStageClass)) + +typedef struct ClutterStagePrivate ClutterStagePrivate; +typedef struct _ClutterStage ClutterStage; +typedef struct _ClutterStageClass ClutterStageClass; + +struct _ClutterStage +{ + ClutterGroup parent; + ClutterStagePrivate *priv; +}; + +struct _ClutterStageClass +{ + ClutterGroupClass parent_class; + + void (*input_event) (ClutterStage *stage, + ClutterEvent *event); +}; + +GType clutter_stage_get_type (void); + +/* FIXME: no need for below to take stage arg ? + * convert to defines also ? +*/ + +Window +clutter_stage_get_xwindow (ClutterStage *stage); + +void +clutter_stage_set_color (ClutterStage *stage, + ClutterColor color); + +ClutterColor +clutter_stage_get_color (ClutterStage *stage); + +ClutterElement* +clutter_stage_pick (ClutterStage *stage, gint x, gint y); + +G_END_DECLS + +#endif diff --git a/clutter/clutter-texture.c b/clutter/clutter-texture.c new file mode 100644 index 000000000..02a2a7544 --- /dev/null +++ b/clutter/clutter-texture.c @@ -0,0 +1,1216 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "clutter-texture.h" +#include "clutter-main.h" +#include "clutter-marshal.h" +#include "clutter-private.h" /* for DBG */ + +#include +#include + +G_DEFINE_TYPE (ClutterTexture, clutter_texture, CLUTTER_TYPE_ELEMENT); + +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +#define PIXEL_TYPE GL_UNSIGNED_BYTE +#else +#define PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV +#endif + +#define PIXEL_FORMAT GL_RGBA + +/* Some code below based on luminocity - copyright Owen Taylor */ + +/* MAX_WASTE: The maximum dimension of blank area we'll accept + * in a pixmap. Bigger values use less textures, smaller + * values less texture memory. The current value of + * 256 means that the smallest texture we'll split to + * save texture memory is 513x512. (That will be split into + * a 512x512 and, if overlap is 32, a 64x512 texture) + */ +#define MAX_WASTE 64 /* FIXME: Make property */ + +/* + * OVERLAP: when we divide the full-resolution image into + * tiles to deal with hardware limitations, we overlap + * tiles by this much. This means that we can scale + * down by up to OVERLAP before we start getting + * seems. + */ + +#define OVERLAP 0 /* 32 */ + +/* FIXME: actually use */ +typedef struct ClutterTextureTileDimention +{ + gint pos, size, waste; +} +ClutterTextureTileDimention; + +struct ClutterTexturePrivate +{ + GdkPixbuf *pixbuf; + gint width, height; + GLenum pixel_format; + GLenum pixel_type; + + gboolean sync_element_size; + gint tile_max_waste; + gboolean repeat_x, repeat_y; + + gboolean tiled; + ClutterTextureTileDimention *x_tiles, *y_tiles; + gint n_x_tiles, n_y_tiles; + GLuint *tiles; +}; + +enum +{ + PROP_0, + PROP_PIXBUF, + PROP_USE_TILES, + PROP_MAX_TILE_WASTE, + PROP_PIXEL_TYPE, /* Texture type */ + PROP_PIXEL_FORMAT, /* Texture format */ + PROP_SYNC_SIZE, + PROP_REPEAT_Y, + PROP_REPEAT_X +}; + +enum +{ + SIGNAL_SIZE_CHANGE, + SIGNAL_PIXBUF_CHANGE, + LAST_SIGNAL +}; + +static int texture_signals[LAST_SIGNAL] = { 0 }; + +static void +init_tiles (ClutterTexture *texture); + +static int +next_p2 (int a) +{ + int rval=1; + + while(rval < a) + rval <<= 1; + + return rval; +} + +static gboolean +can_create (int width, + int height, + GLenum pixel_format, + GLenum pixel_type) +{ + GLint new_width; + + CLUTTER_DBG("checking %ix%i", width, height); + + + glTexImage2D (GL_PROXY_TEXTURE_2D, 0, GL_RGBA, + width, height, 0 /* border */, + pixel_format, pixel_type, NULL); + + glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, + GL_TEXTURE_WIDTH, &new_width); + + + return new_width != 0; +} + +static int +tile_dimension (int to_fill, + int start_size, + ClutterTextureTileDimention *tiles) +{ + int pos = 0; + int n_tiles = 0; + int size = start_size; + + while (TRUE) + { + if (tiles) + { + tiles[n_tiles].pos = pos; + tiles[n_tiles].size = size; + tiles[n_tiles].waste = 0; + } + + n_tiles++; + + if (to_fill <= size) + { + if (tiles) + tiles[n_tiles-1].waste = size - to_fill; + break; + } + else + { + to_fill -= (size - OVERLAP); + pos += size - OVERLAP; + while (size >= 2 * to_fill || size - to_fill > MAX_WASTE) + size /= 2; + } + } + + return n_tiles; +} + +static void +init_tiles (ClutterTexture *texture) +{ + ClutterTexturePrivate *priv; + gint x_pot, y_pot; + + priv = texture->priv; + + x_pot = next_p2 (priv->width); + y_pot = next_p2 (priv->height); + + if (x_pot - priv->width > MAX_WASTE && y_pot - priv->height > MAX_WASTE) + { + while (!(can_create (x_pot, y_pot, priv->pixel_format, priv->pixel_type) + && (x_pot - priv->width < MAX_WASTE) + && (y_pot - priv->height < MAX_WASTE))) + { + CLUTTER_DBG("x_pot:%i - width:%i < max_waste:%i", + x_pot, priv->width, MAX_WASTE ); + + CLUTTER_DBG("y_pot:%i - height:%i < max_waste:%i", + y_pot, priv->height, MAX_WASTE ); + + if (x_pot > y_pot) + x_pot /= 2; + else + y_pot /= 2; + } + } + + if (priv->x_tiles) + g_free(priv->x_tiles); + + priv->n_x_tiles = tile_dimension (priv->width, x_pot, NULL); + priv->x_tiles = g_new (ClutterTextureTileDimention, priv->n_x_tiles); + tile_dimension (priv->width, x_pot, priv->x_tiles); + + if (priv->y_tiles) + g_free(priv->y_tiles); + + priv->n_y_tiles = tile_dimension (priv->height, y_pot, NULL); + priv->y_tiles = g_new (ClutterTextureTileDimention, priv->n_y_tiles); + tile_dimension (priv->height, y_pot, priv->y_tiles); + + CLUTTER_DBG("x_pot:%i, width:%i, y_pot:%i, height: %i max_waste:%i, " + " n_x_tiles: %i, n_y_tiles: %i", + x_pot, priv->width, y_pot, priv->height, MAX_WASTE, + priv->n_x_tiles, priv->n_y_tiles); + +} + +static void +texture_render_to_gl_quad (ClutterTexture *texture, + int x1, + int y1, + int x2, + int y2) +{ + int qx1 = 0, qx2 = 0, qy1 = 0, qy2 = 0; + int qwidth = 0, qheight = 0; + int x, y, i =0, lastx = 0, lasty = 0; + float tx, ty; + + ClutterTexturePrivate *priv; + + priv = texture->priv; + + qwidth = x2-x1; + qheight = y2-y1; + + if (!CLUTTER_ELEMENT_IS_REALIZED (CLUTTER_ELEMENT(texture))) + clutter_element_realize (CLUTTER_ELEMENT(texture)); + + g_return_if_fail(priv->tiles != NULL); + + /* OPT: Put in display list */ + + /* OPT: Optionally avoid tiling and use texture rectangles ext if + * supported. + */ + + if (!priv->tiled) + { + glBindTexture(GL_TEXTURE_2D, priv->tiles[0]); + + tx = (float) priv->width / next_p2 (priv->width); + ty = (float) priv->height / next_p2 (priv->height); + + qx1 = x1; qx2 = x2; + qy1 = y1; qy2 = y2; + + glBegin (GL_QUADS); + glTexCoord2f (tx, ty); glVertex2i (qx2, qy2); + glTexCoord2f (0, ty); glVertex2i (qx1, qy2); + glTexCoord2f (0, 0); glVertex2i (qx1, qy1); + glTexCoord2f (tx, 0); glVertex2i (qx2, qy1); + glEnd (); + + return; + } + + for (x=0; x < priv->n_x_tiles; x++) + { + lasty = 0; + + for (y=0; y < priv->n_y_tiles; y++) + { + int actual_w, actual_h; + + glBindTexture(GL_TEXTURE_2D, priv->tiles[i]); + + actual_w = priv->x_tiles[x].size - priv->x_tiles[x].waste; + actual_h = priv->y_tiles[y].size - priv->y_tiles[y].waste; + + CLUTTER_DBG("rendering text tile x: %i, y: %i - %ix%i", + x, y, actual_w, actual_h); + + tx = (float) actual_w / priv->x_tiles[x].size; + ty = (float) actual_h / priv->y_tiles[y].size; + + qx1 = x1 + lastx; + qx2 = qx1 + ((qwidth * actual_w ) / priv->width ); + + qy1 = y1 + lasty; + qy2 = qy1 + ((qheight * actual_h) / priv->height ); + + glBegin (GL_QUADS); + glTexCoord2f (tx, ty); glVertex2i (qx2, qy2); + glTexCoord2f (0, ty); glVertex2i (qx1, qy2); + glTexCoord2f (0, 0); glVertex2i (qx1, qy1); + glTexCoord2f (tx, 0); glVertex2i (qx2, qy1); + glEnd (); + + lasty += qy2 - qy1; + + i++; + } + lastx += qx2 - qx1; + } +} + +static void +clutter_texture_unrealize (ClutterElement *element) +{ + ClutterTexture *texture; + ClutterTexturePrivate *priv; + + texture = CLUTTER_TEXTURE(element); + priv = texture->priv; + + if (priv->tiles == NULL) + return; + + CLUTTER_MARK(); + + clutter_threads_enter (); + + /* Free up texture memory */ + if (!priv->tiled) + glDeleteTextures(1, priv->tiles); + else + glDeleteTextures(priv->n_x_tiles * priv->n_y_tiles, priv->tiles); + + clutter_threads_leave (); + + CLUTTER_MARK(); + + if (priv->tiles) + { + g_free(priv->tiles); + priv->tiles = NULL; + } + + if (priv->x_tiles) + { + g_free(priv->x_tiles); + priv->x_tiles = NULL; + } + + if (priv->y_tiles) + { + g_free(priv->y_tiles); + priv->y_tiles = NULL; + } + + CLUTTER_DBG("Texture unrealized"); +} + +static void +clutter_texture_sync_pixbuf (ClutterTexture *texture) +{ + ClutterTexturePrivate *priv; + int x, y, i = 0; + gboolean create_textures = FALSE; + + priv = texture->priv; + + g_return_if_fail (priv->pixbuf != NULL); + + CLUTTER_MARK(); + + if (!priv->tiled) + { + /* Single Texture + * + */ + if (!priv->tiles) + { + priv->tiles = g_new (GLuint, 1); + glGenTextures (1, priv->tiles); + create_textures = TRUE; + } + + CLUTTER_DBG("syncing for single tile"); + + glBindTexture(GL_TEXTURE_2D, priv->tiles[0]); + + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_WRAP_S, + priv->repeat_x ? GL_REPEAT : GL_CLAMP); + + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_WRAP_T, + priv->repeat_y ? GL_REPEAT : GL_CLAMP); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glPixelStorei (GL_UNPACK_ROW_LENGTH, + gdk_pixbuf_get_width(priv->pixbuf)); + glPixelStorei (GL_UNPACK_ALIGNMENT, + gdk_pixbuf_get_n_channels (priv->pixbuf)); + + if (create_textures) + { + /* NOTE: Change to GL_RGB for non alpha textures */ + glTexImage2D(GL_TEXTURE_2D, + 0, + (gdk_pixbuf_get_n_channels (priv->pixbuf) == 4) ? + GL_RGBA : GL_RGB, + next_p2(priv->width), + next_p2(priv->height), + 0, + priv->pixel_format, + priv->pixel_type, + NULL); + } + + glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, + priv->width, + priv->height, + priv->pixel_format, + priv->pixel_type, + gdk_pixbuf_get_pixels(priv->pixbuf)); + + return; + } + + /* Multiple tiled texture */ + + CLUTTER_DBG("syncing for multiple tiles for %ix%i pixbuf", + priv->width, priv->height); + + if (priv->tiles == NULL) + { + priv->tiles = g_new (GLuint, priv->n_x_tiles * priv->n_y_tiles); + glGenTextures (priv->n_x_tiles * priv->n_y_tiles, priv->tiles); + create_textures = TRUE; + } + + for (x=0; x < priv->n_x_tiles; x++) + for (y=0; y < priv->n_y_tiles; y++) + { + GdkPixbuf *pixtmp; + int src_h, src_w; + + src_w = priv->x_tiles[x].size; + src_h = priv->y_tiles[y].size; + + pixtmp + = gdk_pixbuf_new(GDK_COLORSPACE_RGB, + (gdk_pixbuf_get_n_channels (priv->pixbuf) == 4) ? + TRUE : FALSE, + 8, + priv->x_tiles[x].size, + priv->y_tiles[y].size); + + /* clip */ + if (priv->x_tiles[x].pos + src_w > priv->width) + { + src_w = priv->width - priv->x_tiles[x].pos; + } + + if (priv->y_tiles[y].pos + src_h > priv->height) + { + src_h = priv->height - priv->y_tiles[y].pos; + } + + CLUTTER_DBG("copying tile %i,%i - %ix%i to 0,0 %ix%i", + priv->x_tiles[x].pos, + priv->y_tiles[y].pos, + src_w, + src_h, + priv->x_tiles[x].size, + priv->y_tiles[y].size); + + gdk_pixbuf_copy_area(priv->pixbuf, + priv->x_tiles[x].pos, + priv->y_tiles[y].pos, + src_w, + src_h, + pixtmp, + 0,0); + +#ifdef CLUTTER_DUMP_TILES + { + gchar *filename; + + filename = g_strdup_printf("/tmp/%i-%i-%i.png", + clutter_element_get_id(CLUTTER_ELEMENT(texture)), + x, y); + printf("saving %s\n", filename); + gdk_pixbuf_save (pixtmp, filename , "png", NULL, NULL); + } +#endif + + glBindTexture(GL_TEXTURE_2D, priv->tiles[i]); + + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_WRAP_S, + priv->repeat_x ? GL_REPEAT : GL_CLAMP); + + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_WRAP_T, + priv->repeat_y ? GL_REPEAT : GL_CLAMP); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glPixelStorei (GL_UNPACK_ROW_LENGTH, gdk_pixbuf_get_width(pixtmp)); + glPixelStorei (GL_UNPACK_ALIGNMENT, + gdk_pixbuf_get_n_channels (priv->pixbuf)); + + if (create_textures) + { + + glTexImage2D(GL_TEXTURE_2D, + 0, + (gdk_pixbuf_get_n_channels (priv->pixbuf) == 4) ? + GL_RGBA : GL_RGB, + priv->x_tiles[x].size, + priv->y_tiles[y].size, + /* + gdk_pixbuf_get_width(pixtmp), + gdk_pixbuf_get_height(pixtmp), + */ + 0, + priv->pixel_format, + priv->pixel_type, + gdk_pixbuf_get_pixels(pixtmp)); + } + else + { + /* Textures already created, so just update whats inside + */ + glTexSubImage2D (GL_TEXTURE_2D, 0, + 0, 0, + priv->x_tiles[x].size, + priv->y_tiles[y].size, + /* + gdk_pixbuf_get_width(pixtmp), + gdk_pixbuf_get_height(pixtmp), + */ + priv->pixel_format, + priv->pixel_type, + gdk_pixbuf_get_pixels(pixtmp)); + } + + g_object_unref(pixtmp); + + i++; + } +} + +static void +clutter_texture_realize (ClutterElement *element) +{ + ClutterTexture *texture; + + texture = CLUTTER_TEXTURE(element); + + CLUTTER_MARK(); + + if (texture->priv->pixbuf == NULL) + { + /* Dont allow realization with no pixbuf */ + CLUTTER_DBG("*** Texture has no pixbuf cannot realize ***"); + CLUTTER_DBG("*** flags %i ***", element->flags); + CLUTTER_ELEMENT_UNSET_FLAGS (element, CLUTTER_ELEMENT_REALIZED); + CLUTTER_DBG("*** flags %i ***", element->flags); + return; + } + CLUTTER_DBG("Texture realized"); + + if (texture->priv->tiled) + init_tiles(texture); + + clutter_texture_sync_pixbuf (texture); +} + +static void +clutter_texture_show (ClutterElement *self) +{ + clutter_element_realize (self); +} + +static void +clutter_texture_hide (ClutterElement *self) +{ + clutter_element_unrealize (self); +} + +static void +clutter_texture_paint (ClutterElement *self) +{ + ClutterTexture *texture = CLUTTER_TEXTURE(self); + gint x1, y1, x2, y2; + + CLUTTER_DBG("@@@ for '%s' @@@", + clutter_element_get_name(self) ? + clutter_element_get_name(self) : "unknown"); + glPushMatrix(); + + glEnable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glColor4ub(255, 255, 255, clutter_element_get_opacity(self)); + + clutter_element_get_coords (self, &x1, &y1, &x2, &y2); + texture_render_to_gl_quad (texture, x1, y1, x2, y2); + + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + + glPopMatrix(); +} + +static void +clutter_texture_dispose (GObject *object) +{ + ClutterTexture *self = CLUTTER_TEXTURE(object); + ClutterTexturePrivate *priv; + + priv = self->priv; + + if (priv != NULL) + { + clutter_element_unrealize (CLUTTER_ELEMENT(self)); + + if (priv->pixbuf != NULL) + { + g_object_unref (priv->pixbuf); + priv->pixbuf = NULL; + } + } + + G_OBJECT_CLASS (clutter_texture_parent_class)->dispose (object); +} + +static void +clutter_texture_finalize (GObject *object) +{ + ClutterTexture *self = CLUTTER_TEXTURE(object); + + if (self->priv) + { + g_free(self->priv); + self->priv = NULL; + } + + G_OBJECT_CLASS (clutter_texture_parent_class)->finalize (object); +} + +static void +clutter_texture_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ClutterTexture *texture; + ClutterTexturePrivate *priv; + + texture = CLUTTER_TEXTURE(object); + priv = texture->priv; + + switch (prop_id) + { + case PROP_PIXBUF: + clutter_texture_set_pixbuf (texture, + (GdkPixbuf*)g_value_get_pointer(value)); + break; + case PROP_USE_TILES: + priv->tiled = g_value_get_boolean (value); + CLUTTER_DBG("Texture is tiled ? %i", priv->tiled); + break; + case PROP_MAX_TILE_WASTE: + priv->tile_max_waste = g_value_get_int (value); + break; + case PROP_PIXEL_TYPE: + priv->pixel_type = g_value_get_int (value); + break; + case PROP_PIXEL_FORMAT: + priv->pixel_format = g_value_get_int (value); + break; + case PROP_SYNC_SIZE: + priv->sync_element_size = g_value_get_boolean (value); + break; + case PROP_REPEAT_X: + priv->repeat_x = g_value_get_boolean (value); + break; + case PROP_REPEAT_Y: + priv->repeat_y = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +clutter_texture_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ClutterTexture *texture; + ClutterTexturePrivate *priv; + + texture = CLUTTER_TEXTURE(object); + priv = texture->priv; + + switch (prop_id) + { + case PROP_PIXBUF: + g_value_set_pointer (value, priv->pixbuf); + break; + case PROP_USE_TILES: + g_value_set_boolean (value, priv->tiled); + break; + case PROP_MAX_TILE_WASTE: + g_value_set_int (value, priv->tile_max_waste); + break; + case PROP_PIXEL_TYPE: + g_value_set_int (value, priv->pixel_type); + break; + case PROP_PIXEL_FORMAT: + g_value_set_int (value, priv->pixel_format); + break; + case PROP_SYNC_SIZE: + g_value_set_boolean (value, priv->sync_element_size); + break; + case PROP_REPEAT_X: + g_value_set_boolean (value, priv->repeat_x); + break; + case PROP_REPEAT_Y: + g_value_set_boolean (value, priv->repeat_y); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static void +clutter_texture_class_init (ClutterTextureClass *klass) +{ + GObjectClass *gobject_class; + ClutterElementClass *element_class; + + gobject_class = (GObjectClass*)klass; + element_class = (ClutterElementClass*)klass; + + element_class->paint = clutter_texture_paint; + element_class->realize = clutter_texture_realize; + element_class->unrealize = clutter_texture_unrealize; + element_class->show = clutter_texture_show; + element_class->hide = clutter_texture_hide; + + gobject_class->dispose = clutter_texture_dispose; + gobject_class->finalize = clutter_texture_finalize; + gobject_class->set_property = clutter_texture_set_property; + gobject_class->get_property = clutter_texture_get_property; + + g_object_class_install_property + (gobject_class, PROP_PIXBUF, + g_param_spec_pointer ("pixbuf", + "Pixbuf source for Texture.", + "Pixbuf source for Texture.", + G_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, PROP_USE_TILES, + g_param_spec_boolean ("tiled", + "Enable use of tiled textures", + "Enables the use of tiled GL textures to more " + "efficiently use available texture memory", + TRUE, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, PROP_SYNC_SIZE, + g_param_spec_boolean ("sync-size", + "Sync size of element", + "Auto sync size of element to underlying pixbuf" + "dimentions", + TRUE, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, PROP_REPEAT_X, + g_param_spec_boolean ("repeat-x", + "Tile underlying pixbuf in x direction", + "Reapeat underlying pixbuf rather than scale" + "in x direction", + FALSE, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, PROP_REPEAT_Y, + g_param_spec_boolean ("repeat-y", + "Tile underlying pixbuf in y direction", + "Reapeat underlying pixbuf rather than scale" + "in y direction", + FALSE, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + + /* FIXME: non working atm */ + g_object_class_install_property + (gobject_class, PROP_MAX_TILE_WASTE, + g_param_spec_int ("tile-waste", + "Tile dimention to waste", + "The maximum dimension of blank area we'll accept" + "in a pixmap. Bigger values use less textures, " + "smaller values less texture memory. ", + 0, + G_MAXINT, + 64, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, PROP_PIXEL_TYPE, + g_param_spec_int ("pixel-type", + "Texture Pixel Type", + "GL texture pixel type used", + 0, + G_MAXINT, + PIXEL_TYPE, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, PROP_PIXEL_FORMAT, + g_param_spec_int ("pixel-format", + "Texture pixel format", + "GL texture pixel format used", + 0, + G_MAXINT, + PIXEL_FORMAT, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + + + + + texture_signals[SIGNAL_SIZE_CHANGE] = + g_signal_new ("size-change", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterTextureClass, size_change), + NULL, NULL, + clutter_marshal_VOID__INT_INT, + G_TYPE_NONE, + 2, G_TYPE_INT, G_TYPE_INT); + + texture_signals[SIGNAL_PIXBUF_CHANGE] = + g_signal_new ("pixbuf-change", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterTextureClass, pixbuf_change), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + +} + +static void +clutter_texture_init (ClutterTexture *self) +{ + ClutterTexturePrivate *priv; + + priv = g_new0 (ClutterTexturePrivate, 1); + priv->pixbuf = NULL; + + self->priv = priv; +} + +/** + * clutter_texture_get_pixbuf + * @texture A #ClutterTexture + * + * Gets the underlying #GdkPixbuf for the #ClutterTexture + * + * Return value: The underlying #GdkPixbuf + **/ +GdkPixbuf* +clutter_texture_get_pixbuf (ClutterTexture* texture) +{ + return texture->priv->pixbuf; +} + +/** + * clutter_texture_set_pixbuf + * @texture A #ClutterTexture + * @pixbuf: A #GdkPixbuf + * + * Sets the underlying #GdkPixbuf for the #ClutterTexture + * + **/ +void +clutter_texture_set_pixbuf (ClutterTexture *texture, GdkPixbuf *pixbuf) +{ + ClutterTexturePrivate *priv; + gboolean texture_dirty = TRUE; + + priv = texture->priv; + + g_return_if_fail (pixbuf != NULL); + + if (priv->pixbuf != NULL) + { + texture_dirty = (gdk_pixbuf_get_width (pixbuf) + != gdk_pixbuf_get_width (priv->pixbuf) + || + gdk_pixbuf_get_height (pixbuf) + != gdk_pixbuf_get_height (priv->pixbuf) + || + gdk_pixbuf_get_n_channels (pixbuf) + != gdk_pixbuf_get_n_channels (priv->pixbuf)); + + g_object_unref(priv->pixbuf); + + /* If the actual pixbuf has changed size/format destroy + * existing textures ready for recreation. If + * size matches we can reuse. + */ + if (texture_dirty) + { + clutter_element_unrealize (CLUTTER_ELEMENT(texture)); + } + else + { + /* If texture realised sync things for change */ + if (CLUTTER_ELEMENT_IS_REALIZED(CLUTTER_ELEMENT(texture))) + { + priv->pixbuf = pixbuf; + + /* FIXME: better locking stratergy + */ + clutter_threads_enter(); + clutter_texture_sync_pixbuf (texture); + clutter_threads_leave(); + } + } + } + + clutter_threads_enter(); + + priv->pixbuf = pixbuf; + priv->width = gdk_pixbuf_get_width (pixbuf); + priv->height = gdk_pixbuf_get_height (pixbuf); + + g_object_ref (pixbuf); + + if (gdk_pixbuf_get_n_channels (pixbuf) == 3) + priv->pixel_format = GL_RGB; + else + priv->pixel_format = GL_RGBA; + + /* Force tiling if pixbuf is too big for single texture */ + if (priv->tiled == FALSE + && texture_dirty + && !can_create(next_p2(priv->width), next_p2(priv->height), + priv->pixel_format, priv->pixel_type)) + priv->tiled = TRUE; + clutter_threads_leave(); + + /* FIXME: for priv->tiled = FALSE textures, pixbuf could be + * format we dont like ( ie no alpha ). therfore + * we need to pixbuf_copy it into one that is. + * + * Actually I dont think this is worth worrying about... + * is non tiled textures are being used, texture data + * type can be set at initialisation. + */ + + /* reset set if element does not yet have size */ + /* FIXME: caller has to handle this via signal, OR + set prop so its always handled automatically OR + always happens and client can resize via signal + if (clutter_element_width (CLUTTER_ELEMENT(texture)) == 0 + || clutter_element_height (CLUTTER_ELEMENT(texture)) == 0) + */ + if (priv->sync_element_size) + clutter_element_set_size (CLUTTER_ELEMENT(texture), + priv->width, + priv->height); + + CLUTTER_DBG("set size %ix%i\n", priv->width, priv->height); + + if (texture_dirty) + g_signal_emit (texture, texture_signals[SIGNAL_SIZE_CHANGE], + 0, priv->width, priv->height); + + if (priv->tiled && texture_dirty) + init_tiles (texture); + + g_signal_emit (texture, texture_signals[SIGNAL_PIXBUF_CHANGE], 0); + + /* If resized element may need resizing but paint() will do this */ + if (CLUTTER_ELEMENT_IS_MAPPED (CLUTTER_ELEMENT(texture))) + clutter_element_queue_redraw (CLUTTER_ELEMENT(texture)); +} + +/** + * clutter_texture_new_from_pixbuf + * @pixbuf: A #GdkPixbuf + * + * Creates a new #ClutterTexture object. + * + * Return value: A newly created #ClutterTexture object. + **/ +ClutterElement* +clutter_texture_new_from_pixbuf (GdkPixbuf *pixbuf) +{ + ClutterTexture *texture; + + texture = g_object_new (CLUTTER_TYPE_TEXTURE, "pixbuf", pixbuf, NULL); + + return CLUTTER_ELEMENT(texture); +} + +/** + * clutter_texture_new + * + * Creates a new empty #ClutterTexture object. + * + * Return value: A newly created #ClutterTexture object. + **/ +ClutterElement* +clutter_texture_new (void) +{ + ClutterTexture *texture; + + texture = g_object_new (CLUTTER_TYPE_TEXTURE, NULL); + + return CLUTTER_ELEMENT(texture); +} + +/** + * clutter_texture_get_base_size + * @texture: A #ClutterTexture + * @width: Pointer to gint to be populated with width value if non NULL. + * @height: Pointer to gint to be populated with height value if non NULL. + * + * Gets the size in pixels of the untransformed underlying texture pixbuf data. + * + **/ +void +clutter_texture_get_base_size (ClutterTexture *texture, + gint *width, + gint *height) +{ + if (width) + *width = texture->priv->width; + + if (height) + *height = texture->priv->height; + +} + +/** + * clutter_texture_bind_tile + * @texture A #ClutterTexture + * @index: Tile index to bind + * + * Proxys a call to glBindTexture a to bind an internal 'tile'. + * + * This function is only useful for sub class implementations + * and never should be called by an application. + **/ +void +clutter_texture_bind_tile (ClutterTexture *texture, gint index) +{ + ClutterTexturePrivate *priv; + + priv = texture->priv; + glBindTexture(GL_TEXTURE_2D, priv->tiles[index]); +} + +/** + * clutter_texture_get_n_tiles + * @texture A #ClutterTexture + * @n_x_tiles: Location to store number of tiles in horizonally axis + * @n_y_tiles: Location to store number of tiles in vertical axis + * + * Retreives internal tile dimentioning. + * + * This function is only useful for sub class implementations + * and never should be called by an application. + **/ +void +clutter_texture_get_n_tiles (ClutterTexture *texture, + gint *n_x_tiles, + gint *n_y_tiles) +{ + if (n_x_tiles) + *n_x_tiles = texture->priv->n_x_tiles; + + if (n_y_tiles) + *n_y_tiles = texture->priv->n_y_tiles; + +} + +/** + * clutter_texture_get_x_tile_detail + * @texture A #ClutterTexture + * @x_index: X index of tile to query + * @pos: Location to store tiles X position + * @size: Location to store tiles horizontal size in pixels + * @waste: Location to store tiles horizontal wastage in pixels + * + * Retreives details of a tile on x axis. + * + * This function is only useful for sub class implementations + * and never should be called by an application. + **/ +void +clutter_texture_get_x_tile_detail (ClutterTexture *texture, + gint x_index, + gint *pos, + gint *size, + gint *waste) +{ + g_return_if_fail(x_index < texture->priv->n_x_tiles); + + if (pos) + *pos = texture->priv->x_tiles[x_index].pos; + + if (size) + *size = texture->priv->x_tiles[x_index].size; + + if (waste) + *waste = texture->priv->x_tiles[x_index].waste; +} + +/** + * clutter_texture_get_y_tile_detail + * @texture A #ClutterTexture + * @x_index: Y index of tile to query + * @pos: Location to store tiles Y position + * @size: Location to store tiles vertical size in pixels + * @waste: Location to store tiles vertical wastage in pixels + * + * Retreives details of a tile on y axis. + * + * This function is only useful for sub class implementations + * and never should be called by an application. + **/ +void +clutter_texture_get_y_tile_detail (ClutterTexture *texture, + gint y_index, + gint *pos, + gint *size, + gint *waste) +{ + g_return_if_fail(y_index < texture->priv->n_y_tiles); + + if (pos) + *pos = texture->priv->y_tiles[y_index].pos; + + if (size) + *size = texture->priv->y_tiles[y_index].size; + + if (waste) + *waste = texture->priv->y_tiles[y_index].waste; +} + +/** + * clutter_texture_has_generated_tiles + * @texture A #ClutterTexture + * + * Checks if #ClutterTexture has generated underlying GL texture tiles. + * + * This function is only useful for sub class implementations + * and never should be called by an application. + * + * Return value: TRUE if texture has pregenerated GL tiles. + **/ +gboolean +clutter_texture_has_generated_tiles (ClutterTexture *texture) +{ + return (texture->priv->tiles != NULL); +} + +/** + * clutter_texture_has_generated_tiles + * @texture A #ClutterTexture + * + * Checks if #ClutterTexture is tiled. + * + * This function is only useful for sub class implementations + * and never should be called by an application. + * + * Return value: TRUE if texture is tiled + **/ +gboolean +clutter_texture_is_tiled (ClutterTexture *texture) +{ + return texture->priv->tiled; +} diff --git a/clutter/clutter-texture.h b/clutter/clutter-texture.h new file mode 100644 index 000000000..0ab89f50c --- /dev/null +++ b/clutter/clutter-texture.h @@ -0,0 +1,127 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, 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 +#include +#include + +G_BEGIN_DECLS + +#define CLUTTER_TYPE_TEXTURE clutter_texture_get_type() + +#define CLUTTER_TEXTURE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + CLUTTER_TYPE_TEXTURE, ClutterTexture)) + +#define CLUTTER_TEXTURE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + CLUTTER_TYPE_TEXTURE, ClutterTextureClass)) + +#define CLUTTER_IS_TEXTURE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + CLUTTER_TYPE_TEXTURE)) + +#define CLUTTER_IS_TEXTURE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + CLUTTER_TYPE_TEXTURE)) + +#define CLUTTER_TEXTURE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + CLUTTER_TYPE_TEXTURE, ClutterTextureClass)) + +typedef struct ClutterTexturePrivate ClutterTexturePrivate ; +typedef struct _ClutterTexture ClutterTexture; +typedef struct _ClutterTextureClass ClutterTextureClass; + +struct _ClutterTexture +{ + ClutterElement parent; + + ClutterTexturePrivate *priv; +}; + +struct _ClutterTextureClass +{ + ClutterElementClass parent_class; + + void (*size_change) (ClutterTexture *texture, gint width, gint height); + void (*pixbuf_change) (ClutterTexture *texture ); +}; + +GType clutter_texture_get_type (void); + +ClutterElement* +clutter_texture_new_from_pixbuf (GdkPixbuf *pixbuf); + +ClutterElement* +clutter_texture_new (void); + +void +clutter_texture_set_pixbuf (ClutterTexture *texture, GdkPixbuf *pixbuf); + +GdkPixbuf* +clutter_texture_get_pixbuf (ClutterTexture* texture); + +void +clutter_texture_get_base_size (ClutterTexture *texture, + gint *width, + gint *height); + +/* Below mainly for subclassed texture based elements */ + +void +clutter_texture_bind_tile (ClutterTexture *texture, gint index); + +void +clutter_texture_get_n_tiles (ClutterTexture *texture, + gint *n_x_tiles, + gint *n_y_tiles); + +void +clutter_texture_get_x_tile_detail (ClutterTexture *texture, + gint x_index, + gint *pos, + gint *size, + gint *waste); + +void +clutter_texture_get_y_tile_detail (ClutterTexture *texture, + gint y_index, + gint *pos, + gint *size, + gint *waste); + +gboolean +clutter_texture_has_generated_tiles (ClutterTexture *texture); + +gboolean +clutter_texture_is_tiled (ClutterTexture *texture); + +G_END_DECLS + +#endif diff --git a/clutter/clutter-timeline.c b/clutter/clutter-timeline.c new file mode 100644 index 000000000..bcbf03f51 --- /dev/null +++ b/clutter/clutter-timeline.c @@ -0,0 +1,482 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "clutter-timeline.h" +#include "clutter-main.h" +#include "clutter-private.h" /* for DBG */ + +G_DEFINE_TYPE (ClutterTimeline, clutter_timeline, G_TYPE_OBJECT); + +#define FPS_TO_INTERVAL(f) (1000/f) + +struct ClutterTimelinePrivate +{ + guint timeout_id; + guint fps; + guint nframes; + guint current_frame_num; + gulong last_frame_msecs; + gulong start_frame_secs; + gboolean loop; +}; + +enum +{ + PROP_0, + PROP_FPS, + PROP_NFRAMES, + PROP_LOOP +}; + +enum +{ + SIGNAL_NEW_FRAME, + SIGNAL_COMPLETED, + LAST_SIGNAL +}; + +static int timeline_signals[LAST_SIGNAL] = { 0 }; + +static void +clutter_timeline_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ClutterTimeline *timeline; + ClutterTimelinePrivate *priv; + + timeline = CLUTTER_TIMELINE(object); + priv = timeline->priv; + + switch (prop_id) + { + case PROP_FPS: + clutter_timeline_set_speed (timeline, g_value_get_int (value)); + break; + case PROP_NFRAMES: + priv->nframes = g_value_get_int (value); + break; + case PROP_LOOP: + priv->loop = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +clutter_timeline_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ClutterTimeline *timeline; + ClutterTimelinePrivate *priv; + + timeline = CLUTTER_TIMELINE(object); + priv = timeline->priv; + + switch (prop_id) + { + case PROP_FPS: + g_value_set_int (value, priv->fps); + break; + case PROP_NFRAMES: + g_value_set_int (value, priv->nframes); + break; + case PROP_LOOP: + g_value_set_boolean (value, priv->loop); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +clutter_timeline_finalize (GObject *object) +{ + G_OBJECT_CLASS (clutter_timeline_parent_class)->finalize (object); +} + +static void +clutter_timeline_dispose (GObject *object) +{ + ClutterTimeline *self = CLUTTER_TIMELINE(object); + ClutterTimelinePrivate *priv; + + priv = self->priv; + + if (priv != NULL) + { + if (priv->timeout_id) + { + g_source_remove (priv->timeout_id); + priv->timeout_id = 0; + } + } + + G_OBJECT_CLASS (clutter_timeline_parent_class)->dispose (object); +} + + +static void +clutter_timeline_class_init (ClutterTimelineClass *klass) +{ + GObjectClass *object_class; + + object_class = (GObjectClass*) klass; + + object_class->set_property = clutter_timeline_set_property; + object_class->get_property = clutter_timeline_get_property; + object_class->finalize = clutter_timeline_finalize; + object_class->dispose = clutter_timeline_dispose; + + g_type_class_add_private (klass, sizeof (ClutterTimelinePrivate)); + + g_object_class_install_property + (object_class, PROP_FPS, + g_param_spec_int ("fps", + "Frames Per Second", + "Timeline frames per second", + 0, + 1000, + 50, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_NFRAMES, + g_param_spec_int ("num-frames", + "Total number of frames", + "Timelines total number of frames", + 0, + G_MAXINT, + 0, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_LOOP, + g_param_spec_boolean ("loop", + "Loop", + "Should the timeline automatically restart", + FALSE, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + + timeline_signals[SIGNAL_NEW_FRAME] = + g_signal_new ("new-frame", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterTimelineClass, new_frame), + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, + 1, G_TYPE_INT); + + timeline_signals[SIGNAL_COMPLETED] = + g_signal_new ("completed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterTimelineClass, completed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + +} + +static void +clutter_timeline_init (ClutterTimeline *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, + CLUTTER_TYPE_TIMELINE, + ClutterTimelinePrivate); +} + +static gboolean +timeline_timeout_func (gpointer data) +{ + ClutterTimeline *timeline = CLUTTER_TIMELINE(data); + ClutterTimelinePrivate *priv; + GTimeVal timeval; + gint nframes; + gulong msecs; + + priv = timeline->priv; + + /* Figure out potential frame skips */ + g_get_current_time (&timeval); + + /* Fire off signal */ + g_signal_emit (timeline, timeline_signals[SIGNAL_NEW_FRAME], + 0, priv->current_frame_num); + + /* Signal frees timeline ? */ + if (timeline == NULL) + return FALSE; + + /* Signal removes source ? */ + if (!priv->timeout_id) + { + clutter_timeline_stop (timeline); + return FALSE; + } + + if (priv->last_frame_msecs) + { + /* Check time diff from out last call and adjust number + * of frames to advance accordingly. + */ + msecs = ((timeval.tv_sec - priv->start_frame_secs) * 1000) + + (timeval.tv_usec / 1000); + nframes = (msecs - priv->last_frame_msecs ) / (1000 / priv->fps); + if (nframes < 0) nframes = 1; + + if (nframes > 1) + CLUTTER_DBG("*** Skipping %i frames ***", nframes); + } + else + { + /* First frame, set up timings.*/ + priv->start_frame_secs = timeval.tv_sec; + msecs = timeval.tv_usec / 1000; + nframes = 1; + } + + priv->last_frame_msecs = msecs; + + /* Advance frames */ + priv->current_frame_num += nframes;; + + /* Handle loop or stop */ + if (priv->current_frame_num > priv->nframes) + { + priv->current_frame_num = priv->nframes; + + if (nframes > 1) + g_signal_emit (timeline, timeline_signals[SIGNAL_NEW_FRAME], + 0, priv->current_frame_num); + + if (priv->loop) + clutter_timeline_rewind (timeline); + else + { + clutter_timeline_stop (timeline); + g_signal_emit (timeline, timeline_signals[SIGNAL_COMPLETED], 0); + return FALSE; + } + } + + return TRUE; +} + +/** + * clutter_timeline_start: + * @timeline: A #ClutterTimeline + * + * Starts the #ClutterTimeline playing. + **/ +void +clutter_timeline_start (ClutterTimeline *timeline) +{ + ClutterTimelinePrivate *priv; + + priv = timeline->priv; + + if (!priv->timeout_id) + priv->timeout_id = g_timeout_add (FPS_TO_INTERVAL(priv->fps), + timeline_timeout_func, + (gpointer)timeline); +} + +/** + * clutter_timeline_pause: + * @timeline: A #ClutterTimeline + * + * Pauses the #ClutterTimeline on current frame + **/ +void +clutter_timeline_pause (ClutterTimeline *timeline) +{ + g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); + + if (timeline->priv->timeout_id) + g_source_remove (timeline->priv->timeout_id); + + timeline->priv->timeout_id = 0; + timeline->priv->last_frame_msecs = 0; +} + +/** + * clutter_timeline_stop: + * @timeline: A #ClutterTimeline + * + * Stops the #ClutterTimeline and moves to frame 0 + **/ +void +clutter_timeline_stop (ClutterTimeline *timeline) +{ + clutter_timeline_pause (timeline); + clutter_timeline_rewind (timeline); +} + +void +clutter_timeline_set_loop (ClutterTimeline *timeline, gboolean loop) +{ + timeline->priv->loop = loop; +} + +/** + * clutter_timeline_rewind: + * @timeline: A #ClutterTimeline + * + * Rewinds #ClutterTimeline to frame 0. + **/ +void +clutter_timeline_rewind (ClutterTimeline *timeline) +{ + clutter_timeline_advance (timeline, 0); +} + +/** + * clutter_timeline_advance: + * @timeline: A #ClutterTimeline + * @nframes: Number of frames to skip + * + * Advance timeline by requested number of frames. + **/ +void +clutter_timeline_skip (ClutterTimeline *timeline, guint nframes) +{ + ClutterTimelinePrivate *priv; + + g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); + + priv = timeline->priv; + + priv->current_frame_num += nframes; + + if (priv->current_frame_num > priv->nframes) + priv->current_frame_num = 1; +} + +/** + * clutter_timeline_advance: + * @timeline: A #ClutterTimeline + * @frame_num: Frame number to advance to + * + * Advance timeline to requested frame number + **/ +void +clutter_timeline_advance (ClutterTimeline *timeline, guint frame_num) +{ + ClutterTimelinePrivate *priv; + + g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); + + priv = timeline->priv; + + if (frame_num < priv->nframes) + priv->current_frame_num = frame_num; +} + +/** + * clutter_timeline_get_current_frame: + * @timeline: A #ClutterTimeline + * + * Request the current frame number of the timeline. + * + * Return Value: current frame number + **/ +gint +clutter_timeline_get_current_frame (ClutterTimeline *timeline) +{ + g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0); + + return timeline->priv->current_frame_num; +} + +/** + * clutter_timeline_get_n_frames: + * @timeline: A #ClutterTimeline + * + * Request the totle number of frames for the #ClutterTimeline. + * + * Return Value: Number of frames for this #ClutterTimeline. + **/ +guint +clutter_timeline_get_n_frames (ClutterTimeline *timeline) +{ + g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0); + + return timeline->priv->nframes; +} + +/** + * clutter_timeline_get_current_frame: + * @timeline: A #ClutterTimeline + * @fps: New speed of timeline as frames per second + * + * Set the speed in frames per second of the timeline. + **/ +void +clutter_timeline_set_speed (ClutterTimeline *timeline, guint fps) +{ + ClutterTimelinePrivate *priv; + + g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); + + priv = timeline->priv; + + priv->fps = fps; + + /* if the timeline is playing restart */ + if (priv->timeout_id) + { + g_source_remove (priv->timeout_id); + priv->timeout_id = g_timeout_add (FPS_TO_INTERVAL(priv->fps), + timeline_timeout_func, + (gpointer)timeline); + } +} + +/** + * clutter_timeline_new: + * @nframes: #ClutterTimeline number of frames + * @fps: #ClutterTimeline frames per second + * + * Create a new #ClutterTimeline instance. + * + * Return Value: a new #ClutterTimeline + */ +ClutterTimeline * +clutter_timeline_new (guint nframes, + guint fps) +{ + return g_object_new (CLUTTER_TYPE_TIMELINE, + "fps", fps, + "num-frames", nframes, + NULL); +} diff --git a/clutter/clutter-timeline.h b/clutter/clutter-timeline.h new file mode 100644 index 000000000..96043233e --- /dev/null +++ b/clutter/clutter-timeline.h @@ -0,0 +1,112 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, 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 + +G_BEGIN_DECLS + +#define CLUTTER_TYPE_TIMELINE clutter_timeline_get_type() + +#define CLUTTER_TIMELINE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + CLUTTER_TYPE_TIMELINE, ClutterTimeline)) + +#define CLUTTER_TIMELINE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + CLUTTER_TYPE_TIMELINE, ClutterTimelineClass)) + +#define CLUTTER_IS_TIMELINE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + CLUTTER_TYPE_TIMELINE)) + +#define CLUTTER_IS_TIMELINE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + CLUTTER_TYPE_TIMELINE)) + +#define CLUTTER_TIMELINE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + CLUTTER_TYPE_TIMELINE, ClutterTimelineClass)) + +typedef struct _ClutterTimeline ClutterTimeline; +typedef struct _ClutterTimelineClass ClutterTimelineClass; +typedef struct ClutterTimelinePrivate ClutterTimelinePrivate; + +struct _ClutterTimeline +{ + GObject parent; + ClutterTimelinePrivate *priv; +}; + +struct _ClutterTimelineClass +{ + GObjectClass parent_class; + + void (*new_frame) (ClutterTimeline *timeline, gint frame_num); + void (*completed) (ClutterTimeline *timeline); +}; + +GType clutter_timeline_get_type (void); + +ClutterTimeline* +clutter_timeline_new (guint nframes, guint fps); + +void +clutter_timeline_set_speed (ClutterTimeline *timeline, guint fps); + +void +clutter_timeline_start (ClutterTimeline *timeline); + +void +clutter_timeline_pause (ClutterTimeline *timeline); + +void +clutter_timeline_stop (ClutterTimeline *timeline); + +void +clutter_timeline_set_loop (ClutterTimeline *timeline, gboolean loop); + +void +clutter_timeline_rewind (ClutterTimeline *timeline); + +void +clutter_timeline_skip (ClutterTimeline *timeline, guint nframes); + +void +clutter_timeline_advance (ClutterTimeline *timeline, guint frame_num); + +gint +clutter_timeline_get_current_frame (ClutterTimeline *timeline); + +guint +clutter_timeline_get_n_frames (ClutterTimeline *timeline); + +G_END_DECLS + +#endif diff --git a/clutter/clutter-util.c b/clutter/clutter-util.c new file mode 100644 index 000000000..2b9deb409 --- /dev/null +++ b/clutter/clutter-util.c @@ -0,0 +1,55 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "clutter-util.h" +#include "clutter-main.h" + +int +clutter_util_next_p2 (int a) +{ + int rval=1; + + while(rval < a) + rval <<= 1; + + return rval; +} + +#if 0 +gboolean +clutter_util_can_create_texture (int width, int height) +{ + GLint new_width; + + glTexImage2D (GL_PROXY_VIDEO_TEXTURE_2D, 0, GL_RGBA, + width, height, 0 /* border */, + GL_RGBA, PIXEL_TYPE, NULL); + + glGetTexLevelParameteriv (GL_PROXY_VIDEO_TEXTURE_2D, 0, + GL_VIDEO_TEXTURE_WIDTH, &new_width); + + return new_width != 0; +} +#endif diff --git a/clutter/clutter-util.h b/clutter/clutter-util.h new file mode 100644 index 000000000..9a4d61e88 --- /dev/null +++ b/clutter/clutter-util.h @@ -0,0 +1,41 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, 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 + +G_BEGIN_DECLS + +int +clutter_util_next_p2 (int a); + +gboolean +clutter_util_can_create_texture (int width, int height); + +G_END_DECLS + +#endif diff --git a/clutter/clutter-video-texture.c b/clutter/clutter-video-texture.c new file mode 100644 index 000000000..a2fa630d5 --- /dev/null +++ b/clutter/clutter-video-texture.c @@ -0,0 +1,1853 @@ +/* Heavily based on totems bacon-video-widget .. */ + +#include "clutter-video-texture.h" +#include "clutter-main.h" +#include "clutter-private.h" /* for DBG */ +#include "clutter-marshal.h" + +#include +#include +#include + +#include +#include + +#include + +static void +got_time_tick (GstElement *play, + gint64 time_nanos, + ClutterVideoTexture *video_texture); +static void +stop_play_pipeline (ClutterVideoTexture *video_texture); + +G_DEFINE_TYPE (ClutterVideoTexture, \ + clutter_video_texture, \ + CLUTTER_TYPE_TEXTURE); + +enum +{ + SIGNAL_ERROR, + SIGNAL_EOS, + SIGNAL_REDIRECT, + SIGNAL_TITLE_CHANGE, + SIGNAL_CHANNELS_CHANGE, + SIGNAL_TICK, + SIGNAL_GOT_METADATA, + SIGNAL_BUFFERING, + SIGNAL_SPEED_WARNING, + LAST_SIGNAL +}; + +/* Properties */ +enum +{ + PROP_0, + PROP_POSITION, + PROP_CURRENT_TIME, + PROP_STREAM_LENGTH, + PROP_PLAYING, + PROP_SEEKABLE, +}; + +struct ClutterVideoTexturePrivate +{ + GstElement *play, *video_sink, *audio_sink; + gboolean has_video, has_audio; + gint64 stream_length; + gint64 current_time_nanos; + gint64 current_time; + float current_position; + gchar *mrl; + + gboolean got_redirect; + gint eos_id; + guint update_id; + + GstTagList *tagcache, *audiotags, *videotags; + + const GValue *movie_par; /* Movie pixel aspect ratio */ + gint video_fps_d, video_fps_n; + gint video_width, video_height; + ClutterVideoTextureAspectRatio ratio_type; + + GstMessageType ignore_messages_mask; + GstBus *bus; + gulong sig_bus_async; +}; + +static int cvt_signals[LAST_SIGNAL] = { 0 }; + +GQuark +clutter_video_texture_error_quark (void) +{ + return g_quark_from_static_string ("clutter-video-texture-error-quark"); +} + +/* This is a hack to avoid doing poll_for_state_change() indirectly + * from the bus message callback (via EOS => totem => close => wait for READY) + * and deadlocking there. We need something like a + * gst_bus_set_auto_flushing(bus, FALSE) ... */ +static gboolean +signal_eos_delayed (gpointer user_data) +{ + ClutterVideoTexture *video_texture = (ClutterVideoTexture*)user_data; + + g_signal_emit (video_texture, cvt_signals[SIGNAL_EOS], 0, NULL); + + video_texture->priv->eos_id = 0; + + return FALSE; +} + +static gboolean +query_timeout (ClutterVideoTexture *video_texture) +{ + ClutterVideoTexturePrivate *priv; + GstFormat fmt = GST_FORMAT_TIME; + gint64 prev_len = -1, pos = -1, len = -1; + + priv = video_texture->priv; + + /* check length/pos of stream */ + prev_len = priv->stream_length; + + if (gst_element_query_duration (priv->play, &fmt, &len)) + { + if (len != -1 && fmt == GST_FORMAT_TIME) + { + priv->stream_length = len / GST_MSECOND; + if (priv->stream_length != prev_len) + { + g_signal_emit (video_texture, + cvt_signals[SIGNAL_GOT_METADATA], 0, NULL); + } + } + } + else + { + CLUTTER_DBG ("could not get duration"); + } + + if (gst_element_query_position (priv->play, &fmt, &pos)) + { + if (pos != -1 && fmt == GST_FORMAT_TIME) + { + got_time_tick (GST_ELEMENT (priv->play), pos, video_texture); + } + } + else + CLUTTER_DBG ("could not get position"); + + return TRUE; +} + +static void +got_video_size (ClutterVideoTexture *video_texture) +{ + GstMessage *msg; + + g_return_if_fail (video_texture != NULL); + + /* Do we even care about this info as comes from texture sizing ? */ + CLUTTER_DBG("%ix%i", + video_texture->priv->video_width, + video_texture->priv->video_height); + + msg = gst_message_new_application + (GST_OBJECT (video_texture->priv->play), + gst_structure_new ("video-size", + "width", G_TYPE_INT, + video_texture->priv->video_width, + "height", G_TYPE_INT, + video_texture->priv->video_height, NULL)); + + gst_element_post_message (video_texture->priv->play, msg); +} + + +static void +caps_set (GObject *obj, + GParamSpec *pspec, + ClutterVideoTexture *video_texture) +{ + ClutterVideoTexturePrivate *priv; + GstPad *pad = GST_PAD (obj); + GstStructure *s; + GstCaps *caps; + + priv = video_texture->priv; + + if (!(caps = gst_pad_get_negotiated_caps (pad))) + return; + + /* Get video decoder caps */ + s = gst_caps_get_structure (caps, 0); + + /* Again do we even need this - sizing info from texture signal.. */ + + if (s) + { + /* We need at least width/height and framerate */ + if (!(gst_structure_get_fraction (s, "framerate", + &priv->video_fps_n, + &priv->video_fps_d) + && + gst_structure_get_int (s, "width", &priv->video_width) && + gst_structure_get_int (s, "height", &priv->video_height))) + return; + + /* Get the movie PAR if available */ + priv->movie_par = gst_structure_get_value (s, "pixel-aspect-ratio"); + + /* Now set for real */ + clutter_video_texture_set_aspect_ratio (video_texture, priv->ratio_type); + } + + gst_caps_unref (caps); +} + +static void +parse_stream_info (ClutterVideoTexture *video_texture) +{ + ClutterVideoTexturePrivate *priv; + GList *streaminfo = NULL; + GstPad *videopad = NULL; + + priv = video_texture->priv; + + g_object_get (priv->play, "stream-info", &streaminfo, NULL); + + streaminfo = g_list_copy (streaminfo); + + g_list_foreach (streaminfo, (GFunc) g_object_ref, NULL); + + for ( ; streaminfo != NULL; streaminfo = streaminfo->next) + { + GObject *info = streaminfo->data; + gint type; + GParamSpec *pspec; + GEnumValue *val; + + if (!info) + continue; + + g_object_get (info, "type", &type, NULL); + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (info), "type"); + val = g_enum_get_value (G_PARAM_SPEC_ENUM (pspec)->enum_class, type); + + if (!g_strcasecmp (val->value_nick, "audio")) + { + priv->has_audio = TRUE; + } + else if (!g_strcasecmp (val->value_nick, "video")) + { + priv->has_video = TRUE; + + if (!videopad) + g_object_get (info, "object", &videopad, NULL); + } + } + + if (videopad) + { + GstCaps *caps; + + if ((caps = gst_pad_get_negotiated_caps (videopad))) + { + caps_set (G_OBJECT (videopad), NULL, video_texture); + gst_caps_unref (caps); + } + + g_signal_connect (videopad, "notify::caps", + G_CALLBACK (caps_set), video_texture); + } + + g_list_foreach (streaminfo, (GFunc) g_object_unref, NULL); + g_list_free (streaminfo); +} + +static void +handle_element_message (ClutterVideoTexture *video_texture, GstMessage *msg) +{ + const gchar *type_name = NULL; + gchar *src_name; + + CLUTTER_MARK(); + + src_name = gst_object_get_name (msg->src); + + if (msg->structure) + type_name = gst_structure_get_name (msg->structure); + + if (type_name == NULL) + goto unhandled; + + if (strcmp (type_name, "redirect") == 0) + { + const gchar *new_location; + + new_location = gst_structure_get_string (msg->structure, "new-location"); + + CLUTTER_DBG ("Got redirect to '%s'", GST_STR_NULL (new_location)); + + if (new_location && *new_location) + { + g_signal_emit (video_texture, + cvt_signals[SIGNAL_REDIRECT], + 0, + new_location); + goto done; + } + } + + unhandled: + CLUTTER_DBG ("Unhandled element message '%s' from element '%s'", + GST_STR_NULL (type_name), src_name); + done: + g_free (src_name); +} + +static void +handle_application_message (ClutterVideoTexture *video_texture, + GstMessage *msg) +{ + const gchar *msg_name; + + msg_name = gst_structure_get_name (msg->structure); + + g_return_if_fail (msg_name != NULL); + + CLUTTER_DBG ("Handling application message"); + + if (strcmp (msg_name, "notify-streaminfo") == 0) + { + g_signal_emit (video_texture, cvt_signals[SIGNAL_GOT_METADATA], 0, NULL); + g_signal_emit (video_texture, cvt_signals[SIGNAL_CHANNELS_CHANGE], 0); + } + else if (strcmp (msg_name, "video-size") == 0) + { + g_signal_emit (video_texture, cvt_signals[SIGNAL_GOT_METADATA], 0, NULL); + + CLUTTER_DBG("Got video size"); + } + else + CLUTTER_DBG ("Unhandled application message %s", msg_name); +} + +static void +bus_message_cb (GstBus *bus, GstMessage *message, gpointer data) +{ + ClutterVideoTexturePrivate *priv; + ClutterVideoTexture *video_texture = (ClutterVideoTexture*)data; + GstMessageType msg_type; + + g_return_if_fail (video_texture != NULL); + g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE(video_texture)); + + priv = video_texture->priv; + + msg_type = GST_MESSAGE_TYPE (message); + + /* somebody else is handling the message, + probably in poll_for_state_change */ + if (priv->ignore_messages_mask & msg_type) + { + gchar *src_name = gst_object_get_name (message->src); + CLUTTER_DBG ("Ignoring %s message from element %s as requested", + gst_message_type_get_name (msg_type), src_name); + g_free (src_name); + return; + } + + if (msg_type != GST_MESSAGE_STATE_CHANGED && clutter_want_debug()) + { + gchar *src_name = gst_object_get_name (message->src); + CLUTTER_DBG ("Handling %s message from element %s", + gst_message_type_get_name (msg_type), src_name); + g_free (src_name); + } + + switch (msg_type) + { + case GST_MESSAGE_ERROR: + { + GError *error = NULL; + gchar *debug = NULL; + + gst_message_parse_error (message, &error, &debug); + + CLUTTER_DBG ("Error message: %s [%s]", + GST_STR_NULL (error->message), + GST_STR_NULL (debug)); + + g_signal_emit (video_texture, + cvt_signals[SIGNAL_ERROR], + 0, + error->message, + TRUE, + FALSE); + + g_error_free (error); + + if (priv->play) + gst_element_set_state (priv->play, GST_STATE_NULL); + + g_free (debug); + break; + } + case GST_MESSAGE_WARNING: + { + GError *error = NULL; + gchar *debug = NULL; + + gst_message_parse_warning (message, &error, &debug); + + g_warning ("%s [%s]", + GST_STR_NULL (error->message), + GST_STR_NULL (debug)); + + g_error_free (error); + g_free (debug); + break; + } + case GST_MESSAGE_TAG: + { + GstTagList *tag_list, *result; + GstElementFactory *f; + + gst_message_parse_tag (message, &tag_list); + + CLUTTER_DBG ("Tags: %p", tag_list); + + /* all tags */ + result = gst_tag_list_merge (priv->tagcache, + tag_list, + GST_TAG_MERGE_KEEP); + + if (priv->tagcache) + gst_tag_list_free (priv->tagcache); + priv->tagcache = result; + + /* media-type-specific tags */ + if (GST_IS_ELEMENT (message->src) && + (f = gst_element_get_factory (GST_ELEMENT (message->src)))) + { + const gchar *klass = gst_element_factory_get_klass (f); + GstTagList **cache = NULL; + + if (g_strrstr (klass, "Video")) + { + cache = &priv->videotags; + } + else if (g_strrstr (klass, "Audio")) + { + cache = &priv->audiotags; + } + + if (cache) + { + result = gst_tag_list_merge (*cache, tag_list, + GST_TAG_MERGE_KEEP); + if (*cache) + gst_tag_list_free (*cache); + *cache = result; + } + } + + gst_tag_list_free (tag_list); + g_signal_emit (video_texture, cvt_signals[SIGNAL_GOT_METADATA], 0); + break; + } + case GST_MESSAGE_EOS: + CLUTTER_DBG ("GST_MESSAGE_EOS"); + + if (priv->eos_id == 0) + priv->eos_id = g_idle_add (signal_eos_delayed, video_texture); + break; + case GST_MESSAGE_BUFFERING: + { + gint percent = 0; + gst_structure_get_int (message->structure, "buffer-percent", &percent); + + CLUTTER_DBG ("Buffering message (%u%%)", percent); + + g_signal_emit (video_texture, + cvt_signals[SIGNAL_BUFFERING], + 0, + percent); + break; + } + + case GST_MESSAGE_APPLICATION: + handle_application_message (video_texture, message); + break; + + case GST_MESSAGE_STATE_CHANGED: + { + GstState old_state, new_state; + gchar *src_name; + + CLUTTER_DBG ("GST_MESSAGE_STATE_CHANGED"); + + gst_message_parse_state_changed (message, + &old_state, &new_state, NULL); + + if (old_state == new_state) + break; + + /* we only care about playbin (pipeline) state changes */ + if (GST_MESSAGE_SRC (message) != GST_OBJECT (priv->play)) + break; + + src_name = gst_object_get_name (message->src); + + CLUTTER_DBG ("%s changed state from %s to %s", src_name, + gst_element_state_get_name (old_state), + gst_element_state_get_name (new_state)); + + g_free (src_name); + + if (new_state <= GST_STATE_PAUSED) + { + if (priv->update_id != 0) + { + CLUTTER_DBG ("removing tick timeout"); + g_source_remove (priv->update_id); + priv->update_id = 0; + } + } + else if (new_state > GST_STATE_PAUSED) + { + if (priv->update_id == 0) + { + CLUTTER_DBG ("starting tick timeout"); + + priv->update_id = g_timeout_add (200, + (GSourceFunc) query_timeout, + video_texture); + } + } + + if (old_state == GST_STATE_READY && new_state == GST_STATE_PAUSED) + { + parse_stream_info (video_texture); + } + else if (old_state == GST_STATE_PAUSED && new_state == GST_STATE_READY) + { + priv->has_video = FALSE; + priv->has_audio = FALSE; + + /* clean metadata cache */ + if (priv->tagcache) + { + gst_tag_list_free (priv->tagcache); + priv->tagcache = NULL; + } + + if (priv->audiotags) + { + gst_tag_list_free (priv->audiotags); + priv->audiotags = NULL; + } + + if (priv->videotags) + { + gst_tag_list_free (priv->videotags); + priv->videotags = NULL; + } + + priv->video_width = 0; + priv->video_height = 0; + } + break; + } + + case GST_MESSAGE_ELEMENT: + handle_element_message (video_texture, message); + break; + + case GST_MESSAGE_DURATION: + { + CLUTTER_DBG ("GST_MESSAGE_DURATION"); + /* force _get_stream_length() to do new duration query */ + priv->stream_length = 0; + if (clutter_video_texture_get_stream_length (video_texture) == 0) + CLUTTER_DBG ("Failed to query duration after DURATION message?!"); + break; + } + + case GST_MESSAGE_CLOCK_PROVIDE: + case GST_MESSAGE_CLOCK_LOST: + case GST_MESSAGE_NEW_CLOCK: + case GST_MESSAGE_STATE_DIRTY: + break; + default: + CLUTTER_DBG ("Unhandled message of type '%s' (0x%x)", + gst_message_type_get_name (msg_type), msg_type); + break; + } +} + +static void +got_time_tick (GstElement *play, + gint64 time_nanos, + ClutterVideoTexture *video_texture) +{ + gboolean seekable; + ClutterVideoTexturePrivate *priv; + + g_return_if_fail (video_texture != NULL); + g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE(video_texture)); + + priv = video_texture->priv; + + priv->current_time_nanos = time_nanos; + priv->current_time = (gint64) time_nanos / GST_MSECOND; + + if (priv->stream_length == 0) + { + priv->current_position = 0; + seekable = clutter_video_texture_is_seekable (video_texture); + } + else + { + priv->current_position = + (gfloat) priv->current_time / priv->stream_length; + seekable = TRUE; + } + + g_signal_emit (video_texture, + cvt_signals[SIGNAL_TICK], + 0, + priv->current_time, + priv->stream_length, + priv->current_position, + seekable); +} + +static void +playbin_got_source (GObject *play, + GParamSpec *pspec, + ClutterVideoTexture *video_texture) +{ + /* Called via notify::source on playbin */ + + ClutterVideoTexturePrivate *priv; + GObject *source = NULL; + + priv = video_texture->priv; + + if (priv->tagcache) + { + gst_tag_list_free (priv->tagcache); + priv->tagcache = NULL; + } + + if (priv->audiotags) + { + gst_tag_list_free (priv->audiotags); + priv->audiotags = NULL; + } + + if (priv->videotags) + { + gst_tag_list_free (priv->videotags); + priv->videotags = NULL; + } + + g_object_get (play, "source", &source, NULL); + + if (!source) + return; + + g_object_unref (source); +} + +static void +playbin_stream_info_set (GObject *obj, + GParamSpec *pspec, + ClutterVideoTexture *video_texture) +{ + ClutterVideoTexturePrivate *priv; + GstMessage *msg; + + priv = video_texture->priv; + + parse_stream_info (video_texture); + + msg = gst_message_new_application (GST_OBJECT (priv->play), + gst_structure_new ("notify-streaminfo", + NULL)); + gst_element_post_message (priv->play, msg); +} + + +static gboolean +poll_for_state_change_full (ClutterVideoTexture *video_texture, + GstElement *element, + GstState state, + GError **error, + gint64 timeout) +{ + GstBus *bus; + GstMessageType events, saved_events; + ClutterVideoTexturePrivate *priv; + + priv = video_texture->priv; + bus = gst_element_get_bus (element); + saved_events = priv->ignore_messages_mask; + + events = GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS; + + if (element != NULL && element == priv->play) + { + /* we do want the main handler to process state changed messages for + * playbin as well, otherwise it won't hook up the timeout etc. */ + priv->ignore_messages_mask |= (events ^ GST_MESSAGE_STATE_CHANGED); + } + else + priv->ignore_messages_mask |= events; + + while (TRUE) + { + GstMessage *message; + GstElement *src; + + message = gst_bus_poll (bus, events, timeout); + + if (!message) + goto timed_out; + + src = (GstElement*)GST_MESSAGE_SRC (message); + + switch (GST_MESSAGE_TYPE (message)) + { + case GST_MESSAGE_STATE_CHANGED: + { + GstState old, new, pending; + + if (src == element) + { + gst_message_parse_state_changed (message, + &old, &new, &pending); + if (new == state) + { + gst_message_unref (message); + goto success; + } + } + } + break; + case GST_MESSAGE_ERROR: + { + gchar *debug = NULL; + GError *gsterror = NULL; + + gst_message_parse_error (message, &gsterror, &debug); + + g_warning ("Error: %s (%s)", gsterror->message, debug); + + gst_message_unref (message); + g_error_free (gsterror); + g_free (debug); + goto error; + } + break; + case GST_MESSAGE_EOS: + g_set_error (error, CLUTTER_VIDEO_TEXTURE_ERROR, + CLUTTER_VIDEO_TEXTURE_ERROR_FILE_GENERIC, + "Media file could not be played."); + gst_message_unref (message); + goto error; + break; + default: + g_assert_not_reached (); + break; + } + gst_message_unref (message); + } + + g_assert_not_reached (); + +success: + /* state change succeeded */ + CLUTTER_DBG ("state change to %s succeeded", + gst_element_state_get_name (state)); + + priv->ignore_messages_mask = saved_events; + return TRUE; + +timed_out: + /* it's taking a long time to open -- just tell totem it was ok, this allows + * the user to stop the loading process with the normal stop button */ + CLUTTER_DBG ("state change to %s timed out, returning success and handling " + "errors asynchroneously", gst_element_state_get_name (state)); + priv->ignore_messages_mask = saved_events; + return TRUE; + +error: + CLUTTER_DBG ("error while waiting for state change to %s: %s", + gst_element_state_get_name (state), + (error && *error) ? (*error)->message : "unknown"); + priv->ignore_messages_mask = saved_events; + return FALSE; +} + +static gboolean +poll_for_state_change (ClutterVideoTexture *video_texture, + GstElement *element, + GstState state, + GError **error) +{ + return poll_for_state_change_full (video_texture, + element, + state, + error, + GST_SECOND/4 ); +} + +static void +fakesink_handoff_cb (GstElement *fakesrc, + GstBuffer *buffer, + GstPad *pad, + gpointer user_data) +{ + + GstStructure *structure; + int width, height; + GdkPixbuf *pixb; + + structure = gst_caps_get_structure(GST_CAPS(buffer->caps), 0); + gst_structure_get_int(structure, "width", &width); + gst_structure_get_int(structure, "height", &height); + + /* FIXME: We really dont want to do this every time as gobject creation + * really need a clutter_texture_set_from_data call ? + */ + pixb = gdk_pixbuf_new_from_data (GST_BUFFER_DATA (buffer), + GDK_COLORSPACE_RGB, + FALSE, + 8, + width, + height, + (3 * width + 3) &~ 3, + NULL, + NULL); + + if (pixb) + { + clutter_texture_set_pixbuf (CLUTTER_TEXTURE(user_data), pixb); + g_object_unref(G_OBJECT(pixb)); + } +} + +static void +clutter_video_texture_finalize (GObject *object) +{ + ClutterVideoTexture *self; + ClutterVideoTexturePrivate *priv; + + self = CLUTTER_VIDEO_TEXTURE(object); + priv = self->priv; + + if (priv->bus) + { + /* make bus drop all messages to make sure none of our callbacks is ever + * called again (main loop might be run again to display error dialog) */ + gst_bus_set_flushing (priv->bus, TRUE); + + if (priv->sig_bus_async) + g_signal_handler_disconnect (priv->bus, priv->sig_bus_async); + + gst_object_unref (priv->bus); + priv->bus = NULL; + } + + if (priv->mrl) + g_free (priv->mrl); + priv->mrl = NULL; + + if (priv->play != NULL && GST_IS_ELEMENT (priv->play)) + { + gst_element_set_state (priv->play, GST_STATE_NULL); + gst_object_unref (priv->play); + priv->play = NULL; + } + + if (priv->update_id) + { + g_source_remove (priv->update_id); + priv->update_id = 0; + } + + if (priv->tagcache) + { + gst_tag_list_free (priv->tagcache); + priv->tagcache = NULL; + } + + if (priv->audiotags) + { + gst_tag_list_free (priv->audiotags); + priv->audiotags = NULL; + } + + if (priv->videotags) + { + gst_tag_list_free (priv->videotags); + priv->videotags = NULL; + } + + if (priv->eos_id != 0) + g_source_remove (priv->eos_id); + + g_free (priv); + + self->priv = NULL; + + G_OBJECT_CLASS (clutter_video_texture_parent_class)->finalize (object); +} + +static void +clutter_video_texture_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +clutter_video_texture_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + ClutterVideoTexture *video_texture; + + video_texture = CLUTTER_VIDEO_TEXTURE (object); + + switch (property_id) + { + case PROP_POSITION: + g_value_set_int64 (value, + clutter_video_texture_get_position (video_texture)); + break; + case PROP_STREAM_LENGTH: + g_value_set_int64 (value, + clutter_video_texture_get_stream_length (video_texture)); + break; + case PROP_PLAYING: + g_value_set_boolean (value, + clutter_video_texture_is_playing (video_texture)); + break; + case PROP_SEEKABLE: + g_value_set_boolean (value, + clutter_video_texture_is_seekable (video_texture)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + + +static void +clutter_video_texture_class_init (ClutterVideoTextureClass *klass) +{ + GObjectClass *object_class; + ClutterElementClass *element_class; + + object_class = (GObjectClass*)klass; + element_class = (ClutterElementClass*)klass; + + object_class->finalize = clutter_video_texture_finalize; + object_class->set_property = clutter_video_texture_set_property; + object_class->get_property = clutter_video_texture_get_property; + + /* Properties */ + g_object_class_install_property (object_class, PROP_POSITION, + g_param_spec_int ("position", NULL, NULL, + 0, G_MAXINT, 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_STREAM_LENGTH, + g_param_spec_int64 ("stream_length", NULL, + NULL, 0, G_MAXINT64, 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_PLAYING, + g_param_spec_boolean ("playing", NULL, + NULL, FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_SEEKABLE, + g_param_spec_boolean ("seekable", NULL, + NULL, FALSE, + G_PARAM_READABLE)); + + /* Signals */ + cvt_signals[SIGNAL_ERROR] = + g_signal_new ("error", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterVideoTextureClass, error), + NULL, NULL, + clutter_marshal_VOID__STRING_BOOLEAN_BOOLEAN, + G_TYPE_NONE, 3, G_TYPE_STRING, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN); + + cvt_signals[SIGNAL_EOS] = + g_signal_new ("eos", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterVideoTextureClass, eos), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + cvt_signals[SIGNAL_GOT_METADATA] = + g_signal_new ("got-metadata", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterVideoTextureClass, got_metadata), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + cvt_signals[SIGNAL_REDIRECT] = + g_signal_new ("got-redirect", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterVideoTextureClass, got_redirect), + NULL, NULL, g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + + cvt_signals[SIGNAL_TITLE_CHANGE] = + g_signal_new ("title-change", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterVideoTextureClass, title_change), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + + cvt_signals[SIGNAL_CHANNELS_CHANGE] = + g_signal_new ("channels-change", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterVideoTextureClass, channels_change), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + cvt_signals[SIGNAL_TICK] = + g_signal_new ("tick", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterVideoTextureClass, tick), + NULL, NULL, + clutter_marshal_VOID__INT64_INT64_FLOAT_BOOLEAN, + G_TYPE_NONE, 4, G_TYPE_INT64, G_TYPE_INT64, G_TYPE_FLOAT, + G_TYPE_BOOLEAN); + + cvt_signals[SIGNAL_BUFFERING] = + g_signal_new ("buffering", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterVideoTextureClass, buffering), + NULL, NULL, + g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + + cvt_signals[SIGNAL_SPEED_WARNING] = + g_signal_new ("speed-warning", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterVideoTextureClass, speed_warning), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + +} + + +static void +clutter_video_texture_init (ClutterVideoTexture *video_texture) +{ + ClutterVideoTexturePrivate *priv; + GstElement *audio_sink, *video_sink, *bin, *capsfilter; + GstCaps *filtercaps; + GstPad *ghost_pad; + + priv = g_new0 (ClutterVideoTexturePrivate, 1); + video_texture->priv = priv; + + priv->ratio_type = CLUTTER_VIDEO_TEXTURE_AUTO; + + priv->play = gst_element_factory_make ("playbin", "play"); + + if (!priv->play) + { + g_warning ("Could not create element 'playbin'"); + return; + } + + priv->bus = gst_element_get_bus (priv->play); + gst_bus_add_signal_watch (priv->bus); + priv->sig_bus_async = g_signal_connect (priv->bus, + "message", + G_CALLBACK (bus_message_cb), + video_texture); + + audio_sink = gst_element_factory_make ("gconfaudiosink", "audio-sink"); + + if (audio_sink == NULL) + { + g_warning ("Could not create element 'gconfaudiosink' trying autosink"); + audio_sink = gst_element_factory_make ("autoaudiosink", "audio-sink"); + + if (audio_sink == NULL) + { + g_warning ("Could not create element 'autoaudiosink' " + "trying fakesink"); + audio_sink = gst_element_factory_make ("fakesink", + "audio-fake-sink"); + if (audio_sink == NULL) + { + g_warning ("Could not create element 'fakesink' for audio, giving up. "); + } + } + } + + priv->audio_sink = audio_sink; + + video_sink = gst_element_factory_make ("fakesink", "fakesink"); + + if (video_sink == NULL) + { + g_warning ("Could not create element 'fakesink' for video playback"); + return; + } + + bin = gst_bin_new ("video-bin"); + + capsfilter = gst_element_factory_make ("capsfilter", "vfilter"); + + filtercaps + = gst_caps_new_simple("video/x-raw-rgb", + "bpp", G_TYPE_INT, 24, + "depth", G_TYPE_INT, 24, + "endianness", G_TYPE_INT, G_BIG_ENDIAN, + "red_mask", G_TYPE_INT, 0xff0000 /* >> 8 for 24bpp */, + "green_mask", G_TYPE_INT, 0xff00, + "blue_mask", G_TYPE_INT, 0xff, + "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "framerate", GST_TYPE_FRACTION_RANGE, + 0, 1, G_MAXINT, 1, + NULL); + + g_object_set(G_OBJECT(capsfilter), "caps", filtercaps, NULL); + + gst_bin_add(GST_BIN(bin), capsfilter); + gst_bin_add(GST_BIN(bin), video_sink); + + gst_element_link (capsfilter, video_sink); + + ghost_pad = gst_ghost_pad_new ("sink", + gst_element_get_pad (capsfilter, "sink")); + + gst_element_add_pad (bin, ghost_pad); + + g_object_set (G_OBJECT(video_sink), + "signal-handoffs", TRUE, + "sync", TRUE, + NULL); + + g_signal_connect(G_OBJECT (video_sink), "handoff", + G_CALLBACK(fakesink_handoff_cb), video_texture); + + priv->video_sink = bin; + + if (priv->video_sink) + g_object_set (priv->play, "video-sink", bin, NULL); + + if (priv->audio_sink) + g_object_set (priv->play, "audio-sink", audio_sink, NULL); + + g_signal_connect (priv->play, "notify::source", + G_CALLBACK (playbin_got_source), video_texture); + g_signal_connect (priv->play, "notify::stream-info", + G_CALLBACK (playbin_stream_info_set), video_texture); + return; +} + +ClutterElement* +clutter_video_texture_new (void) +{ + ClutterVideoTexture *video_texture; + + video_texture = g_object_new (CLUTTER_TYPE_VIDEO_TEXTURE, + "tiled", FALSE, + "pixel-format", GL_RGB, + NULL); + + return CLUTTER_ELEMENT(video_texture); +} + +gboolean +clutter_video_texture_open (ClutterVideoTexture *video_texture, + const gchar *mrl, + const gchar *subtitle_uri, + GError **error) +{ + ClutterVideoTexturePrivate *priv; + gboolean ret; + + priv = video_texture->priv; + + g_return_val_if_fail (video_texture != NULL, FALSE); + g_return_val_if_fail (mrl != NULL, FALSE); + g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE(video_texture), FALSE); + g_return_val_if_fail (priv->play != NULL, FALSE); + + if (priv->mrl && strcmp (priv->mrl, mrl) == 0) + return TRUE; + + /* this allows non-URI type of files in the thumbnailer and so on */ + if (priv->mrl) + g_free (priv->mrl); + + if (mrl[0] == '/') + { + priv->mrl = g_strdup_printf ("file://%s", mrl); + } + else + { + if (strchr (mrl, ':')) + { + priv->mrl = g_strdup (mrl); + } + else + { + gchar *cur_dir = g_get_current_dir (); + if (!cur_dir) + { + g_set_error (error, CLUTTER_VIDEO_TEXTURE_ERROR, + CLUTTER_VIDEO_TEXTURE_ERROR_GENERIC, + "Failed to retrieve working directory"); + return FALSE; + } + priv->mrl = g_strdup_printf ("file://%s/%s", cur_dir, mrl); + g_free (cur_dir); + } + } + + priv->got_redirect = FALSE; + priv->has_video = FALSE; + priv->has_audio = FALSE; + priv->stream_length = 0; + + if (g_strrstr (priv->mrl, "#subtitle:")) + { + gchar **uris; + gchar *subtitle_uri; + + uris = g_strsplit (priv->mrl, "#subtitle:", 2); + /* Try to fix subtitle uri if needed */ + if (uris[1][0] == '/') + { + subtitle_uri = g_strdup_printf ("file://%s", uris[1]); + } + else + { + if (strchr (uris[1], ':')) + { + subtitle_uri = g_strdup (uris[1]); + } + else + { + gchar *cur_dir = g_get_current_dir (); + if (!cur_dir) + { + g_set_error (error, CLUTTER_VIDEO_TEXTURE_ERROR, + CLUTTER_VIDEO_TEXTURE_ERROR_GENERIC, + "Failed to retrieve working directory"); + return FALSE; + } + + subtitle_uri = g_strdup_printf ("file://%s/%s", + cur_dir, uris[1]); + g_free (cur_dir); + } + } + + g_object_set (priv->play, + "uri", priv->mrl, + "suburi", subtitle_uri, + NULL); + g_free (subtitle_uri); + g_strfreev (uris); + } + else + { + g_object_set (priv->play, + "uri", priv->mrl, + "suburi", subtitle_uri, + NULL); + } + + gst_element_set_state (priv->play, GST_STATE_PAUSED); + + ret = poll_for_state_change (video_texture, + priv->play, + GST_STATE_PAUSED, + NULL); + + if (!ret) + { + priv->ignore_messages_mask |= GST_MESSAGE_ERROR; + stop_play_pipeline (video_texture); + g_free (priv->mrl); + priv->mrl = NULL; + } + else + g_signal_emit (video_texture, cvt_signals[SIGNAL_CHANNELS_CHANGE], 0); + + return ret; +} + +gboolean +clutter_video_texture_play (ClutterVideoTexture *video_texture, + GError ** error) +{ + ClutterVideoTexturePrivate *priv; + gboolean ret; + + priv = video_texture->priv; + + g_return_val_if_fail (video_texture != NULL, FALSE); + g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE(video_texture), FALSE); + g_return_val_if_fail (priv->play != NULL, FALSE); + + gst_element_set_state (priv->play, GST_STATE_PLAYING); + + ret = poll_for_state_change (video_texture, + priv->play, + GST_STATE_PLAYING, + error); + return ret; +} + +void +clutter_video_texture_pause (ClutterVideoTexture *video_texture) +{ + g_return_if_fail (video_texture != NULL); + g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture)); + g_return_if_fail (GST_IS_ELEMENT (video_texture->priv->play)); + + CLUTTER_DBG ("Pausing"); + + gst_element_set_state (GST_ELEMENT (video_texture->priv->play), + GST_STATE_PAUSED); +} + + +gboolean +clutter_video_texture_can_direct_seek (ClutterVideoTexture *video_texture) +{ + g_return_val_if_fail (video_texture != NULL, FALSE); + g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), FALSE); + g_return_val_if_fail (GST_IS_ELEMENT (video_texture->priv->play), FALSE); + + if (!video_texture->priv->mrl) + return FALSE; + + /* (instant seeking only make sense with video, hence no cdda:// here) */ + if (g_str_has_prefix (video_texture->priv->mrl, "file://") || + g_str_has_prefix (video_texture->priv->mrl, "dvd://") || + g_str_has_prefix (video_texture->priv->mrl, "vcd://")) + return TRUE; + + return FALSE; +} + +gboolean +clutter_video_texture_seek_time (ClutterVideoTexture *video_texture, + gint64 time, + GError **gerror) +{ + g_return_val_if_fail (video_texture != NULL, FALSE); + g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), FALSE); + g_return_val_if_fail (GST_IS_ELEMENT (video_texture->priv->play), FALSE); + + got_time_tick (video_texture->priv->play, time * GST_MSECOND, video_texture); + + gst_element_seek (video_texture->priv->play, + 1.0, + GST_FORMAT_TIME, + GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT, + GST_SEEK_TYPE_SET, + time * GST_MSECOND, + GST_SEEK_TYPE_NONE, + GST_CLOCK_TIME_NONE); + + gst_element_get_state (video_texture->priv->play, + NULL, NULL, 100 * GST_MSECOND); + return TRUE; +} + +gboolean +clutter_video_texture_seek (ClutterVideoTexture *video_texture, + float position, + GError **error) +{ + gint64 seek_time, length_nanos; + + g_return_val_if_fail (video_texture != NULL, FALSE); + g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), FALSE); + g_return_val_if_fail (GST_IS_ELEMENT (video_texture->priv->play), FALSE); + + length_nanos = (gint64) (video_texture->priv->stream_length * GST_MSECOND); + seek_time = (gint64) (length_nanos * position); + + return clutter_video_texture_seek_time (video_texture, + seek_time / GST_MSECOND, error); +} + +static void +stop_play_pipeline (ClutterVideoTexture *video_texture) +{ + GstElement *playbin = video_texture->priv->play; + GstState current_state; + + /* first go to ready, that way our state change handler gets to see + * our state change messages (before the bus goes to flushing) and + * cleans up */ + gst_element_get_state (playbin, ¤t_state, NULL, 0); + + if (current_state > GST_STATE_READY) + { + GError *err = NULL; + + gst_element_set_state (playbin, GST_STATE_READY); + poll_for_state_change_full (video_texture, + playbin, + GST_STATE_READY, &err, -1); + if (err) + g_error_free (err); + } + + /* now finally go to null state */ + gst_element_set_state (playbin, GST_STATE_NULL); + gst_element_get_state (playbin, NULL, NULL, -1); +} + +void +clutter_video_texture_stop (ClutterVideoTexture *video_texture) +{ + g_return_if_fail (video_texture != NULL); + g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture)); + g_return_if_fail (GST_IS_ELEMENT (video_texture->priv->play)); + + stop_play_pipeline (video_texture); + + /* Reset position to 0 when stopping */ + got_time_tick (GST_ELEMENT (video_texture->priv->play), 0, video_texture); +} + +gboolean +clutter_video_texture_can_set_volume (ClutterVideoTexture *video_texture) +{ + g_return_val_if_fail (video_texture != NULL, FALSE); + g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), FALSE); + g_return_val_if_fail (GST_IS_ELEMENT (video_texture->priv->play), FALSE); + + return TRUE; +} + +void +clutter_video_texture_set_volume (ClutterVideoTexture *video_texture, + int volume) +{ + g_return_if_fail (video_texture != NULL); + g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture)); + g_return_if_fail (GST_IS_ELEMENT (video_texture->priv->play)); + + if (clutter_video_texture_can_set_volume (video_texture) != FALSE) + { + volume = CLAMP (volume, 0, 100); + g_object_set (video_texture->priv->play, "volume", + (gdouble) (1. * volume / 100), NULL); + } +} + +int +clutter_video_texture_get_volume (ClutterVideoTexture *video_texture) +{ + gdouble vol; + + g_return_val_if_fail (video_texture != NULL, -1); + g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), -1); + g_return_val_if_fail (GST_IS_ELEMENT (video_texture->priv->play), -1); + + g_object_get (G_OBJECT (video_texture->priv->play), "volume", &vol, NULL); + + return (gint) (vol * 100 + 0.5); +} + +gint64 +clutter_video_texture_get_current_time (ClutterVideoTexture *video_texture) +{ + g_return_val_if_fail (video_texture != NULL, -1); + g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), -1); + + return video_texture->priv->current_time; +} + +gint64 +clutter_video_texture_get_stream_length (ClutterVideoTexture *video_texture) +{ + ClutterVideoTexturePrivate *priv; + + g_return_val_if_fail (video_texture != NULL, -1); + g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), -1); + + priv = video_texture->priv; + + if (priv->stream_length == 0 && priv->play != NULL) + { + GstFormat fmt = GST_FORMAT_TIME; + gint64 len = -1; + + if (gst_element_query_duration (priv->play, &fmt, &len) && len != -1) + priv->stream_length = len / GST_MSECOND; + } + + return priv->stream_length; +} + +gboolean +clutter_video_texture_is_playing (ClutterVideoTexture *video_texture) +{ + GstState cur, pending; + + g_return_val_if_fail (video_texture != NULL, FALSE); + g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), FALSE); + g_return_val_if_fail (GST_IS_ELEMENT (video_texture->priv->play), FALSE); + + gst_element_get_state (video_texture->priv->play, &cur, &pending, 0); + + if (cur == GST_STATE_PLAYING || pending == GST_STATE_PLAYING) + return TRUE; + + return FALSE; +} + +gboolean +clutter_video_texture_is_seekable (ClutterVideoTexture *video_texture) +{ + gboolean res; + + g_return_val_if_fail (video_texture != NULL, FALSE); + g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), FALSE); + g_return_val_if_fail (GST_IS_ELEMENT (video_texture->priv->play), FALSE); + + if (video_texture->priv->stream_length == 0) + res = (clutter_video_texture_get_stream_length (video_texture) > 0); + else + res = (video_texture->priv->stream_length > 0); + + return res; +} + +float +clutter_video_texture_get_position (ClutterVideoTexture *video_texture) +{ + g_return_val_if_fail (video_texture != NULL, -1); + g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), -1); + + return video_texture->priv->current_position; +} + +void +clutter_video_texture_set_aspect_ratio (ClutterVideoTexture *video_texture, + ClutterVideoTextureAspectRatio ratio) +{ + g_return_if_fail (video_texture != NULL); + g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture)); + + video_texture->priv->ratio_type = ratio; + got_video_size (video_texture); +} + +ClutterVideoTextureAspectRatio +clutter_video_texture_get_aspect_ratio (ClutterVideoTexture *video_texture) +{ + g_return_val_if_fail (video_texture != NULL, 0); + g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), 0); + + return video_texture->priv->ratio_type; +} + +/* Metadata */ + +static const struct _metadata_map_info +{ + ClutterVideoTextureMetadataType type; + const gchar *str; +} metadata_str_map[] = { + { CLUTTER_INFO_TITLE, "title" }, + { CLUTTER_INFO_ARTIST, "artist" }, + { CLUTTER_INFO_YEAR, "year" }, + { CLUTTER_INFO_ALBUM, "album" }, + { CLUTTER_INFO_DURATION, "duration" }, + { CLUTTER_INFO_TRACK_NUMBER, "track-number" }, + { CLUTTER_INFO_HAS_VIDEO, "has-video" }, + { CLUTTER_INFO_DIMENSION_X, "dimension-x" }, + { CLUTTER_INFO_DIMENSION_Y, "dimension-y" }, + { CLUTTER_INFO_VIDEO_BITRATE,"video-bitrate" }, + { CLUTTER_INFO_VIDEO_CODEC, "video-codec" }, + { CLUTTER_INFO_FPS, "fps" }, + { CLUTTER_INFO_HAS_AUDIO, "has-audio" }, + { CLUTTER_INFO_AUDIO_BITRATE,"audio-bitrate" }, + { CLUTTER_INFO_AUDIO_CODEC, "audio-codec" } +}; + +static const gchar* +get_metadata_type_name (ClutterVideoTextureMetadataType type) +{ + guint i; + for (i = 0; i < G_N_ELEMENTS (metadata_str_map); ++i) + { + if (metadata_str_map[i].type == type) + return metadata_str_map[i].str; + } + return "unknown"; +} + +static void +get_metadata_string (ClutterVideoTexture *video_texture, + ClutterVideoTextureMetadataType type, + GValue *value) +{ + ClutterVideoTexturePrivate *priv; + char *string = NULL; + gboolean res = FALSE; + + priv = video_texture->priv; + + g_value_init (value, G_TYPE_STRING); + + if (priv->play == NULL || priv->tagcache == NULL) + { + g_value_set_string (value, NULL); + return; + } + + switch (type) + { + case CLUTTER_INFO_TITLE: + res = gst_tag_list_get_string_index (priv->tagcache, + GST_TAG_TITLE, 0, &string); + break; + case CLUTTER_INFO_ARTIST: + res = gst_tag_list_get_string_index (priv->tagcache, + GST_TAG_ARTIST, 0, &string); + break; + case CLUTTER_INFO_YEAR: + { + GDate *date; + if ((res = gst_tag_list_get_date (priv->tagcache, + GST_TAG_DATE, &date))) + { + string = g_strdup_printf ("%d", g_date_get_year (date)); + g_date_free (date); + } + break; + } + case CLUTTER_INFO_ALBUM: + res = gst_tag_list_get_string_index (priv->tagcache, + GST_TAG_ALBUM, 0, &string); + break; + case CLUTTER_INFO_VIDEO_CODEC: + res = gst_tag_list_get_string (priv->tagcache, + GST_TAG_VIDEO_CODEC, &string); + break; + case CLUTTER_INFO_AUDIO_CODEC: + res = gst_tag_list_get_string (priv->tagcache, + GST_TAG_AUDIO_CODEC, &string); + break; + default: + g_assert_not_reached (); + } + + if (res) + { + g_value_take_string (value, string); + CLUTTER_DBG ("%s = '%s'", get_metadata_type_name (type), string); + } + else + g_value_set_string (value, NULL); + + return; +} + +static void +get_metadata_int (ClutterVideoTexture *video_texture, + ClutterVideoTextureMetadataType type, + GValue *value) +{ + ClutterVideoTexturePrivate *priv; + int integer = 0; + + priv = video_texture->priv; + + g_value_init (value, G_TYPE_INT); + + if (priv->play == NULL) + { + g_value_set_int (value, 0); + return; + } + + switch (type) + { + case CLUTTER_INFO_DURATION: + integer = clutter_video_texture_get_stream_length (video_texture) / 1000; + break; + case CLUTTER_INFO_TRACK_NUMBER: + if (!gst_tag_list_get_uint (priv->tagcache, + GST_TAG_TRACK_NUMBER, (guint *) &integer)) + integer = 0; + break; + case CLUTTER_INFO_DIMENSION_X: + integer = priv->video_width; + break; + case CLUTTER_INFO_DIMENSION_Y: + integer = priv->video_height; + break; + case CLUTTER_INFO_FPS: + if (priv->video_fps_d > 0) + { + /* Round up/down to the nearest integer framerate */ + integer = (priv->video_fps_n + priv->video_fps_d/2) / + priv->video_fps_d; + } + else + integer = 0; + break; + case CLUTTER_INFO_AUDIO_BITRATE: + if (priv->audiotags == NULL) + break; + if (gst_tag_list_get_uint (priv->audiotags, GST_TAG_BITRATE, + (guint *)&integer) || + gst_tag_list_get_uint (priv->audiotags, GST_TAG_NOMINAL_BITRATE, + (guint *)&integer)) { + integer /= 1000; + } + break; + case CLUTTER_INFO_VIDEO_BITRATE: + if (priv->videotags == NULL) + break; + if (gst_tag_list_get_uint (priv->videotags, GST_TAG_BITRATE, + (guint *)&integer) || + gst_tag_list_get_uint (priv->videotags, GST_TAG_NOMINAL_BITRATE, + (guint *)&integer)) { + integer /= 1000; + } + break; + default: + g_assert_not_reached (); + } + + g_value_set_int (value, integer); + CLUTTER_DBG ("%s = %d", get_metadata_type_name (type), integer); + + return; +} + +static void +get_metadata_bool (ClutterVideoTexture *video_texture, + ClutterVideoTextureMetadataType type, + GValue *value) +{ + ClutterVideoTexturePrivate *priv; + gboolean boolean = FALSE; + + priv = video_texture->priv; + + g_value_init (value, G_TYPE_BOOLEAN); + + if (priv->play == NULL) + { + g_value_set_boolean (value, FALSE); + return; + } + + switch (type) + { + case CLUTTER_INFO_HAS_VIDEO: + boolean = priv->has_video; + /* if properties dialog, show the metadata we + * have even if we cannot decode the stream */ + if (!boolean + && priv->tagcache != NULL + && gst_structure_has_field ((GstStructure *) priv->tagcache, + GST_TAG_VIDEO_CODEC)) + boolean = TRUE; + break; + case CLUTTER_INFO_HAS_AUDIO: + boolean = priv->has_audio; + /* if properties dialog, show the metadata we + * have even if we cannot decode the stream */ + if (!boolean + && priv->tagcache != NULL + && gst_structure_has_field ((GstStructure *) priv->tagcache, + GST_TAG_AUDIO_CODEC)) + boolean = TRUE; + break; + default: + g_assert_not_reached (); + } + + g_value_set_boolean (value, boolean); + CLUTTER_DBG ("%s = %s", get_metadata_type_name (type), + (boolean) ? "yes" : "no"); + return; +} + +void +clutter_video_texture_get_metadata (ClutterVideoTexture *video_texture, + ClutterVideoTextureMetadataType type, + GValue *value) +{ + g_return_if_fail (video_texture != NULL); + g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture)); + g_return_if_fail (GST_IS_ELEMENT (video_texture->priv->play)); + + switch (type) + { + case CLUTTER_INFO_TITLE: + case CLUTTER_INFO_ARTIST: + case CLUTTER_INFO_YEAR: + case CLUTTER_INFO_ALBUM: + case CLUTTER_INFO_VIDEO_CODEC: + case CLUTTER_INFO_AUDIO_CODEC: + get_metadata_string (video_texture, type, value); + break; + case CLUTTER_INFO_DURATION: + case CLUTTER_INFO_DIMENSION_X: + case CLUTTER_INFO_DIMENSION_Y: + case CLUTTER_INFO_FPS: + case CLUTTER_INFO_AUDIO_BITRATE: + case CLUTTER_INFO_VIDEO_BITRATE: + case CLUTTER_INFO_TRACK_NUMBER: + get_metadata_int (video_texture, type, value); + break; + case CLUTTER_INFO_HAS_VIDEO: + case CLUTTER_INFO_HAS_AUDIO: + get_metadata_bool (video_texture, type, value); + break; + default: + g_return_if_reached (); + } + + return; +} diff --git a/clutter/clutter-video-texture.h b/clutter/clutter-video-texture.h new file mode 100644 index 000000000..94e6b63e3 --- /dev/null +++ b/clutter/clutter-video-texture.h @@ -0,0 +1,213 @@ +#ifndef _HAVE_CLUTTER_VIDEO_TEXTURE_H +#define _HAVE_CLUTTER_VIDEO_TEXTURE_H + +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define CLUTTER_TYPE_VIDEO_TEXTURE clutter_video_texture_get_type() + +#define CLUTTER_VIDEO_TEXTURE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + CLUTTER_TYPE_VIDEO_TEXTURE, ClutterVideoTexture)) + +#define CLUTTER_VIDEO_TEXTURE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + CLUTTER_TYPE_VIDEO_TEXTURE, ClutterVideoTextureClass)) + +#define CLUTTER_IS_VIDEO_TEXTURE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + CLUTTER_TYPE_VIDEO_TEXTURE)) + +#define CLUTTER_IS_VIDEO_TEXTURE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + CLUTTER_TYPE_VIDEO_TEXTURE)) + +#define CLUTTER_VIDEO_TEXTURE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + CLUTTER_TYPE_VIDEO_TEXTURE, ClutterVideoTextureClass)) + +typedef struct ClutterVideoTexturePrivate ClutterVideoTexturePrivate ; +typedef struct _ClutterVideoTexture ClutterVideoTexture; +typedef struct _ClutterVideoTextureClass ClutterVideoTextureClass; + + +#define CLUTTER_VIDEO_TEXTURE_ERROR clutter_video_texture_error_quark() + +typedef enum +{ + /* Plugins */ + CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_PLUGIN, + CLUTTER_VIDEO_TEXTURE_ERROR_NO_PLUGIN_FOR_FILE, + CLUTTER_VIDEO_TEXTURE_ERROR_VIDEO_PLUGIN, + CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_BUSY, + + /* File */ + CLUTTER_VIDEO_TEXTURE_ERROR_BROKEN_FILE, + CLUTTER_VIDEO_TEXTURE_ERROR_FILE_GENERIC, + CLUTTER_VIDEO_TEXTURE_ERROR_FILE_PERMISSION, + CLUTTER_VIDEO_TEXTURE_ERROR_FILE_ENCRYPTED, + CLUTTER_VIDEO_TEXTURE_ERROR_FILE_NOT_FOUND, + + /* Devices */ + CLUTTER_VIDEO_TEXTURE_ERROR_DVD_ENCRYPTED, + CLUTTER_VIDEO_TEXTURE_ERROR_INVALID_DEVICE, + + /* Network */ + CLUTTER_VIDEO_TEXTURE_ERROR_UNKNOWN_HOST, + CLUTTER_VIDEO_TEXTURE_ERROR_NETWORK_UNREACHABLE, + CLUTTER_VIDEO_TEXTURE_ERROR_CONNECTION_REFUSED, + + /* Generic */ + CLUTTER_VIDEO_TEXTURE_ERROR_UNVALID_LOCATION, + CLUTTER_VIDEO_TEXTURE_ERROR_GENERIC, + CLUTTER_VIDEO_TEXTURE_ERROR_CODEC_NOT_HANDLED, + CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_ONLY, + CLUTTER_VIDEO_TEXTURE_ERROR_CANNOT_CAPTURE, + CLUTTER_VIDEO_TEXTURE_ERROR_READ_ERROR, + CLUTTER_VIDEO_TEXTURE_ERROR_PLUGIN_LOAD, + CLUTTER_VIDEO_TEXTURE_ERROR_STILL_IMAGE, + CLUTTER_VIDEO_TEXTURE_ERROR_EMPTY_FILE +} ClutterVideoTextureError; + +GQuark clutter_video_texture_error_quark (void); + +typedef enum +{ + CLUTTER_VIDEO_TEXTURE_AUTO, + CLUTTER_VIDEO_TEXTURE_SQUARE, + CLUTTER_VIDEO_TEXTURE_FOURBYTHREE, + CLUTTER_VIDEO_TEXTURE_ANAMORPHIC, + CLUTTER_VIDEO_TEXTURE_DVB +} ClutterVideoTextureAspectRatio; + +struct _ClutterVideoTexture +{ + ClutterTexture parent; + ClutterVideoTexturePrivate *priv; +}; + +struct _ClutterVideoTextureClass +{ + ClutterTextureClass parent_class; + + void (*error) (ClutterVideoTexture *cvt, const char *message, + gboolean playback_stopped, gboolean fatal); + void (*eos) (ClutterVideoTexture *cvt); + void (*got_metadata) (ClutterVideoTexture *cvt); + void (*got_redirect) (ClutterVideoTexture *cvt, const char *mrl); + void (*title_change) (ClutterVideoTexture *cvt, const char *title); + void (*channels_change) (ClutterVideoTexture *cvt); + void (*tick) (ClutterVideoTexture *cvt, + gint64 current_time, + gint64 stream_length, + float current_position, + gboolean seekable); + void (*buffering) (ClutterVideoTexture *cvt, guint progress); + void (*speed_warning) (ClutterVideoTexture *cvt); +}; + +GType clutter_video_texture_get_type (void); + +ClutterElement* +clutter_video_texture_new (void); + +gboolean +clutter_video_texture_open (ClutterVideoTexture *video_texture, + const gchar *mrl, + const gchar *subtitle_uri, + GError **error); + +gboolean +clutter_video_texture_play (ClutterVideoTexture *video_texture, + GError ** error); + +void +clutter_video_texture_pause (ClutterVideoTexture *video_texture); + +gboolean +clutter_video_texture_can_direct_seek (ClutterVideoTexture *video_texture); + +gboolean +clutter_video_texture_seek_time (ClutterVideoTexture *video_texture, + gint64 time, + GError **gerror); + +gboolean +clutter_video_texture_seek (ClutterVideoTexture *video_texture, + float position, + GError **error); + +void +clutter_video_texture_stop (ClutterVideoTexture *video_texture); + +gboolean +clutter_video_texture_can_set_volume (ClutterVideoTexture *video_texture); + +void +clutter_video_texture_set_volume (ClutterVideoTexture *video_texture, + int volume); +int +clutter_video_texture_get_volume (ClutterVideoTexture *video_texture); + +gint64 +clutter_video_texture_get_current_time (ClutterVideoTexture *video_texture); + +gint64 +clutter_video_texture_get_stream_length (ClutterVideoTexture *video_texture); + +gboolean +clutter_video_texture_is_playing (ClutterVideoTexture *video_texture); + +gboolean +clutter_video_texture_is_seekable (ClutterVideoTexture * video_texture); + +float +clutter_video_texture_get_position (ClutterVideoTexture *video_texture); + +void +clutter_video_texture_set_aspect_ratio (ClutterVideoTexture *video_texture, + ClutterVideoTextureAspectRatio ratio); + +ClutterVideoTextureAspectRatio +clutter_video_texture_get_aspect_ratio (ClutterVideoTexture *video_texture); + +/* Metadata + * FIXME: This should probably go in some kind of genric 'Media' class + * You would open the media, get a media object and then pass + * that to the video texture. media object could handle being + * just a metadata reader etc... +*/ +typedef enum +{ + CLUTTER_INFO_TITLE, + CLUTTER_INFO_ARTIST, + CLUTTER_INFO_YEAR, + CLUTTER_INFO_ALBUM, + CLUTTER_INFO_DURATION, + CLUTTER_INFO_TRACK_NUMBER, + /* Video */ + CLUTTER_INFO_HAS_VIDEO, + CLUTTER_INFO_DIMENSION_X, + CLUTTER_INFO_DIMENSION_Y, + CLUTTER_INFO_VIDEO_BITRATE, + CLUTTER_INFO_VIDEO_CODEC, + CLUTTER_INFO_FPS, + /* Audio */ + CLUTTER_INFO_HAS_AUDIO, + CLUTTER_INFO_AUDIO_BITRATE, + CLUTTER_INFO_AUDIO_CODEC, +} ClutterVideoTextureMetadataType; + + +void +clutter_video_texture_get_metadata (ClutterVideoTexture *video_texture, + ClutterVideoTextureMetadataType type, + GValue *value); + +G_END_DECLS + +#endif diff --git a/clutter/clutter.h b/clutter/clutter.h new file mode 100644 index 000000000..9b6cd6486 --- /dev/null +++ b/clutter/clutter.h @@ -0,0 +1,20 @@ +#ifndef _HAVE_CLUTTER_H +#define _HAVE_CLUTTER_H + +#include "clutter-keysyms.h" +#include "clutter-main.h" +#include "clutter-color.h" +#include "clutter-util.h" +#include "clutter-event.h" +#include "clutter-timeline.h" +#include "clutter-stage.h" +#include "clutter-element.h" +#include "clutter-rectangle.h" +#include "clutter-group.h" +#include "clutter-texture.h" +#include "clutter-clone-texture.h" +#include "clutter-video-texture.h" +#include "clutter-label.h" +#include "clutter-enum-types.h" + +#endif diff --git a/clutter/fonts.c b/clutter/fonts.c deleted file mode 100644 index dc767260b..000000000 --- a/clutter/fonts.c +++ /dev/null @@ -1,231 +0,0 @@ -#include "fonts.h" - -ClutterFont* -font_new (const char *face) -{ - ClutterFont *font; - PangoFontDescription *desc; - - font = util_malloc0(sizeof(ClutterFont)); - - font->font_map = pango_ft2_font_map_new (); - - pango_ft2_font_map_set_resolution (PANGO_FT2_FONT_MAP (font->font_map), - 96., 96.); - - desc = pango_font_description_from_string (face); - - font->context - = pango_ft2_font_map_create_context (PANGO_FT2_FONT_MAP (font->font_map)); - - pango_context_set_font_description (font->context, desc); - - pango_font_description_free (desc); - - cltr_font_ref(font); - - return font; -} - -#if 0 -static int -decoration_get_title_width (LmcDecoration *decoration) -{ - int title_space; - int width; - - title_space = (decoration->window_width - + lmc_theme->border_info.left - + lmc_theme->border_info.right - - lmc_theme->border_info.left_unscaled - - lmc_theme->border_info.right_unscaled); - title_space = MAX (title_space, 0); - - pango_layout_get_pixel_size (decoration->layout, &width, NULL); - - return MIN (width + TITLE_RIGHT_PAD, title_space); -} -#endif - -static void -get_layout_bitmap (PangoLayout *layout, - FT_Bitmap *bitmap, - PangoRectangle *ink) -{ - PangoRectangle ink_rect; - - pango_layout_get_extents (layout, &ink_rect, NULL); - - printf("%s() gave width:%i, height %i\n", __func__, ink->width, ink->height); - - /* XXX why the >> 10 */ - ink->x = ink_rect.x >> 10; - ink->width = ((ink_rect.x + ink_rect.width + 1023) >> 10) - ink->x; - ink->y = ink_rect.y >> 10; - ink->height = ((ink_rect.y + ink_rect.height + 1023) >> 10) - ink->y; - - if (ink->width == 0) - ink->width = 1; - if (ink->height == 0) - ink->height = 1; - - bitmap->width = ink->width; - bitmap->pitch = (bitmap->width + 3) & ~3; - bitmap->rows = ink->height; - bitmap->buffer = malloc (bitmap->pitch * bitmap->rows); - bitmap->num_grays = 256; - bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; - - memset (bitmap->buffer, 0, bitmap->pitch * bitmap->rows); - - pango_ft2_render_layout (bitmap, layout, - ink->x, - ink->y); -} - -static void -draw_layout_on_pixbuf (PangoLayout *layout, - Pixbuf *pixb, - const PixbufPixel *color, - int x, - int y, - int clip_x, - int clip_y, - int clip_width, - int clip_height) -{ - PangoRectangle ink; - FT_Bitmap bitmap; - int i, j; - unsigned char *layout_bits; - - get_layout_bitmap (layout, &bitmap, &ink); - - layout_bits = bitmap.buffer; - - for (j = y + ink.y; j < y + ink.y + ink.height; j++) - { - if (j >= clip_y && j < clip_y + clip_height) - { - int start_x, end_x; - - start_x = MAX (x + ink.x, clip_x); - end_x = MIN (x + ink.x + ink.width, clip_x + clip_width); - - if (start_x < end_x) - { - unsigned char *b = layout_bits + (start_x - (x + ink.x)); - - for (i = start_x ; i < end_x; i++) - { - PixbufPixel pixel; - -#if 0 - int tr1, tg1, tb1, tr2, tg2, tb2; - int a = (*b * color->a + 0x80) >> 8; - - /* - this is wrong for when the backing has an - alpha of zero. we need a different algorythm - to handle that - so we can overlay just a font - text texture with no bg - - */ - - if (!a) - { b++; continue; } - - pixbuf_get_pixel (pixb, i, j, &pixel); - - tr1 = (255 - a) * pixel.r + 0x80; - tr2 = a * color->r + 0x80; - pixel.r = ((tr1 + (tr1 >> 8)) >> 8) + ((tr2 + (tr2 >> 8)) >> 8); - tg1 = (255 - a) * pixel.g + 0x80; - tg2 = a * color->g + 0x80; - pixel.g = ((tg1 + (tg1 >> 8)) >> 8) + ((tg2 + (tg2 >> 8)) >> 8); - tb1 = (255 - a) * pixel.b + 0x80; - tb2 = a * color->b + 0x80; - pixel.b = ((tb1 + (tb1 >> 8)) >> 8) + ((tb2 + (tb2 >> 8)) >> 8); - tb1 = (255 - a) * pixel.a + 0x80; - tb2 = a * color->a + 0x80; - pixel.a = ((tb1 + (tb1 >> 8)) >> 8) + ((tb2 + (tb2 >> 8)) >> 8); -#endif - pixel.r = color->r; - pixel.g = color->g; - pixel.b = color->b; - pixel.a = (( *b * color->a ) >> 8 ); - - pixbuf_set_pixel (pixb, i, j, &pixel); - b++; - } - } - } - - layout_bits += bitmap.pitch; - } - - free (bitmap.buffer); -} - - -void -font_draw(ClutterFont *font, - Pixbuf *pixb, - const char *text, - int x, - int y, - PixbufPixel *p) -{ - int layout_width, layout_height; - PangoLayout *layout; - - layout = pango_layout_new (font->context); - - pango_layout_set_text (layout, text, -1); - - /* cant rely on just clip - need to set layout width too ? */ - /* pango_layout_set_width(layout, (pixb->width - x) << 10); */ - - draw_layout_on_pixbuf (layout, pixb, p, x, y, - x, - y, - pixb->width - x, - pixb->height - y); - - g_object_unref(G_OBJECT(layout)); -} - -void -font_get_pixel_size (ClutterFont *font, - const char *text, - int *width, - int *height) -{ - PangoLayout *layout; - - layout = pango_layout_new (font->context); - - pango_layout_set_text (layout, text, -1); - - pango_layout_get_pixel_size (layout, width, height); - - printf("%s() gave width:%i, height %i\n", __func__, *width, *height); - - g_object_unref(G_OBJECT(layout)); -} - -void -cltr_font_ref(CltrFont *font) -{ - font->refcnt++; -} - -void -cltr_font_unref(CltrFont *font) -{ - font->refcnt--; - - if (font->refcnt <= 0) - { - /* XXX free up pango stuff */ - g_free(font); - } -} diff --git a/clutter/fonts.h b/clutter/fonts.h deleted file mode 100644 index eb1035177..000000000 --- a/clutter/fonts.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef _HAVE_FONTS_H -#define _HAVE_FONTS_H - -#include - -#include "pixbuf.h" -#include "util.h" - -/* Code based on stuff found in luminocity */ - -typedef struct ClutterFont ClutterFont; - -struct ClutterFont -{ - PangoFontMap *font_map; - PangoContext *context; - int refcnt; -}; - -typedef ClutterFont CltrFont ; /* Tsk Tsk .. */ - -ClutterFont* -font_new (const char *face); - -void -cltr_font_ref(CltrFont *font); - -void -cltr_font_unref(CltrFont *font); - -void -font_draw(ClutterFont *font, - Pixbuf *pixb, - const char *text, - int x, - int y, - PixbufPixel *p); - -void -font_get_pixel_size (ClutterFont *font, - const char *text, - int *width, - int *height); - -#endif diff --git a/clutter/pixbuf.c b/clutter/pixbuf.c deleted file mode 100644 index d23594a21..000000000 --- a/clutter/pixbuf.c +++ /dev/null @@ -1,1232 +0,0 @@ -#include -#include - -#include /* For memset() */ -#include /* For read() */ - - -#include -#include -#include - -#include /* For mmap()/munmap() */ -#include - - -#include -#include - -#include "pixbuf.h" -#include "util.h" - -#define CLTR_CLAMP(x, y) ((x) > (y)) ? (y) : (x); - -static void -fix_png_write_data (png_structp png, - png_row_infop row_info, - png_bytep data) -{ - int i; - - for (i = 0; i < row_info->rowbytes; i += 4) - { - unsigned char *b = &data[i]; - unsigned int pixel; - - memcpy (&pixel, b, sizeof (unsigned int)); - - b[0] = (pixel >> 24) & 0xff; - b[1] = (pixel >> 16) & 0xff; - b[2] = (pixel >> 8) & 0xff; - b[3] = pixel & 0xff; - } -} - -static void -fix_png_read_data (png_structp png, - png_row_infop row_info, - png_bytep data) -{ - int i; - - for (i = 0; i < row_info->rowbytes; i += 4) - { - unsigned char *b = &data[i]; - unsigned int pixel; - - memcpy (&pixel, b, sizeof (unsigned int)); - - b[0] = (pixel >> 24) & 0xff; - b[1] = (pixel >> 16) & 0xff; - b[2] = (pixel >> 8) & 0xff; - b[3] = pixel & 0xff; - } -} - -int -pixbuf_write_png(Pixbuf *pixb, char *filename) -{ - FILE *f; - int i; - png_struct *png; - png_info *info; - png_byte **rows; - png_color_16 white; - - f = fopen (filename, "w"); - - rows = malloc (pixb->height * sizeof(png_byte*)); - - for (i = 0; i < pixb->height; i++) - { - rows[i] = pixb->data + (i * (pixb->width)); - } - - png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - - info = png_create_info_struct (png); - - png_init_io (png, f); - - png_set_IHDR (png, info, - pixb->width, pixb->height, 8, - PNG_COLOR_TYPE_RGB_ALPHA, - PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - - white.red = 0xff; - white.blue = 0xff; - white.green = 0xff; - png_set_bKGD (png, info, &white); - - /* png_set_write_user_transform_fn (png, unpremultiply_data); */ - - /* png_set_bgr (png); */ - - /* png_set_filler(png, 0, PNG_FILLER_BEFORE); */ - - /* - png_set_packswap(png); - - png_set_swap(png); - */ - - png_set_write_user_transform_fn (png, fix_png_write_data); - - png_write_info (png, info); - png_write_image (png, rows); - png_write_end (png, info); - - png_destroy_write_struct (&png, &info); - - free (rows); - fclose (f); - - return 1; -} - -static int* -load_png_file( const char *file, - int *width, - int *height) -{ - FILE *fd; - /* GLubyte *data; */ - int *data; - unsigned char header[8]; - int bit_depth, color_type; - png_uint_32 png_width, png_height, i, rowbytes; - png_structp png_ptr; - png_infop info_ptr; - png_bytep *row_pointers; - - if ((fd = fopen( file, "rb" )) == NULL) return NULL; - - /* check header etc */ - - fread(header, 1, 8, fd); - - if (!png_check_sig(header, 8)) - { - fclose(fd); - return NULL; - } - - png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - - if (!png_ptr) - { - fclose(fd); - return NULL; - } - - info_ptr = png_create_info_struct(png_ptr); - - if (!info_ptr) - { - png_destroy_read_struct( &png_ptr, (png_infopp)NULL, (png_infopp)NULL); - fclose(fd); - return NULL; - } - - if (setjmp( png_ptr->jmpbuf ) ) - { - png_destroy_read_struct( &png_ptr, &info_ptr, NULL); - fclose(fd); - return NULL; - } - - png_init_io( png_ptr, fd ); - - png_set_sig_bytes( png_ptr, 8); - png_read_info( png_ptr, info_ptr); - - png_get_IHDR( png_ptr, info_ptr, - &png_width, &png_height, &bit_depth, - &color_type, NULL, NULL, NULL); - - *width = (int) png_width; - *height = (int) png_height; - - /* Tranform to req 8888 */ - - if (bit_depth == 16 ) png_set_strip_16(png_ptr); /* 16 -> 8 */ - - if (bit_depth < 8) png_set_packing(png_ptr); /* 1,2,4 -> 8 */ - - if (( color_type == PNG_COLOR_TYPE_GRAY ) || - ( color_type == PNG_COLOR_TYPE_GRAY_ALPHA )) - png_set_gray_to_rgb(png_ptr); - - if (( color_type == PNG_COLOR_TYPE_GRAY ) || - ( color_type == PNG_COLOR_TYPE_RGB )) - png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_BEFORE); /* req 1.2.7 */ - else /* */ - { - if (( color_type == PNG_COLOR_TYPE_PALETTE )|| - ( png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS ))) - png_set_expand(png_ptr); - - /* Needed to fix endianess */ - png_set_read_user_transform_fn (png_ptr, fix_png_read_data); - } - - - /* png_set_packswap(png_ptr); */ - - png_read_update_info( png_ptr, info_ptr); - - /* Now load the actual data */ - - rowbytes = png_get_rowbytes( png_ptr, info_ptr); - - data = (int *) malloc( (rowbytes*(*height + 1))); - - row_pointers = (png_bytep *) malloc( (*height)*sizeof(png_bytep)); - - if (( data == NULL ) || ( row_pointers == NULL )) - { - png_destroy_read_struct( &png_ptr, &info_ptr, NULL); - if (data) free(data); - if (row_pointers) free(row_pointers); - return NULL; - } - - for ( i = 0; i < *height; i++ ) - row_pointers[i] = (png_bytep) data + i*rowbytes; - - png_read_image( png_ptr, row_pointers ); - png_read_end( png_ptr, NULL); - - free(row_pointers); - png_destroy_read_struct( &png_ptr, &info_ptr, NULL); - fclose(fd); - - return data; -} - -struct local_error_mgr -{ - struct jpeg_error_mgr pub; /* "public" fields */ - jmp_buf setjmp_buffer; /* for return to caller */ -}; - -typedef struct local_error_mgr * local_error_ptr; - -static void -_jpeg_error_exit (j_common_ptr cinfo) -{ - local_error_ptr err = (local_error_ptr) cinfo->err; - (*cinfo->err->output_message) (cinfo); - longjmp(err->setjmp_buffer, 1); -} - -static int* -load_jpg_file( const char *file, - int *width, - int *height) -{ - struct jpeg_decompress_struct cinfo; - struct local_error_mgr jerr; - FILE *infile; /* source file */ - JSAMPLE *buffer; /* Output row buffer */ - int row_stride; /* physical row width in output buffer */ - - int *data = NULL, *d = NULL; - - if ((infile = fopen(file, "rb")) == NULL) - return NULL; - - cinfo.err = jpeg_std_error(&jerr.pub); - jerr.pub.error_exit = _jpeg_error_exit; - - if (setjmp(jerr.setjmp_buffer)) { - jpeg_destroy_decompress(&cinfo); - fclose(infile); - return NULL; - } - - jpeg_create_decompress(&cinfo); - jpeg_stdio_src(&cinfo, infile); - jpeg_read_header(&cinfo, TRUE); - - cinfo.do_fancy_upsampling = FALSE; - cinfo.do_block_smoothing = FALSE; - cinfo.out_color_space = JCS_RGB; - cinfo.scale_num = 1; - - jpeg_start_decompress(&cinfo); - - if( cinfo.output_components != 3 ) - { - /* - fprintf( stderr, "mbpixbuf: jpegs with %d channles not supported\n", - cinfo.output_components ); - */ - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - return NULL; - } - - *width = cinfo.output_width; - *height = cinfo.output_height; - - d = data = malloc(*width * *height * 4 ); - - row_stride = cinfo.output_width * cinfo.output_components; - buffer = malloc( sizeof(JSAMPLE)*row_stride ); - - while (cinfo.output_scanline < cinfo.output_height) - { - int off = 0; - - jpeg_read_scanlines(&cinfo, &buffer, 1); - - while (off < row_stride) - { - /* XXX Endianess */ - *d++ = - (buffer[off] << 24) | /* RGBA */ - (buffer[off+1] << 16) | - (buffer[off+2] << 8) | - (0xff << 0); - off += 3; - } - } - - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - fclose(infile); - - if (buffer) free(buffer); - - return data; -} - -/* X pcx code, based on usplash code by paul coden */ -/* http://courses.ece.uiuc.edu/ece390/books/labmanual/graphics-pcx.html */ - -typedef struct -{ - unsigned char manufacturer; - unsigned char version; - unsigned char encoding; - unsigned char bits_per_pixel; - unsigned short xmin; - unsigned short ymin; - unsigned short xmax; - unsigned short ymax; - unsigned short xdpi; - unsigned short ydpi; - unsigned char colourmap[48]; - unsigned char reserved; - unsigned char planes; - unsigned short scanline_length; - unsigned short palette_info; - unsigned short xsize; - unsigned short ysize; - unsigned char fill[54]; - unsigned char data[0]; -} pcx; - -enum -{ - PCX_ZSOFT = 10, - PCX_RLE = 1, - PCX_WITH_PALETTE = 2, - PCX_COLOUR_MAP_LENGTH = 769 -}; - - -/* -** Reads the first 128 bytes of a PCX headers, from an file -** descriptor, into memory. -** RETURN zero on success. -*/ -int -pcx_read_header(pcx *header, int fd) -{ - if(!lseek(fd, 0, SEEK_SET)) - if(read(fd, header, sizeof(pcx)) == sizeof(pcx)) - return 0; - return -1; -} - -/* -** Does the file descriptor point to a PCX file, which is of a -** suitable colour-depth (8-bit) for us to use? -** RETURN zero on success. -*/ -static int -pcx_is_suitable(int fd) -{ - pcx header; - if(!pcx_read_header(&header, fd)) - if(header.manufacturer == PCX_ZSOFT - /* && header.version >= PCX_WITH_PALETTE && */ - && header.encoding == PCX_RLE - && header.planes == 3 /* 24bpp */ - && header.bits_per_pixel == 8 ) /* why not 24 from gimp */ - return 0; - - return -1; -} - -/* -** Takes a raw PCX RLE stream and decompresses it into the destination -** buffer, which must be big enough! -** RETURN zero on success -** -** PCX images are RLE (Run Length Encoded as follows: -** if(top two bits are set) // >= 0xc0 -** use bottom six bit (& 0x3f) as RLE count for next byte; -** else // < 0xc0 -** copy one byte normally; -*/ -static void -pcx_raw_decode24(int *dest, - unsigned char *src, - int width, - int height) -{ - int x, y, i, count; - int *d = dest; - unsigned char *p; - - memset(dest, 0xff, height * width * 4); - - for(y = 0; y < height; y++) - { - d = dest + (y * width); - /* RGB */ - for(x = 0; x < width;) - if(*src < 0xc0) - { - x++; - p = (unsigned char *)d++; - *p = *src++; - } - else - { - count = *src++ & 0x3f; - for (i=0; ixmax - header->xmin + 1; - *height = header->ymax - header->ymin + 1; - - /* Allocate enough room for the data and colourmap*/ - data = malloc(*width * *height * 4); - - if (!data) - { - munmap(header, file_length); - return NULL; - } - - /* Decode the data */ - pcx_raw_decode24(data, header->data, *width, *height); - - /* Clean up */ - munmap(header, file_length); - - close(fd); - - return data; -} - - -/* -------------------------------------------------------------------- */ - -Pixbuf* -pixbuf_new(int width, int height) -{ - Pixbuf *pixb; - - pixb = util_malloc0(sizeof(Pixbuf)); - - pixb->width = width; - pixb->height = height; - pixb->bytes_per_pixel = 4; - pixb->channels = 4; - pixb->bytes_per_line = pixb->bytes_per_pixel * pixb->width; - pixb->data = malloc(pixb->bytes_per_line * pixb->height); - - memset(pixb->data, 0, pixb->bytes_per_line * pixb->height); - - return pixb; -} - -void -pixbuf_unref(Pixbuf *pixb) -{ - pixb->refcnt--; - - if (pixb->refcnt < 0) - { - free(pixb->data); - free(pixb); - } -} - -void -pixbuf_ref(Pixbuf *pixb) -{ - pixb->refcnt++; -} - -Pixbuf* -pixbuf_new_from_file(const char *filename) -{ - Pixbuf *pixb; - - pixb = util_malloc0(sizeof(Pixbuf)); - - if (!strcasecmp(&filename[strlen(filename)-4], ".png")) - pixb->data =load_png_file(filename, &pixb->width, &pixb->height); - else if (!strcasecmp(&filename[strlen(filename)-4], ".jpg") - || !strcasecmp(&filename[strlen(filename)-5], ".jpeg")) - pixb->data = load_jpg_file( filename, &pixb->width, &pixb->height); - else if (!strcasecmp(&filename[strlen(filename)-4], ".pcx")) - pixb->data = load_pcx_file( filename, &pixb->width, &pixb->height); - - if (pixb->data == NULL) - { - free (pixb); - return NULL; - } - - pixb->bytes_per_pixel = 4; - pixb->channels = 4; - pixb->bytes_per_line = pixb->bytes_per_pixel * pixb->width; - - return pixb; -} - -void -pixbuf_set_pixel(Pixbuf *pixb, int x, int y, PixbufPixel *p) -{ - int *offset = pixb->data + ( y * pixb->width) + x; - - /* ARGB_32 MSB */ - - // *offset = (p->r << 0) | (p->g << 8) | (p->b << 16) | (p->a << 24); - *offset = ( (p->r << 24) | (p->g << 16) | (p->b << 8) | (p->a) ); - - /* - printf("set %i,%i,%i,%i\n", p->r, p->g, p->b, p->a); - printf("Looks like %i %x\n", *offset, *offset); - */ -} - -void -pixbuf_get_pixel(Pixbuf *pixb, int x, int y, PixbufPixel *p) -{ - int *offset = pixb->data + ( y * pixb->width) + x; - - /* ARGB_32 MSB */ - - p->r = (*offset >> 24) & 0xff; - p->g = (*offset >> 16) & 0xff; - p->b = (*offset >> 8) & 0xff; - p->a = *offset & 0xff; - -} - -void /* XXX could be DEFINE */ -pixel_set_vals(PixbufPixel *p, - const unsigned char r, - const unsigned char g, - const unsigned char b, - const unsigned char a) -{ - p->r = r; p->g = g; p->b = b; p->a = a; -} - -void -pixbuf_copy(Pixbuf *src_pixb, - Pixbuf *dst_pixb, - int srcx, - int srcy, - int srcw, - int srch, - int dstx, - int dsty) -{ - int j, *sp, *dp; - - sp = src_pixb->data + (srcy * src_pixb->width) + srcx; - dp = dst_pixb->data + (dsty * dst_pixb->width) + dstx; - - /* basic source clipping - needed by texture tiling code */ - - if (srcx + srcw > src_pixb->width) - srcw = src_pixb->width - srcx; - - if (srcy + srch > src_pixb->height) - srch = src_pixb->height - srcy; - - while (srch--) - { - j = srcw; - while (j--) - *dp++ = *sp++; - dp += (dst_pixb->width - srcw); - sp += (src_pixb->width - srcw); - } -} - -void -pixbuf_fill_rect(Pixbuf *pixb, - int x, - int y, - int width, - int height, - PixbufPixel *p) -{ - int i, j; - - if (width < 0) width = pixb->width; - if (height < 0) height = pixb->height; - - for (i = x; i pixb->width || new_height > pixb->height) - return NULL; - - pixb_scaled = pixbuf_new(new_width, new_height); - - xsample = malloc( (new_width+1) * sizeof(int)); - ysample = malloc( (new_height+1) * sizeof(int)); - - for ( i = 0; i <= new_width; i++ ) - xsample[i] = i * pixb->width / new_width; - - for ( i = 0; i <= new_height; i++ ) - ysample[i] = i * pixb->height / new_height * pixb->width; - - dest = pixb_scaled->data; - - /* scan output image */ - for ( y = 0; y < new_height; y++ ) - { - yrange = ( ysample[y+1] - ysample[y] ) / pixb->width; - for ( x = 0; x < new_width; x++) - { - xrange = xsample[x+1] - xsample[x]; - srcy = pixb->data + ( ysample[y] + xsample[x] ); - - /* average R,G,B,A values on sub-rectangle of source image */ - nb_samples = xrange * yrange; - - if ( nb_samples > 1 ) - { - r = 0; g = 0; b = 0; a = 0; - for ( ry = 0; ry < yrange; ry++ ) - { - src = srcy; - for ( rx = 0; rx < xrange; rx++ ) - { - /* average R,G,B,A values */ - r += *src & 0xff; - g += ((*src) >> 8) & 0xff; - b += ((*src) >> 16) & 0xff; - a += ((*src) >> 24) & 0xff; - - src++; - } - - srcy += pixb->width; - } - - *dest++ = - ((unsigned char)(r/nb_samples) << 0) | - ((unsigned char)(g/nb_samples) << 8) | - ((unsigned char)(b/nb_samples) << 16) | - ((unsigned char)(a/nb_samples) << 24); - } - else - { - *dest++ = *srcy++; - } - } - } - - /* cleanup */ - free( xsample ); - free( ysample ); - - return pixb_scaled; -} - -Pixbuf* -pixbuf_clone(Pixbuf *pixb) -{ - Pixbuf *clone; - - if (pixb == NULL) - return NULL; - - clone = util_malloc0(sizeof(Pixbuf)); - - clone->width = pixb->width; - clone->height = pixb->height; - clone->bytes_per_pixel = pixb->bytes_per_pixel; - clone->channels = pixb->channels; - clone->bytes_per_line = pixb->bytes_per_line; - clone->data = malloc(pixb->bytes_per_line * pixb->height); - - memcpy(clone->data, pixb->data, pixb->bytes_per_line * pixb->height); - - return clone; -} - -Pixbuf* -pixbuf_convolve(Pixbuf *pixb, - int *kernel, - int kernel_size, - int kernel_divisor) -{ - int padding, x, y, r, g, b, a, l, k; - PixbufPixel pixel; - Pixbuf *clone_pixb; - - padding = ( kernel_size - 1 ) / 2; - clone_pixb = pixbuf_clone(pixb); - - for( y = padding; y < pixb->height - padding; y++ ) - { - for( x = padding; x < pixb->width - padding; x++ ) - { - r = b = g = a = 0; - - for( l = 0; l < kernel_size; l++ ) - { - for( k = 0; k < kernel_size; k++ ) - { - pixbuf_get_pixel(pixb, (x+k-padding), (y+l-padding), &pixel); - - r += pixel.r * kernel[k + l * kernel_size]; - g += pixel.g * kernel[k + l * kernel_size]; - b += pixel.b * kernel[k + l * kernel_size]; - a += pixel.a * kernel[k + l * kernel_size]; - } - } - - r = CLTR_CLAMP( r / kernel_divisor, 0xff); - g = CLTR_CLAMP( g / kernel_divisor, 0xff); - b = CLTR_CLAMP( b / kernel_divisor, 0xff); - a = CLTR_CLAMP( a / kernel_divisor, 0xff); - - pixel_set_vals(&pixel, r, g, b, a); - - pixbuf_set_pixel(clone_pixb, x, y, &pixel); - - } - } - - return clone_pixb; -} - -Pixbuf* -pixbuf_blur(Pixbuf *pixb) -{ - /* - int kernel[] = { 1, 1, 1, - 1, 0, 1, - 1, 1, 1 }; - */ - - int kernel[] = { 1, 1, 1, - 1, 1, 1, - 1, 1, 1 }; - - - return pixbuf_convolve( pixb, kernel, 3, 9 ); -} - -Pixbuf* -pixbuf_sharpen(Pixbuf *pixb) -{ - int kernel[] = {-1, -1, -1, - -1, 9, -1, - -1, -1, -1 }; - - return pixbuf_convolve( pixb, kernel, 3, 1 ); -} - - -#if 0 - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% C o n v o l v e I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% Method ConvolveImage applies a general image convolution kernel to an -% image returns the results. ConvolveImage allocates the memory necessary for -% the new Image structure and returns a pointer to the new image. -% -% The format of the ConvolveImage method is: -% -% Image *ConvolveImage(Image *image,const unsigned int order, -% const double *kernel,ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o convolve_image: Method ConvolveImage returns a pointer to the image -% after it is convolved. A null image is returned if there is a memory -% shortage. -% -% o image: The address of a structure of type Image; returned from -% ReadImage. -% -% o order: The number of columns and rows in the filter kernel. -% -% o kernel: An array of double representing the convolution kernel. -% -% o exception: return any errors or warnings in this structure. -% -% -*/ -MagickExport Image *ConvolveImage(Image *image, - const unsigned int order, - const double *kernel, - ExceptionInfo *exception) -{ -#define ConvolveImageText " Convolving image... " -#define Cx(x) \ - (x) < 0 ? (x)+image->columns : (x) >= image->columns ? (x)-image->columns : x -#define Cy(y) \ - (y) < 0 ? (y)+image->rows : (y) >= image->rows ? (y)-image->rows : y - - double - blue, - green, - normalize, - opacity, - red; - - Image - *convolve_image; - - int - i, - width, - y; - - PixelPacket - *p, - pixel; - - register const double - *k; - - register int - u, - v, - x; - - register PixelPacket - *q, - *s; - - /* - Initialize convolved image attributes. - */ - assert(image != (Image *) NULL); - assert(image->signature == MagickSignature); - assert(exception != (ExceptionInfo *) NULL); - assert(exception->signature == MagickSignature); - width=order; - if ((width % 2) == 0) - ThrowImageException(OptionWarning,"Unable to convolve image", - "kernel width must be an odd number"); - if ((image->columns < width) || (image->rows < width)) - ThrowImageException(OptionWarning,"Unable to convolve image", - "image smaller than kernel width"); - convolve_image=CloneImage(image,image->columns,image->rows,False,exception); - if (convolve_image == (Image *) NULL) - return((Image *) NULL); - convolve_image->storage_class=DirectClass; - /* - Convolve image. - */ - normalize=0.0; - for (i=0; i < (width*width); i++) - normalize+=kernel[i]; - for (y=0; y < (int) convolve_image->rows; y++) - { - p=(PixelPacket *) NULL; - q=SetImagePixels(convolve_image,0,y,convolve_image->columns,1); - if (q == (PixelPacket *) NULL) - break; - for (x=0; x < (int) convolve_image->columns; x++) - { - red=0.0; - green=0.0; - blue=0.0; - opacity=0.0; - k=kernel; - if ((x < (width/2)) || (x >= (int) (image->columns-width/2)) || - (y < (width/2)) || (y >= (int) (image->rows-width/2))) - { - for (v=(-width/2); v <= (width/2); v++) - { - for (u=(-width/2); u <= (width/2); u++) - { - pixel=GetOnePixel(image,Cx(x+u),Cy(y+v)); - red+=(*k)*pixel.red; - green+=(*k)*pixel.green; - blue+=(*k)*pixel.blue; - opacity+=(*k)*pixel.opacity; - k++; - } - } - } - else - { - if (p == (PixelPacket *) NULL) - { - p=GetImagePixels(image,0,y-width/2,image->columns,width); - if (p == (PixelPacket *) NULL) - break; - } - s=p+x; - for (v=(-width/2); v <= (width/2); v++) - { - for (u=(-width/2); u <= (width/2); u++) - { - red+=(*k)*s[u].red; - green+=(*k)*s[u].green; - blue+=(*k)*s[u].blue; - opacity+=(*k)*s[u].opacity; - k++; - } - s+=image->columns; - } - } - if ((normalize != 0.0) && (normalize != 1.0)) - { - red/=normalize; - green/=normalize; - blue/=normalize; - opacity/=normalize; - } - q->red=(Quantum) ((red < 0) ? 0 : (red > MaxRGB) ? MaxRGB : red+0.5); - q->green=(Quantum) - ((green < 0) ? 0 : (green > MaxRGB) ? MaxRGB : green+0.5); - q->blue=(Quantum) ((blue < 0) ? 0 : (blue > MaxRGB) ? MaxRGB : blue+0.5); - q->opacity=(Quantum) - ((opacity < 0) ? 0 : (opacity > MaxRGB) ? MaxRGB : opacity+0.5); - q++; - } - if (!SyncImagePixels(convolve_image)) - break; - if (QuantumTick(y,convolve_image->rows)) - MagickMonitor(ConvolveImageText,y,convolve_image->rows); - } - return(convolve_image); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% G a u s s i a n B l u r I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% Method GaussianBlurImage creates a new image that is a copy of an existing -% one with the pixels blur. It allocates the memory necessary for the -% new Image structure and returns a pointer to the new image. -% -% The format of the BlurImage method is: -% -% Image *GaussianBlurImage(Image *image,const double radius, -% const double sigma,ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o blur_image: Method GaussianBlurImage returns a pointer to the image -% after it is blur. A null image is returned if there is a memory -% shortage. -% -% o radius: the radius of the Gaussian, in pixels, not counting the center -% pixel. -% -% o sigma: the standard deviation of the Gaussian, in pixels. -% -% o exception: return any errors or warnings in this structure. -% -% -*/ -MagickExport Image *GaussianBlurImage(Image *image,const double radius, - const double sigma,ExceptionInfo *exception) -{ - double - *kernel; - - Image - *blur_image; - - int - width; - - register int - i, - u, - v; - - assert(image != (Image *) NULL); - assert(image->signature == MagickSignature); - assert(exception != (ExceptionInfo *) NULL); - assert(exception->signature == MagickSignature); - width=GetOptimalKernelWidth2D(radius,sigma); - if ((image->columns < width) || (image->rows < width)) - ThrowImageException(OptionWarning,"Unable to Gaussian blur image", - "image is smaller than radius"); - kernel=(double *) AcquireMemory(width*width*sizeof(double)); - if (kernel == (double *) NULL) - ThrowImageException(ResourceLimitWarning,"Unable to Gaussian blur image", - "Memory allocation failed"); - i=0; - for (v=(-width/2); v <= (width/2); v++) - { - for (u=(-width/2); u <= (width/2); u++) - { - kernel[i]=exp((double) -(u*u+v*v)/(sigma*sigma)); - i++; - } - } - blur_image=ConvolveImage(image,width,kernel,exception); - LiberateMemory((void **) &kernel); - return(blur_image); -} - -/* GPE-gallery convolve code */ - -static void -image_convolve( GdkPixbuf *pixbuf, - int *mask, - int mask_size, - int mask_divisor ) { - - int x, y, k, l, b, rowstride, width, height, channels, padding, new_value; - int* temp_pixel; - guchar *temp_image, *image; - - rowstride = gdk_pixbuf_get_rowstride( GDK_PIXBUF( pixbuf ) ); - channels = gdk_pixbuf_get_n_channels( GDK_PIXBUF( pixbuf ) ); - - width = gdk_pixbuf_get_width( GDK_PIXBUF( pixbuf ) ); - height = gdk_pixbuf_get_height( GDK_PIXBUF( pixbuf ) ); - - // fprintf( stderr, "Rowstride: %d, width: %d, height: %d, channels: %d\n", rowstride, width, height, channels ); - - - padding = ( mask_size - 1 ) / 2; - - image = gdk_pixbuf_get_pixels( GDK_PIXBUF( pixbuf ) ); - temp_image = (guchar*) malloc( width * height * channels * sizeof( guchar ) ); - memcpy( temp_image, image, width * height * channels * sizeof( guchar ) ); - temp_pixel =(int*) malloc( channels * sizeof( int ) ); - for( y = padding; y < height - padding; y++ ) { - - for( x = padding; x < width - padding; x++ ) { - - for( b = 0; b < channels; b++ ) - temp_pixel[b] = 0; - - for( l = 0; l < mask_size; l++ ) { - - for( k = 0; k < mask_size; k++ ) { - - for( b = 0; b < channels; b++ ) - temp_pixel[b] += temp_image[ ( y + l - padding ) * rowstride - + ( x + k - padding ) * channels + b ] * mask[ k + l * - mask_size ]; - - } - - } - - for( b = 0; b < channels; b++ ) { - - new_value = temp_pixel[b] / mask_divisor; - image[ y * rowstride + x * channels + b ] = ( new_value > 255 ? 255 - : new_value < 0 ? 0 : new_value ); - - } - - } - - } - - - free( temp_image ); - free( temp_pixel ); - -} - -void image_tools_blur( GdkPixbuf* pixbuf ) { - - int mask[] = { 1, 1, 1, - 1, 1, 1, - 1, 1, 1 }; - - image_convolve( pixbuf, mask, 3, 9 ); - -} - -void image_tools_sharpen( GdkPixbuf* pixbuf ) { - - int mask[] = {-1, -1, -1, - -1, 9, -1, - -1, -1, -1 }; - - image_convolve( pixbuf, mask, 3, 1 ); - -} - -#endif diff --git a/clutter/pixbuf.h b/clutter/pixbuf.h deleted file mode 100644 index 155d0b953..000000000 --- a/clutter/pixbuf.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef _HAVE_PIXBUF_H -#define _HAVE_PIXBUF_H - -typedef struct Pixbuf Pixbuf; -typedef struct PixbufPixel PixbufPixel; - -typedef enum PixbufFormat -{ - PB_FMT_RGBA -} -PixbufFormat; - -struct PixbufPixel -{ - unsigned char r,g,b,a; -}; - -struct Pixbuf -{ - int *data; - int bytes_per_pixel; /* bits per pixel = bpp << 3 */ - int channels; /* 4 with alpha */ - int width, height; - int bytes_per_line; /* ( width * bpp ) */ - - int refcnt; /* starts at 0 */ - - void *meta; /* for jpeg meta text ? to a hash ? */ - - /* Possibles */ - - int rmask, gmask, bmask, amask; /* Masks - good for packed formats > */ - int has_alpha; /* Rather than channels ? */ - - - /* PixbufFormat format; like GL format */ - -}; - -Pixbuf* -pixbuf_new_from_file(const char *filename); - -Pixbuf* -pixbuf_new(int width, int height); - -void -pixbuf_unref(Pixbuf *pixb); - -void -pixbuf_ref(Pixbuf *pixb); - -void -pixbuf_set_pixel(Pixbuf *pixb, int x, int y, PixbufPixel *p); - -void -pixbuf_get_pixel(Pixbuf *pixbuf, int x, int y, PixbufPixel *p); - -void -pixel_set_vals(PixbufPixel *p, - const unsigned char r, - const unsigned char g, - const unsigned char b, - const unsigned char a); - -void -pixbuf_copy(Pixbuf *src_pixb, - Pixbuf *dst_pixb, - int srcx, - int srcy, - int srcw, - int srch, - int dstx, - int dsty); - -void -pixbuf_fill_rect(Pixbuf *pixb, - int x, - int y, - int width, - int height, - PixbufPixel *p); - - -Pixbuf* -pixbuf_scale_down(Pixbuf *pixb, - int new_width, - int new_height); - -Pixbuf* -pixbuf_clone(Pixbuf *pixb); - -Pixbuf* -pixbuf_convolve(Pixbuf *pixb, - int *kernel, - int kernel_size, - int kernel_divisor) ; - -Pixbuf* -pixbuf_blur(Pixbuf *pixb); - -Pixbuf* -pixbuf_sharpen(Pixbuf *pixb); - - -#endif diff --git a/clutter/util.c b/clutter/util.c deleted file mode 100644 index 67cc5eb65..000000000 --- a/clutter/util.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "util.h" - -/* misc utility code */ - - -void* -util_malloc0(int size) -{ - void *p; - - p = malloc(size); - memset(p, 0, size); - - return p; -} - -int -util_next_p2 ( int a ) -{ - int rval=1; - while(rval < a) - rval <<= 1; - - return rval; -} - diff --git a/clutter/util.h b/clutter/util.h deleted file mode 100644 index 67593acd4..000000000 --- a/clutter/util.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _HAVE_UTIL_H -#define _HAVE_UTIL_H - -#include -#include - -void* -util_malloc0(int size); - -int -util_next_p2 ( int a ); - -#endif diff --git a/configure.ac b/configure.ac index c6688f3c7..97b687856 100644 --- a/configure.ac +++ b/configure.ac @@ -1,11 +1,39 @@ AC_PREREQ(2.53) -AC_INIT([clutter], 0.0.1, [mallum@o-hand.com]) -AC_CONFIG_SRCDIR([clutter/cltr.h]) -AM_INIT_AUTOMAKE() +# clutter package version number, (as distinct from shared library version) +# An odd micro number indicates in-progress development, (eg. from CVS) +# An even micro number indicates a released version. +m4_define(clutter_version_major, 0) +m4_define(clutter_version_minor, 0) +m4_define(clutter_version_micro, 1) +AC_INIT([clutter], + clutter_version_major.clutter_version_minor.clutter_version_micro, + [mallum@o-hand.com]) +AC_CONFIG_SRCDIR([clutter/clutter.h]) AM_CONFIG_HEADER([config.h]) +AM_INIT_AUTOMAKE([1.7]) + +CLUTTER_MAJORMINOR=clutter_version_major.clutter_version_minor +AC_SUBST(CLUTTER_MAJORMINOR) + +# CURRENT, REVISION, AGE +# - library source changed -> increment REVISION +# - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 +# - interfaces added -> increment AGE +# - interfaces removed -> AGE = 0 +CLUTTER_LT_CURRENT=0 +CLUTTER_LT_REV=0 +CLUTTER_LT_AGE=0 +CLUTTER_LT_VERSION="$CLUTTER_LT_CURRENT:$CLUTTER_LT_REV:$CLUTTER_LT_AGE" +CLUTTER_LT_LDFLAGS="-version-info $CLUTTER_LT_VERSION" + +AC_SUBST(CLUTTER_LT_VERSION) +AC_SUBST(CLUTTER_LT_LDFLAGS) + +dnl ======================================================================== + # Checks for programs. AC_PROG_CC AC_PROG_LIBTOOL @@ -22,12 +50,13 @@ AC_FUNC_MALLOC AC_FUNC_MMAP AC_CHECK_FUNCS([memset munmap strcasecmp strdup]) -dnl ------ X + GL ------------------------------------------------------------- + +dnl ======================================================================== + +# FIXME: redo below AC_PATH_XTRA -# below is broken - if test "x$have_x" = "xyes"; then GLX_LIBS="$X_LIBS -lX11 -lGL" GLX_CFLAGS="$X_CFLAGS" @@ -56,75 +85,109 @@ if test "x$have_x" = "xyes"; then AC_DEFINE([XTHREADS], [], [1]) fi else - AC_MSG_ERROR([*** Cannot find X + GL****]) + AC_MSG_ERROR([*** Cannot find X + GL ****]) fi -dnl ----- Pango, glib etc --------------------------------------------------- +dnl ======================================================================== -pkg_modules="pangoft2 glib-2.0 gthread-2.0" -PKG_CHECK_MODULES(CLTR, pangoft2 glib-2.0 gthread-2.0) +pkg_modules="pangoft2 glib-2.0 >= 2.8 gthread-2.0 gdk-pixbuf-2.0" +PKG_CHECK_MODULES(CLUTTER, [$pkg_modules]) -dnl ----- Gstreamer --------------------------------------------------------- +dnl ======================================================================== -pkg_modules="gstreamer-0.8 gstreamer-interfaces-0.8 gthread-2.0 gstreamer-play-0.8 gstreamer-gconf-0.8" +GST_MAJORMINOR=0.10 + +pkg_modules="gstreamer-$GST_MAJORMINOR gstreamer-plugins-base-$GST_MAJORMINOR" 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 ------ 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 --------------------------------------------------------------- +dnl ======================================================================== if test "x$GCC" = "xyes"; then GCC_FLAGS="-g -Wall" 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_LIBS) -AC_SUBST(GCONF_CFLAGS) -AC_SUBST(GCONF_LIBS) +CLUTTER_CFLAGS="$GLX_CLAGS $CLUTTER_CFLAGS" +CLUTTER_LIBS="$GLX_LIBS $CLUTTER_LIBS" -CLTR_CFLAGS="$GLX_CLAGS $CLTR_CFLAGS" -CLTR_LIBS="$GLX_LIBS $PNG_LIBS $JPEG_LIBS $CLTR_LIBS" - -AC_SUBST(CLTR_CFLAGS) -AC_SUBST(CLTR_LIBS) +AC_SUBST(CLUTTER_CFLAGS) +AC_SUBST(CLUTTER_LIBS) AC_OUTPUT([Makefile clutter/Makefile +bindings/Makefile +bindings/python/Makefile examples/Makefile -gst/Makefile +doc/Makefile +doc/reference/Makefile +clutter.pc ]) diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 000000000..b68c77455 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1 @@ +SUBDIRS=reference diff --git a/doc/reference/ChangeLog b/doc/reference/ChangeLog new file mode 100644 index 000000000..10e32858c --- /dev/null +++ b/doc/reference/ChangeLog @@ -0,0 +1,19 @@ +2006-05-26 Emmanuele Bassi + + 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 + + A tmpl + A tmpl/*.sgml + + * tmpl/*.sgml: Add gtk-doc templates. + +2006-05-26 Emmanuele Bassi + + * *: Initial entry. + diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am new file mode 100644 index 000000000..8e3111faa --- /dev/null +++ b/doc/reference/Makefile.am @@ -0,0 +1,78 @@ +## Process this file with automake to produce Makefile.in + +# We require automake 1.6 at least. +AUTOMAKE_OPTIONS = 1.6 + +# This is a blank Makefile.am for using gtk-doc. +# Copy this to your project's API docs directory and modify the variables to +# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples +# of using the various options. + +# The name of the module, e.g. 'glib'. +DOC_MODULE=clutter-@CLUTTER_MAJORMINOR@ + +# The top-level SGML file. You can change this if you want to. +DOC_MAIN_SGML_FILE=clutter-docs.sgml + +# The directory containing the source code. Relative to $(srcdir). +# gtk-doc will search all .c & .h files beneath here for inline comments +# documenting the functions and macros. +# e.g. DOC_SOURCE_DIR=../../../gtk +DOC_SOURCE_DIR=../../clutter + +# Extra options to pass to gtkdoc-scangobj. Not normally needed. +SCANGOBJ_OPTIONS= + +# Extra options to supply to gtkdoc-scan. +# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" +SCAN_OPTIONS= + +# Extra options to supply to gtkdoc-mkdb. +# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml +MKDB_OPTIONS=--sgml-mode --output-format=xml + +# Extra options to supply to gtkdoc-mktmpl +# e.g. MKTMPL_OPTIONS=--only-section-tmpl +MKTMPL_OPTIONS= + +# Extra options to supply to gtkdoc-fixref. Not normally needed. +# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html +FIXXREF_OPTIONS= + +# Used for dependencies. The docs will be rebuilt if any of these change. +# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h +# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c +HFILE_GLOB=$(top_srcdir)/clutter/*.h +CFILE_GLOB=$(top_srcdir)/clutter/*.c + +# Header files to ignore when scanning. +# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h +IGNORE_HFILES=clutter-private.h stamp-clutter-enum-types.h + +# Images to copy into HTML directory. +# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png +HTML_IMAGES= + +# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). +# e.g. content_files=running.sgml building.sgml changes-2.0.sgml +content_files= + +# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded +# These files must be listed here *and* in content_files +# e.g. expand_content_files=running.sgml +expand_content_files= + +# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. +# Only needed if you are using gtkdoc-scangobj to dynamically query widget +# signals and properties. +# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) +# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) +INCLUDES=-I$(top_srcdir) $(CLUTTERR_CFLAGS) +GTKDOC_LIBS=$(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la $(CLUTTER_LIBS) + +# This includes the standard gtk-doc make rules, copied by gtkdocize. +include $(top_srcdir)/gtk-doc.make + +# Other files to distribute +# e.g. EXTRA_DIST += version.xml.in +#EXTRA_DIST += diff --git a/doc/reference/clutter-0.0-sections.txt b/doc/reference/clutter-0.0-sections.txt new file mode 100644 index 000000000..487e8fc46 --- /dev/null +++ b/doc/reference/clutter-0.0-sections.txt @@ -0,0 +1,1689 @@ +
+clutter-label +ClutterLabel +ClutterLabel +ClutterLabelClass +clutter_label_new_with_text +clutter_label_new +clutter_label_set_text +clutter_label_set_font +clutter_label_set_color +clutter_label_set_text_extents + +CLUTTER_LABEL +CLUTTER_IS_LABEL +CLUTTER_TYPE_LABEL +CLUTTER_LABEL_CLASS +CLUTTER_IS_LABEL_CLASS +CLUTTER_LABEL_GET_CLASS + +ClutterLabelPrivate +clutter_label_get_type +
+ +
+clutter-element +ClutterElement +CLUTTER_TYPE_GEOMETRY +CLUTTER_TYPE_ELEMENT_BOX +CLUTTER_ELEMENT_SET_FLAGS +CLUTTER_ELEMENT_UNSET_FLAGS +CLUTTER_ELEMENT_IS_MAPPED +CLUTTER_ELEMENT_IS_REALIZED +CLUTTER_ELEMENT_IS_VISIBLE +ClutterElementBox +ClutterGeometry +ClutterElementTransform +ClutterElementFlags +clutter_element_box_get_type +ClutterElement +ClutterElementClass +clutter_element_get_type +clutter_element_show +clutter_element_hide +clutter_element_realize +clutter_element_unrealize +clutter_element_paint +clutter_element_queue_redraw +clutter_element_request_coords +clutter_element_allocate_coords +clutter_element_set_geometry +clutter_element_get_geometry +clutter_element_get_coords +clutter_element_set_position +clutter_element_set_size +clutter_element_get_abs_position +clutter_element_get_width +clutter_element_get_height +clutter_element_get_x +clutter_element_get_y +clutter_element_rotate_z +clutter_element_rotate_x +clutter_element_rotate_y +clutter_element_set_opacity +clutter_element_get_opacity +clutter_element_set_name +clutter_element_get_name +clutter_element_get_id +clutter_element_set_clip +clutter_element_remove_clip +clutter_element_set_parent +clutter_element_get_parent +clutter_element_raise +clutter_element_lower +clutter_element_raise_top +clutter_element_lower_bottom + +CLUTTER_ELEMENT +CLUTTER_IS_ELEMENT +CLUTTER_TYPE_ELEMENT +CLUTTER_ELEMENT_CLASS +CLUTTER_IS_ELEMENT_CLASS +CLUTTER_ELEMENT_GET_CLASS + +clutter_geometry_get_type +ClutterElementPrivate +
+ +
+clutter-group +ClutterGroupPrivate +ClutterGroup +ClutterGroup +clutter_group_new +clutter_group_add +clutter_group_add_many_valist +clutter_group_add_many +clutter_group_remove +clutter_group_show_all +clutter_group_hide_all +clutter_group_find_child_by_id +clutter_group_raise +clutter_group_lower + +CLUTTER_GROUP +CLUTTER_IS_GROUP +CLUTTER_TYPE_GROUP +clutter_group_get_type +CLUTTER_GROUP_CLASS +CLUTTER_IS_GROUP_CLASS +CLUTTER_GROUP_GET_CLASS +
+ +
+clutter-clone-texture +ClutterCloneTexturePrivate +ClutterCloneTexture +ClutterCloneTexture +clutter_clone_texture_new + +CLUTTER_CLONE_TEXTURE +CLUTTER_IS_CLONE_TEXTURE +CLUTTER_TYPE_CLONE_TEXTURE +clutter_clone_texture_get_type +CLUTTER_CLONE_TEXTURE_CLASS +CLUTTER_IS_CLONE_TEXTURE_CLASS +CLUTTER_CLONE_TEXTURE_GET_CLASS +
+ +
+clutter-texture +ClutterTexturePrivate +ClutterTexture +ClutterTexture +clutter_texture_new_from_pixbuf +clutter_texture_new +clutter_texture_set_pixbuf +clutter_texture_get_pixbuf +clutter_texture_get_base_size +clutter_texture_bind_tile +clutter_texture_get_n_tiles +clutter_texture_get_x_tile_detail +clutter_texture_get_y_tile_detail +clutter_texture_has_generated_tiles +clutter_texture_is_tiled + +CLUTTER_TEXTURE +CLUTTER_IS_TEXTURE +CLUTTER_TYPE_TEXTURE +clutter_texture_get_type +CLUTTER_TEXTURE_CLASS +CLUTTER_IS_TEXTURE_CLASS +CLUTTER_TEXTURE_GET_CLASS +
+ +
+clutter-stage +CLUTTER_STAGE_WIDTH +CLUTTER_STAGE_HEIGHT +ClutterStagePrivate +ClutterStage +ClutterStage +clutter_stage_get_xwindow +clutter_stage_set_color +clutter_stage_get_color +clutter_stage_pick + +CLUTTER_STAGE +CLUTTER_IS_STAGE +CLUTTER_TYPE_STAGE +clutter_stage_get_type +CLUTTER_STAGE_CLASS +CLUTTER_IS_STAGE_CLASS +CLUTTER_STAGE_GET_CLASS +
+ +
+clutter-rectangle +ClutterRectanglePrivate +ClutterRectangle +ClutterRectangle +clutter_rectangle_new + +CLUTTER_RECTANGLE +CLUTTER_IS_RECTANGLE +CLUTTER_TYPE_RECTANGLE +clutter_rectangle_get_type +CLUTTER_RECTANGLE_CLASS +CLUTTER_IS_RECTANGLE_CLASS +CLUTTER_RECTANGLE_GET_CLASS +
+ +
+clutter-video-texture +ClutterVideoTexturePrivate +CLUTTER_VIDEO_TEXTURE_ERROR +ClutterVideoTextureError +clutter_video_texture_error_quark +ClutterVideoTextureAspectRatio +ClutterVideoTexture +ClutterVideoTexture +clutter_video_texture_new +clutter_video_texture_open +clutter_video_texture_play +clutter_video_texture_pause +clutter_video_texture_can_direct_seek +clutter_video_texture_seek_time +clutter_video_texture_seek +clutter_video_texture_stop +clutter_video_texture_can_set_volume +clutter_video_texture_set_volume +clutter_video_texture_get_volume +clutter_video_texture_get_current_time +clutter_video_texture_get_stream_length +clutter_video_texture_is_playing +clutter_video_texture_is_seekable +clutter_video_texture_get_position +clutter_video_texture_set_aspect_ratio +clutter_video_texture_get_aspect_ratio +ClutterVideoTextureMetadataType +clutter_video_texture_get_metadata + +CLUTTER_VIDEO_TEXTURE +CLUTTER_IS_VIDEO_TEXTURE +CLUTTER_TYPE_VIDEO_TEXTURE +clutter_video_texture_get_type +CLUTTER_VIDEO_TEXTURE_CLASS +CLUTTER_IS_VIDEO_TEXTURE_CLASS +CLUTTER_VIDEO_TEXTURE_GET_CLASS +
+ +
+clutter-timeline +ClutterTimelinePrivate +ClutterTimeline +ClutterTimeline +clutter_timeline_new +clutter_timeline_set_speed +clutter_timeline_start +clutter_timeline_pause +clutter_timeline_stop +clutter_timeline_set_loop +clutter_timeline_rewind +clutter_timeline_skip +clutter_timeline_advance +clutter_timeline_get_current_frame +clutter_timeline_get_n_frames + +CLUTTER_TIMELINE +CLUTTER_IS_TIMELINE +CLUTTER_TYPE_TIMELINE +clutter_timeline_get_type +CLUTTER_TIMELINE_CLASS +CLUTTER_IS_TIMELINE_CLASS +CLUTTER_TIMELINE_GET_CLASS +
+ +
+clutter-util +clutter_util_next_p2 +clutter_util_can_create_texture +
+ +
+clutter-color +clutter_color_r +clutter_color_g +clutter_color_b +clutter_color_a +clutter_color_set_r +clutter_color_set_g +clutter_color_set_b +clutter_color_set_a +ClutterColor +clutter_color_new +clutter_color_set +clutter_color_get +
+ +
+clutter-event +ClutterEventType +ClutterKeyEvent +ClutterButtonEvent +ClutterMotionEvent +ClutterInputDevice +ClutterEvent +clutter_key_event_type +clutter_key_event_time +clutter_key_event_state +clutter_key_event_symbol +clutter_key_event_code +clutter_key_event_unicode +clutter_keysym_to_unicode +
+ +
+clutter-main +CLUTTER_HAS_DEBUG_MESSGES +CLUTTER_DBG +CLUTTER_GLERR +CLUTTER_MARK +clutter_init +clutter_main +clutter_stage +clutter_redraw +clutter_xdisplay +clutter_xscreen +clutter_root_xwindow +clutter_gl_context +clutter_want_debug +clutter_threads_enter +clutter_threads_leave +
+ +
+clutter +
+ +
+clutter-keysyms +CLUTTER_VoidSymbol +CLUTTER_BackSpace +CLUTTER_Tab +CLUTTER_Linefeed +CLUTTER_Clear +CLUTTER_Return +CLUTTER_Pause +CLUTTER_Scroll_Lock +CLUTTER_Sys_Req +CLUTTER_Escape +CLUTTER_Delete +CLUTTER_Multi_key +CLUTTER_Codeinput +CLUTTER_SingleCandidate +CLUTTER_MultipleCandidate +CLUTTER_PreviousCandidate +CLUTTER_Kanji +CLUTTER_Muhenkan +CLUTTER_Henkan_Mode +CLUTTER_Henkan +CLUTTER_Romaji +CLUTTER_Hiragana +CLUTTER_Katakana +CLUTTER_Hiragana_Katakana +CLUTTER_Zenkaku +CLUTTER_Hankaku +CLUTTER_Zenkaku_Hankaku +CLUTTER_Touroku +CLUTTER_Massyo +CLUTTER_Kana_Lock +CLUTTER_Kana_Shift +CLUTTER_Eisu_Shift +CLUTTER_Eisu_toggle +CLUTTER_Kanji_Bangou +CLUTTER_Zen_Koho +CLUTTER_Mae_Koho +CLUTTER_Home +CLUTTER_Left +CLUTTER_Up +CLUTTER_Right +CLUTTER_Down +CLUTTER_Prior +CLUTTER_Page_Up +CLUTTER_Next +CLUTTER_Page_Down +CLUTTER_End +CLUTTER_Begin +CLUTTER_Select +CLUTTER_Print +CLUTTER_Execute +CLUTTER_Insert +CLUTTER_Undo +CLUTTER_Redo +CLUTTER_Menu +CLUTTER_Find +CLUTTER_Cancel +CLUTTER_Help +CLUTTER_Break +CLUTTER_Mode_switch +CLUTTER_script_switch +CLUTTER_Num_Lock +CLUTTER_KP_Space +CLUTTER_KP_Tab +CLUTTER_KP_Enter +CLUTTER_KP_F1 +CLUTTER_KP_F2 +CLUTTER_KP_F3 +CLUTTER_KP_F4 +CLUTTER_KP_Home +CLUTTER_KP_Left +CLUTTER_KP_Up +CLUTTER_KP_Right +CLUTTER_KP_Down +CLUTTER_KP_Prior +CLUTTER_KP_Page_Up +CLUTTER_KP_Next +CLUTTER_KP_Page_Down +CLUTTER_KP_End +CLUTTER_KP_Begin +CLUTTER_KP_Insert +CLUTTER_KP_Delete +CLUTTER_KP_Equal +CLUTTER_KP_Multiply +CLUTTER_KP_Add +CLUTTER_KP_Separator +CLUTTER_KP_Subtract +CLUTTER_KP_Decimal +CLUTTER_KP_Divide +CLUTTER_KP_0 +CLUTTER_KP_1 +CLUTTER_KP_2 +CLUTTER_KP_3 +CLUTTER_KP_4 +CLUTTER_KP_5 +CLUTTER_KP_6 +CLUTTER_KP_7 +CLUTTER_KP_8 +CLUTTER_KP_9 +CLUTTER_F1 +CLUTTER_F2 +CLUTTER_F3 +CLUTTER_F4 +CLUTTER_F5 +CLUTTER_F6 +CLUTTER_F7 +CLUTTER_F8 +CLUTTER_F9 +CLUTTER_F10 +CLUTTER_F11 +CLUTTER_L1 +CLUTTER_F12 +CLUTTER_L2 +CLUTTER_F13 +CLUTTER_L3 +CLUTTER_F14 +CLUTTER_L4 +CLUTTER_F15 +CLUTTER_L5 +CLUTTER_F16 +CLUTTER_L6 +CLUTTER_F17 +CLUTTER_L7 +CLUTTER_F18 +CLUTTER_L8 +CLUTTER_F19 +CLUTTER_L9 +CLUTTER_F20 +CLUTTER_L10 +CLUTTER_F21 +CLUTTER_R1 +CLUTTER_F22 +CLUTTER_R2 +CLUTTER_F23 +CLUTTER_R3 +CLUTTER_F24 +CLUTTER_R4 +CLUTTER_F25 +CLUTTER_R5 +CLUTTER_F26 +CLUTTER_R6 +CLUTTER_F27 +CLUTTER_R7 +CLUTTER_F28 +CLUTTER_R8 +CLUTTER_F29 +CLUTTER_R9 +CLUTTER_F30 +CLUTTER_R10 +CLUTTER_F31 +CLUTTER_R11 +CLUTTER_F32 +CLUTTER_R12 +CLUTTER_F33 +CLUTTER_R13 +CLUTTER_F34 +CLUTTER_R14 +CLUTTER_F35 +CLUTTER_R15 +CLUTTER_Shift_L +CLUTTER_Shift_R +CLUTTER_Control_L +CLUTTER_Control_R +CLUTTER_Caps_Lock +CLUTTER_Shift_Lock +CLUTTER_Meta_L +CLUTTER_Meta_R +CLUTTER_Alt_L +CLUTTER_Alt_R +CLUTTER_Super_L +CLUTTER_Super_R +CLUTTER_Hyper_L +CLUTTER_Hyper_R +CLUTTER_ISO_Lock +CLUTTER_ISO_Level2_Latch +CLUTTER_ISO_Level3_Shift +CLUTTER_ISO_Level3_Latch +CLUTTER_ISO_Level3_Lock +CLUTTER_ISO_Group_Shift +CLUTTER_ISO_Group_Latch +CLUTTER_ISO_Group_Lock +CLUTTER_ISO_Next_Group +CLUTTER_ISO_Next_Group_Lock +CLUTTER_ISO_Prev_Group +CLUTTER_ISO_Prev_Group_Lock +CLUTTER_ISO_First_Group +CLUTTER_ISO_First_Group_Lock +CLUTTER_ISO_Last_Group +CLUTTER_ISO_Last_Group_Lock +CLUTTER_ISO_Left_Tab +CLUTTER_ISO_Move_Line_Up +CLUTTER_ISO_Move_Line_Down +CLUTTER_ISO_Partial_Line_Up +CLUTTER_ISO_Partial_Line_Down +CLUTTER_ISO_Partial_Space_Left +CLUTTER_ISO_Partial_Space_Right +CLUTTER_ISO_Set_Margin_Left +CLUTTER_ISO_Set_Margin_Right +CLUTTER_ISO_Release_Margin_Left +CLUTTER_ISO_Release_Margin_Right +CLUTTER_ISO_Release_Both_Margins +CLUTTER_ISO_Fast_Cursor_Left +CLUTTER_ISO_Fast_Cursor_Right +CLUTTER_ISO_Fast_Cursor_Up +CLUTTER_ISO_Fast_Cursor_Down +CLUTTER_ISO_Continuous_Underline +CLUTTER_ISO_Discontinuous_Underline +CLUTTER_ISO_Emphasize +CLUTTER_ISO_Center_Object +CLUTTER_ISO_Enter +CLUTTER_dead_grave +CLUTTER_dead_acute +CLUTTER_dead_circumflex +CLUTTER_dead_tilde +CLUTTER_dead_macron +CLUTTER_dead_breve +CLUTTER_dead_abovedot +CLUTTER_dead_diaeresis +CLUTTER_dead_abovering +CLUTTER_dead_doubleacute +CLUTTER_dead_caron +CLUTTER_dead_cedilla +CLUTTER_dead_ogonek +CLUTTER_dead_iota +CLUTTER_dead_voiced_sound +CLUTTER_dead_semivoiced_sound +CLUTTER_dead_belowdot +CLUTTER_dead_hook +CLUTTER_dead_horn +CLUTTER_First_Virtual_Screen +CLUTTER_Prev_Virtual_Screen +CLUTTER_Next_Virtual_Screen +CLUTTER_Last_Virtual_Screen +CLUTTER_Terminate_Server +CLUTTER_AccessX_Enable +CLUTTER_AccessX_Feedback_Enable +CLUTTER_RepeatKeys_Enable +CLUTTER_SlowKeys_Enable +CLUTTER_BounceKeys_Enable +CLUTTER_StickyKeys_Enable +CLUTTER_MouseKeys_Enable +CLUTTER_MouseKeys_Accel_Enable +CLUTTER_Overlay1_Enable +CLUTTER_Overlay2_Enable +CLUTTER_AudibleBell_Enable +CLUTTER_Pointer_Left +CLUTTER_Pointer_Right +CLUTTER_Pointer_Up +CLUTTER_Pointer_Down +CLUTTER_Pointer_UpLeft +CLUTTER_Pointer_UpRight +CLUTTER_Pointer_DownLeft +CLUTTER_Pointer_DownRight +CLUTTER_Pointer_Button_Dflt +CLUTTER_Pointer_Button1 +CLUTTER_Pointer_Button2 +CLUTTER_Pointer_Button3 +CLUTTER_Pointer_Button4 +CLUTTER_Pointer_Button5 +CLUTTER_Pointer_DblClick_Dflt +CLUTTER_Pointer_DblClick1 +CLUTTER_Pointer_DblClick2 +CLUTTER_Pointer_DblClick3 +CLUTTER_Pointer_DblClick4 +CLUTTER_Pointer_DblClick5 +CLUTTER_Pointer_Drag_Dflt +CLUTTER_Pointer_Drag1 +CLUTTER_Pointer_Drag2 +CLUTTER_Pointer_Drag3 +CLUTTER_Pointer_Drag4 +CLUTTER_Pointer_Drag5 +CLUTTER_Pointer_EnableKeys +CLUTTER_Pointer_Accelerate +CLUTTER_Pointer_DfltBtnNext +CLUTTER_Pointer_DfltBtnPrev +CLUTTER_3270_Duplicate +CLUTTER_3270_FieldMark +CLUTTER_3270_Right2 +CLUTTER_3270_Left2 +CLUTTER_3270_BackTab +CLUTTER_3270_EraseEOF +CLUTTER_3270_EraseInput +CLUTTER_3270_Reset +CLUTTER_3270_Quit +CLUTTER_3270_PA1 +CLUTTER_3270_PA2 +CLUTTER_3270_PA3 +CLUTTER_3270_Test +CLUTTER_3270_Attn +CLUTTER_3270_CursorBlink +CLUTTER_3270_AltCursor +CLUTTER_3270_KeyClick +CLUTTER_3270_Jump +CLUTTER_3270_Ident +CLUTTER_3270_Rule +CLUTTER_3270_Copy +CLUTTER_3270_Play +CLUTTER_3270_Setup +CLUTTER_3270_Record +CLUTTER_3270_ChangeScreen +CLUTTER_3270_DeleteWord +CLUTTER_3270_ExSelect +CLUTTER_3270_CursorSelect +CLUTTER_3270_PrintScreen +CLUTTER_3270_Enter +CLUTTER_space +CLUTTER_exclam +CLUTTER_quotedbl +CLUTTER_numbersign +CLUTTER_dollar +CLUTTER_percent +CLUTTER_ampersand +CLUTTER_apostrophe +CLUTTER_quoteright +CLUTTER_parenleft +CLUTTER_parenright +CLUTTER_asterisk +CLUTTER_plus +CLUTTER_comma +CLUTTER_minus +CLUTTER_period +CLUTTER_slash +CLUTTER_0 +CLUTTER_1 +CLUTTER_2 +CLUTTER_3 +CLUTTER_4 +CLUTTER_5 +CLUTTER_6 +CLUTTER_7 +CLUTTER_8 +CLUTTER_9 +CLUTTER_colon +CLUTTER_semicolon +CLUTTER_less +CLUTTER_equal +CLUTTER_greater +CLUTTER_question +CLUTTER_at +CLUTTER_A +CLUTTER_B +CLUTTER_C +CLUTTER_D +CLUTTER_E +CLUTTER_F +CLUTTER_G +CLUTTER_H +CLUTTER_I +CLUTTER_J +CLUTTER_K +CLUTTER_L +CLUTTER_M +CLUTTER_N +CLUTTER_O +CLUTTER_P +CLUTTER_Q +CLUTTER_R +CLUTTER_S +CLUTTER_T +CLUTTER_U +CLUTTER_V +CLUTTER_W +CLUTTER_X +CLUTTER_Y +CLUTTER_Z +CLUTTER_bracketleft +CLUTTER_backslash +CLUTTER_bracketright +CLUTTER_asciicircum +CLUTTER_underscore +CLUTTER_grave +CLUTTER_quoteleft +CLUTTER_a +CLUTTER_b +CLUTTER_c +CLUTTER_d +CLUTTER_e +CLUTTER_f +CLUTTER_g +CLUTTER_h +CLUTTER_i +CLUTTER_j +CLUTTER_k +CLUTTER_l +CLUTTER_m +CLUTTER_n +CLUTTER_o +CLUTTER_p +CLUTTER_q +CLUTTER_r +CLUTTER_s +CLUTTER_t +CLUTTER_u +CLUTTER_v +CLUTTER_w +CLUTTER_x +CLUTTER_y +CLUTTER_z +CLUTTER_braceleft +CLUTTER_bar +CLUTTER_braceright +CLUTTER_asciitilde +CLUTTER_nobreakspace +CLUTTER_exclamdown +CLUTTER_cent +CLUTTER_sterling +CLUTTER_currency +CLUTTER_yen +CLUTTER_brokenbar +CLUTTER_section +CLUTTER_diaeresis +CLUTTER_copyright +CLUTTER_ordfeminine +CLUTTER_guillemotleft +CLUTTER_notsign +CLUTTER_hyphen +CLUTTER_registered +CLUTTER_macron +CLUTTER_degree +CLUTTER_plusminus +CLUTTER_twosuperior +CLUTTER_threesuperior +CLUTTER_acute +CLUTTER_mu +CLUTTER_paragraph +CLUTTER_periodcentered +CLUTTER_cedilla +CLUTTER_onesuperior +CLUTTER_masculine +CLUTTER_guillemotright +CLUTTER_onequarter +CLUTTER_onehalf +CLUTTER_threequarters +CLUTTER_questiondown +CLUTTER_Agrave +CLUTTER_Aacute +CLUTTER_Acircumflex +CLUTTER_Atilde +CLUTTER_Adiaeresis +CLUTTER_Aring +CLUTTER_AE +CLUTTER_Ccedilla +CLUTTER_Egrave +CLUTTER_Eacute +CLUTTER_Ecircumflex +CLUTTER_Ediaeresis +CLUTTER_Igrave +CLUTTER_Iacute +CLUTTER_Icircumflex +CLUTTER_Idiaeresis +CLUTTER_ETH +CLUTTER_Eth +CLUTTER_Ntilde +CLUTTER_Ograve +CLUTTER_Oacute +CLUTTER_Ocircumflex +CLUTTER_Otilde +CLUTTER_Odiaeresis +CLUTTER_multiply +CLUTTER_Ooblique +CLUTTER_Ugrave +CLUTTER_Uacute +CLUTTER_Ucircumflex +CLUTTER_Udiaeresis +CLUTTER_Yacute +CLUTTER_THORN +CLUTTER_Thorn +CLUTTER_ssharp +CLUTTER_agrave +CLUTTER_aacute +CLUTTER_acircumflex +CLUTTER_atilde +CLUTTER_adiaeresis +CLUTTER_aring +CLUTTER_ae +CLUTTER_ccedilla +CLUTTER_egrave +CLUTTER_eacute +CLUTTER_ecircumflex +CLUTTER_ediaeresis +CLUTTER_igrave +CLUTTER_iacute +CLUTTER_icircumflex +CLUTTER_idiaeresis +CLUTTER_eth +CLUTTER_ntilde +CLUTTER_ograve +CLUTTER_oacute +CLUTTER_ocircumflex +CLUTTER_otilde +CLUTTER_odiaeresis +CLUTTER_division +CLUTTER_oslash +CLUTTER_ugrave +CLUTTER_uacute +CLUTTER_ucircumflex +CLUTTER_udiaeresis +CLUTTER_yacute +CLUTTER_thorn +CLUTTER_ydiaeresis +CLUTTER_Aogonek +CLUTTER_breve +CLUTTER_Lstroke +CLUTTER_Lcaron +CLUTTER_Sacute +CLUTTER_Scaron +CLUTTER_Scedilla +CLUTTER_Tcaron +CLUTTER_Zacute +CLUTTER_Zcaron +CLUTTER_Zabovedot +CLUTTER_aogonek +CLUTTER_ogonek +CLUTTER_lstroke +CLUTTER_lcaron +CLUTTER_sacute +CLUTTER_caron +CLUTTER_scaron +CLUTTER_scedilla +CLUTTER_tcaron +CLUTTER_zacute +CLUTTER_doubleacute +CLUTTER_zcaron +CLUTTER_zabovedot +CLUTTER_Racute +CLUTTER_Abreve +CLUTTER_Lacute +CLUTTER_Cacute +CLUTTER_Ccaron +CLUTTER_Eogonek +CLUTTER_Ecaron +CLUTTER_Dcaron +CLUTTER_Dstroke +CLUTTER_Nacute +CLUTTER_Ncaron +CLUTTER_Odoubleacute +CLUTTER_Rcaron +CLUTTER_Uring +CLUTTER_Udoubleacute +CLUTTER_Tcedilla +CLUTTER_racute +CLUTTER_abreve +CLUTTER_lacute +CLUTTER_cacute +CLUTTER_ccaron +CLUTTER_eogonek +CLUTTER_ecaron +CLUTTER_dcaron +CLUTTER_dstroke +CLUTTER_nacute +CLUTTER_ncaron +CLUTTER_odoubleacute +CLUTTER_udoubleacute +CLUTTER_rcaron +CLUTTER_uring +CLUTTER_tcedilla +CLUTTER_abovedot +CLUTTER_Hstroke +CLUTTER_Hcircumflex +CLUTTER_Iabovedot +CLUTTER_Gbreve +CLUTTER_Jcircumflex +CLUTTER_hstroke +CLUTTER_hcircumflex +CLUTTER_idotless +CLUTTER_gbreve +CLUTTER_jcircumflex +CLUTTER_Cabovedot +CLUTTER_Ccircumflex +CLUTTER_Gabovedot +CLUTTER_Gcircumflex +CLUTTER_Ubreve +CLUTTER_Scircumflex +CLUTTER_cabovedot +CLUTTER_ccircumflex +CLUTTER_gabovedot +CLUTTER_gcircumflex +CLUTTER_ubreve +CLUTTER_scircumflex +CLUTTER_kra +CLUTTER_kappa +CLUTTER_Rcedilla +CLUTTER_Itilde +CLUTTER_Lcedilla +CLUTTER_Emacron +CLUTTER_Gcedilla +CLUTTER_Tslash +CLUTTER_rcedilla +CLUTTER_itilde +CLUTTER_lcedilla +CLUTTER_emacron +CLUTTER_gcedilla +CLUTTER_tslash +CLUTTER_ENG +CLUTTER_eng +CLUTTER_Amacron +CLUTTER_Iogonek +CLUTTER_Eabovedot +CLUTTER_Imacron +CLUTTER_Ncedilla +CLUTTER_Omacron +CLUTTER_Kcedilla +CLUTTER_Uogonek +CLUTTER_Utilde +CLUTTER_Umacron +CLUTTER_amacron +CLUTTER_iogonek +CLUTTER_eabovedot +CLUTTER_imacron +CLUTTER_ncedilla +CLUTTER_omacron +CLUTTER_kcedilla +CLUTTER_uogonek +CLUTTER_utilde +CLUTTER_umacron +CLUTTER_OE +CLUTTER_oe +CLUTTER_Ydiaeresis +CLUTTER_overline +CLUTTER_kana_fullstop +CLUTTER_kana_openingbracket +CLUTTER_kana_closingbracket +CLUTTER_kana_comma +CLUTTER_kana_conjunctive +CLUTTER_kana_middledot +CLUTTER_kana_WO +CLUTTER_kana_a +CLUTTER_kana_i +CLUTTER_kana_u +CLUTTER_kana_e +CLUTTER_kana_o +CLUTTER_kana_ya +CLUTTER_kana_yu +CLUTTER_kana_yo +CLUTTER_kana_tsu +CLUTTER_kana_tu +CLUTTER_prolongedsound +CLUTTER_kana_A +CLUTTER_kana_I +CLUTTER_kana_U +CLUTTER_kana_E +CLUTTER_kana_O +CLUTTER_kana_KA +CLUTTER_kana_KI +CLUTTER_kana_KU +CLUTTER_kana_KE +CLUTTER_kana_KO +CLUTTER_kana_SA +CLUTTER_kana_SHI +CLUTTER_kana_SU +CLUTTER_kana_SE +CLUTTER_kana_SO +CLUTTER_kana_TA +CLUTTER_kana_CHI +CLUTTER_kana_TI +CLUTTER_kana_TSU +CLUTTER_kana_TU +CLUTTER_kana_TE +CLUTTER_kana_TO +CLUTTER_kana_NA +CLUTTER_kana_NI +CLUTTER_kana_NU +CLUTTER_kana_NE +CLUTTER_kana_NO +CLUTTER_kana_HA +CLUTTER_kana_HI +CLUTTER_kana_FU +CLUTTER_kana_HU +CLUTTER_kana_HE +CLUTTER_kana_HO +CLUTTER_kana_MA +CLUTTER_kana_MI +CLUTTER_kana_MU +CLUTTER_kana_ME +CLUTTER_kana_MO +CLUTTER_kana_YA +CLUTTER_kana_YU +CLUTTER_kana_YO +CLUTTER_kana_RA +CLUTTER_kana_RI +CLUTTER_kana_RU +CLUTTER_kana_RE +CLUTTER_kana_RO +CLUTTER_kana_WA +CLUTTER_kana_N +CLUTTER_voicedsound +CLUTTER_semivoicedsound +CLUTTER_kana_switch +CLUTTER_Arabic_comma +CLUTTER_Arabic_semicolon +CLUTTER_Arabic_question_mark +CLUTTER_Arabic_hamza +CLUTTER_Arabic_maddaonalef +CLUTTER_Arabic_hamzaonalef +CLUTTER_Arabic_hamzaonwaw +CLUTTER_Arabic_hamzaunderalef +CLUTTER_Arabic_hamzaonyeh +CLUTTER_Arabic_alef +CLUTTER_Arabic_beh +CLUTTER_Arabic_tehmarbuta +CLUTTER_Arabic_teh +CLUTTER_Arabic_theh +CLUTTER_Arabic_jeem +CLUTTER_Arabic_hah +CLUTTER_Arabic_khah +CLUTTER_Arabic_dal +CLUTTER_Arabic_thal +CLUTTER_Arabic_ra +CLUTTER_Arabic_zain +CLUTTER_Arabic_seen +CLUTTER_Arabic_sheen +CLUTTER_Arabic_sad +CLUTTER_Arabic_dad +CLUTTER_Arabic_tah +CLUTTER_Arabic_zah +CLUTTER_Arabic_ain +CLUTTER_Arabic_ghain +CLUTTER_Arabic_tatweel +CLUTTER_Arabic_feh +CLUTTER_Arabic_qaf +CLUTTER_Arabic_kaf +CLUTTER_Arabic_lam +CLUTTER_Arabic_meem +CLUTTER_Arabic_noon +CLUTTER_Arabic_ha +CLUTTER_Arabic_heh +CLUTTER_Arabic_waw +CLUTTER_Arabic_alefmaksura +CLUTTER_Arabic_yeh +CLUTTER_Arabic_fathatan +CLUTTER_Arabic_dammatan +CLUTTER_Arabic_kasratan +CLUTTER_Arabic_fatha +CLUTTER_Arabic_damma +CLUTTER_Arabic_kasra +CLUTTER_Arabic_shadda +CLUTTER_Arabic_sukun +CLUTTER_Arabic_switch +CLUTTER_Serbian_dje +CLUTTER_Macedonia_gje +CLUTTER_Cyrillic_io +CLUTTER_Ukrainian_ie +CLUTTER_Ukranian_je +CLUTTER_Macedonia_dse +CLUTTER_Ukrainian_i +CLUTTER_Ukranian_i +CLUTTER_Ukrainian_yi +CLUTTER_Ukranian_yi +CLUTTER_Cyrillic_je +CLUTTER_Serbian_je +CLUTTER_Cyrillic_lje +CLUTTER_Serbian_lje +CLUTTER_Cyrillic_nje +CLUTTER_Serbian_nje +CLUTTER_Serbian_tshe +CLUTTER_Macedonia_kje +CLUTTER_Ukrainian_ghe_with_upturn +CLUTTER_Byelorussian_shortu +CLUTTER_Cyrillic_dzhe +CLUTTER_Serbian_dze +CLUTTER_numerosign +CLUTTER_Serbian_DJE +CLUTTER_Macedonia_GJE +CLUTTER_Cyrillic_IO +CLUTTER_Ukrainian_IE +CLUTTER_Ukranian_JE +CLUTTER_Macedonia_DSE +CLUTTER_Ukrainian_I +CLUTTER_Ukranian_I +CLUTTER_Ukrainian_YI +CLUTTER_Ukranian_YI +CLUTTER_Cyrillic_JE +CLUTTER_Serbian_JE +CLUTTER_Cyrillic_LJE +CLUTTER_Serbian_LJE +CLUTTER_Cyrillic_NJE +CLUTTER_Serbian_NJE +CLUTTER_Serbian_TSHE +CLUTTER_Macedonia_KJE +CLUTTER_Ukrainian_GHE_WITH_UPTURN +CLUTTER_Byelorussian_SHORTU +CLUTTER_Cyrillic_DZHE +CLUTTER_Serbian_DZE +CLUTTER_Cyrillic_yu +CLUTTER_Cyrillic_a +CLUTTER_Cyrillic_be +CLUTTER_Cyrillic_tse +CLUTTER_Cyrillic_de +CLUTTER_Cyrillic_ie +CLUTTER_Cyrillic_ef +CLUTTER_Cyrillic_ghe +CLUTTER_Cyrillic_ha +CLUTTER_Cyrillic_i +CLUTTER_Cyrillic_shorti +CLUTTER_Cyrillic_ka +CLUTTER_Cyrillic_el +CLUTTER_Cyrillic_em +CLUTTER_Cyrillic_en +CLUTTER_Cyrillic_o +CLUTTER_Cyrillic_pe +CLUTTER_Cyrillic_ya +CLUTTER_Cyrillic_er +CLUTTER_Cyrillic_es +CLUTTER_Cyrillic_te +CLUTTER_Cyrillic_u +CLUTTER_Cyrillic_zhe +CLUTTER_Cyrillic_ve +CLUTTER_Cyrillic_softsign +CLUTTER_Cyrillic_yeru +CLUTTER_Cyrillic_ze +CLUTTER_Cyrillic_sha +CLUTTER_Cyrillic_e +CLUTTER_Cyrillic_shcha +CLUTTER_Cyrillic_che +CLUTTER_Cyrillic_hardsign +CLUTTER_Cyrillic_YU +CLUTTER_Cyrillic_A +CLUTTER_Cyrillic_BE +CLUTTER_Cyrillic_TSE +CLUTTER_Cyrillic_DE +CLUTTER_Cyrillic_IE +CLUTTER_Cyrillic_EF +CLUTTER_Cyrillic_GHE +CLUTTER_Cyrillic_HA +CLUTTER_Cyrillic_I +CLUTTER_Cyrillic_SHORTI +CLUTTER_Cyrillic_KA +CLUTTER_Cyrillic_EL +CLUTTER_Cyrillic_EM +CLUTTER_Cyrillic_EN +CLUTTER_Cyrillic_O +CLUTTER_Cyrillic_PE +CLUTTER_Cyrillic_YA +CLUTTER_Cyrillic_ER +CLUTTER_Cyrillic_ES +CLUTTER_Cyrillic_TE +CLUTTER_Cyrillic_U +CLUTTER_Cyrillic_ZHE +CLUTTER_Cyrillic_VE +CLUTTER_Cyrillic_SOFTSIGN +CLUTTER_Cyrillic_YERU +CLUTTER_Cyrillic_ZE +CLUTTER_Cyrillic_SHA +CLUTTER_Cyrillic_E +CLUTTER_Cyrillic_SHCHA +CLUTTER_Cyrillic_CHE +CLUTTER_Cyrillic_HARDSIGN +CLUTTER_Greek_ALPHAaccent +CLUTTER_Greek_EPSILONaccent +CLUTTER_Greek_ETAaccent +CLUTTER_Greek_IOTAaccent +CLUTTER_Greek_IOTAdieresis +CLUTTER_Greek_IOTAdiaeresis +CLUTTER_Greek_OMICRONaccent +CLUTTER_Greek_UPSILONaccent +CLUTTER_Greek_UPSILONdieresis +CLUTTER_Greek_OMEGAaccent +CLUTTER_Greek_accentdieresis +CLUTTER_Greek_horizbar +CLUTTER_Greek_alphaaccent +CLUTTER_Greek_epsilonaccent +CLUTTER_Greek_etaaccent +CLUTTER_Greek_iotaaccent +CLUTTER_Greek_iotadieresis +CLUTTER_Greek_iotaaccentdieresis +CLUTTER_Greek_omicronaccent +CLUTTER_Greek_upsilonaccent +CLUTTER_Greek_upsilondieresis +CLUTTER_Greek_upsilonaccentdieresis +CLUTTER_Greek_omegaaccent +CLUTTER_Greek_ALPHA +CLUTTER_Greek_BETA +CLUTTER_Greek_GAMMA +CLUTTER_Greek_DELTA +CLUTTER_Greek_EPSILON +CLUTTER_Greek_ZETA +CLUTTER_Greek_ETA +CLUTTER_Greek_THETA +CLUTTER_Greek_IOTA +CLUTTER_Greek_KAPPA +CLUTTER_Greek_LAMDA +CLUTTER_Greek_LAMBDA +CLUTTER_Greek_MU +CLUTTER_Greek_NU +CLUTTER_Greek_XI +CLUTTER_Greek_OMICRON +CLUTTER_Greek_PI +CLUTTER_Greek_RHO +CLUTTER_Greek_SIGMA +CLUTTER_Greek_TAU +CLUTTER_Greek_UPSILON +CLUTTER_Greek_PHI +CLUTTER_Greek_CHI +CLUTTER_Greek_PSI +CLUTTER_Greek_OMEGA +CLUTTER_Greek_alpha +CLUTTER_Greek_beta +CLUTTER_Greek_gamma +CLUTTER_Greek_delta +CLUTTER_Greek_epsilon +CLUTTER_Greek_zeta +CLUTTER_Greek_eta +CLUTTER_Greek_theta +CLUTTER_Greek_iota +CLUTTER_Greek_kappa +CLUTTER_Greek_lamda +CLUTTER_Greek_lambda +CLUTTER_Greek_mu +CLUTTER_Greek_nu +CLUTTER_Greek_xi +CLUTTER_Greek_omicron +CLUTTER_Greek_pi +CLUTTER_Greek_rho +CLUTTER_Greek_sigma +CLUTTER_Greek_finalsmallsigma +CLUTTER_Greek_tau +CLUTTER_Greek_upsilon +CLUTTER_Greek_phi +CLUTTER_Greek_chi +CLUTTER_Greek_psi +CLUTTER_Greek_omega +CLUTTER_Greek_switch +CLUTTER_leftradical +CLUTTER_topleftradical +CLUTTER_horizconnector +CLUTTER_topintegral +CLUTTER_botintegral +CLUTTER_vertconnector +CLUTTER_topleftsqbracket +CLUTTER_botleftsqbracket +CLUTTER_toprightsqbracket +CLUTTER_botrightsqbracket +CLUTTER_topleftparens +CLUTTER_botleftparens +CLUTTER_toprightparens +CLUTTER_botrightparens +CLUTTER_leftmiddlecurlybrace +CLUTTER_rightmiddlecurlybrace +CLUTTER_topleftsummation +CLUTTER_botleftsummation +CLUTTER_topvertsummationconnector +CLUTTER_botvertsummationconnector +CLUTTER_toprightsummation +CLUTTER_botrightsummation +CLUTTER_rightmiddlesummation +CLUTTER_lessthanequal +CLUTTER_notequal +CLUTTER_greaterthanequal +CLUTTER_integral +CLUTTER_therefore +CLUTTER_variation +CLUTTER_infinity +CLUTTER_nabla +CLUTTER_approximate +CLUTTER_similarequal +CLUTTER_ifonlyif +CLUTTER_implies +CLUTTER_identical +CLUTTER_radical +CLUTTER_includedin +CLUTTER_includes +CLUTTER_intersection +CLUTTER_union +CLUTTER_logicaland +CLUTTER_logicalor +CLUTTER_partialderivative +CLUTTER_function +CLUTTER_leftarrow +CLUTTER_uparrow +CLUTTER_rightarrow +CLUTTER_downarrow +CLUTTER_blank +CLUTTER_soliddiamond +CLUTTER_checkerboard +CLUTTER_ht +CLUTTER_ff +CLUTTER_cr +CLUTTER_lf +CLUTTER_nl +CLUTTER_vt +CLUTTER_lowrightcorner +CLUTTER_uprightcorner +CLUTTER_upleftcorner +CLUTTER_lowleftcorner +CLUTTER_crossinglines +CLUTTER_horizlinescan1 +CLUTTER_horizlinescan3 +CLUTTER_horizlinescan5 +CLUTTER_horizlinescan7 +CLUTTER_horizlinescan9 +CLUTTER_leftt +CLUTTER_rightt +CLUTTER_bott +CLUTTER_topt +CLUTTER_vertbar +CLUTTER_emspace +CLUTTER_enspace +CLUTTER_em3space +CLUTTER_em4space +CLUTTER_digitspace +CLUTTER_punctspace +CLUTTER_thinspace +CLUTTER_hairspace +CLUTTER_emdash +CLUTTER_endash +CLUTTER_signifblank +CLUTTER_ellipsis +CLUTTER_doubbaselinedot +CLUTTER_onethird +CLUTTER_twothirds +CLUTTER_onefifth +CLUTTER_twofifths +CLUTTER_threefifths +CLUTTER_fourfifths +CLUTTER_onesixth +CLUTTER_fivesixths +CLUTTER_careof +CLUTTER_figdash +CLUTTER_leftanglebracket +CLUTTER_decimalpoint +CLUTTER_rightanglebracket +CLUTTER_marker +CLUTTER_oneeighth +CLUTTER_threeeighths +CLUTTER_fiveeighths +CLUTTER_seveneighths +CLUTTER_trademark +CLUTTER_signaturemark +CLUTTER_trademarkincircle +CLUTTER_leftopentriangle +CLUTTER_rightopentriangle +CLUTTER_emopencircle +CLUTTER_emopenrectangle +CLUTTER_leftsinglequotemark +CLUTTER_rightsinglequotemark +CLUTTER_leftdoublequotemark +CLUTTER_rightdoublequotemark +CLUTTER_prescription +CLUTTER_minutes +CLUTTER_seconds +CLUTTER_latincross +CLUTTER_hexagram +CLUTTER_filledrectbullet +CLUTTER_filledlefttribullet +CLUTTER_filledrighttribullet +CLUTTER_emfilledcircle +CLUTTER_emfilledrect +CLUTTER_enopencircbullet +CLUTTER_enopensquarebullet +CLUTTER_openrectbullet +CLUTTER_opentribulletup +CLUTTER_opentribulletdown +CLUTTER_openstar +CLUTTER_enfilledcircbullet +CLUTTER_enfilledsqbullet +CLUTTER_filledtribulletup +CLUTTER_filledtribulletdown +CLUTTER_leftpointer +CLUTTER_rightpointer +CLUTTER_club +CLUTTER_diamond +CLUTTER_heart +CLUTTER_maltesecross +CLUTTER_dagger +CLUTTER_doubledagger +CLUTTER_checkmark +CLUTTER_ballotcross +CLUTTER_musicalsharp +CLUTTER_musicalflat +CLUTTER_malesymbol +CLUTTER_femalesymbol +CLUTTER_telephone +CLUTTER_telephonerecorder +CLUTTER_phonographcopyright +CLUTTER_caret +CLUTTER_singlelowquotemark +CLUTTER_doublelowquotemark +CLUTTER_cursor +CLUTTER_leftcaret +CLUTTER_rightcaret +CLUTTER_downcaret +CLUTTER_upcaret +CLUTTER_overbar +CLUTTER_downtack +CLUTTER_upshoe +CLUTTER_downstile +CLUTTER_underbar +CLUTTER_jot +CLUTTER_quad +CLUTTER_uptack +CLUTTER_circle +CLUTTER_upstile +CLUTTER_downshoe +CLUTTER_rightshoe +CLUTTER_leftshoe +CLUTTER_lefttack +CLUTTER_righttack +CLUTTER_hebrew_doublelowline +CLUTTER_hebrew_aleph +CLUTTER_hebrew_bet +CLUTTER_hebrew_beth +CLUTTER_hebrew_gimel +CLUTTER_hebrew_gimmel +CLUTTER_hebrew_dalet +CLUTTER_hebrew_daleth +CLUTTER_hebrew_he +CLUTTER_hebrew_waw +CLUTTER_hebrew_zain +CLUTTER_hebrew_zayin +CLUTTER_hebrew_chet +CLUTTER_hebrew_het +CLUTTER_hebrew_tet +CLUTTER_hebrew_teth +CLUTTER_hebrew_yod +CLUTTER_hebrew_finalkaph +CLUTTER_hebrew_kaph +CLUTTER_hebrew_lamed +CLUTTER_hebrew_finalmem +CLUTTER_hebrew_mem +CLUTTER_hebrew_finalnun +CLUTTER_hebrew_nun +CLUTTER_hebrew_samech +CLUTTER_hebrew_samekh +CLUTTER_hebrew_ayin +CLUTTER_hebrew_finalpe +CLUTTER_hebrew_pe +CLUTTER_hebrew_finalzade +CLUTTER_hebrew_finalzadi +CLUTTER_hebrew_zade +CLUTTER_hebrew_zadi +CLUTTER_hebrew_qoph +CLUTTER_hebrew_kuf +CLUTTER_hebrew_resh +CLUTTER_hebrew_shin +CLUTTER_hebrew_taw +CLUTTER_hebrew_taf +CLUTTER_Hebrew_switch +CLUTTER_Thai_kokai +CLUTTER_Thai_khokhai +CLUTTER_Thai_khokhuat +CLUTTER_Thai_khokhwai +CLUTTER_Thai_khokhon +CLUTTER_Thai_khorakhang +CLUTTER_Thai_ngongu +CLUTTER_Thai_chochan +CLUTTER_Thai_choching +CLUTTER_Thai_chochang +CLUTTER_Thai_soso +CLUTTER_Thai_chochoe +CLUTTER_Thai_yoying +CLUTTER_Thai_dochada +CLUTTER_Thai_topatak +CLUTTER_Thai_thothan +CLUTTER_Thai_thonangmontho +CLUTTER_Thai_thophuthao +CLUTTER_Thai_nonen +CLUTTER_Thai_dodek +CLUTTER_Thai_totao +CLUTTER_Thai_thothung +CLUTTER_Thai_thothahan +CLUTTER_Thai_thothong +CLUTTER_Thai_nonu +CLUTTER_Thai_bobaimai +CLUTTER_Thai_popla +CLUTTER_Thai_phophung +CLUTTER_Thai_fofa +CLUTTER_Thai_phophan +CLUTTER_Thai_fofan +CLUTTER_Thai_phosamphao +CLUTTER_Thai_moma +CLUTTER_Thai_yoyak +CLUTTER_Thai_rorua +CLUTTER_Thai_ru +CLUTTER_Thai_loling +CLUTTER_Thai_lu +CLUTTER_Thai_wowaen +CLUTTER_Thai_sosala +CLUTTER_Thai_sorusi +CLUTTER_Thai_sosua +CLUTTER_Thai_hohip +CLUTTER_Thai_lochula +CLUTTER_Thai_oang +CLUTTER_Thai_honokhuk +CLUTTER_Thai_paiyannoi +CLUTTER_Thai_saraa +CLUTTER_Thai_maihanakat +CLUTTER_Thai_saraaa +CLUTTER_Thai_saraam +CLUTTER_Thai_sarai +CLUTTER_Thai_saraii +CLUTTER_Thai_saraue +CLUTTER_Thai_sarauee +CLUTTER_Thai_sarau +CLUTTER_Thai_sarauu +CLUTTER_Thai_phinthu +CLUTTER_Thai_maihanakat_maitho +CLUTTER_Thai_baht +CLUTTER_Thai_sarae +CLUTTER_Thai_saraae +CLUTTER_Thai_sarao +CLUTTER_Thai_saraaimaimuan +CLUTTER_Thai_saraaimaimalai +CLUTTER_Thai_lakkhangyao +CLUTTER_Thai_maiyamok +CLUTTER_Thai_maitaikhu +CLUTTER_Thai_maiek +CLUTTER_Thai_maitho +CLUTTER_Thai_maitri +CLUTTER_Thai_maichattawa +CLUTTER_Thai_thanthakhat +CLUTTER_Thai_nikhahit +CLUTTER_Thai_leksun +CLUTTER_Thai_leknung +CLUTTER_Thai_leksong +CLUTTER_Thai_leksam +CLUTTER_Thai_leksi +CLUTTER_Thai_lekha +CLUTTER_Thai_lekhok +CLUTTER_Thai_lekchet +CLUTTER_Thai_lekpaet +CLUTTER_Thai_lekkao +CLUTTER_Hangul +CLUTTER_Hangul_Start +CLUTTER_Hangul_End +CLUTTER_Hangul_Hanja +CLUTTER_Hangul_Jamo +CLUTTER_Hangul_Romaja +CLUTTER_Hangul_Codeinput +CLUTTER_Hangul_Jeonja +CLUTTER_Hangul_Banja +CLUTTER_Hangul_PreHanja +CLUTTER_Hangul_PostHanja +CLUTTER_Hangul_SingleCandidate +CLUTTER_Hangul_MultipleCandidate +CLUTTER_Hangul_PreviousCandidate +CLUTTER_Hangul_Special +CLUTTER_Hangul_switch +CLUTTER_Hangul_Kiyeog +CLUTTER_Hangul_SsangKiyeog +CLUTTER_Hangul_KiyeogSios +CLUTTER_Hangul_Nieun +CLUTTER_Hangul_NieunJieuj +CLUTTER_Hangul_NieunHieuh +CLUTTER_Hangul_Dikeud +CLUTTER_Hangul_SsangDikeud +CLUTTER_Hangul_Rieul +CLUTTER_Hangul_RieulKiyeog +CLUTTER_Hangul_RieulMieum +CLUTTER_Hangul_RieulPieub +CLUTTER_Hangul_RieulSios +CLUTTER_Hangul_RieulTieut +CLUTTER_Hangul_RieulPhieuf +CLUTTER_Hangul_RieulHieuh +CLUTTER_Hangul_Mieum +CLUTTER_Hangul_Pieub +CLUTTER_Hangul_SsangPieub +CLUTTER_Hangul_PieubSios +CLUTTER_Hangul_Sios +CLUTTER_Hangul_SsangSios +CLUTTER_Hangul_Ieung +CLUTTER_Hangul_Jieuj +CLUTTER_Hangul_SsangJieuj +CLUTTER_Hangul_Cieuc +CLUTTER_Hangul_Khieuq +CLUTTER_Hangul_Tieut +CLUTTER_Hangul_Phieuf +CLUTTER_Hangul_Hieuh +CLUTTER_Hangul_A +CLUTTER_Hangul_AE +CLUTTER_Hangul_YA +CLUTTER_Hangul_YAE +CLUTTER_Hangul_EO +CLUTTER_Hangul_E +CLUTTER_Hangul_YEO +CLUTTER_Hangul_YE +CLUTTER_Hangul_O +CLUTTER_Hangul_WA +CLUTTER_Hangul_WAE +CLUTTER_Hangul_OE +CLUTTER_Hangul_YO +CLUTTER_Hangul_U +CLUTTER_Hangul_WEO +CLUTTER_Hangul_WE +CLUTTER_Hangul_WI +CLUTTER_Hangul_YU +CLUTTER_Hangul_EU +CLUTTER_Hangul_YI +CLUTTER_Hangul_I +CLUTTER_Hangul_J_Kiyeog +CLUTTER_Hangul_J_SsangKiyeog +CLUTTER_Hangul_J_KiyeogSios +CLUTTER_Hangul_J_Nieun +CLUTTER_Hangul_J_NieunJieuj +CLUTTER_Hangul_J_NieunHieuh +CLUTTER_Hangul_J_Dikeud +CLUTTER_Hangul_J_Rieul +CLUTTER_Hangul_J_RieulKiyeog +CLUTTER_Hangul_J_RieulMieum +CLUTTER_Hangul_J_RieulPieub +CLUTTER_Hangul_J_RieulSios +CLUTTER_Hangul_J_RieulTieut +CLUTTER_Hangul_J_RieulPhieuf +CLUTTER_Hangul_J_RieulHieuh +CLUTTER_Hangul_J_Mieum +CLUTTER_Hangul_J_Pieub +CLUTTER_Hangul_J_PieubSios +CLUTTER_Hangul_J_Sios +CLUTTER_Hangul_J_SsangSios +CLUTTER_Hangul_J_Ieung +CLUTTER_Hangul_J_Jieuj +CLUTTER_Hangul_J_Cieuc +CLUTTER_Hangul_J_Khieuq +CLUTTER_Hangul_J_Tieut +CLUTTER_Hangul_J_Phieuf +CLUTTER_Hangul_J_Hieuh +CLUTTER_Hangul_RieulYeorinHieuh +CLUTTER_Hangul_SunkyeongeumMieum +CLUTTER_Hangul_SunkyeongeumPieub +CLUTTER_Hangul_PanSios +CLUTTER_Hangul_KkogjiDalrinIeung +CLUTTER_Hangul_SunkyeongeumPhieuf +CLUTTER_Hangul_YeorinHieuh +CLUTTER_Hangul_AraeA +CLUTTER_Hangul_AraeAE +CLUTTER_Hangul_J_PanSios +CLUTTER_Hangul_J_KkogjiDalrinIeung +CLUTTER_Hangul_J_YeorinHieuh +CLUTTER_Korean_Won +CLUTTER_EcuSign +CLUTTER_ColonSign +CLUTTER_CruzeiroSign +CLUTTER_FFrancSign +CLUTTER_LiraSign +CLUTTER_MillSign +CLUTTER_NairaSign +CLUTTER_PesetaSign +CLUTTER_RupeeSign +CLUTTER_WonSign +CLUTTER_NewSheqelSign +CLUTTER_DongSign +CLUTTER_EuroSign +
+ +
+clutter-marshal +clutter_marshal_VOID__INT64_INT64_FLOAT_BOOLEAN +clutter_marshal_VOID__STRING_BOOLEAN_BOOLEAN +clutter_marshal_VOID__INT_INT +
+ +
+clutter-enum-types +CLUTTER_TYPE_EVENT_TYPE +clutter_event_type_get_type +CLUTTER_TYPE_ELEMENT_TRANSFORM +clutter_element_transform_get_type +CLUTTER_TYPE_ELEMENT_FLAGS +clutter_element_flags_get_type +CLUTTER_TYPE_VIDEO_TEXTURE_ERROR +clutter_video_texture_error_get_type +CLUTTER_TYPE_VIDEO_TEXTURE_ASPECT_RATIO +clutter_video_texture_aspect_ratio_get_type +CLUTTER_TYPE_VIDEO_TEXTURE_METADATA_TYPE +clutter_video_texture_metadata_type_get_type +
+ +
+stamp-clutter-enum-types +
+ diff --git a/doc/reference/clutter.types b/doc/reference/clutter.types new file mode 100644 index 000000000..44a606c27 --- /dev/null +++ b/doc/reference/clutter.types @@ -0,0 +1,11 @@ +#include + +clutter_element_get_type +clutter_group_get_type +clutter_stage_get_type +clutter_rectangle_get_type +clutter_texture_get_type +clutter_video_texture_get_type +clutter_clone_texture_get_type +clutter_label_get_type +clutter_timeline_get_type \ No newline at end of file diff --git a/doc/reference/tmpl/clutter-0.0-unused.sgml b/doc/reference/tmpl/clutter-0.0-unused.sgml new file mode 100644 index 000000000..8f7b8b8b3 --- /dev/null +++ b/doc/reference/tmpl/clutter-0.0-unused.sgml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/doc/reference/tmpl/clutter-clone-texture.sgml b/doc/reference/tmpl/clutter-clone-texture.sgml new file mode 100644 index 000000000..bd02605d5 --- /dev/null +++ b/doc/reference/tmpl/clutter-clone-texture.sgml @@ -0,0 +1,42 @@ + +ClutterCloneTexture + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@parent: +@priv: + + + + + + +@texture: +@Returns: + + diff --git a/doc/reference/tmpl/clutter-color.sgml b/doc/reference/tmpl/clutter-color.sgml new file mode 100644 index 000000000..84abd7ddf --- /dev/null +++ b/doc/reference/tmpl/clutter-color.sgml @@ -0,0 +1,129 @@ + +clutter-color + + + + + + + + + + + + + + + + + + + + + + +@col: + + + + + + + +@col: + + + + + + + +@col: + + + + + + + +@col: + + + + + + + +@col: +@r: + + + + + + + +@col: +@g: + + + + + + + +@col: +@b: + + + + + + + +@col: +@a: + + + + + + + + + + + + + +@r: +@g: +@b: +@a: +@Returns: + + + + + + + +@color: +@r: +@g: +@b: +@a: + + + + + + + +@color: +@r: +@g: +@b: +@a: + + diff --git a/doc/reference/tmpl/clutter-element.sgml b/doc/reference/tmpl/clutter-element.sgml new file mode 100644 index 000000000..779d56563 --- /dev/null +++ b/doc/reference/tmpl/clutter-element.sgml @@ -0,0 +1,466 @@ + +ClutterElement + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@e: +@f: + + + + + + + +@e: +@f: + + + + + + + +@e: + + + + + + + +@e: + + + + + + + +@e: + + + + + + + +@x1: +@y1: +@x2: +@y2: + + + + + + +@x: +@y: +@width: +@height: + + + + + + +@CLUTTER_ELEMENT_MIRROR_X: +@CLUTTER_ELEMENT_MIRROR_Y: + + + + + + +@CLUTTER_ELEMENT_MAPPED: +@CLUTTER_ELEMENT_REALIZED: + + + + + + +@Returns: + + + + + + + +@parent: +@flags: + + + + + + +@parent_class: +@show: +@hide: +@realize: +@unrealize: +@paint: +@request_coords: +@allocate_coords: +@set_depth: +@get_depth: +@show_all: +@hide_all: +@queue_redraw: + + + + + + +@Returns: + + + + + + + +@self: + + + + + + + +@self: + + + + + + + +@self: + + + + + + + +@self: + + + + + + + +@self: + + + + + + + +@self: + + + + + + + +@self: +@box: + + + + + + + +@self: +@box: + + + + + + + +@self: +@geom: + + + + + + + +@self: +@geom: + + + + + + + +@self: +@x1: +@y1: +@x2: +@y2: + + + + + + + +@self: +@x: +@y: + + + + + + + +@self: +@width: +@height: + + + + + + + +@self: +@x: +@y: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@angle: +@x: +@y: + + + + + + + +@self: +@angle: +@y: +@z: + + + + + + + +@self: +@angle: +@x: +@z: + + + + + + + +@self: +@opacity: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@id: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@xoff: +@yoff: +@width: +@height: + + + + + + + +@self: + + + + + + + +@self: +@parent: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@below: + + + + + + + +@self: +@above: + + + + + + + +@self: + + + + + + + +@self: + + diff --git a/doc/reference/tmpl/clutter-enum-types.sgml b/doc/reference/tmpl/clutter-enum-types.sgml new file mode 100644 index 000000000..649e1065d --- /dev/null +++ b/doc/reference/tmpl/clutter-enum-types.sgml @@ -0,0 +1,109 @@ + +clutter-enum-types + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + + + +@Returns: + + diff --git a/doc/reference/tmpl/clutter-event.sgml b/doc/reference/tmpl/clutter-event.sgml new file mode 100644 index 000000000..debc0a61f --- /dev/null +++ b/doc/reference/tmpl/clutter-event.sgml @@ -0,0 +1,144 @@ + +clutter-event + + + + + + + + + + + + + + + + + + + + + + +@CLUTTER_KEY_PRESS: +@CLUTTER_KEY_RELEASE: +@CLUTTER_MOTION: +@CLUTTER_BUTTON_PRESS: +@CLUTTER_2BUTTON_PRESS: +@CLUTTER_BUTTON_RELEASE: + + + + + + +@type: +@time: +@modifier_state: +@keyval: +@hardware_keycode: + + + + + + +@type: +@time: +@x: +@y: +@modifier_state: +@button: +@axes: +@device: + + + + + + +@type: +@time: +@x: +@y: +@modifier_state: +@axes: +@device: + + + + + + + + + + + + + + + + + + +@keyev: +@Returns: + + + + + + + +@keyev: +@Returns: + + + + + + + +@keyev: +@Returns: + + + + + + + +@keyev: +@Returns: + + + + + + + +@keyev: +@Returns: + + + + + + + +@keyev: +@Returns: + + + + + + + +@keyval: +@Returns: + + diff --git a/doc/reference/tmpl/clutter-group.sgml b/doc/reference/tmpl/clutter-group.sgml new file mode 100644 index 000000000..71b1d495a --- /dev/null +++ b/doc/reference/tmpl/clutter-group.sgml @@ -0,0 +1,124 @@ + +ClutterGroup + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@parent: + + + + + + +@Returns: + + + + + + + +@group: +@element: + + + + + + + +@group: +@first_element: +@args: + + + + + + + +@group: +@first_element: +@Varargs: + + + + + + + +@group: +@element: + + + + + + + +@self: + + + + + + + +@self: + + + + + + + +@self: +@id: +@Returns: + + + + + + + +@self: +@element: +@sibling: + + + + + + + +@self: +@element: +@sibling: + + diff --git a/doc/reference/tmpl/clutter-keysyms.sgml b/doc/reference/tmpl/clutter-keysyms.sgml new file mode 100644 index 000000000..454fab6d7 --- /dev/null +++ b/doc/reference/tmpl/clutter-keysyms.sgml @@ -0,0 +1,9399 @@ + +clutter-keysyms + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/reference/tmpl/clutter-label.sgml b/doc/reference/tmpl/clutter-label.sgml new file mode 100644 index 000000000..453ffb42f --- /dev/null +++ b/doc/reference/tmpl/clutter-label.sgml @@ -0,0 +1,87 @@ + +ClutterLabel + + + + + + + + + + + + + + + + + + + + + + +@parent: + + + + + + + + + + + + +@font_desc: +@text: +@Returns: + + + + + + + +@Returns: + + + + + + + +@label: +@text: + + + + + + + +@label: +@desc: + + + + + + + +@label: +@pixel: + + + + + + + +@label: +@width: +@height: + + diff --git a/doc/reference/tmpl/clutter-main.sgml b/doc/reference/tmpl/clutter-main.sgml new file mode 100644 index 000000000..38ad5c655 --- /dev/null +++ b/doc/reference/tmpl/clutter-main.sgml @@ -0,0 +1,138 @@ + +clutter-main + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@x: +@a...: +@a...: +@a...: +@a...: + + + + + + + + + + + + + + + + + + + + + +@argc: +@argv: +@Returns: + + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + + + +@Returns: + + + + + + + +@Returns: + + + + + + + +@Returns: + + + + + + + +@Returns: + + + + + + + +@Returns: + + + + + + + + + + + + + + + + diff --git a/doc/reference/tmpl/clutter-marshal.sgml b/doc/reference/tmpl/clutter-marshal.sgml new file mode 100644 index 000000000..f71bab8b0 --- /dev/null +++ b/doc/reference/tmpl/clutter-marshal.sgml @@ -0,0 +1,58 @@ + +clutter-marshal + + + + + + + + + + + + + + + + + + + + + + +@closure: +@return_value: +@n_param_values: +@param_values: +@invocation_hint: +@marshal_data: + + + + + + + +@closure: +@return_value: +@n_param_values: +@param_values: +@invocation_hint: +@marshal_data: + + + + + + + +@closure: +@return_value: +@n_param_values: +@param_values: +@invocation_hint: +@marshal_data: + + diff --git a/doc/reference/tmpl/clutter-rectangle.sgml b/doc/reference/tmpl/clutter-rectangle.sgml new file mode 100644 index 000000000..29e7205d6 --- /dev/null +++ b/doc/reference/tmpl/clutter-rectangle.sgml @@ -0,0 +1,42 @@ + +ClutterRectangle + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@parent: +@priv: + + + + + + +@col: +@Returns: + + diff --git a/doc/reference/tmpl/clutter-stage.sgml b/doc/reference/tmpl/clutter-stage.sgml new file mode 100644 index 000000000..58ce359d8 --- /dev/null +++ b/doc/reference/tmpl/clutter-stage.sgml @@ -0,0 +1,85 @@ + +ClutterStage + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@parent: +@priv: + + + + + + +@stage: +@Returns: + + + + + + + +@stage: +@color: + + + + + + + +@stage: +@Returns: + + + + + + + +@stage: +@x: +@y: +@Returns: + + diff --git a/doc/reference/tmpl/clutter-texture.sgml b/doc/reference/tmpl/clutter-texture.sgml new file mode 100644 index 000000000..f3056b68c --- /dev/null +++ b/doc/reference/tmpl/clutter-texture.sgml @@ -0,0 +1,139 @@ + +ClutterTexture + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@parent: +@priv: + + + + + + +@pixbuf: +@Returns: + + + + + + + +@Returns: + + + + + + + +@texture: +@pixbuf: + + + + + + + +@texture: +@Returns: + + + + + + + +@texture: +@width: +@height: + + + + + + + +@texture: +@index: + + + + + + + +@texture: +@n_x_tiles: +@n_y_tiles: + + + + + + + +@texture: +@x_index: +@pos: +@size: +@waste: + + + + + + + +@texture: +@y_index: +@pos: +@size: +@waste: + + + + + + + +@texture: +@Returns: + + + + + + + +@texture: +@Returns: + + diff --git a/doc/reference/tmpl/clutter-timeline.sgml b/doc/reference/tmpl/clutter-timeline.sgml new file mode 100644 index 000000000..4cb93a1f2 --- /dev/null +++ b/doc/reference/tmpl/clutter-timeline.sgml @@ -0,0 +1,129 @@ + +ClutterTimeline + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@parent: +@priv: + + + + + + +@nframes: +@fps: +@Returns: + + + + + + + +@timeline: +@fps: + + + + + + + +@timeline: + + + + + + + +@timeline: + + + + + + + +@timeline: + + + + + + + +@timeline: +@loop: + + + + + + + +@timeline: + + + + + + + +@timeline: +@nframes: + + + + + + + +@timeline: +@frame_num: + + + + + + + +@timeline: +@Returns: + + + + + + + +@timeline: +@Returns: + + diff --git a/doc/reference/tmpl/clutter-util.sgml b/doc/reference/tmpl/clutter-util.sgml new file mode 100644 index 000000000..6ba39f0c8 --- /dev/null +++ b/doc/reference/tmpl/clutter-util.sgml @@ -0,0 +1,38 @@ + +clutter-util + + + + + + + + + + + + + + + + + + + + + + +@a: +@Returns: + + + + + + + +@width: +@height: +@Returns: + + diff --git a/doc/reference/tmpl/clutter-video-texture.sgml b/doc/reference/tmpl/clutter-video-texture.sgml new file mode 100644 index 000000000..1053bee46 --- /dev/null +++ b/doc/reference/tmpl/clutter-video-texture.sgml @@ -0,0 +1,286 @@ + +ClutterVideoTexture + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_PLUGIN: +@CLUTTER_VIDEO_TEXTURE_ERROR_NO_PLUGIN_FOR_FILE: +@CLUTTER_VIDEO_TEXTURE_ERROR_VIDEO_PLUGIN: +@CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_BUSY: +@CLUTTER_VIDEO_TEXTURE_ERROR_BROKEN_FILE: +@CLUTTER_VIDEO_TEXTURE_ERROR_FILE_GENERIC: +@CLUTTER_VIDEO_TEXTURE_ERROR_FILE_PERMISSION: +@CLUTTER_VIDEO_TEXTURE_ERROR_FILE_ENCRYPTED: +@CLUTTER_VIDEO_TEXTURE_ERROR_FILE_NOT_FOUND: +@CLUTTER_VIDEO_TEXTURE_ERROR_DVD_ENCRYPTED: +@CLUTTER_VIDEO_TEXTURE_ERROR_INVALID_DEVICE: +@CLUTTER_VIDEO_TEXTURE_ERROR_UNKNOWN_HOST: +@CLUTTER_VIDEO_TEXTURE_ERROR_NETWORK_UNREACHABLE: +@CLUTTER_VIDEO_TEXTURE_ERROR_CONNECTION_REFUSED: +@CLUTTER_VIDEO_TEXTURE_ERROR_UNVALID_LOCATION: +@CLUTTER_VIDEO_TEXTURE_ERROR_GENERIC: +@CLUTTER_VIDEO_TEXTURE_ERROR_CODEC_NOT_HANDLED: +@CLUTTER_VIDEO_TEXTURE_ERROR_AUDIO_ONLY: +@CLUTTER_VIDEO_TEXTURE_ERROR_CANNOT_CAPTURE: +@CLUTTER_VIDEO_TEXTURE_ERROR_READ_ERROR: +@CLUTTER_VIDEO_TEXTURE_ERROR_PLUGIN_LOAD: +@CLUTTER_VIDEO_TEXTURE_ERROR_STILL_IMAGE: +@CLUTTER_VIDEO_TEXTURE_ERROR_EMPTY_FILE: + + + + + + +@Returns: + + + + + + + +@CLUTTER_VIDEO_TEXTURE_AUTO: +@CLUTTER_VIDEO_TEXTURE_SQUARE: +@CLUTTER_VIDEO_TEXTURE_FOURBYTHREE: +@CLUTTER_VIDEO_TEXTURE_ANAMORPHIC: +@CLUTTER_VIDEO_TEXTURE_DVB: + + + + + + +@parent: +@priv: + + + + + + +@Returns: + + + + + + + +@video_texture: +@mrl: +@subtitle_uri: +@error: +@Returns: + + + + + + + +@video_texture: +@error: +@Returns: + + + + + + + +@video_texture: + + + + + + + +@video_texture: +@Returns: + + + + + + + +@video_texture: +@time: +@gerror: +@Returns: + + + + + + + +@video_texture: +@position: +@error: +@Returns: + + + + + + + +@video_texture: + + + + + + + +@video_texture: +@Returns: + + + + + + + +@video_texture: +@volume: + + + + + + + +@video_texture: +@Returns: + + + + + + + +@video_texture: +@Returns: + + + + + + + +@video_texture: +@Returns: + + + + + + + +@video_texture: +@Returns: + + + + + + + +@video_texture: +@Returns: + + + + + + + +@video_texture: +@Returns: + + + + + + + +@video_texture: +@ratio: + + + + + + + +@video_texture: +@Returns: + + + + + + + +@CLUTTER_INFO_TITLE: +@CLUTTER_INFO_ARTIST: +@CLUTTER_INFO_YEAR: +@CLUTTER_INFO_ALBUM: +@CLUTTER_INFO_DURATION: +@CLUTTER_INFO_TRACK_NUMBER: +@CLUTTER_INFO_HAS_VIDEO: +@CLUTTER_INFO_DIMENSION_X: +@CLUTTER_INFO_DIMENSION_Y: +@CLUTTER_INFO_VIDEO_BITRATE: +@CLUTTER_INFO_VIDEO_CODEC: +@CLUTTER_INFO_FPS: +@CLUTTER_INFO_HAS_AUDIO: +@CLUTTER_INFO_AUDIO_BITRATE: +@CLUTTER_INFO_AUDIO_CODEC: + + + + + + +@video_texture: +@type: +@value: + + diff --git a/doc/reference/tmpl/clutter.sgml b/doc/reference/tmpl/clutter.sgml new file mode 100644 index 000000000..b93d9132c --- /dev/null +++ b/doc/reference/tmpl/clutter.sgml @@ -0,0 +1,19 @@ + +clutter + + + + + + + + + + + + + + + + + diff --git a/examples/Makefile.am b/examples/Makefile.am index 5aa71c0ee..2d63565a0 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,35 +1,45 @@ -noinst_PROGRAMS = scratch photos player select +noinst_PROGRAMS = test test-video video-cube test-text super-oh -scratch_SOURCES = scratch.c -scratch_CFLAGS = $(CLTR_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS) -scratch_LDFLAGS = \ - $(CLTR_LIBS) \ +INCLUDES = -I$(top_srcdir)/clutter + +test_SOURCES = test.c +test_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS) +test_LDFLAGS = \ + $(CLUTTER_LIBS) \ $(GST_LIBS) \ $(GCONF_LIBS) \ - $(top_builddir)/clutter/libclutter.la + $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la -photos_SOURCES = photos.c -photos_CFLAGS = $(CLTR_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS) -photos_LDFLAGS = \ - $(CLTR_LIBS) \ +test_video_SOURCES = test-video.c +test_video_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS) +test_video_LDFLAGS = \ + $(CLUTTER_LIBS) \ $(GST_LIBS) \ $(GCONF_LIBS) \ - $(top_builddir)/clutter/libclutter.la + $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la -player_SOURCES = player.c -player_CFLAGS = $(CLTR_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS) -player_LDFLAGS = \ - $(CLTR_LIBS) \ +video_cube_SOURCES = video-cube.c +video_cube_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS) +video_cube_LDFLAGS = \ + $(CLUTTER_LIBS) \ $(GST_LIBS) \ $(GCONF_LIBS) \ - $(top_builddir)/clutter/libclutter.la + $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la -select_SOURCES = select.c -select_CFLAGS = $(CLTR_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS) -select_LDFLAGS = \ - $(CLTR_LIBS) \ +test_text_SOURCES = test-text.c +test_text_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS) +test_text_LDFLAGS = \ + $(CLUTTER_LIBS) \ $(GST_LIBS) \ $(GCONF_LIBS) \ - $(top_builddir)/clutter/libclutter.la + $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la +super_oh_SOURCES = super-oh.c +super_oh_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS) +super_oh_LDFLAGS = \ + $(CLUTTER_LIBS) \ + $(GST_LIBS) \ + $(GCONF_LIBS) \ + $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la +EXTRA_DIST = redhand.png clutter-logo-800x600.png \ No newline at end of file diff --git a/examples/clutter-logo-800x600.png b/examples/clutter-logo-800x600.png index 93bae5ad2..7a81de9f4 100644 Binary files a/examples/clutter-logo-800x600.png and b/examples/clutter-logo-800x600.png differ diff --git a/examples/photos.c b/examples/photos.c deleted file mode 100644 index 6553c3b43..000000000 --- a/examples/photos.c +++ /dev/null @@ -1,158 +0,0 @@ -#include - -gchar *ImgPath = NULL; - -int -usage(char *progname) -{ - fprintf(stderr, "Usage ... check source for now\n"); - exit(-1); -} - -gpointer -photo_grid_populate(gpointer data) -{ - CltrPhotoGrid *grid = (CltrPhotoGrid *)data; - GDir *dir; - GError *error; - const gchar *entry = NULL; - gchar *fullpath = NULL; - int n_pixb = 0, i =0; - ClutterFont *font = NULL; - PixbufPixel font_col = { 255, 0, 0, 255 }; - - font = font_new("Sans Bold 96"); - - if ((dir = g_dir_open (ImgPath, 0, &error)) == NULL) - { - /* handle this much better */ - fprintf(stderr, "failed to open '%s'\n", ImgPath); - return NULL; - } - - while ((entry = g_dir_read_name (dir)) != NULL) - { - if (!strcasecmp(&entry[strlen(entry)-4], ".png") - || !strcasecmp(&entry[strlen(entry)-4], ".jpg") - || !strcasecmp(&entry[strlen(entry)-5], ".jpeg")) - n_pixb++; - } - - g_dir_rewind (dir); - - while ((entry = g_dir_read_name (dir)) != NULL) - { - Pixbuf *pixb = NULL; - fullpath = g_strconcat(ImgPath, "/", entry, NULL); - - pixb = pixbuf_new_from_file(fullpath); - - if (pixb) - { - CltrPhotoGridCell *cell; - gchar buf[24]; - Pixbuf *tmp_pixb; - - cell = cltr_photo_grid_cell_new(grid, pixb); - - /* - g_snprintf(&buf[0], 24, "%i", i); - font_draw(font, cltr_photo_grid_cell_pixbuf(cell), - buf, 10, 10, &font_col); - */ - g_mutex_lock(cltr_photo_grid_mutex(grid)); - - if (!cltr_photo_grid_get_active_cell(grid)) - cltr_photo_grid_set_active_cell(grid, - cltr_photo_grid_get_first_cell(grid)); - - cltr_photo_grid_append_cell(grid, cell); - - g_mutex_unlock(cltr_photo_grid_mutex(grid)); - - i++; - } - - g_free(fullpath); - } - - g_dir_close (dir); - - g_mutex_lock(cltr_photo_grid_mutex(grid)); - - cltr_photo_grid_set_populated(grid, TRUE); - - g_mutex_unlock(cltr_photo_grid_mutex(grid)); - - cltr_widget_queue_paint(CLTR_WIDGET(grid)); - - return NULL; -} - -int -main(int argc, char **argv) -{ - CltrWidget *win = NULL, *grid = NULL; - gchar *img_path = NULL; - gboolean want_fullscreen = FALSE; - gint i, cols = 3; - - GThread *loader_thread; - - cltr_init(&argc, &argv); - - if (argc < 2) - usage(argv[0]); - - for (i = 1; i < argc; i++) - { - if (!strcmp ("--image-path", argv[i]) || !strcmp ("-i", argv[i])) - { - if (++i>=argc) usage (argv[0]); - ImgPath = argv[i]; - continue; - } - if (!strcmp ("--cols", argv[i]) || !strcmp ("-c", argv[i])) - { - if (++i>=argc) usage (argv[0]); - cols = atoi(argv[i]); - continue; - } - if (!strcmp ("-fs", argv[i]) || !strcmp ("--fullscreen", argv[i])) - { - want_fullscreen = TRUE; - continue; - } - if (!strcmp("--help", argv[i]) || !strcmp("-h", argv[i])) - { - usage(argv[0]); - } - - usage(argv[0]); - } - - win = cltr_window_new(800, 600); - - if (want_fullscreen) - cltr_window_set_fullscreen(CLTR_WINDOW(win)); - - grid = cltr_photo_grid_new(800, 600, cols, cols, ImgPath); - - cltr_window_focus_widget(CLTR_WINDOW(win), grid); - - cltr_widget_add_child(win, grid, 0, 0); - - cltr_widget_show_all(win); - - /* grid->state = CLTR_PHOTO_GRID_STATE_BROWSE; */ - - loader_thread = g_thread_create (photo_grid_populate, - (gpointer)grid, - TRUE, - NULL); - - - cltr_main_loop(); - - return 0; -} diff --git a/examples/player.c b/examples/player.c deleted file mode 100644 index c8c9f72ff..000000000 --- a/examples/player.c +++ /dev/null @@ -1,69 +0,0 @@ -#include - -int Paused = 0; - -void -handle_xevent(CltrWidget *win, XEvent *xev, void *cookie) -{ - KeySym kc; - CltrVideo *video = CLTR_VIDEO(cookie); - - if (xev->type == KeyPress) - { - XKeyEvent *xkeyev = &xev->xkey; - - kc = XKeycodeToKeysym(xkeyev->display, xkeyev->keycode, 0); - - switch (kc) - { - case XK_Return: - if (Paused) - cltr_video_play (video, NULL); - else - cltr_video_pause (video); - Paused ^= 1; - - break; - } - } - -} - -int -main (int argc, char *argv[]) -{ - CltrWidget *win, *video, *label; - CltrFont *font; - PixbufPixel col = { 0x66, 0x00, 0x00, 0x99 }; - - cltr_init (&argc, &argv); - - if (argc != 2) { - g_print ("usage: %s