--- /dev/null
+ GNU Free Documentation License
+ Version 1.2, November 2002
+
+
+ Copyright (C) 2000,2001,2002 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.
+
+
+0. PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document "free" in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of "copyleft", which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+
+1. APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The "Document", below,
+refers to any such manual or work. Any member of the public is a
+licensee, and is addressed as "you". You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A "Modified Version" of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A "Secondary Section" is a named appendix or a front-matter section of
+the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall subject
+(or to related matters) and contains nothing that could fall directly
+within that overall subject. (Thus, if the Document is in part a
+textbook of mathematics, a Secondary Section may not explain any
+mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The "Invariant Sections" are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License. If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant. The Document may contain zero
+Invariant Sections. If the Document does not identify any Invariant
+Sections then there are none.
+
+The "Cover Texts" are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License. A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A "Transparent" copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text. A copy that is not "Transparent" is called "Opaque".
+
+Examples of suitable formats for Transparent copies include plain
+ASCII without markup, Texinfo input format, LaTeX input format, SGML
+or XML using a publicly available DTD, and standard-conforming simple
+HTML, PostScript or PDF designed for human modification. Examples of
+transparent image formats include PNG, XCF and JPG. Opaque formats
+include proprietary formats that can be read and edited only by
+proprietary word processors, SGML or XML for which the DTD and/or
+processing tools are not generally available, and the
+machine-generated HTML, PostScript or PDF produced by some word
+processors for output purposes only.
+
+The "Title Page" means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, "Title Page" means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+A section "Entitled XYZ" means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as "Acknowledgements",
+"Dedications", "Endorsements", or "History".) To "Preserve the Title"
+of such a section when you modify the Document means that it remains a
+section "Entitled XYZ" according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+
+2. VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+
+3. COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+
+4. MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+A. Use in the Title Page (and on the covers, if any) a title distinct
+ from that of the Document, and from those of previous versions
+ (which should, if there were any, be listed in the History section
+ of the Document). You may use the same title as a previous version
+ if the original publisher of that version gives permission.
+B. List on the Title Page, as authors, one or more persons or entities
+ responsible for authorship of the modifications in the Modified
+ Version, together with at least five of the principal authors of the
+ Document (all of its principal authors, if it has fewer than five),
+ unless they release you from this requirement.
+C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+D. Preserve all the copyright notices of the Document.
+E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+F. Include, immediately after the copyright notices, a license notice
+ giving the public permission to use the Modified Version under the
+ terms of this License, in the form shown in the Addendum below.
+G. Preserve in that license notice the full lists of Invariant Sections
+ and required Cover Texts given in the Document's license notice.
+H. Include an unaltered copy of this License.
+I. Preserve the section Entitled "History", Preserve its Title, and add
+ to it an item stating at least the title, year, new authors, and
+ publisher of the Modified Version as given on the Title Page. If
+ there is no section Entitled "History" in the Document, create one
+ stating the title, year, authors, and publisher of the Document as
+ given on its Title Page, then add an item describing the Modified
+ Version as stated in the previous sentence.
+J. Preserve the network location, if any, given in the Document for
+ public access to a Transparent copy of the Document, and likewise
+ the network locations given in the Document for previous versions
+ it was based on. These may be placed in the "History" section.
+ You may omit a network location for a work that was published at
+ least four years before the Document itself, or if the original
+ publisher of the version it refers to gives permission.
+K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the section all
+ the substance and tone of each of the contributor acknowledgements
+ and/or dedications given therein.
+L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section titles.
+M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+N. Do not retitle any existing section to be Entitled "Endorsements"
+ or to conflict in title with any Invariant Section.
+O. Preserve any Warranty Disclaimers.
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled "Endorsements", provided it contains
+nothing but endorsements of your Modified Version by various
+parties--for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+
+5. COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled "History"
+in the various original documents, forming one section Entitled
+"History"; likewise combine any sections Entitled "Acknowledgements",
+and any sections Entitled "Dedications". You must delete all sections
+Entitled "Endorsements".
+
+
+6. COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+
+7. AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an "aggregate" if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included in an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+
+8. TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers. In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled "Acknowledgements",
+"Dedications", or "History", the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+
+9. TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document except
+as expressly provided for under this License. Any other attempt to
+copy, modify, sublicense or distribute the Document 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.
+
+
+10. FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation 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. See
+http://www.gnu.org/copyleft/.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License "or any later version" applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation.
+
+
+ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+ Copyright (c) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.2
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+ A copy of the license is included in the section entitled "GNU
+ Free Documentation License".
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with the
+ Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
--- /dev/null
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+\f
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
-SUBDIRS = po themes data render parser kernel plugins tools
+SUBDIRS = po themes data glft render2 parser kernel plugins tools
MAINTAINERCLEANFILES = aclocal.m4 config.h.in configure Makefile.in stamp-h.in
doc:
----
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+This program is licensed under a number of different terms:
+
+Anything found in the render2 and glft directories is licensed under version
+2.1 of the GNU Lesser General Public License as published by the Free Software
+Foundation, and can be redistributed and/or modified under its terms.
+
+Anything found in the doc directory is licensed under version 1.2 of the GNU
+Free Documentation License as published by the Free Software Foundation, and
+can be redistributed and/or modified under its terms; with no Invariant
+Sections, no Front-Cover Texts, and no Back-Cover Texts.
+
+The remainder of this program, not aforementioned, is licensed under
+version 2 or the GNU General Public License as published by the Free Software
+Foundation, and can be redistributed and/or modified under its terms.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- See the COPYING file for a copy of the GNU General Public License.
-
+See the COPYING.LGPL file for a copy of the GNU Lesser General Public License.
+See the COPYING.FDL file for a copy of the GNU Free Documentation License.
+See the COPYING.GPL file for a copy of the GNU General Public License.
AC_SUBST(GMODULE_CFLAGS)
AC_SUBST(GMODULE_LIBS)
+PKG_CHECK_MODULES(FC, [fontconfig])
+AC_SUBST(FC_CFLAGS)
+AC_SUBST(FC_LIBS)
+
+## XXX REMOVE ME PLS XXX ##
PKG_CHECK_MODULES(XFT, [xft])
AC_SUBST(XFT_CFLAGS)
AC_SUBST(XFT_LIBS)
+## XXX REMOVE ME PLS XXX ##
PKG_CHECK_MODULES(XML, [libxml-2.0])
AC_SUBST(XML_CFLAGS)
X11_EXT_SHAPE
X11_EXT_XINERAMA
-GL_OPTION
+GL_DEVEL
AC_CONFIG_FILES([Makefile
po/Makefile.in
themes/Makefile
data/Makefile
- render/Makefile
+ glft/Makefile
+ render2/Makefile
parser/Makefile
kernel/Makefile
plugins/Makefile
--- /dev/null
+.libs
+.deps
+Makefile.in
+Makefile
+libglft.la
+init.lo
+glfttest
+debug.lo
+font.lo
+render.lo
--- /dev/null
+themedir=$(datadir)/openbox/themes
+
+theme=operation
+
+CPPFLAGS=$(FC_CFLAGS) $(GLIB_CFLAGS) $(GL_CFLAGS) @CPPFLAGS@ \
+ $(shell freetype-config --cflags) \
+ -DG_LOG_DOMAIN=\"GlFt\" \
+ -DDEFAULT_THEME=\"$(theme)\" \
+ -DTHEMEDIR=\"$(themedir)\"
+
+INCLUDES=-I..
+LIBS=$(FC_LIBS) $(GLIB_LIBS) $(X_LIBS) $(GL_LIBS) \
+ $(shell freetype-config --libs) @LIBS@
+
+noinst_PROGRAMS=glfttest
+glfttest_LDFLAGS=-lglft -L.
+glfttest_SOURCES=test.c
+
+lib_LTLIBRARIES=libglft.la
+libglft_la_SOURCES=\
+ init.c \
+ font.c \
+ debug.c \
+ render.c
+
+noinst_HEADERS=\
+ glft.h \
+ font.h \
+ init.h \
+ debug.h \
+ render.h
+
+MAINTAINERCLEANFILES=Makefile.in
+
+distclean-local:
+ $(RM) *\~ *.orig *.rej .\#*
--- /dev/null
+#include <stdio.h>
+#include <stdarg.h>
+
+void GlftDebug(char *a, ...)
+{
+#ifdef DEBUG
+ va_list vl;
+ va_start(vl, a);
+ vprintf(a, vl);
+#endif
+}
--- /dev/null
+#ifndef __glft_debug_h
+#define __glft_debug_h
+
+void GlftDebug(char *a, ...);
+
+#endif
--- /dev/null
+#include "font.h"
+#include "glft.h"
+#include "init.h"
+#include "debug.h"
+#include "render.h"
+#include <assert.h>
+#include <stdlib.h>
+#include <GL/glx.h>
+
+struct GHashTable *glyph_map = NULL;
+
+#define FLOOR(x) ((x) & -64)
+#define CEIL(x) (((x)+63) & -64)
+#define TRUNC(x) ((x) >> 6)
+#define ROUND(x) (((x)+32) & -64)
+
+#define GLFT_SHADOW "shadow"
+#define GLFT_SHADOW_OFFSET "shadowoffset"
+#define GLFT_SHADOW_ALPHA "shadowalpha"
+
+void dest_glyph_map_value(gpointer key, gpointer val, gpointer data)
+{
+ struct GlftGlyph *g = val;
+ glDeleteTextures(1, &g->tnum);
+ free(g);
+}
+
+static void GlftDefaultSubstitute(Display *d, int s, FcPattern *pat)
+{
+ FcValue v;
+ double dpi;
+
+ if (FcPatternGet(pat, FC_DPI, 0, &v) == FcResultNoMatch) {
+ dpi = DisplayHeight(d, s) * 25.4 / (double)DisplayHeightMM(d, s);
+ FcPatternAddDouble(pat, FC_DPI, dpi);
+ }
+ if (FcPatternGet(pat, FC_ANTIALIAS, 0, &v) == FcResultNoMatch) {
+ FcPatternAddBool(pat, FC_ANTIALIAS, FcFalse);
+ g_message("SETTING ANTIALIAS TRUE");
+ }
+ if (FcPatternGet(pat, FC_HINTING, 0, &v) == FcResultNoMatch)
+ FcPatternAddBool(pat, FC_HINTING, FcTrue);
+ if (FcPatternGet(pat, FC_AUTOHINT, 0, &v) == FcResultNoMatch)
+ FcPatternAddBool(pat, FC_AUTOHINT, FcFalse);
+ if (FcPatternGet(pat, FC_GLOBAL_ADVANCE, 0, &v) == FcResultNoMatch)
+ FcPatternAddBool(pat, FC_GLOBAL_ADVANCE, FcTrue);
+ if (FcPatternGet(pat, FC_SPACING, 0, &v) == FcResultNoMatch)
+ FcPatternAddInteger(pat, FC_SPACING, FC_PROPORTIONAL);
+ if (FcPatternGet(pat, FC_MINSPACE, 0, &v) == FcResultNoMatch)
+ FcPatternAddBool(pat, FC_MINSPACE, FcTrue);
+ if (FcPatternGet(pat, FC_CHAR_WIDTH, 0, &v) == FcResultNoMatch)
+ FcPatternAddInteger(pat, FC_CHAR_WIDTH, 0);
+ if (FcPatternGet(pat, GLFT_SHADOW, 0, &v) == FcResultNoMatch)
+ FcPatternAddBool(pat, GLFT_SHADOW, FcFalse);
+ if (FcPatternGet(pat, GLFT_SHADOW_OFFSET, 0, &v) == FcResultNoMatch)
+ FcPatternAddInteger(pat, GLFT_SHADOW_OFFSET, 2);
+ if (FcPatternGet(pat, GLFT_SHADOW_ALPHA, 0, &v) == FcResultNoMatch)
+ FcPatternAddDouble(pat, GLFT_SHADOW_ALPHA, 0.5);
+
+ FcDefaultSubstitute(pat);
+}
+
+struct GlftFont *GlftFontOpen(Display *d, int screen, const char *name)
+{
+ struct GlftFont *font;
+ FcPattern *pat, *match;
+ FcResult res;
+ double alpha, psize;
+ FcBool hinting, autohint, advance;
+
+ assert(init_done);
+
+ pat = FcNameParse((const unsigned char*)name);
+ assert(pat);
+
+ /* XXX read our extended attributes here? (if failing below..) */
+
+ FcConfigSubstitute(NULL, pat, FcMatchPattern);
+ GlftDefaultSubstitute(d, screen, pat);
+
+ match = FcFontMatch(NULL, pat, &res);
+ FcPatternDestroy(pat);
+ if (!match) {
+ GlftDebug("failed to find matching font\n");
+ return NULL;
+ }
+
+ font = malloc(sizeof(struct GlftFont));
+ font->display = d;
+ font->screen = screen;
+ font->pat = match;
+ font->ftflags = FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP;
+
+ if (FcPatternGetString(match, FC_FILE, 0, (FcChar8**) &font->filename) !=
+ FcResultMatch) {
+ GlftDebug("error getting FC_FILE from pattern\n");
+ goto openfail0;
+ }
+
+ switch (FcPatternGetInteger(match, FC_INDEX, 0, &font->index)) {
+ case FcResultNoMatch:
+ font->index = 0;
+ break;
+ case FcResultMatch:
+ break;
+ default:
+ GlftDebug("error getting FC_INDEX from pattern\n");
+ goto openfail0;
+ }
+
+ switch (FcPatternGetBool(match, FC_ANTIALIAS, 0, &font->antialias)) {
+ case FcResultNoMatch:
+ font->antialias = FcTrue;
+ break;
+ case FcResultMatch:
+ break;
+ default:
+ GlftDebug("error getting FC_ANTIALIAS from pattern\n");
+ goto openfail0;
+ }
+
+ switch (FcPatternGetBool(match, FC_HINTING, 0, &hinting)) {
+ case FcResultNoMatch:
+ hinting = FcTrue;
+ break;
+ case FcResultMatch:
+ break;
+ default:
+ GlftDebug("error getting FC_HINTING from pattern\n");
+ goto openfail0;
+ }
+ if (!hinting) font->ftflags |= FT_LOAD_NO_HINTING;
+
+ switch (FcPatternGetBool(match, FC_AUTOHINT, 0, &autohint)) {
+ case FcResultNoMatch:
+ autohint = FcFalse;
+ break;
+ case FcResultMatch:
+ break;
+ default:
+ GlftDebug("error getting FC_AUTOHINT from pattern\n");
+ goto openfail0;
+ }
+ if (autohint) font->ftflags |= FT_LOAD_FORCE_AUTOHINT;
+
+ switch (FcPatternGetBool(match, FC_GLOBAL_ADVANCE, 0, &advance)) {
+ case FcResultNoMatch:
+ advance = FcTrue;
+ break;
+ case FcResultMatch:
+ break;
+ default:
+ GlftDebug("error getting FC_GLOBAL_ADVANCE from pattern\n");
+ goto openfail0;
+ }
+ if (!advance) font->ftflags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
+
+ switch (FcPatternGetInteger(match, FC_SPACING, 0, &font->spacing)) {
+ case FcResultNoMatch:
+ font->spacing = FC_PROPORTIONAL;
+ break;
+ case FcResultMatch:
+ break;
+ default:
+ GlftDebug("error getting FC_SPACING from pattern\n");
+ goto openfail0;
+ }
+
+ switch (FcPatternGetBool(match, FC_MINSPACE, 0, &font->minspace)) {
+ case FcResultNoMatch:
+ font->minspace = FcTrue;
+ break;
+ case FcResultMatch:
+ break;
+ default:
+ GlftDebug("error getting FC_MINSPACE from pattern\n");
+ goto openfail0;
+ }
+
+ switch (FcPatternGetInteger(match, FC_CHAR_WIDTH, 0, &font->char_width)) {
+ case FcResultNoMatch:
+ font->char_width = 0;
+ break;
+ case FcResultMatch:
+ if (font->char_width)
+ font->spacing = FC_MONO;
+ break;
+ default:
+ GlftDebug("error getting FC_CHAR_WIDTH from pattern\n");
+ goto openfail0;
+ }
+
+ if (FcPatternGetDouble(match, FC_PIXEL_SIZE, 0, &psize) != FcResultMatch)
+ goto openfail0;
+ font->ftcharsize = (FT_F26Dot6) psize * 64;
+
+ if (FcPatternGetBool(match, GLFT_SHADOW, 0, &font->shadow) != FcResultMatch)
+ font->shadow = FcFalse;
+
+ if (FcPatternGetInteger(match,GLFT_SHADOW_OFFSET,0,&font->shadow_offset) !=
+ FcResultMatch)
+ font->shadow_offset = 2;
+
+ if (FcPatternGetDouble(match, GLFT_SHADOW_ALPHA,0,&alpha) != FcResultMatch)
+ alpha = 0.5;
+ font->shadow_alpha = (float)alpha;
+
+ /* time to load the font! */
+
+ if (FT_New_Face(ft_lib, font->filename, font->index, &font->face)) {
+ GlftDebug("failed to open FT face\n");
+ goto openfail0;
+ }
+ assert(FT_IS_SCALABLE(font->face));
+ if (!FT_IS_SCALABLE(font->face)) {
+ GlftDebug("got a non-scalable face");
+ goto openfail1;
+ }
+ if (FT_Set_Char_Size(font->face, 0, font->ftcharsize, 0, 0)) {
+ GlftDebug("failed to set char size on FT face\n");
+ goto openfail1;
+ }
+
+ if (!FcPatternGetCharSet(match, FC_CHARSET, 0, &font->chars) !=
+ FcResultMatch)
+ font->chars = FcFreeTypeCharSet(font->face, FcConfigGetBlanks(NULL));
+ if (!font->chars) {
+ GlftDebug("failed to get a valid CharSet\n");
+ goto openfail1;
+ }
+
+ if (font->char_width)
+ font->max_advance_width = font->char_width;
+ else
+ font->max_advance_width = font->face->size->metrics.max_advance >> 6;
+ font->descent = -(font->face->size->metrics.descender >> 6);
+ font->ascent = font->face->size->metrics.ascender >> 6;
+ if (font->minspace) font->height = font->ascent + font->descent;
+ else font->height = font->face->size->metrics.height >> 6;
+
+ font->kerning = FT_HAS_KERNING(font->face);
+
+ font->glyph_map = g_hash_table_new(g_int_hash, g_int_equal);
+
+ return font;
+
+openfail1:
+ FT_Done_Face(font->face);
+openfail0:
+ FcPatternDestroy(match);
+ free(font);
+ return NULL;
+}
+
+void GlftFontClose(struct GlftFont *font)
+{
+ if (font) {
+ FT_Done_Face(font->face);
+ FcPatternDestroy(font->pat);
+ FcCharSetDestroy(font->chars);
+ g_hash_table_foreach(font->glyph_map, dest_glyph_map_value, NULL);
+ g_hash_table_destroy(font->glyph_map);
+ free(font);
+ }
+}
+
+struct GlftGlyph *GlftFontGlyph(struct GlftFont *font, const char *c)
+{
+ const char *n = g_utf8_next_char(c);
+ int b = n - c;
+ struct GlftGlyph *g;
+ FcChar32 w;
+
+ FcUtf8ToUcs4((const FcChar8*) c, &w, b);
+
+ g = g_hash_table_lookup(font->glyph_map, &w);
+ if (!g) {
+ if (FT_Load_Glyph(font->face, FcFreeTypeCharIndex(font->face, w),
+ font->ftflags)) {
+ if (FT_Load_Glyph(font->face, 0, font->ftflags))
+ return NULL;
+ else {
+ g = g_hash_table_lookup(font->glyph_map, &w);
+ }
+ }
+ }
+ if (!g) {
+ g = malloc(sizeof(struct GlftGlyph));
+ g->w = w;
+ glGenTextures(1, &g->tnum);
+
+ GlftRenderGlyph(font->face, g);
+
+ if (!(font->spacing == FC_PROPORTIONAL)) {
+ g->width = font->max_advance_width;
+ } else {
+ g->width = TRUNC(ROUND(font->face->glyph->metrics.horiAdvance));
+ }
+ g->x = TRUNC(FLOOR(font->face->glyph->metrics.horiBearingX));
+ g->y = TRUNC(CEIL(font->face->glyph->metrics.horiBearingY));
+ g->height = TRUNC(ROUND(font->face->glyph->metrics.height));
+
+ g_hash_table_insert(font->glyph_map, &g->w, g);
+ }
+
+ return g;
+}
+
+int GlftFontAdvance(struct GlftFont *font,
+ struct GlftGlyph *left,
+ struct GlftGlyph *right)
+{
+ FT_Vector v;
+ int k = 0;
+
+ if (left) k+= left->width;
+
+ if (right) {
+ k -= right->x;
+ if (font->kerning) {
+ FT_Get_Kerning(font->face, left->glyph, right->glyph,
+ FT_KERNING_UNFITTED, &v);
+ k += v.x >> 6;
+ }
+ }
+
+ return k;
+}
+
+int GlftFontHeight(struct GlftFont *font)
+{
+ return font->height;
+}
--- /dev/null
+#ifndef __glft_font_h
+#define __glft_font_h
+
+#include <fontconfig/fontconfig.h>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include <fontconfig/fcfreetype.h>
+
+#include <X11/Xlib.h>
+#include <glib.h>
+
+struct GlftFont {
+ Display *display;
+ int screen;
+
+ FcPattern *pat;
+ FcCharSet *chars;
+
+ char *filename;
+ int index;
+
+ FT_Face face;
+ FT_Int ftflags;
+ FT_F26Dot6 ftcharsize;
+
+ FcBool antialias;
+ int spacing;
+ FcBool minspace;
+ int char_width;
+ /* extended font attributes */
+ FcBool shadow;
+ int shadow_offset;
+ float shadow_alpha;
+
+ GHashTable *glyph_map;
+
+ int kerning : 1;
+
+ /* public shit */
+ int ascent;
+ int descent;
+ int height;
+ int max_advance_width;
+};
+
+struct GlftGlyph {
+ /* The character in UCS-4 encoding */
+ FcChar32 w;
+ /* OpenGL texture for the character */
+ unsigned int tnum;
+ /* The FT_Face glyph */
+ FT_UInt glyph;
+
+ int x;
+ int y;
+ int width;
+ int height;
+
+ int padx, pady;
+ int texw, texh;
+ int left, yoff;
+};
+
+/*! Takes a character in UTF-8 encoding and returns an OpenGL display list
+ for it */
+struct GlftGlyph *GlftFontGlyph(struct GlftFont *font, const char *c);
+
+int GlftFontAdvance(struct GlftFont *font,
+ struct GlftGlyph *left,
+ struct GlftGlyph *right);
+
+#endif
--- /dev/null
+#ifndef __glft_h__
+#define __glft_h__
+
+#include <fontconfig/fontconfig.h>
+#include <X11/Xlib.h>
+
+/* initialization */
+
+FcBool GlftInit();
+
+/* fonts */
+
+struct GlftFont;
+
+struct GlftFont *GlftFontOpen(Display *d, int screen, const char *name);
+
+void GlftFontClose(struct GlftFont *font);
+
+int GlftFontHeight(struct GlftFont *font);
+
+/* rendering */
+
+struct GlftColor {
+ float r;
+ float g;
+ float b;
+ float a;
+};
+
+/*! Renders a string in UTF-8 encoding */
+void GlftRenderString(struct GlftFont *font,
+ const char *str,
+ int bytes,
+ struct GlftColor *color,
+ int x,
+ int y);
+
+/* metrics */
+
+/*! Measures a string in UTF-8 encoding */
+void GlftMeasureString(struct GlftFont *font,
+ const char *str,
+ int bytes,
+ int *w,
+ int *h);
+
+#endif
--- /dev/null
+#include "glft.h"
+#include "font.h"
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include <fontconfig/fcfreetype.h>
+
+FcBool init_done = 0;
+FT_Library ft_lib;
+
+FcBool GlftInit()
+{
+ return init_done = (FcInit() && !FT_Init_FreeType(&ft_lib));
+}
--- /dev/null
+#ifndef __glft_init_h
+#define __glft_init_h
+
+extern FcBool init_done;
+extern FT_Library ft_lib;
+
+#endif
--- /dev/null
+#include "render.h"
+#include "font.h"
+#include "debug.h"
+#include "glft.h"
+#include <glib.h>
+#include <GL/glx.h>
+
+#define TPOINTS 15.0
+
+#define TOFLOAT(x) (((x) >> 6) + ((x) & 63)/64.0)
+
+void GlftRenderGlyph(FT_Face face, struct GlftGlyph *g)
+{
+ unsigned char *padbuf;
+ int err, i;
+ FT_GlyphSlot slot = face->glyph;
+
+ err = FT_Render_Glyph(slot, ft_render_mode_normal);
+ g_assert(!err);
+
+ g->texw = slot->bitmap.width;
+ g->texh = slot->bitmap.rows;
+
+ g->left = slot->bitmap_left;
+
+ g->yoff = slot->bitmap.rows - slot->bitmap_top;
+ g->padx = 1;
+ while (g->padx < slot->bitmap.width)
+ g->padx <<= 1;
+
+ g->pady = 1;
+ while (g->pady < slot->bitmap.rows)
+ g->pady <<= 1;
+
+ padbuf = g_new0(unsigned char, g->padx * g->pady);
+ for (i = 0; i < slot->bitmap.rows; i++)
+ memcpy(padbuf + i*g->padx,
+ slot->bitmap.buffer + i*slot->bitmap.width,
+ slot->bitmap.width);
+ glBindTexture(GL_TEXTURE_2D, g->tnum);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, g->padx, g->pady,
+ 0, GL_ALPHA, GL_UNSIGNED_BYTE, padbuf);
+
+ g_free(padbuf);
+}
+
+void GlftRenderString(struct GlftFont *font, const char *str, int bytes,
+ struct GlftColor *color, int x, int y)
+{
+ const char *c;
+ struct GlftGlyph *g, *p = NULL;
+
+ if (!g_utf8_validate(str, bytes, NULL)) {
+ GlftDebug("Invalid UTF-8 in string\n");
+ return;
+ }
+
+ glColor4f(color->r, color->g, color->b, color->a);
+ glPushMatrix();
+ glTranslatef(x, y, 0.0);
+ c = str;
+ while (c - str < bytes) {
+ g = GlftFontGlyph(font, c);
+ if (g) {
+ glTranslatef(GlftFontAdvance(font, p, g), 0.0, 0.0);
+ glBindTexture(GL_TEXTURE_2D, g->tnum);
+
+ glBegin(GL_QUADS);
+
+ glTexCoord2f(0, g->texh/(float)g->pady);
+ glVertex2i(g->left, 0 - g->yoff);
+
+ glTexCoord2f(g->texw/(float)g->padx, g->texh/(float)g->pady);
+ glVertex2i(g->left + g->texw, 0 - g->yoff);
+
+ glTexCoord2f(g->texw/(float)g->padx, 0);
+ glVertex2i(g->left + g->texw, g->texh - g->yoff);
+
+ glTexCoord2f(0, 0);
+ glVertex2i(g->left, g->texh - g->yoff);
+ glEnd();
+ } else
+ glTranslatef(font->max_advance_width, 0.0, 0.0);
+ p = g;
+ c = g_utf8_next_char(c);
+ }
+
+ glPopMatrix();
+}
+
+void GlftMeasureString(struct GlftFont *font,
+ const char *str,
+ int bytes,
+ int *w,
+ int *h)
+{
+ const char *c;
+ struct GlftGlyph *g, *p = NULL;
+
+ if (!g_utf8_validate(str, bytes, NULL)) {
+ GlftDebug("Invalid UTF-8 in string\n");
+ return;
+ }
+
+ *w = 0;
+ *h = 0;
+
+ c = str;
+ while (c - str < bytes) {
+ g = GlftFontGlyph(font, c);
+ if (g) {
+ *w += GlftFontAdvance(font, p, g);
+ *h = MAX(g->height, *h);
+ } else
+ *w += font->max_advance_width;
+ p = g;
+ c = g_utf8_next_char(c);
+ }
+}
--- /dev/null
+#ifndef __glft_render_h
+#define __glft_render_h
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#include "font.h"
+
+void GlftRenderGlyph(FT_Face face, struct GlftGlyph *g);
+
+#endif
--- /dev/null
+#include "glft.h"
+#include <stdio.h>
+
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/shape.h>
+#include <string.h>
+#include <stdlib.h>
+#include "render.h"
+#include <glib.h>
+#include <GL/glx.h>
+#include <assert.h>
+
+static int x_error_handler(Display * disp, XErrorEvent * error)
+{
+ char buf[1024];
+ XGetErrorText(disp, error->error_code, buf, 1024);
+ printf("%s\n", buf);
+ return 0;
+}
+
+#define X 10
+#define Y 10
+#define W 500
+#define H 500
+
+int main(int argc, char **argv)
+{
+ struct GlftColor col;
+ Display *display;
+ Window win;
+ XVisualInfo *vi;
+ XEvent report, report2;
+ XClassHint chint;
+ Atom delete_win, protocols;
+ GLXContext cont;
+ int quit;
+ int config[] =
+ { GLX_DEPTH_SIZE, 1, GLX_DOUBLEBUFFER, GLX_RGBA, None };
+
+ struct GlftFont *font;
+
+ if (argc < 3) {
+ printf("Usage: %s fontname text\n", argv[0]);
+ return 1;
+ }
+
+ if (!GlftInit()) return 1;
+
+ if (!(display = XOpenDisplay(NULL))) {
+ fprintf(stderr, "couldn't connect to X server in DISPLAY\n");
+ return EXIT_FAILURE;
+ }
+
+ font = GlftFontOpen(display, DefaultScreen(display), argv[1]);
+ assert(font);
+
+ XSetErrorHandler(x_error_handler);
+ win = XCreateWindow(display, RootWindow(display, DefaultScreen(display)),
+ X, Y, W, H, 0,
+ CopyFromParent, /* depth */
+ CopyFromParent, /* class */
+ CopyFromParent, /* visual */
+ 0, /* valuemask */
+ 0); /* attributes */
+ chint.res_name = "glfttest";
+ chint.res_class = "Glfttest";
+ XSetClassHint(display, win, &chint);
+ XSelectInput(display, win, ExposureMask | StructureNotifyMask);
+ XMapWindow(display, win);
+
+ vi = glXChooseVisual(display, DefaultScreen(display), config);
+ if (vi == NULL)
+ printf("no conforming visual\n");
+ cont = glXCreateContext(display, vi, NULL, GL_TRUE);
+ if (cont == NULL)
+ printf("context creation failed\n");
+ glXMakeCurrent(display, win, cont);
+
+ delete_win = XInternAtom(display, "WM_DELETE_WINDOW", False);
+ protocols = XInternAtom(display, "WM_PROTOCOLS", False);
+ XSetWMProtocols(display, win, &delete_win, 1);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-50, W-50, -100, H-100, 0, 10);
+ glMatrixMode(GL_MODELVIEW);
+ glEnable(GL_TEXTURE_2D);
+ glClearColor(0.0, 0.0, 1.0, 0.0);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ quit = 0;
+ while (!quit) {
+ XNextEvent(display, &report);
+ switch (report.type) {
+ case ClientMessage:
+ if ((Atom)report.xclient.message_type == protocols)
+ if ((Atom)report.xclient.data.l[0] == delete_win)
+ quit = 1;
+ case Expose:
+ glClear(GL_COLOR_BUFFER_BIT);
+ col.r = 0.0; col.g = 0.0; col.b = 0.0; col.a = 1.0;
+ GlftRenderString(font, argv[2], strlen(argv[2]), &col, 9, -9);
+ col.r = 1.0; col.g = 1.0; col.b = 0.0; col.a = 0.25;
+ GlftRenderString(font, argv[2], strlen(argv[2]), &col, 0, 0);
+ glXSwapBuffers(display, win);
+ case ConfigureNotify:
+ break;
+ }
+
+ }
+ GlftFontClose(font);
+
+ return 1;
+}
-# X11_DEVEL()
+# GL_DEVEL()
#
-# Check for the presence of the X Window System headers and libraries.
-# Sets the CPPFLAGS and LIBS variables as appropriate.
-AC_DEFUN([GL_OPTION],
+# Check for the presence of OpenGL development headers and libraries.
+# Sets the GL_CFLAGS and GL_LIBS variables as appropriate.
+AC_DEFUN([GL_DEVEL],
[
AC_REQUIRE([X11_DEVEL])
- AC_ARG_ENABLE(gl, [ --enable-gl enable support for OpenGL rendering default=no],
- ,[enable_gl="no"])
-
# Store these
OLDLIBS=$LIBS
OLDCPPFLAGS=$CPPFLAGS
- if test "$enable_gl" = "yes"; then
- AC_CHECK_LIB([GL], [glXGetConfig],
- ,
- [
- enable_gl="no"
- AC_MSG_WARN([Disabling GL rendering support])
- ])
- fi
-
- if test "$enable_gl" = "yes"; then
- CPPFLAGS="$CPPFLAGS $X_CFLAGS"
- LIBS="$LIBS $X_PRE_LIBS $X_LIBS $X_EXTRA_LIBS"
-
- AC_MSG_CHECKING([if we can compile with GL])
- AC_TRY_LINK(
- [
- #include <GL/gl.h>
- ],
- [
- GLfloat f = 0.0;
- glVertex3f(f, f, f);
- ],
- [
- AC_MSG_RESULT([yes])
- ],
- [
- AC_MSG_RESULT([no])
- AC_MSG_WARN([Disabling GL rendering support])
- enable_gl="no"
- ])
+ AC_CHECK_LIB([GL], [glXGetConfig],
+ ,
+ [
+ AC_MSG_ERROR([A valid libGL could not be found.])
+ ])
+
+ CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+ LIBS="$LIBS $X_PRE_LIBS $X_LIBS $X_EXTRA_LIBS"
+
+ AC_MSG_CHECKING([if we can compile with GL])
+ AC_TRY_LINK(
+ [
+ #include <GL/gl.h>
+ ],
+ [
+ GLfloat f = 0.0;
+ glVertex3f(f, f, f);
+ ],
+ [
+ AC_MSG_RESULT([yes])
+ ],
+ [
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([Could not compile against GL])
+ ])
- GL_CFLAGS=""
- GL_LIBS="-lGL"
- AC_SUBST(GL_CFLAGS)
- AC_SUBST(GL_LIBS)
- fi
+ GL_CFLAGS=""
+ GL_LIBS="-lGL"
+ AC_SUBST(GL_CFLAGS)
+ AC_SUBST(GL_LIBS)
CPPFLAGS=$OLDCPPFLAGS
LIBS=$OLDLIBS
-
- AC_MSG_CHECKING([if GL support is enabled])
- if test "$enable_gl" = "yes"; then
- AC_MSG_RESULT([yes])
-
- AC_DEFINE(USE_GL)
- else
- AC_MSG_RESULT([no])
- fi
- AM_CONDITIONAL([USE_GL], [test "$enable_gl" = "yes"])
])
bin_PROGRAMS=$(binary)
-openbox3_LDADD=-lobrender -L../render -lobparser -L../parser
+openbox3_LDADD=-lobrender2 -L../render2 -lobparser -L../parser
openbox3_LDFLAGS=-export-dynamic
openbox3_SOURCES=action.c client.c config.c \
extensions.c focus.c frame.c grab.c menu.c menu_render.c \
#include "group.h"
#include "config.h"
#include "menu.h"
-#include "render/render.h"
+#include "render2/render.h"
#include <glib.h>
#include <X11/Xutil.h>
if (w*h == 0) continue;
- self->icons[j].data = g_new(pixel32, w * h);
+ self->icons[j].data = g_new(RrData32, w * h);
for (x = 0, y = 0, t = 0; t < w * h; ++t, ++x, ++i) {
if (x >= w) {
x = 0;
++y;
}
+ /* XXX optimize me, less shifts pls */
self->icons[j].data[t] =
- (((data[i] >> 24) & 0xff) << default_alpha_offset) +
- (((data[i] >> 16) & 0xff) << default_red_offset) +
- (((data[i] >> 8) & 0xff) << default_green_offset) +
- (((data[i] >> 0) & 0xff) << default_blue_offset);
+ (((data[i] >> 24) & 0xff) << 0) +
+ (((data[i] >> 16) & 0xff) << 24) +
+ (((data[i] >> 8) & 0xff) << 16) +
+ (((data[i] >> 0) & 0xff) << 8);
}
g_assert(i <= num);
}
g_free(data);
- } else if (PROP_GETA32(self->window, kwm_win_icon,
+ }/* XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX
+ else if (PROP_GETA32(self->window, kwm_win_icon,
kwm_win_icon, &data, &num)) {
if (num == 2) {
self->nicons++;
XFree(hints);
}
}
+*/
if (self->frame)
frame_adjust_icon(self->frame);
#include "geom.h"
#include "stacking.h"
-#include "render/color.h"
+#include "render2/render.h"
#include <glib.h>
#include <X11/Xlib.h>
/*! Holds an icon in ARGB format */
typedef struct Icon {
int width, height;
- pixel32 *data;
+ RrData32 *data;
} Icon;
/*! The MWM Hints as retrieved from the window property
#include "config.h"
#include "grab.h"
#include "openbox.h"
-#include "render/theme.h"
+#include "render2/render.h"
+#include "render2/theme.h"
#define DOCK_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | \
EnterWindowMask | LeaveWindowMask)
attrib.event_mask = DOCK_EVENT_MASK;
attrib.override_redirect = True;
dock->frame = XCreateWindow(ob_display, ob_root, 0, 0, 1, 1, 0,
- render_depth, InputOutput, render_visual,
+ RrInstanceDepth(ob_render_inst),
+ InputOutput,
+ RrInstanceVisual(ob_render_inst),
CWOverrideRedirect | CWEventMask,
&attrib);
- dock->a_frame = appearance_copy(theme_a_unfocused_title);
- XSetWindowBorder(ob_display, dock->frame, theme_b_color->pixel);
- XSetWindowBorderWidth(ob_display, dock->frame, theme_bwidth);
+ dock->s_frame = RrSurfaceNew(ob_render_inst, 0, dock->frame, 0);
+ RrSurfaceCopy(dock->s_frame, ob_theme->title);
g_hash_table_insert(window_map, &dock->frame, dock);
stacking_add(DOCK_AS_WINDOW(dock));
void dock_shutdown()
{
+ RrSurfaceFree(dock->s_frame);
XDestroyWindow(ob_display, dock->frame);
- appearance_free(dock->a_frame);
g_hash_table_remove(window_map, &dock->frame);
stacking_remove(dock);
}
XMoveWindow(ob_display, app->icon_win, app->x, app->y);
}
- /* used for calculating offsets */
- dock->w += theme_bwidth * 2;
- dock->h += theme_bwidth * 2;
+ dock->w += ob_theme->bwidth * 2;
+ dock->h += ob_theme->bwidth * 2;
/* calculate position */
switch (config_dock_pos) {
break;
case DockPos_TopLeft:
if (config_dock_horz)
- dock->y -= dock->h - theme_bwidth;
+ dock->y -= dock->h - ob_theme->bwidth;
else
- dock->x -= dock->w - theme_bwidth;
+ dock->x -= dock->w - ob_theme->bwidth;
break;
case DockPos_Top:
- dock->y -= dock->h - theme_bwidth;
+ dock->y -= dock->h - ob_theme->bwidth;
break;
case DockPos_TopRight:
if (config_dock_horz)
- dock->y -= dock->h - theme_bwidth;
+ dock->y -= dock->h - ob_theme->bwidth;
else
- dock->x += dock->w - theme_bwidth;
+ dock->x += dock->w - ob_theme->bwidth;
break;
case DockPos_Left:
- dock->x -= dock->w - theme_bwidth;
+ dock->x -= dock->w - ob_theme->bwidth;
break;
case DockPos_Right:
- dock->x += dock->w - theme_bwidth;
+ dock->x += dock->w - ob_theme->bwidth;
break;
case DockPos_BottomLeft:
if (config_dock_horz)
- dock->y += dock->h - theme_bwidth;
+ dock->y += dock->h - ob_theme->bwidth;
else
- dock->x -= dock->w - theme_bwidth;
+ dock->x -= dock->w - ob_theme->bwidth;
break;
case DockPos_Bottom:
- dock->y += dock->h - theme_bwidth;
+ dock->y += dock->h - ob_theme->bwidth;
break;
case DockPos_BottomRight:
if (config_dock_horz)
- dock->y += dock->h - theme_bwidth;
+ dock->y += dock->h - ob_theme->bwidth;
else
- dock->x += dock->w - theme_bwidth;
+ dock->x += dock->w - ob_theme->bwidth;
break;
}
}
break;
}
- /* not used for actually sizing shit */
- dock->w -= theme_bwidth * 2;
- dock->h -= theme_bwidth * 2;
-
if (dock->w > 0 && dock->h > 0) {
- RECT_SET(dock->a_frame->area, 0, 0, dock->w, dock->h);
- XMoveResizeWindow(ob_display, dock->frame,
- dock->x, dock->y, dock->w, dock->h);
-
- paint(dock->frame, dock->a_frame);
- XMapWindow(ob_display, dock->frame);
+ RrSurfaceSetArea(dock->s_frame, dock->x, dock->y, dock->w, dock->h);
+ RrSurfaceShow(dock->s_frame);
} else
- XUnmapWindow(ob_display, dock->frame);
+ RrSurfaceHide(dock->s_frame);
- /* but they are useful outside of this function! */
- dock->w += theme_bwidth * 2;
- dock->h += theme_bwidth * 2;
+ dock->w += ob_theme->bwidth * 2;
+ dock->h += ob_theme->bwidth * 2;
screen_update_struts();
}
#include "window.h"
#include "stacking.h"
#include "geom.h"
-#include "render/render.h"
+#include "render2/render.h"
#include <glib.h>
#include <X11/Xlib.h>
ObWindow obwin;
Window frame;
- Appearance *a_frame;
+ struct RrSurface *s_frame;
/* actual position (when not auto-hidden) */
int x, y;
sn_display_process_event(ob_sn_display, &e);
#endif
+ if (ob_state == State_Running && e.type == Expose)
+ RrExpose(ob_render_inst, &e.xexpose);
+
event_process(&e);
had_event = TRUE;
}
#include "openbox.h"
#include "extensions.h"
#include "framerender.h"
-#include "render/theme.h"
+#include "render2/theme.h"
#define PLATE_EVENTMASK (SubstructureRedirectMask | ButtonPressMask)
#define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
- ButtonPressMask | ButtonReleaseMask)
+ ButtonPressMask | ButtonReleaseMask | ExposureMask)
#define ELEMENT_EVENTMASK (ButtonPressMask | ButtonReleaseMask | \
ButtonMotionMask | ExposureMask)
void frame_startup()
{
- RECT_SET(theme_a_focused_pressed_desk->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_focused_pressed_set_desk->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_focused_unpressed_desk->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_unfocused_pressed_desk->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_unfocused_pressed_set_desk->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_unfocused_unpressed_desk->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_focused_pressed_shade->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_focused_pressed_set_shade->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_focused_unpressed_shade->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_unfocused_pressed_shade->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_unfocused_pressed_set_shade->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_unfocused_unpressed_shade->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_focused_pressed_iconify->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_focused_unpressed_iconify->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_unfocused_pressed_iconify->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_unfocused_unpressed_iconify->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_unfocused_unpressed_iconify->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_focused_pressed_max->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_focused_pressed_set_max->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_focused_unpressed_max->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_unfocused_pressed_max->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_unfocused_pressed_set_max->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_unfocused_unpressed_max->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_focused_pressed_close->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_focused_unpressed_close->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_unfocused_pressed_close->area, 0, 0,
- theme_button_size, theme_button_size);
- RECT_SET(theme_a_unfocused_unpressed_close->area, 0, 0,
- theme_button_size, theme_button_size);
-
- RECT_SET(theme_a_focused_grip->area, 0, 0,
- theme_grip_width, theme_handle_height);
- RECT_SET(theme_a_unfocused_grip->area, 0, 0,
- theme_grip_width, theme_handle_height);
}
void frame_shutdown()
XSetWindowAttributes *attrib)
{
return XCreateWindow(ob_display, parent, 0, 0, 1, 1, 0,
- render_depth, InputOutput, render_visual,
- mask, attrib);
+ RrInstanceDepth(ob_render_inst), InputOutput,
+ RrInstanceVisual(ob_render_inst), mask, attrib);
}
mask = 0;
self->plate = createWindow(self->window, mask, &attrib);
- mask = CWEventMask;
- attrib.event_mask = ELEMENT_EVENTMASK;
- self->title = createWindow(self->window, mask, &attrib);
- self->label = createWindow(self->title, mask, &attrib);
- self->max = createWindow(self->title, mask, &attrib);
- self->close = createWindow(self->title, mask, &attrib);
- self->desk = createWindow(self->title, mask, &attrib);
- self->shade = createWindow(self->title, mask, &attrib);
- self->icon = createWindow(self->title, mask, &attrib);
- self->iconify = createWindow(self->title, mask, &attrib);
- self->handle = createWindow(self->window, mask, &attrib);
- mask |= CWCursor;
- attrib.cursor = ob_cursors.bl;
- self->lgrip = createWindow(self->handle, mask, &attrib);
- attrib.cursor = ob_cursors.br;
- self->rgrip = createWindow(self->handle, mask, &attrib);
+ self->s_frame = RrSurfaceNew(ob_render_inst, 0, self->window, 0);
+ self->s_title = RrSurfaceNewChild(0, self->s_frame, 0);
+ self->s_label = RrSurfaceNewChild(0, self->s_title, 0);
+ self->s_max = RrSurfaceNewChild(0, self->s_title, 0);
+ self->s_close = RrSurfaceNewChild(0, self->s_title, 0);
+ self->s_desk = RrSurfaceNewChild(0, self->s_title, 0);
+ self->s_shade = RrSurfaceNewChild(0, self->s_title, 0);
+ self->s_iconify = RrSurfaceNewChild(0, self->s_title, 0);
+ self->s_icon = RrSurfaceNewChild(0, self->s_title, 0);
+ self->s_handle = RrSurfaceNewChild(0, self->s_frame, 0);
+ self->s_lgrip = RrSurfaceNewChild(0, self->s_handle, 0);
+ self->s_rgrip = RrSurfaceNewChild(0, self->s_handle, 0);
+
+ self->w_title = RrSurfaceWindow(self->s_title);
+ self->w_label = RrSurfaceWindow(self->s_label);
+ self->w_max = RrSurfaceWindow(self->s_max);
+ self->w_close = RrSurfaceWindow(self->s_close);
+ self->w_desk = RrSurfaceWindow(self->s_desk);
+ self->w_shade = RrSurfaceWindow(self->s_shade);
+ self->w_iconify = RrSurfaceWindow(self->s_iconify);
+ self->w_icon = RrSurfaceWindow(self->s_icon);
+ self->w_handle = RrSurfaceWindow(self->s_handle);
+ self->w_lgrip = RrSurfaceWindow(self->s_lgrip);
+ self->w_rgrip = RrSurfaceWindow(self->s_rgrip);
+
+ XSelectInput(ob_display, self->w_title, ELEMENT_EVENTMASK);
+ XSelectInput(ob_display, self->w_label, ELEMENT_EVENTMASK);
+ XSelectInput(ob_display, self->w_max, ELEMENT_EVENTMASK);
+ XSelectInput(ob_display, self->w_close, ELEMENT_EVENTMASK);
+ XSelectInput(ob_display, self->w_desk, ELEMENT_EVENTMASK);
+ XSelectInput(ob_display, self->w_shade, ELEMENT_EVENTMASK);
+ XSelectInput(ob_display, self->w_iconify, ELEMENT_EVENTMASK);
+ XSelectInput(ob_display, self->w_icon, ELEMENT_EVENTMASK);
+ XSelectInput(ob_display, self->w_handle, ELEMENT_EVENTMASK);
+ XSelectInput(ob_display, self->w_lgrip, ELEMENT_EVENTMASK);
+ XSelectInput(ob_display, self->w_rgrip, ELEMENT_EVENTMASK);
+
+ XDefineCursor(ob_display, self->w_lgrip, ob_cursors.bl);
+ XDefineCursor(ob_display, self->w_rgrip, ob_cursors.br);
self->focused = FALSE;
/* the other stuff is shown based on decor settings */
XMapWindow(ob_display, self->plate);
- XMapWindow(ob_display, self->lgrip);
- XMapWindow(ob_display, self->rgrip);
- XMapWindow(ob_display, self->label);
-
- /* set colors/appearance/sizes for stuff that doesn't change */
- XSetWindowBorder(ob_display, self->window, theme_b_color->pixel);
- XSetWindowBorder(ob_display, self->label, theme_b_color->pixel);
- XSetWindowBorder(ob_display, self->rgrip, theme_b_color->pixel);
- XSetWindowBorder(ob_display, self->lgrip, theme_b_color->pixel);
-
- XResizeWindow(ob_display, self->max, theme_button_size, theme_button_size);
- XResizeWindow(ob_display, self->iconify,
- theme_button_size, theme_button_size);
- XResizeWindow(ob_display, self->icon,
- theme_button_size + 2, theme_button_size + 2);
- XResizeWindow(ob_display, self->close,
- theme_button_size, theme_button_size);
- XResizeWindow(ob_display, self->desk,
- theme_button_size, theme_button_size);
- XResizeWindow(ob_display, self->shade,
- theme_button_size, theme_button_size);
- XResizeWindow(ob_display, self->lgrip,
- theme_grip_width, theme_handle_height);
- XResizeWindow(ob_display, self->rgrip,
- theme_grip_width, theme_handle_height);
-
- /* set up the dynamic appearances */
- self->a_unfocused_title = appearance_copy(theme_a_unfocused_title);
- self->a_focused_title = appearance_copy(theme_a_focused_title);
- self->a_unfocused_label = appearance_copy(theme_a_unfocused_label);
- self->a_focused_label = appearance_copy(theme_a_focused_label);
- self->a_unfocused_handle = appearance_copy(theme_a_unfocused_handle);
- self->a_focused_handle = appearance_copy(theme_a_focused_handle);
- self->a_icon = appearance_copy(theme_a_icon);
+ RrSurfaceShow(self->s_label);
+ RrSurfaceShow(self->s_lgrip);
+ RrSurfaceShow(self->s_rgrip);
self->max_press = self->close_press = self->desk_press =
self->iconify_press = self->shade_press = FALSE;
static void frame_free(Frame *self)
{
- appearance_free(self->a_unfocused_title);
- appearance_free(self->a_focused_title);
- appearance_free(self->a_unfocused_label);
- appearance_free(self->a_focused_label);
- appearance_free(self->a_unfocused_handle);
- appearance_free(self->a_focused_handle);
- appearance_free(self->a_icon);
-
+ RrSurfaceFree(self->s_rgrip);
+ RrSurfaceFree(self->s_lgrip);
+ RrSurfaceFree(self->s_handle);
+ RrSurfaceFree(self->s_icon);
+ RrSurfaceFree(self->s_iconify);
+ RrSurfaceFree(self->s_shade);
+ RrSurfaceFree(self->s_desk);
+ RrSurfaceFree(self->s_close);
+ RrSurfaceFree(self->s_max);
+ RrSurfaceFree(self->s_label);
+ RrSurfaceFree(self->s_title);
+ RrSurfaceFree(self->s_frame);
+
+ XDestroyWindow(ob_display, self->plate);
XDestroyWindow(ob_display, self->window);
g_free(self);
{
if (!self->visible) {
self->visible = TRUE;
- XMapWindow(ob_display, self->window);
+ RrSurfaceShow(self->s_frame);
}
}
if (self->visible) {
self->visible = FALSE;
self->client->ignore_unmaps++;
- XUnmapWindow(ob_display, self->window);
+ RrSurfaceHide(self->s_frame);
}
}
if (!self->client->shaped) {
/* clear the shape on the frame window */
XShapeCombineMask(ob_display, self->window, ShapeBounding,
- self->innersize.left,
- self->innersize.top,
+ self->size.left,
+ self->size.top,
None, ShapeSet);
} else {
/* make the frame's shape match the clients */
XShapeCombineShape(ob_display, self->window, ShapeBounding,
- self->innersize.left,
- self->innersize.top,
+ self->size.left,
+ self->size.top,
self->client->window,
ShapeBounding, ShapeSet);
num = 0;
if (self->client->decorations & Decor_Titlebar) {
- xrect[0].x = -theme_bevel;
- xrect[0].y = -theme_bevel;
- xrect[0].width = self->width + self->bwidth * 2;
- xrect[0].height = theme_title_height +
- self->bwidth * 2;
+ xrect[0].x = 0;
+ xrect[0].y = 0;
+ xrect[0].width = self->area.width;
+ xrect[0].height = self->size.top - ob_theme->bwidth;
++num;
}
if (self->client->decorations & Decor_Handle) {
- xrect[1].x = -theme_bevel;
+ xrect[1].x = 0;
xrect[1].y = FRAME_HANDLE_Y(self);
- xrect[1].width = self->width + self->bwidth * 2;
- xrect[1].height = theme_handle_height +
- self->bwidth * 2;
+ xrect[1].width = self->area.width;
+ xrect[1].height = self->size.bottom - ob_theme->bwidth;
++num;
}
{
if (resized) {
if (self->client->decorations & Decor_Border) {
- self->bwidth = theme_bwidth;
- self->cbwidth = theme_cbwidth;
+ self->bwidth = ob_theme->bwidth;
+ self->cbwidth = ob_theme->cbwidth;
} else {
self->bwidth = self->cbwidth = 0;
}
- STRUT_SET(self->innersize, self->cbwidth, self->cbwidth,
- self->cbwidth, self->cbwidth);
- self->width = self->client->area.width + self->cbwidth * 2;
+ STRUT_SET(self->size,
+ self->bwidth + self->cbwidth,
+ self->bwidth + self->cbwidth,
+ self->bwidth + self->cbwidth,
+ self->bwidth + self->cbwidth);
+ self->width = self->client->area.width +
+ (self->bwidth + self->cbwidth) * 2;
g_assert(self->width > 0);
- /* set border widths */
- XSetWindowBorderWidth(ob_display, self->plate, self->cbwidth);
- XSetWindowBorderWidth(ob_display, self->window, self->bwidth);
- XSetWindowBorderWidth(ob_display, self->title, self->bwidth);
- XSetWindowBorderWidth(ob_display, self->handle, self->bwidth);
- XSetWindowBorderWidth(ob_display, self->lgrip, self->bwidth);
- XSetWindowBorderWidth(ob_display, self->rgrip, self->bwidth);
-
/* position/size and map/unmap all the windows */
/* they all default off, they're turned on in layout_title */
self->close_x = -1;
if (self->client->decorations & Decor_Titlebar) {
- XMoveResizeWindow(ob_display, self->title,
- -self->bwidth, -self->bwidth,
- self->width, theme_title_height);
- self->innersize.top += theme_title_height + self->bwidth;
- XMapWindow(ob_display, self->title);
-
- RECT_SET(self->a_focused_title->area, 0, 0,
- self->width, theme_title_height);
- RECT_SET(self->a_unfocused_title->area, 0, 0,
- self->width, theme_title_height);
+ RrSurfaceSetArea(self->s_title, 0, 0,
+ self->width, RrThemeTitleHeight(ob_theme));
+ self->size.top += RrThemeTitleHeight(ob_theme) - self->bwidth;
+ RrSurfaceShow(self->s_title);
/* layout the title bar elements */
layout_title(self);
} else
- XUnmapWindow(ob_display, self->title);
+ RrSurfaceHide(self->s_title);
if (self->client->decorations & Decor_Handle) {
- XMoveResizeWindow(ob_display, self->handle,
- -self->bwidth, FRAME_HANDLE_Y(self),
- self->width, theme_handle_height);
- XMoveWindow(ob_display, self->lgrip,
- -self->bwidth, -self->bwidth);
- XMoveWindow(ob_display, self->rgrip,
- -self->bwidth + self->width -
- theme_grip_width, -self->bwidth);
- self->innersize.bottom += theme_handle_height +
- self->bwidth;
- XMapWindow(ob_display, self->handle);
-
- if (theme_a_focused_grip->surface.data.planar.grad ==
- Background_ParentRelative)
- RECT_SET(self->a_focused_handle->area, 0, 0,
- self->width, theme_handle_height);
- else
- RECT_SET(self->a_focused_handle->area,
- theme_grip_width + self->bwidth, 0,
- self->width - (theme_grip_width + self->bwidth) * 2,
- theme_handle_height);
- if (theme_a_unfocused_grip->surface.data.planar.grad ==
- Background_ParentRelative)
- RECT_SET(self->a_unfocused_handle->area, 0, 0,
- self->width, theme_handle_height);
- else
- RECT_SET(self->a_unfocused_handle->area,
- theme_grip_width + self->bwidth, 0,
- self->width - (theme_grip_width + self->bwidth) * 2,
- theme_handle_height);
-
+ RrSurfaceSetArea(self->s_handle, 0, FRAME_HANDLE_Y(self),
+ self->width, ob_theme->handle_height);
+ RrSurfaceSetArea(self->s_lgrip, 0, 0,
+ RrThemeGripWidth(ob_theme),
+ ob_theme->handle_height);
+ RrSurfaceSetArea(self->s_lgrip,
+ self->width - RrThemeGripWidth(ob_theme), 0,
+ RrThemeGripWidth(ob_theme),
+ ob_theme->handle_height);
+ self->size.bottom += ob_theme->handle_height - ob_theme->bwidth;
+ RrSurfaceShow(self->s_handle);
} else
- XUnmapWindow(ob_display, self->handle);
+ RrSurfaceHide(self->s_handle);
}
if (resized) {
/* move and resize the plate */
XMoveResizeWindow(ob_display, self->plate,
- self->innersize.left - self->cbwidth,
- self->innersize.top - self->cbwidth,
+ self->size.left - self->cbwidth,
+ self->size.top - self->cbwidth,
self->client->area.width,
self->client->area.height);
/* when the client has StaticGravity, it likes to move around. */
XMoveWindow(ob_display, self->client->window, 0, 0);
}
- if (resized) {
- STRUT_SET(self->size,
- self->innersize.left + self->bwidth,
- self->innersize.top + self->bwidth,
- self->innersize.right + self->bwidth,
- self->innersize.bottom + self->bwidth);
- }
-
/* shading can change without being moved or resized */
RECT_SET_SIZE(self->area,
self->client->area.width +
self->size.left + self->size.right,
- (self->client->shaded ? theme_title_height + self->bwidth*2:
+ (self->client->shaded ? RrThemeTitleHeight(ob_theme) :
self->client->area.height +
self->size.top + self->size.bottom));
/* move and resize the top level frame.
shading can change without being moved or resized */
- XMoveResizeWindow(ob_display, self->window,
- self->area.x, self->area.y,
- self->width,
- self->area.height - self->bwidth * 2);
+ RrSurfaceSetArea(self->s_frame, self->area.x, self->area.y,
+ self->area.width, self->area.height);
if (resized) {
framerender_frame(self);
/* set all the windows for the frame in the window_map */
g_hash_table_insert(window_map, &self->window, client);
g_hash_table_insert(window_map, &self->plate, client);
- g_hash_table_insert(window_map, &self->title, client);
- g_hash_table_insert(window_map, &self->label, client);
- g_hash_table_insert(window_map, &self->max, client);
- g_hash_table_insert(window_map, &self->close, client);
- g_hash_table_insert(window_map, &self->desk, client);
- g_hash_table_insert(window_map, &self->shade, client);
- g_hash_table_insert(window_map, &self->icon, client);
- g_hash_table_insert(window_map, &self->iconify, client);
- g_hash_table_insert(window_map, &self->handle, client);
- g_hash_table_insert(window_map, &self->lgrip, client);
- g_hash_table_insert(window_map, &self->rgrip, client);
+ g_hash_table_insert(window_map, &self->w_title, client);
+ g_hash_table_insert(window_map, &self->w_label, client);
+ g_hash_table_insert(window_map, &self->w_max, client);
+ g_hash_table_insert(window_map, &self->w_close, client);
+ g_hash_table_insert(window_map, &self->w_desk, client);
+ g_hash_table_insert(window_map, &self->w_shade, client);
+ g_hash_table_insert(window_map, &self->w_iconify, client);
+ g_hash_table_insert(window_map, &self->w_icon, client);
+ g_hash_table_insert(window_map, &self->w_handle, client);
+ g_hash_table_insert(window_map, &self->w_lgrip, client);
+ g_hash_table_insert(window_map, &self->w_rgrip, client);
}
void frame_release_client(Frame *self, Client *client)
/* remove all the windows for the frame from the window_map */
g_hash_table_remove(window_map, &self->window);
g_hash_table_remove(window_map, &self->plate);
- g_hash_table_remove(window_map, &self->title);
- g_hash_table_remove(window_map, &self->label);
- g_hash_table_remove(window_map, &self->max);
- g_hash_table_remove(window_map, &self->close);
- g_hash_table_remove(window_map, &self->desk);
- g_hash_table_remove(window_map, &self->shade);
- g_hash_table_remove(window_map, &self->icon);
- g_hash_table_remove(window_map, &self->iconify);
- g_hash_table_remove(window_map, &self->handle);
- g_hash_table_remove(window_map, &self->lgrip);
- g_hash_table_remove(window_map, &self->rgrip);
+ g_hash_table_remove(window_map, &self->w_title);
+ g_hash_table_remove(window_map, &self->w_label);
+ g_hash_table_remove(window_map, &self->w_max);
+ g_hash_table_remove(window_map, &self->w_close);
+ g_hash_table_remove(window_map, &self->w_desk);
+ g_hash_table_remove(window_map, &self->w_shade);
+ g_hash_table_remove(window_map, &self->w_icon);
+ g_hash_table_remove(window_map, &self->w_iconify);
+ g_hash_table_remove(window_map, &self->w_handle);
+ g_hash_table_remove(window_map, &self->w_lgrip);
+ g_hash_table_remove(window_map, &self->w_rgrip);
frame_free(self);
}
n = d = i = l = m = c = s = FALSE;
/* figure out whats being shown, and the width of the label */
- self->label_width = self->width - (theme_bevel + 1) * 2;
- for (lc = theme_title_layout; *lc != '\0'; ++lc) {
+ self->label_width = self->width - (ob_theme->bevel + 1) * 2;
+ for (lc = ob_theme->title_layout; *lc != '\0'; ++lc) {
switch (*lc) {
case 'N':
if (!(self->client->decorations & Decor_Icon)) break;
if (n) { *lc = ' '; break; } /* rm duplicates */
n = TRUE;
- self->label_width -= theme_button_size + 2 + theme_bevel + 1;
+ self->label_width -= RrThemeButtonSize(ob_theme) + 2 +
+ ob_theme->bevel + 1;
break;
case 'D':
if (!(self->client->decorations & Decor_AllDesktops)) break;
if (d) { *lc = ' '; break; } /* rm duplicates */
d = TRUE;
- self->label_width -= theme_button_size + theme_bevel + 1;
+ self->label_width -= RrThemeButtonSize(ob_theme) +
+ ob_theme->bevel + 1;
break;
case 'S':
if (!(self->client->decorations & Decor_Shade)) break;
if (s) { *lc = ' '; break; } /* rm duplicates */
s = TRUE;
- self->label_width -= theme_button_size + theme_bevel + 1;
+ self->label_width -= RrThemeButtonSize(ob_theme) +
+ ob_theme->bevel + 1;
break;
case 'I':
if (!(self->client->decorations & Decor_Iconify)) break;
if (i) { *lc = ' '; break; } /* rm duplicates */
i = TRUE;
- self->label_width -= theme_button_size + theme_bevel + 1;
+ self->label_width -= RrThemeButtonSize(ob_theme) +
+ ob_theme->bevel + 1;
break;
case 'L':
if (l) { *lc = ' '; break; } /* rm duplicates */
if (!(self->client->decorations & Decor_Maximize)) break;
if (m) { *lc = ' '; break; } /* rm duplicates */
m = TRUE;
- self->label_width -= theme_button_size + theme_bevel + 1;
+ self->label_width -= RrThemeButtonSize(ob_theme) +
+ ob_theme->bevel + 1;
break;
case 'C':
if (!(self->client->decorations & Decor_Close)) break;
if (c) { *lc = ' '; break; } /* rm duplicates */
c = TRUE;
- self->label_width -= theme_button_size + theme_bevel + 1;
+ self->label_width -= RrThemeButtonSize(ob_theme) +
+ ob_theme->bevel + 1;
break;
}
}
if (self->label_width < 1) self->label_width = 1;
- XResizeWindow(ob_display, self->label, self->label_width,
- theme_label_height);
-
- if (!n) XUnmapWindow(ob_display, self->icon);
- if (!d) XUnmapWindow(ob_display, self->desk);
- if (!s) XUnmapWindow(ob_display, self->shade);
- if (!i) XUnmapWindow(ob_display, self->iconify);
- if (!l) XUnmapWindow(ob_display, self->label);
- if (!m) XUnmapWindow(ob_display, self->max);
- if (!c) XUnmapWindow(ob_display, self->close);
-
- x = theme_bevel + 1;
- for (lc = theme_title_layout; *lc != '\0'; ++lc) {
+ if (!n) RrSurfaceHide(self->s_icon);
+ if (!d) RrSurfaceHide(self->s_desk);
+ if (!s) RrSurfaceHide(self->s_shade);
+ if (!i) RrSurfaceHide(self->s_iconify);
+ if (!l) RrSurfaceHide(self->s_label);
+ if (!m) RrSurfaceHide(self->s_max);
+ if (!c) RrSurfaceHide(self->s_close);
+
+
+ x = ob_theme->bevel + 1;
+ for (lc = ob_theme->title_layout; *lc != '\0'; ++lc) {
switch (*lc) {
case 'N':
if (!n) break;
self->icon_x = x;
- RECT_SET(self->a_icon->area, 0, 0,
- theme_button_size + 2, theme_button_size + 2);
- XMapWindow(ob_display, self->icon);
- XMoveWindow(ob_display, self->icon, x, theme_bevel);
- x += theme_button_size + 2 + theme_bevel + 1;
+ RrSurfaceSetArea(self->s_icon, x, ob_theme->bevel,
+ RrThemeButtonSize(ob_theme) + 2,
+ RrThemeButtonSize(ob_theme) + 2);
+ RrSurfaceShow(self->s_icon);
+ x += RrThemeButtonSize(ob_theme) + 2 + ob_theme->bevel + 1;
break;
case 'D':
if (!d) break;
self->desk_x = x;
- XMapWindow(ob_display, self->desk);
- XMoveWindow(ob_display, self->desk, x, theme_bevel + 1);
- x += theme_button_size + theme_bevel + 1;
+ RrSurfaceSetArea(self->s_desk, x, ob_theme->bevel + 1,
+ RrThemeButtonSize(ob_theme),
+ RrThemeButtonSize(ob_theme));
+ RrSurfaceShow(self->s_desk);
+ x += RrThemeButtonSize(ob_theme) + ob_theme->bevel + 1;
break;
case 'S':
if (!s) break;
self->shade_x = x;
- XMapWindow(ob_display, self->shade);
- XMoveWindow(ob_display, self->shade, x, theme_bevel + 1);
- x += theme_button_size + theme_bevel + 1;
+ RrSurfaceSetArea(self->s_shade, x, ob_theme->bevel + 1,
+ RrThemeButtonSize(ob_theme),
+ RrThemeButtonSize(ob_theme));
+ RrSurfaceShow(self->s_shade);
+ x += RrThemeButtonSize(ob_theme) + ob_theme->bevel + 1;
break;
case 'I':
if (!i) break;
self->iconify_x = x;
- XMapWindow(ob_display, self->iconify);
- XMoveWindow(ob_display, self->iconify, x, theme_bevel + 1);
- x += theme_button_size + theme_bevel + 1;
+ RrSurfaceSetArea(self->s_iconify, x, ob_theme->bevel + 1,
+ RrThemeButtonSize(ob_theme),
+ RrThemeButtonSize(ob_theme));
+ RrSurfaceShow(self->s_iconify);
+ x += RrThemeButtonSize(ob_theme) + ob_theme->bevel + 1;
break;
case 'L':
if (!l) break;
self->label_x = x;
- XMapWindow(ob_display, self->label);
- XMoveWindow(ob_display, self->label, x, theme_bevel);
- x += self->label_width + theme_bevel + 1;
+ RrSurfaceSetArea(self->s_label, x, ob_theme->bevel,
+ self->label_width, RrThemeLabelHeight(ob_theme));
+ RrSurfaceShow(self->s_label);
+ x += self->label_width + ob_theme->bevel + 1;
break;
case 'M':
if (!m) break;
self->max_x = x;
- XMapWindow(ob_display, self->max);
- XMoveWindow(ob_display, self->max, x, theme_bevel + 1);
- x += theme_button_size + theme_bevel + 1;
+ RrSurfaceSetArea(self->s_max, x, ob_theme->bevel + 1,
+ RrThemeButtonSize(ob_theme),
+ RrThemeButtonSize(ob_theme));
+ RrSurfaceShow(self->s_max);
+ x += RrThemeButtonSize(ob_theme) + ob_theme->bevel + 1;
break;
case 'C':
if (!c) break;
self->close_x = x;
- XMapWindow(ob_display, self->close);
- XMoveWindow(ob_display, self->close, x, theme_bevel + 1);
- x += theme_button_size + theme_bevel + 1;
+ RrSurfaceSetArea(self->s_close, x, ob_theme->bevel + 1,
+ RrThemeButtonSize(ob_theme),
+ RrThemeButtonSize(ob_theme));
+ RrSurfaceShow(self->s_close);
+ x += RrThemeButtonSize(ob_theme) + ob_theme->bevel + 1;
break;
}
}
-
- RECT_SET(self->a_focused_label->area, 0, 0,
- self->label_width, theme_label_height);
- RECT_SET(self->a_unfocused_label->area, 0, 0,
- self->label_width, theme_label_height);
}
Context frame_context_from_string(char *name)
if (win == client->window) return Context_Client;
self = client->frame;
- if (win == self->window) return Context_Frame;
- if (win == self->plate) return Context_Client;
- if (win == self->title) return Context_Titlebar;
- if (win == self->label) return Context_Titlebar;
- if (win == self->handle) return Context_Handle;
- if (win == self->lgrip) return Context_BLCorner;
- if (win == self->rgrip) return Context_BRCorner;
- if (win == self->max) return Context_Maximize;
- if (win == self->iconify)return Context_Iconify;
- if (win == self->close) return Context_Close;
- if (win == self->icon) return Context_Icon;
- if (win == self->desk) return Context_AllDesktops;
- if (win == self->shade) return Context_Shade;
+ if (win == self->window) return Context_Frame;
+ if (win == self->plate) return Context_Client;
+ if (win == self->w_title) return Context_Titlebar;
+ if (win == self->w_label) return Context_Titlebar;
+ if (win == self->w_handle) return Context_Handle;
+ if (win == self->w_lgrip) return Context_BLCorner;
+ if (win == self->w_rgrip) return Context_BRCorner;
+ if (win == self->w_max) return Context_Maximize;
+ if (win == self->w_iconify)return Context_Iconify;
+ if (win == self->w_close) return Context_Close;
+ if (win == self->w_icon) return Context_Icon;
+ if (win == self->w_desk) return Context_AllDesktops;
+ if (win == self->w_shade) return Context_Shade;
return Context_None;
}
#include "geom.h"
#include "client.h"
-#include "render/render.h"
+#include "render2/render.h"
typedef enum {
Context_None,
NUM_CONTEXTS
} Context;
-#define FRAME_HANDLE_Y(f) (f->innersize.top + f->client->area.height + \
+#define FRAME_HANDLE_Y(f) (f->size.top + f->client->area.height + \
f->cbwidth)
typedef struct Frame {
Rect area;
gboolean visible;
- Window title;
- Window label;
- Window max;
- Window close;
- Window desk;
- Window shade;
- Window icon;
- Window iconify;
- Window handle;
- Window lgrip;
- Window rgrip;
-
- Appearance *a_unfocused_title;
- Appearance *a_focused_title;
- Appearance *a_unfocused_label;
- Appearance *a_focused_label;
- Appearance *a_icon;
- Appearance *a_unfocused_handle;
- Appearance *a_focused_handle;
-
- Strut innersize;
+ struct RrSurface *s_frame;
+ struct RrSurface *s_title;
+ struct RrSurface *s_label;
+ struct RrSurface *s_max;
+ struct RrSurface *s_close;
+ struct RrSurface *s_desk;
+ struct RrSurface *s_shade;
+ struct RrSurface *s_iconify;
+ struct RrSurface *s_icon;
+ struct RrSurface *s_handle;
+ struct RrSurface *s_lgrip;
+ struct RrSurface *s_rgrip;
+
+ Window w_title;
+ Window w_label;
+ Window w_max;
+ Window w_close;
+ Window w_desk;
+ Window w_shade;
+ Window w_iconify;
+ Window w_icon;
+ Window w_handle;
+ Window w_lgrip;
+ Window w_rgrip;
GSList *clients;
#include "openbox.h"
#include "screen.h"
#include "framerender.h"
-#include "render/theme.h"
-
-static void framerender_label(Frame *self, Appearance *a);
-static void framerender_icon(Frame *self, Appearance *a);
-static void framerender_max(Frame *self, Appearance *a);
-static void framerender_iconify(Frame *self, Appearance *a);
-static void framerender_desk(Frame *self, Appearance *a);
-static void framerender_shade(Frame *self, Appearance *a);
-static void framerender_close(Frame *self, Appearance *a);
+#include "render2/theme.h"
void framerender_frame(Frame *self)
{
- if (self->focused)
- XSetWindowBorder(ob_display, self->plate,
- theme_cb_focused_color->pixel);
- else
- XSetWindowBorder(ob_display, self->plate,
- theme_cb_unfocused_color->pixel);
+ /* XXX plate, client border */
if (self->client->decorations & Decor_Titlebar) {
- Appearance *t, *l, *m, *n, *i, *d, *s, *c;
+ struct RrSurface *t, *l, *m, *n, *i, *d, *s, *c;
t = (self->focused ?
- self->a_focused_title : self->a_unfocused_title);
+ ob_theme->title_f : ob_theme->title);
l = (self->focused ?
- self->a_focused_label : self->a_unfocused_label);
+ ob_theme->label_f : ob_theme->label);
m = (self->focused ?
(self->client->max_vert || self->client->max_horz ?
- theme_a_focused_pressed_set_max :
- (self->max_press ?
- theme_a_focused_pressed_max : theme_a_focused_unpressed_max)) :
+ ob_theme->max_p_f : (self->max_press ?
+ ob_theme->max_p_f : ob_theme->max_f)) :
(self->client->max_vert || self->client->max_horz ?
- theme_a_unfocused_pressed_set_max :
- (self->max_press ?
- theme_a_unfocused_pressed_max :
- theme_a_unfocused_unpressed_max)));
- n = self->a_icon;
+ ob_theme->max_p : (self->max_press ?
+ ob_theme->max_p : ob_theme->max)));
+ n = ob_theme->icon;
i = (self->focused ?
(self->iconify_press ?
- theme_a_focused_pressed_iconify :
- theme_a_focused_unpressed_iconify) :
+ ob_theme->iconify_p_f : ob_theme->iconify_f) :
(self->iconify_press ?
- theme_a_unfocused_pressed_iconify :
- theme_a_unfocused_unpressed_iconify));
+ ob_theme->iconify_p : ob_theme->iconify));
d = (self->focused ?
(self->client->desktop == DESKTOP_ALL ?
- theme_a_focused_pressed_set_desk :
- (self->desk_press ?
- theme_a_focused_pressed_desk :
- theme_a_focused_unpressed_desk)) :
+ ob_theme->desk_p_f : (self->desk_press ?
+ ob_theme->desk_p_f : ob_theme->desk_f)) :
(self->client->desktop == DESKTOP_ALL ?
- theme_a_unfocused_pressed_set_desk :
- (self->desk_press ?
- theme_a_unfocused_pressed_desk :
- theme_a_unfocused_unpressed_desk)));
+ ob_theme->desk_p : (self->desk_press ?
+ ob_theme->desk_p : ob_theme->desk)));
s = (self->focused ?
(self->client->shaded ?
- theme_a_focused_pressed_set_shade :
- (self->shade_press ?
- theme_a_focused_pressed_shade :
- theme_a_focused_unpressed_shade)) :
+ ob_theme->shade_p_f : (self->shade_press ?
+ ob_theme->shade_p_f : ob_theme->shade_f)):
(self->client->shaded ?
- theme_a_unfocused_pressed_set_shade :
- (self->shade_press ?
- theme_a_unfocused_pressed_shade :
- theme_a_unfocused_unpressed_shade)));
+ ob_theme->shade_p : (self->shade_press ?
+ ob_theme->shade_p : ob_theme->shade)));
c = (self->focused ?
(self->close_press ?
- theme_a_focused_pressed_close :
- theme_a_focused_unpressed_close) :
+ ob_theme->close_p_f : ob_theme->close_f) :
(self->close_press ?
- theme_a_unfocused_pressed_close :
- theme_a_unfocused_unpressed_close));
-
- paint(self->title, t);
-
- /* set parents for any parent relative guys */
- l->surface.data.planar.parent = t;
- l->surface.data.planar.parentx = self->label_x;
- l->surface.data.planar.parenty = theme_bevel;
-
- m->surface.data.planar.parent = t;
- m->surface.data.planar.parentx = self->max_x;
- m->surface.data.planar.parenty = theme_bevel + 1;
-
- n->surface.data.planar.parent = t;
- n->surface.data.planar.parentx = self->icon_x;
- n->surface.data.planar.parenty = theme_bevel;
-
- i->surface.data.planar.parent = t;
- i->surface.data.planar.parentx = self->iconify_x;
- i->surface.data.planar.parenty = theme_bevel + 1;
-
- d->surface.data.planar.parent = t;
- d->surface.data.planar.parentx = self->desk_x;
- d->surface.data.planar.parenty = theme_bevel + 1;
-
- s->surface.data.planar.parent = t;
- s->surface.data.planar.parentx = self->shade_x;
- s->surface.data.planar.parenty = theme_bevel + 1;
-
- c->surface.data.planar.parent = t;
- c->surface.data.planar.parentx = self->close_x;
- c->surface.data.planar.parenty = theme_bevel + 1;
-
- framerender_label(self, l);
- framerender_max(self, m);
- framerender_icon(self, n);
- framerender_iconify(self, i);
- framerender_desk(self, d);
- framerender_shade(self, s);
- framerender_close(self, c);
+ ob_theme->close_p : ob_theme->close));
+
+ RrSurfaceCopy(self->s_title, t);
+ RrSurfaceCopy(self->s_label, l);
+
+ RrTextureSetText(self->s_label, 0, ob_theme->title_font,
+ ob_theme->title_justify,
+ (self->focused ?
+ &ob_theme->title_color_f : &ob_theme->title_color),
+ self->client->title);
+
+ if (self->icon_x >= 0) {
+ Icon *icon;
+
+ RrSurfaceCopy(self->s_icon, n);
+
+ icon = client_icon(self->client,
+ RrThemeButtonSize(ob_theme) + 2,
+ RrThemeButtonSize(ob_theme) + 2);
+ if (icon)
+ RrTextureSetRGBA(self->s_icon, 0,
+ icon->data,
+ 0, 0, icon->width, icon->height);
+ else
+ RrTextureSetNone(self->s_icon, 0);
+ }
+ if (self->iconify_x >= 0)
+ RrSurfaceCopy(self->s_iconify, i);
+ if (self->desk_x >= 0)
+ RrSurfaceCopy(self->s_desk, d);
+ if (self->shade_x >= 0)
+ RrSurfaceCopy(self->s_shade, s);
+ if (self->close_x >= 0)
+ RrSurfaceCopy(self->s_close, c);
}
if (self->client->decorations & Decor_Handle) {
- Appearance *h, *g;
+ struct RrSurface *h, *g;
h = (self->focused ?
- self->a_focused_handle : self->a_unfocused_handle);
+ ob_theme->handle_f : ob_theme->handle);
g = (self->focused ?
- theme_a_focused_grip : theme_a_unfocused_grip);
-
- if (g->surface.data.planar.grad == Background_ParentRelative) {
- g->surface.data.planar.parent = h;
- paint(self->handle, h);
- } else
- paint(self->handle, h);
-
- g->surface.data.planar.parentx = 0;
- g->surface.data.planar.parenty = 0;
+ ob_theme->grip_f : ob_theme->grip);
- paint(self->lgrip, g);
-
- g->surface.data.planar.parentx = self->width - theme_grip_width;
- g->surface.data.planar.parenty = 0;
-
- paint(self->rgrip, g);
+ RrSurfaceCopy(self->s_handle, h);
+ RrSurfaceCopy(self->s_lgrip, g);
+ RrSurfaceCopy(self->s_rgrip, g);
}
-}
-
-static void framerender_label(Frame *self, Appearance *a)
-{
- if (self->label_x < 0) return;
-
-
- /* set the texture's text! */
- a->texture[0].data.text.string = self->client->title;
- RECT_SET(a->texture[0].position, 0, 0,
- self->label_width, theme_label_height);
-
- paint(self->label, a);
-}
-
-static void framerender_icon(Frame *self, Appearance *a)
-{
- if (self->icon_x < 0) return;
-
- if (self->client->nicons) {
- Icon *icon = client_icon(self->client,
- theme_button_size + 2, theme_button_size + 2);
- a->texture[0].type = RGBA;
- a->texture[0].data.rgba.width = icon->width;
- a->texture[0].data.rgba.height = icon->height;
- a->texture[0].data.rgba.data = icon->data;
- RECT_SET(self->a_icon->texture[0].position, 0, 0,
- theme_button_size + 2, theme_button_size + 2);
- } else
- a->texture[0].type = NoTexture;
-
- paint(self->icon, a);
-}
-
-static void framerender_max(Frame *self, Appearance *a)
-{
- if (self->max_x < 0) return;
-
- RECT_SET(a->texture[0].position, 0, 0,
- theme_button_size, theme_button_size);
- paint(self->max, a);
-}
-
-static void framerender_iconify(Frame *self, Appearance *a)
-{
- if (self->iconify_x < 0) return;
-
- RECT_SET(a->texture[0].position, 0, 0,
- theme_button_size, theme_button_size);
- paint(self->iconify, a);
-}
-
-static void framerender_desk(Frame *self, Appearance *a)
-{
- if (self->desk_x < 0) return;
-
- RECT_SET(a->texture[0].position, 0, 0,
- theme_button_size, theme_button_size);
- paint(self->desk, a);
-}
-
-static void framerender_shade(Frame *self, Appearance *a)
-{
- if (self->shade_x < 0) return;
-
- RECT_SET(a->texture[0].position, 0, 0,
- theme_button_size, theme_button_size);
- paint(self->shade, a);
-}
-
-static void framerender_close(Frame *self, Appearance *a)
-{
- if (self->close_x < 0) return;
-
- RECT_SET(a->texture[0].position, 0, 0,
- theme_button_size, theme_button_size);
- paint(self->close, a);
+ /* XXX this could be more efficient */
+ RrPaint(self->s_frame);
}
#include "openbox.h"
#include "stacking.h"
#include "grab.h"
-#include "render/theme.h"
#include "screen.h"
#include "geom.h"
#include "plugin.h"
+#include "render2/theme.h"
GHashTable *menu_hash = NULL;
-#define FRAME_EVENTMASK (ButtonPressMask |ButtonMotionMask | EnterWindowMask | \
- LeaveWindowMask)
-#define TITLE_EVENTMASK (ButtonPressMask | ButtonMotionMask)
+#define FRAME_EVENTMASK (ButtonPressMask |ButtonMotionMask | EnterWindowMask |\
+ LeaveWindowMask | ExposureMask)
+#define TITLE_EVENTMASK (ButtonPressMask | ButtonMotionMask | ExposureMask)
#define ENTRY_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
- ButtonPressMask | ButtonReleaseMask)
+ ButtonPressMask | ButtonReleaseMask | ExposureMask)
void menu_control_show(Menu *self, int x, int y, Client *client);
g_free(self->label);
g_free(self->name);
- g_hash_table_remove(window_map, &self->title);
- g_hash_table_remove(window_map, &self->frame);
- g_hash_table_remove(window_map, &self->items);
+ g_hash_table_remove(window_map, &self->w_title);
+ g_hash_table_remove(window_map, &self->w_frame);
+ g_hash_table_remove(window_map, &self->w_items);
stacking_remove(self);
- appearance_free(self->a_title);
- XDestroyWindow(ob_display, self->title);
- XDestroyWindow(ob_display, self->frame);
- XDestroyWindow(ob_display, self->items);
+ RrSurfaceFree(self->s_items);
+ RrSurfaceFree(self->s_title);
+ RrSurfaceFree(self->s_frame);
+ XDestroyWindow(ob_display, self->w_frame);
g_free(self);
}
g_free(self->label);
action_free(self->action);
- g_hash_table_remove(window_map, &self->item);
+ g_hash_table_remove(window_map, &self->w_item);
+ g_hash_table_remove(window_map, &self->w_text);
- appearance_free(self->a_item);
- appearance_free(self->a_disabled);
- appearance_free(self->a_hilite);
- XDestroyWindow(ob_display, self->item);
+ RrSurfaceFree(self->s_item);
g_free(self);
}
XSetWindowAttributes *attrib)
{
return XCreateWindow(ob_display, parent, 0, 0, 1, 1, 0,
- render_depth, InputOutput, render_visual,
- mask, attrib);
+ RrInstanceDepth(ob_render_inst), InputOutput,
+ RrInstanceVisual(ob_render_inst), mask, attrib);
}
attrib.override_redirect = TRUE;
attrib.event_mask = FRAME_EVENTMASK;
- self->frame = createWindow(ob_root, CWOverrideRedirect|CWEventMask, &attrib);
- attrib.event_mask = TITLE_EVENTMASK;
- self->title = createWindow(self->frame, CWEventMask, &attrib);
- self->items = createWindow(self->frame, 0, &attrib);
-
- XSetWindowBorderWidth(ob_display, self->frame, theme_bwidth);
- XSetWindowBackground(ob_display, self->frame, theme_b_color->pixel);
- XSetWindowBorderWidth(ob_display, self->title, theme_bwidth);
- XSetWindowBorder(ob_display, self->frame, theme_b_color->pixel);
- XSetWindowBorder(ob_display, self->title, theme_b_color->pixel);
-
- XMapWindow(ob_display, self->title);
- XMapWindow(ob_display, self->items);
-
- self->a_title = appearance_copy(theme_a_menu_title);
- self->a_items = appearance_copy(theme_a_menu);
-
- g_hash_table_insert(window_map, &self->frame, self);
- g_hash_table_insert(window_map, &self->title, self);
- g_hash_table_insert(window_map, &self->items, self);
+ self->w_frame = createWindow(ob_root,
+ CWOverrideRedirect|CWEventMask, &attrib);
+ self->s_frame = RrSurfaceNew(ob_render_inst, 0, self->w_frame, 0);
+
+ self->s_title = RrSurfaceNewChild(0, self->s_frame, 0);
+ self->w_title = RrSurfaceWindow(self->s_title);
+ XSelectInput(ob_display, self->w_title, TITLE_EVENTMASK);
+
+ self->s_items = RrSurfaceNewChild(0, self->s_frame, 0);
+ self->w_items = RrSurfaceWindow(self->s_items);
+
+ RrSurfaceShow(self->s_items);
+
+ g_hash_table_insert(window_map, &self->w_frame, self);
+ g_hash_table_insert(window_map, &self->w_title, self);
+ g_hash_table_insert(window_map, &self->w_items, self);
g_hash_table_insert(menu_hash, g_strdup(name), self);
stacking_add(MENU_AS_WINDOW(self));
void menu_add_entry(Menu *menu, MenuEntry *entry)
{
- XSetWindowAttributes attrib;
+ struct RrColor c;
g_assert(menu != NULL);
g_assert(entry != NULL);
- g_assert(entry->item == None);
+ g_assert(entry->w_item == None);
menu->entries = g_list_append(menu->entries, entry);
entry->parent = menu;
- attrib.event_mask = ENTRY_EVENTMASK;
- entry->item = createWindow(menu->items, CWEventMask, &attrib);
- XMapWindow(ob_display, entry->item);
- entry->a_item = appearance_copy(theme_a_menu_item);
- entry->a_disabled = appearance_copy(theme_a_menu_disabled);
- entry->a_hilite = appearance_copy(theme_a_menu_hilite);
+ entry->s_item = RrSurfaceNewChild(0, menu->s_items, 0);
+ entry->w_item = RrSurfaceWindow(entry->s_item);
+ XSelectInput(ob_display, entry->w_item, ENTRY_EVENTMASK);
+
+ entry->s_text = RrSurfaceNewChild(RR_SURFACE_PLANAR, entry->s_item, 1);
+ entry->w_text = RrSurfaceWindow(entry->s_text);
+ XSelectInput(ob_display, entry->w_text, ENTRY_EVENTMASK);
+ RrColorSet(&c, 0, 0, 0, 0); /* clear */
+ RrPlanarSet(entry->s_text, RR_PLANAR_SOLID, RR_BEVEL_NONE, &c, NULL,
+ 0, NULL);
+
+ RrSurfaceShow(entry->s_item);
+ RrSurfaceShow(entry->s_text);
menu->invalid = TRUE;
- g_hash_table_insert(window_map, &entry->item, menu);
+ g_hash_table_insert(window_map, &entry->w_item, menu);
+ g_hash_table_insert(window_map, &entry->w_text, menu);
}
void menu_show(char *name, int x, int y, Client *client)
void menu_hide(Menu *self) {
if (self->shown) {
- XUnmapWindow(ob_display, self->frame);
+ RrSurfaceHide(self->s_frame);
self->shown = FALSE;
if (self->open_submenu)
menu_hide(self->open_submenu);
for (it = menu->entries; it; it = it->next) {
MenuEntry *entry = it->data;
- if (entry->item == win)
+ if (entry->w_item == win || entry->w_text == win)
return entry;
}
return NULL;
void menu_control_show(Menu *self, int x, int y, Client *client) {
g_assert(!self->invalid);
-
- XMoveWindow(ob_display, self->frame,
- MIN(x, screen_physical_size.width - self->size.width),
- MIN(y, screen_physical_size.height - self->size.height));
+
POINT_SET(self->location,
MIN(x, screen_physical_size.width - self->size.width),
MIN(y, screen_physical_size.height - self->size.height));
+ self->invalid = TRUE;
+ menu_render(self);
if (!self->shown) {
- XMapWindow(ob_display, self->frame);
+ RrSurfaceShow(self->s_frame);
stacking_raise(MENU_AS_WINDOW(self));
self->shown = TRUE;
} else if (self->shown && self->open_submenu) {
/* TODO: I don't understand why these bevels should be here.
Something must be wrong in the width calculation */
x = self->parent->location.x + self->parent->size.width +
- theme_bevel;
+ ob_theme->bevel;
/* need to get the width. is this bad?*/
menu_render(self->submenu);
if (self->submenu->size.width + x > screen_physical_size.width)
x = self->parent->location.x - self->submenu->size.width -
- theme_bevel;
+ ob_theme->bevel;
menu_show_full(self->submenu, x,
self->parent->location.y + self->y,
#define __menu_h
#include "action.h"
-#include "render/render.h"
+#include "render2/render.h"
#include "geom.h"
#include <glib.h>
/* render stuff */
Client *client;
- Window frame;
- Window title;
- Appearance *a_title;
+ struct RrSurface *s_frame;
+ struct RrSurface *s_title;
+ struct RrSurface *s_items;
+ Window w_frame;
+ Window w_title;
+ Window w_items;
int title_min_w, title_h;
- Window items;
- Appearance *a_items;
int bullet_w;
int item_h;
Point location;
Menu *submenu;
/* render stuff */
- Window item;
- Appearance *a_item;
- Appearance *a_disabled;
- Appearance *a_hilite;
+ struct RrSurface *s_item;
+ struct RrSurface *s_text;
+ Window w_item;
+ Window w_text;
int y;
int min_w;
} MenuEntry;
#include "menu.h"
#include "openbox.h"
-#include "render/theme.h"
+#include "render2/theme.h"
void menu_render_full(Menu *self);
/* set texture data and size them mofos out */
if (self->label) {
- self->a_title->texture[0].data.text.string = self->label;
- appearance_minsize(self->a_title, &self->title_min_w, &self->title_h);
- self->title_min_w += theme_bevel * 2;
- self->title_h += theme_bevel * 2;
+ RrSurfaceCopy(self->s_title, ob_theme->menu_title);
+ RrTextureSetText(self->s_title, 0, ob_theme->title_font,
+ ob_theme->title_justify, &ob_theme->title_color_f,
+ self->label);
+ RrSurfaceMinSize(self->s_title, &self->title_min_w, &self->title_h);
+ self->title_min_w += (ob_theme->bevel + ob_theme->bwidth) * 2;
+ self->title_h += (ob_theme->bevel + ob_theme->bwidth) * 2;
self->size.width = MAX(self->size.width, self->title_min_w);
}
MenuEntry *e = it->data;
int h;
- e->a_item->texture[0].data.text.string = e->label;
- appearance_minsize(e->a_item, &e->min_w, &self->item_h);
+ RrTextureSetText(e->s_text, 0, ob_theme->title_font,
+ ob_theme->title_justify, &ob_theme->title_color_f,
+ e->label);
+
+ RrSurfaceCopy(e->s_item, ob_theme->menu_item);
+ RrSurfaceMinSize(e->s_item, &e->min_w, &self->item_h);
self->size.width = MAX(self->size.width, e->min_w);
- e->a_disabled->texture[0].data.text.string = e->label;
- appearance_minsize(e->a_disabled, &e->min_w, &h);
+ RrSurfaceCopy(e->s_item, ob_theme->menu_disabled);
+ RrSurfaceMinSize(e->s_item, &e->min_w, &h);
self->item_h = MAX(self->item_h, h);
self->size.width = MAX(self->size.width, e->min_w);
- e->a_hilite->texture[0].data.text.string = e->label;
- appearance_minsize(e->a_hilite, &e->min_w, &h);
+ RrSurfaceCopy(e->s_item, ob_theme->menu_hilite);
+ RrSurfaceMinSize(e->s_item, &e->min_w, &h);
self->item_h = MAX(self->item_h, h);
self->size.width = MAX(self->size.width, e->min_w);
-
- e->min_w += theme_bevel * 2;
+
+ e->min_w += ob_theme->bevel * 2;
++nitems;
}
- self->bullet_w = self->item_h + theme_bevel;
- self->size.width += 2 * self->bullet_w + 2 * theme_bevel;
- self->item_h += theme_bevel * 2;
+ self->bullet_w = self->item_h + ob_theme->bevel;
+ self->size.width += 2 * self->bullet_w + 2 * ob_theme->bevel;
+ self->item_h += ob_theme->bevel * 2;
items_h = self->item_h * MAX(nitems, 1);
- if (self->label) {
- RECT_SET(self->a_title->area, 0, 0, self->size.width,
- self->title_h);
- RECT_SET(self->a_title->texture[0].position, 0, 0, self->size.width,
- self->title_h);
- }
+ RrSurfaceSetArea(self->s_frame, self->location.x, self->location.y,
+ self->size.width, MAX(self->title_h + items_h, 1));
- RECT_SET(self->a_items->area, 0, 0, self->size.width, items_h);
-
- XResizeWindow(ob_display, self->frame, self->size.width,
- MAX(self->title_h + items_h, 1));
- if (self->label)
- XMoveResizeWindow(ob_display, self->title, -theme_bwidth,
- -theme_bwidth, self->size.width, self->title_h);
-
- XMoveResizeWindow(ob_display, self->items, 0,
- self->title_h + theme_bwidth, self->size.width,
- items_h);
+ if (self->label) {
+ RrSurfaceSetArea(self->s_title, 0, 0, self->size.width, self->title_h);
+ RrSurfaceShow(self->s_title);
+ } else
+ RrSurfaceHide(self->s_title);
- if (self->label)
- paint(self->title, self->a_title);
- paint(self->items, self->a_items);
+ RrSurfaceSetArea(self->s_items, 0, self->title_h + ob_theme->bwidth,
+ self->size.width, items_h);
item_y = 0;
for (it = self->entries; it; it = it->next) {
void menu_entry_render(MenuEntry *self)
{
Menu *menu = self->parent;
- Appearance *a;
+ struct RrSurface *s;
switch (self->render_type) {
case MenuEntryRenderType_Submenu:
/* TODO: submenu mask */
case MenuEntryRenderType_Boolean:
/* TODO: boolean check */
- a = self->enabled ? (self->hilite ? self->a_hilite : self->a_item)
- : self->a_disabled;
+ s = self->enabled ?
+ (self->hilite ? ob_theme->menu_hilite : ob_theme->menu_item) :
+ ob_theme->menu_disabled;
break;
case MenuEntryRenderType_None:
- a = self->enabled ? (self->hilite ? self->a_hilite : self->a_item )
- : self->a_disabled;
+ s = self->enabled ?
+ (self->hilite ? ob_theme->menu_hilite : ob_theme->menu_item) :
+ ob_theme->menu_disabled;
break;
case MenuEntryRenderType_Separator:
- a = self->a_item;
+ s = ob_theme->menu_item;
break;
default:
g_message("unhandled render_type");
- a = !self->enabled ? self->a_disabled :
- (self->hilite &&
- (self->action || self->render_type == MenuEntryRenderType_Submenu) ?
- self->a_hilite : self->a_item);
+ s = !self->enabled ? ob_theme->menu_disabled :
+ (self->hilite &&
+ (self->action ||
+ self->render_type == MenuEntryRenderType_Submenu) ?
+ ob_theme->menu_hilite : ob_theme->menu_item);
break;
}
- RECT_SET(a->area, 0, 0, menu->size.width,
- menu->item_h);
- RECT_SET(a->texture[0].position, menu->bullet_w,
- 0, menu->size.width - 2 * menu->bullet_w,
- menu->item_h);
-
- XMoveResizeWindow(ob_display, self->item, 0, self->y,
- menu->size.width, menu->item_h);
- a->surface.data.planar.parent = menu->a_items;
- a->surface.data.planar.parentx = 0;
- a->surface.data.planar.parenty = self->y;
+ RrSurfaceCopy(self->s_item, s);
- paint(self->item, a);
+ RrSurfaceSetArea(self->s_item, 0, self->y, menu->size.width, menu->item_h);
+ RrSurfaceSetArea(self->s_text, menu->bullet_w, 0,
+ menu->size.width - 2 * menu->bullet_w, menu->item_h);
}
#include "openbox.h"
#include "popup.h"
#include "config.h"
-#include "render/render.h"
-#include "render/theme.h"
+#include "render2/render.h"
+#include "render2/theme.h"
#include <X11/Xlib.h>
#include <glib.h>
attrib.save_under = True;
opaque_window.win = XCreateWindow(ob_display, ob_root, 0, 0, 1, 1, 0,
- render_depth, InputOutput, render_visual,
+ RrInstanceDepth(ob_render_inst),
+ InputOutput,
+ RrInstanceVisual(ob_render_inst),
CWSaveUnder, &attrib);
stacking_add(INTERNAL_AS_WINDOW(&opaque_window));
stacking_raise(INTERNAL_AS_WINDOW(&opaque_window));
/* a GC to invert stuff */
gcv.function = GXxor;
- gcv.line_width = theme_bwidth;
+ gcv.line_width = ob_theme->bwidth;
gcv.foreground = (WhitePixel(ob_display, ob_screen) ^
BlackPixel(ob_display, ob_screen));
opaque_gc = XCreateGC(ob_display, opaque_window.win,
#include "config.h"
#include "gettext.h"
#include "parser/parse.h"
-#include "render/render.h"
-#include "render/font.h"
-#include "render/theme.h"
+#include "render2/render.h"
+#include "render2/theme.h"
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#include <X11/cursorfont.h>
+struct RrInstance *ob_render_inst;
+struct RrTheme *ob_theme;
+
Display *ob_display = NULL;
int ob_screen;
Window ob_root;
struct sigaction action;
sigset_t sigset;
char *path;
- char *theme;
xmlDocPtr doc;
xmlNodePtr node;
/* set our error handler */
XSetErrorHandler(xerror_handler);
+ ob_render_inst = RrInstanceNew(ob_display, ob_screen);
+ if (!ob_render_inst) {
+ g_critical("Unable to initialize GL rendering subsystem.");
+ exit(1);
+ }
+
/* set the DISPLAY environment variable for any lauched children, to the
display we're using, so they open in the right place. */
putenv(g_strdup_printf("DISPLAY=%s", DisplayString(ob_display)));
/* anything that is going to read data from the rc file needs to be
in this group */
timer_startup();
- render_startup();
- font_startup();
- theme_startup();
event_startup();
grab_startup();
plugin_startup();
parse_shutdown();
/* load the theme specified in the rc file */
- theme = theme_load(config_theme);
- g_free(theme);
- if (!theme) return 1;
+ ob_theme = RrThemeLoad(ob_render_inst, config_theme);
+ if (!ob_theme) {
+ g_critical("Unable to load a theme.");
+ exit(1);
+ }
window_startup();
menu_startup();
window_shutdown();
grab_shutdown();
event_shutdown();
- theme_shutdown();
- render_shutdown();
timer_shutdown();
config_shutdown();
}
+ RrInstanceFree(ob_render_inst);
+
dispatch_shutdown();
XCloseDisplay(ob_display);
/*! The X display */
extern Display *ob_display;
+struct RrInstance;
+extern struct RrInstance *ob_render_inst;
+struct RrTheme;
+extern struct RrTheme *ob_theme;
+
#ifdef USE_LIBSN
SnDisplay *ob_sn_display;
#endif
#include "frame.h"
#include "window.h"
#include "stacking.h"
-#include "render/render.h"
-#include "render/theme.h"
+#include "render2/render.h"
+#include "render2/theme.h"
typedef struct Popup {
ObWindow obwin;
Window text;
gboolean hasicon;
- Appearance *a_bg;
- Appearance *a_icon;
- Appearance *a_text;
+ struct RrSurface *s_bg;
+ struct RrSurface *s_icon;
+ struct RrSurface *s_text;
int gravity;
int x;
int y;
int w;
int h;
- gboolean mapped;
} Popup;
Popup *popup_new(gboolean hasicon)
{
- Popup *self = g_new(Popup, 1);
+ XSetWindowAttributes attrib;
+ Popup *self;
+
+ self = g_new(Popup, 1);
self->obwin.type = Window_Internal;
self->hasicon = hasicon;
- self->bg = None;
- self->a_text = NULL;
self->gravity = NorthWestGravity;
self->x = self->y = self->w = self->h = 0;
- self->mapped = FALSE;
stacking_add(INTERNAL_AS_WINDOW(self));
stacking_raise(INTERNAL_AS_WINDOW(self));
+
+ attrib.override_redirect = True;
+ attrib.event_mask = ExposureMask;
+ self->bg = XCreateWindow(ob_display, ob_root,
+ 0, 0, 1, 1, 0, RrInstanceDepth(ob_render_inst),
+ InputOutput, RrInstanceVisual(ob_render_inst),
+ CWEventMask|CWOverrideRedirect, &attrib);
+ self->s_bg = RrSurfaceNew(ob_render_inst, 0, self->bg, 0);
+ RrSurfaceCopy(self->s_bg, ob_theme->app_bg_h);
+
+ self->s_text = RrSurfaceNewChild(0, self->s_bg, 1);
+ RrSurfaceCopy(self->s_text, ob_theme->app_label_h);
+
+ self->text = RrSurfaceWindow(self->s_text);
+
+ if (self->hasicon) {
+ self->s_icon = RrSurfaceNewChild(RR_SURFACE_PLANAR, self->s_bg, 1);
+ RrSurfaceCopy(self->s_icon, ob_theme->app_icon);
+
+ self->icon = RrSurfaceWindow(self->s_icon);
+ } else {
+ self->s_icon = NULL;
+ self->icon = None;
+ }
+
return self;
}
void popup_free(Popup *self)
{
- if (self->bg) {
- XDestroyWindow(ob_display, self->bg);
- XDestroyWindow(ob_display, self->text);
- XDestroyWindow(ob_display, self->icon);
- appearance_free(self->a_bg);
- if (self->hasicon)
- appearance_free(self->a_icon);
- }
- if (self->a_text)
- appearance_free(self->a_text);
+ RrSurfaceFree(self->s_icon);
+ RrSurfaceFree(self->s_text);
+ RrSurfaceFree(self->s_bg);
+ XDestroyWindow(ob_display, self->bg);
stacking_remove(self);
g_free(self);
}
{
int textw, texth;
int iconw;
+ struct RrColor c;
- if (!self->a_text)
- self->a_text = appearance_copy(theme_app_hilite_label);
-
- self->a_text->texture[0].data.text.string = text;
- appearance_minsize(self->a_text, &textw, &texth);
- textw += theme_bevel * 2;
- texth += theme_bevel * 2;
+ RrColorSet(&c, 0, 0, 0, 1.0);
+ RrTextureSetText(self->s_text, 0, NULL, RR_LEFT, &c, text);
+ RrSurfaceMinSize(self->s_text, &textw, &texth);
+ textw += ob_theme->bevel * 2;
+ texth += ob_theme->bevel * 2;
- self->h = texth + theme_bevel * 2;
- iconw = (self->hasicon ? texth : 0);
- self->w = textw + iconw + theme_bevel * (self->hasicon ? 3 : 2);
+ self->h = texth + ob_theme->bevel * 2 + ob_theme->bwidth * 2;
+ iconw = (self->hasicon ? texth + ob_theme->bevel : 0);
+ self->w = textw + iconw + ob_theme->bevel * 2 + ob_theme->bwidth * 2;
}
void popup_show(Popup *self, char *text, Icon *icon)
{
- XSetWindowAttributes attrib;
int x, y, w, h;
int textw, texth;
int iconw;
-
- /* create the shit if needed */
- if (!self->bg) {
- attrib.override_redirect = True;
- self->bg = XCreateWindow(ob_display, ob_root,
- 0, 0, 1, 1, 0, render_depth, InputOutput,
- render_visual, CWOverrideRedirect, &attrib);
-
- XSetWindowBorderWidth(ob_display, self->bg, theme_bwidth);
- XSetWindowBorder(ob_display, self->bg, theme_b_color->pixel);
-
- self->text = XCreateWindow(ob_display, self->bg,
- 0, 0, 1, 1, 0, render_depth, InputOutput,
- render_visual, 0, NULL);
- if (self->hasicon)
- self->icon = XCreateWindow(ob_display, self->bg,
- 0, 0, 1, 1, 0,
- render_depth, InputOutput,
- render_visual, 0, NULL);
-
- XMapWindow(ob_display, self->text);
- XMapWindow(ob_display, self->icon);
-
- self->a_bg = appearance_copy(theme_app_hilite_bg);
- if (self->hasicon)
- self->a_icon = appearance_copy(theme_app_icon);
- }
- if (!self->a_text)
- self->a_text = appearance_copy(theme_app_hilite_label);
+ struct RrColor c;
+ struct RrFont *font;
/* set up the textures */
- self->a_text->texture[0].data.text.string = text;
- if (self->hasicon) {
- if (icon) {
- self->a_icon->texture[0].type = RGBA;
- self->a_icon->texture[0].data.rgba.width = icon->width;
- self->a_icon->texture[0].data.rgba.height = icon->height;
- self->a_icon->texture[0].data.rgba.data = icon->data;
- } else
- self->a_icon->texture[0].type = NoTexture;
- }
+ RrColorSet(&c, 0, 0, 0, 1.0);
+ font = RrFontOpen(ob_render_inst, "arial-10:bold"); /* XXX mem leak! */
+ RrTextureSetText(self->s_text, 0, font, RR_LEFT, &c, text);
/* measure the shit out */
- appearance_minsize(self->a_text, &textw, &texth);
- textw += theme_bevel * 2;
- texth += theme_bevel * 2;
+ RrSurfaceMinSize(self->s_text, &textw, &texth);
+ textw += ob_theme->bevel * 2;
+ texth += ob_theme->bevel * 2;
/* set the sizes up and reget the text sizes from the calculated
outer sizes */
if (self->h) {
h = self->h;
- texth = h - (theme_bevel * 2);
+ texth = h - (ob_theme->bevel * 2) - ob_theme->bwidth * 2;
} else
- h = texth + theme_bevel * 2;
+ h = texth + ob_theme->bevel * 2 + ob_theme->bwidth * 2;
iconw = (self->hasicon ? texth : 0);
if (self->w) {
w = self->w;
- textw = w - (iconw + theme_bevel * (self->hasicon ? 3 : 2));
+ textw = w - (iconw + ob_theme->bevel * (self->hasicon ? 3 : 2)) -
+ ob_theme->bwidth * 2;
} else
- w = textw + iconw + theme_bevel * (self->hasicon ? 3 : 2);
+ w = textw + iconw + ob_theme->bevel * (self->hasicon ? 3 : 2) +
+ ob_theme->bwidth * 2;
/* sanity checks to avoid crashes! */
if (w < 1) w = 1;
if (h < 1) h = 1;
break;
}
- /* set the windows/appearances up */
- RECT_SET(self->a_bg->area, 0, 0, w, h);
- XMoveResizeWindow(ob_display, self->bg, x, y, w, h);
-
- RECT_SET(self->a_text->area, 0, 0, textw, texth);
- RECT_SET(self->a_text->texture[0].position, theme_bevel, theme_bevel,
- textw - theme_bevel * 2, texth - theme_bevel * 2);
- self->a_text->surface.data.planar.parent = self->a_bg;
- self->a_text->surface.data.planar.parentx = iconw +
- theme_bevel * (self->hasicon ? 2 : 1);
- self->a_text->surface.data.planar.parenty = theme_bevel;
- XMoveResizeWindow(ob_display, self->text,
- iconw + theme_bevel * (self->hasicon ? 2 : 1),
- theme_bevel, textw, texth);
+ /* set the surfaces up */
+ RrSurfaceSetArea(self->s_bg, x, y, w, h);
+
+ RrSurfaceSetArea(self->s_text,
+ iconw + ob_theme->bevel * (self->hasicon ? 2 : 1) +
+ ob_theme->bwidth,
+ ob_theme->bevel + ob_theme->bwidth,
+ textw, texth);
if (self->hasicon) {
+ if (icon)
+ RrTextureSetRGBA(self->s_icon, 0, icon->data, 0, 0, icon->width,
+ icon->height);
+ else
+ RrTextureSetNone(self->s_icon, 0);
if (iconw < 1) iconw = 1; /* sanity check for crashes */
- RECT_SET(self->a_icon->area, 0, 0, iconw, texth);
- RECT_SET(self->a_icon->texture[0].position, 0, 0, iconw, texth);
- self->a_icon->surface.data.planar.parent = self->a_bg;
- self->a_icon->surface.data.planar.parentx = theme_bevel;
- self->a_icon->surface.data.planar.parenty = theme_bevel;
- XMoveResizeWindow(ob_display, self->icon,
- theme_bevel, theme_bevel, iconw, texth);
+ RrSurfaceSetArea(self->s_icon,
+ ob_theme->bwidth + ob_theme->bevel,
+ ob_theme->bwidth + ob_theme->bevel,
+ iconw, iconw);
}
- paint(self->bg, self->a_bg);
- paint(self->text, self->a_text);
- if (self->hasicon)
- paint(self->icon, self->a_icon);
-
- if (!self->mapped) {
- XMapWindow(ob_display, self->bg);
+ if (!RrSurfaceVisible(self->s_bg)) {
+ RrSurfaceShow(self->s_bg);
stacking_raise(INTERNAL_AS_WINDOW(self));
- self->mapped = TRUE;
- }
+ } else
+ RrPaint(self->s_bg);
}
void popup_hide(Popup *self)
{
- if (self->mapped) {
- XUnmapWindow(ob_display, self->bg);
- self->mapped = FALSE;
- }
+ RrSurfaceHide(self->s_bg);
}
#include "focus.h"
#include "dispatch.h"
#include "extensions.h"
-#include "../render/render.h"
+#include "render2/render.h"
+
#ifdef USE_LIBSN
# define SN_API_NOT_YET_FROZEN
if (client == NULL) {
if (install)
- XInstallColormap(ob_display, render_colormap);
+ XInstallColormap(ob_display, RrInstanceColormap(ob_render_inst));
else
- XUninstallColormap(ob_display, render_colormap);
+ XUninstallColormap(ob_display, RrInstanceColormap(ob_render_inst));
} else {
if (XGetWindowAttributes(ob_display, client->window, &wa) &&
wa.colormap != None) {
{
switch (self->type) {
case Window_Menu:
- return ((Menu*)self)->frame;
+ return ((Menu*)self)->w_frame;
case Window_Dock:
return ((Dock*)self)->frame;
case Window_DockApp:
#include "kernel/screen.h"
#include "kernel/client.h"
#include "kernel/openbox.h"
-
#include "kernel/frame.h"
-
-#include "render/theme.h"
+#include "render2/theme.h"
static char *PLUGIN_NAME = "client_menu";
static Menu *layer_menu;
typedef struct {
-
+ int foo;
} Client_Menu_Data;
#define CLIENT_MENU(m) ((Menu *)m)
g_assert(!self->invalid);
g_assert(client);
- newy = MAX(client->frame->area.y +
- client->frame->a_focused_title->area.height + theme_bwidth,
- y - theme_bwidth);
+ newy = MAX(client->frame->area.y + client->frame->size.top, y);
+ newy -= ob_theme->bwidth;
POINT_SET(self->location,
- MIN(x, screen_physical_size.width - self->size.width -
- theme_bwidth * 2),
- MIN(newy, screen_physical_size.height - self->size.height -
- theme_bwidth * 2));
- XMoveWindow(ob_display, self->frame, self->location.x, self->location.y);
+ MIN(x, screen_physical_size.width - self->size.width),
+ MIN(newy, screen_physical_size.height - self->size.height));
+ menu_render(self);
if (!self->shown) {
- XMapWindow(ob_display, self->frame);
+ RrSurfaceShow(self->s_frame);
stacking_raise(MENU_AS_WINDOW(self));
self->shown = TRUE;
} else if (self->shown && self->open_submenu) {
+++ /dev/null
-rendertest
-librender.a
-.libs
-color.lo
-font.lo
-gradient.lo
-image.lo
-mask.lo
-render.lo
-test.lo
-libobrender.la
-theme.lo
-Makefile.in
-.deps
-Makefile
+++ /dev/null
-themedir=$(datadir)/openbox/themes
-
-theme=operation
-
-CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) $(LIBSN_CFLAGS) $(GL_CFLAGS) @CPPFLAGS@ \
- -DG_LOG_DOMAIN=\"Render\" \
- -DDEFAULT_THEME=\"$(theme)\" \
- -DTHEMEDIR=\"$(themedir)\"
-
-INCLUDES=-I..
-LIBS=$(XFT_LIBS) $(GLIB_LIBS) $(GL_LIBS) @LIBS@
-
-noinst_PROGRAMS=rendertest
-rendertest_LDFLAGS=-lobrender -L.
-rendertest_SOURCES=test.c
-
-lib_LTLIBRARIES=libobrender.la
-libobrender_la_SOURCES=color.c font.c gradient.c image.c mask.c render.c \
- theme.c
-
-
-noinst_HEADERS=render.h gradient.h color.h font.h mask.h image.h
-
-MAINTAINERCLEANFILES=Makefile.in
-
-distclean-local:
- $(RM) *\~ *.orig *.rej .\#*
+++ /dev/null
-#ifndef __color_h
-#define __color_h
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#else
-# ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-# endif
-#endif
-
-
-#ifdef HAVE_STDINT_H
-typedef uint32_t pixel32;
-typedef uint16_t pixel16;
-#else
-typedef u_int32_t pixel32;
-typedef u_int16_t pixel16;
-#endif /* HAVE_STDINT_H */
-
-#if (G_BYTE_ORDER == G_BIG_ENDIAN)
-#define default_red_offset 0
-#define default_green_offset 8
-#define default_blue_offset 16
-#define default_alpha_offset 24
-#define render_endian MSBFirst
-#else
-#define default_alpha_offset 24
-#define default_red_offset 16
-#define default_green_offset 8
-#define default_blue_offset 0
-#define render_endian LSBFirst
-#endif /* G_BYTE_ORDER == G_BIG_ENDIAN */
-
-
-typedef struct color_rgb {
- int r;
- int g;
- int b;
- unsigned long pixel;
- GC gc;
-} color_rgb;
-
-void color_allocate_gc(color_rgb *in);
-XColor *pickColor(int r, int g, int b);
-color_rgb *color_parse(char *colorname);
-color_rgb *color_new(int r, int g, int b);
-void color_free(color_rgb *in);
-void reduce_depth(pixel32 *data, XImage *im);
-void increase_depth(pixel32 *data, XImage *im);
-
-extern int render_red_offset;
-extern int render_green_offset;
-extern int render_blue_offset;
-
-extern int render_red_shift;
-extern int render_green_shift;
-extern int render_blue_shift;
-
-extern int render_red_mask;
-extern int render_green_mask;
-extern int render_blue_mask;
-
-extern int pseudo_bpc;
-#define pseudo_ncolors() (1 << (pseudo_bpc * 3))
-extern XColor *pseudo_colors;
-#endif /* __color_h */
+++ /dev/null
-#include "font.h"
-#include "kernel/openbox.h"
-#include "kernel/geom.h"
-#include "kernel/gettext.h"
-#define _(str) gettext(str)
-
-#include <X11/Xft/Xft.h>
-#include <glib.h>
-#include <string.h>
-
-#define ELIPSES "..."
-#define ELIPSES_LENGTH(font, shadow, offset) \
- (font->elipses_length + (shadow ? offset : 0))
-
-void font_startup(void)
-{
-#ifdef DEBUG
- int version;
-#endif /* DEBUG */
- if (!XftInit(0)) {
- g_warning(_("Couldn't initialize Xft.\n"));
- exit(3);
- }
-#ifdef DEBUG
- version = XftGetVersion();
- g_message("Using Xft %d.%d.%d (Built against %d.%d.%d).",
- version / 10000 % 100, version / 100 % 100, version % 100,
- XFT_MAJOR, XFT_MINOR, XFT_REVISION);
-#endif
-}
-
-static void measure_height(ObFont *f)
-{
- XGlyphInfo info;
- char *str;
-
- /* XXX add some extended UTF8 characters in here? */
- str = "12345678900-qwertyuiopasdfghjklzxcvbnm"
- "!@#$%^&*()_+QWERTYUIOPASDFGHJKLZXCVBNM"
- "`~[]\\;',./{}|:\"<>?";
-
- XftTextExtentsUtf8(ob_display, f->xftfont,
- (FcChar8*)str, strlen(str), &info);
- f->height = (signed) info.height;
-
- /* measure an elipses */
- XftTextExtentsUtf8(ob_display, f->xftfont,
- (FcChar8*)ELIPSES, strlen(ELIPSES), &info);
- f->elipses_length = (signed) info.xOff;
-}
-
-ObFont *font_open(char *fontstring)
-{
- ObFont *out;
- XftFont *xf;
-
- if ((xf = XftFontOpenName(ob_display, ob_screen, fontstring))) {
- out = g_new(ObFont, 1);
- out->xftfont = xf;
- measure_height(out);
- return out;
- }
- g_warning(_("Unable to load font: %s\n"), fontstring);
- g_warning(_("Trying fallback font: %s\n"), "sans");
-
- if ((xf = XftFontOpenName(ob_display, ob_screen, "sans"))) {
- out = g_new(ObFont, 1);
- out->xftfont = xf;
- measure_height(out);
- return out;
- }
- g_warning(_("Unable to load font: %s\n"), "sans");
- g_warning(_("Aborting!.\n"));
-
- exit(3); /* can't continue without a font */
-}
-
-void font_close(ObFont *f)
-{
- if (f) {
- XftFontClose(ob_display, f->xftfont);
- g_free(f);
- }
-}
-
-int font_measure_string(ObFont *f, char *str, int shadow, int offset)
-{
- XGlyphInfo info;
-
- XftTextExtentsUtf8(ob_display, f->xftfont,
- (FcChar8*)str, strlen(str), &info);
-
- return (signed) info.xOff + (shadow ? offset : 0);
-}
-
-int font_height(ObFont *f, int shadow, int offset)
-{
- return f->height + (shadow ? offset : 0);
-}
-
-int font_max_char_width(ObFont *f)
-{
- return (signed) f->xftfont->max_advance_width;
-}
-
-void font_draw(XftDraw *d, TextureText *t, Rect *position)
-{
- int x,y,w,h;
- XftColor c;
- GString *text;
- int m, em;
- size_t l;
- gboolean shortened = FALSE;
-
- y = position->y;
- w = position->width;
- h = position->height;
-
- /* accomidate for areas bigger/smaller than Xft thinks the font is tall */
- y -= (2 * (t->font->xftfont->ascent + t->font->xftfont->descent) -
- (t->font->height + h) - 1) / 2;
-
- text = g_string_new(t->string);
- l = g_utf8_strlen(text->str, -1);
- m = font_measure_string(t->font, text->str, t->shadow, t->offset);
- while (l && m > position->width) {
- shortened = TRUE;
- /* remove a character from the middle */
- text = g_string_erase(text, l-- / 2, 1);
- em = ELIPSES_LENGTH(t->font, t->shadow, t->offset);
- /* if the elipses are too large, don't show them at all */
- if (em > position->width)
- shortened = FALSE;
- m = font_measure_string(t->font, text->str, t->shadow, t->offset) + em;
- }
- if (shortened) {
- text = g_string_insert(text, (l + 1) / 2, ELIPSES);
- l += 3;
- }
- if (!l) return;
-
- switch (t->justify) {
- case Justify_Left:
- x = position->x;
- break;
- case Justify_Right:
- x = position->x + (w - m);
- break;
- case Justify_Center:
- x = position->x + (w - m) / 2;
- break;
- }
-
- l = strlen(text->str); /* number of bytes */
-
- if (t->shadow) {
- if (t->tint >= 0) {
- c.color.red = 0;
- c.color.green = 0;
- c.color.blue = 0;
- c.color.alpha = 0xffff * t->tint / 100; /* transparent shadow */
- c.pixel = BlackPixel(ob_display, ob_screen);
- } else {
- c.color.red = 0xffff * -t->tint / 100;
- c.color.green = 0xffff * -t->tint / 100;
- c.color.blue = 0xffff * -t->tint / 100;
- c.color.alpha = 0xffff * -t->tint / 100; /* transparent shadow */
- c.pixel = WhitePixel(ob_display, ob_screen);
- }
- XftDrawStringUtf8(d, &c, t->font->xftfont, x + t->offset,
- t->font->xftfont->ascent + y + t->offset,
- (FcChar8*)text->str, l);
- }
- c.color.red = t->color->r | t->color->r << 8;
- c.color.green = t->color->g | t->color->g << 8;
- c.color.blue = t->color->b | t->color->b << 8;
- c.color.alpha = 0xff | 0xff << 8; /* fully opaque text */
- c.pixel = t->color->pixel;
-
- XftDrawStringUtf8(d, &c, t->font->xftfont, x,
- t->font->xftfont->ascent + y,
- (FcChar8*)text->str, l);
- return;
-}
+++ /dev/null
-#ifndef __font_h
-#define __font_h
-#include <X11/Xft/Xft.h>
-#include "render.h"
-#include "kernel/geom.h"
-
-void font_startup(void);
-ObFont *font_open(char *fontstring);
-void font_close(ObFont *f);
-int font_measure_string(ObFont *f, char *str, int shadow, int offset);
-int font_height(ObFont *f, int shadow, int offset);
-int font_max_char_width(ObFont *f);
-void font_draw(XftDraw *d, TextureText *t, Rect *position);
-#endif /* __font_h */
+++ /dev/null
-#ifdef USE_GL
-#include <GL/gl.h>
-#endif /* USE_GL */
-#include <glib.h>
-#include "render.h"
-#include "gradient.h"
-#include "../kernel/openbox.h"
-#include "color.h"
-
-void gradient_render(Surface *sf, int w, int h)
-{
- pixel32 *data = sf->data.planar.pixel_data;
- pixel32 current;
- unsigned int r,g,b;
- int off, x;
-
- switch (sf->data.planar.grad) {
- case Background_Solid: /* already handled */
- return;
- case Background_Vertical:
- gradient_vertical(sf, w, h);
- break;
- case Background_Horizontal:
- gradient_horizontal(sf, w, h);
- break;
- case Background_Diagonal:
- gradient_diagonal(sf, w, h);
- break;
- case Background_CrossDiagonal:
- gradient_crossdiagonal(sf, w, h);
- break;
- case Background_Pyramid:
- gradient_pyramid(sf, w, h);
- break;
- case Background_PipeCross:
- gradient_pipecross(sf, w, h);
- break;
- case Background_Rectangle:
- gradient_rectangle(sf, w, h);
- break;
- default:
- g_message("unhandled gradient");
- return;
- }
-
- if (sf->data.planar.relief == Flat && sf->data.planar.border) {
- r = sf->data.planar.border_color->r;
- g = sf->data.planar.border_color->g;
- b = sf->data.planar.border_color->b;
- current = (r << default_red_offset)
- + (g << default_green_offset)
- + (b << default_blue_offset);
- for (off = 0, x = 0; x < w; ++x, off++) {
- *(data + off) = current;
- *(data + off + ((h-1) * w)) = current;
- }
- for (off = 0, x = 0; x < h; ++x, off++) {
- *(data + (off * w)) = current;
- *(data + (off * w) + w - 1) = current;
- }
- }
-
- if (sf->data.planar.relief != Flat) {
- if (sf->data.planar.bevel == Bevel1) {
- for (off = 1, x = 1; x < w - 1; ++x, off++)
- highlight(data + off,
- data + off + (h-1) * w,
- sf->data.planar.relief==Raised);
- for (off = 0, x = 0; x < h; ++x, off++)
- highlight(data + off * w,
- data + off * w + w - 1,
- sf->data.planar.relief==Raised);
- }
-
- if (sf->data.planar.bevel == Bevel2) {
- for (off = 2, x = 2; x < w - 2; ++x, off++)
- highlight(data + off + w,
- data + off + (h-2) * w,
- sf->data.planar.relief==Raised);
- for (off = 1, x = 1; x < h-1; ++x, off++)
- highlight(data + off * w + 1,
- data + off * w + w - 2,
- sf->data.planar.relief==Raised);
- }
- }
-}
-
-
-
-void gradient_vertical(Surface *sf, int w, int h)
-{
- pixel32 *data = sf->data.planar.pixel_data;
- pixel32 current;
- float dr, dg, db;
- unsigned int r,g,b;
- int x, y;
-
- dr = (float)(sf->data.planar.secondary->r - sf->data.planar.primary->r);
- dr/= (float)h;
-
- dg = (float)(sf->data.planar.secondary->g - sf->data.planar.primary->g);
- dg/= (float)h;
-
- db = (float)(sf->data.planar.secondary->b - sf->data.planar.primary->b);
- db/= (float)h;
-
- for (y = 0; y < h; ++y) {
- r = sf->data.planar.primary->r + (int)(dr * y);
- g = sf->data.planar.primary->g + (int)(dg * y);
- b = sf->data.planar.primary->b + (int)(db * y);
- current = (r << default_red_offset)
- + (g << default_green_offset)
- + (b << default_blue_offset);
- for (x = 0; x < w; ++x, ++data)
- *data = current;
- }
-}
-
-void gradient_horizontal(Surface *sf, int w, int h)
-{
- pixel32 *data = sf->data.planar.pixel_data;
- pixel32 current;
- float dr, dg, db;
- unsigned int r,g,b;
- int x, y;
-
- dr = (float)(sf->data.planar.secondary->r - sf->data.planar.primary->r);
- dr/= (float)w;
-
- dg = (float)(sf->data.planar.secondary->g - sf->data.planar.primary->g);
- dg/= (float)w;
-
- db = (float)(sf->data.planar.secondary->b - sf->data.planar.primary->b);
- db/= (float)w;
-
- for (x = 0; x < w; ++x, ++data) {
- r = sf->data.planar.primary->r + (int)(dr * x);
- g = sf->data.planar.primary->g + (int)(dg * x);
- b = sf->data.planar.primary->b + (int)(db * x);
- current = (r << default_red_offset)
- + (g << default_green_offset)
- + (b << default_blue_offset);
- for (y = 0; y < h; ++y)
- *(data + y*w) = current;
- }
-}
-
-void gradient_diagonal(Surface *sf, int w, int h)
-{
- pixel32 *data = sf->data.planar.pixel_data;
- pixel32 current;
- float drx, dgx, dbx, dry, dgy, dby;
- unsigned int r,g,b;
- int x, y;
-
- for (y = 0; y < h; ++y) {
- drx = (float)(sf->data.planar.secondary->r -
- sf->data.planar.primary->r);
- dry = drx/(float)h;
- drx/= (float)w;
-
- dgx = (float)(sf->data.planar.secondary->g -
- sf->data.planar.primary->g);
- dgy = dgx/(float)h;
- dgx/= (float)w;
-
- dbx = (float)(sf->data.planar.secondary->b -
- sf->data.planar.primary->b);
- dby = dbx/(float)h;
- dbx/= (float)w;
- for (x = 0; x < w; ++x, ++data) {
- r = sf->data.planar.primary->r +
- ((int)(drx * x) + (int)(dry * y))/2;
- g = sf->data.planar.primary->g +
- ((int)(dgx * x) + (int)(dgy * y))/2;
- b = sf->data.planar.primary->b +
- ((int)(dbx * x) + (int)(dby * y))/2;
- current = (r << default_red_offset)
- + (g << default_green_offset)
- + (b << default_blue_offset);
- *data = current;
- }
- }
-}
-
-void gradient_crossdiagonal(Surface *sf, int w, int h)
-{
- pixel32 *data = sf->data.planar.pixel_data;
- pixel32 current;
- float drx, dgx, dbx, dry, dgy, dby;
- unsigned int r,g,b;
- int x, y;
-
- for (y = 0; y < h; ++y) {
- drx = (float)(sf->data.planar.secondary->r -
- sf->data.planar.primary->r);
- dry = drx/(float)h;
- drx/= (float)w;
-
- dgx = (float)(sf->data.planar.secondary->g -
- sf->data.planar.primary->g);
- dgy = dgx/(float)h;
- dgx/= (float)w;
-
- dbx = (float)(sf->data.planar.secondary->b -
- sf->data.planar.primary->b);
- dby = dbx/(float)h;
- dbx/= (float)w;
- for (x = w; x > 0; --x, ++data) {
- r = sf->data.planar.primary->r +
- ((int)(drx * (x-1)) + (int)(dry * y))/2;
- g = sf->data.planar.primary->g +
- ((int)(dgx * (x-1)) + (int)(dgy * y))/2;
- b = sf->data.planar.primary->b +
- ((int)(dbx * (x-1)) + (int)(dby * y))/2;
- current = (r << default_red_offset)
- + (g << default_green_offset)
- + (b << default_blue_offset);
- *data = current;
- }
- }
-}
-
-void highlight(pixel32 *x, pixel32 *y, gboolean raised)
-{
- int r, g, b;
-
- pixel32 *up, *down;
- if (raised) {
- up = x;
- down = y;
- } else {
- up = y;
- down = x;
- }
- r = (*up >> default_red_offset) & 0xFF;
- r += r >> 1;
- g = (*up >> default_green_offset) & 0xFF;
- g += g >> 1;
- b = (*up >> default_blue_offset) & 0xFF;
- b += b >> 1;
- if (r > 0xFF) r = 0xFF;
- if (g > 0xFF) g = 0xFF;
- if (b > 0xFF) b = 0xFF;
- *up = (r << default_red_offset) + (g << default_green_offset)
- + (b << default_blue_offset);
-
- r = (*down >> default_red_offset) & 0xFF;
- r = (r >> 1) + (r >> 2);
- g = (*down >> default_green_offset) & 0xFF;
- g = (g >> 1) + (g >> 2);
- b = (*down >> default_blue_offset) & 0xFF;
- b = (b >> 1) + (b >> 2);
- *down = (r << default_red_offset) + (g << default_green_offset)
- + (b << default_blue_offset);
-}
-
-static void create_bevel_colors(Appearance *l)
-{
- int r, g, b;
-
- /* light color */
- r = l->surface.data.planar.primary->r;
- r += r >> 1;
- g = l->surface.data.planar.primary->g;
- g += g >> 1;
- b = l->surface.data.planar.primary->b;
- b += b >> 1;
- if (r > 0xFF) r = 0xFF;
- if (g > 0xFF) g = 0xFF;
- if (b > 0xFF) b = 0xFF;
- g_assert(!l->surface.data.planar.bevel_light);
- l->surface.data.planar.bevel_light = color_new(r, g, b);
- color_allocate_gc(l->surface.data.planar.bevel_light);
-
- /* dark color */
- r = l->surface.data.planar.primary->r;
- r = (r >> 1) + (r >> 2);
- g = l->surface.data.planar.primary->g;
- g = (g >> 1) + (g >> 2);
- b = l->surface.data.planar.primary->b;
- b = (b >> 1) + (b >> 2);
- g_assert(!l->surface.data.planar.bevel_dark);
- l->surface.data.planar.bevel_dark = color_new(r, g, b);
- color_allocate_gc(l->surface.data.planar.bevel_dark);
-}
-
-void gradient_solid(Appearance *l, int x, int y, int w, int h)
-{
- pixel32 pix;
- int i, a, b;
- PlanarSurface *sp = &l->surface.data.planar;
- int left = x, top = y, right = x + w - 1, bottom = y + h - 1;
-
- if (sp->primary->gc == None)
- color_allocate_gc(sp->primary);
- pix = (sp->primary->r << default_red_offset)
- + (sp->primary->g << default_green_offset)
- + (sp->primary->b << default_blue_offset);
-
- for (a = 0; a < l->area.width; a++)
- for (b = 0; b < l->area.height; b++)
- sp->pixel_data[a + b*l->area.width] = pix;
-
- XFillRectangle(ob_display, l->pixmap, sp->primary->gc,
- x, y, w, h);
-
- if (sp->interlaced) {
- if (sp->secondary->gc == None)
- color_allocate_gc(sp->secondary);
- for (i = y; i < h; i += 2)
- XDrawLine(ob_display, l->pixmap, sp->secondary->gc,
- x, i, w, i);
- }
-
- switch (sp->relief) {
- case Raised:
- if (!sp->bevel_dark)
- create_bevel_colors(l);
-
- switch (sp->bevel) {
- case Bevel1:
- XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
- left, bottom, right, bottom);
- XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
- right, bottom, right, top);
-
- XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
- left, top, right, top);
- XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
- left, bottom, left, top);
- break;
- case Bevel2:
- XDrawLine(ob_display, l->pixmap,
- sp->bevel_dark->gc,
- left + 1, bottom - 2, right - 2, bottom - 2);
- XDrawLine(ob_display, l->pixmap,
- sp->bevel_dark->gc,
- right - 2, bottom - 2, right - 2, top + 1);
-
- XDrawLine(ob_display, l->pixmap,
- sp->bevel_light->gc,
- left + 1, top + 1, right - 2, top + 1);
- XDrawLine(ob_display, l->pixmap,
- sp->bevel_light->gc,
- left + 1, bottom - 2, left + 1, top + 1);
- break;
- default:
- g_assert_not_reached(); /* unhandled BevelType */
- }
- break;
- case Sunken:
- if (!sp->bevel_dark)
- create_bevel_colors(l);
-
- switch (sp->bevel) {
- case Bevel1:
- XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
- left, bottom, right, bottom);
- XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
- right, bottom, right, top);
-
- XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
- left, top, right, top);
- XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
- left, bottom, left, top);
- break;
- case Bevel2:
- XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
- left + 1, bottom - 2, right - 2, bottom - 2);
- XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
- right - 2, bottom - 2, right - 2, top + 1);
-
- XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
- left + 1, top + 1, right - 2, top + 1);
- XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
- left + 1, bottom - 2, left + 1, top + 1);
-
- break;
- default:
- g_assert_not_reached(); /* unhandled BevelType */
- }
- break;
- case Flat:
- if (sp->border) {
- if (sp->border_color->gc == None)
- color_allocate_gc(sp->border_color);
- XDrawRectangle(ob_display, l->pixmap, sp->border_color->gc,
- left, top, right, bottom);
- }
- break;
- default:
- g_assert_not_reached(); /* unhandled ReliefType */
- }
-}
-
-void gradient_pyramid(Surface *sf, int inw, int inh)
-{
- pixel32 *data = sf->data.planar.pixel_data;
- pixel32 *end = data + inw*inh - 1;
- pixel32 current;
- float drx, dgx, dbx, dry, dgy, dby;
- unsigned int r,g,b;
- int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
- for (y = 0; y < h; ++y) {
- drx = (float)(sf->data.planar.secondary->r -
- sf->data.planar.primary->r);
- dry = drx/(float)h;
- drx/= (float)w;
-
- dgx = (float)(sf->data.planar.secondary->g -
- sf->data.planar.primary->g);
- dgy = dgx/(float)h;
- dgx/= (float)w;
-
- dbx = (float)(sf->data.planar.secondary->b -
- sf->data.planar.primary->b);
- dby = dbx/(float)h;
- dbx/= (float)w;
- for (x = 0; x < w; ++x, data) {
- r = sf->data.planar.primary->r +
- ((int)(drx * x) + (int)(dry * y))/2;
- g = sf->data.planar.primary->g +
- ((int)(dgx * x) + (int)(dgy * y))/2;
- b = sf->data.planar.primary->b +
- ((int)(dbx * x) + (int)(dby * y))/2;
- current = (r << default_red_offset)
- + (g << default_green_offset)
- + (b << default_blue_offset);
- *(data+x) = current;
- *(data+inw-x) = current;
- *(end-x) = current;
- *(end-(inw-x)) = current;
- }
- data+=inw;
- end-=inw;
- }
-}
-
-void gradient_rectangle(Surface *sf, int inw, int inh)
-{
- pixel32 *data = sf->data.planar.pixel_data;
- pixel32 *end = data + inw*inh - 1;
- pixel32 current;
- float drx, dgx, dbx, dry, dgy, dby;
- unsigned int r,g,b;
- int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
- int val;
-
- for (y = 0; y < h; ++y) {
- drx = (float)(sf->data.planar.primary->r -
- sf->data.planar.secondary->r);
- dry = drx/(float)h;
- drx/= (float)w;
-
- dgx = (float)(sf->data.planar.primary->g -
- sf->data.planar.secondary->g);
- dgy = dgx/(float)h;
- dgx/= (float)w;
-
- dbx = (float)(sf->data.planar.primary->b -
- sf->data.planar.secondary->b);
- dby = dbx/(float)h;
- dbx/= (float)w;
- for (x = 0; x < w; ++x, data) {
- if ((float)x/(float)w < (float)y/(float)h) val = (int)(drx * x);
- else val = (int)(dry * y);
-
- r = sf->data.planar.secondary->r + val;
- g = sf->data.planar.secondary->g + val;
- b = sf->data.planar.secondary->b + val;
- current = (r << default_red_offset)
- + (g << default_green_offset)
- + (b << default_blue_offset);
- *(data+x) = current;
- *(data+inw-x) = current;
- *(end-x) = current;
- *(end-(inw-x)) = current;
- }
- data+=inw;
- end-=inw;
- }
-}
-
-void gradient_pipecross(Surface *sf, int inw, int inh)
-{
- pixel32 *data = sf->data.planar.pixel_data;
- pixel32 *end = data + inw*inh - 1;
- pixel32 current;
- float drx, dgx, dbx, dry, dgy, dby;
- unsigned int r,g,b;
- int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
- int val;
-
- for (y = 0; y < h; ++y) {
- drx = (float)(sf->data.planar.secondary->r -
- sf->data.planar.primary->r);
- dry = drx/(float)h;
- drx/= (float)w;
-
- dgx = (float)(sf->data.planar.secondary->g -
- sf->data.planar.primary->g);
- dgy = dgx/(float)h;
- dgx/= (float)w;
-
- dbx = (float)(sf->data.planar.secondary->b -
- sf->data.planar.primary->b);
- dby = dbx/(float)h;
- dbx/= (float)w;
- for (x = 0; x < w; ++x, data) {
- if ((float)x/(float)w > (float)y/(float)h) val = (int)(drx * x);
- else val = (int)(dry * y);
-
- r = sf->data.planar.primary->r + val;
- g = sf->data.planar.primary->g + val;
- b = sf->data.planar.primary->b + val;
- current = (r << default_red_offset)
- + (g << default_green_offset)
- + (b << default_blue_offset);
- *(data+x) = current;
- *(data+inw-x) = current;
- *(end-x) = current;
- *(end-(inw-x)) = current;
- }
- data+=inw;
- end-=inw;
- }
-}
-#ifdef USE_GL
-void render_gl_gradient(Surface *sf, int x, int y, int w, int h)
-{
- float pr,pg,pb;
- float sr, sg, sb;
- float ar, ag, ab;
-
- pr = (float)sf->data.planar.primary->r/255.0;
- pg = (float)sf->data.planar.primary->g/255.0;
- pb = (float)sf->data.planar.primary->b/255.0;
- if (sf->data.planar.secondary) {
- sr = (float)sf->data.planar.secondary->r/255.0;
- sg = (float)sf->data.planar.secondary->g/255.0;
- sb = (float)sf->data.planar.secondary->b/255.0;
- }
- switch (sf->data.planar.grad) {
- case Background_Solid: /* already handled */
- glBegin(GL_TRIANGLES);
- glColor3f(pr, pg, pb);
- glVertex2i(x, y);
- glVertex2i(x+w, y);
- glVertex2i(x+w, y+h);
-
- glVertex2i(x+w, y+h);
- glVertex2i(x, y+h);
- glVertex2i(x, y);
- glEnd();
- return;
- case Background_Horizontal:
- glBegin(GL_TRIANGLES);
- glColor3f(pr, pg, pb);
- glVertex2i(x, y);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w, y);
- glVertex2i(x+w, y+h);
-
- glVertex2i(x+w, y+h);
- glColor3f(pr, pg, pb);
- glVertex2i(x, y+h);
- glVertex2i(x, y);
- glEnd();
- break;
- case Background_Vertical:
- glBegin(GL_TRIANGLES);
- glColor3f(pr, pg, pb);
- glVertex2i(x, y);
- glVertex2i(x+w, y);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w, y+h);
-
- glVertex2i(x+w, y+h);
- glVertex2i(x, y+h);
- glColor3f(pr, pg, pb);
- glVertex2i(x, y);
- glEnd();
- break;
- case Background_Diagonal:
- ar = (pr + sr) / 2.0;
- ag = (pg + sg) / 2.0;
- ab = (pb + sb) / 2.0;
- glBegin(GL_TRIANGLES);
- glColor3f(ar, ag, ab);
- glVertex2i(x, y);
- glColor3f(pr, pg, pb);
- glVertex2i(x+w, y);
- glColor3f(ar, ag, ab);
- glVertex2i(x+w, y+h);
-
- glColor3f(ar, ag, ab);
- glVertex2i(x+w, y+h);
- glColor3f(sr, sg, sb);
- glVertex2i(x, y+h);
- glColor3f(ar, ag, ab);
- glVertex2i(x, y);
- glEnd();
- break;
- case Background_CrossDiagonal:
- ar = (pr + sr) / 2.0;
- ag = (pg + sg) / 2.0;
- ab = (pb + sb) / 2.0;
- glBegin(GL_TRIANGLES);
- glColor3f(pr, pg, pb);
- glVertex2i(x, y);
- glColor3f(ar, ag, ab);
- glVertex2i(x+w, y);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w, y+h);
-
- glColor3f(sr, sg, sb);
- glVertex2i(x+w, y+h);
- glColor3f(ar, ag, ab);
- glVertex2i(x, y+h);
- glColor3f(pr, pg, pb);
- glVertex2i(x, y);
- glEnd();
- break;
- case Background_Pyramid:
- ar = (pr + sr) / 2.0;
- ag = (pg + sg) / 2.0;
- ab = (pb + sb) / 2.0;
- glBegin(GL_TRIANGLES);
- glColor3f(pr, pg, pb);
- glVertex2i(x, y);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w/2, y+h/2);
- glColor3f(ar, ag, ab);
- glVertex2i(x, y+h/2);
-
- glVertex2i(x, y+h/2);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w/2, y+h/2);
- glColor3f(pr, pg, pb);
- glVertex2i(x, y+h);
-
- glVertex2i(x, y+h);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w/2, y+h/2);
- glColor3f(ar, ag, ab);
- glVertex2i(x+w/2, y+h);
-
- glVertex2i(x+w/2, y+h);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w/2, y+h/2);
- glColor3f(pr, pg, pb);
- glVertex2i(x+w, y+h);
-
- glVertex2i(x+w, y+h);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w/2, y+h/2);
- glColor3f(ar, ag, ab);
- glVertex2i(x+w, y+h/2);
-
- glVertex2i(x+w, y+h/2);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w/2, y+h/2);
- glColor3f(pr, pg, pb);
- glVertex2i(x+w, y);
-
- glVertex2i(x+w, y);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w/2, y+h/2);
- glColor3f(ar, ag, ab);
- glVertex2i(x+w/2, y);
-
- glVertex2i(x+w/2, y);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w/2, y+h/2);
- glColor3f(pr, pg, pb);
- glVertex2i(x, y);
- glEnd();
- break;
- case Background_PipeCross:
- glBegin(GL_TRIANGLES);
- glColor3f(pr, pg, pb);
- glVertex2i(x, y);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w/2, y+h/2);
- glVertex2i(x, y+h/2);
-
- glVertex2i(x, y+h/2);
- glVertex2i(x+w/2, y+h/2);
- glColor3f(pr, pg, pb);
- glVertex2i(x, y+h);
-
- glVertex2i(x, y+h);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w/2, y+h/2);
- glVertex2i(x+w/2, y+h);
-
- glVertex2i(x+w/2, y+h);
- glVertex2i(x+w/2, y+h/2);
- glColor3f(pr, pg, pb);
- glVertex2i(x+w, y+h);
-
- glVertex2i(x+w, y+h);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w/2, y+h/2);
- glVertex2i(x+w, y+h/2);
-
- glVertex2i(x+w, y+h/2);
- glVertex2i(x+w/2, y+h/2);
- glColor3f(pr, pg, pb);
- glVertex2i(x+w, y);
-
- glVertex2i(x+w, y);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w/2, y+h/2);
- glVertex2i(x+w/2, y);
-
- glVertex2i(x+w/2, y);
- glVertex2i(x+w/2, y+h/2);
- glColor3f(pr, pg, pb);
- glVertex2i(x, y);
- glEnd();
- break;
- case Background_Rectangle:
- glBegin(GL_TRIANGLES);
- glColor3f(pr, pg, pb);
- glVertex2i(x, y);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w/2, y+h/2);
- glColor3f(pr, pg, pb);
- glVertex2i(x, y+h);
-
- glVertex2i(x, y+h);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w/2, y+h/2);
- glColor3f(pr, pg, pb);
- glVertex2i(x+w, y+h);
-
- glVertex2i(x+w, y+h);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w/2, y+h/2);
- glColor3f(pr, pg, pb);
- glVertex2i(x+w, y);
-
- glVertex2i(x+w, y);
- glColor3f(sr, sg, sb);
- glVertex2i(x+w/2, y+h/2);
- glColor3f(pr, pg, pb);
- glVertex2i(x, y);
-
- glEnd();
- break;
- default:
- g_message("unhandled gradient");
- return;
- }
-}
-#endif /* USE_GL */
+++ /dev/null
-#ifndef __gradient_h
-#define __gradient_h
-
-#include "render.h"
-
-void gradient_render(Surface *sf, int w, int h);
-void gradient_vertical(Surface *sf, int w, int h);
-void gradient_horizontal(Surface *sf, int w, int h);
-void gradient_diagonal(Surface *sf, int w, int h);
-void gradient_crossdiagonal(Surface *sf, int w, int h);
-void gradient_pyramid(Surface *sf, int w, int h);
-void gradient_pipecross(Surface *sf, int w, int h);
-void gradient_rectangle(Surface *sf, int w, int h);
-void gradient_solid(Appearance *l, int x, int y, int w, int h);
-void highlight(pixel32 *x, pixel32 *y, gboolean raised);
-
-void render_gl_gradient(Surface *sf, int x, int y, int w, int h);
-
-#endif /* __gradient_h */
+++ /dev/null
-#include <glib.h>
-#include "../kernel/geom.h"
-#include "image.h"
-
-void image_draw(pixel32 *target, TextureRGBA *rgba, Rect *position,
- Rect *surarea)
-{
- pixel32 *draw = rgba->data;
- guint c, i, e, t, sfw, sfh;
- sfw = position->width;
- sfh = position->height;
-
- /* it would be nice if this worked, but this function is well broken in
- these circumstances. */
- g_assert(position->width == surarea->width &&
- position->height == surarea->height);
-
- g_assert(rgba->data != NULL);
-
- if ((rgba->width != sfw || rgba->height != sfh) &&
- (rgba->width != rgba->cwidth || rgba->height != rgba->cheight)) {
- double dx = rgba->width / (double)sfw;
- double dy = rgba->height / (double)sfh;
- double px = 0.0;
- double py = 0.0;
- int iy = 0;
-
- /* scale it and cache it */
- if (rgba->cache != NULL)
- g_free(rgba->cache);
- rgba->cache = g_new(unsigned long, sfw * sfh);
- rgba->cwidth = sfw;
- rgba->cheight = sfh;
- for (i = 0, c = 0, e = sfw*sfh; i < e; ++i) {
- rgba->cache[i] = rgba->data[(int)px + iy];
- if (++c >= sfw) {
- c = 0;
- px = 0;
- py += dy;
- iy = (int)py * rgba->width;
- } else
- px += dx;
- }
-
- /* do we use the cache we may have just created, or the original? */
- if (rgba->width != sfw || rgba->height != sfh)
- draw = rgba->cache;
-
- /* apply the alpha channel */
- for (i = 0, c = 0, t = position->x, e = sfw*sfh; i < e; ++i, ++t) {
- guchar alpha, r, g, b, bgr, bgg, bgb;
-
- alpha = draw[i] >> default_alpha_offset;
- r = draw[i] >> default_red_offset;
- g = draw[i] >> default_green_offset;
- b = draw[i] >> default_blue_offset;
-
- if (c >= sfw) {
- c = 0;
- t += surarea->width - sfw;
- }
-
- /* background color */
- bgr = target[t] >> default_red_offset;
- bgg = target[t] >> default_green_offset;
- bgb = target[t] >> default_blue_offset;
-
- r = bgr + (((r - bgr) * alpha) >> 8);
- g = bgg + (((g - bgg) * alpha) >> 8);
- b = bgb + (((b - bgb) * alpha) >> 8);
-
- target[t] = (r << default_red_offset)
- | (g << default_green_offset)
- | (b << default_blue_offset);
- }
- }
-}
+++ /dev/null
-#ifndef __image_h
-#define __image_h
-
-#include "render.h"
-#include "../kernel/geom.h"
-
-void image_draw(pixel32 *target, TextureRGBA *rgba, Rect *position,
- Rect *surarea);
-
-#endif
+++ /dev/null
-#include "mask.h"
-#include "../kernel/openbox.h"
-
-pixmap_mask *pixmap_mask_new(int w, int h, char *data)
-{
- pixmap_mask *m = g_new(pixmap_mask, 1);
- m->w = w;
- m->h = h;
- /* round up to nearest byte */
- m->data = g_memdup(data, (w * h + 7) / 8);
- m->mask = XCreateBitmapFromData(ob_display, ob_root, data, w, h);
- return m;
-}
-
-void pixmap_mask_free(pixmap_mask *m)
-{
- if (m) {
- XFreePixmap(ob_display, m->mask);
- g_free(m->data);
- g_free(m);
- }
-}
-
-void mask_draw(Pixmap p, TextureMask *m, Rect *position)
-{
- int x, y;
- if (m->mask == None) return; /* no mask given */
-
- /* set the clip region */
- x = position->x + (position->width - m->mask->w) / 2;
- y = position->y + (position->height - m->mask->h) / 2;
-
- if (x < 0) x = 0;
- if (y < 0) y = 0;
-
- XSetClipMask(ob_display, m->color->gc, m->mask->mask);
- XSetClipOrigin(ob_display, m->color->gc, x, y);
-
- /* fill in the clipped region */
- XFillRectangle(ob_display, p, m->color->gc, x, y,
- x + m->mask->w, y + m->mask->h);
-
- /* unset the clip region */
- XSetClipMask(ob_display, m->color->gc, None);
- XSetClipOrigin(ob_display, m->color->gc, 0, 0);
-}
-
-pixmap_mask *pixmap_mask_copy(pixmap_mask *src)
-{
- pixmap_mask *m = g_new(pixmap_mask, 1);
- m->w = src->w;
- m->h = src->h;
- /* round up to nearest byte */
- m->data = g_memdup(src->data, (src->w * src->h + 7) / 8);
- m->mask = XCreateBitmapFromData(ob_display, ob_root, m->data, m->w, m->h);
- return m;
-}
+++ /dev/null
-#ifndef __mask_h
-#define __mask_h
-
-#include "render.h"
-#include "kernel/geom.h"
-
-pixmap_mask *pixmap_mask_new(int w, int h, char *data);
-pixmap_mask *pixmap_mask_copy(pixmap_mask *src);
-void pixmap_mask_free(pixmap_mask *m);
-void mask_draw(Pixmap p, TextureMask *m, Rect *position);
-
-#endif
+++ /dev/null
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#ifdef USE_GL
-# include <GL/glx.h>
-#endif
-
-#include <glib.h>
-#include "render.h"
-#include "gradient.h"
-#include "font.h"
-#include "mask.h"
-#include "color.h"
-#include "image.h"
-#include "theme.h"
-#include "kernel/openbox.h"
-
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-
-int render_depth;
-XVisualInfo render_visual_info;
-
-Visual *render_visual;
-Colormap render_colormap;
-
-int render_red_offset = 0, render_green_offset = 0, render_blue_offset = 0;
-int render_red_shift, render_green_shift, render_blue_shift;
-int render_red_mask, render_green_mask, render_blue_mask;
-
-
-#ifdef USE_GL
-
-GLXContext render_glx_context;
-
-int render_glx_rating(XVisualInfo *v)
-{
- int er;
- int rating = 0;
- int val;
- printf("evaluating visual %d\n", v->visualid);
- glXGetConfig(ob_display, v, GLX_BUFFER_SIZE, &val);
- printf("buffer size %d\n", val);
-
- switch (val) {
- case 32:
- rating += 300;
- break;
- case 24:
- rating += 200;
- break;
- case 16:
- rating += 100;
- break;
- }
-
- glXGetConfig(ob_display, v, GLX_LEVEL, &val);
- printf("level %d\n", val);
- if (val != 0)
- rating = -10000;
-
- glXGetConfig(ob_display, v, GLX_DEPTH_SIZE, &val);
- printf("depth size %d\n", val);
- switch (val) {
- case 32:
- rating += 30;
- break;
- case 24:
- rating += 20;
- break;
- case 16:
- rating += 10;
- break;
- case 0:
- rating -= 10000;
- }
-
- glXGetConfig(ob_display, v, GLX_DOUBLEBUFFER, &val);
- printf("double buffer %d\n", val);
- if (val)
- rating++;
- return rating;
-}
-#endif /* USE_GL */
-
-void render_startup(void)
-{
- int count, i = 0, val, best = 0, rate = 0, temp;
- XVisualInfo vimatch, *vilist;
- paint = x_paint;
-
- render_depth = DefaultDepth(ob_display, ob_screen);
- render_visual = DefaultVisual(ob_display, ob_screen);
- render_colormap = DefaultColormap(ob_display, ob_screen);
-
-#ifdef USE_GL
- vimatch.screen = ob_screen;
- vimatch.class = TrueColor;
- vilist = XGetVisualInfo(ob_display, VisualScreenMask | VisualClassMask,
- &vimatch, &count);
-
- if (vilist) {
- printf("looking for a GL visualin %d visuals\n", count);
- for (i = 0; i < count; i++) {
- glXGetConfig(ob_display, &vilist[i], GLX_USE_GL, &val);
- if (val) {
- temp = render_glx_rating(&vilist[i]);
- if (temp > rate) {
- best = i;
- rate = temp;
- }
- }
- }
- }
- if (rate > 0) {
- printf("picked visual %d with rating %d\n", best, rate);
- render_depth = vilist[best].depth;
- render_visual = vilist[best].visual;
- render_colormap = XCreateColormap(ob_display, ob_root,
- render_visual, AllocNone);
- render_visual_info = vilist[best];
- render_glx_context = glXCreateContext(ob_display, &render_visual_info,
- NULL, True);
- if (render_glx_context == NULL)
- printf("sadness\n");
- else {
- paint = gl_paint;
- }
- }
-#endif /*USE_GL*/
-
-
- switch (render_visual->class) {
- case TrueColor:
- truecolor_startup();
- break;
- case PseudoColor:
- case StaticColor:
- case GrayScale:
- case StaticGray:
- pseudocolor_startup();
- break;
- default:
- g_critical("unsupported visual class.\n");
- exit(EXIT_FAILURE);
-
- }
-}
-
-void truecolor_startup(void)
-{
- unsigned long red_mask, green_mask, blue_mask;
- XImage *timage = NULL;
-
- timage = XCreateImage(ob_display, render_visual, render_depth,
- ZPixmap, 0, NULL, 1, 1, 32, 0);
- g_assert(timage != NULL);
- /* find the offsets for each color in the visual's masks */
- render_red_mask = red_mask = timage->red_mask;
- render_green_mask = green_mask = timage->green_mask;
- render_blue_mask = blue_mask = timage->blue_mask;
-
- render_red_offset = 0;
- render_green_offset = 0;
- render_blue_offset = 0;
-
- while (! (red_mask & 1)) { render_red_offset++; red_mask >>= 1; }
- while (! (green_mask & 1)) { render_green_offset++; green_mask >>= 1; }
- while (! (blue_mask & 1)) { render_blue_offset++; blue_mask >>= 1; }
-
- render_red_shift = render_green_shift = render_blue_shift = 8;
- while (red_mask) { red_mask >>= 1; render_red_shift--; }
- while (green_mask) { green_mask >>= 1; render_green_shift--; }
- while (blue_mask) { blue_mask >>= 1; render_blue_shift--; }
- XFree(timage);
-}
-
-void pseudocolor_startup(void)
-{
- XColor icolors[256];
- int tr, tg, tb, n, r, g, b, i, incolors, ii;
- unsigned long dev;
- int cpc, _ncolors;
- g_message("Initializing PseudoColor RenderControl\n");
-
- /* determine the number of colors and the bits-per-color */
- pseudo_bpc = 2; /* XXX THIS SHOULD BE A USER OPTION */
- g_assert(pseudo_bpc >= 1);
- _ncolors = pseudo_ncolors();
-
- if (_ncolors > 1 << render_depth) {
- g_warning("PseudoRenderControl: Invalid colormap size. Resizing.\n");
- pseudo_bpc = 1 << (render_depth/3) >> 3;
- _ncolors = 1 << (pseudo_bpc * 3);
- }
-
- /* build a color cube */
- pseudo_colors = malloc(_ncolors * sizeof(XColor));
- cpc = 1 << pseudo_bpc; /* colors per channel */
-
- for (n = 0, r = 0; r < cpc; r++)
- for (g = 0; g < cpc; g++)
- for (b = 0; b < cpc; b++, n++) {
- tr = (int)(((float)(r)/(float)(cpc-1)) * 0xFF);
- tg = (int)(((float)(g)/(float)(cpc-1)) * 0xFF);
- tb = (int)(((float)(b)/(float)(cpc-1)) * 0xFF);
- pseudo_colors[n].red = tr | tr << 8;
- pseudo_colors[n].green = tg | tg << 8;
- pseudo_colors[n].blue = tb | tb << 8;
- pseudo_colors[n].flags = DoRed|DoGreen|DoBlue; /* used to track
- allocation */
- }
-
- /* allocate the colors */
- for (i = 0; i < _ncolors; i++)
- if (!XAllocColor(ob_display, render_colormap, &pseudo_colors[i]))
- pseudo_colors[i].flags = 0; /* mark it as unallocated */
-
- /* try allocate any colors that failed allocation above */
-
- /* get the allocated values from the X server (only the first 256 XXX why!?)
- */
- incolors = (((1 << render_depth) > 256) ? 256 : (1 << render_depth));
- for (i = 0; i < incolors; i++)
- icolors[i].pixel = i;
- XQueryColors(ob_display, render_colormap, icolors, incolors);
-
- /* try match unallocated ones */
- for (i = 0; i < _ncolors; i++) {
- if (!pseudo_colors[i].flags) { /* if it wasn't allocated... */
- unsigned long closest = 0xffffffff, close = 0;
- for (ii = 0; ii < incolors; ii++) {
- /* find deviations */
- r = (pseudo_colors[i].red - icolors[ii].red) & 0xff;
- g = (pseudo_colors[i].green - icolors[ii].green) & 0xff;
- b = (pseudo_colors[i].blue - icolors[ii].blue) & 0xff;
- /* find a weighted absolute deviation */
- dev = (r * r) + (g * g) + (b * b);
-
- if (dev < closest) {
- closest = dev;
- close = ii;
- }
- }
-
- pseudo_colors[i].red = icolors[close].red;
- pseudo_colors[i].green = icolors[close].green;
- pseudo_colors[i].blue = icolors[close].blue;
- pseudo_colors[i].pixel = icolors[close].pixel;
-
- /* try alloc this closest color, it had better succeed! */
- if (XAllocColor(ob_display, render_colormap, &pseudo_colors[i]))
- pseudo_colors[i].flags = DoRed|DoGreen|DoBlue; /* mark as alloced */
- else
- g_assert(FALSE); /* wtf has gone wrong, its already alloced for
- chissake! */
- }
- }
-}
-
-void x_paint(Window win, Appearance *l)
-{
- int i, transferred = 0, sw;
- pixel32 *source, *dest;
- Pixmap oldp;
- int x = l->area.x;
- int y = l->area.y;
- int w = l->area.width;
- int h = l->area.height;
- Rect tarea; /* area in which to draw textures */
-
- if (w <= 0 || h <= 0 || x+w <= 0 || y+h <= 0) return;
-
- g_assert(l->surface.type == Surface_Planar);
-
- oldp = l->pixmap; /* save to free after changing the visible pixmap */
- l->pixmap = XCreatePixmap(ob_display, ob_root, x+w, y+h, render_depth);
- g_assert(l->pixmap != None);
-
- if (l->xftdraw != NULL)
- XftDrawDestroy(l->xftdraw);
- l->xftdraw = XftDrawCreate(ob_display, l->pixmap, render_visual,
- render_colormap);
- g_assert(l->xftdraw != NULL);
-
- g_free(l->surface.data.planar.pixel_data);
- l->surface.data.planar.pixel_data = g_new(pixel32, w * h);
-
-
- if (l->surface.data.planar.grad == Background_ParentRelative) {
- sw = l->surface.data.planar.parent->area.width;
- source = l->surface.data.planar.parent->surface.data.planar.pixel_data
- + l->surface.data.planar.parentx
- + sw * l->surface.data.planar.parenty;
- dest = l->surface.data.planar.pixel_data;
- for (i = 0; i < h; i++, source += sw, dest += w) {
- memcpy(dest, source, w * sizeof(pixel32));
- }
- }
- else if (l->surface.data.planar.grad == Background_Solid)
- gradient_solid(l, x, y, w, h);
- else gradient_render(&l->surface, w, h);
-
- for (i = 0; i < l->textures; i++) {
- tarea = l->texture[i].position;
- if (l->surface.data.planar.grad != Background_ParentRelative) {
- if (l->surface.data.planar.relief != Flat) {
- switch (l->surface.data.planar.bevel) {
- case Bevel1:
- tarea.x += 1; tarea.y += 1;
- tarea.width -= 2; tarea.height -= 2;
- break;
- case Bevel2:
- tarea.x += 2; tarea.y += 2;
- tarea.width -= 4; tarea.height -= 4;
- break;
- }
- } else if (l->surface.data.planar.border) {
- tarea.x += 1; tarea.y += 1;
- tarea.width -= 2; tarea.height -= 2;
- }
- }
-
- switch (l->texture[i].type) {
- case Text:
- if (!transferred) {
- transferred = 1;
- if (l->surface.data.planar.grad != Background_Solid)
- pixel32_to_pixmap(l->surface.data.planar.pixel_data,
- l->pixmap,x,y,w,h);
- }
- if (l->xftdraw == NULL) {
- l->xftdraw = XftDrawCreate(ob_display, l->pixmap,
- render_visual, render_colormap);
- }
- font_draw(l->xftdraw, &l->texture[i].data.text,
- &tarea);
- break;
- case Bitmask:
- if (!transferred) {
- transferred = 1;
- if (l->surface.data.planar.grad != Background_Solid)
- pixel32_to_pixmap(l->surface.data.planar.pixel_data,
- l->pixmap,x,y,w,h);
- }
- if (l->texture[i].data.mask.color->gc == None)
- color_allocate_gc(l->texture[i].data.mask.color);
- mask_draw(l->pixmap, &l->texture[i].data.mask,
- &tarea);
- break;
- case RGBA:
- image_draw(l->surface.data.planar.pixel_data,
- &l->texture[i].data.rgba,
- &tarea, &l->area);
- break;
- }
- }
-
- if (!transferred) {
- transferred = 1;
- if (l->surface.data.planar.grad != Background_Solid)
- pixel32_to_pixmap(l->surface.data.planar.pixel_data, l->pixmap
- ,x,y,w,h);
- }
-
-
- XSetWindowBackgroundPixmap(ob_display, win, l->pixmap);
- XClearWindow(ob_display, win);
- if (oldp != None) XFreePixmap(ob_display, oldp);
-}
-
-void render_shutdown(void)
-{
-}
-
-Appearance *appearance_new(SurfaceType type, int numtex)
-{
- PlanarSurface *p;
- Appearance *out;
-
- out = g_new(Appearance, 1);
- out->surface.type = type;
- out->textures = numtex;
- out->xftdraw = NULL;
- if (numtex) out->texture = g_new0(Texture, numtex);
- else out->texture = NULL;
- out->pixmap = None;
-
- switch (type) {
- case Surface_Planar:
- p = &out->surface.data.planar;
- p->primary = NULL;
- p->secondary = NULL;
- p->border_color = NULL;
- p->bevel_dark = NULL;
- p->bevel_light = NULL;
- p->pixel_data = NULL;
- break;
- }
- return out;
-}
-
-Appearance *appearance_copy(Appearance *orig)
-{
- PlanarSurface *spo, *spc;
- Appearance *copy = g_new(Appearance, 1);
- copy->surface.type = orig->surface.type;
- switch (orig->surface.type) {
- case Surface_Planar:
- spo = &(orig->surface.data.planar);
- spc = &(copy->surface.data.planar);
- spc->grad = spo->grad;
- spc->relief = spo->relief;
- spc->bevel = spo->bevel;
- if (spo->primary != NULL)
- spc->primary = color_new(spo->primary->r,
- spo->primary->g,
- spo->primary->b);
- else spc->primary = NULL;
-
- if (spo->secondary != NULL)
- spc->secondary = color_new(spo->secondary->r,
- spo->secondary->g,
- spo->secondary->b);
- else spc->secondary = NULL;
-
- if (spo->border_color != NULL)
- spc->border_color = color_new(spo->border_color->r,
- spo->border_color->g,
- spo->border_color->b);
- else spc->border_color = NULL;
-
- if (spo->bevel_dark != NULL)
- spc->bevel_dark = color_new(spo->bevel_dark->r,
- spo->bevel_dark->g,
- spo->bevel_dark->b);
- else spc->bevel_dark = NULL;
-
- if (spo->bevel_light != NULL)
- spc->bevel_light = color_new(spo->bevel_light->r,
- spo->bevel_light->g,
- spo->bevel_light->b);
- else spc->bevel_light = NULL;
-
- spc->interlaced = spo->interlaced;
- spc->border = spo->border;
- spc->pixel_data = NULL;
- break;
- }
- copy->textures = orig->textures;
- copy->texture = g_memdup(orig->texture, orig->textures * sizeof(Texture));
- copy->pixmap = None;
- copy->xftdraw = NULL;
- return copy;
-}
-
-void appearance_free(Appearance *a)
-{
- if (a) {
- PlanarSurface *p;
- if (a->pixmap != None) XFreePixmap(ob_display, a->pixmap);
- if (a->xftdraw != NULL) XftDrawDestroy(a->xftdraw);
- if (a->textures)
- g_free(a->texture);
- if (a->surface.type == Surface_Planar) {
- p = &a->surface.data.planar;
- color_free(p->primary);
- color_free(p->secondary);
- color_free(p->border_color);
- color_free(p->bevel_dark);
- color_free(p->bevel_light);
- g_free(p->pixel_data);
- }
- g_free(a);
- }
-}
-
-
-void pixel32_to_pixmap(pixel32 *in, Pixmap out, int x, int y, int w, int h)
-{
- pixel32 *scratch;
- XImage *im = NULL;
- im = XCreateImage(ob_display, render_visual, render_depth,
- ZPixmap, 0, NULL, w, h, 32, 0);
- g_assert(im != NULL);
- im->byte_order = render_endian;
-/* this malloc is a complete waste of time on normal 32bpp
- as reduce_depth just sets im->data = data and returns
-*/
- scratch = g_new(pixel32, im->width * im->height);
- im->data = (char*) scratch;
- reduce_depth(in, im);
- XPutImage(ob_display, out, DefaultGC(ob_display, ob_screen),
- im, 0, 0, x, y, w, h);
- im->data = NULL;
- XDestroyImage(im);
- g_free(scratch);
-}
-
-void appearance_minsize(Appearance *l, int *w, int *h)
-{
- int i;
- int m;
- *w = *h = 1;
-
- switch (l->surface.type) {
- case Surface_Planar:
- if (l->surface.data.planar.relief != Flat) {
- switch (l->surface.data.planar.bevel) {
- case Bevel1:
- *w = *h = 2;
- break;
- case Bevel2:
- *w = *h = 4;
- break;
- }
- } else if (l->surface.data.planar.border)
- *w = *h = 2;
-
- for (i = 0; i < l->textures; ++i) {
- switch (l->texture[i].type) {
- case Bitmask:
- *w += l->texture[i].data.mask.mask->w;
- *h += l->texture[i].data.mask.mask->h;
- break;
- case Text:
- m = font_measure_string(l->texture[i].data.text.font,
- l->texture[i].data.text.string,
- l->texture[i].data.text.shadow,
- l->texture[i].data.text.offset);
- *w += m;
- m = font_height(l->texture[i].data.text.font,
- l->texture[i].data.text.shadow,
- l->texture[i].data.text.offset);
- *h += m;
- break;
- case RGBA:
- *w += l->texture[i].data.rgba.width;
- *h += l->texture[i].data.rgba.height;
- break;
- case NoTexture:
- break;
- }
- }
- break;
- }
-}
-
-gboolean render_pixmap_to_rgba(Pixmap pmap, Pixmap mask,
- int *w, int *h, pixel32 **data)
-{
- Window xr;
- int xx, xy;
- guint pw, ph, mw, mh, xb, xd, i, x, y, di;
- XImage *xi, *xm = NULL;
-
- if (!XGetGeometry(ob_display, pmap, &xr, &xx, &xy, &pw, &ph, &xb, &xd))
- return FALSE;
- if (mask) {
- if (!XGetGeometry(ob_display, mask, &xr, &xx, &xy, &mw, &mh, &xb, &xd))
- return FALSE;
- if (pw != mw || ph != mh || xd != 1)
- return FALSE;
- }
-
- xi = XGetImage(ob_display, pmap, 0, 0, pw, ph, 0xffffffff, ZPixmap);
- if (!xi)
- return FALSE;
-
- if (mask) {
- xm = XGetImage(ob_display, mask, 0, 0, mw, mh, 0xffffffff, ZPixmap);
- if (!xm)
- return FALSE;
- }
-
- *data = g_new(pixel32, pw * ph);
- increase_depth(*data, xi);
-
- if (mask) {
- /* apply transparency from the mask */
- di = 0;
- for (i = 0, y = 0; y < ph; ++y) {
- for (x = 0; x < pw; ++x, ++i) {
- if (!((((unsigned)xm->data[di + x / 8]) >> (x % 8)) & 0x1))
- (*data)[i] &= ~(0xff << default_alpha_offset);
- }
- di += xm->bytes_per_line;
- }
- }
-
- *w = pw;
- *h = ph;
-
- return TRUE;
-}
-
-#ifdef USE_GL
-void gl_paint(Window win, Appearance *l)
-{
- int err;
- Window root, child;
- int i, transferred = 0, sw, b, d;
- pixel32 *source, *dest;
- Pixmap oldp;
- int tempx, tempy, absx, absy, absw, absh;
- int x = l->area.x;
- int y = l->area.y;
- int w = l->area.width;
- int h = l->area.height;
- Rect tarea; /* area in which to draw textures */
- if (w <= 0 || h <= 0 || x+w <= 0 || y+h <= 0) return;
-
- g_assert(l->surface.type == Surface_Planar);
-
-printf("making %p, %p, %p current\n", ob_display, win, render_glx_context);
- err = glXMakeCurrent(ob_display, win, render_glx_context);
-g_assert(err != 0);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, 1376, 1032, 0, 0, 10);
- if (XGetGeometry(ob_display, win, &root, &tempx, &tempy,
- &absw, &absh, &b, &d) &&
- XTranslateCoordinates(ob_display, win, root, tempx, tempy,
- &absx, &absy, &child))
- printf("window at %d, %d (%d,%d)\n", absx, absy, absw, absh);
- else
- return;
-
- glViewport(0, 0, 1376, 1032);
- glMatrixMode(GL_MODELVIEW);
- glTranslatef(-absx, 1032-absh-absy, 0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-
- if (l->surface.data.planar.grad == Background_ParentRelative) {
- printf("crap\n");
- } else
- render_gl_gradient(&l->surface, absx+x, absy+y, absw, absh);
-
- glXSwapBuffers(ob_display, win);
-}
-
-#endif /* USE_GL */
+++ /dev/null
-#ifndef __render_h
-#define __render_h
-
-#include <X11/Xlib.h>
-#define _XFT_NO_COMPAT_ /* no Xft 1 API */
-#include <X11/Xft/Xft.h>
-#include <glib.h>
-#include "color.h"
-#include "kernel/geom.h"
-
-typedef enum {
- Surface_Planar,
- Surface_Nonplanar
-} SurfaceType;
-
-typedef enum {
- Flat,
- Raised,
- Sunken
-} ReliefType;
-
-typedef enum {
- Bevel1,
- Bevel2
-} BevelType;
-
-typedef enum {
- Background_ParentRelative,
- Background_Solid,
- Background_Horizontal,
- Background_Vertical,
- Background_Diagonal,
- Background_CrossDiagonal,
- Background_PipeCross,
- Background_Rectangle,
- Background_Pyramid
-} SurfaceColorType;
-
-typedef enum {
- Bitmask,
- Text,
- RGBA,
- NoTexture
-} TextureType;
-
-struct Appearance;
-
-typedef struct PlanarSurface {
- SurfaceColorType grad;
- ReliefType relief;
- BevelType bevel;
- color_rgb *primary;
- color_rgb *secondary;
- color_rgb *border_color;
- color_rgb *bevel_dark;
- color_rgb *bevel_light;
- gboolean interlaced;
- gboolean border;
- struct Appearance *parent;
- int parentx;
- int parenty;
- pixel32 *pixel_data;
-} PlanarSurface;
-
-typedef struct NonplanarSurface {
- int poo;
-} NonplanarSurface;
-
-typedef union {
- PlanarSurface planar;
- NonplanarSurface nonplanar;
-} SurfaceData;
-
-typedef struct Surface {
- SurfaceType type;
- SurfaceColorType colortype;
- SurfaceData data;
-} Surface;
-
-typedef struct {
- XftFont *xftfont;
- int height;
- int elipses_length;
-} ObFont;
-
-typedef enum {
- Justify_Center,
- Justify_Left,
- Justify_Right
-} Justify;
-
-typedef struct TextureText {
- ObFont *font;
- Justify justify;
- int shadow;
- char tint;
- unsigned char offset;
- color_rgb *color;
- char *string;
-} TextureText;
-
-typedef struct {
- Pixmap mask;
- guint w, h;
- char *data;
-} pixmap_mask;
-
-typedef struct TextureMask {
- color_rgb *color;
- pixmap_mask *mask;
-} TextureMask;
-
-typedef struct TextureRGBA {
- guint width;
- guint height;
- pixel32 *data;
-/* cached scaled so we don't have to scale often */
- guint cwidth;
- guint cheight;
- pixel32 *cache;
-} TextureRGBA;
-
-typedef union {
- TextureRGBA rgba;
- TextureText text;
- TextureMask mask;
-} TextureData;
-
-typedef struct Texture {
- Rect position;
- TextureType type;
- TextureData data;
-} Texture;
-
-typedef struct Appearance {
- Surface surface;
- Rect area;
- int textures;
- Texture *texture;
- Pixmap pixmap;
- XftDraw *xftdraw;
-} Appearance;
-
-extern Visual *render_visual;
-extern XVisualInfo render_visual_info;
-extern int render_depth;
-extern Colormap render_colormap;
-
-void (*paint)(Window win, Appearance *l);
-
-void render_startup(void);
-void init_appearance(Appearance *l);
-void x_paint(Window win, Appearance *l);
-void gl_paint(Window win, Appearance *l);
-void render_shutdown(void);
-Appearance *appearance_new(SurfaceType type, int numtex);
-Appearance *appearance_copy(Appearance *a);
-void appearance_free(Appearance *a);
-void truecolor_startup(void);
-void pseudocolor_startup(void);
-void pixel32_to_pixmap(pixel32 *in, Pixmap out, int x, int y, int w, int h);
-
-void appearance_minsize(Appearance *l, int *w, int *h);
-
-gboolean render_pixmap_to_rgba(Pixmap pmap, Pixmap mask,
- int *w, int *h, pixel32 **data);
-
-#endif /*__render_h*/
+++ /dev/null
-#include <stdio.h>
-#include <X11/Xlib.h>
-#include <X11/extensions/shape.h>
-#include <string.h>
-#include <stdlib.h>
-#include "render.h"
-#include <glib.h>
-
-static int x_error_handler(Display * disp, XErrorEvent * error)
-{
- char buf[1024];
- XGetErrorText(disp, error->error_code, buf, 1024);
- printf("%s\n", buf);
- return 0;
-}
-
-Display *ob_display;
-int ob_screen;
-Window ob_root;
-
-int main()
-{
- Window win;
- GC gc;
- Pixmap pm;
- Appearance *look;
-
- int grabbed = 0;
- Window root;
- XGCValues values;
- XEvent report;
- int h = 500, w = 500, tmp;
- XVisualInfo *vi;
- int i;
-
- ob_display = XOpenDisplay(NULL);
- XSetErrorHandler(x_error_handler);
- ob_screen = DefaultScreen(ob_display);
- ob_root = RootWindow(ob_display, ob_screen);
- win =
- XCreateWindow(ob_display, RootWindow(ob_display, 0)
- , 10, 10, w, h, 10,
- CopyFromParent, /* depth */
- CopyFromParent, /* class */
- CopyFromParent, /* visual */
- 0, /* valuemask */
- 0); /* attributes */
- XMapWindow(ob_display, win);
- XSelectInput(ob_display, win, ExposureMask | StructureNotifyMask);
- root = RootWindow (ob_display, DefaultScreen (ob_display));
- render_startup();
-
- look = appearance_new(Surface_Planar, 0);
- look->surface.data.planar.grad = Background_Pyramid;
- look->surface.data.planar.secondary = color_parse("Yellow");
- look->surface.data.planar.primary = color_parse("Blue");
- look->surface.data.planar.interlaced = FALSE;
- look->area.x = 0;
- look->area.y = 0;
- look->area.width = 500;
- look->area.height = 500;
- if (ob_display == NULL) {
- fprintf(stderr, "couldn't connect to X server :0\n");
- return 0;
- }
-
- paint(win, look);
- while (1) {
- XNextEvent(ob_display, &report);
- switch (report.type) {
- case Expose:
- break;
- case ConfigureNotify:
- look->area.width = report.xconfigure.width;
- look->area.height = report.xconfigure.height;
- paint(win, look);
- break;
- }
-
- }
-
- return 1;
-}
+++ /dev/null
-#include "render.h"
-#include "color.h"
-#include "font.h"
-#include "mask.h"
-
-#include <X11/Xlib.h>
-#include <X11/Xresource.h>
-
-/* style settings - geometry */
-int theme_bevel;
-int theme_handle_height;
-int theme_bwidth;
-int theme_cbwidth;
-/* style settings - colors */
-color_rgb *theme_b_color;
-color_rgb *theme_cb_focused_color;
-color_rgb *theme_cb_unfocused_color;
-color_rgb *theme_title_focused_color;
-color_rgb *theme_title_unfocused_color;
-color_rgb *theme_titlebut_focused_color;
-color_rgb *theme_titlebut_unfocused_color;
-color_rgb *theme_menu_title_color;
-color_rgb *theme_menu_color;
-color_rgb *theme_menu_disabled_color;
-color_rgb *theme_menu_hilite_color;
-/* style settings - fonts */
-int theme_winfont_height;
-ObFont *theme_winfont;
-gboolean theme_winfont_shadow;
-int theme_winfont_shadow_offset;
-int theme_winfont_shadow_tint;
-int theme_mtitlefont_height;
-ObFont *theme_mtitlefont;
-gboolean theme_mtitlefont_shadow;
-int theme_mtitlefont_shadow_offset;
-int theme_mtitlefont_shadow_tint;
-int theme_mfont_height;
-ObFont *theme_mfont;
-gboolean theme_mfont_shadow;
-int theme_mfont_shadow_offset;
-int theme_mfont_shadow_tint;
-/* style settings - title layout */
-char *theme_title_layout;
-/* style settings - masks */
-pixmap_mask *theme_max_set_mask;
-pixmap_mask *theme_max_unset_mask;
-pixmap_mask *theme_iconify_mask;
-pixmap_mask *theme_desk_set_mask;
-pixmap_mask *theme_desk_unset_mask;
-pixmap_mask *theme_shade_set_mask;
-pixmap_mask *theme_shade_unset_mask;
-pixmap_mask *theme_close_mask;
-
-/* global appearances */
-Appearance *theme_a_focused_unpressed_max;
-Appearance *theme_a_focused_pressed_max;
-Appearance *theme_a_focused_pressed_set_max;
-Appearance *theme_a_unfocused_unpressed_max;
-Appearance *theme_a_unfocused_pressed_max;
-Appearance *theme_a_unfocused_pressed_set_max;
-Appearance *theme_a_focused_unpressed_close;
-Appearance *theme_a_focused_pressed_close;
-Appearance *theme_a_unfocused_unpressed_close;
-Appearance *theme_a_unfocused_pressed_close;
-Appearance *theme_a_focused_unpressed_desk;
-Appearance *theme_a_focused_pressed_desk;
-Appearance *theme_a_focused_pressed_set_desk;
-Appearance *theme_a_unfocused_unpressed_desk;
-Appearance *theme_a_unfocused_pressed_desk;
-Appearance *theme_a_unfocused_pressed_set_desk;
-Appearance *theme_a_focused_unpressed_shade;
-Appearance *theme_a_focused_pressed_shade;
-Appearance *theme_a_focused_pressed_set_shade;
-Appearance *theme_a_unfocused_unpressed_shade;
-Appearance *theme_a_unfocused_pressed_shade;
-Appearance *theme_a_unfocused_pressed_set_shade;
-Appearance *theme_a_focused_unpressed_iconify;
-Appearance *theme_a_focused_pressed_iconify;
-Appearance *theme_a_unfocused_unpressed_iconify;
-Appearance *theme_a_unfocused_pressed_iconify;
-Appearance *theme_a_focused_grip;
-Appearance *theme_a_unfocused_grip;
-Appearance *theme_a_focused_title;
-Appearance *theme_a_unfocused_title;
-Appearance *theme_a_focused_label;
-Appearance *theme_a_unfocused_label;
-Appearance *theme_a_icon; /* always parentrelative, so no focused/unfocused */
-Appearance *theme_a_focused_handle;
-Appearance *theme_a_unfocused_handle;
-Appearance *theme_a_menu_title;
-Appearance *theme_a_menu;
-Appearance *theme_a_menu_item;
-Appearance *theme_a_menu_disabled;
-Appearance *theme_a_menu_hilite;
-
-Appearance *theme_app_hilite_bg;
-Appearance *theme_app_unhilite_bg;
-Appearance *theme_app_hilite_label;
-Appearance *theme_app_unhilite_label;
-Appearance *theme_app_icon;
-
-void theme_startup()
-{
- theme_b_color = theme_cb_unfocused_color = theme_cb_focused_color =
- theme_title_unfocused_color = theme_title_focused_color =
- theme_titlebut_unfocused_color = theme_titlebut_focused_color =
- theme_menu_color = theme_menu_title_color = theme_menu_disabled_color =
- theme_menu_hilite_color = NULL;
- theme_winfont = theme_mtitlefont = theme_mfont = NULL;
- theme_title_layout = NULL;
- theme_max_set_mask = theme_max_unset_mask = NULL;
- theme_desk_set_mask = theme_desk_unset_mask = NULL;
- theme_shade_set_mask = theme_shade_unset_mask = NULL;
- theme_iconify_mask = theme_close_mask = NULL;
-
- theme_a_focused_unpressed_max = appearance_new(Surface_Planar, 1);
- theme_a_focused_pressed_max = appearance_new(Surface_Planar, 1);
- theme_a_focused_pressed_set_max = appearance_new(Surface_Planar, 1);
- theme_a_unfocused_unpressed_max = appearance_new(Surface_Planar, 1);
- theme_a_unfocused_pressed_max = appearance_new(Surface_Planar, 1);
- theme_a_unfocused_pressed_set_max = appearance_new(Surface_Planar, 1);
- theme_a_focused_unpressed_close = NULL;
- theme_a_focused_pressed_close = NULL;
- theme_a_unfocused_unpressed_close = NULL;
- theme_a_unfocused_pressed_close = NULL;
- theme_a_focused_unpressed_desk = NULL;
- theme_a_focused_pressed_desk = NULL;
- theme_a_focused_pressed_set_desk = NULL;
- theme_a_unfocused_unpressed_desk = NULL;
- theme_a_unfocused_pressed_desk = NULL;
- theme_a_unfocused_pressed_set_desk = NULL;
- theme_a_focused_unpressed_shade = NULL;
- theme_a_focused_pressed_shade = NULL;
- theme_a_focused_pressed_set_shade = NULL;
- theme_a_unfocused_unpressed_shade = NULL;
- theme_a_unfocused_pressed_shade = NULL;
- theme_a_unfocused_pressed_set_shade = NULL;
- theme_a_focused_unpressed_iconify = NULL;
- theme_a_focused_pressed_iconify = NULL;
- theme_a_unfocused_unpressed_iconify = NULL;
- theme_a_unfocused_pressed_iconify = NULL;
- theme_a_focused_grip = appearance_new(Surface_Planar, 0);
- theme_a_unfocused_grip = appearance_new(Surface_Planar, 0);
- theme_a_focused_title = appearance_new(Surface_Planar, 0);
- theme_a_unfocused_title = appearance_new(Surface_Planar, 0);
- theme_a_focused_label = appearance_new(Surface_Planar, 1);
- theme_a_unfocused_label = appearance_new(Surface_Planar, 1);
- theme_a_icon = appearance_new(Surface_Planar, 1);
- theme_a_focused_handle = appearance_new(Surface_Planar, 0);
- theme_a_unfocused_handle = appearance_new(Surface_Planar, 0);
- theme_a_menu = appearance_new(Surface_Planar, 0);
- theme_a_menu_title = appearance_new(Surface_Planar, 1);
- theme_a_menu_item = appearance_new(Surface_Planar, 1);
- theme_a_menu_disabled = appearance_new(Surface_Planar, 1);
- theme_a_menu_hilite = appearance_new(Surface_Planar, 1);
-
- theme_app_hilite_bg = appearance_new(Surface_Planar, 0);
- theme_app_unhilite_bg = appearance_new(Surface_Planar, 0);
- theme_app_hilite_label = appearance_new(Surface_Planar, 1);
- theme_app_unhilite_label = appearance_new(Surface_Planar, 1);
- theme_app_icon = appearance_new(Surface_Planar, 1);
-
-}
-
-void theme_shutdown()
-{
- color_free(theme_b_color);
- color_free(theme_cb_unfocused_color);
- color_free(theme_cb_focused_color);
- color_free(theme_title_unfocused_color);
- color_free(theme_title_focused_color);
- color_free(theme_titlebut_unfocused_color);
- color_free(theme_titlebut_focused_color);
- color_free(theme_menu_color);
- color_free(theme_menu_title_color);
- color_free(theme_menu_disabled_color);
- color_free(theme_menu_hilite_color);
-
- pixmap_mask_free(theme_max_set_mask);
- pixmap_mask_free(theme_max_unset_mask);
- pixmap_mask_free(theme_desk_set_mask);
- pixmap_mask_free(theme_desk_unset_mask);
- pixmap_mask_free(theme_shade_set_mask);
- pixmap_mask_free(theme_shade_unset_mask);
- pixmap_mask_free(theme_iconify_mask);
- pixmap_mask_free(theme_close_mask);
-
- font_close(theme_winfont);
- font_close(theme_mtitlefont);
- font_close(theme_mfont);
-
- g_free(theme_title_layout);
-
- appearance_free(theme_a_focused_unpressed_max);
- appearance_free(theme_a_focused_pressed_max);
- appearance_free(theme_a_focused_pressed_set_max);
- appearance_free(theme_a_unfocused_unpressed_max);
- appearance_free(theme_a_unfocused_pressed_max);
- appearance_free(theme_a_unfocused_pressed_set_max);
- appearance_free(theme_a_focused_unpressed_close);
- appearance_free(theme_a_focused_pressed_close);
- appearance_free(theme_a_unfocused_unpressed_close);
- appearance_free(theme_a_unfocused_pressed_close);
- appearance_free(theme_a_focused_unpressed_desk);
- appearance_free(theme_a_focused_pressed_desk);
- appearance_free(theme_a_unfocused_unpressed_desk);
- appearance_free(theme_a_unfocused_pressed_desk);
- appearance_free(theme_a_focused_unpressed_shade);
- appearance_free(theme_a_focused_pressed_shade);
- appearance_free(theme_a_unfocused_unpressed_shade);
- appearance_free(theme_a_unfocused_pressed_shade);
- appearance_free(theme_a_focused_unpressed_iconify);
- appearance_free(theme_a_focused_pressed_iconify);
- appearance_free(theme_a_unfocused_unpressed_iconify);
- appearance_free(theme_a_unfocused_pressed_iconify);
- appearance_free(theme_a_focused_grip);
- appearance_free(theme_a_unfocused_grip);
- appearance_free(theme_a_focused_title);
- appearance_free(theme_a_unfocused_title);
- appearance_free(theme_a_focused_label);
- appearance_free(theme_a_unfocused_label);
- appearance_free(theme_a_icon);
- appearance_free(theme_a_focused_handle);
- appearance_free(theme_a_unfocused_handle);
- appearance_free(theme_a_menu);
- appearance_free(theme_a_menu_title);
- appearance_free(theme_a_menu_item);
- appearance_free(theme_a_menu_disabled);
- appearance_free(theme_a_menu_hilite);
- appearance_free(theme_app_hilite_bg);
- appearance_free(theme_app_unhilite_bg);
- appearance_free(theme_app_hilite_label);
- appearance_free(theme_app_unhilite_label);
- appearance_free(theme_app_icon);
-}
-
-static XrmDatabase loaddb(char *theme)
-{
- XrmDatabase db;
-
- db = XrmGetFileDatabase(theme);
- if (db == NULL) {
- char *s = g_build_filename(g_get_home_dir(), ".openbox", "themes",
- theme, NULL);
- db = XrmGetFileDatabase(s);
- g_free(s);
- }
- if (db == NULL) {
- char *s = g_build_filename(THEMEDIR, theme, NULL);
- db = XrmGetFileDatabase(s);
- g_free(s);
- }
- return db;
-}
-
-static char *create_class_name(char *rname)
-{
- char *rclass = g_strdup(rname);
- char *p = rclass;
-
- while (TRUE) {
- *p = toupper(*p);
- p = strchr(p+1, '.');
- if (p == NULL) break;
- ++p;
- if (*p == '\0') break;
- }
- return rclass;
-}
-
-static gboolean read_int(XrmDatabase db, char *rname, int *value)
-{
- gboolean ret = FALSE;
- char *rclass = create_class_name(rname);
- char *rettype, *end;
- XrmValue retvalue;
-
- if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
- retvalue.addr != NULL) {
- *value = (int)strtol(retvalue.addr, &end, 10);
- if (end != retvalue.addr)
- ret = TRUE;
- }
-
- g_free(rclass);
- return ret;
-}
-
-static gboolean read_string(XrmDatabase db, char *rname, char **value)
-{
- gboolean ret = FALSE;
- char *rclass = create_class_name(rname);
- char *rettype;
- XrmValue retvalue;
-
- if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
- retvalue.addr != NULL) {
- *value = g_strdup(retvalue.addr);
- ret = TRUE;
- }
-
- g_free(rclass);
- return ret;
-}
-
-static gboolean read_color(XrmDatabase db, char *rname, color_rgb **value)
-{
- gboolean ret = FALSE;
- char *rclass = create_class_name(rname);
- char *rettype;
- XrmValue retvalue;
-
- if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
- retvalue.addr != NULL) {
- color_rgb *c = color_parse(retvalue.addr);
- if (c != NULL) {
- *value = c;
- ret = TRUE;
- }
- }
-
- g_free(rclass);
- return ret;
-}
-
-static gboolean read_mask(XrmDatabase db, char *rname, char *theme,
- pixmap_mask **value)
-{
- gboolean ret = FALSE;
- char *rclass = create_class_name(rname);
- char *rettype;
- char *s;
- char *button_dir;
- XrmValue retvalue;
- int hx, hy; /* ignored */
- unsigned int w, h;
- unsigned char *b;
-
- if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
- retvalue.addr != NULL) {
-
- button_dir = g_strdup_printf("%s_data", theme);
-
- s = g_build_filename(g_get_home_dir(), ".openbox", "themes",
- button_dir, retvalue.addr, NULL);
-
- if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == BitmapSuccess)
- ret = TRUE;
- else {
- g_free(s);
- s = g_build_filename(THEMEDIR, button_dir, retvalue.addr, NULL);
-
- if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == BitmapSuccess)
- ret = TRUE;
- else {
- char *themename;
-
- g_free(s);
- themename = g_path_get_basename(theme);
- s = g_strdup_printf("%s/%s_data/%s", theme,
- themename, retvalue.addr);
- g_free(themename);
- if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) ==
- BitmapSuccess)
- ret = TRUE;
- else
- g_message("Unable to find bitmap '%s'", retvalue.addr);
- }
- }
-
- if (ret) {
- *value = pixmap_mask_new(w, h, (char*)b);
- XFree(b);
- }
-
- g_free(s);
- g_free(button_dir);
- }
-
- g_free(rclass);
- return ret;
-}
-
-static void parse_appearance(char *tex, SurfaceColorType *grad,
- ReliefType *relief, BevelType *bevel,
- gboolean *interlaced, gboolean *border)
-{
- char *t;
-
- /* convert to all lowercase */
- for (t = tex; *t != '\0'; ++t)
- *t = g_ascii_tolower(*t);
-
- if (strstr(tex, "parentrelative") != NULL) {
- *grad = Background_ParentRelative;
- } else {
- if (strstr(tex, "gradient") != NULL) {
- if (strstr(tex, "crossdiagonal") != NULL)
- *grad = Background_CrossDiagonal;
- else if (strstr(tex, "rectangle") != NULL)
- *grad = Background_Rectangle;
- else if (strstr(tex, "pyramid") != NULL)
- *grad = Background_Pyramid;
- else if (strstr(tex, "pipecross") != NULL)
- *grad = Background_PipeCross;
- else if (strstr(tex, "elliptic") != NULL)
- *grad = Background_Rectangle;
- else if (strstr(tex, "horizontal") != NULL)
- *grad = Background_Horizontal;
- else if (strstr(tex, "vertical") != NULL)
- *grad = Background_Vertical;
- else
- *grad = Background_Diagonal;
- } else {
- *grad = Background_Solid;
- }
-
- if (strstr(tex, "sunken") != NULL)
- *relief = Sunken;
- else if (strstr(tex, "flat") != NULL)
- *relief = Flat;
- else
- *relief = Raised;
-
- *border = FALSE;
- if (*relief == Flat) {
- if (strstr(tex, "border") != NULL)
- *border = TRUE;
- } else {
- if (strstr(tex, "bevel2") != NULL)
- *bevel = Bevel2;
- else
- *bevel = Bevel1;
- }
-
- if (strstr(tex, "interlaced") != NULL)
- *interlaced = TRUE;
- else
- *interlaced = FALSE;
- }
-}
-
-
-static gboolean read_appearance(XrmDatabase db, char *rname, Appearance *value)
-{
- gboolean ret = FALSE;
- char *rclass = create_class_name(rname), *cname, *ctoname, *bcname;
- char *rettype;
- XrmValue retvalue;
-
- cname = g_strconcat(rname, ".color", NULL);
- ctoname = g_strconcat(rname, ".colorTo", NULL);
- bcname = g_strconcat(rname, ".borderColor", NULL);
-
- if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
- retvalue.addr != NULL) {
- parse_appearance(retvalue.addr,
- &value->surface.data.planar.grad,
- &value->surface.data.planar.relief,
- &value->surface.data.planar.bevel,
- &value->surface.data.planar.interlaced,
- &value->surface.data.planar.border);
- if (!read_color(db, cname, &value->surface.data.planar.primary))
- value->surface.data.planar.primary = color_new(0, 0, 0);
- if (!read_color(db, ctoname, &value->surface.data.planar.secondary))
- value->surface.data.planar.secondary = color_new(0, 0, 0);
- if (value->surface.data.planar.border)
- if (!read_color(db, bcname,
- &value->surface.data.planar.border_color))
- value->surface.data.planar.border_color = color_new(0, 0, 0);
- ret = TRUE;
- }
-
- g_free(bcname);
- g_free(ctoname);
- g_free(cname);
- g_free(rclass);
- return ret;
-}
-
-static void set_default_appearance(Appearance *a)
-{
- a->surface.data.planar.grad = Background_Solid;
- a->surface.data.planar.relief = Flat;
- a->surface.data.planar.bevel = Bevel1;
- a->surface.data.planar.interlaced = FALSE;
- a->surface.data.planar.border = FALSE;
- a->surface.data.planar.primary = color_new(0, 0, 0);
- a->surface.data.planar.secondary = color_new(0, 0, 0);
-}
-
-char *theme_load(char *theme)
-{
- XrmDatabase db = NULL;
- char *loaded = NULL;
- Justify winjust, mtitlejust, mjust;
- char *str;
- char *font_str;
-
- if (theme) {
- db = loaddb(theme);
- if (db == NULL) {
- g_warning("Failed to load the theme '%s'", theme);
- g_message("Falling back to the default: '%s'", DEFAULT_THEME);
- } else
- loaded = g_strdup(theme);
- }
- if (db == NULL) {
- db = loaddb(DEFAULT_THEME);
- if (db == NULL) {
- g_warning("Failed to load the theme '%s'.", DEFAULT_THEME);
- return NULL;
- } else
- loaded = g_strdup(DEFAULT_THEME);
- }
-
- /* load the font stuff */
- font_str = "arial-8:bold";
-
- theme_winfont_shadow = FALSE;
- if (read_string(db, "window.xft.flags", &str)) {
- if (g_strrstr(str, "shadow"))
- theme_winfont_shadow = TRUE;
- g_free(str);
- }
-
- if (!read_int(db, "window.xft.shadow.offset",
- &theme_winfont_shadow_offset))
- theme_winfont_shadow_offset = 1;
- if (!read_int(db, "window.xft.shadow.tint",
- &theme_winfont_shadow_tint) ||
- theme_winfont_shadow_tint < 100 || theme_winfont_shadow_tint > 100)
- theme_winfont_shadow_tint = 25;
-
- theme_winfont = font_open(font_str);
- theme_winfont_height = font_height(theme_winfont, theme_winfont_shadow,
- theme_winfont_shadow_offset);
-
- winjust = Justify_Left;
- if (read_string(db, "window.justify", &str)) {
- if (!g_ascii_strcasecmp(str, "right"))
- winjust = Justify_Right;
- else if (!g_ascii_strcasecmp(str, "center"))
- winjust = Justify_Center;
- g_free(str);
- }
-
- font_str = "arial-10:bold";
-
- theme_mtitlefont_shadow = FALSE;
- if (read_string(db, "menu.title.xft.flags", &str)) {
- if (g_strrstr(str, "shadow"))
- theme_mtitlefont_shadow = TRUE;
- g_free(str);
- }
-
- if (!read_int(db, "menu.title.xft.shadow.offset",
- &theme_mtitlefont_shadow_offset))
- theme_mtitlefont_shadow_offset = 1;
- if (!read_int(db, "menu.title.xft.shadow.tint",
- &theme_mtitlefont_shadow_tint) ||
- theme_mtitlefont_shadow_tint < 100 ||
- theme_mtitlefont_shadow_tint > 100)
- theme_mtitlefont_shadow_tint = 25;
-
- theme_mtitlefont = font_open(font_str);
- theme_mtitlefont_height = font_height(theme_mtitlefont,
- theme_mtitlefont_shadow,
- theme_mtitlefont_shadow_offset);
-
- mtitlejust = Justify_Left;
- if (read_string(db, "menu.title.justify", &str)) {
- if (!g_ascii_strcasecmp(str, "right"))
- mtitlejust = Justify_Right;
- else if (!g_ascii_strcasecmp(str, "center"))
- mtitlejust = Justify_Center;
- g_free(str);
- }
-
- font_str = "arial-8";
-
- theme_mfont_shadow = FALSE;
- if (read_string(db, "menu.frame.xft.flags", &str)) {
- if (g_strrstr(str, "shadow"))
- theme_mfont_shadow = TRUE;
- g_free(str);
- }
-
- if (!read_int(db, "menu.frame.xft.shadow.offset",
- &theme_mfont_shadow_offset))
- theme_mfont_shadow_offset = 1;
- if (!read_int(db, "menu.frame.xft.shadow.tint",
- &theme_mfont_shadow_tint) ||
- theme_mfont_shadow_tint < 100 ||
- theme_mfont_shadow_tint > 100)
- theme_mfont_shadow_tint = 25;
-
- theme_mfont = font_open(font_str);
- theme_mfont_height = font_height(theme_mfont, theme_mfont_shadow,
- theme_mfont_shadow_offset);
-
- mjust = Justify_Left;
- if (read_string(db, "menu.frame.justify", &str)) {
- if (!g_ascii_strcasecmp(str, "right"))
- mjust = Justify_Right;
- else if (!g_ascii_strcasecmp(str, "center"))
- mjust = Justify_Center;
- g_free(str);
- }
-
- /* load the title layout */
- theme_title_layout = g_strdup("NLIMC");
-
- if (!read_int(db, "handleWidth", &theme_handle_height) ||
- theme_handle_height < 0 || theme_handle_height > 100)
- theme_handle_height = 6;
- if (!read_int(db, "bevelWidth", &theme_bevel) ||
- theme_bevel <= 0 || theme_bevel > 100) theme_bevel = 3;
- if (!read_int(db, "borderWidth", &theme_bwidth) ||
- theme_bwidth < 0 || theme_bwidth > 100) theme_bwidth = 1;
- if (!read_int(db, "frameWidth", &theme_cbwidth) ||
- theme_cbwidth < 0 || theme_cbwidth > 100) theme_cbwidth = theme_bevel;
-
- /* load colors */
- if (!read_color(db, "borderColor", &theme_b_color))
- theme_b_color = color_new(0, 0, 0);
- if (!read_color(db, "window.frame.focusColor", &theme_cb_focused_color))
- theme_cb_focused_color = color_new(0xff, 0xff, 0xff);
- if (!read_color(db, "window.frame.unfocusColor",&theme_cb_unfocused_color))
- theme_cb_unfocused_color = color_new(0xff, 0xff, 0xff);
- if (!read_color(db, "window.label.focus.textColor",
- &theme_title_focused_color))
- theme_title_focused_color = color_new(0x0, 0x0, 0x0);
- if (!read_color(db, "window.label.unfocus.textColor",
- &theme_title_unfocused_color))
- theme_title_unfocused_color = color_new(0xff, 0xff, 0xff);
- if (!read_color(db, "window.button.focus.picColor",
- &theme_titlebut_focused_color))
- theme_titlebut_focused_color = color_new(0, 0, 0);
- if (!read_color(db, "window.button.unfocus.picColor",
- &theme_titlebut_unfocused_color))
- theme_titlebut_unfocused_color = color_new(0xff, 0xff, 0xff);
- if (!read_color(db, "menu.title.textColor", &theme_menu_title_color))
- theme_menu_title_color = color_new(0, 0, 0);
- if (!read_color(db, "menu.frame.textColor", &theme_menu_color))
- theme_menu_color = color_new(0xff, 0xff, 0xff);
- if (!read_color(db, "menu.frame.disableColor", &theme_menu_disabled_color))
- theme_menu_disabled_color = color_new(0, 0, 0);
- if (!read_color(db, "menu.hilite.textColor", &theme_menu_hilite_color))
- theme_menu_hilite_color = color_new(0, 0, 0);
-
- if (read_mask(db, "window.button.max.mask", theme, &theme_max_unset_mask)){
- if (!read_mask(db, "window.button.max.toggled.mask", theme,
- &theme_max_set_mask)) {
- theme_max_set_mask = pixmap_mask_copy(theme_max_unset_mask);
- }
- } else {
- {
- char data[] = { 0x7f, 0x7f, 0x7f, 0x41, 0x41, 0x41, 0x7f };
- theme_max_unset_mask = pixmap_mask_new(7, 7, data);
- }
- {
- char data[] = { 0x7c, 0x44, 0x47, 0x47, 0x7f, 0x1f, 0x1f };
- theme_max_set_mask = pixmap_mask_new(7, 7, data);
- }
- }
-
- if (!read_mask(db, "window.button.icon.mask", theme,
- &theme_iconify_mask)) {
- char data[] = { 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f };
- theme_iconify_mask = pixmap_mask_new(7, 7, data);
- }
-
- if (read_mask(db, "window.button.stick.mask", theme,
- &theme_desk_unset_mask)) {
- if (!read_mask(db, "window.button.stick.toggled.mask", theme,
- &theme_desk_set_mask)) {
- theme_desk_set_mask =
- pixmap_mask_copy(theme_desk_unset_mask);
- }
- } else {
- {
- char data[] = { 0x63, 0x63, 0x00, 0x00, 0x00, 0x63, 0x63 };
- theme_desk_unset_mask = pixmap_mask_new(7, 7, data);
- }
- {
- char data[] = { 0x00, 0x36, 0x36, 0x08, 0x36, 0x36, 0x00 };
- theme_desk_set_mask = pixmap_mask_new(7, 7, data);
- }
- }
-
- if (read_mask(db, "window.button.shade.mask", theme,
- &theme_shade_unset_mask)) {
- if (!read_mask(db, "window.button.shade.toggled.mask", theme,
- &theme_shade_set_mask)) {
- theme_shade_set_mask =
- pixmap_mask_copy(theme_shade_unset_mask);
- }
- } else {
- {
- char data[] = { 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00 };
- theme_shade_unset_mask = pixmap_mask_new(7, 7, data);
- }
- {
- char data[] = { 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x7f };
- theme_shade_set_mask = pixmap_mask_new(7, 7, data);
- }
- }
-
- if (!read_mask(db, "window.button.close.mask", theme,
- &theme_close_mask)) {
- char data[] = { 0x63, 0x77, 0x3e, 0x1c, 0x3e, 0x77, 0x63 };
- theme_close_mask = pixmap_mask_new(7, 7, data);
- }
-
- /* read the decoration textures */
- if (!read_appearance(db, "window.title.focus", theme_a_focused_title))
- set_default_appearance(theme_a_focused_title);
- if (!read_appearance(db, "window.title.unfocus", theme_a_unfocused_title))
- set_default_appearance(theme_a_unfocused_title);
- if (!read_appearance(db, "window.label.focus", theme_a_focused_label))
- set_default_appearance(theme_a_focused_label);
- if (!read_appearance(db, "window.label.unfocus", theme_a_unfocused_label))
- set_default_appearance(theme_a_unfocused_label);
- if (!read_appearance(db, "window.handle.focus", theme_a_focused_handle))
- set_default_appearance(theme_a_focused_handle);
- if (!read_appearance(db, "window.handle.unfocus",theme_a_unfocused_handle))
- set_default_appearance(theme_a_unfocused_handle);
- if (!read_appearance(db, "window.grip.focus", theme_a_focused_grip))
- set_default_appearance(theme_a_focused_grip);
- if (!read_appearance(db, "window.grip.unfocus", theme_a_unfocused_grip))
- set_default_appearance(theme_a_unfocused_grip);
- if (!read_appearance(db, "menu.frame", theme_a_menu))
- set_default_appearance(theme_a_menu);
- if (!read_appearance(db, "menu.title", theme_a_menu_title))
- set_default_appearance(theme_a_menu_title);
- if (!read_appearance(db, "menu.hilite", theme_a_menu_hilite))
- set_default_appearance(theme_a_menu_hilite);
-
- /* read the appearances for rendering non-decorations */
- if (!read_appearance(db, "window.title.focus", theme_app_hilite_bg))
- set_default_appearance(theme_app_hilite_bg);
- if (!read_appearance(db, "window.label.focus", theme_app_hilite_label))
- set_default_appearance(theme_app_hilite_label);
- if (!read_appearance(db, "window.title.unfocus", theme_app_unhilite_bg))
- set_default_appearance(theme_app_unhilite_bg);
- if (!read_appearance(db, "window.label.unfocus", theme_app_unhilite_label))
- set_default_appearance(theme_app_unhilite_label);
-
- /* read buttons textures */
- if (!read_appearance(db, "window.button.pressed.focus",
- theme_a_focused_pressed_max))
- if (!read_appearance(db, "window.button.pressed",
- theme_a_focused_pressed_max))
- set_default_appearance(theme_a_focused_pressed_max);
- if (!read_appearance(db, "window.button.pressed.unfocus",
- theme_a_unfocused_pressed_max))
- if (!read_appearance(db, "window.button.pressed",
- theme_a_unfocused_pressed_max))
- set_default_appearance(theme_a_unfocused_pressed_max);
- if (!read_appearance(db, "window.button.focus",
- theme_a_focused_unpressed_max))
- set_default_appearance(theme_a_focused_unpressed_max);
- if (!read_appearance(db, "window.button.unfocus",
- theme_a_unfocused_unpressed_max))
- set_default_appearance(theme_a_unfocused_unpressed_max);
-
- theme_a_unfocused_unpressed_close =
- appearance_copy(theme_a_unfocused_unpressed_max);
- theme_a_unfocused_pressed_close =
- appearance_copy(theme_a_unfocused_pressed_max);
- theme_a_focused_unpressed_close =
- appearance_copy(theme_a_focused_unpressed_max);
- theme_a_focused_pressed_close =
- appearance_copy(theme_a_focused_pressed_max);
- theme_a_unfocused_unpressed_desk =
- appearance_copy(theme_a_unfocused_unpressed_max);
- theme_a_unfocused_pressed_desk =
- appearance_copy(theme_a_unfocused_pressed_max);
- theme_a_unfocused_pressed_set_desk =
- appearance_copy(theme_a_unfocused_pressed_max);
- theme_a_focused_unpressed_desk =
- appearance_copy(theme_a_focused_unpressed_max);
- theme_a_focused_pressed_desk =
- appearance_copy(theme_a_focused_pressed_max);
- theme_a_focused_pressed_set_desk =
- appearance_copy(theme_a_focused_pressed_max);
- theme_a_unfocused_unpressed_shade =
- appearance_copy(theme_a_unfocused_unpressed_max);
- theme_a_unfocused_pressed_shade =
- appearance_copy(theme_a_unfocused_pressed_max);
- theme_a_unfocused_pressed_set_shade =
- appearance_copy(theme_a_unfocused_pressed_max);
- theme_a_focused_unpressed_shade =
- appearance_copy(theme_a_focused_unpressed_max);
- theme_a_focused_pressed_shade =
- appearance_copy(theme_a_focused_pressed_max);
- theme_a_focused_pressed_set_shade =
- appearance_copy(theme_a_focused_pressed_max);
- theme_a_unfocused_unpressed_iconify =
- appearance_copy(theme_a_unfocused_unpressed_max);
- theme_a_unfocused_pressed_iconify =
- appearance_copy(theme_a_unfocused_pressed_max);
- theme_a_focused_unpressed_iconify =
- appearance_copy(theme_a_focused_unpressed_max);
- theme_a_focused_pressed_iconify =
- appearance_copy(theme_a_focused_pressed_max);
- theme_a_unfocused_pressed_set_max =
- appearance_copy(theme_a_unfocused_pressed_max);
- theme_a_focused_pressed_set_max =
- appearance_copy(theme_a_focused_pressed_max);
-
- theme_a_icon->surface.data.planar.grad = Background_ParentRelative;
-
- /* set up the textures */
- theme_a_focused_label->texture[0].type =
- theme_app_hilite_label->texture[0].type = Text;
- theme_a_focused_label->texture[0].data.text.justify = winjust;
- theme_app_hilite_label->texture[0].data.text.justify = Justify_Left;
- theme_a_focused_label->texture[0].data.text.font =
- theme_app_hilite_label->texture[0].data.text.font = theme_winfont;
- theme_a_focused_label->texture[0].data.text.shadow =
- theme_app_hilite_label->texture[0].data.text.shadow =
- theme_winfont_shadow;
- theme_a_focused_label->texture[0].data.text.offset =
- theme_app_hilite_label->texture[0].data.text.offset =
- theme_winfont_shadow_offset;
- theme_a_focused_label->texture[0].data.text.tint =
- theme_app_hilite_label->texture[0].data.text.tint =
- theme_winfont_shadow_tint;
- theme_a_focused_label->texture[0].data.text.color =
- theme_app_hilite_label->texture[0].data.text.color =
- theme_title_focused_color;
-
- theme_a_unfocused_label->texture[0].type =
- theme_app_unhilite_label->texture[0].type = Text;
- theme_a_unfocused_label->texture[0].data.text.justify = winjust;
- theme_app_unhilite_label->texture[0].data.text.justify = Justify_Left;
- theme_a_unfocused_label->texture[0].data.text.font =
- theme_app_unhilite_label->texture[0].data.text.font = theme_winfont;
- theme_a_unfocused_label->texture[0].data.text.shadow =
- theme_app_unhilite_label->texture[0].data.text.shadow =
- theme_winfont_shadow;
- theme_a_unfocused_label->texture[0].data.text.offset =
- theme_app_unhilite_label->texture[0].data.text.offset =
- theme_winfont_shadow_offset;
- theme_a_unfocused_label->texture[0].data.text.tint =
- theme_app_unhilite_label->texture[0].data.text.tint =
- theme_winfont_shadow_tint;
- theme_a_unfocused_label->texture[0].data.text.color =
- theme_app_unhilite_label->texture[0].data.text.color =
- theme_title_unfocused_color;
-
- theme_a_menu_title->texture[0].type = Text;
- theme_a_menu_title->texture[0].data.text.justify = mtitlejust;
- theme_a_menu_title->texture[0].data.text.font = theme_mtitlefont;
- theme_a_menu_title->texture[0].data.text.shadow = theme_mtitlefont_shadow;
- theme_a_menu_title->texture[0].data.text.offset =
- theme_mtitlefont_shadow_offset;
- theme_a_menu_title->texture[0].data.text.tint =
- theme_mtitlefont_shadow_tint;
- theme_a_menu_title->texture[0].data.text.color = theme_menu_title_color;
-
- theme_a_menu_item->surface.data.planar.grad =
- theme_a_menu_disabled->surface.data.planar.grad =
- theme_app_icon->surface.data.planar.grad =
- Background_ParentRelative;
-
- theme_a_menu_item->texture[0].type =
- theme_a_menu_disabled->texture[0].type =
- theme_a_menu_hilite->texture[0].type = Text;
- theme_a_menu_item->texture[0].data.text.justify =
- theme_a_menu_disabled->texture[0].data.text.justify =
- theme_a_menu_hilite->texture[0].data.text.justify = mjust;
- theme_a_menu_item->texture[0].data.text.font =
- theme_a_menu_disabled->texture[0].data.text.font =
- theme_a_menu_hilite->texture[0].data.text.font = theme_mfont;
- theme_a_menu_item->texture[0].data.text.shadow =
- theme_a_menu_disabled->texture[0].data.text.shadow =
- theme_a_menu_hilite->texture[0].data.text.shadow = theme_mfont_shadow;
- theme_a_menu_item->texture[0].data.text.offset =
- theme_a_menu_disabled->texture[0].data.text.offset =
- theme_a_menu_hilite->texture[0].data.text.offset =
- theme_mfont_shadow_offset;
- theme_a_menu_item->texture[0].data.text.tint =
- theme_a_menu_disabled->texture[0].data.text.tint =
- theme_a_menu_hilite->texture[0].data.text.tint =
- theme_mfont_shadow_tint;
- theme_a_menu_item->texture[0].data.text.color = theme_menu_color;
- theme_a_menu_disabled->texture[0].data.text.color =
- theme_menu_disabled_color;
- theme_a_menu_hilite->texture[0].data.text.color = theme_menu_hilite_color;
-
- theme_a_focused_unpressed_max->texture[0].type =
- theme_a_focused_pressed_max->texture[0].type =
- theme_a_focused_pressed_set_max->texture[0].type =
- theme_a_unfocused_unpressed_max->texture[0].type =
- theme_a_unfocused_pressed_max->texture[0].type =
- theme_a_unfocused_pressed_set_max->texture[0].type =
- theme_a_focused_unpressed_close->texture[0].type =
- theme_a_focused_pressed_close->texture[0].type =
- theme_a_unfocused_unpressed_close->texture[0].type =
- theme_a_unfocused_pressed_close->texture[0].type =
- theme_a_focused_unpressed_desk->texture[0].type =
- theme_a_focused_pressed_desk->texture[0].type =
- theme_a_focused_pressed_set_desk->texture[0].type =
- theme_a_unfocused_unpressed_desk->texture[0].type =
- theme_a_unfocused_pressed_desk->texture[0].type =
- theme_a_unfocused_pressed_set_desk->texture[0].type =
- theme_a_focused_unpressed_shade->texture[0].type =
- theme_a_focused_pressed_shade->texture[0].type =
- theme_a_focused_pressed_set_shade->texture[0].type =
- theme_a_unfocused_unpressed_shade->texture[0].type =
- theme_a_unfocused_pressed_shade->texture[0].type =
- theme_a_unfocused_pressed_set_shade->texture[0].type =
- theme_a_focused_unpressed_iconify->texture[0].type =
- theme_a_focused_pressed_iconify->texture[0].type =
- theme_a_unfocused_unpressed_iconify->texture[0].type =
- theme_a_unfocused_pressed_iconify->texture[0].type = Bitmask;
- theme_a_focused_unpressed_max->texture[0].data.mask.mask =
- theme_a_unfocused_unpressed_max->texture[0].data.mask.mask =
- theme_a_focused_pressed_max->texture[0].data.mask.mask =
- theme_a_unfocused_pressed_max->texture[0].data.mask.mask =
- theme_max_unset_mask;
- theme_a_focused_pressed_set_max->texture[0].data.mask.mask =
- theme_a_unfocused_pressed_set_max->texture[0].data.mask.mask =
- theme_max_set_mask;
- theme_a_focused_pressed_close->texture[0].data.mask.mask =
- theme_a_unfocused_pressed_close->texture[0].data.mask.mask =
- theme_a_focused_unpressed_close->texture[0].data.mask.mask =
- theme_a_unfocused_unpressed_close->texture[0].data.mask.mask =
- theme_close_mask;
- theme_a_focused_unpressed_desk->texture[0].data.mask.mask =
- theme_a_unfocused_unpressed_desk->texture[0].data.mask.mask =
- theme_a_focused_pressed_desk->texture[0].data.mask.mask =
- theme_a_unfocused_pressed_desk->texture[0].data.mask.mask =
- theme_desk_unset_mask;
- theme_a_focused_pressed_set_desk->texture[0].data.mask.mask =
- theme_a_unfocused_pressed_set_desk->texture[0].data.mask.mask =
- theme_desk_set_mask;
- theme_a_focused_unpressed_shade->texture[0].data.mask.mask =
- theme_a_unfocused_unpressed_shade->texture[0].data.mask.mask =
- theme_a_focused_pressed_shade->texture[0].data.mask.mask =
- theme_a_unfocused_pressed_shade->texture[0].data.mask.mask =
- theme_shade_unset_mask;
- theme_a_focused_pressed_set_shade->texture[0].data.mask.mask =
- theme_a_unfocused_pressed_set_shade->texture[0].data.mask.mask =
- theme_shade_set_mask;
- theme_a_focused_unpressed_iconify->texture[0].data.mask.mask =
- theme_a_unfocused_unpressed_iconify->texture[0].data.mask.mask =
- theme_a_focused_pressed_iconify->texture[0].data.mask.mask =
- theme_a_unfocused_pressed_iconify->texture[0].data.mask.mask =
- theme_iconify_mask;
- theme_a_focused_unpressed_max->texture[0].data.mask.color =
- theme_a_focused_pressed_max->texture[0].data.mask.color =
- theme_a_focused_pressed_set_max->texture[0].data.mask.color =
- theme_a_focused_unpressed_close->texture[0].data.mask.color =
- theme_a_focused_pressed_close->texture[0].data.mask.color =
- theme_a_focused_unpressed_desk->texture[0].data.mask.color =
- theme_a_focused_pressed_desk->texture[0].data.mask.color =
- theme_a_focused_pressed_set_desk->texture[0].data.mask.color =
- theme_a_focused_unpressed_shade->texture[0].data.mask.color =
- theme_a_focused_pressed_shade->texture[0].data.mask.color =
- theme_a_focused_pressed_set_shade->texture[0].data.mask.color =
- theme_a_focused_unpressed_iconify->texture[0].data.mask.color =
- theme_a_focused_pressed_iconify->texture[0].data.mask.color =
- theme_titlebut_focused_color;
- theme_a_unfocused_unpressed_max->texture[0].data.mask.color =
- theme_a_unfocused_pressed_max->texture[0].data.mask.color =
- theme_a_unfocused_pressed_set_max->texture[0].data.mask.color =
- theme_a_unfocused_unpressed_close->texture[0].data.mask.color =
- theme_a_unfocused_pressed_close->texture[0].data.mask.color =
- theme_a_unfocused_unpressed_desk->texture[0].data.mask.color =
- theme_a_unfocused_pressed_desk->texture[0].data.mask.color =
- theme_a_unfocused_pressed_set_desk->texture[0].data.mask.color =
- theme_a_unfocused_unpressed_shade->texture[0].data.mask.color =
- theme_a_unfocused_pressed_shade->texture[0].data.mask.color =
- theme_a_unfocused_pressed_set_shade->texture[0].data.mask.color =
- theme_a_unfocused_unpressed_iconify->texture[0].data.mask.color =
- theme_a_unfocused_pressed_iconify->texture[0].data.mask.color =
- theme_titlebut_unfocused_color;
-
- XrmDestroyDatabase(db);
-
- return loaded;
-}
+++ /dev/null
-#ifndef __theme_h
-#define __theme_h
-
-#include "render.h"
-#include "color.h"
-#include "font.h"
-#include "mask.h"
-
-extern int theme_bevel;
-extern int theme_handle_height;
-extern int theme_bwidth;
-extern int theme_cbwidth;
-
-#define theme_label_height (theme_winfont_height + 2)
-#define theme_title_height (theme_label_height + theme_bevel * 2)
-#define theme_button_size (theme_label_height - 2)
-#define theme_grip_width (theme_button_size * 2)
-
-extern color_rgb *theme_b_color;
-extern color_rgb *theme_cb_focused_color;
-extern color_rgb *theme_cb_unfocused_color;
-extern color_rgb *theme_title_focused_color;
-extern color_rgb *theme_title_unfocused_color;
-extern color_rgb *theme_titlebut_focused_color;
-extern color_rgb *theme_titlebut_unfocused_color;
-
-extern int theme_winfont_height;
-extern ObFont *theme_winfont;
-extern char *theme_title_layout;
-
-extern pixmap_mask *theme_max_set_mask;
-extern pixmap_mask *theme_max_unset_mask;
-extern pixmap_mask *theme_iconify_mask;
-extern pixmap_mask *theme_desk_set_mask;
-extern pixmap_mask *theme_desk_unset_mask;
-extern pixmap_mask *theme_shade_set_mask;
-extern pixmap_mask *theme_shade_unset_mask;
-extern pixmap_mask *theme_close_mask;
-
-extern Appearance *theme_a_focused_unpressed_max;
-extern Appearance *theme_a_focused_pressed_max;
-extern Appearance *theme_a_focused_pressed_set_max;
-extern Appearance *theme_a_unfocused_unpressed_max;
-extern Appearance *theme_a_unfocused_pressed_max;
-extern Appearance *theme_a_unfocused_pressed_set_max;
-extern Appearance *theme_a_focused_unpressed_close;
-extern Appearance *theme_a_focused_pressed_close;
-extern Appearance *theme_a_unfocused_unpressed_close;
-extern Appearance *theme_a_unfocused_pressed_close;
-extern Appearance *theme_a_focused_unpressed_desk;
-extern Appearance *theme_a_focused_pressed_desk;
-extern Appearance *theme_a_focused_pressed_set_desk;
-extern Appearance *theme_a_unfocused_unpressed_desk;
-extern Appearance *theme_a_unfocused_pressed_desk;
-extern Appearance *theme_a_unfocused_pressed_set_desk;
-extern Appearance *theme_a_focused_unpressed_shade;
-extern Appearance *theme_a_focused_pressed_shade;
-extern Appearance *theme_a_focused_pressed_set_shade;
-extern Appearance *theme_a_unfocused_unpressed_shade;
-extern Appearance *theme_a_unfocused_pressed_shade;
-extern Appearance *theme_a_unfocused_pressed_set_shade;
-extern Appearance *theme_a_focused_unpressed_iconify;
-extern Appearance *theme_a_focused_pressed_iconify;
-extern Appearance *theme_a_unfocused_unpressed_iconify;
-extern Appearance *theme_a_unfocused_pressed_iconify;
-extern Appearance *theme_a_focused_grip;
-extern Appearance *theme_a_unfocused_grip;
-extern Appearance *theme_a_focused_title;
-extern Appearance *theme_a_unfocused_title;
-extern Appearance *theme_a_focused_label;
-extern Appearance *theme_a_unfocused_label;
-extern Appearance *theme_a_icon;
-extern Appearance *theme_a_focused_handle;
-extern Appearance *theme_a_unfocused_handle;
-extern Appearance *theme_a_menu_title;
-extern Appearance *theme_a_menu;
-extern Appearance *theme_a_menu_item;
-extern Appearance *theme_a_menu_disabled;
-extern Appearance *theme_a_menu_hilite;
-
-extern Appearance *theme_app_hilite_bg;
-extern Appearance *theme_app_unhilite_bg;
-extern Appearance *theme_app_hilite_label;
-extern Appearance *theme_app_unhilite_label;
-extern Appearance *theme_app_icon;
-
-void theme_startup();
-void theme_shutdown();
-
-char *theme_load(char *theme);
-
-#endif
--- /dev/null
+rendertest
+librender.a
+.libs
+Makefile.in
+.deps
+Makefile
+libobrender2.la
+instance.lo
+init.lo
+debug.lo
+color.lo
+font.lo
+surface.lo
+paint.lo
+texture.lo
+planar.lo
--- /dev/null
+themedir=$(datadir)/openbox/themes
+
+theme=operation
+
+CPPFLAGS=$(FC_CFLAGS) $(GLIB_CFLAGS) $(GL_CFLAGS) @CPPFLAGS@ \
+ -DG_LOG_DOMAIN=\"Render\" \
+ -DDEFAULT_THEME=\"$(theme)\" \
+ -DTHEMEDIR=\"$(themedir)\"
+
+INCLUDES=-I..
+LIBS=$(GL_LIBS) $(GLIB_LIBS) $(X_LIBS) $(XSHAPE_LIBS) @LIBS@
+
+noinst_PROGRAMS=rendertest
+rendertest_LDFLAGS=-lobrender2 -L.
+rendertest_SOURCES=test.c
+
+lib_LTLIBRARIES=libobrender2.la
+libobrender2_la_LIBADD=-lglft -L../glft
+libobrender2_la_SOURCES=\
+ instance.c \
+ color.c \
+ debug.c \
+ font.c \
+ surface.c \
+ planar.c \
+ texture.c \
+ paint.c \
+ theme.c
+
+noinst_HEADERS=\
+ render.h \
+ instance.h \
+ debug.h \
+ surface.h \
+ planar.h \
+ texture.h \
+ color.h \
+ theme.h
+
+MAINTAINERCLEANFILES=Makefile.in
+
+distclean-local:
+ $(RM) *\~ *.orig *.rej .\#*
--- /dev/null
+#include "render.h"
+#include "instance.h"
+#include "debug.h"
+#include <X11/Xlib.h>
+
+int RrColorParse(struct RrInstance *inst, const char *colorname,
+ struct RrColor *ret)
+{
+ XColor xcol;
+
+ if (!XParseColor(RrDisplay(inst), RrColormap(inst), colorname, &xcol)) {
+ RrDebug("unable to parse color '%s'", colorname);
+ ret->r = 0.0;
+ ret->g = 0.0;
+ ret->b = 0.0;
+ ret->a = 0.0;
+ return 0;
+ }
+ ret->r = (xcol.red >> 8) / 255.0;
+ ret->g = (xcol.green >> 8) / 255.0;
+ ret->b = (xcol.blue >> 8) / 255.0;
+ ret->a = 0.0;
+ return 1;
+}
--- /dev/null
+#ifndef __render_color_h
+#define __render_color_h
+
+#include "render.h"
+
+#define RrColor3f(c) glColor3f((c)->r, (c)->g, (c)->b)
+#define RrColor4f(c) glColor4f((c)->r, (c)->g, (c)->b, (c)->a)
+
+#define RrColorAvg(avg, c1, c2) \
+ RrColorSet((avg), \
+ ((c1)->r + (c2)->r) / 2.0, \
+ ((c1)->g + (c2)->g) / 2.0, \
+ ((c1)->b + (c2)->b) / 2.0, \
+ ((c1)->a + (c2)->a) / 2.0)
+
+
+#endif
--- /dev/null
+#include <stdio.h>
+#include <stdarg.h>
+
+void RrDebug(char *a, ...)
+{
+#ifdef DEBUG
+ va_list vl;
+ va_start(vl, a);
+ vprintf(a, vl);
+#endif
+}
--- /dev/null
+#ifndef __render_debug_h
+#define __render_debug_h
+
+void RrDebug(char *a, ...);
+
+#endif
--- /dev/null
+#include "render.h"
+#include "instance.h"
+#include "font.h"
+#include <stdlib.h>
+
+struct RrFont *RrFontOpen(struct RrInstance *inst, const char *fontstring)
+{
+ struct RrFont *font;
+
+ font = malloc(sizeof(struct RrFont));
+ font->inst = inst;
+ font->font = GlftFontOpen(RrDisplay(inst), RrScreen(inst), fontstring);
+ return font;
+}
+
+void RrFontClose(struct RrFont *font)
+{
+ if (font) {
+ GlftFontClose(font->font);
+ free(font);
+ }
+}
+
+int RrFontMeasureString(struct RrFont *font, const char *string)
+{
+ return 20;
+}
+
+int RrFontHeight(struct RrFont *font)
+{
+ return GlftFontHeight(font->font);
+}
+
+int RrFontMaxCharWidth(struct RrFont *font)
+{
+ return 5;
+}
--- /dev/null
+#ifndef __render_font_h
+#define __render_font_h
+
+#include "glft/glft.h"
+
+struct RrInstance;
+
+struct RrFont {
+ struct RrInstance *inst;
+ struct GlftFont *font;
+};
+
+#endif
--- /dev/null
+#include "instance.h"
+#include "render.h"
+#include "debug.h"
+#include "glft/glft.h"
+
+static int glXRating(Display *display, XVisualInfo *v)
+{
+ int rating = 0;
+ int val;
+ RrDebug("evaluating visual %d\n", (int)v->visualid);
+ glXGetConfig(display, v, GLX_BUFFER_SIZE, &val);
+ RrDebug("buffer size %d\n", val);
+
+ switch (val) {
+ case 32:
+ rating += 300;
+ break;
+ case 24:
+ rating += 200;
+ break;
+ case 16:
+ rating += 100;
+ break;
+ }
+
+ glXGetConfig(display, v, GLX_LEVEL, &val);
+ RrDebug("level %d\n", val);
+ if (val != 0)
+ rating = -10000;
+
+ glXGetConfig(display, v, GLX_DEPTH_SIZE, &val);
+ RrDebug("depth size %d\n", val);
+ switch (val) {
+ case 32:
+ rating += 30;
+ break;
+ case 24:
+ rating += 20;
+ break;
+ case 16:
+ rating += 10;
+ break;
+ case 0:
+ rating -= 10000;
+ }
+
+ glXGetConfig(display, v, GLX_DOUBLEBUFFER, &val);
+ RrDebug("double buffer %d\n", val);
+ if (val)
+ rating++;
+ return rating;
+}
+
+struct RrInstance *RrInit(Display *display,
+ int screen)
+{
+ int count, i = 0, val, best = 0, rate = 0, temp;
+ XVisualInfo vimatch, *vilist;
+ struct RrInstance *ret = NULL;
+
+ vimatch.screen = screen;
+ vimatch.class = TrueColor;
+ vilist = XGetVisualInfo(display, VisualScreenMask | VisualClassMask,
+ &vimatch, &count);
+
+ if (vilist) {
+ RrDebug("looking for a GL visual in %d visuals\n", count);
+ for (i = 0; i < count; i++) {
+ glXGetConfig(display, &vilist[i], GLX_USE_GL, &val);
+ if (val) {
+ temp = glXRating(display, &vilist[i]);
+ if (temp > rate) {
+ best = i;
+ rate = temp;
+ }
+ }
+ }
+ }
+ if (rate > 0) {
+ RrDebug("picked visual %d with rating %d\n", best, rate);
+ ret = RrInstanceNew(display, screen, vilist[best]);
+
+ GlftInit();
+ }
+
+ return ret;
+}
+
+void RrDestroy(struct RrInstance *inst)
+{
+ if (inst) {
+ RrInstanceFree(inst);
+ }
+}
--- /dev/null
+#include "instance.h"
+#include "surface.h"
+#include "debug.h"
+#include "glft/glft.h"
+#include <stdlib.h>
+#include <assert.h>
+
+static int glft_init = 0;
+
+static int glx_rating(Display *display, XVisualInfo *v)
+{
+ int rating = 0;
+ int val;
+ RrDebug("evaluating visual %d\n", (int)v->visualid);
+ glXGetConfig(display, v, GLX_BUFFER_SIZE, &val);
+ RrDebug("buffer size %d\n", val);
+
+ switch (val) {
+ case 32:
+ rating += 300;
+ break;
+ case 24:
+ rating += 200;
+ break;
+ case 16:
+ rating += 100;
+ break;
+ }
+
+ glXGetConfig(display, v, GLX_LEVEL, &val);
+ RrDebug("level %d\n", val);
+ if (val != 0)
+ rating = -10000;
+
+ glXGetConfig(display, v, GLX_DEPTH_SIZE, &val);
+ RrDebug("depth size %d\n", val);
+ switch (val) {
+ case 32:
+ rating += 30;
+ break;
+ case 24:
+ rating += 20;
+ break;
+ case 16:
+ rating += 10;
+ break;
+ case 0:
+ rating -= 10000;
+ }
+
+ glXGetConfig(display, v, GLX_DOUBLEBUFFER, &val);
+ RrDebug("double buffer %d\n", val);
+ if (val)
+ rating++;
+ return rating;
+}
+
+struct RrInstance *RrInstanceNew(Display *display, int screen)
+{
+ int count, i = 0, val, best = 0, rate = 0, temp, ok;
+ XVisualInfo vimatch, *vilist;
+
+ vimatch.screen = screen;
+ vimatch.class = TrueColor;
+ vilist = XGetVisualInfo(display, VisualScreenMask | VisualClassMask,
+ &vimatch, &count);
+
+ if (vilist) {
+ RrDebug("looking for a GL visual in %d visuals\n", count);
+ for (i = 0; i < count; i++) {
+ glXGetConfig(display, &vilist[i], GLX_USE_GL, &val);
+ if (val) {
+ temp = glx_rating(display, &vilist[i]);
+ if (temp > rate) {
+ best = i;
+ rate = temp;
+ }
+ }
+ }
+ }
+ if (rate > 0) {
+ struct RrInstance *inst;
+
+ RrDebug("picked visual %d with rating %d\n", best, rate);
+
+ if (!glft_init) {
+ if (!GlftInit())
+ return NULL;
+ glft_init = 1;
+ }
+
+ inst = malloc(sizeof(struct RrInstance));
+ inst->display = display;
+ inst->screen = screen;
+ inst->visinfo = vilist[best];
+ inst->cmap = XCreateColormap(display, RootWindow(display, screen),
+ RrVisual(inst), AllocNone);
+ inst->glx_context = glXCreateContext(display, &vilist[best],
+ NULL, True);
+ inst->shape_window = XCreateSimpleWindow(display,
+ RootWindow(display, screen),
+ 0, 0, 1, 1, 0, 0, 0);
+ /* make the context current on anything we can so we can dl
+ textures */
+
+ ok = glXMakeCurrent(display, inst->shape_window, inst->glx_context);
+ assert(ok);
+ inst->surface_map = g_hash_table_new(g_int_hash, g_int_equal);
+
+ assert(inst->glx_context);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, RrScreenWidth(inst), 0, RrScreenHeight(inst), 0, 10);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ return inst;
+ }
+
+ RrDebug("unable to find a suitable GL visual\n");
+ return NULL;
+}
+
+void RrInstanceFree(struct RrInstance *inst)
+{
+ if (inst) {
+ g_hash_table_destroy(inst->surface_map);
+ glXDestroyContext(inst->display, inst->glx_context);
+ XFreeColormap(inst->display, inst->cmap);
+ free(inst);
+ }
+}
+
+int RrInstanceDepth(struct RrInstance *inst)
+{
+ return inst->visinfo.depth;
+}
+
+Colormap RrInstanceColormap(struct RrInstance *inst)
+{
+ return inst->cmap;
+}
+
+Visual *RrInstanceVisual(struct RrInstance *inst)
+{
+ return inst->visinfo.visual;
+}
+
+void RrInstaceAddSurface(struct RrSurface *sur)
+{
+ g_hash_table_replace(RrSurfaceInstance(sur)->surface_map, &sur->win, sur);
+}
+
+void RrInstaceRemoveSurface(struct RrSurface *sur)
+{
+ g_hash_table_remove(RrSurfaceInstance(sur)->surface_map, &sur->win);
+}
+
+struct RrSurface *RrInstaceLookupSurface(struct RrInstance *inst, Window win)
+{
+ return g_hash_table_lookup(inst->surface_map, &win);
+}
--- /dev/null
+#ifndef __render_instance_h
+#define __render_instance_h
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <GL/glx.h>
+
+#include <glib.h>
+
+struct RrInstance {
+ Display *display;
+ int screen;
+ XVisualInfo visinfo;
+ Colormap cmap;
+ GLXContext glx_context;
+
+ Window shape_window;
+
+ GHashTable *surface_map;
+};
+
+#define RrDisplay(i) ((i)->display)
+#define RrScreen(i) ((i)->screen)
+#define RrScreenWidth(i) (WidthOfScreen(ScreenOfDisplay((i)->display, \
+ (i)->screen)))
+#define RrScreenHeight(i) (HeightOfScreen(ScreenOfDisplay((i)->display, \
+ (i)->screen)))
+#define RrDepth(i) ((i)->visinfo.depth)
+#define RrVisual(i) ((i)->visinfo.visual)
+#define RrColormap(i) ((i)->cmap)
+#define RrContext(i) ((i)->glx_context)
+
+#define RrShapeWindow(i) ((i)->shape_window)
+
+struct RrSurface;
+
+void RrInstaceAddSurface(struct RrSurface *sur);
+void RrInstaceRemoveSurface(struct RrSurface *sur);
+struct RrSurface *RrInstaceLookupSurface(struct RrInstance *inst, Window win);
+
+#endif
--- /dev/null
+#include "render.h"
+#include "surface.h"
+#include "instance.h"
+#include "debug.h"
+#include <assert.h>
+#include <stdlib.h>
+#include <GL/glx.h>
+
+struct ExposeArea {
+ struct RrSurface *sur;
+ int x;
+ int y;
+ int w;
+ int h;
+};
+
+#define MERGE_AREA(a, x, y, w, h) \
+ a->w = MAX(a->x + a->w - 1, x + w - 1) - MIN(a->x, x), \
+ a->h = MAX(a->y + a->h - 1, y + h - 1) - MIN(a->y, y), \
+ a->x = MIN(a->x, x), \
+ a->y = MIN(a->y, y)
+
+
+void RrExpose(struct RrInstance *inst, XExposeEvent *e)
+{
+ XEvent e2;
+ struct RrSurface *sur;
+ Window win;
+
+ win = e->window;
+
+ if ((sur = RrInstaceLookupSurface(inst, win))) {
+ while (XCheckTypedWindowEvent(RrDisplay(inst), Expose, win, &e2));
+ while (sur->parent && RrSurfaceType(sur->parent) != RR_SURFACE_NONE)
+ sur = sur->parent;
+ RrPaint(sur);
+ } else
+ RrDebug("Unable to find surface for window 0x%lx\n", win);
+}
+
+/*! Paints the surface, and all its children */
+void RrPaint(struct RrSurface *sur)
+{
+ struct RrInstance *inst;
+ struct RrSurface *p;
+ int ok, i;
+ int surx, sury;
+ GSList *it;
+
+ inst = RrSurfaceInstance(sur);
+
+ /* can't paint a prototype! */
+ assert(inst);
+ if (!inst) return;
+
+ if (!RrSurfaceVisible(sur)) return;
+
+ /* recurse and paint children */
+ for (it = RrSurfaceChildren(sur); it; it = g_slist_next(it))
+ RrPaint(it->data);
+
+ ok = glXMakeCurrent(RrDisplay(inst), RrSurfaceWindow(sur),RrContext(inst));
+ assert(ok);
+
+ glViewport(0, 0, RrScreenWidth(inst), RrScreenHeight(inst));
+/*
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(RrSurfaceX(sur), RrSurfaceX(sur) + RrSurfaceWidth(sur),
+ RrSurfaceY(sur), RrSurfaceY(sur) + RrSurfaceHeight(sur),
+ 0, 10);
+ glMatrixMode(GL_MODELVIEW);
+ glViewport(0, 0, RrSurfaceWidth(sur), RrSurfaceHeight(sur));
+*/
+
+ glPushMatrix();
+ glTranslatef(-RrSurfaceX(sur),
+ -RrSurfaceY(sur), 0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ p = sur;
+ surx = sury = 0;
+ while (p) {
+ surx += RrSurfaceX(p);
+ sury += RrSurfaceY(p);
+ p = p->parent;
+ }
+
+ switch (RrSurfaceType(sur)) {
+ case RR_SURFACE_PLANAR:
+ RrPlanarPaint(sur, surx, sury);
+ break;
+ case RR_SURFACE_NONPLANAR:
+ assert(0);
+ break;
+ case RR_SURFACE_NONE:
+ break;
+ }
+
+ for (i = 0; i < sur->ntextures; ++i)
+ RrTexturePaint(sur, &sur->texture[i]);
+
+ glPopMatrix();
+
+ glXSwapBuffers(RrDisplay(inst), RrSurfaceWindow(sur));
+}
--- /dev/null
+#include "planar.h"
+#include "surface.h"
+#include "texture.h"
+#include "color.h"
+#include "debug.h"
+#include "font.h"
+#include <string.h>
+#include <assert.h>
+#include <GL/glx.h>
+
+void RrPlanarSet(struct RrSurface *sur,
+ enum RrSurfaceColorType type,
+ enum RrBevelType bevel,
+ struct RrColor *primary,
+ struct RrColor *secondary,
+ int borderwidth,
+ struct RrColor *border)
+{
+ sur->data.planar.colortype = type;
+ sur->data.planar.bevel = bevel;
+ sur->data.planar.primary = *primary;
+ if (!(type == RR_PLANAR_NONE || type == RR_PLANAR_SOLID))
+ sur->data.planar.secondary = *secondary;
+ assert(borderwidth >= 0);
+ sur->data.planar.borderwidth = borderwidth >= 0 ? borderwidth : 0;
+ if (borderwidth)
+ sur->data.planar.border = *border;
+}
+
+static void copy_parent(struct RrSurface *sur)
+{
+ int ncols;
+ int copy;
+
+ switch (RrPlanarColorType(sur)) {
+ case RR_PLANAR_NONE:
+ return;
+ case RR_PLANAR_SOLID:
+ ncols = 1;
+ break;
+ case RR_PLANAR_HORIZONTAL:
+ ncols = 2;
+ break;
+ case RR_PLANAR_VERTICAL:
+ ncols = 2;
+ break;
+ case RR_PLANAR_DIAGONAL:
+ ncols = 2;
+ break;
+ case RR_PLANAR_CROSSDIAGONAL:
+ ncols = 2;
+ break;
+ case RR_PLANAR_PYRAMID:
+ ncols = 2;
+ break;
+ case RR_PLANAR_PIPECROSS:
+ ncols = 2;
+ break;
+ case RR_PLANAR_RECTANGLE:
+ ncols = 2;
+ break;
+ }
+
+ copy = 0;
+ if (ncols >= 1 && RrColorHasAlpha(RrPlanarPrimaryColor(sur)))
+ copy = 1;
+ if (ncols >= 1 && RrColorHasAlpha(RrPlanarSecondaryColor(sur)))
+ copy = 1;
+ if (copy) {
+ /*
+ struct RrSurface *parent = RrSurfaceParent(sur);
+
+ XXX COPY PARENT PLS
+ */
+ RrDebug("copy parent here pls\n");
+ }
+}
+
+static void RrBevelPaint(int x, int y, int w, int h, int bwidth,
+ int inset, int raise)
+{
+ int offset = bwidth + inset;
+ h--; w--;
+
+ if (raise)
+ glColor4f(1.0, 1.0, 1.0, 0.25);
+ else
+ glColor4f(0.0, 0.0, 0.0, 0.25);
+
+ glBegin(GL_LINES);
+ glVertex2i(x + offset, y + offset);
+ glVertex2i(x + offset, y + h - offset);
+
+ glVertex2i(x + offset, y + h - offset);
+ glVertex2i(x + w - offset, y + h - offset);
+
+ if (!raise)
+ glColor4f(1.0, 1.0, 1.0, 0.25);
+ else
+ glColor4f(0.0, 0.0, 0.0, 0.25);
+
+ glVertex2i(x + w - offset, y + h - offset);
+ glVertex2i(x + w - offset, y + offset);
+
+ glVertex2i(x + w - offset, y + offset);
+ glVertex2i(x + offset, y + offset);
+ glEnd();
+}
+
+void RrPlanarPaint(struct RrSurface *sur, int absx, int absy)
+{
+ struct RrColor *pri, *sec, avg;
+ int x, y, w, h;
+
+ copy_parent(sur);
+
+ pri = &RrPlanarPrimaryColor(sur);
+ sec = &RrPlanarSecondaryColor(sur);
+
+ x = RrSurfaceX(sur);
+ y = RrSurfaceY(sur);
+ w = RrSurfaceWidth(sur);
+ h = RrSurfaceHeight(sur);
+
+ switch (RrPlanarColorType(sur)) {
+ case RR_PLANAR_NONE:
+ return;
+ case RR_PLANAR_SOLID:
+ glBegin(GL_TRIANGLES);
+ RrColor3f(pri);
+ glVertex2i(x, y);
+ glVertex2i(x+w, y);
+ glVertex2i(x+w, y+h);
+
+ glVertex2i(x+w, y+h);
+ glVertex2i(x, y+h);
+ glVertex2i(x, y);
+ glEnd();
+ break;
+ case RR_PLANAR_HORIZONTAL:
+ glBegin(GL_TRIANGLES);
+ RrColor3f(pri);
+ glVertex2i(x, y);
+ RrColor3f(sec);
+ glVertex2i(x+w, y);
+ glVertex2i(x+w, y+h);
+
+ glVertex2i(x+w, y+h);
+ RrColor3f(pri);
+ glVertex2i(x, y+h);
+ glVertex2i(x, y);
+ glEnd();
+ break;
+ case RR_PLANAR_VERTICAL:
+ glBegin(GL_TRIANGLES);
+ RrColor3f(pri);
+ glVertex2i(x, y);
+ glVertex2i(x+w, y);
+ RrColor3f(sec);
+ glVertex2i(x+w, y+h);
+
+ glVertex2i(x+w, y+h);
+ glVertex2i(x, y+h);
+ RrColor3f(pri);
+ glVertex2i(x, y);
+ glEnd();
+ break;
+ case RR_PLANAR_DIAGONAL:
+ RrColorAvg(&avg, pri, sec);
+ glBegin(GL_TRIANGLES);
+ RrColor3f(&avg);
+ glVertex2i(x, y);
+ RrColor3f(pri);
+ glVertex2i(x+w, y);
+ RrColor3f(&avg);
+ glVertex2i(x+w, y+h);
+
+ RrColor3f(&avg);
+ glVertex2i(x+w, y+h);
+ RrColor3f(sec);
+ glVertex2i(x, y+h);
+ RrColor3f(&avg);
+ glVertex2i(x, y);
+ glEnd();
+ break;
+ case RR_PLANAR_CROSSDIAGONAL:
+ RrColorAvg(&avg, pri, sec);
+ glBegin(GL_TRIANGLES);
+ RrColor3f(pri);
+ glVertex2i(x, y);
+ RrColor3f(&avg);
+ glVertex2i(x+w, y);
+ RrColor3f(sec);
+ glVertex2i(x+w, y+h);
+
+ RrColor3f(sec);
+ glVertex2i(x+w, y+h);
+ RrColor3f(&avg);
+ glVertex2i(x, y+h);
+ RrColor3f(pri);
+ glVertex2i(x, y);
+ glEnd();
+ break;
+ case RR_PLANAR_PYRAMID:
+ RrColorAvg(&avg, pri, sec);
+ glBegin(GL_TRIANGLES);
+ RrColor3f(pri);
+ glVertex2i(x, y);
+ RrColor3f(sec);
+ glVertex2i(x+w/2, y+h/2);
+ RrColor3f(&avg);
+ glVertex2i(x, y+h/2);
+
+ glVertex2i(x, y+h/2);
+ RrColor3f(sec);
+ glVertex2i(x+w/2, y+h/2);
+ RrColor3f(pri);
+ glVertex2i(x, y+h);
+
+ glVertex2i(x, y+h);
+ RrColor3f(sec);
+ glVertex2i(x+w/2, y+h/2);
+ RrColor3f(&avg);
+ glVertex2i(x+w/2, y+h);
+
+ glVertex2i(x+w/2, y+h);
+ RrColor3f(sec);
+ glVertex2i(x+w/2, y+h/2);
+ RrColor3f(pri);
+ glVertex2i(x+w, y+h);
+
+ glVertex2i(x+w, y+h);
+ RrColor3f(sec);
+ glVertex2i(x+w/2, y+h/2);
+ RrColor3f(&avg);
+ glVertex2i(x+w, y+h/2);
+
+ glVertex2i(x+w, y+h/2);
+ RrColor3f(sec);
+ glVertex2i(x+w/2, y+h/2);
+ RrColor3f(pri);
+ glVertex2i(x+w, y);
+
+ glVertex2i(x+w, y);
+ RrColor3f(sec);
+ glVertex2i(x+w/2, y+h/2);
+ RrColor3f(&avg);
+ glVertex2i(x+w/2, y);
+
+ glVertex2i(x+w/2, y);
+ RrColor3f(sec);
+ glVertex2i(x+w/2, y+h/2);
+ RrColor3f(pri);
+ glVertex2i(x, y);
+ glEnd();
+ break;
+ case RR_PLANAR_PIPECROSS:
+ glBegin(GL_TRIANGLES);
+ RrColor3f(pri);
+ glVertex2i(x, y);
+ RrColor3f(sec);
+ glVertex2i(x+w/2, y+h/2);
+ glVertex2i(x, y+h/2);
+
+ glVertex2i(x, y+h/2);
+ glVertex2i(x+w/2, y+h/2);
+ RrColor3f(pri);
+ glVertex2i(x, y+h);
+
+ glVertex2i(x, y+h);
+ RrColor3f(sec);
+ glVertex2i(x+w/2, y+h/2);
+ glVertex2i(x+w/2, y+h);
+
+ glVertex2i(x+w/2, y+h);
+ glVertex2i(x+w/2, y+h/2);
+ RrColor3f(pri);
+ glVertex2i(x+w, y+h);
+
+ glVertex2i(x+w, y+h);
+ RrColor3f(sec);
+ glVertex2i(x+w/2, y+h/2);
+ glVertex2i(x+w, y+h/2);
+
+ glVertex2i(x+w, y+h/2);
+ glVertex2i(x+w/2, y+h/2);
+ RrColor3f(pri);
+ glVertex2i(x+w, y);
+
+ glVertex2i(x+w, y);
+ RrColor3f(sec);
+ glVertex2i(x+w/2, y+h/2);
+ glVertex2i(x+w/2, y);
+
+ glVertex2i(x+w/2, y);
+ glVertex2i(x+w/2, y+h/2);
+ RrColor3f(pri);
+ glVertex2i(x, y);
+ glEnd();
+ break;
+ case RR_PLANAR_RECTANGLE:
+ glBegin(GL_TRIANGLES);
+ RrColor3f(pri);
+ glVertex2i(x, y);
+ RrColor3f(sec);
+ glVertex2i(x+w/2, y+h/2);
+ RrColor3f(pri);
+ glVertex2i(x, y+h);
+
+ glVertex2i(x, y+h);
+ RrColor3f(sec);
+ glVertex2i(x+w/2, y+h/2);
+ RrColor3f(pri);
+ glVertex2i(x+w, y+h);
+
+ glVertex2i(x+w, y+h);
+ RrColor3f(sec);
+ glVertex2i(x+w/2, y+h/2);
+ RrColor3f(pri);
+ glVertex2i(x+w, y);
+
+ glVertex2i(x+w, y);
+ RrColor3f(sec);
+ glVertex2i(x+w/2, y+h/2);
+ RrColor3f(pri);
+ glVertex2i(x, y);
+
+ glEnd();
+ break;
+ }
+
+ switch (RrPlanarBevelType(sur)) {
+ case RR_SUNKEN_OUTER:
+ RrBevelPaint(RrSurfaceX(sur), RrSurfaceY(sur),
+ RrSurfaceWidth(sur), RrSurfaceHeight(sur),
+ 0, 0, 0);
+ break;
+ case RR_SUNKEN_INNER:
+ RrBevelPaint(RrSurfaceX(sur), RrSurfaceY(sur),
+ RrSurfaceWidth(sur), RrSurfaceHeight(sur),
+ 0, 1, 0);
+ break;
+ case RR_RAISED_OUTER:
+ RrBevelPaint(RrSurfaceX(sur), RrSurfaceY(sur),
+ RrSurfaceWidth(sur), RrSurfaceHeight(sur),
+ 0, 0, 1);
+ break;
+ case RR_RAISED_INNER:
+ RrBevelPaint(RrSurfaceX(sur), RrSurfaceY(sur),
+ RrSurfaceWidth(sur), RrSurfaceHeight(sur),
+ 0, 1, 1);
+ break;
+ case RR_BEVEL_NONE:
+ break;
+ }
+}
+
+void RrPlanarMinSize(struct RrSurface *sur, int *w, int *h)
+{
+ *w = 0;
+ *h = 0;
+}
--- /dev/null
+#ifndef __render_planar_h
+#define __render_planar_h
+
+#include "render.h"
+
+struct RrPlanarSurface {
+ enum RrSurfaceColorType colortype;
+ enum RrBevelType bevel;
+
+ struct RrColor primary;
+ struct RrColor secondary;
+
+ int borderwidth;
+ struct RrColor border;
+};
+
+#define RrPlanarColorType(sur) ((sur)->data.planar.colortype)
+#define RrPlanarPrimaryColor(sur) ((sur)->data.planar.primary)
+#define RrPlanarSecondaryColor(sur) ((sur)->data.planar.secondary)
+#define RrPlanarBevelType(sur) ((sur)->data.planar.bevel)
+
+void RrPlanarPaint(struct RrSurface *sur, int absx, int absy);
+
+void RrPlanarMinSize(struct RrSurface *sur, int *w, int *h);
+
+#endif
--- /dev/null
+#ifndef __render_h__
+#define __render_h__
+
+#include <glib.h>
+#include <X11/Xlib.h>
+
+/* instances */
+
+struct RrInstance;
+
+/*! Returns a struct to be used when calling members of the library.
+ If the library fails to initialize, NULL is returned.
+ @param display The X Display to use.
+ @param screen The number of the screen to use.
+*/
+struct RrInstance *RrInstanceNew(Display *display,
+ int screen);
+
+/*! Destroys an instance of the library. The instance should not be used after
+ calling this function.
+ @param inst The instance to destroy.
+*/
+void RrInstanceFree(struct RrInstance *inst);
+
+int RrInstanceDepth(struct RrInstance *inst);
+Colormap RrInstanceColormap(struct RrInstance *inst);
+Visual *RrInstanceVisual(struct RrInstance *inst);
+
+/* colors */
+
+/*! A Color (including alpha component) for the Render library. This should be
+ treated as an opaque data type, and be accessed only via the available
+ functions. */
+struct RrColor {
+ /*! The red component. */
+ float r;
+ /*! The green component. */
+ float g;
+ /*! The blue component. */
+ float b;
+ /*! The alpha component. */
+ float a;
+};
+
+/*! Returns if an RrColor is non-opaque */
+#define RrColorHasAlpha(c) ((c).a > 0.0000001)
+
+/*! Sets the values of all components for an RrColor */
+#define RrColorSet(c, w, x, y, z) (c)->r = (w), (c)->g = (x), \
+ (c)->b = (y), (c)->a = z
+
+
+/*! Gets color values from a colorname.
+ @param inst An instance of the library
+ @param colorname The name of the color.
+ @param ret The RrColor to set the colorvalues in.
+ @return nonzero if the colorname could be parsed; on error, it returns zero.
+*/
+int RrColorParse(struct RrInstance *inst, const char *colorname,
+ struct RrColor *ret);
+
+/* fonts */
+
+struct RrFont;
+
+struct RrFont *RrFontOpen(struct RrInstance *inst, const char *fontstring);
+void RrFontClose(struct RrFont *font);
+
+int RrFontMeasureString(struct RrFont *font, const char *string);
+int RrFontHeight(struct RrFont *font);
+int RrFontMaxCharWidth(struct RrFont *font);
+
+/* surfaces */
+
+struct RrSurface;
+
+enum RrSurfaceType {
+ RR_SURFACE_NONE,
+ RR_SURFACE_PLANAR,
+ RR_SURFACE_NONPLANAR
+};
+
+/*! Create a new RrSurface prototype that can't render. A prototype can be
+ copied to a new RrSurface that can render. */
+struct RrSurface *RrSurfaceNewProto(enum RrSurfaceType type,
+ int numtex);
+/*! Create a new top-level RrSurface for a Window. The new RrSurface defaults
+ to a non-visible state.*/
+struct RrSurface *RrSurfaceNew(struct RrInstance *inst,
+ enum RrSurfaceType type,
+ Window win,
+ int numtex);
+/*! Create a new RrSurface which is a child of another. The new RrSurface
+ defaults to a visible state. */
+struct RrSurface *RrSurfaceNewChild(enum RrSurfaceType type,
+ struct RrSurface *parent,
+ int numtex);
+/*! Destroys an RrSurface. */
+void RrSurfaceFree(struct RrSurface *sur);
+
+/*! Copy an RrSurface, setting the dest surface to be identical to the source
+ surface. */
+void RrSurfaceCopy(struct RrSurface *dest,
+ struct RrSurface *src);
+
+void RrSurfaceSetArea(struct RrSurface *sur,
+ int x,
+ int y,
+ int w,
+ int h);
+void RrSurfaceSetPos(struct RrSurface *sur,
+ int x,
+ int y);
+void RrSurfaceSetSize(struct RrSurface *sur,
+ int w,
+ int h);
+
+Window RrSurfaceWindow(struct RrSurface *sur);
+
+void RrSurfaceShow(struct RrSurface *sur);
+void RrSurfaceHide(struct RrSurface *sur);
+int RrSurfaceVisible(struct RrSurface *sur);
+
+void RrSurfaceMinSize(struct RrSurface *sur,
+ int *w,
+ int *h);
+
+/*! Shape a surface to its children. This is not done implicitly inside the
+ library at *any* time. You must call this for each surface you want to
+ shape, when you want to update it. This means when you resize the surface
+ or change its base shape, or move/resize any of its children, you will need
+ to call this explicitly. Also, please note that you must call it on the
+ children surfaces first and work your way up to the top level surface for it
+ to function properly.
+*/
+void RrSurfaceShape(struct RrSurface *sur);
+
+/*! Set the base shape for a surface. To clear the base, pass 0 for all
+ of the arguments (except for the surface of course!)
+*/
+void RrSurfaceShapeSetBase(struct RrSurface *sur,
+ Window base,
+ int x,
+ int y);
+
+/* planar surfaces */
+
+/*! The options available for the background of an RrSurface */
+enum RrSurfaceColorType {
+ /*! No rendering on the surface background, its contents will be
+ undefined. */
+ RR_PLANAR_NONE,
+ /*! Solid color fill. */
+ RR_PLANAR_SOLID,
+ /*! Horizontal gradient. */
+ RR_PLANAR_HORIZONTAL,
+ /*! Vertical gradient. */
+ RR_PLANAR_VERTICAL,
+ /*! Diagonal (TL->BR) gradient. */
+ RR_PLANAR_DIAGONAL,
+ /*! Cross-Diagonal (TR->BL) gradient. */
+ RR_PLANAR_CROSSDIAGONAL,
+ /*! Pipecross gradient. */
+ RR_PLANAR_PIPECROSS,
+ /*! Rectangle gradient. */
+ RR_PLANAR_RECTANGLE,
+ /*! Pyramid gradient. */
+ RR_PLANAR_PYRAMID
+};
+
+enum RrBevelType {
+ RR_SUNKEN_OUTER = -2,
+ RR_SUNKEN_INNER = -1,
+ RR_BEVEL_NONE = 0,
+ RR_RAISED_INNER = 1,
+ RR_RAISED_OUTER = 2
+};
+
+void RrPlanarSet(struct RrSurface *sur,
+ enum RrSurfaceColorType type,
+ enum RrBevelType bevel,
+ struct RrColor *primary,
+ struct RrColor *secondary,
+ int borderwidth,
+ struct RrColor *border);
+
+/* textures */
+
+enum RrLayout {
+ RR_TOP_LEFT,
+ RR_TOP,
+ RR_TOP_RIGHT,
+ RR_LEFT,
+ RR_CENTER,
+ RR_RIGHT,
+ RR_BOTTOM_LEFT,
+ RR_BOTTOM,
+ RR_BOTTOM_RIGHT
+};
+
+#ifndef __LONG64
+typedef long RrData32;
+#else
+typedef int RrData32;
+#endif
+
+void RrTextureSetRGBA(struct RrSurface *sur,
+ int texnum,
+ RrData32 *data,
+ int x,
+ int y,
+ int w,
+ int h);
+void RrTextureSetText(struct RrSurface *sur,
+ int texnum,
+ struct RrFont *font,
+ enum RrLayout layout,
+ struct RrColor *color,
+ const char *text);
+void RrTextureSetNone(struct RrSurface *sur,
+ int texnum);
+
+/* drawing */
+
+/*! Paints the surface, and all its children */
+void RrPaint(struct RrSurface *sur);
+
+void RrExpose(struct RrInstance *inst, XExposeEvent *e);
+
+#endif
--- /dev/null
+#include "surface.h"
+#include "instance.h"
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef SHAPE
+#include <X11/extensions/shape.h>
+#endif
+
+/* doesn't set win or parent */
+static struct RrSurface *surface_new(enum RrSurfaceType type,
+ int numtex)
+{
+ struct RrSurface *sur;
+
+ sur = malloc(sizeof(struct RrSurface));
+ sur->type = type;
+ sur->shape_base = None;
+ sur->shape_base_x = 0;
+ sur->shape_base_y = 0;
+ sur->ntextures = numtex;
+ if (numtex) {
+ sur->texture = malloc(sizeof(struct RrTexture) * numtex);
+ memset(sur->texture, 0, sizeof(struct RrTexture) * numtex);
+ } else
+ sur->texture = NULL;
+ sur->x = 0;
+ sur->y = 0;
+ sur->w = 1;
+ sur->h = 1;
+ sur->visible = 0;
+ sur->children = NULL;
+ return sur;
+}
+
+static Window create_window(struct RrInstance *inst, Window parent)
+{
+ XSetWindowAttributes attrib;
+ Window win;
+
+ attrib.event_mask = ExposureMask;
+ win = XCreateWindow(RrDisplay(inst), parent, 0, 0, 1, 1, 0,
+ RrDepth(inst), InputOutput, RrVisual(inst),
+ CWEventMask, &attrib);
+ return win;
+}
+
+struct RrSurface *RrSurfaceNewProto(enum RrSurfaceType type,
+ int numtex)
+{
+ struct RrSurface *sur;
+
+ sur = surface_new(type, numtex);
+ sur->inst = NULL;
+ sur->win = None;
+ sur->parent = NULL;
+ sur->visible = 0;
+ return sur;
+}
+
+struct RrSurface *RrSurfaceNew(struct RrInstance *inst,
+ enum RrSurfaceType type,
+ Window win,
+ int numtex)
+{
+ struct RrSurface *sur;
+
+ sur = surface_new(type, numtex);
+ sur->inst = inst;
+ sur->win = win;
+ sur->parent = NULL;
+ sur->visible = 0;
+
+ RrInstaceAddSurface(sur);
+ return sur;
+}
+
+struct RrSurface *RrSurfaceNewChild(enum RrSurfaceType type,
+ struct RrSurface *parent,
+ int numtex)
+{
+ struct RrSurface *sur;
+
+ /* can't be a child of a prototype! */
+ assert(parent->inst);
+ if (!parent->inst) return NULL;
+
+ sur = surface_new(type, numtex);
+ sur->inst = parent->inst;
+ sur->win = create_window(sur->inst, parent->win);
+ sur->parent = parent;
+ RrSurfaceShow(sur);
+
+ parent->children = g_slist_append(parent->children, sur);
+
+ RrInstaceAddSurface(sur);
+ return sur;
+}
+
+void RrSurfaceCopy(struct RrSurface *dest, struct RrSurface *src)
+{
+ dest->type = src->type;
+ switch (dest->type) {
+ case RR_SURFACE_PLANAR:
+ dest->data = src->data;
+ break;
+ case RR_SURFACE_NONPLANAR:
+ assert(0);
+ break;
+ case RR_SURFACE_NONE:
+ break;
+ }
+ free(dest->texture);
+ dest->ntextures = src->ntextures;
+ dest->texture = malloc(sizeof(struct RrTexture) * dest->ntextures);
+ memcpy(dest->texture, src->texture,
+ sizeof(struct RrTexture) * dest->ntextures);
+}
+
+void RrSurfaceFree(struct RrSurface *sur)
+{
+ int i;
+ if (sur) {
+ if (sur->parent)
+ sur->parent->children = g_slist_remove(sur->parent->children, sur);
+
+ RrInstaceRemoveSurface(sur);
+ for (i = 0; i < sur->ntextures; ++i)
+ RrTextureFreeContents(&sur->texture[i]);
+ if (sur->ntextures)
+ free(sur->texture);
+ if (sur->parent && sur->win)
+ XDestroyWindow(RrDisplay(sur->inst), sur->win);
+ free(sur);
+ }
+}
+
+void RrSurfaceSetPos(struct RrSurface *sur,
+ int x,
+ int y)
+{
+ RrSurfaceSetArea(sur, x, y, sur->w, sur->h);
+}
+
+void RrSurfaceSetSize(struct RrSurface *sur,
+ int w,
+ int h)
+{
+ RrSurfaceSetArea(sur, sur->x, sur->y, w, h);
+}
+
+void RrSurfaceSetArea(struct RrSurface *sur,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ assert(w > 0 && h > 0);
+ if (!(w > 0 && h > 0)) return;
+
+ sur->x = x;
+ sur->y = y;
+ sur->w = w;
+ sur->h = h;
+ if (sur->win)
+ XMoveResizeWindow(RrDisplay(sur->inst), sur->win, x, y, w, h);
+}
+
+Window RrSurfaceWindow(struct RrSurface *sur)
+{
+ /* can't get a window for a prototype */
+ assert(sur->inst);
+ if (!sur->inst) return None;
+
+ return sur->win;
+}
+
+struct RrTexture *RrSurfaceTexture(struct RrSurface *sur, int texnum)
+{
+ assert(texnum < sur->ntextures);
+ return &(sur->texture[texnum]);
+}
+
+void RrSurfaceMinSize(struct RrSurface *sur, int *w, int *h)
+{
+ int i;
+ int minw, minh;
+
+ switch(sur->type) {
+ case RR_SURFACE_NONE:
+ *w = *h = 0;
+ break;
+ case RR_SURFACE_PLANAR:
+ RrPlanarMinSize(sur, w, h);
+ break;
+ case RR_SURFACE_NONPLANAR:
+ assert(0);
+ break;
+ }
+
+ minw = minh = 0;
+ for (i = 0; i < sur->ntextures; ++i) {
+ switch (sur->texture[i].type) {
+ case RR_TEXTURE_NONE:
+ minw = MAX(minw, 0);
+ minh = MAX(minh, 0);
+ break;
+ case RR_TEXTURE_TEXT:
+ /* XXX MEASUER STRING PLS */
+ minw = MAX(minw, 100 /*MEASURESTRING*/);
+ minh = MAX(minh, 10 /*HEIGHTOFFONT*/);
+ break;
+ case RR_TEXTURE_RGBA:
+ minw = MAX(minw, (sur->texture[i].data.rgba.x +
+ sur->texture[i].data.rgba.w));
+ minh = MAX(minw, (sur->texture[i].data.rgba.y +
+ sur->texture[i].data.rgba.h));
+ break;
+ }
+ }
+
+ *w += minw;
+ *h += minh;
+ /* zeros are bad. */
+ if (*w == 0) *w = 1;
+ if (*h == 0) *h = 1;
+}
+
+void RrSurfaceShow(struct RrSurface *sur)
+{
+ sur->visible = 1;
+ if (sur->win)
+ XMapWindow(RrDisplay(sur->inst), sur->win);
+}
+
+void RrSurfaceHide(struct RrSurface *sur)
+{
+ sur->visible = 0;
+ if (sur->win)
+ XUnmapWindow(RrDisplay(sur->inst), sur->win);
+}
+
+int RrSurfaceVisible(struct RrSurface *sur)
+{
+ assert(sur->inst);
+ return sur->visible;
+}
+
+void RrSurfaceShapeSetBase(struct RrSurface *sur, Window base, int x, int y)
+{
+ assert(sur->inst);
+ sur->shape_base = base;
+ sur->shape_base_x = x;
+ sur->shape_base_y = y;
+}
+
+void RrSurfaceShape(struct RrSurface *sur)
+{
+ GSList *it;
+
+ assert(sur->inst);
+
+#ifdef SHAPE
+ XResizeWindow(RrDisplay(sur->inst), RrShapeWindow(sur->inst),
+ sur->w, sur->h);
+ XShapeCombineShape(RrDisplay(sur->inst), RrShapeWindow(sur->inst),
+ ShapeBounding,
+ sur->shape_base_x, sur->shape_base_y,
+ sur->shape_base, ShapeBounding, ShapeSet);
+ /* include the shape of the children */
+ for (it = sur->children; it; it = g_slist_next(it)) {
+ struct RrSurface *ch = it->data;
+ if (ch->win)
+ XShapeCombineShape(RrDisplay(sur->inst),
+ RrShapeWindow(sur->inst),
+ ShapeBounding, ch->x, ch->y, ch->win,
+ ShapeBounding, ShapeUnion);
+ }
+ switch (sur->type) {
+ case RR_SURFACE_NONE:
+ break;
+ case RR_SURFACE_PLANAR:
+ /* XXX shape me based on something! an alpha mask? */
+ break;
+ case RR_SURFACE_NONPLANAR:
+ /* XXX shape me based on my GL form! */
+ assert(0);
+ break;
+ }
+
+ /* apply the final shape */
+ XShapeCombineShape(RrDisplay(sur->inst), sur->win, ShapeBounding, 0, 0,
+ RrShapeWindow(sur->inst), ShapeBounding, ShapeSet);
+#endif
+}
--- /dev/null
+#ifndef __render_surface_h
+#define __render_surface_h
+
+#include "render.h"
+#include "texture.h"
+#include "planar.h"
+#include <glib.h>
+
+struct RrNonPlanarSurface {
+ int foo;
+};
+
+union RrSurfaceData {
+ struct RrPlanarSurface planar;
+ struct RrNonPlanarSurface nonplanar;
+};
+
+struct RrSurface {
+ struct RrInstance *inst;
+
+ enum RrSurfaceType type;
+ union RrSurfaceData data;
+
+ /* This member is created inside Render if parent != NULL, but is passed
+ in if parent == NULL and should not be destroyed!
+
+ Always check for this to be None before rendering it. Just skip by
+ (and assert) if it is None.
+ */
+ Window win; /* XXX this can optionally be None if parent != NULL ... */
+
+ Window shape_base;
+ int shape_base_x;
+ int shape_base_y;
+
+ int ntextures;
+ struct RrTexture *texture;
+
+ struct RrSurface *parent;
+
+ int x;
+ int y;
+ int w;
+ int h;
+
+ int visible : 1;
+
+ GSList *children;
+};
+
+struct RrTexture *RrSurfaceTexture(struct RrSurface *sur, int texnum);
+
+#define RrSurfaceInstance(sur) ((sur)->inst)
+#define RrSurfaceType(sur) ((sur)->type)
+
+#define RrSurfaceParent(sur) ((sur)->parent)
+
+#define RrSurfaceX(sur) ((sur)->x)
+#define RrSurfaceY(sur) ((sur)->y)
+#define RrSurfaceWidth(sur) ((sur)->w)
+#define RrSurfaceHeight(sur) ((sur)->h)
+
+#define RrSurfaceChildren(sur) ((sur)->children)
+
+#endif
--- /dev/null
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/shape.h>
+#include <string.h>
+#include <stdlib.h>
+#include "render.h"
+#include <glib.h>
+
+static int x_error_handler(Display * disp, XErrorEvent * error)
+{
+ char buf[1024];
+ XGetErrorText(disp, error->error_code, buf, 1024);
+ printf("%s\n", buf);
+ return 0;
+}
+
+#define X 10
+#define Y 10
+#define W 100
+#define H 100
+
+int main()
+{
+ Display *display;
+ Window win;
+ XEvent report, report2;
+ XClassHint chint;
+ Atom delete_win, protocols;
+ int quit;
+
+ struct RrInstance *inst;
+ struct RrSurface *sur;
+ struct RrColor pri, sec;
+
+ if (!(display = XOpenDisplay(NULL))) {
+ fprintf(stderr, "couldn't connect to X server in DISPLAY\n");
+ return EXIT_FAILURE;
+ }
+ XSetErrorHandler(x_error_handler);
+ win = XCreateWindow(display, RootWindow(display, DefaultScreen(display)),
+ X, Y, W, H, 0,
+ CopyFromParent, /* depth */
+ CopyFromParent, /* class */
+ CopyFromParent, /* visual */
+ 0, /* valuemask */
+ 0); /* attributes */
+ XMapWindow(display, win);
+ XSelectInput(display, win, ExposureMask | StructureNotifyMask);
+
+ chint.res_name = "rendertest";
+ chint.res_class = "Rendertest";
+ XSetClassHint(display, win, &chint);
+
+ delete_win = XInternAtom(display, "WM_DELETE_WINDOW", False);
+ protocols = XInternAtom(display, "WM_PROTOCOLS", False);
+ XSetWMProtocols(display, win, &delete_win, 1);
+
+ /* init Render */
+ if (!(inst = RrInstanceNew(display, DefaultScreen(display)))) {
+ fprintf(stderr, "couldn't initialize the Render library "
+ "(no suitable GL support found)\n");
+ return EXIT_FAILURE;
+ }
+
+ sur = RrSurfaceNew(inst, RR_SURFACE_PLANAR, win, 0);
+ RrSurfaceSetArea(sur, X, Y, W, H);
+ RrColorSet(&pri, 0, 0, 0, 0);
+ RrColorSet(&sec, 1, 1, 1, 0);
+ RrPlanarSet(sur, RR_PLANAR_PIPECROSS, RR_RAISED_INNER, &pri, &sec,
+ 0, NULL);
+
+ quit = 0;
+ while (!quit) {
+ XNextEvent(display, &report);
+ switch (report.type) {
+ case ClientMessage:
+ if ((Atom)report.xclient.message_type == protocols)
+ if ((Atom)report.xclient.data.l[0] == delete_win)
+ quit = 1;
+ case Expose:
+ if (XCheckTypedWindowEvent(display, win, ConfigureNotify,
+ &report2)) {
+ XPutBackEvent(display, &report);
+ XPutBackEvent(display, &report2);
+ /* fall through ... */
+ } else {
+ while (XCheckTypedWindowEvent(display, win, Expose, &report));
+ RrPaint(sur);
+ break;
+ }
+ case ConfigureNotify:
+ while (XCheckTypedWindowEvent(display, win, ConfigureNotify,
+ &report));
+ RrSurfaceSetSize(sur,
+ report.xconfigure.width,
+ report.xconfigure.height);
+ break;
+ }
+
+ }
+
+ RrInstanceFree(inst);
+
+ return 1;
+}
--- /dev/null
+#include "instance.h"
+#include "texture.h"
+#include "surface.h"
+#include "font.h"
+#include "glft/glft.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+void RrTextureFreeContents(struct RrTexture *tex)
+{
+ switch (tex->type) {
+ case RR_TEXTURE_NONE:
+ break;
+ case RR_TEXTURE_TEXT:
+ free(tex->data.text.string);
+ break;
+ case RR_TEXTURE_RGBA:
+ glDeleteTextures(1, &tex->data.rgba.texid);
+ break;
+ }
+ tex->type = RR_TEXTURE_NONE;
+}
+
+void RrTextureSetRGBA(struct RrSurface *sur,
+ int texnum,
+ RrData32 *data,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ unsigned int num;
+ struct RrTexture *tex = RrSurfaceTexture(sur, texnum);
+
+ if (!tex) return;
+ RrTextureFreeContents(tex);
+ tex->type = RR_TEXTURE_RGBA;
+ tex->data.rgba.x = x;
+ tex->data.rgba.y = y;
+ tex->data.rgba.w = w;
+ tex->data.rgba.h = h;
+ glGenTextures(1, &num);
+ tex->data.rgba.texid = num;
+ glBindTexture(GL_TEXTURE_2D, num);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+}
+
+void RrTextureSetText(struct RrSurface *sur,
+ int texnum,
+ struct RrFont *font,
+ enum RrLayout layout,
+ struct RrColor *color,
+ const char *text)
+{
+ struct RrTexture *tex = RrSurfaceTexture(sur, texnum);
+ int l;
+
+ if (!tex) return;
+ RrTextureFreeContents(tex);
+ tex->type = RR_TEXTURE_TEXT;
+ tex->data.text.font = font;
+ tex->data.text.layout = layout;
+ tex->data.text.color = *color;
+
+ l = strlen(text) + 1;
+ tex->data.text.string = malloc(l);
+ memcpy(tex->data.text.string, text, l);
+}
+
+void RrTextureSetNone(struct RrSurface *sur,
+ int texnum)
+{
+ struct RrTexture *tex = RrSurfaceTexture(sur, texnum);
+
+ if (!tex) return;
+ RrTextureFreeContents(tex);
+}
+
+void RrTexturePaint(struct RrSurface *sur, struct RrTexture *tex)
+{
+ struct GlftColor col;
+
+ glEnable(GL_TEXTURE_2D);
+
+ switch (tex->type) {
+ case RR_TEXTURE_NONE:
+ break;
+ case RR_TEXTURE_TEXT:
+ printf("text %s\n", tex->data.text.string);
+ assert(tex->data.text.font);
+ col.r = tex->data.text.color.r;
+ col.g = tex->data.text.color.g;
+ col.b = tex->data.text.color.b;
+ col.a = tex->data.text.color.a;
+ GlftRenderString(tex->data.text.font->font, tex->data.text.string,
+ strlen(tex->data.text.string), &col, 0, 0);
+ break;
+ }
+ glDisable(GL_TEXTURE_2D);
+}
--- /dev/null
+#ifndef __render_texture_h
+#define __render_texture_h
+
+#include "render.h"
+#include <GL/gl.h>
+
+enum RrTextureType {
+ RR_TEXTURE_NONE,
+ RR_TEXTURE_TEXT,
+ RR_TEXTURE_RGBA
+};
+
+struct RrTextureText {
+ struct RrFont *font;
+ enum RrLayout layout;
+ struct RrColor color;
+ char *string;
+};
+
+struct RrTextureRGBA {
+ GLuint texid;
+ int x;
+ int y;
+ int w;
+ int h;
+};
+
+struct RrTexture;
+
+void RrTextureFreeContents(struct RrTexture *tex);
+
+union RrTextureData {
+ struct RrTextureText text;
+ struct RrTextureRGBA rgba;
+};
+
+struct RrTexture {
+ enum RrTextureType type;
+ union RrTextureData data;
+};
+
+void RrTexturePaint(struct RrSurface *sur, struct RrTexture *tex);
+
+#endif
--- /dev/null
+#include "render.h"
+#include "theme.h"
+#include <stdlib.h>
+
+struct RrTheme *RrThemeLoad(struct RrInstance *inst, const char *name)
+{
+ struct RrTheme *theme;
+ struct RrColor pri, sec, bor;
+
+ theme = malloc(sizeof(struct RrTheme));
+ theme->inst = inst;
+
+#define MERRY
+#ifdef MERRY
+
+ theme->bevel = 1;
+ theme->bwidth = 1;
+ theme->cbwidth = 1;
+ theme->handle_height = 4;
+
+ theme->title_layout = "NLIMC";
+
+ theme->title_font = RrFontOpen(inst,
+ "arial:bold:pixelsize=10:"
+ "shadow:shadowoffset=1:shadowtint=0.1");
+ theme->title_justify = RR_CENTER;
+
+ RrColorSet(&theme->b_color, 0, 0, 0, 1);
+ RrColorSet(&theme->cb_color, 0, 0, 0, 1);
+ RrColorSet(&theme->cb_color_f, 0, 0, 0, 1);
+ RrColorSet(&theme->title_color, 1, 1, 1, 1);
+ RrColorSet(&theme->title_color_f, 1, 1, 1, 1);
+ RrColorSet(&theme->button_color, 0.3, 0.3, 0.3, 1);
+ RrColorSet(&theme->button_color_f, 0.12, 0.12, 0.12, 1);
+ RrColorSet(&theme->menu_title_color, 1, 1, 1, 1);
+ RrColorSet(&theme->menu_item_color, 1, 1, 1, 1);
+ RrColorSet(&theme->menu_disabled_color, 1, 1, 1, 1);
+ RrColorSet(&theme->menu_hilite_color, 1, 1, 1, 1);
+
+ theme->max = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->max_f = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->max_p = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->max_p_f = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->iconify = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->iconify_f = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->iconify_p = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->iconify_p_f = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->close = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->close_f = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->close_p = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->close_p_f = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->desk = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->desk_f = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->desk_p = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->desk_p_f = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->shade = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->shade_f = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->shade_p = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->shade_p_f = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+
+ RrColorSet(&pri, 0.9, 0.91, 0.9, 1);
+ RrPlanarSet(theme->max, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 0, NULL);
+ RrPlanarSet(theme->max_f, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 0, NULL);
+
+ RrColorSet(&pri, 0.71, 0.7, 0.68, 1);
+ RrPlanarSet(theme->max_p, RR_PLANAR_SOLID, RR_SUNKEN_OUTER,
+ &pri, NULL, 0, NULL);
+ RrPlanarSet(theme->max_p, RR_PLANAR_SOLID, RR_SUNKEN_OUTER,
+ &pri, NULL, 0, NULL);
+
+ RrColorSet(&pri, 0.9, 0.91, 0.9, 1);
+ RrPlanarSet(theme->iconify, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 0, NULL);
+ RrPlanarSet(theme->iconify_f, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 0, NULL);
+
+ RrColorSet(&pri, 0.71, 0.7, 0.68, 1);
+ RrPlanarSet(theme->iconify_p, RR_PLANAR_SOLID, RR_SUNKEN_OUTER,
+ &pri, NULL, 0, NULL);
+ RrPlanarSet(theme->iconify_p, RR_PLANAR_SOLID, RR_SUNKEN_OUTER,
+ &pri, NULL, 0, NULL);
+
+ RrColorSet(&pri, 0.9, 0.91, 0.9, 1);
+ RrPlanarSet(theme->close, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 0, NULL);
+ RrPlanarSet(theme->close_f, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 0, NULL);
+
+ RrColorSet(&pri, 0.71, 0.7, 0.68, 1);
+ RrPlanarSet(theme->close_p, RR_PLANAR_SOLID, RR_SUNKEN_OUTER,
+ &pri, NULL, 0, NULL);
+ RrPlanarSet(theme->close_p, RR_PLANAR_SOLID, RR_SUNKEN_OUTER,
+ &pri, NULL, 0, NULL);
+
+ RrColorSet(&pri, 0.9, 0.91, 0.9, 1);
+ RrPlanarSet(theme->desk, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 0, NULL);
+ RrPlanarSet(theme->desk_f, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 0, NULL);
+
+ RrColorSet(&pri, 0.71, 0.7, 0.68, 1);
+ RrPlanarSet(theme->desk_p, RR_PLANAR_SOLID, RR_SUNKEN_OUTER,
+ &pri, NULL, 0, NULL);
+ RrPlanarSet(theme->desk_p, RR_PLANAR_SOLID, RR_SUNKEN_OUTER,
+ &pri, NULL, 0, NULL);
+
+ RrColorSet(&pri, 0.9, 0.91, 0.9, 1);
+ RrPlanarSet(theme->shade, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 0, NULL);
+ RrPlanarSet(theme->shade_f, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 0, NULL);
+
+ RrColorSet(&pri, 0.71, 0.7, 0.68, 1);
+ RrPlanarSet(theme->shade_p, RR_PLANAR_SOLID, RR_SUNKEN_OUTER,
+ &pri, NULL, 0, NULL);
+ RrPlanarSet(theme->shade_p, RR_PLANAR_SOLID, RR_SUNKEN_OUTER,
+ &pri, NULL, 0, NULL);
+
+ theme->frame = RrSurfaceNewProto(RR_SURFACE_PLANAR, 0);
+
+ RrColorSet(&pri, 0.9, 0.91, 0.9, 1);
+ RrColorSet(&bor, 0, 0, 0, 1);
+ RrPlanarSet(theme->frame, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 1, &bor);
+
+ theme->title = RrSurfaceNewProto(RR_SURFACE_PLANAR, 0);
+ theme->title_f = RrSurfaceNewProto(RR_SURFACE_PLANAR, 0);
+
+ RrColorSet(&pri, 0.9, 0.91, 0.9, 1);
+ RrColorSet(&bor, 0, 0, 0, 1);
+ RrPlanarSet(theme->title, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 1, &bor);
+ RrPlanarSet(theme->title_f, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 1, &bor);
+
+ theme->label = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->label_f = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+
+ RrColorSet(&pri, 0.30, 0.34, 0.65, 1);
+ RrColorSet(&sec, 0.35, 0.43, 0.75, 1);
+ RrColorSet(&bor, 0, 0, 0, 1);
+ RrPlanarSet(theme->title, RR_PLANAR_VERTICAL, RR_BEVEL_NONE,
+ &pri, &sec, 1, &bor);
+ RrColorSet(&pri, 0.70, 0.70, 0.68, 1);
+ RrColorSet(&sec, 0.75, 0.73, 0.71, 1);
+ RrColorSet(&bor, 0.42, 0.41, 0.42, 1);
+ RrPlanarSet(theme->title_f, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, &sec, 1, &bor);
+
+
+ theme->grip = RrSurfaceNewProto(RR_SURFACE_PLANAR, 0);
+ theme->grip_f = RrSurfaceNewProto(RR_SURFACE_PLANAR, 0);
+
+ RrColorSet(&pri, 0.9, 0.91, 0.9, 1);
+ RrColorSet(&bor, 0, 0, 0, 1);
+ RrPlanarSet(theme->grip, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 1, &bor);
+ RrPlanarSet(theme->grip_f, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 1, &bor);
+
+ theme->handle = RrSurfaceNewProto(RR_SURFACE_PLANAR, 0);
+ theme->handle_f = RrSurfaceNewProto(RR_SURFACE_PLANAR, 0);
+
+ RrColorSet(&pri, 0.9, 0.91, 0.9, 1);
+ RrColorSet(&bor, 0, 0, 0, 1);
+ RrPlanarSet(theme->handle, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 1, &bor);
+ RrPlanarSet(theme->handle_f, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 1, &bor);
+
+ theme->menu_title = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+
+ RrColorSet(&pri, 0.29, 0.35, 0.65, 1);
+ RrColorSet(&bor, 0, 0, 0, 1);
+ RrPlanarSet(theme->menu_title, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 1, &bor);
+
+ theme->menu_item = RrSurfaceNewProto(RR_SURFACE_PLANAR, 0);
+
+ RrColorSet(&pri, 0.9, 0.91, 0.9, 1);
+ RrPlanarSet(theme->menu_item, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 0, NULL);
+
+ theme->menu_disabled = RrSurfaceNewProto(RR_SURFACE_PLANAR, 0);
+
+ RrColorSet(&pri, 0.9, 0.91, 0.9, 1);
+ RrPlanarSet(theme->menu_item, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 0, NULL);
+
+ theme->menu_hilite = RrSurfaceNewProto(RR_SURFACE_PLANAR, 0);
+
+ RrColorSet(&pri, 0.9, 0.91, 0.9, 1);
+ RrPlanarSet(theme->menu_item, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 0, NULL);
+
+ theme->app_bg = RrSurfaceNewProto(RR_SURFACE_PLANAR, 0);
+ theme->app_bg_h = RrSurfaceNewProto(RR_SURFACE_PLANAR, 0);
+
+ RrColorSet(&pri, 0.9, 0.91, 0.9, 1);
+ RrColorSet(&bor, 0, 0, 0, 1);
+ RrPlanarSet(theme->app_bg, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 1, &bor);
+ RrPlanarSet(theme->app_bg_h, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 1, &bor);
+
+ theme->app_label = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ theme->app_label_h = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+
+ RrColorSet(&pri, 0.30, 0.34, 0.65, 1);
+ RrColorSet(&sec, 0.35, 0.43, 0.75, 1);
+ RrColorSet(&bor, 0, 0, 0, 1);
+ RrPlanarSet(theme->app_label, RR_PLANAR_VERTICAL, RR_BEVEL_NONE,
+ &pri, &sec, 1, &bor);
+ RrColorSet(&pri, 0.70, 0.70, 0.68, 1);
+ RrColorSet(&sec, 0.75, 0.73, 0.71, 1);
+ RrColorSet(&bor, 0.42, 0.41, 0.42, 1);
+ RrPlanarSet(theme->app_label_h, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, &sec, 1, &bor);
+
+#endif
+
+ RrColorSet(&pri, 0, 0, 0, 0); /* clear */
+
+ theme->icon = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ RrPlanarSet(theme->icon, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 0, NULL);
+
+ theme->app_icon = RrSurfaceNewProto(RR_SURFACE_PLANAR, 1);
+ RrPlanarSet(theme->app_icon, RR_PLANAR_SOLID, RR_BEVEL_NONE,
+ &pri, NULL, 0, NULL);
+
+ return theme;
+}
+
+void RrThemeDestroy(struct RrTheme *theme)
+{
+ if (theme) {
+ RrFontClose(theme->title_font);
+
+ RrSurfaceFree(theme->max);
+ RrSurfaceFree(theme->max_f);
+ RrSurfaceFree(theme->max_p);
+ RrSurfaceFree(theme->max_p_f);
+
+ RrSurfaceFree(theme->iconify);
+ RrSurfaceFree(theme->iconify_f);
+ RrSurfaceFree(theme->iconify_p);
+ RrSurfaceFree(theme->iconify_p_f);
+
+ RrSurfaceFree(theme->close);
+ RrSurfaceFree(theme->close_f);
+ RrSurfaceFree(theme->close_p);
+ RrSurfaceFree(theme->close_p_f);
+
+ RrSurfaceFree(theme->desk);
+ RrSurfaceFree(theme->desk_f);
+ RrSurfaceFree(theme->desk_p);
+ RrSurfaceFree(theme->desk_p_f);
+
+ RrSurfaceFree(theme->shade);
+ RrSurfaceFree(theme->shade_f);
+ RrSurfaceFree(theme->shade_p);
+ RrSurfaceFree(theme->shade_p_f);
+
+ RrSurfaceFree(theme->icon);
+
+ RrSurfaceFree(theme->frame);
+
+ RrSurfaceFree(theme->title);
+ RrSurfaceFree(theme->title_f);
+
+ RrSurfaceFree(theme->label);
+ RrSurfaceFree(theme->label_f);
+
+ RrSurfaceFree(theme->grip);
+ RrSurfaceFree(theme->grip_f);
+
+ RrSurfaceFree(theme->handle);
+ RrSurfaceFree(theme->handle_f);
+
+ RrSurfaceFree(theme->menu_title);
+ RrSurfaceFree(theme->menu_item);
+ RrSurfaceFree(theme->menu_disabled);
+ RrSurfaceFree(theme->menu_hilite);
+
+ RrSurfaceFree(theme->app_bg);
+ RrSurfaceFree(theme->app_bg_h);
+ RrSurfaceFree(theme->app_label);
+ RrSurfaceFree(theme->app_label_h);
+ RrSurfaceFree(theme->app_icon);
+
+ free(theme);
+ }
+}
--- /dev/null
+#ifndef __render_theme_h
+#define __render_theme_h
+
+#include "render.h"
+
+struct RrTheme;
+
+struct RrTheme *RrThemeLoad(struct RrInstance *inst, const char *name);
+void RrThemeDestroy(struct RrTheme *theme);
+
+struct RrTheme {
+ struct RrInstance *inst;
+
+ int bevel;
+ int bwidth;
+ int cbwidth;
+ int handle_height;
+
+ char *title_layout;
+
+ struct RrFont *title_font;
+ enum RrLayout title_justify;
+
+ struct RrColor b_color;
+ struct RrColor cb_color;
+ struct RrColor cb_color_f; /* focused */
+ struct RrColor title_color;
+ struct RrColor title_color_f; /* focused */
+ struct RrColor button_color;
+ struct RrColor button_color_f; /* focused */
+ struct RrColor menu_title_color;
+ struct RrColor menu_item_color;
+ struct RrColor menu_disabled_color;
+ struct RrColor menu_hilite_color;
+
+ struct RrSurface *max;
+ struct RrSurface *max_f; /* focused */
+ struct RrSurface *max_p; /* pressed */
+ struct RrSurface *max_p_f; /* pressed-focused */
+
+ struct RrSurface *iconify;
+ struct RrSurface *iconify_f; /* focused */
+ struct RrSurface *iconify_p; /* pressed */
+ struct RrSurface *iconify_p_f; /* pressed-focused */
+
+ struct RrSurface *close;
+ struct RrSurface *close_f; /* focused */
+ struct RrSurface *close_p; /* pressed */
+ struct RrSurface *close_p_f; /* pressed-focused */
+
+ struct RrSurface *desk;
+ struct RrSurface *desk_f; /* focused */
+ struct RrSurface *desk_p; /* pressed */
+ struct RrSurface *desk_p_f; /* pressed-focused */
+
+ struct RrSurface *shade;
+ struct RrSurface *shade_f; /* focused */
+ struct RrSurface *shade_p; /* pressed */
+ struct RrSurface *shade_p_f; /* pressed-focused */
+
+ struct RrSurface *icon;
+
+ struct RrSurface *frame;
+
+ struct RrSurface *title;
+ struct RrSurface *title_f; /* focused */
+
+ struct RrSurface *label;
+ struct RrSurface *label_f; /* focused */
+
+ struct RrSurface *grip;
+ struct RrSurface *grip_f; /* focused */
+
+ struct RrSurface *handle;
+ struct RrSurface *handle_f; /* focused */
+
+ struct RrSurface *menu_title;
+ struct RrSurface *menu_item;
+ struct RrSurface *menu_disabled;
+ struct RrSurface *menu_hilite;
+
+ struct RrSurface *app_bg;
+ struct RrSurface *app_bg_h; /* hilited */
+ struct RrSurface *app_label;
+ struct RrSurface *app_label_h; /* hilited */
+ struct RrSurface *app_icon;
+};
+
+#define RrThemeLabelHeight(t) (RrFontHeight((t)->title_font) + 2)
+#define RrThemeTitleHeight(t) (RrThemeLabelHeight(t) + \
+ ((t)->bevel + (t)->bwidth) * 2)
+#define RrThemeButtonSize(t) (RrThemeLabelHeight(t) - \
+ ((t)->bevel + (t)->bwidth) * 2)
+#define RrThemeGripWidth(t) (RrThemeButtonSize(t) * 2)
+
+#endif