the kernel is using th gl shit to render itself, but with the old style frame shit...
authorDana Jansens <danakj@orodu.net>
Tue, 3 Jun 2003 10:39:35 +0000 (10:39 +0000)
committerDana Jansens <danakj@orodu.net>
Tue, 3 Jun 2003 10:39:35 +0000 (10:39 +0000)
76 files changed:
COPYING.FDL [new file with mode: 0644]
COPYING.GPL [moved from COPYING with 100% similarity]
COPYING.LGPL [new file with mode: 0644]
Makefile.am
README
configure.ac
glft/.cvsignore [new file with mode: 0644]
glft/Makefile.am [new file with mode: 0644]
glft/debug.c [new file with mode: 0644]
glft/debug.h [new file with mode: 0644]
glft/font.c [new file with mode: 0644]
glft/font.h [new file with mode: 0644]
glft/glft.h [new file with mode: 0644]
glft/init.c [new file with mode: 0644]
glft/init.h [new file with mode: 0644]
glft/render.c [new file with mode: 0644]
glft/render.h [new file with mode: 0644]
glft/test.c [new file with mode: 0644]
m4/gl.m4
openbox/Makefile.am
openbox/client.c
openbox/client.h
openbox/dock.c
openbox/dock.h
openbox/event.c
openbox/frame.c
openbox/frame.h
openbox/framerender.c
openbox/menu.c
openbox/menu.h
openbox/menu_render.c
openbox/moveresize.c
openbox/openbox.c
openbox/openbox.h
openbox/popup.c
openbox/screen.c
openbox/window.c
plugins/menu/client_menu.c
render/.cvsignore [deleted file]
render/Makefile.am [deleted file]
render/color.h [deleted file]
render/font.c [deleted file]
render/font.h [deleted file]
render/gradient.c [deleted file]
render/gradient.h [deleted file]
render/image.c [deleted file]
render/image.h [deleted file]
render/mask.c [deleted file]
render/mask.h [deleted file]
render/render.c [deleted file]
render/render.h [deleted file]
render/test.c [deleted file]
render/theme.c [deleted file]
render/theme.h [deleted file]
render2/.cvsignore [new file with mode: 0644]
render2/Makefile.am [new file with mode: 0644]
render2/color.c [new file with mode: 0644]
render2/color.h [new file with mode: 0644]
render2/debug.c [new file with mode: 0644]
render2/debug.h [new file with mode: 0644]
render2/font.c [new file with mode: 0644]
render2/font.h [new file with mode: 0644]
render2/init.c [new file with mode: 0644]
render2/instance.c [new file with mode: 0644]
render2/instance.h [new file with mode: 0644]
render2/paint.c [new file with mode: 0644]
render2/planar.c [new file with mode: 0644]
render2/planar.h [new file with mode: 0644]
render2/render.h [new file with mode: 0644]
render2/surface.c [new file with mode: 0644]
render2/surface.h [new file with mode: 0644]
render2/test.c [new file with mode: 0644]
render2/texture.c [new file with mode: 0644]
render2/texture.h [new file with mode: 0644]
render2/theme.c [new file with mode: 0644]
render2/theme.h [new file with mode: 0644]

diff --git a/COPYING.FDL b/COPYING.FDL
new file mode 100644 (file)
index 0000000..d1e3b79
--- /dev/null
@@ -0,0 +1,397 @@
+               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.
similarity index 100%
rename from COPYING
rename to COPYING.GPL
diff --git a/COPYING.LGPL b/COPYING.LGPL
new file mode 100644 (file)
index 0000000..b1e3f5a
--- /dev/null
@@ -0,0 +1,504 @@
+                 GNU LESSER GENERAL PUBLIC LICENSE
+                      Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+                 GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                           NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
index 433af840f589441e36f502da4f5f2c8c09592b91..312982442b58b23148771906a23b479017f3a136 100644 (file)
@@ -1,4 +1,4 @@
-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:
diff --git a/README b/README
index afa52ea8eb9b41db8dfdc213b547674090c23a70..886919d6c4300c3a74fca2eddb8aeab4901171e0 100644 (file)
--- a/README
+++ b/README
@@ -8,15 +8,26 @@ Copyright (C) 2002-2003  Ben Jansens
 
 ----
 
-    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.
index 033431104fd307f8895317d619a99ef54b35a575..4b2769413834ce43c6066c4696f00db48c5e382d 100644 (file)
@@ -49,9 +49,15 @@ PKG_CHECK_MODULES([GMODULE], [gmodule-2.0])
 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)
@@ -100,13 +106,14 @@ X11_EXT_VIDMODE
 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
diff --git a/glft/.cvsignore b/glft/.cvsignore
new file mode 100644 (file)
index 0000000..b9e3361
--- /dev/null
@@ -0,0 +1,10 @@
+.libs
+.deps
+Makefile.in
+Makefile
+libglft.la
+init.lo
+glfttest
+debug.lo
+font.lo
+render.lo
diff --git a/glft/Makefile.am b/glft/Makefile.am
new file mode 100644 (file)
index 0000000..3dccc94
--- /dev/null
@@ -0,0 +1,36 @@
+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 .\#*
diff --git a/glft/debug.c b/glft/debug.c
new file mode 100644 (file)
index 0000000..d93603d
--- /dev/null
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+void GlftDebug(char *a, ...)
+{
+#ifdef DEBUG
+    va_list vl;
+    va_start(vl, a);
+    vprintf(a, vl);
+#endif
+}
diff --git a/glft/debug.h b/glft/debug.h
new file mode 100644 (file)
index 0000000..a1afe8e
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __glft_debug_h
+#define __glft_debug_h
+
+void GlftDebug(char *a, ...);
+
+#endif
diff --git a/glft/font.c b/glft/font.c
new file mode 100644 (file)
index 0000000..60a93b0
--- /dev/null
@@ -0,0 +1,333 @@
+#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;
+}
diff --git a/glft/font.h b/glft/font.h
new file mode 100644 (file)
index 0000000..7842ff8
--- /dev/null
@@ -0,0 +1,73 @@
+#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
diff --git a/glft/glft.h b/glft/glft.h
new file mode 100644 (file)
index 0000000..f441504
--- /dev/null
@@ -0,0 +1,47 @@
+#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
diff --git a/glft/init.c b/glft/init.c
new file mode 100644 (file)
index 0000000..2c4410e
--- /dev/null
@@ -0,0 +1,14 @@
+#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));
+}
diff --git a/glft/init.h b/glft/init.h
new file mode 100644 (file)
index 0000000..e5f3166
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __glft_init_h
+#define __glft_init_h
+
+extern FcBool init_done;
+extern FT_Library ft_lib;
+
+#endif
diff --git a/glft/render.c b/glft/render.c
new file mode 100644 (file)
index 0000000..730e47f
--- /dev/null
@@ -0,0 +1,125 @@
+#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);
+    }
+}
diff --git a/glft/render.h b/glft/render.h
new file mode 100644 (file)
index 0000000..facdb41
--- /dev/null
@@ -0,0 +1,11 @@
+#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
diff --git a/glft/test.c b/glft/test.c
new file mode 100644 (file)
index 0000000..90c5a1a
--- /dev/null
@@ -0,0 +1,116 @@
+#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;
+}
index e359271293353e55df8763129a4bc0c98ce48e9b..8ae3ba30bae14a32a8f8ebcc09a8c8ee7818c810 100644 (file)
--- a/m4/gl.m4
+++ b/m4/gl.m4
@@ -1,65 +1,46 @@
-# 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"])
 ])
index fc9f4ae3ec90fa1d55c019eb8b0030c999f7b30e..6fb48b9f93ae4041b390701976a0bb1ebb5e7402 100644 (file)
@@ -20,7 +20,7 @@ LIBS=$(X_LIBS) $(XFT_LIBS) $(XINERAMA_LIBS) $(XKB_LIBS) $(XRANDR_LIBS) \
 
 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 \
index 9e56de050dbdb29c371628e4b58b831f7918b0ed..029bccfddbbafe184271958320a8195baca4918f 100644 (file)
@@ -16,7 +16,7 @@
 #include "group.h"
 #include "config.h"
 #include "menu.h"
-#include "render/render.h"
+#include "render2/render.h"
 
 #include <glib.h>
 #include <X11/Xutil.h>
@@ -1342,23 +1342,25 @@ void client_update_icons(Client *self)
 
             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++;
@@ -1396,6 +1398,7 @@ void client_update_icons(Client *self)
             XFree(hints);
         }
     }
+*/
 
     if (self->frame)
        frame_adjust_icon(self->frame);
index 5d84df0b3a26777c940f961b4969c6f4fe3c69f2..a335c36ef3094b519fd471fc778eda91f3754822 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "geom.h"
 #include "stacking.h"
-#include "render/color.h"
+#include "render2/render.h"
 
 #include <glib.h>
 #include <X11/Xlib.h>
@@ -18,7 +18,7 @@ struct Group;
 /*! 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
index 934d3d03bcd8072390b4bb587a2c153df06b5ad4..f28c371d8f7099ef1867f1fe40985cf08d274204 100644 (file)
@@ -4,7 +4,8 @@
 #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)
@@ -28,12 +29,13 @@ void dock_startup()
     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));
@@ -42,8 +44,8 @@ void dock_startup()
 
 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);
 }
@@ -180,9 +182,8 @@ void dock_configure()
         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) {
@@ -264,39 +265,39 @@ void dock_configure()
             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;
         }    
     }
@@ -344,23 +345,14 @@ void dock_configure()
         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();
 }
index 2b6dc4d2fdf28202ba2241aedfff7b98145acb76..c88320d8ffc291136e0854761336426c75005866 100644 (file)
@@ -5,7 +5,7 @@
 #include "window.h"
 #include "stacking.h"
 #include "geom.h"
-#include "render/render.h"
+#include "render2/render.h"
 
 #include <glib.h>
 #include <X11/Xlib.h>
@@ -27,7 +27,7 @@ typedef struct Dock {
     ObWindow obwin;
 
     Window frame;
-    Appearance *a_frame;
+    struct RrSurface *s_frame;
 
     /* actual position (when not auto-hidden) */
     int x, y;
index b6126464ccb5119a1ce76e3f7cd33149e9ad05d6..cef0ae08e06a7432d478461cff3d70116a36ff21 100644 (file)
@@ -138,6 +138,9 @@ void event_loop()
         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;
     }
index 211a275c75024bbd002aab55c8da3d0f1ad037e6..af7dbcaeeef73243b068752051e3e45da0c58a7b 100644 (file)
@@ -2,11 +2,11 @@
 #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)
 
@@ -14,65 +14,6 @@ static void layout_title(Frame *self);
 
 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()
@@ -83,8 +24,8 @@ static Window createWindow(Window parent, unsigned long mask,
                           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);
                        
 }
 
@@ -107,61 +48,53 @@ Frame *frame_new()
     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;
@@ -171,14 +104,20 @@ Frame *frame_new()
 
 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);
@@ -188,7 +127,7 @@ void frame_show(Frame *self)
 {
     if (!self->visible) {
        self->visible = TRUE;
-       XMapWindow(ob_display, self->window);
+        RrSurfaceShow(self->s_frame);
     }
 }
 
@@ -197,7 +136,7 @@ void frame_hide(Frame *self)
     if (self->visible) {
        self->visible = FALSE;
        self->client->ignore_unmaps++;
-       XUnmapWindow(ob_display, self->window);
+        RrSurfaceHide(self->s_frame);
     }
 }
 
@@ -210,33 +149,31 @@ void frame_adjust_shape(Frame *self)
     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;
        }
 
@@ -251,24 +188,20 @@ void frame_adjust_area(Frame *self, gboolean moved, gboolean resized)
 {
     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 */
@@ -281,82 +214,48 @@ void frame_adjust_area(Frame *self, gboolean moved, gboolean resized)
         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));
 
@@ -371,10 +270,8 @@ void frame_adjust_area(Frame *self, gboolean moved, gboolean resized)
 
     /* 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);
@@ -433,17 +330,17 @@ void frame_grab_client(Frame *self, Client *client)
     /* 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)
@@ -473,17 +370,17 @@ 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);
 }
@@ -497,32 +394,36 @@ static void layout_title(Frame *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 */
@@ -532,90 +433,96 @@ static void layout_title(Frame *self)
            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)
@@ -662,19 +569,19 @@ Context frame_context(Client *client, Window win)
     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;
 }
index 3d395342f21ea97a33a4f980183c65b2a528cafa..ccc799ec74cd5a4aff2dfd5ad92f5d826bc485ac 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "geom.h"
 #include "client.h"
-#include "render/render.h"
+#include "render2/render.h"
 
 typedef enum {
     Context_None,
@@ -25,7 +25,7 @@ typedef enum {
     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 {
@@ -38,27 +38,30 @@ 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;
 
index 737dfe950bb00d2661f1c16eb92e3ab714451fba..3c9c618c5ff4e1ce460334dad23fe1b645d11700 100644 (file)
 #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);
 }
index 2af1a01f2f791e78f91ae273c84939193109ebed..be937877d2b1eac61146005ee6f85e87906a7d8b 100644 (file)
@@ -2,18 +2,18 @@
 #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);
 
@@ -33,16 +33,16 @@ void menu_destroy_hash_value(Menu *self)
     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);
 }
@@ -52,12 +52,10 @@ void menu_entry_free(MenuEntry *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);
 }
@@ -125,8 +123,8 @@ static Window createWindow(Window parent, unsigned long mask,
                           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);
                        
 }
 
@@ -159,26 +157,22 @@ Menu *menu_new_full(char *label, char *name, Menu *parent,
 
     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));
@@ -222,25 +216,33 @@ void menu_entry_set_submenu(MenuEntry *entry, Menu *submenu)
 
 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)
@@ -274,7 +276,7 @@ void menu_show_full(Menu *self, 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);
@@ -302,7 +304,7 @@ MenuEntry *menu_find_entry(Menu *menu, Window win)
 
     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;
@@ -329,16 +331,15 @@ void menu_entry_fire(MenuEntry *self)
 
 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) {
@@ -363,14 +364,14 @@ void menu_control_mouseover(MenuEntry *self, gboolean enter) {
            /* 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,
index 49a79fb4d266ccd2bc8cb126201375372d1882d9..be3bb5ca6b930fc2be7365d8a2ff0f4cc7565756 100644 (file)
@@ -2,7 +2,7 @@
 #define __menu_h
 
 #include "action.h"
-#include "render/render.h"
+#include "render2/render.h"
 #include "geom.h"
 
 #include <glib.h>
@@ -44,12 +44,13 @@ typedef struct Menu {
 
     /* 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;
@@ -83,10 +84,10 @@ typedef struct {
     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;
index 4df4e413d7e3a193a578698b86faa8833ff259e9..3c01537e01b22e299b4e494a3e177ad0ae8afb95 100644 (file)
@@ -2,7 +2,7 @@
 
 #include "menu.h"
 #include "openbox.h"
-#include "render/theme.h"
+#include "render2/theme.h"
 
 void menu_render_full(Menu *self);
 
@@ -28,10 +28,13 @@ 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);
     }
 
@@ -39,50 +42,43 @@ void menu_render_full(Menu *self) {
         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) {
@@ -98,44 +94,39 @@ void menu_render_full(Menu *self) {
 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);
 }
index 871e96536f6e4867d8c850a0029560dbee69ab0f..abbb308ecc28fbaaa04b1756c74df348ac84d7f2 100644 (file)
@@ -7,8 +7,8 @@
 #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>
@@ -53,14 +53,16 @@ void moveresize_startup()
 
     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,
index 0455e88c523406e929a1aba28a4745d89550b72a..c48d42ba772117ccc9b34f42c7e3c2976e34b912 100644 (file)
@@ -19,9 +19,8 @@
 #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>
@@ -45,6 +44,9 @@
 
 #include <X11/cursorfont.h>
 
+struct RrInstance *ob_render_inst;
+struct RrTheme    *ob_theme;
+
 Display *ob_display  = NULL;
 int      ob_screen;
 Window   ob_root;
@@ -65,7 +67,6 @@ int main(int argc, char **argv)
     struct sigaction action;
     sigset_t sigset;
     char *path;
-    char *theme;
     xmlDocPtr doc;
     xmlNodePtr node;
 
@@ -141,6 +142,12 @@ int main(int argc, char **argv)
     /* 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)));
@@ -170,9 +177,6 @@ int main(int argc, char **argv)
         /* 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();
@@ -188,9 +192,11 @@ int main(int argc, char **argv)
         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();
@@ -228,12 +234,12 @@ int main(int argc, char **argv)
         window_shutdown();
         grab_shutdown();
        event_shutdown();
-        theme_shutdown();
-       render_shutdown();
        timer_shutdown();
         config_shutdown();
     }
 
+    RrInstanceFree(ob_render_inst);
+
     dispatch_shutdown();
 
     XCloseDisplay(ob_display);
index 51f620793d6ee7c3043d20a42052ce3a41b2ff3b..cae4120d7695a3775dbe1dfd473142b858d2f19a 100644 (file)
 /*! 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
index a550e815856b668b1e3d39e8c2a55dd59ab8b607..22bcd5d51329aef01bc4b918815adbaa40bae8f7 100644 (file)
@@ -2,8 +2,8 @@
 #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;
@@ -13,44 +13,62 @@ typedef struct Popup {
     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);
 }
@@ -72,86 +90,52 @@ void popup_size_to_string(Popup *self, char *text)
 {
     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;
@@ -188,48 +172,36 @@ void popup_show(Popup *self, char *text, Icon *icon)
         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);
 }
index a1ad36e0e5fe69b06b78a399cbc80b78eec314ec..75ec5a99bd041f94f72c3e95431b0c38b4c02b4c 100644 (file)
@@ -11,7 +11,8 @@
 #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
@@ -482,9 +483,9 @@ void screen_install_colormap(Client *client, gboolean install)
 
     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) {
index ed139b64e04483030e908e0bff9ee16deeb1377d..bd9c4f81fc7bd41f0cf9c8610311eeaaacee7441 100644 (file)
@@ -21,7 +21,7 @@ Window window_top(ObWindow *self)
 {
     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:
index 9905291edf245066902cec4c1e2c507cc707a5ce..753c01403eb262d0553c01755a35820b77e66a67 100644 (file)
@@ -4,10 +4,8 @@
 #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";
 
@@ -15,7 +13,7 @@ static Menu *send_to_menu;
 static Menu *layer_menu;
 
 typedef struct {
-
+    int foo;
 } Client_Menu_Data;
 
 #define CLIENT_MENU(m) ((Menu *)m)
@@ -47,19 +45,16 @@ void client_menu_show(Menu *self, int x, int y, Client *client)
     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) {
diff --git a/render/.cvsignore b/render/.cvsignore
deleted file mode 100644 (file)
index 54aa917..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-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
diff --git a/render/Makefile.am b/render/Makefile.am
deleted file mode 100644 (file)
index 579ff68..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-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 .\#*
diff --git a/render/color.h b/render/color.h
deleted file mode 100644 (file)
index fb669fb..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-#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 */
diff --git a/render/font.c b/render/font.c
deleted file mode 100644 (file)
index db4e848..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-#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;
-}
diff --git a/render/font.h b/render/font.h
deleted file mode 100644 (file)
index 6a5d4c6..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#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 */
diff --git a/render/gradient.c b/render/gradient.c
deleted file mode 100644 (file)
index 31d4c73..0000000
+++ /dev/null
@@ -1,758 +0,0 @@
-#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 */
diff --git a/render/gradient.h b/render/gradient.h
deleted file mode 100644 (file)
index bbadcd0..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#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 */
diff --git a/render/image.c b/render/image.c
deleted file mode 100644 (file)
index feb2597..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-#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);
-        }
-    }
-}
diff --git a/render/image.h b/render/image.h
deleted file mode 100644 (file)
index 84f61d7..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#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
diff --git a/render/mask.c b/render/mask.c
deleted file mode 100644 (file)
index 22cb3fe..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#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;
-}
diff --git a/render/mask.h b/render/mask.h
deleted file mode 100644 (file)
index 9328daf..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#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
diff --git a/render/render.c b/render/render.c
deleted file mode 100644 (file)
index 712ed7f..0000000
+++ /dev/null
@@ -1,647 +0,0 @@
-#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 */
diff --git a/render/render.h b/render/render.h
deleted file mode 100644 (file)
index 16f5c31..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-#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*/
diff --git a/render/test.c b/render/test.c
deleted file mode 100644 (file)
index 7c3c83b..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-#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;
-}
diff --git a/render/theme.c b/render/theme.c
deleted file mode 100644 (file)
index 8ba7a9d..0000000
+++ /dev/null
@@ -1,986 +0,0 @@
-#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;
-}
diff --git a/render/theme.h b/render/theme.h
deleted file mode 100644 (file)
index 2a93c8d..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-#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
diff --git a/render2/.cvsignore b/render2/.cvsignore
new file mode 100644 (file)
index 0000000..98a69ed
--- /dev/null
@@ -0,0 +1,16 @@
+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
diff --git a/render2/Makefile.am b/render2/Makefile.am
new file mode 100644 (file)
index 0000000..d62d53d
--- /dev/null
@@ -0,0 +1,43 @@
+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 .\#*
diff --git a/render2/color.c b/render2/color.c
new file mode 100644 (file)
index 0000000..1458c0e
--- /dev/null
@@ -0,0 +1,24 @@
+#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;
+}
diff --git a/render2/color.h b/render2/color.h
new file mode 100644 (file)
index 0000000..667ab37
--- /dev/null
@@ -0,0 +1,17 @@
+#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
diff --git a/render2/debug.c b/render2/debug.c
new file mode 100644 (file)
index 0000000..34d009a
--- /dev/null
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+void RrDebug(char *a, ...)
+{
+#ifdef DEBUG
+    va_list vl;
+    va_start(vl, a);
+    vprintf(a, vl);
+#endif
+}
diff --git a/render2/debug.h b/render2/debug.h
new file mode 100644 (file)
index 0000000..cb5413b
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __render_debug_h
+#define __render_debug_h
+
+void RrDebug(char *a, ...);
+
+#endif
diff --git a/render2/font.c b/render2/font.c
new file mode 100644 (file)
index 0000000..3a21e16
--- /dev/null
@@ -0,0 +1,37 @@
+#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;
+}
diff --git a/render2/font.h b/render2/font.h
new file mode 100644 (file)
index 0000000..f73e479
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef __render_font_h
+#define __render_font_h
+
+#include "glft/glft.h"
+
+struct RrInstance;
+
+struct RrFont {
+    struct RrInstance *inst;
+    struct GlftFont *font;
+};
+
+#endif
diff --git a/render2/init.c b/render2/init.c
new file mode 100644 (file)
index 0000000..b691645
--- /dev/null
@@ -0,0 +1,94 @@
+#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);
+    }
+}
diff --git a/render2/instance.c b/render2/instance.c
new file mode 100644 (file)
index 0000000..311a86e
--- /dev/null
@@ -0,0 +1,166 @@
+#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);
+}
diff --git a/render2/instance.h b/render2/instance.h
new file mode 100644 (file)
index 0000000..a9b7833
--- /dev/null
@@ -0,0 +1,41 @@
+#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
diff --git a/render2/paint.c b/render2/paint.c
new file mode 100644 (file)
index 0000000..135ae79
--- /dev/null
@@ -0,0 +1,106 @@
+#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));
+}
diff --git a/render2/planar.c b/render2/planar.c
new file mode 100644 (file)
index 0000000..91d769f
--- /dev/null
@@ -0,0 +1,362 @@
+#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;
+}
diff --git a/render2/planar.h b/render2/planar.h
new file mode 100644 (file)
index 0000000..755b122
--- /dev/null
@@ -0,0 +1,26 @@
+#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
diff --git a/render2/render.h b/render2/render.h
new file mode 100644 (file)
index 0000000..701b712
--- /dev/null
@@ -0,0 +1,230 @@
+#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
diff --git a/render2/surface.c b/render2/surface.c
new file mode 100644 (file)
index 0000000..2ead9fb
--- /dev/null
@@ -0,0 +1,295 @@
+#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
+}
diff --git a/render2/surface.h b/render2/surface.h
new file mode 100644 (file)
index 0000000..39dbffc
--- /dev/null
@@ -0,0 +1,65 @@
+#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
diff --git a/render2/test.c b/render2/test.c
new file mode 100644 (file)
index 0000000..eb76e5c
--- /dev/null
@@ -0,0 +1,106 @@
+#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;
+}
diff --git a/render2/texture.c b/render2/texture.c
new file mode 100644 (file)
index 0000000..0e0cac8
--- /dev/null
@@ -0,0 +1,108 @@
+#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);
+}
diff --git a/render2/texture.h b/render2/texture.h
new file mode 100644 (file)
index 0000000..5d535e3
--- /dev/null
@@ -0,0 +1,44 @@
+#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
diff --git a/render2/theme.c b/render2/theme.c
new file mode 100644 (file)
index 0000000..803fcc1
--- /dev/null
@@ -0,0 +1,296 @@
+#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);
+    }
+}
diff --git a/render2/theme.h b/render2/theme.h
new file mode 100644 (file)
index 0000000..8386d31
--- /dev/null
@@ -0,0 +1,96 @@
+#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